Net::HTTP 强制标头满足大小写和标点符号方面的规范。您可以通过多种方式对其进行猴子修补(取决于 Net::HTTP 的版本),但这些解决方案目前都相当陈旧。无论如何,对第三方库进行猴子修补会导致灾难。
任何依赖 Net::HTTP 的客户端(例如 HTTParty)都有同样的问题。您可以在以下位置阅读其中一些解决方法:https://github.com/jnunemaker/httparty/issues/406 https://github.com/jnunemaker/httparty/issues/406,但我再次不推荐它们。
您可以阅读有关 HTTP 标头中下划线问题的更多信息:为什么我的自定义标头有时不存在? https://stackoverflow.com/q/58292976/3784008 and 为什么 HTTP 服务器禁止 HTTP 标头名称中使用下划线 https://stackoverflow.com/q/22856136/3784008.
更简单的解决方案是使用typhoeus https://github.com/typhoeus/typhoeus它包装了 libcurl 而不是依赖于 Net::HTTP。以下是斑疹伤寒如何发挥作用的最快演示:
require 'typhoeus'
request = Typhoeus.get('www.example.com', headers: {'foo_bar' => 'baz'})
=> #<Typhoeus::Response:0x00007fdf3aa717e8 @options={:httpauth_avail=>0, :total_time=>0.336714, :starttransfer_time=>0.336496, :appconnect_time=>0.0, :pretransfer_time=>0.26573, :connect_time=>0.265662, :namelookup_time=>0.00133, :redirect_time=>0.0, :effective_url=>"www.example.com", :primary_ip=>"93.184.216.34", :response_code=>200, :request_size=>129, :redirect_count=>0, :return_code=>:ok, :response_headers=>"HTTP/1.1 200 OK\r\nAge: 459799\r\nCache-Control: max-age=604800\r\nContent-Type: text/html; charset=UTF-8\r\nDate: Tue, 24 Mar 2020 21:29:22 GMT\r\nEtag: \"3147526947+ident\"\r\nExpires: Tue, 31 Mar 2020 21:29:22 GMT\r\nLast-Modified: Thu, 17 Oct 2019 07:18:26 GMT\r\nServer: ECS (ord/4CD5)\r\nVary: Accept-Encoding\r\nX-Cache: HIT\r\nContent-Length: 1256\r\n\r\n", :response_body=>"<!doctype html>\n<html>\n<head>\n <title>Example Domain</title>\n\n <meta charset=\"utf-8\" />\n <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <style type=\"text/css\">\n body {\n background-color: #f0f0f2;\n margin: 0;\n padding: 0;\n font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n \n }\n div {\n width: 600px;\n margin: 5em auto;\n padding: 2em;\n background-color: #fdfdff;\n border-radius: 0.5em;\n box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n }\n a:link, a:visited {\n color: #38488f;\n text-decoration: none;\n }\n @media (max-width: 700px) {\n div {\n margin: 0 auto;\n width: auto;\n }\n }\n </style> \n</head>\n\n<body>\n<div>\n <h1>Example Domain</h1>\n <p>This domain is for use in illustrative examples in documents. You may use this\n domain in literature without prior coordination or asking for permission.</p>\n <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n", :debug_info=>#<Ethon::Easy::DebugInfo:0x00007fdf3b3dbf40 @messages=[]>}, @request=#<Typhoeus::Request:0x00007fdf3aa72c60 @base_url="www.example.com", @original_options={:headers=>{"foo_bar"=>"baz"}, :method=>:get}, @options={:headers=>{"User-Agent"=>"Typhoeus - https://github.com/typhoeus/typhoeus", "foo_bar"=>"baz", "Expect"=>""}, :method=>:get, :maxredirs=>50}, @on_progress=[], @on_headers=[], @response=#<Typhoeus::Response:0x00007fdf3aa717e8 ...>, @on_complete=[], @on_success=[]>>
然后验证请求中的标头是否设置正确:
request.request.options[:headers]
=> {
"User-Agent" => "Typhoeus - https://github.com/typhoeus/typhoeus",
"foo_bar" => "baz",
"Expect" => ""
}
但即便如此,请注意可能正在处理这些标头的完整堆栈,因为下划线有时对于堆栈中的各个组件仍然存在问题。
我之前回答过一次类似的问题https://stackoverflow.com/a/58459132/3784008 https://stackoverflow.com/a/58459132/3784008.