# Using map and proxy\_pass

**URL:** <https://www.ruby-forum.com/t/using-map-and-proxy-pass/206387>\
**Category:** NGINX\
**Created:** [April 29, 2011, 5:46pm UTC](https://www.ruby-forum.com/t/using-map-and-proxy-pass/206387 "2011-04-29T17:46:22Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![luislavena](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/0ea827/32.png) [@luislavena](https://www.ruby-forum.com/u/luislavena)\
**Post date:** [April 29, 2011, 5:46pm UTC](https://www.ruby-forum.com/t/using-map-and-proxy-pass/206387/1 "2011-04-29T17:46:22Z")

</div>

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,

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [April 29, 2011, 5:49pm UTC](https://www.ruby-forum.com/t/using-map-and-proxy-pass/206387/2 "2011-04-29T17:49:27Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [April 30, 2011, 5:41am UTC](https://www.ruby-forum.com/t/using-map-and-proxy-pass/206387/3 "2011-04-30T05:41:20Z")

</div>

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](http://host01:8080);  
}

…

Posted at Nginx Forum:

> **[Re: Using map and proxy\_pass](https://forum.nginx.org/read.php?2,194480,194616)**
>
> 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;

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [May 2, 2011, 2:56pm UTC](https://www.ruby-forum.com/t/using-map-and-proxy-pass/206387/4 "2011-05-02T14:56:51Z")

</div>

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  
> > [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> > [mailman.nginx.org archive](http://nginx.org/mailman/listinfo/nginx)
> 
> * * *
> 
> nginx mailing list  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [mailman.nginx.org archive](http://nginx.org/mailman/listinfo/nginx)

–  
Markus J. - CTO - Openindex  
[http://www.linkedin.com/in/markus17](http://www.linkedin.com/in/markus17)  
050-8536620 / 06-50258350

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [April 30, 2011, 12:52pm UTC](https://www.ruby-forum.com/t/using-map-and-proxy-pass/206387/5 "2011-04-30T12:52:39Z")

</div>

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

Thanks

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [May 3, 2011, 11:11am UTC](https://www.ruby-forum.com/t/using-map-and-proxy-pass/206387/6 "2011-05-03T11:11:43Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [May 3, 2011, 1:03pm UTC](https://www.ruby-forum.com/t/using-map-and-proxy-pass/206387/7 "2011-05-03T13:03:33Z")

</div>

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](http://www.linkedin.com/in/markus17)  
050-8536620 / 06-50258350

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [May 3, 2011, 2:06pm UTC](https://www.ruby-forum.com/t/using-map-and-proxy-pass/206387/8 "2011-05-03T14:06:54Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [May 2, 2011, 5:35pm UTC](https://www.ruby-forum.com/t/using-map-and-proxy-pass/206387/9 "2011-05-02T17:35:48Z")

</div>

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. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
