# Vhost support

**URL:** <https://www.ruby-forum.com/t/vhost-support/202446>\
**Category:** NGINX\
**Created:** [January 29, 2011, 8:07am UTC](https://www.ruby-forum.com/t/vhost-support/202446 "2011-01-29T08:07:27Z")\
**Posts on this page:** 8\
**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:** [January 29, 2011, 8:07am UTC](https://www.ruby-forum.com/t/vhost-support/202446/1 "2011-01-29T08:07:27Z")

</div>

So there doesn’t seem to be any interest in some kind of  
vhost\_alias module so I’d like to try and write one but I  
need a little help with the nginx codebase.

server {  
listen 80;  
server\_name \_;  
location / {  
root /var/www/$host;  
}  
}

If I use the above then I get this in the logs…

2011/01/29 16:09:13 [error] 32404#0:  
\*1 “/var/www/domain.org/index.html” is not found  
(2: No such file or directory), client: 192.168.1.2,  
server: \_, request: “GET / HTTP/1.1”, host: “[domain.org](http://domain.org)”

(yes, I know the /var/www/domain.org directory does not exist)

This is pretty good but I want to reverse the [domain.org](http://domain.org) $host  
variable and provide, say, a $rhost variable of “org/domain”.

I have an apache2 module that already does this so I just need  
some orientation or assistance to find where in the nginx code  
to do the same thing so any pointers would be appreciated.

Anyone care to offers some clues?

–markc

---

<div class="post-metadata">

**Author:** ![Mark\_Constable](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Mark\_Constable](https://www.ruby-forum.com/u/Mark_Constable)\
**Post date:** [January 29, 2011, 8:38am UTC](https://www.ruby-forum.com/t/vhost-support/202446/2 "2011-01-29T08:38:05Z")

</div>

On 29/01/11, Igor S. wrote:

> > This is pretty good but I want to reverse the [domain.org](http://domain.org) $host  
> > variable and provide, say, a $rhost variable of “org/domain”.  
> > […]
> 
> [Server names](http://nginx.org/en/docs/http/server_names.html#regex_names)

Thanks for the reply, but how do I take into account…

[domain.com](http://domain.com)  
[www.domain.com](http://www.domain.com)  
[www.username.domain.com](http://www.username.domain.com)

so, ie; the first one becomes com/domain and the last one becomes  
com/domain/username/www ?

I have tried this but couldn’t get it to work…

server {  
server\_name ~^(?.)?(?.)?(?.)?(?.)?(?.);  
#server\_name  
~^(?P.)?(?P.)?(?P.)?(?P.)?(?P.);  
location / {  
root /var/www/$p5/$p4/$p3/$p2/$p1;  
}  
}

–markc

---

<div class="post-metadata">

**Author:** ![Mark\_Constable](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Mark\_Constable](https://www.ruby-forum.com/u/Mark_Constable)\
**Post date:** [January 29, 2011, 8:09am UTC](https://www.ruby-forum.com/t/vhost-support/202446/3 "2011-01-29T08:09:20Z")

</div>

On Sat, Jan 29, 2011 at 05:04:23PM +1000, Mark Constable wrote:

> }  
> This is pretty good but I want to reverse the [domain.org](http://domain.org) $host  
> variable and provide, say, a $rhost variable of “org/domain”.
> 
> I have an apache2 module that already does this so I just need  
> some orientation or assistance to find where in the nginx code  
> to do the same thing so any pointers would be appreciated.
> 
> Anyone care to offers some clues?

> **[Server names](http://nginx.org/en/docs/http/server_names.html#regex_names)**
>
> Server names are defined using the server\_name directive and determine which server block is used for a given request. See also “How nginx processes a request”. They may be defined using exact names, wildcard names, or regular expressions:

–  
Igor S.

> **[Igor Sysoev](http://sysoev.ru/en/)**

---

<div class="post-metadata">

**Author:** ![Mark\_Constable](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Mark\_Constable](https://www.ruby-forum.com/u/Mark_Constable)\
**Post date:** [January 29, 2011, 9:04am UTC](https://www.ruby-forum.com/t/vhost-support/202446/4 "2011-01-29T09:04:19Z")

</div>

On 29 Jan 2011 07h35 WET, [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> [www.domain.com](http://www.domain.com)  
> #~^(?P.)?(?P.)?(?P.)?(?P.)?(?P.);  
> location / {  
> root /var/www/$p5/$p4/$p3/$p2/$p1;  
> }  
> }

Try with:

server\_name  
~^(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]+).(?[^.]+);

I’m uncertain about the way the root directive value gets assigned  
when there are null valued variables. Never tried anything of that sort.

— appa

---

<div class="post-metadata">

**Author:** ![Mark\_Constable](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Mark\_Constable](https://www.ruby-forum.com/u/Mark_Constable)\
**Post date:** [January 29, 2011, 9:02am UTC](https://www.ruby-forum.com/t/vhost-support/202446/5 "2011-01-29T09:02:27Z")

</div>

On Sat, Jan 29, 2011 at 05:35:19PM +1000, Mark Constable wrote:

> [www.domain.com](http://www.domain.com)  
> location / {  
> root /var/www/$p5/$p4/$p3/$p2/$p1;  
> }  
> }

Make several servers with different regexes:

server {  
server\_name  
~^(?[^.]+).(?[^.]+).(?[^.]+).(?[^.]+)$;  
location / {  
root /var/www/$p4/$p3/$p2/$p1;  
}  
}

server {  
server\_name ~^(?[^.]+).(?[^.]+).(?[^.]+)$;  
location / {  
root /var/www/$p3/$p2/$p1;  
}  
}

server {  
server\_name ~^(?[^.]+).(?[^.]+)$;  
location / {  
root /var/www/$p2/$p1/www;  
}  
}

–  
Igor S.

> **[Igor Sysoev](http://sysoev.ru/en/)**

---

<div class="post-metadata">

**Author:** ![Mark\_Constable](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Mark\_Constable](https://www.ruby-forum.com/u/Mark_Constable)\
**Post date:** [January 29, 2011, 9:45am UTC](https://www.ruby-forum.com/t/vhost-support/202446/6 "2011-01-29T09:45:38Z")

</div>

On 29 Jan 2011 07h58 WET, [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > server\_name ~^(?.)?(?.)?(?.)?(?.)?(?.);  
> > ~^(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]+).(?[^.]+);  
> > Make it:

server\_name  
~^(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]+).(?[^.]+)$;

Forgot to escape the “.” in the named capturing groups.

— appa

---

<div class="post-metadata">

**Author:** ![Mark\_Constable](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Mark\_Constable](https://www.ruby-forum.com/u/Mark_Constable)\
**Post date:** [January 29, 2011, 1:38pm UTC](https://www.ruby-forum.com/t/vhost-support/202446/7 "2011-01-29T13:38:29Z")

</div>

On 29/01/11, Antnio P. P. Almeida wrote:

> Make it:  
> server\_name  
> ~^(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]+).(?[^.]+)$;  
> Forgot to escape the “.” in the named capturing groups.

Thanks Antonio, this does indeed work. The only downside I can see is  
that the system file path is something like /var/www////com/domain/,  
when there are less than 5 parts, but it still seems to work okay.

server {  
listen 80;  
server\_name  
~^(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]\*)$;

location / {  
root /var/www/$p5/$p4/$p3/$p2/$p1;  
index index.html index.htm index.jsx index.php;  
}  
}

I’d still be interested to do this without requiring a regex as all  
it would take is something like this small amount of code in a module,  
or as a patch to core…

char \*add\_path\_element(char \*dest, char \*element)  
{  
\*dest++ = ‘/’;  
strcpy(dest,element);  
return dest + strlen(element);  
}

```
[...]
server_name = ap_get_server_name(r);
buf = apr_pstrdup(r->pool, server_name);
rvp = apr_palloc(r->pool, strlen(buf)+1);

r->canonical_filename = "";

```

/\* Work out the reverse path \*/  
for (p = rvp, q = buf+strlen(buf); q \>= buf; q–) {  
if (\*q == ‘.’) {  
\*q = ‘\0’;  
p = add\_path\_element(p, q+1);  
}  
}  
p = add\_path\_element(p,buf);  
[…]

Anyone care to suggest where is the best place to start to look for  
a module or patch to add something like the above?

–markc

---

<div class="post-metadata">

**Author:** ![Mark\_Constable](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Mark\_Constable](https://www.ruby-forum.com/u/Mark_Constable)\
**Post date:** [January 29, 2011, 7:16pm UTC](https://www.ruby-forum.com/t/vhost-support/202446/8 "2011-01-29T19:16:09Z")

</div>

On Sat, Jan 29, 2011 at 10:37:02PM +1000, Mark Constable wrote:

> listen 80;  
> server\_name  
> ~^(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]_)[.]_(?[^.]\*)$;
> 
> location / {  
> root /var/www/$p5/$p4/$p3/$p2/$p1;  
> index index.html index.htm index.jsx index.php;  
> }  
> }

You just need to set several servers with different regexes.

–  
Igor S.

> **[Igor Sysoev](http://sysoev.ru/en/)**
