Hi Everyone,
I encountered a strange problem when trying to write a cgi script to
handle a PUT/POST scenario for a set of REST-style web services I’m
writing in Ruby.
If I do a normal post to a url, say:
/cgi-bin/cgi.rb?a=1&b=1
The params attribute in the CGI class contains {‘a’=>‘1’, ‘b’=>‘1’}.
However, when doing a PUT or POST to the same URL, the params hash
contains two elements, one that’s empty, and the other that is keyed on
the payload to the PUT/POST operation.
Can anyone see my error?
Thanks!
-Trevor Elliott
#!/usr/bin/ruby
CGI script
require ‘cgi’
require ‘stringio’
cgi = CGI.new
cgi.out(‘type’ => ‘text/plain’) {
$stderr.write(“handling #{cgi.request_method} request”)
cgi.params.inject(StringIO.new) { |out,value|
value.each { |item| out << 'Item: ’ << item << “\n” }
out
}.string
}
#!/usr/bin/env ruby
Test script
uses the ruby-json gem
require ‘net/http’
require ‘uri’
require ‘rubygems’
require ‘json/objects’
host = URI.parse(‘http://127.0.0.1:8080/cgi-bin/cgi.rb?thing=1’)
req = Net::HTTP::Put.new(host.path + ‘?’ + host.query)
req.body = {:id => 1, :name => ‘test’}.to_json
req.set_content_type(‘text/plain’)
puts req.body
puts req.path
res = Net::HTTP.new(host.host, host.port).start { |http|
http.request(req)
}
puts res.body
Trevor Elliott wrote:
The params attribute in the CGI class contains {‘a’=>‘1’, ‘b’=>‘1’}.
However, when doing a PUT or POST to the same URL, the params hash
contains two elements, one that’s empty, and the other that is keyed on
the payload to the PUT/POST operation.
Can anyone see my error?
There is no error, Ruby’s CGI module ignores the query string when the
method isn’t GET. AFAIK, this is correct behaviour, you put all query
parameters into the body of the request when using POST - no idea about
PUT, that method only sees use with REST, which has been of only passing
interest to me. [insert rant about HTTP flawedness and bending over
business logic backwards to be stateless here]
Either redo the client code to use the proper way of passing the query
string to the application, or redo the CGI script to manually parse the
request string for the query string. The CGI module should have some
functionality for that.
Also, see http://www.w3.org/Provider/Style/URI for why “/cgi-bin/” and
“.rb” are bad, bad things to put in your URL.
David V.
PUT, that method only sees use with REST, which has been of only passing
interest to me. [insert rant about HTTP flawedness and bending over
business logic backwards to be stateless here]
David V.
I had my suspicions after I posted the question, so thanks for
confirming
them Given that this behavior had worked for me previously in other
situations, I just expected it to work here; I’ll rethink my interaction
with the server.
-trevor elliott