Rack::Request - how do I get all headers?

Viewed 27308

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

3 Answers

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']
Related