Сохранение регистра в заголовках HTTP с помощью Ruby's Net: HTTP - PullRequest
3 голосов
/ 26 апреля 2010

Хотя в спецификации HTTP говорится, что заголовки нечувствительны к регистру; Paypal с их новым API адаптивных платежей требует, чтобы в их заголовках учитывался регистр.

Используя расширение адаптивных платежей PayPal для ActiveMerchant (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

(я добавил прокси-строку, чтобы я мог видеть, что происходит с Чарльзом - 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

Я проверил, что это не Чарльз делает преобразование дела, выполнив аналогичный запрос с помощью curl. В этом тесте дело было сохранено.

Ответы [ 2 ]

2 голосов
/ 26 апреля 2010

В RFC указано, что ключи заголовка не чувствительны к регистру , поэтому, к сожалению, вы столкнулись с раздражающим требованием с помощью API PayPal.

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

"Устанавливает поле заголовка, соответствующее ключу без учета регистра."

Поскольку приведенный выше простой класс, он может быть залатан обезьяной. Я подумаю дальше для лучшего решения.

1 голос
/ 17 октября 2017

Используйте следующий код для принудительного ввода регистрозависимых заголовков.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...