6

在 Ruby 中,在实际发出请求之前,如何获取将由 net/http(s) 或 open-uri 请求发送的 HTTP 请求标头。

在某些情况下,在 URI 中创建签名字符串时会使用标头。当然,有一些方法可以获取将要发送的请求标头。例如,这些应包括“主机:”标头。

4

3 回答 3

7

http://ruby-doc.org/stdlib-2.0/libdoc/net/http/rdoc/Net/HTTP.html#label-Setting+Headers

在 ruby​​ 2.0.0 中运行良好 - 但你是正确的,在 1.9.3 中的行为不同

红宝石 2.0.0

require 'net/http'
uri = URI('http://github.com/ruby')

http_request = Net::HTTP::Get.new(uri)
http_request.each_header { |header| puts header }

# => accept-encoding
# => accept
# => user-agent
# => host    

http_response = Net::HTTP.start(uri.hostname, uri.port) do |http|
  http.request(http_request)
end

红宝石 1.9.3

require 'uri'
require 'net/http'
uri = URI.parse('http://github.com/ruby')

http_request = Net::HTTP::Get.new(uri.path)
http_request.each_header { |header| puts header }

# => accept
# => user-agent

http_response = Net::HTTP.start(uri.hostname, uri.port) do |http|
  http.request(http_request)
end

http_request.each_header { |header| puts header }

# => accept
# => user-agent
# => host
于 2013-07-27T17:00:45.073 回答
3

Net::HTTP 类似乎都使用 Net::HTTPHeader 作为 mixin。您应该能够在请求对象上使用to_hash()一次获取所有标头,或者使用 each_header() / each()一次迭代一个标头。

于 2013-07-27T16:56:38.157 回答
0

这是我写的一些代码来提供帮助。

def get_request_headers(request)
  http_method = request.method
  path = request.path

  request.to_hash.merge("method" => [http_method]).merge("path" => [path])
end

所以现在,你可以运行这样的东西。

url = URI("http://www.google.com")

request, response = Net::HTTP.start(uri(ico).host) do |http|
  request = Net::HTTP::Get.new(uri(ico))
  response = http.request request

  [request, response]
end

get_request_headers(request)
=> {"accept-encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"], "accept"=>["*/*"], "user-agent"=>["Ruby"], "host"=>["www.google.com"], "method"=>["GET"], "path"=>["/"]}

request.to_hash免费为我们提供一些标头,但在请求和响应类的实例变量中存储了更多信息。

使用以下代码,您可以检查是否有任何其他内容要合并到基本请求哈希中。

request.instance_variables.each do |variable|
  puts "#{variable}: #{request.instance_variable_get(variable)}"
end

=> @method: GET
=> @request_has_body: false
=> @response_has_body: true
=> @uri: http://www.google.com
=> @path: /
=> @decode_content: true
=> @header: {"accept-encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"], "accept"=>["*/*"], "user-agent"=>["Ruby"], "host"=>["www.google.com"]}
=> @body: 
=> @body_stream: 
=> @body_data: 
=> [:@method, :@request_has_body, :@response_has_body, :@uri, :@path, :@decode_content, :@header, :@body, :@body_stream, :@body_data]

请注意,我已经为该方法提取了methodand 。pathget_request_headers

最后,您可以对响应执行相同的操作。

def get_response_headers(response)
  code = response.code
  http_version = response.http_version
  message = response.message

  response.to_hash.merge("code" => [code]).merge("http_version" => [http_version]).merge("message" => [message])
end

get_response_headers(response)
=> {"date"=>["Thu, 06 May 2021 14:34:27 GMT"], "expires"=>["-1"], "cache-control"=>["private, max-age=0"], "content-type"=>["text/html; charset=ISO-8859-1"], "p3p"=>["CP=\"This is not a P3P policy! See g.co/p3phelp for more info.\""], "server"=>["gws"], "content-length"=>["6067"], "x-xss-protection"=>["0"], "x-frame-options"=>["SAMEORIGIN"], "set-cookie"=>["NID=215=dYowhmNSD9_CnKYLtsFI3uWVGy8ca8PKJTE8VY6_92q7tU5Y_AOWLsaabXxlSPBjc2QjOr4xXVX5SGMCrccTCnBR9pbdsKkrpVTV5TMqrV6H09ChxGjBr5mHVdZkgjOxswiXu72TF3eAX0uhXqloDb-5gmZ6NJ4w1YDKQKNoDp4; expires=Fri, 05-Nov-2021 14:34:27 GMT; path=/; domain=.google.com; HttpOnly"], "code"=>["200"], "http_version"=>["1.1"], "message"=>["OK"]}
于 2021-05-06T14:42:12.817 回答