From: Mihai Danila Date: 2007-04-04T04:39:43+09:00 Subject: net/http bugs ------=_Part_17300_1066367.1175629179532 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline I noticed a while back a few limitations in the Ruby net/http library. First, the implementation bluntly ignores a crucial part of the HTTP protocol, that is, the fact that a parameter may appear multiple times in a request string. Using a hash behind the scenes, keyed by parameter name, Ruby in effect forces a single occurrence of any individual parameter. To bypass, I had to do: module Net class HTTP def HTTP.querystring(params, sep = '&') if params.keys.length > 0 p = params.keys.sort.collect do |k| q = params[k].collect { |v| CGI.escape(k) + '=' + CGI.escape(v) } q = [ CGI.escape(k) + '=' ] if params[k] == "" q.join(sep) end p.join(sep) else nil end end end module HTTPHeader def set_form_data(params, sep = '&') self.body = Net::HTTP.querystring(params, sep) self.content_type = 'application/x-www-form-urlencoded' end alias form_data= set_form_data end end # Client code. uri = URI.parse(server) + path http = Net::HTTP.new(uri.host, uri.port) uri = uri.to_s http.start do |http| http.read_timeout = @read_timeout if method == 'GET' if params.length > 0 params = Net:: HTTP.querystring(params) uri = "#{uri}?#{params}" end q = Net::HTTP::Get.new(uri) else q = Net::HTTP::Post.new(uri) q.form_data = params end Second, I had to overwrite HTTP.post_form_with_timeout for it to work correctly. (I forget what the actual bug was, but while I'm at it) module Net class HTTP def HTTP.post_form_with_timeout(url, params, read_timeout) req = Post.new(url.path) req.form_data = params req.basic_auth url.user, url.password if url.user new(url.host, url.port).start {|http| http.read_timeout = read_timeout http.request(req) } end end end What is the status of these issues? I used ruby184-16p3.exe on WinXP. Mihai ------=_Part_17300_1066367.1175629179532 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline I noticed a while back a few limitations in the Ruby net/http library.

First, the implementation bluntly ignores a crucial part of the HTTP protocol, that is, the fact that a parameter may appear multiple times in a request string. Using a hash behind the scenes, keyed by parameter name, Ruby in effect forces a single occurrence of any individual parameter. To bypass, I had to do:

module Net
  class HTTP
    def HTTP.querystring(params, sep = '&')
      if params.keys.length > 0
        p = params.keys.sort.collect do |k|
          q = params[k].collect { |v| CGI.escape(k) + '=' + CGI.escape(v) }
          q = [ CGI.escape(k) + '=' ] if params[k] == ""
          q.join(sep)
        end
        p.join(sep)
      else
        nil
      end
    end
  end

  module HTTPHeader
    def set_form_data(params, sep = '&')
      self.body = Net::HTTP.querystring(params, sep)
      self.content_type = 'application/x-www-form-urlencoded'
    end
    alias form_data= set_form_data
  end
end

    # Client code.
    uri = URI.parse(server) + path
    http = Net::HTTP.new(uri.host, uri.port)
    uri = uri.to_s
    http.start do |http|
      http.read_timeout = @read_timeout
      if method == 'GET'
        if params.length > 0
          params = Net:: HTTP.querystring(params)
          uri = "#{uri}?#{params}"
        end
        q = Net::HTTP::Get.new(uri)
      else
        q = Net::HTTP::Post.new(uri)
        q.form_data = params
      end


Second, I had to overwrite HTTP.post_form_with_timeout for it to work correctly. (I forget what the actual bug was, but while I'm at it)

module Net
  class HTTP
    def HTTP.post_form_with_timeout(url, params, read_timeout)
      req = Post.new(url.path)
      req.form_data = params
      req.basic_auth url.user, url.password if url.user
      new(url.host, url.port).start {|http|
        http.read_timeout = read_timeout
        http.request(req)
      }
    end
  end
end

What is the status of these issues?

I used ruby184-16p3.exe on WinXP.


Mihai

------=_Part_17300_1066367.1175629179532--