6

我在 ruby​​ 中做一个 http 请求:

  http = Net::HTTP.new(uri.host, uri.port)
  req = Net::HTTP::Post.new(uri.path)
  req.body = payload
  req['customeheader'] = 'xxxxxxxxx'
  http.set_debug_output $stdout

我已经打开了调试,当请求发布时,我可以看到标题被发布为:

  Customheader: xxxxxxxxx

无论如何要阻止这个,我发布到的第三方服务器给出了一个错误,因为标题名称不正确 - 它期待customheader:

4

3 回答 3

14

虽然可以修改 Net::HTTPHeader 和 Net:HTTPGenericRequest 以删除小写和大写,但我发现了一种不同的方法,它允许选择性区分大小写而不是强制所有内容。

解决方案:

class CaseSensitiveString < String
    def downcase
        self
    end
    def capitalize
        self
    end
end

然后 CaseSensitiveString.new('keyname') 在区分大小写时创建您的密钥。对其他键使用字符串/符号来保持现有行为。这比猴子补丁要简单得多,并且可以很好地与 rest-client 库以及 Net::HTTP 一起使用。

于 2013-05-15T21:06:35.063 回答
6

根据 HTTP 规范 (RFC 2616),标头字段名称不区分大小写。所以第三方服务器的实现有问题。

如果您真的需要,您可以对 Net::HTTP 进行猴子补丁以保留大小写,因为它在存储字段名称时将其小写,然后用初始大写字母写入它们。

这是您使用的存储方法 ( Net::HTTPHeader#[]=):

# File net/http.rb, line 1160
    def []=(key, val)
      unless val
        @header.delete key.downcase
        return val
      end
      @header[key.downcase] = [val]
    end

这里是它写入标题 ( Net::HTTPGenericRequest#write_header) 的地方:

# File lib/net/http.rb, line 2071
    def write_header(sock, ver, path)
      buf = "#{@method} #{path} HTTP/#{ver}\r\n"
      each_capitalized do |k,v|
        buf << "#{k}: #{v}\r\n"
      end
      buf << "\r\n"
      sock.write buf
    end

这些可能是您需要覆盖的唯一方法,但我不是 100% 确定。

于 2012-04-21T15:02:32.240 回答
5

基于先前的答案,这将适用于 ruby​​ 2.3:

class CaseSensitiveString < String
  def downcase
    self
  end

  def capitalize
    self
  end

  def to_s
    self
  end
end

to_s需要添加该方法,因为从 2.3 开始,每个标头都会调用HTTP::Header's方法。capitalizeto_s

于 2017-02-08T18:54:37.270 回答