proxy_pass based on (possibly changed) $host

Igor Sysoev is at rambler-co.ru
Wed Jan 28 18:01:48 MSK 2009


On Wed, Jan 28, 2009 at 03:49:23PM +0100, Johan Bergstr?m wrote:

> Hello,
> 
> On Jan 28, 2009, at 12:02 , Igor Sysoev wrote:
> 
> >On Wed, Jan 28, 2009 at 02:52:24AM -0800, Dave Bailey wrote:
> >
> >>Hi,
> >>
> >>I am porting a lighttpd module that I wrote to nginx.  I am new to
> >>nginx.  I would like to know if it is possible to choose the
> >>proxy_pass backend from the Host header within a server.  In  
> >>lighttpd,
> >>this is possible by:
> >>
> >>$SERVER["socket"] == ":80" {
> >> $HTTP["host"] == "bar.foo.com" {
> >>   proxy-core.backends = ( "10.0.0.1:80" )
> >> }
> >> $HTTP["host"] == "baz.foo.com" {
> >>   proxy-core.backends = ( "10.0.0.2:80" )
> >> }
> >>}
> >
> >However, the better:
> >
> >   server {
> >       listen   80;
> >       server_name   bar.foo.com;
> >
> >       location  / {
> >           proxy_pass  http://10.0.0.1:80;
> >       }
> >   }
> >
> >   server {
> >       listen   80;
> >       server_name   baz.foo.com;
> >
> >       location  / {
> >           proxy_pass  http://10.0.0.2:80;
> >       }
> >   }
> >
> >
> >>The module that I am porting to nginx will sometimes update the Host
> >>header such that a different proxy backend should be chosen.  For
> >>example, a request from a particular IP address to http:// 
> >>bar.foo.com/
> >>might be updated such that its Host header changes from bar.foo.com  
> >>to
> >>baz.foo.com, and thus it is served by the 10.0.0.2:80 backend.  Is
> >>there a way to specify a relationship between $host and proxy_pass in
> >>nginx.conf within the same server { ... }?
> >
> >   map $remote_addr  $back1 {
> >       default       10.0.0.1:80;
> >       192.168.1.1   10.0.0.2:80;
> >       192.168.1.5   10.0.0.2:80;
> >   }
> >
> >   server {
> >       listen   80;
> >       server_name   bar.foo.com;
> >
> >       location  / {
> >           proxy_pass  http://$back1$request_uri;
> >       }
> >   }
> >
> >   map $remote_addr   $back2 {
> >       default        10.0.0.2:80;
> >       192.168.10.1   10.0.0.1:80;
> >       192.168.10.5   10.0.0.1:80;
> >   }
> >
> >   server {
> >       listen   80;
> >       server_name   baz.foo.com;
> >
> >       location  / {
> >           proxy_pass  http://$back2$request_uri;
> >       }
> >   }
> 
> This is very similar to how i have things set up; but this map is  
> rather static. I "solved" this by using memcached as "map", a simple  
> FastCGI application written in C doing the lookup which returns the  
> backend to use. My question is if this map thing somehow could be  
> expanded to something of a more dynamic nature?

You may write a variable handler in C/ngx_http_perl_module for $back1
and $back2, but the problem is now variable handlers are blockeing ones.
There is no way to postpone proxy_pass processing while variable resolution.

So, currently you may only use X-Accel-Redirect:

     location / {
         fastcgi_pass  ...;

         # it returns
         # ...
         # X-Accel-Redirect: /xar"
         # X-Proxy: http://10.0.0.1:80/some/uri?args
     }

     location = /xar {
         internal;

         # you have to store $upstream_http_x_proxy somewhere as it
         # will be discarded just proxy module will start to work
         set   $xproxy  $upstream_http_x_proxy;

         proxy_pass   $xproxy;
     }


-- 
Igor Sysoev
http://sysoev.ru/en/





More information about the nginx mailing list