Skip to content
This repository
Browse code

Use a BodyProxy instead of including a Module that responds to close.

Closes #4441 if Active Record is disabled assets are delivered correctly
  • Loading branch information...
commit c159b01b85ac3955c53cd6b8a62d5d90ee973cfb 1 parent 4ca3592
Santiago Pastorino spastorino authored
4 actionpack/CHANGELOG.md
Source Rendered
... ... @@ -1,5 +1,9 @@
1 1 ## Rails 3.2.0 (unreleased) ##
2 2
  3 +* Use a BodyProxy instead of including a Module that responds to
  4 + close. Closes #4441 if Active Record is disabled assets are delivered
  5 + correctly *Santiago Pastorino*
  6 +
3 7 * Rails initialization with initialize_on_precompile = false should set assets_dir *Santiago Pastorino*
4 8
5 9 * Add font_path helper method *Santiago Pastorino*
28 actionpack/lib/action_dispatch/middleware/body_proxy.rb
... ... @@ -0,0 +1,28 @@
  1 +# Keep this file meanwhile https://github.com/rack/rack/pull/313 is not released
  2 +module ActionDispatch
  3 + class BodyProxy
  4 + def initialize(body, &block)
  5 + @body, @block, @closed = body, block, false
  6 + end
  7 +
  8 + def respond_to?(*args)
  9 + super or @body.respond_to?(*args)
  10 + end
  11 +
  12 + def close
  13 + return if @closed
  14 + @closed = true
  15 + @body.close if @body.respond_to? :close
  16 + ensure
  17 + @block.call
  18 + end
  19 +
  20 + def closed?
  21 + @closed
  22 + end
  23 +
  24 + def method_missing(*args, &block)
  25 + @body.__send__(*args, &block)
  26 + end
  27 + end
  28 +end
17 actionpack/lib/action_dispatch/middleware/reloader.rb
... ... @@ -1,3 +1,5 @@
  1 +require 'action_dispatch/middleware/body_proxy'
  2 +
1 3 module ActionDispatch
2 4 # ActionDispatch::Reloader provides prepare and cleanup callbacks,
3 5 # intended to assist with code reloading during development.
@@ -61,7 +63,7 @@ def call(env)
61 63 @validated = @condition.call
62 64 prepare!
63 65 response = @app.call(env)
64   - response[2].extend(module_hook)
  66 + response[2] = ActionDispatch::BodyProxy.new(response[2]) { cleanup! }
65 67 response
66 68 rescue Exception
67 69 cleanup!
@@ -83,18 +85,5 @@ def cleanup! #:nodoc:
83 85 def validated? #:nodoc:
84 86 @validated
85 87 end
86   -
87   - def module_hook #:nodoc:
88   - middleware = self
89   - Module.new do
90   - define_method :close do
91   - begin
92   - super() if defined?(super)
93   - ensure
94   - middleware.cleanup!
95   - end
96   - end
97   - end
98   - end
99 88 end
100 89 end
13 actionpack/test/dispatch/reloader_test.rb
@@ -43,6 +43,16 @@ def test_returned_body_object_always_responds_to_close
43 43 assert_respond_to body, :close
44 44 end
45 45
  46 + def test_returned_body_object_always_responds_to_close_even_if_called_twice
  47 + body = call_and_return_body
  48 + assert_respond_to body, :close
  49 + body.close
  50 +
  51 + body = call_and_return_body
  52 + assert_respond_to body, :close
  53 + body.close
  54 + end
  55 +
46 56 def test_condition_specifies_when_to_reload
47 57 i, j = 0, 0, 0, 0
48 58 Reloader.to_prepare { |*args| i += 1 }
@@ -154,7 +164,8 @@ def test_cleanup_callbacks_are_called_on_exceptions
154 164
155 165 private
156 166 def call_and_return_body(&block)
157   - @reloader ||= Reloader.new(block || proc {[200, {}, 'response']})
  167 + @response ||= 'response'
  168 + @reloader ||= Reloader.new(block || proc {[200, {}, @response]})
158 169 @reloader.call({'rack.input' => StringIO.new('')})[2]
159 170 end
160 171 end
2  railties/guides/source/3_2_release_notes.textile
Source Rendered
@@ -215,6 +215,8 @@ In the example above, Posts controller will no longer automatically look up for
215 215
216 216 h4. Action Dispatch
217 217
  218 +* Use a BodyProxy instead of including a Module that responds to close. Closes #4441 if Active Record is disabled assets are delivered correctly.
  219 +
218 220 * Added <tt>ActionDispatch::RequestId</tt> middleware that'll make a unique X-Request-Id header available to the response and enables the <tt>ActionDispatch::Request#uuid</tt> 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.
219 221
220 222 * The <tt>ShowExceptions</tt> 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 <tt>PATH_INFO</tt> rewritten to the status code.

0 comments on commit c159b01

José Valim

Bro, it needs to be like the pull request I sent to rack. It needs to be:

begin
  @body.close
ensure
  @block.call
end

The current way will always call the block even if return if @closed returns.

Please sign in to comment.
Something went wrong with that request. Please try again.