本文介绍了使用 Ruby 的 Net:HTTP 在 HTTP 标头中保留大小写的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Although the HTTP spec says that headers are case insensitive; Paypal, with their new adaptive payments API require their headers to be case-sensitive.

使用 ActiveMerchant 的 paypal 自适应支付扩​​展 (http://github.com/lamp/paypal_adaptive_gateway) 好像虽然headers都是大写的,但是都是大小写混合发送的.

Using the paypal adaptive payments extension for ActiveMerchant (http://github.com/lamp/paypal_adaptive_gateway) it seems that although the headers are set in all caps, they are sent in mixed case.

这是发送 HTTP 请求的代码:

Here is the code that sends the HTTP request:

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

(我添加了代理行,所以我可以看到 Charles 发生了什么 - http://www.charlesproxy.com/)

(i added the proxy line so i could see what was going on with Charles - http://www.charlesproxy.com/)

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

When I look at the request headers in charles, this is what i see:

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

我通过使用 curl 运行类似的请求来验证不是 Charles 进行大小写转换.在那个测试中,这个案例被保留了下来.

I verified that it is not Charles doing the case conversion by running a similar request using curl. In that test the case was preserved.

推荐答案

使用以下代码强制区分大小写的标头.

Use following code to force case sensitive headers.

class CaseSensitivePost < Net::HTTP::Post
  def initialize_http_header(headers)
    @header = {}
    headers.each{|k,v| @header[k.to_s] = [v] }
  end

  def [](name)
    @header[name.to_s]
  end

  def []=(name, val)
    if val
      @header[name.to_s] = [val]
    else
      @header.delete(name.to_s)
    end
  end

  def capitalize(name)
    name
  end
end

使用示例:

post = CaseSensitivePost.new(url, {myCasedHeader: '1'})
post.body = body
http = Net::HTTP.new(host, port)
http.request(post)

这篇关于使用 Ruby 的 Net:HTTP 在 HTTP 标头中保留大小写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 12:21
查看更多