views:

525

answers:

1

Rails provides a request.headers method that returns both all headers and a lot of extra non-header information... i would like to access only the request headers, how can I do so?

Regards

+2  A: 

You essentially have to isolate all environment entries which are prefixed with HTTP_ or CONTENT_, which correspond to your HTTP headers, e.g:

# CONTENT_LENGTH -> Content-Length
# HTTP_COOKIE -> Cookie
# HTTP_USER_AGENT -> User-Agent
@headers |= request.env.inject({}) { |h, (k, v)|
  if k =~ /^(HTTP|CONTENT)_/ then
    h[k.sub(/^HTTP_/, '').dasherize.gsub(/([^\-]+)/) { $1.capitalize }] = v 
  end
  h
}

Alternatively, you can be more restrictive and only look for specific HTTP headers in order to avoid accidentally picking up environment variables that may look like headers but are not actually valid such as CONTENT_BLA or HTTP_DUMMY.

@headers |= %w[ CONTENT_LENGTH CONTENT_TYPE HTTP_ACCEPT
HTTP_REFERER HTTP_USER_AGENT ].inject({}) { |h, k|
  if v = request.env[k] then
    h[k.sub(/^HTTP_/, '').dasherize.gsub(/([^\-]+)/) { $1.capitalize }] = v 
  end
  h
}

Take a look at actionpack/lib/action_controller/request.rb to see how they comb the environment to extract request headers.

vladr
I can't actually go for the second one because all http headers (i.e. extended headers) are unknown to the server. Those headers, as X-Runtime, will appear as env HTTP_X-RUNTIME?Regards
Guilherme Silveira
That would be `HTTP_X_RUNTIME` in the environment, and `X-Runtime` in the resulting `@headers` hash. The second snippet only uses a "white list" of headers that could be interesting to you (to filter out uninteresting stuff); if something on the whitelist isn't actually present in your environment, it does not get added to `@headers`; also the other way around, if it's in the environment but not on the whitelist it does not get added to `@headers`.
vladr
Thanks Vlad... ill go with the first option: I need all request headers - even those I am unaware of, so I cant go with a white list.
Guilherme Silveira