X-Sendfile's new friend: X-Rewrite-* 4

Posted by jan Sat, 22 Jul 2006 11:37:00 GMT

Today on IRC I got a question on:

<b>Fobax</b> can you x-send-file from fast-cgi to a proxy request?

Or asked in another way ?

Can you use a mod_proxy_core backend to rewrite a URL or a Host header ?

After 30 minutes of coding … Yes, you can …

Some tweaking and here and there and we had:

proxy-core.allow-x-rewrite = "enable" 

which allows you to send:

HTTP/1.0 200 OK
X-Rewrite-URI: /pi.php
X-Rewrite-Host: www.foobar.com

as response and lighty will replace both values and the original request and start the whole request from scratch. Here I rewrite the incoming request to use another internal Host and a new URI.

What is this good for ?

  • rewriting http://user.example.org/ to http://xample.org/~user/
  • denying access to host with unwanted content based on the Hostname
  • filtering in general

Do you have other examples ?

Trackbacks

Use the following link to trackback from your own site:
http://blog.lighttpd.net/articles/trackback/1824

  1. I just uploaded the 3rd pre-release of lighttpd 1.4.12: http://www.lighttpd.net/download/lighttpd-1.4.12-20060724-0947.tar.gz This pre-release should work on most platforms and it mainly got improvements for our mongrel users. A small test has sho...
Comments

Leave a response

  1. Yusuf Sat, 22 Jul 2006 16:33:19 GMT
    Just to clarify this, does this mean you can have one set of backends which only does rewrites and another set of backends which can handle the request post-rewrite ?
  2. Jan Kneschke Sat, 22 Jul 2006 16:58:25 GMT
    Yes.
  3. Fobax Sat, 22 Jul 2006 23:44:53 GMT
    This is great for doing much more complex rewrites, like lookups to a database/memcache, with logic. It means converting one url style to another on the fly is possible without having to necessarily keep a backward compatible version on the filesystem (think of the case where extra data is added so a regex isn't possible). Another use would be things like much more complex authentication or bandwidth control. The big question is, can you do custom proxy balancing this way? The reason for this is the balance modes right now are: round robin, least connection, or hash. But all of those assume all backends have all the data. With the hash it will increase cache locality and keep only a small subset in ram, but it must at least have it all on disk. If you have millions of files or terabytes of data that won't work. The goal here is to only have to keep it on one or two backends, and have the rewrite specify which backend has the data. I guess this can be done by having an fcgi block on the external domain, and a bunch of proxy blocks for the internal servers, one each. The rewrite would rewrite the host header to be to the correct backend domain. Do I have this correct Jan? ie:
    $HTTP["host"] == "external.com" {
      fastcgi.server = ( ".php" => ("socket" => "/tmp/php-fcgi.socket", 
      proxy-core.allow-x-rewrite = "enable" ))
      url.rewrite = ( "(.*)" => "/rewrite.php?$1")
    }
    $HTTP["host"] == "internal1.external.com" {
      proxy.server = ( "" => ( "host" => "192.168.1.1", "port" => 80 ))
    }
    $HTTP["host"] == "internal2.external.com" {
      proxy.server = ( "" => ( "host" => "192.168.1.2", "port" => 80 ))
    }
    
  4. Jan Kneschke Mon, 24 Jul 2006 09:52:34 GMT
    It would be something like this:
    $HTTP["host"] == "external.com" {
      $HTTP["url"] !~ "\.php$" {
        proxy-core.protocol = "fastcgi"
        proxy-core.backends = ( "/tmp/php-fcgi.socket" )
    
        proxy-core.allow-x-rewrite = "enable" 
        proxy-core.rewrite-request = ( 
          "_uri"  => ( "(.*)" => "/rewrite.php?$1"))
      }
    }
    $HTTP["host"] == "internal1.external.com" {
      proxy-core.backends = ( "192.168.1.1" )
    }
    $HTTP["host"] == "internal2.external.com" {
      proxy-core.backends = ( "192.168.1.2" )
    }
    
Comments