64a65,179
> #define HUGE_STRING_LEN 0x2000
> void ngx_vhost_calc_root(ngx_str_t *newroot, ngx_str_t *cfgroot, ngx_http_request_t *r)
> {
>     /* 0..9 9..0 */
>     enum { MAXDOTS = 19 };
>     const char *dots[MAXDOTS+1];
>     int ndots;
> 
>     char buf[HUGE_STRING_LEN];
>     char *dest, last;
> 
>     int N, M, Np, Mp, Nd, Md;
>     const char *start, *end;
> 
>     const char *p;
>     const char *map = cfgroot->data;
> 
>     ndots = 0;
>     dots[ndots++] = r->headers_in.host->value.data - 1; /* slightly naughty */
>     for (p = r->headers_in.host->value.data; *p && *p!=':'; ++p){
>         if (*p == '.' && ndots < MAXDOTS) {
>             dots[ndots++] = p;
>         }
>     }
>     dots[ndots] = p;
> 
>     dest = buf;
>     last = '\0';
>     while (*map) {
>         if (*map != '%') {
>             /* normal characters */
>             last = *dest++ = *map++;
>             continue;
>         }
>         /* we are in a format specifier */
>         ++map;
>         /* can't be a slash */
>         last = '\0';
>         /* %% -> % */
>         if (*map == '%') {
>             ++map;
>             *dest++ = '%';
>             continue;
>         }
>         N = M = 0;   /* value */
>         Np = Mp = 0; /* is there a plus? */
>         Nd = Md = 0; /* is there a dash? */
>         if (*map == '-') ++map, Nd = 1;
>         N = *map++ - '0';
>         if (*map == '+') ++map, Np = 1;
>         if (*map == '.') {
>             ++map;
>             if (*map == '-') {
>                 ++map, Md = 1;
>             }
>             M = *map++ - '0';
>             if (*map == '+') {
>                 ++map, Mp = 1;
>             }
>         }
>         /* note that N and M are one-based indices, not zero-based */
>         start = dots[0]+1; /* ptr to the first character */
>         end = dots[ndots]; /* ptr to the character after the last one */
>         if (N != 0) {
>             if (N > ndots) {
>                 start = "_";
>                 end = start+1;
>             }
>             else if (!Nd) {
>                 start = dots[N-1]+1;
>                 if (!Np) {
>                     end = dots[N];
>                 }
>             }
>             else {
>                 if (!Np) {
>                     start = dots[ndots-N]+1;
>                 }
>                 end = dots[ndots-N+1];
>             }
>         }
>         if (M != 0) {
>             if (M > end - start) {
>                 start = "_";
>                 end = start+1;
>             }
>             else if (!Md) {
>                 start = start+M-1;
>                 if (!Mp) {
>                     end = start+1;
>                 }
>             }
>             else {
>                 if (!Mp) {
>                     start = end-M;
>                 }
>                 end = end-M+1;
>             }
>         }
>         for (p = start; p < end; ++p) {
>             *dest++ = ngx_tolower(*p);
>         }
>     }
>     *dest = '\0';
> 
>     newroot->len = ngx_strlen(buf);
>     newroot->data = ngx_palloc(r->pool, newroot->len+1);
>     if(newroot->data)
>     {
>         ngx_cpystrn(newroot->data, buf, newroot->len+1);
>     } else
>     {
> 	newroot->len = 0;
>     }
> }
72c187
<     ngx_str_t                    name, location;
---
>     ngx_str_t                    root, name, location;
128a244,247
>     ngx_vhost_calc_root(&root, &clcf->root, r);
>     if (root.data == NULL) {
>         return NGX_HTTP_INTERNAL_SERVER_ERROR;
>     }
131c250
<         name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2
---
>         name.data = ngx_palloc(r->pool, root.len + r->uri.len + 2
137c256
<         last = ngx_cpymem(name.data, clcf->root.data, clcf->root.len);
---
>         last = ngx_cpymem(name.data, root.data, root.len);
164c283
<         name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2);
---
>         name.data = ngx_palloc(r->pool, root.len + r->uri.len + 2);
169c288
<         location.data = ngx_cpymem(name.data, clcf->root.data, clcf->root.len);
---
>         location.data = ngx_cpymem(name.data, root.data, root.len);
