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
appProtocol::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
requestProtocol::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
requestProtocol::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
requestProtocol::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