class Protocol::Rack::Rewindable

can be read multiple times, which is required by Rack’s specification.
This middleware ensures that request bodies for certain content types
Content-type driven input buffering, specific to the needs of ‘rack`.

def call(request)

@returns [Protocol::HTTP::Response] The response from the wrapped middleware.
@parameter request [Protocol::HTTP::Request] The request to process.

If the request needs a rewindable body, wraps it in a {Protocol::HTTP::Body::Rewindable}.
Wrap the request body in a rewindable buffer if required.
def call(request)
	if body = request.body and needs_rewind?(request)
		request.body = Protocol::HTTP::Body::Rewindable.new(body)
	end
	
	return super
end

def initialize(app)

@parameter app [Protocol::HTTP::Middleware] The middleware to wrap.

Initialize the rewindable middleware.
def initialize(app)
	super(app)
end

def make_environment(request)

@returns [Hash] The Rack environment hash.
@parameter request [Protocol::HTTP::Request] The request to create an environment from.

Delegates to the wrapped middleware.
Create a Rack environment from the request.
def make_environment(request)
	@delegate.make_environment(request)
end

def needs_rewind?(request)

@returns [Boolean] True if the request body should be rewindable.
@parameter request [Protocol::HTTP::Request] The request to check.

- It has a content type that matches BUFFERED_MEDIA_TYPES
- It's a POST request with no content type (legacy behavior)
A request needs a rewindable body if:
Determine whether the request needs a rewindable body.
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