Rack::Request - 如何获取所有标头?

发布于 2024-11-14 21:57:49 字数 67 浏览 1 评论 0原文

标题是非常不言自明的。有什么方法可以获取标头(Rack::Request.env[] 除外)?

The title is pretty self-explanatory. Is there any way to get the headers (except for Rack::Request.env[])?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风透绣罗衣 2024-11-21 21:57:49

HTTP 标头可在传递给您的应用的机架环境中使用:

HTTP_ 变量:与客户端提供的 HTTP 请求标头相对应的变量(即名称以 HTTP_ 开头的变量)。这些变量的存在或不存在应与请求中相应的 HTTP 标头的存在或不存在相对应。

因此,HTTP 标头以“HTTP_”为前缀并添加到哈希中。

这是一个提取并显示它们的小程序:

require 'rack'

app = Proc.new do |env|
  headers = env.select {|k,v| k.start_with? 'HTTP_'}
    .collect {|key, val| [key.sub(/^HTTP_/, ''), val]}
    .collect {|key, val| "#{key}: #{val}<br>"}
    .sort
  [200, {'Content-Type' => 'text/html'}, headers]
end

Rack::Server.start :app => app, :Port => 8080

当我运行这个程序时,除了 Chrome 或 Firefox 显示的 HTTP 标头之外,还有一个“版本:HTPP/1.1”(即带有键“HTTP_VERSION”和值“ HTTP/1.1”被添加到 env 哈希中)。

The HTTP headers are available in the Rack environment passed to your app:

HTTP_ Variables: Variables corresponding to the client-supplied HTTP request headers (i.e., variables whose names begin with HTTP_). The presence or absence of these variables should correspond with the presence or absence of the appropriate HTTP header in the request.

So the HTTP headers are prefixed with "HTTP_" and added to the hash.

Here's a little program that extracts and displays them:

require 'rack'

app = Proc.new do |env|
  headers = env.select {|k,v| k.start_with? 'HTTP_'}
    .collect {|key, val| [key.sub(/^HTTP_/, ''), val]}
    .collect {|key, val| "#{key}: #{val}<br>"}
    .sort
  [200, {'Content-Type' => 'text/html'}, headers]
end

Rack::Server.start :app => app, :Port => 8080

When I run this, in addition to the HTTP headers as shown by Chrome or Firefox, there is a "VERSION: HTPP/1.1" (i.e. an entry with key "HTTP_VERSION" and value "HTTP/1.1" is being added to the env hash).

眼睛会笑 2024-11-21 21:57:49

基于@matt的答案,但这确实为您提供了问题中所要求的哈希中的请求标头:

headers = Hash[*env.select {|k,v| k.start_with? 'HTTP_'}
  .collect {|k,v| [k.sub(/^HTTP_/, ''), v]}
  .collect {|k,v| [k.split('_').collect(&:capitalize).join('-'), v]}
  .sort
  .flatten]

根据您喜欢的键约定,您可能想要使用其他内容而不是 :capitalize。

Based on @matt's answer, but this really gives you the request headers in a hash as requested in the question:

headers = Hash[*env.select {|k,v| k.start_with? 'HTTP_'}
  .collect {|k,v| [k.sub(/^HTTP_/, ''), v]}
  .collect {|k,v| [k.split('_').collect(&:capitalize).join('-'), v]}
  .sort
  .flatten]

Depending on what key convention you prefer you might want to use something else instead of :capitalize.

吻安 2024-11-21 21:57:49

就像@Gavriel的答案,但使用 transform_keys (更简单):

class Request
  def headers
    env.select { |k,v| k.start_with? 'HTTP_'}.
      transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') }
  end
end

您甚至可以使其即使大小写不同,查找仍然有效:

  def headers
    env.
      select { |k,v| k.start_with? 'HTTP_'}.
      transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') }.
      sort.to_h.
      tap do |headers|
        headers.define_singleton_method :[] do |k|
          super(k.split(/[-_]/).map(&:capitalize).join('-'))
        end
      end
  end

例如,即使 headers 标准化键,因此它返回以下内容:

{
  Dnt: '1',
  Etag: 'W/"ec4454af5ae1bacff1afc5a06a2133f4"',
  'X-Xss-Protection': '1; mode=block',
}

您仍然可以使用这些标头的更自然/常见名称来查找标头:

headers['DNT']
headers['ETag']
headers['X-XSS-Protection']

Like @Gavriel's answer, but using transform_keys (simpler):

class Request
  def headers
    env.select { |k,v| k.start_with? 'HTTP_'}.
      transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') }
  end
end

You can even make it so lookups still work even if the case is different:

  def headers
    env.
      select { |k,v| k.start_with? 'HTTP_'}.
      transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') }.
      sort.to_h.
      tap do |headers|
        headers.define_singleton_method :[] do |k|
          super(k.split(/[-_]/).map(&:capitalize).join('-'))
        end
      end
  end

So for example, even if headers normalizes the keys so it returns this:

{
  Dnt: '1',
  Etag: 'W/"ec4454af5ae1bacff1afc5a06a2133f4"',
  'X-Xss-Protection': '1; mode=block',
}

you can still look up headers using the more natural/common names for these headers:

headers['DNT']
headers['ETag']
headers['X-XSS-Protection']
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文