Search code examples
rubysinatrarack

Sinatra request["SOME_HEADER"] doesn't work on POST; doc bug?


The Sinatra README says:

request["SOME_HEADER"]      # value of SOME_HEADER header

Given this app:

require 'sinatra'

post '/env' do
    env['HTTP_X_FOO']
end

post '/request' do 
    request['X-Foo']
end

post '/request_rack_http_format' do
    request['HTTP_X_FOO']
end

The first spec passes; the next two fail:

describe "Sinatra should place the header in" do
    before(:all) do
        header 'X-Foo', 'Bar'
    end

    example "env" do
        post '/env'
        last_response.body.should == 'Bar' #pass
    end

    example "request[]" do
        post '/request'
        last_response.body.should == 'Bar' #fail; got ""
    end

    example "request[] (rack format)" do
        post '/request_rack_http_format'
        last_response.body.should == 'Bar' #fail; got ""
    end
end

Looking at the source, Sinatra doesn't actually do anything with []; it's implemented in Rack as the union of GET and POST. And POST just returns the form hash. For GET it's the query hash. In all three routes, request.params is empty.

My question: Is this a doc bug, or am I misunderstanding how to use request[]? For now, my application is working fine with the env[] method. But I want to do it "right."


Solution

  • Seems to be a bug in the documentation. request[] actually retrieves the params for the request, not the header:

    https://github.com/rack/rack/blob/master/lib/rack/request.rb#L262

    def [](key)
      params[key.to_s]
    end
    

    I double checked it by testing also. Seems a bit silly, but it looks like you really can't directly access the header in any way except through env. At least I could not figure out any other way.