Using map and proxy_pass

Hi list,

I’m pulling my hair out. I need to pass to different proxies based on
the
first uri segment but don’t seem be able to get it working.

I have the following map:

map $uri $upstream
{
/abc/bla/ host01;
/xyz/bla/ host02;
}

Originally i tried using regex in the uri because different 2nd segments
can
be used, doing /abx/(.*)/ doesn’t work either, or i’m using it the wrong
way.
So for now i’m trying with fixed uri’s.

In the location handling the 2nd segment i rewrite and proxy_pass.

location ~ "/(.)/abc"
{
rewrite ^(.
)$ /another_segment$1 break;
proxy_pass http://:8080$upstream;
}

Cheers,

Accidentally sent it too early. See below

/xyz/bla/ host02;
rewrite ^(.*)$ /another_segment$1 break;
proxy_pass http://:8080$upstream;
}

I’ve tried various approaches such as using $upstream in rewrite or
other
combinations but they always result in a HTTP 500 error:

2011/04/29 15:50:44 [error] 17886#0: *2 invalid host in upstream
“:8080”,

etc.

Is there anyone that can point me in the right direction?

How many uri / backend mappings do you have? You could perform the
above in two straight forward location blocks, based on the uri.

location /abc {

proxy_pass http://host01:8080;
}

Posted at Nginx Forum:

Anyone else having some thoughs on how to use the map in conjunction
with
proxy_pass to set different hosts based on the first URI segment?

On Saturday 30 April 2011 12:52:42 Markus J. wrote:

nginx mailing list
[email protected]
nginx Info Page


nginx mailing list
[email protected]
nginx Info Page


Markus J. - CTO - Openindex
http://www.linkedin.com/in/markus17
050-8536620 / 06-50258350

Too many. I need to generate the mappings in an external program. I’d
rather
not generate as many different locations.

Thanks

On Sat, Apr 30, 2011 at 12:52:42PM +0200, Markus J. wrote:

Too many. I need to generate the mappings in an external program. I’d rather
not generate as many different locations.

Why ? locations without regex will run fast.


Igor S.

Thanks Francis and Igor. Is there are penalty for having a huge
configuration
because of a very large number of locations?

On Tuesday 03 May 2011 11:10:55 Igor S. wrote:

On Sat, Apr 30, 2011 at 12:52:42PM +0200, Markus J. wrote:

Too many. I need to generate the mappings in an external program. I’d
rather not generate as many different locations.

Why ? locations without regex will run fast.


Markus J. - CTO - Openindex
http://www.linkedin.com/in/markus17
050-8536620 / 06-50258350

On Tue, May 03, 2011 at 01:02:53PM +0200, Markus J. wrote:

Thanks Francis and Igor. Is there are penalty for having a huge configuration
because of a very large number of locations?

nginx uses some kind of binary tree to search locations, so penalty
should be small.


Igor S.

On Mon, May 02, 2011 at 02:56:19PM +0200, Markus J. wrote:

Hi there,

A general rule for most config confusions is “the debug log is your
friend”.

Anyone else having some thoughs on how to use the map in conjunction with
proxy_pass to set different hosts based on the first URI segment?

It’s not clear to me why you’re happy to generate an include file of
mappings in an external program, but not happy to generate an include
file of locations in an external program.

And if you have a large number of locations, you’ll probably be happier
having no top-level regex locations.

But all that aside…

“map $var1 $var2” sets $var2 based on a string match of $var1.

You wish to match based on the first uri segment. So, do just that:

===
http {
map $first_segment $value {
default 127.0.0.1;
/abc 127.0.0.2;
/def 127.0.0.3;
}
server {
if ($uri ~* ^(/[^/]*) ) {
set $first_segment $1;
}
location / {
proxy_pass http://:8080$value/$uri ;
}
}
}

You may want to play with the proxy_pass line depending on exactly what
you want to do, but the above seems to work for me.

You can also add a $second_segment (or $part2) in the if{} block, if
you want a separate map for that.

Good luck with it,

f

Francis D. [email protected]