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

rails request headers
sinatra request headers
rack::request session
rack request
rack middleware
rack middleware example
rack middleware request object
actiondispatch request headers

The title is pretty self-explanatory. Is there any way to get the headers (except for Rack::Request.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>"}
  [200, {'Content-Type' => 'text/html'}, headers]

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).

Class: Rack::Request — Documentation for rack (2.2.3), Rack::Request provides a convenient interface to a Rack environment. It is stateless, the environment env passed to the constructor will be directly modified. A Headers object. Example In the following snippet, we create a new request using the Request.Request() constructor (for an image file in the same directory as the script), then save the request headers in a variable:

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]}

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

The Rack Env, All headers that have been part of the actual HTTP request are prefixed with HTTP and uppercased. For example the request header host: localhost:9292 will be� The getResponseHeader () method returns the value as a UTF byte sequence. Note: The search for the header name is case-insensitive. If you need to get the raw string of all of the headers, use the getAllResponseHeaders () method, which returns the entire raw header string.

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('-') }

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

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

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:


How to access request headers, Google Groups allows you to create and participate in online forums and email- based request method seems to give access only to response headers. See the Rack spec for more information on what can be included in the env Hash: Under Header or Footer, on the pop-up menu, select (none). Go to Insert > Header & Footer . On the top right side of the document, select Options > Remove Headers & Footers .

Rack::Request, All the HTTP headers in the request.env hash will have keys that are prefixed with HTTP_ ; all other keys are additional info that the webserver� How to read email full headers Open the email you want to check the headers for. Next to Reply, click More Show original. Copy the text on the page.

Unlock HTTP Info in Rails with Rack, request.env and URI, We use Rack because that allows different frameworks & servers to be interchangeable. Small Ruby programs that get called as part of the request- response cycle & get a require 'rack'; handler = Rack::Handler::Thin; class RackApp; def call(env) The HTTP headers (“Content-Type”); The contents (“ Hello from Rack”). To get started, open Outlook and click on Home > Get Add-Ins. In the search box in the top right, start typing “message header” and select the “Message Header Analyzer” add-in. Click the Add button to install the add-in. Once the add-in is installed, the Add button will change to say “Added.”

Rack Explained For Ruby Developers, rails server does the basic job of creating a Rack::Server object and starting the You will have to restart the server for changes to be reflected in the running Makes a unique X-Request-Id header available to the response and enables the � HTTP headers let the client and the server pass additional information with an HTTP request or response. An HTTP header consists of its case-insensitive name followed by a colon (:), then by its value.

  • Ah, so it's basically env anyway :). What I dislike are the upcased names with some chars replaced. Well, I guess I will have to get away with it....
  • @PJK well the names should be case insensitive anyway: w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2. What characters are being replaced? Are you trying to use characters from outside the ASCII chracter set? Header names should be ASCII only.
  • I know, it is just a matter of convenience... For instance, X-Build becomes HTTP_X_BUILD, which means X_Build and X-BUILD should be equivalent but (I've been told that) browsers differentiate between these two alternatives.
  • @PJK I see: - is being changed to _. I guess that's to remain compatible with CGI (an environment variable can't contain -). But the response headers shouldn't be affected.
  • in your example, shouldn't it be 'Dnt': '1' instead of Dnt: '1'?
  • @RonKlein Dnt: is correct. Using 'Dnt': is JSON not ruby.
  • @MarlinPierce Well it is syntactically correct Ruby but it's not what the code produces. @RonKlein is right, it should be 'Dnt': '1', The keys here are strings from start to end. Capitalized literals denote constants in Ruby.
  • @ArnaudMeuret Now, I think you are mixing up Constants and Literals. In ruby, 'Dnt': resolves to the symbol :Dnt. If you want string keys, you need { 'Dnt' => '1' }. This will show you that 'Dnt': is a symbol, { 'Dnt': '1' }.each_pair { |key, value| puts key.inspect }.
  • @ArnaudMeuret another way to see this, is that Dnt='Knock';{ 'Dnt': 1, 'Dnt' => 2, Dnt => 3 } evaluates to {:Dnt=>1, "Dnt"=>2, "Knock"=>3}.