Always buffer rack.input if it is not rewindable

Signed-off-by: Joshua Peek <josh@joshpeek.com>
This commit is contained in:
Mislav Marohnić
2009-04-17 21:53:44 -05:00
committed by Joshua Peek
parent 878aec9d95
commit 35c5727ace
4 changed files with 11 additions and 18 deletions

View File

@@ -1,27 +1,18 @@
module ActionController
class RewindableInput
class RewindableIO < ActiveSupport::BasicObject
def initialize(io)
@io = io
@rewindable = io.is_a?(::StringIO)
end
def method_missing(method, *args, &block)
unless @rewindable
@io = ::StringIO.new(@io.read)
@rewindable = true
end
@io.__send__(method, *args, &block)
end
end
def initialize(app)
@app = app
end
def call(env)
env['rack.input'] = RewindableIO.new(env['rack.input'])
begin
env['rack.input'].rewind
rescue NoMethodError, Errno::ESPIPE
# Handles exceptions raised by input streams that cannot be rewound
# such as when using plain CGI under Apache
env['rack.input'] = StringIO.new(env['rack.input'].read)
end
@app.call(env)
end
end

View File

@@ -94,7 +94,7 @@ class DispatcherTest < Test::Unit::TestCase
def dispatch(cache_classes = true)
ActionController::Routing::RouteSet.any_instance.stubs(:call).returns([200, {}, 'response'])
Dispatcher.define_dispatcher_callbacks(cache_classes)
Dispatcher.new.call({})
Dispatcher.new.call({'rack.input' => StringIO.new('')})
end
def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)

View File

@@ -207,6 +207,7 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest
def call(env)
env['rack.input'].read
env['rack.input'].rewind
@app.call(env)
end
end

View File

@@ -151,6 +151,7 @@ class UrlEncodedParamsParsingTest < ActionController::IntegrationTest
def call(env)
env['rack.input'].read
env['rack.input'].rewind
@app.call(env)
end
end