proxy_pass based on (possibly changed) $host

Igor Sysoev is at rambler-co.ru
Wed Jan 28 20:00:43 MSK 2009


On Wed, Jan 28, 2009 at 08:13:05AM -0800, Dave Bailey wrote:

> >> 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;
> >     }
> 
> Hmm, interesting.  Suppose, then, that my module stores a hash table
> that relates the incoming {Host, uri} to the upstream {Host, uri} for
> a large number of {Host, uri} keys.  In addition to this mapping, I
> would have some "default" location-based mappings in nginx.conf, such
> as:
> 
> server {
>   listen 80;
>   server_name bar.foo.com;
>   location / {
>     proxy_pass http://10.0.0.1:80;
>     proxy_set_header Host $http_host;
>   }
> }
> 
> server {
>   listen 80;
>   server_name baz.foo.com;
>   location / {
>     proxy_pass http://10.0.0.2:80;
>     proxy_set_header Host $http_host;
>   }
>   location /bar/path/one {
>     proxy_pass http://10.0.0.1:80;
>     proxy_set_header Host "bar.foo.com";
>   }
>   ...
> }
> 
> Suppose that I receive the request:
> 
> GET /bar/path/one/of/many/thousands HTTP/1.1
> Host: baz.foo.com
> 
> In my module, I would look this up in a hash table using the {Host,
> uri} as the key.  I might find that the request should be handled
> upstream by 10.0.0.1:80 (i.e. the upstream server that contains
> bar.foo.com's content) at some completely different URI.  So my goal
> is to rewrite the URI and possibly the Host header as a result of what
> I find in the hash lookup, and have the proxy module connect to the
> correct upstream backend as a result (and retrieve the rewritten URI).
> 
> In your config sample, you have:
> 
> set $xproxy $upstream_http_x_proxy;
> proxy_pass $xproxy;
> 
> Within the module's C source code that I write, could I do this
> through the ngx_ API, as well as something similar to update the
> upstream URI?  There will be too many entries in the hash table for me
> to represent it in nginx.conf.

You may create $xproxy_url and $xproxy_host variable handlers in C module
and use them as

     proxy_pass        $xproxy_url;
     proxy_set_header  Host $xproxy_host;


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





More information about the nginx mailing list