From c159b01b85ac3955c53cd6b8a62d5d90ee973cfb Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 13 Jan 2012 18:40:34 -0200 Subject: Use a BodyProxy instead of including a Module that responds to close. Closes #4441 if Active Record is disabled assets are delivered correctly --- actionpack/CHANGELOG.md | 4 ++++ .../lib/action_dispatch/middleware/body_proxy.rb | 28 ++++++++++++++++++++++ .../lib/action_dispatch/middleware/reloader.rb | 17 +++---------- actionpack/test/dispatch/reloader_test.rb | 13 +++++++++- railties/guides/source/3_2_release_notes.textile | 2 ++ 5 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 actionpack/lib/action_dispatch/middleware/body_proxy.rb diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 42bd1c6d57..8a4be5667e 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,9 @@ ## Rails 3.2.0 (unreleased) ## +* Use a BodyProxy instead of including a Module that responds to + close. Closes #4441 if Active Record is disabled assets are delivered + correctly *Santiago Pastorino* + * Rails initialization with initialize_on_precompile = false should set assets_dir *Santiago Pastorino* * Add font_path helper method *Santiago Pastorino* diff --git a/actionpack/lib/action_dispatch/middleware/body_proxy.rb b/actionpack/lib/action_dispatch/middleware/body_proxy.rb new file mode 100644 index 0000000000..867afe3b48 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/body_proxy.rb @@ -0,0 +1,28 @@ +# Keep this file meanwhile https://github.com/rack/rack/pull/313 is not released +module ActionDispatch + class BodyProxy + def initialize(body, &block) + @body, @block, @closed = body, block, false + end + + def respond_to?(*args) + super or @body.respond_to?(*args) + end + + def close + return if @closed + @closed = true + @body.close if @body.respond_to? :close + ensure + @block.call + end + + def closed? + @closed + end + + def method_missing(*args, &block) + @body.__send__(*args, &block) + end + end +end diff --git a/actionpack/lib/action_dispatch/middleware/reloader.rb b/actionpack/lib/action_dispatch/middleware/reloader.rb index 4f48f1c974..7a5aff214d 100644 --- a/actionpack/lib/action_dispatch/middleware/reloader.rb +++ b/actionpack/lib/action_dispatch/middleware/reloader.rb @@ -1,3 +1,5 @@ +require 'action_dispatch/middleware/body_proxy' + module ActionDispatch # ActionDispatch::Reloader provides prepare and cleanup callbacks, # intended to assist with code reloading during development. @@ -61,7 +63,7 @@ module ActionDispatch @validated = @condition.call prepare! response = @app.call(env) - response[2].extend(module_hook) + response[2] = ActionDispatch::BodyProxy.new(response[2]) { cleanup! } response rescue Exception cleanup! @@ -83,18 +85,5 @@ module ActionDispatch def validated? #:nodoc: @validated end - - def module_hook #:nodoc: - middleware = self - Module.new do - define_method :close do - begin - super() if defined?(super) - ensure - middleware.cleanup! - end - end - end - end end end diff --git a/actionpack/test/dispatch/reloader_test.rb b/actionpack/test/dispatch/reloader_test.rb index 3411bd14ea..df66e88cb1 100644 --- a/actionpack/test/dispatch/reloader_test.rb +++ b/actionpack/test/dispatch/reloader_test.rb @@ -43,6 +43,16 @@ class ReloaderTest < Test::Unit::TestCase assert_respond_to body, :close end + def test_returned_body_object_always_responds_to_close_even_if_called_twice + body = call_and_return_body + assert_respond_to body, :close + body.close + + body = call_and_return_body + assert_respond_to body, :close + body.close + end + def test_condition_specifies_when_to_reload i, j = 0, 0, 0, 0 Reloader.to_prepare { |*args| i += 1 } @@ -154,7 +164,8 @@ class ReloaderTest < Test::Unit::TestCase private def call_and_return_body(&block) - @reloader ||= Reloader.new(block || proc {[200, {}, 'response']}) + @response ||= 'response' + @reloader ||= Reloader.new(block || proc {[200, {}, @response]}) @reloader.call({'rack.input' => StringIO.new('')})[2] end end diff --git a/railties/guides/source/3_2_release_notes.textile b/railties/guides/source/3_2_release_notes.textile index ba536ed278..41f565ea28 100644 --- a/railties/guides/source/3_2_release_notes.textile +++ b/railties/guides/source/3_2_release_notes.textile @@ -215,6 +215,8 @@ In the example above, Posts controller will no longer automatically look up for h4. Action Dispatch +* Use a BodyProxy instead of including a Module that responds to close. Closes #4441 if Active Record is disabled assets are delivered correctly. + * Added ActionDispatch::RequestId middleware that'll make a unique X-Request-Id header available to the response and enables the ActionDispatch::Request#uuid method. This makes it easy to trace requests from end-to-end in the stack and to identify individual requests in mixed logs like Syslog. * The ShowExceptions middleware now accepts a exceptions application that is responsible to render an exception when the application fails. The application is invoked with a copy of the exception in +env["action_dispatch.exception"]+ and with the PATH_INFO rewritten to the status code. -- cgit v1.2.3