I’m developing a Rail application to accept data upload using HTTP PUT
call. Support for PUT in Rails seems to be broken in query params
parsing. I have a patch to fix the problem, but I’m not sure if it is
the “right” solution. Can some Rails developers take a quick look? I
can really use some help.
Here is the evident of broken param parsing.
Processing FoobarController#put_action (for 127.0.0.1 at 2006-01-13
23:12:54)
Parameters: {“action”=>“put_action”, “key1”=>“value1”,
“controller”=>“foobar”, “Hello, I am a test upload via PUT.\n”=>“”}
The content of the PUT-call “Hello, I am a test upload via PUT.\n” get
parsed as a param key. I made the PUT call using
curl -T test-file.txt
‘http://localhost:3000/foobar/put_action?key1=value1’
From action_controller/cgi_ext/raw_post_data_fix.rb, the PUT method is
handled the same way as POST, which would have the content body parsed
for params. So, I made a patch by redefining
CGI::QueryExtension#read_query_params
Note that I have to put the body content into env_table[‘RAW_PUT_DATA’]
instead of env_table[‘RAW_POST_DATA’]. The latter will have the same
problem.
class CGI #:nodoc:
module QueryExtension
private
def setup_raw_put_data
stdinput.binmode if stdinput.respond_to?(:binmode)
content = stdinput.read(Integer(env_table[‘CONTENT_LENGTH’]))
|| ‘’
env_table[‘RAW_PUT_DATA’] = content.freeze
end
def read_query_params(method)
case method
when :get
read_params_from_query
when :post
read_params_from_post
when :put
setup_raw_put_data
when :cmd
read_from_cmdline
else # when :head, :delete, :options
read_params_from_query
end
end
end
end