Add additional documentation on Headers#[] [ci skip]

Issue #16519 covers confusion potentially caused by how HTTP
headers, that contain underscores in their names, are retrieved
through `ActionDispatch::Http::Headers#[]`.

This confusion has its origin in how a CGI maps HTTP header names
to variable names. Even though underscores in header names
are rarely encountered, they are valid according to RFC822 [1].
Nonetheless CGI like variable names, as requested by the Rack
specfication, will only contain underscores and therefore the
original header name cannot be recovered after the Rack server passed
on the environemnt hash. Please, see also the disscussion on
StackOverflow [2], which also links to an explaination in the
nginx documentation [3].

[1] http://www.ietf.org/rfc/rfc822.txt
[2] http://stackoverflow.com/questions/22856136/why-underscores-are-forbidden-in-http-header-names
[3] https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#missing-disappearing-http-headers
This commit is contained in:
Tawan Sierek 2016-01-29 21:01:33 +01:00
parent e6d0d4b1ae
commit 349f187f58
1 changed files with 15 additions and 1 deletions

View File

@ -2,9 +2,23 @@ module ActionDispatch
module Http
# Provides access to the request's HTTP headers from the environment.
#
# env = { "CONTENT_TYPE" => "text/plain" }
# env = { "CONTENT_TYPE" => "text/plain", "HTTP_USER_AGENT" => "curl/7.43.0" }
# headers = ActionDispatch::Http::Headers.new(env)
# headers["Content-Type"] # => "text/plain"
# headers["User-Agent"] # => "curl/7/43/0"
#
# Also note that when headers are mapped to CGI-like variables by the Rack
# server, both dashes and underscores are converted to underscores. This
# ambiguity cannot be resolved at this stage anymore. Both underscores and
# dashes have to be interpreted as if they were originally sent as dashes.
#
# # GET / HTTP/1.1
# # ...
# # User-Agent: curl/7.43.0
# # X_Custom_Header: token
#
# headers["X_Custom_Header"] # => nil
# headers["X-Custom-Header"] # => "token"
class Headers
CGI_VARIABLES = Set.new(%W[
AUTH_TYPE