Rack::Lint Content-Length header error with unicorn/nginx #309

Closed
activestylus opened this Issue Jan 9, 2012 · 4 comments

Projects

None yet

2 participants

@activestylus

I am getting the following error on a GET request

127.0.0.1 - - [09/Jan/2012 23:49:56] "GET /cms/sites/myapp/estimates HTTP/1.0" 200 10674 1.3752
E, [2012-01-09T23:49:56.062346 #13053] ERROR -- : app error: Content-Length header was 10674, but should be 10692 (Rack::Lint::LintError)
E, [2012-01-09T23:49:56.062445 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/gems/rack-1.3.6/lib/rack/lint.rb:19:in `assert'
E, [2012-01-09T23:49:56.062482 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/gems/rack-1.3.6/lib/rack/lint.rb:501:in `verify_content_length'
E, [2012-01-09T23:49:56.062517 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/gems/rack-1.3.6/lib/rack/lint.rb:525:in `each'
E, [2012-01-09T23:49:56.062545 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/gems/rack-1.3.6/lib/rack/body_proxy.rb:23:in `method_missing'
E, [2012-01-09T23:49:56.062583 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/gems/unicorn-4.1.1/lib/unicorn/http_response.rb:41:in `http_response_write'
E, [2012-01-09T23:49:56.062612 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/gems/unicorn-4.1.1/lib/unicorn/http_server.rb:536:in `process_client'
E, [2012-01-09T23:49:56.062642 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/gems/unicorn-4.1.1/lib/unicorn/http_server.rb:600:in `worker_loop'
E, [2012-01-09T23:49:56.062675 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/gems/unicorn-4.1.1/lib/unicorn/http_server.rb:485:in `spawn_missing_workers'
E, [2012-01-09T23:49:56.062719 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/gems/unicorn-4.1.1/lib/unicorn/http_server.rb:135:in `start'
E, [2012-01-09T23:49:56.062754 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/gems/unicorn-4.1.1/bin/unicorn:121:in `<top (required)>'
E, [2012-01-09T23:49:56.062784 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/bin/unicorn:19:in `load'
E, [2012-01-09T23:49:56.062812 #13053] ERROR -- : /Users/me/.rvm/gems/ruby-1.9.3-p0@myapp/bin/unicorn:19:in `<main>'

As you can see the page is loading just fine with a 200 status, but the logger is bugging out with the content-header length. For completeness sake here are the relevant config files

config/unicorn.rb

if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm')
  begin
    rvm_path     = File.dirname(File.dirname(ENV['MY_RUBY_HOME']))
    rvm_lib_path = File.join(rvm_path, 'lib')
    $LOAD_PATH.unshift rvm_lib_path
    require 'rvm'
  rescue LoadError
    raise "The RVM Ruby library is not available."
  end
end

ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', File.dirname(__FILE__))
require 'bundler/setup'

APP_PATH = if ENV['RACK_ENV'] == 'production'
  "/home/me/www/myapp/current"
else
  "~/apps/myapp"
end

working_directory APP_PATH
listen "#{APP_PATH}/tmp/sockets/unicorn.sock", :backlog => 64
listen 8080, :tcp_nopush => true
timeout 30

preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
  GC.copy_on_write_friendly = true

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

nginx.conf

upstream myapp {
   server unix:/Users/me/apps/myapp/tmp/sockets/unicorn.sock fail_timeout=0;
 }

 server {
   server_name www.myapp.local;
   rewrite ^ $scheme://myapp.local$request_uri redirect;
 }

 server {
   server_name myapp.local;
   listen 80;
   client_max_body_size 4G;

   keepalive_timeout 5;

   root /Users/me/apps/myapp/public;

   location / {
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header Host $http_host;
     proxy_redirect off;

     if (!-f $request_filename) {
       proxy_pass http://myapp;
       break;
     }
   }

   error_page 500 502 503 504 /500.html;
   location = /500.html {
     root /Users/me/apps/myapp/public;
   }
 }

Versions

• Ruby 1.9.3-p0
• Rails 3.1.3
• Rack 1.3.6
• nginx 1.0.10

I hope that's enough info to illuminate the issue. Let me know if you need anything else

@lgierth
Contributor
lgierth commented Jan 9, 2012

Did you verify that Rack::Lint's error message is incorrect and your Content-Length header matches the length of the response's body?

@activestylus

Not sure if I did this right but throwing debug request.headers['CONTENT_LENGTH'].to_i into my view gives me 0

@lgierth
Contributor
lgierth commented Jan 9, 2012

In your case Rack::Lint is complaining about the response, not the request ;) It checks if the response' Content-Length header matches the response body's length. If the two don't match, the error you experience is totally correct.

@activestylus

Ok so it turns out I needed to be more explicit in my config.ru

use Rack::ContentType, "text/html"
use Rack::ContentLength

Rebooted and all is well. Thanks for your prompt responses!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment