class Rewindable
Content-type driven input buffering, specific to the needs of rack
.
This middleware ensures that request bodies for certain content types
can be read multiple times, which is required by Rack's specification.
Definitions
BUFFERED_MEDIA_TYPES
Media types that require buffering. These types typically contain form data or file uploads that may need to be read multiple times by Rack applications.
Implementation
BUFFERED_MEDIA_TYPES = %r{
application/x-www-form-urlencoded|
multipart/form-data|
multipart/related|
multipart/mixed
}x
POST = "POST"
The HTTP POST method.
def initialize(app)
Initialize the rewindable middleware.
Signature
-
parameter
app
Protocol::HTTP::Middleware
The middleware to wrap.
Implementation
def initialize(app)
super(app)
end
def needs_rewind?(request)
Determine whether the request needs a rewindable body. A request needs a rewindable body if:
- It's a POST request with no content type (legacy behavior)
- It has a content type that matches BUFFERED_MEDIA_TYPES
Signature
-
parameter
request
Protocol::HTTP::Request
The request to check.
-
returns
Boolean
True if the request body should be rewindable.
Implementation
def needs_rewind?(request)
content_type = request.headers["content-type"]
if request.method == POST and content_type.nil?
return true
end
if BUFFERED_MEDIA_TYPES =~ content_type
return true
end
return false
end
def make_environment(request)
Create a Rack environment from the request. Delegates to the wrapped middleware.
Signature
-
parameter
request
Protocol::HTTP::Request
The request to create an environment from.
-
returns
Hash
The Rack environment hash.
Implementation
def make_environment(request)
@delegate.make_environment(request)
end
def call(request)
Wrap the request body in a rewindable buffer if required.
If the request needs a rewindable body, wraps it in a Protocol::HTTP::Body::Rewindable
.
Signature
-
parameter
request
Protocol::HTTP::Request
The request to process.
-
returns
Protocol::HTTP::Response
The response from the wrapped middleware.
Implementation
def call(request)
if body = request.body and needs_rewind?(request)
request.body = Protocol::HTTP::Body::Rewindable.new(body)
end
return super
end