title: Preserving case in HTTP headers with Ruby's Net:HTTP
body: <p>Although the HTTP spec says that headers are case insensitive; Paypal, with their new adaptive payments API require their headers to be case-sensitive.</p>
  
  <p>Using the paypal adaptive payments extension for ActiveMerchant (<a href="http://github.com/lamp/paypal_adaptive_gateway" rel="nofollow noreferrer">http://github.com/lamp/paypal_adaptive_gateway</a>) it seems that although the headers are set in all caps, they are sent in mixed case.</p>
  
  <p>Here is the code that sends the HTTP request:</p>
  
  <pre><code>headers = {
    "X-PAYPAL-REQUEST-DATA-FORMAT" =&gt; "XML",
    "X-PAYPAL-RESPONSE-DATA-FORMAT" =&gt; "JSON",
    "X-PAYPAL-SECURITY-USERID" =&gt; @config[:login],
    "X-PAYPAL-SECURITY-PASSWORD" =&gt; @config[:password],
    "X-PAYPAL-SECURITY-SIGNATURE" =&gt; @config[:signature],
    "X-PAYPAL-APPLICATION-ID" =&gt; @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
  </code></pre>
  
  <p>(i added the proxy line so i could see what was going on with Charles - <a href="http://www.charlesproxy.com/" rel="nofollow noreferrer">http://www.charlesproxy.com/</a>)</p>
  
  <p>When I look at the request headers in charles, this is what i see:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>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.</p>