This project is archived and is in readonly mode.
rack middleware parse request parameters twice
Reported by Eugene Pimenov | February 7th, 2009 @ 06:59 AM
Rack::MethodOverride parses request parameters, then forgets about it. Rails routes parse it again a bit later.
If I make an upload request, I'll end up with pairs of identical RackMultipart files.
Comments and changes to this ticket
-
josh February 7th, 2009 @ 10:14 PM
- Milestone cleared.
- Assigned user set to josh
Can you please test on edge as well. Also, failing unit tests to prove the issue would be appreciated.
-
josh February 10th, 2009 @ 07:48 PM
- State changed from new to resolved
Appears to be fixed by a recent upgrade of rack.
-
Eugene Pimenov February 10th, 2009 @ 08:05 PM
No, it's not.
Test something like:
Rack::Request.any_instance.expects(:POST).once.returns({}) @dispatcher.call({"REQUEST_METHOD" => "POST", "rack.input" => StringIO.new(""), "REQUEST_URI" => "/"})
where dispatcher is ActionController::Dispatcher. I'll provide normal test case later.
The problem because of Rack::MethodOverride has that code
req = Request.new(env) method = req.POST[METHOD_OVERRIDE_PARAM_KEY] || env[HTTP_METHOD_OVERRIDE_HEADER]
It uses Rack::Request, instead of ActionController::Request. ActionController::Request saves itself into rack env, so doesn't parse arguments twice. Rack::Request parses arguments every time POST is invoked.
To fix that problem locally, I monkey-patched Rack::MethodOverride to use ActionController::Request.
-
josh February 10th, 2009 @ 08:30 PM
def POST if @env["rack.request.form_input"].eql? @env["rack.input"] @env["rack.request.form_hash"] elsif form_data? @env["rack.request.form_input"] = @env["rack.input"] unless @env["rack.request.form_hash"] = Utils::Multipart.parse_multipart(env) form_vars = @env["rack.input"].read # Fix for Safari Ajax postings that always append \0 form_vars.sub!(/\0\z/, '') @env["rack.request.form_vars"] = form_vars @env["rack.request.form_hash"] = Utils.parse_query(form_vars) begin @env["rack.input"].rewind if @env["rack.input"].respond_to?(:rewind) rescue Errno::ESPIPE # Handles exceptions raised by input streams that cannot be rewound # such as when using plain CGI under Apache end end @env["rack.request.form_hash"] else {} end end
Rack caches the result from Request#POST to @env["rack.request.form_hash"].
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
People watching this ticket
Tags
Referenced by
- 1699 Switch to Rack::MethodOverride #1904 is somehow related to this