使用 Ruby 的 Net:HTTP 保留 HTTP 标头中的大小写

emh*_*emh 5 ruby networking paypal http

尽管 HTTP 规范规定标头不区分大小写;Paypal 及其新的自适应支付 API 要求其标头区分大小写。

使用 ActiveMerchant 的 paypal 自适应支付扩​​展 ( http://github.com/lamp/paypal_adaptive_gateway ) 似乎虽然标头全部设置为大写,但它们以混合大小写发送。

下面是发送 HTTP 请求的代码:

headers = {
  "X-PAYPAL-REQUEST-DATA-FORMAT" => "XML",
  "X-PAYPAL-RESPONSE-DATA-FORMAT" => "JSON",
  "X-PAYPAL-SECURITY-USERID" => @config[:login],
  "X-PAYPAL-SECURITY-PASSWORD" => @config[:password],
  "X-PAYPAL-SECURITY-SIGNATURE" => @config[:signature],
  "X-PAYPAL-APPLICATION-ID" => @config[:appid]
}
build_url action

request = Net::HTTP::Post.new(@url.path)

request.body = @xml
headers.each_pair { |k,v| request[k] = v }
request.content_type = 'text/xml'

proxy = Net::HTTP::Proxy("127.0.0.1", "60723")

server = proxy.new(@url.host, 443)
server.use_ssl = true

server.start { |http| http.request(request) }.body
Run Code Online (Sandbox Code Playgroud)

(我添加了代理线,这样我就可以看到 Charles 发生了什么 - http://www.charlesproxy.com/

当我查看 charles 中的请求标头时,我看到的是:

X-Paypal-Application-Id ...
X-Paypal-Security-Password...
X-Paypal-Security-Signature ...
X-Paypal-Security-Userid ...
X-Paypal-Request-Data-Format XML
X-Paypal-Response-Data-Format JSON
Accept */*
Content-Type text/xml
Content-Length 522
Host svcs.sandbox.paypal.com
Run Code Online (Sandbox Code Playgroud)

我通过使用curl 运行类似的请求来验证这不是Charles 进行的大小写转换。在那次测试中,箱子被保存下来。

小智 3

RFC 确实指定标头键不区分大小写,因此不幸的是,您似乎遇到了 PayPal API 的烦人要求。

Net::HTTP 正在改变这种情况,尽管我很惊讶它们并没有全部变成小写:

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

“设置不区分大小写的密钥对应的头字段。”

由于上面是一个简单的类,因此可以对其进行猴子修补。我会进一步思考更好的解决方案。