Rack::Cache and Lighttpd+FCGI July 15th, 2009

On some of the Openminds shared hosting servers we run a Lighttpd+FCGI stack for Ruby/Rails applications. This week we got a complaint from a user saying they had a problem with the latest Radiant 0.8. Every page he loaded was the same as the first page he opened since the last server restart.

When digging into the problem it was clear that it was a problem with Rack::Cache, which only created 1 meta-store entry and served that from there on. On investigation Rack::Cache::Key.call(@request) always returned http://example.com:80/dispatch.fcgi?. Apparently the last part of the key gets created by scriptname and pathinfo:

..snip..
      parts << @request.script_name
      parts << @request.path_info
..snip..

When looking at the request it seems Lighttpd+FCGI doesn’t fill in the env[‘PATH_INFO’], which results in always having the same cache key, thus the same page.

To solve this problem I’ve created a small Rack middleware that sets PATHINFO from REQUESTURI (Like Passenger does with Nginx)

module ::Rack
  class LighttpdFix
    def initialize(app)
      @app = app
    end     

    def call(env)
      env['PATH_INFO'] = env['REQUEST_URI'].split('?', 2).first
      @app.call(env)
    end     
  end
end

# in production.rb
config.middleware.insert_before ::Rack::Cache, ::Rack::LighttpdFix

# or for Radiant
config.middleware.insert_before ::Radiant::Cache, ::Rack::LighttpdFix

I’ll make a gem out of this tomorrow.I made a gem out of this, you can find it on GitHub and install it using RubyGems.

sudo gem install DefV-rack_lighttpd_fix
tags: l

Radiant 0.7.x and Ruby 1.8.4 March 13th, 2009

A client of ours complained that Radiant 0.7.1 was not working out of the box on one of our shared servers. When running the radiant command he got an error:

/usr/lib/ruby/gems/1.8/gems/radiant-0.7.1/vendor/rails/railties/lib/initializer.rb:199:in `set_load_path': undefined method `load_paths' for nil:NilClass (NoMethodError)
  from /usr/lib/ruby/gems/1.8/gems/radiant-0.7.1/vendor/rails/railties/lib/initializer.rb:97:in `run'
  from /usr/lib/ruby/gems/1.8/gems/radiant-0.7.1/lib/radiant/initializer.rb:101:in `run'
  from /usr/lib/ruby/gems/1.8/gems/radiant-0.7.1/bin/../config/boot.rb:72:in `load_initializer'
  from /usr/lib/ruby/gems/1.8/gems/radiant-0.7.1/bin/../config/boot.rb:90:in `load_initializer'
  from /usr/lib/ruby/gems/1.8/gems/radiant-0.7.1/bin/../config/boot.rb:61:in `run'
  from /usr/lib/ruby/gems/1.8/gems/radiant-0.7.1/bin/../config/boot.rb:19:in `boot!'
  from /usr/lib/ruby/gems/1.8/gems/radiant-0.7.1/bin/../config/boot.rb:161
  from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
  from /usr/lib/ruby/gems/1.8/gems/radiant-0.7.1/bin/radiant:3
  from /usr/bin/radiant:19

It worked fine on our other servers, as well as on our local machines, the only thing that was different was the ruby version, which was 1.8.4 on that specific server. Apparently that version handles super a bit different. The solution was to change 1 line in /usr/lib/ruby/gems/1.8/gems/radiant-0.7.1/lib/radiant/initializer.rb:

# In /usr/lib/ruby/gems/1.8/gems/radiant-0.7.1/lib/radiant/initializer.rb line 101:
-     super
+     super(command, configuration)
tags: l