Search code examples
sinatrarack

Overriding Content-Length header with Rack/Sinatra


In Sinatra, how can I override the Content-Length header in the response to set my own value?

The last line in my method returns the following:

[200, {'Content-Type' => component.content_type,
'Content-Length' => component.content_length.to_s}, component.content.data]

This way I was hoping to override the content value, but it results in an exception:

Unexpected error while processing request: Content-Length header was 2, but should be 0

I would like to return a different value for the content length. Is there a way to do this?


Solution

  • This error is being raised by the Rack::Lint middleware, so the quick fix would be to not use that piece of middleware. Depending on how you are starting your application that may be tricky though – Rack adds it in certain cases if you use rackup.

    A better solution would be to change your client to use a HTTP HEAD request rather than a GET. In Sinatra defining a GET route automatically defines a matching HEAD route. Using HEAD will cause the server to send the headers but not the body, and you should be able to set the Content-Length to whatever you want. It will also avoid the Rack::Lint error.

    Here is a gist explaining how to disable Rack::Lint:

    module Rack
      class Lint
        def call(env = nil)
          @app.call(env)
        end
      end
    end
    

    (Taken from https://gist.github.com/shtirlic/2146256).