3/02/2012

Rails 3 issue: 'Content-Length' field not exist in HTTP head when using 'send_data' method

I found this issue in one of my Rails 3 app, here is a simple demo:
class AnyController < ApplicationController
  def any_action
    send_data [SOME-BINARY-DATA]
  end
end

when browser make any request to this controller, Rails 3 app will
REMOVE your 'Content-Length' field of the HTTP response header, even
you add content-length in the logic code explicitly

To fix this, we could add a Rack middleware and plug it in to the app,
in your #{Rails.root}/config/application.rb file, find code like below:

module XX
    class Application < Rails::Application
        config.middleware.use "HttpHeaderFix" # add this line

then create a file named 'http_header_fix.rb' at #{Rails.root}/middleware

class HttpHeaderFix
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    if headers["Content-Type"] == "application/octet-stream"
      if headers["Content-Length"].blank?
        if response.respond_to? :length
          length = response.length
        elsif response.respond_to? :count
          length = response.count
        elsif response.respond_to? :size
          length = response.size
        elsif response.respond_to? :body
          length = response.body.length
        else
          raise "unknown response: #{response.class}"
        end
        headers["Content-Length"] = length.to_s
      end
    end
    [status, headers, response]
  end
end
OK, there you go!!

1 comments:

Anonymous said...

Thank you! Do you why rails does that?