lib/protocol/rack/rewindable.rb
# frozen_string_literal: true # Released under the MIT License. # Copyright, 2022-2024, by Samuel Williams. require "protocol/http/body/rewindable" require "protocol/http/middleware" module Protocol module Rack # Content-type driven input buffering, specific to the needs of `rack`. class Rewindable < ::Protocol::HTTP::Middleware # Media types that require buffering. BUFFERED_MEDIA_TYPES = %r{ application/x-www-form-urlencoded| multipart/form-data| multipart/related| multipart/mixed }x POST = "POST" # Initialize the rewindable middleware. # @parameter app [Protocol::HTTP::Middleware] The middleware to wrap. def initialize(app) super(app) end # Determine whether the request needs a rewindable body. # @parameter request [Protocol::HTTP::Request] # @returns [Boolean] 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) @delegate.make_environment(request) end # Wrap the request body in a rewindable buffer if required. # @parameter request [Protocol::HTTP::Request] # @returns [Protocol::HTTP::Response] the response. def call(request) if body = request.body and needs_rewind?(request) request.body = Protocol::HTTP::Body::Rewindable.new(body) end return super end end end end