LiteSpeed, Rails, and Rewriting URLs

October 23, 2007

I had a situation today in which I wanted to turn a url such as /foo/bar/12345 into /foo/bar/5/4/3/12345.html and pass that into Rails. But it doesn’t work using a LiteSpeed RewriteRule without specifying a redirect code.

The reason it doesn’t work is that LiteSpeed sets REQUEST_URI to the original URL and then sets REDIRECT_URL to the newly rewritten URL. Rails only looks at REQUEST_URI (unless you’re running IIS, but that’s not relevant).

So, if you want to have Rails operate (by which I mean look for in config/routes.rb) the rewritten rule you’ll want to load this up:

But they are a little old now (versions mostly) and didn’t include some of the

module ActionController
      class AbstractRequest
        alias :orig_request_uri :request_uri
        def request_uri
          if @env['SERVER_SOFTWARE'] == 'LiteSpeed' && !@env['REDIRECT_URL'].blank?
            @env['REQUEST_URI'] = @env['REDIRECT_URL']
          else
            orig_request_uri
          end
        end
      end
    end

And now Rails will first check for the existence of REDIRECT_URL and use that if it exists. I’ve done some limited testing of this and it works. Not sure what else down the road might break, but if Rails is good about using request_uri internally it should be fine.

Note: If you’re using Apache/Mongrel you can’t accomplish this. Apache’s rewrite doesn’t seem to set REDIRECT_URL at all. Or mongrel swallows it before it gets to Rails, but not even my rewriting tests using mod_php showed it. Which means this is a litespeed only solution.