Request headers name normalization

I believe, there’s inconsistency between how Rails and curl normalize header names.

If I do a curl -H "some_header: value" it will send the header as HTTP_SOME_HEADER. Then in Rails controller I would expect that header to be accessible as request.headers[:some_header], but it’s not. The culprit is in the [ActionDispatch::Http::Headers#env_name](, which doesn’t adjust the header name if it contains an underscore.

Which of the two is correct? Do you think the issue could addressed in Rails?

I am not sure I understand your question, but how does the headers hash look like? maybe if you show me the result will be easier to understand the mistake!

Also gives a concrete example of which headers you trying to set.

I have always done curl requests like this:

curl -i --header “Accept: application/json” --header “Content-Type: application/json”

the -i option from the manual:

-i, --include

(HTTP) Include the HTTP-header in the output. The HTTP-header includes things like server-

name, date of the document, HTTP-version and more…

so you can see the answer to your curl call.

I figured, it’s not related to curl but to Rails and Rack only.
Here’s what I do:

curl -v -H “hello_world: true” localhost:3000/empty

Now in the controller I dump the request headers and see “HTTP_HELLO_WORLD”=>“true”. Rack converted “hello_world” to “HTTP_HELLO_WORLD”.
But if I try to access the header like request.headers[:hello_world] or request.headers["hello_world"], it will return nil.

If I used ‘hello-world’ instead of ‘hello_world’ (underscore instead of dash), everything would have worked as expected.

Hello Roman,

I wrote a blog post about it a while ago:

I hope it helps.


Thanks, Anuj. I didn’t know that nginx also makes its contribution to confusion with headers.