changeset 400:6ebbca3d5ed7 NGINX_0_7_12

nginx 0.7.12 *) Feature: the "server_name" directive supports empty name "". *) Feature: the "gzip_disable" directive supports special "msie6" mask. *) Bugfix: if the "max_fails=0" parameter was used in upstream with several servers, then a worker process exited on a SIGFPE signal. Thanks to Maxim Dounin. *) Bugfix: a request body was dropped while redirection via an "error_page" directive. *) Bugfix: a full response was returned for request method HEAD while redirection via an "error_page" directive. *) Bugfix: the $r->header_in() method did not return value of the "Host", "User-Agent", and "Connection" request header lines; the bug had appeared in 0.7.0.
author Igor Sysoev <http://sysoev.ru>
date Tue, 26 Aug 2008 00:00:00 +0400
parents 59e324e4d6d3
children d1c2a7a85713
files CHANGES CHANGES.ru conf/mime.types src/core/nginx.h src/core/ngx_config.h src/core/ngx_connection.c src/core/ngx_connection.h src/core/ngx_hash.c src/core/ngx_inet.c src/core/ngx_inet.h src/core/ngx_string.h src/event/ngx_event.c src/event/ngx_event_accept.c src/http/modules/ngx_http_access_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/ngx_http_realip_module.c src/http/modules/ngx_http_xslt_filter_module.c src/http/modules/perl/nginx.pm src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_header_filter_module.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/http/ngx_http_special_response.c src/http/ngx_http_upstream_round_robin.c src/http/ngx_http_variables.c src/mail/ngx_mail.c src/mail/ngx_mail_core_module.c src/os/unix/ngx_files.c
diffstat 29 files changed, 410 insertions(+), 438 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,25 @@
 
+Changes with nginx 0.7.12                                        26 Aug 2008
+
+    *) Feature: the "server_name" directive supports empty name "".
+
+    *) Feature: the "gzip_disable" directive supports special "msie6" mask.
+
+    *) Bugfix: if the "max_fails=0" parameter was used in upstream with 
+       several servers, then a worker process exited on a SIGFPE signal.
+       Thanks to Maxim Dounin.
+
+    *) Bugfix: a request body was dropped while redirection via an 
+       "error_page" directive.
+
+    *) Bugfix: a full response was returned for request method HEAD while 
+       redirection via an "error_page" directive.
+
+    *) Bugfix: the $r->header_in() method did not return value of the 
+       "Host", "User-Agent", and "Connection" request header lines; the bug 
+       had appeared in 0.7.0.
+
+
 Changes with nginx 0.7.11                                        18 Aug 2008
 
     *) Change: now ngx_http_charset_module does not work by default with 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,26 @@
 
+Изменения в nginx 0.7.12                                          26.08.2008
+
+    *) Добавление: директива server_name поддерживает пустое имя "".
+
+    *) Добавление: директива gzip_disable поддерживает специальную маску 
+       msie6.
+
+    *) Исправление: при использовании параметра max_fails=0 в upstream'е с 
+       несколькими серверами рабочий процесс выходил по сигналу SIGFPE.
+       Спасибо Максиму Дунину.
+
+    *) Исправление: при перенаправлении запроса с помощью директивы 
+       error_page терялось тело запроса.
+
+    *) Исправление: при перенаправлении запроса с методом HEAD с помощью 
+       директивы error_page возвращался полный ответ.
+
+    *) Исправление: метод $r->header_in() не возвращал значения строк 
+       "Host", "User-Agent", и "Connection" из заголовка запроса; ошибка 
+       появилась в 0.7.0.
+
+
 Изменения в nginx 0.7.11                                          18.08.2008
 
     *) Изменение: теперь ngx_http_charset_module по умолчанию не работает 
--- a/conf/mime.types
+++ b/conf/mime.types
@@ -33,6 +33,8 @@ types {
     application/vnd.ms-powerpoint         ppt;
     application/vnd.wap.wmlc              wmlc;
     application/vnd.wap.xhtml+xml         xhtml;
+    application/vnd.google-earth.kml+xml  kml;
+    application/vnd.google-earth.kmz      kmz;
     application/x-cocoa                   cco;
     application/x-java-archive-diff       jardiff;
     application/x-java-jnlp-file          jnlp;
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VERSION      "0.7.11"
+#define NGINX_VERSION      "0.7.12"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -116,10 +116,6 @@ typedef intptr_t        ngx_flag_t;
 #define INADDR_NONE  ((unsigned int) -1)
 #endif
 
-#ifndef INET_ADDRSTRLEN  /* Win32 */
-#define INET_ADDRSTRLEN  16
-#endif
-
 #ifdef MAXHOSTNAMELEN
 #define NGX_MAXHOSTNAMELEN  MAXHOSTNAMELEN
 #else
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -37,23 +37,23 @@ ngx_listening_inet_stream_socket(ngx_con
 
 
     ls->addr_text.data = ngx_pnalloc(cf->pool,
-                                    INET_ADDRSTRLEN - 1 + sizeof(":65535") - 1);
+                                    NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1);
     if (ls->addr_text.data == NULL) {
         return NULL;
     }
 
-    len = ngx_inet_ntop(AF_INET, &addr, ls->addr_text.data, INET_ADDRSTRLEN);
+    len = ngx_inet_ntop(AF_INET, &addr, ls->addr_text.data,
+                        NGX_INET_ADDRSTRLEN);
 
     ls->addr_text.len = ngx_sprintf(ls->addr_text.data + len, ":%d", port)
                         - ls->addr_text.data;
 
     ls->fd = (ngx_socket_t) -1;
-    ls->family = AF_INET;
     ls->type = SOCK_STREAM;
     ls->sockaddr = (struct sockaddr *) sin;
     ls->socklen = sizeof(struct sockaddr_in);
     ls->addr = offsetof(struct sockaddr_in, sin_addr);
-    ls->addr_text_max_len = INET_ADDRSTRLEN;
+    ls->addr_text_max_len = NGX_INET_ADDRSTRLEN;
 
     return ls;
 }
@@ -104,17 +104,16 @@ ngx_set_inherited_sockets(ngx_cycle_t *c
             continue;
         }
 
-        ls[i].addr_text_max_len = INET_ADDRSTRLEN;
+        ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
 
         ls[i].addr_text.data = ngx_pnalloc(cycle->pool,
-                                   INET_ADDRSTRLEN - 1 + sizeof(":65535") - 1);
+                                   NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1);
         if (ls[i].addr_text.data == NULL) {
             return NGX_ERROR;
         }
 
-        ls[i].family = sin->sin_family;
-        len = ngx_sock_ntop(ls[i].family, ls[i].sockaddr,
-                            ls[i].addr_text.data, INET_ADDRSTRLEN);
+        len = ngx_sock_ntop(ls[i].sockaddr, ls[i].addr_text.data,
+                            NGX_INET_ADDRSTRLEN);
         if (len == 0) {
             return NGX_ERROR;
         }
@@ -254,7 +253,7 @@ ngx_open_listening_sockets(ngx_cycle_t *
                 continue;
             }
 
-            s = ngx_socket(ls[i].family, ls[i].type, 0);
+            s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0);
 
             if (s == -1) {
                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -23,7 +23,6 @@ struct ngx_listening_s {
     size_t              addr_text_max_len;
     ngx_str_t           addr_text;
 
-    int                 family;
     int                 type;
 
     int                 backlog;
--- a/src/core/ngx_hash.c
+++ b/src/core/ngx_hash.c
@@ -220,6 +220,10 @@ ngx_hash_find_combined(ngx_hash_combined
         }
     }
 
+    if (len == 0) {
+        return NULL;
+    }
+
     if (hash->wc_head && hash->wc_head->hash.buckets) {
         value = ngx_hash_find_wc_head(hash->wc_head, name, len);
 
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -8,7 +8,8 @@
 #include <ngx_core.h>
 
 
-static size_t ngx_sprint_uchar(u_char *text, u_char c, size_t len);
+static ngx_int_t ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u);
+static ngx_int_t ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u);
 
 
 /* AF_INET only */
@@ -56,166 +57,43 @@ ngx_inet_addr(u_char *text, size_t len)
 }
 
 
-/*
- * ngx_sock_ntop() and ngx_inet_ntop() may be implemented as
- * "ngx_sprintf(text, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3])", however,
- * they had been implemented long before the ngx_sprintf() had appeared
- * and they are faster by 1.5-2.5 times, so it is worth to keep them.
- *
- * By the way, the implementation using ngx_sprintf() is faster by 2.5-3 times
- * than using FreeBSD libc's snprintf().
- */
-
 /* AF_INET only */
 
 size_t
-ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, size_t len)
+ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len)
 {
     u_char              *p;
-    size_t               n;
-    ngx_uint_t           i;
     struct sockaddr_in  *sin;
 
-    if (len == 0) {
-        return 0;
-    }
+    if (sa->sa_family == AF_INET) {
 
-    if (family != AF_INET) {
-        return 0;
-    }
+        sin = (struct sockaddr_in *) sa;
+        p = (u_char *) &sin->sin_addr;
 
-    sin = (struct sockaddr_in *) sa;
-    p = (u_char *) &sin->sin_addr;
-
-    if (len > INET_ADDRSTRLEN) {
-        len = INET_ADDRSTRLEN;
+        return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
+                            p[0], p[1], p[2], p[3])
+               - text;
     }
 
-    n = ngx_sprint_uchar(text, p[0], len);
-
-    i = 1;
-
-    do {
-        if (len == n) {
-            text[n - 1] = '\0';
-            return n;
-        }
-
-        text[n++] = '.';
-
-        if (len == n) {
-            text[n - 1] = '\0';
-            return n;
-        }
-
-        n += ngx_sprint_uchar(&text[n], p[i++], len - n);
-
-    } while (i < 4);
-
-    if (len == n) {
-        text[n] = '\0';
-        return n;
-    }
-
-    text[n] = '\0';
-
-    return n;
+    return 0;
 }
 
 
 size_t
 ngx_inet_ntop(int family, void *addr, u_char *text, size_t len)
 {
-    u_char      *p;
-    size_t       n;
-    ngx_uint_t   i;
-
-    if (len == 0) {
-        return 0;
-    }
+    u_char  *p;
 
-    if (family != AF_INET) {
-        return 0;
-    }
-
-    p = (u_char *) addr;
-
-    if (len > INET_ADDRSTRLEN) {
-        len = INET_ADDRSTRLEN;
-    }
-
-    n = ngx_sprint_uchar(text, p[0], len);
+    if (family == AF_INET) {
 
-    i = 1;
-
-    do {
-        if (len == n) {
-            text[n - 1] = '\0';
-            return n;
-        }
-
-        text[n++] = '.';
+        p = (u_char *) addr;
 
-        if (len == n) {
-            text[n - 1] = '\0';
-            return n;
-        }
-
-        n += ngx_sprint_uchar(&text[n], p[i++], len - n);
-
-    } while (i < 4);
-
-    if (len == n) {
-        text[n] = '\0';
-        return n;
+        return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
+                            p[0], p[1], p[2], p[3])
+               - text;
     }
 
-    text[n] = '\0';
-
-    return n;
-}
-
-
-static size_t
-ngx_sprint_uchar(u_char *text, u_char c, size_t len)
-{
-    size_t      n;
-    ngx_uint_t  c1, c2;
-
-    n = 0;
-
-    if (len == n) {
-        return n;
-    }
-
-    c1 = c / 100;
-
-    if (c1) {
-        *text++ = (u_char) (c1 + '0');
-        n++;
-
-        if (len == n) {
-            return n;
-        }
-    }
-
-    c2 = (c % 100) / 10;
-
-    if (c1 || c2) {
-        *text++ = (u_char) (c2 + '0');
-        n++;
-
-        if (len == n) {
-            return n;
-        }
-    }
-
-    c2 = c % 10;
-
-    *text = (u_char) (c2 + '0');
-    n++;
-
-    return n;
+    return 0;
 }
 
 
@@ -224,43 +102,48 @@ ngx_sprint_uchar(u_char *text, u_char c,
 ngx_int_t
 ngx_ptocidr(ngx_str_t *text, void *cidr)
 {
-    ngx_int_t         m;
-    ngx_uint_t        i;
+    u_char           *addr, *mask, *last;
+    ngx_int_t         shift;
     ngx_inet_cidr_t  *in_cidr;
 
     in_cidr = cidr;
-
-    for (i = 0; i < text->len; i++) {
-        if (text->data[i] == '/') {
-            break;
-        }
-    }
+    addr = text->data;
+    last = addr + text->len;
 
-    if (i == text->len) {
-        return NGX_ERROR;
-    }
+    mask = ngx_strlchr(addr, last, '/');
 
-    text->data[i] = '\0';
-    in_cidr->addr = inet_addr((char *) text->data);
-    text->data[i] = '/';
+    in_cidr->addr = ngx_inet_addr(addr, (mask ? mask : last) - addr);
+
     if (in_cidr->addr == INADDR_NONE) {
         return NGX_ERROR;
     }
 
-    m = ngx_atoi(&text->data[i + 1], text->len - (i + 1));
-    if (m == NGX_ERROR) {
+    if (mask == NULL) {
+        in_cidr->mask = 0xffffffff;
+        return NGX_OK;
+    }
+
+    mask++;
+
+    shift = ngx_atoi(mask, last - mask);
+    if (shift == NGX_ERROR) {
         return NGX_ERROR;
     }
 
-    if (m == 0) {
+    if (shift == 0) {
 
         /* the x86 compilers use the shl instruction that shifts by modulo 32 */
 
         in_cidr->mask = 0;
-        return NGX_OK;
+
+        if (in_cidr->addr == 0) {
+            return NGX_OK;
+        }
+
+        return NGX_DONE;
     }
 
-    in_cidr->mask = htonl((ngx_uint_t) (0 - (1 << (32 - m))));
+    in_cidr->mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift))));
 
     if (in_cidr->addr == (in_cidr->addr & in_cidr->mask)) {
         return NGX_OK;
@@ -275,85 +158,12 @@ ngx_ptocidr(ngx_str_t *text, void *cidr)
 ngx_int_t
 ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
 {
-    u_char              *p, *host, *port_start;
-    size_t               len, port_len;
-    ngx_int_t            port;
-    ngx_uint_t           i;
-    struct hostent      *h;
-#if (NGX_HAVE_UNIX_DOMAIN)
-    struct sockaddr_un  *saun;
-#endif
+    u_char  *p;
 
-    len = u->url.len;
     p = u->url.data;
 
     if (ngx_strncasecmp(p, (u_char *) "unix:", 5) == 0) {
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
-        p += 5;
-        len -= 5;
-
-        u->uri.len = len;
-        u->uri.data = p;
-
-        if (u->uri_part) {
-            for (i = 0; i < len; i++) {
-
-                if (p[i] == ':') {
-                    len = i;
-
-                    u->uri.len -= len + 1;
-                    u->uri.data += len + 1;
-
-                    break;
-                }
-            }
-        }
-
-        if (len == 0) {
-            u->err = "no path in the unix domain socket";
-            return NGX_ERROR;
-        }
-
-        if (len + 1 > sizeof(saun->sun_path)) {
-            u->err = "too long path in the unix domain socket";
-            return NGX_ERROR;
-        }
-
-        u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
-        if (u->addrs == NULL) {
-            return NGX_ERROR;
-        }
-
-        saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));
-        if (saun == NULL) {
-            return NGX_ERROR;
-        }
-
-        u->naddrs = 1;
-
-        saun->sun_family = AF_UNIX;
-        (void) ngx_cpystrn((u_char *) saun->sun_path, p, len + 1);
-
-        u->addrs[0].sockaddr = (struct sockaddr *) saun;
-        u->addrs[0].socklen = sizeof(struct sockaddr_un);
-        u->addrs[0].name.len = len + 5;
-        u->addrs[0].name.data = u->url.data;
-
-        u->host.len = len;
-        u->host.data = p;
-
-        u->unix_socket = 1;
-
-        return NGX_OK;
-
-#else
-        u->err = "the unix domain sockets are not supported on this platform";
-
-        return NGX_ERROR;
-
-#endif
+        return ngx_parse_unix_domain_url(pool, u);
     }
 
     if ((p[0] == ':' || p[0] == '/') && !u->listen) {
@@ -361,150 +171,219 @@ ngx_parse_url(ngx_pool_t *pool, ngx_url_
         return NGX_ERROR;
     }
 
-    u->host.data = p;
+    return ngx_parse_inet_url(pool, u);
+}
 
-    port_start = NULL;
-    port_len = 0;
-
-    for (i = 0; i < len; i++) {
 
-        if (p[i] == ':') {
-            port_start = &p[i + 1];
-            u->host.len = i;
-
-            if (!u->uri_part) {
-                port_len = len - (i + 1);
-                break;
-            }
-        }
+static ngx_int_t
+ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)
+{
+#if (NGX_HAVE_UNIX_DOMAIN)
+    u_char              *path, *uri, *last;
+    size_t               len;
+    struct sockaddr_un  *saun;
 
-        if (p[i] == '/') {
-            u->uri.len = len - i;
-            u->uri.data = &p[i];
+    len = u->url.len;
+    path = u->url.data;
 
-            if (u->host.len == 0) {
-                u->host.len = i;
-            }
+    path += 5;
+    len -= 5;
+
+    if (u->uri_part) {
 
-            if (port_start == NULL) {
-                u->no_port = 1;
-                goto no_port;
-            }
-
-            port_len = &p[i] - port_start;
+        last = path + len;
+        uri = ngx_strlchr(path, last, ':');
 
-            if (port_len == 0) {
-                u->err = "invalid port";
-                return NGX_ERROR;
-            }
-
-            break;
+        if (uri) {
+            len = uri - path;
+            uri++;
+            u->uri.len = last - uri;
+            u->uri.data = uri;
         }
     }
 
-    if (port_start) {
+    if (len == 0) {
+        u->err = "no path in the unix domain socket";
+        return NGX_ERROR;
+    }
+
+    u->host.len = len++;
+    u->host.data = path;
+    u->family = AF_UNIX;
+
+    if (len > sizeof(saun->sun_path)) {
+        u->err = "too long path in the unix domain socket";
+        return NGX_ERROR;
+    }
 
-        if (port_len == 0) {
-            port_len = &p[i] - port_start;
+    u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
+    if (u->addrs == NULL) {
+        return NGX_ERROR;
+    }
+
+    saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));
+    if (saun == NULL) {
+        return NGX_ERROR;
+    }
+
+    u->naddrs = 1;
+
+    saun->sun_family = AF_UNIX;
+    (void) ngx_cpystrn((u_char *) saun->sun_path, path, len);
+
+    u->addrs[0].sockaddr = (struct sockaddr *) saun;
+    u->addrs[0].socklen = sizeof(struct sockaddr_un);
+    u->addrs[0].name.len = len + 4;
+    u->addrs[0].name.data = u->url.data;
 
-            if (port_len == 0) {
-                u->err = "invalid port";
-                return NGX_ERROR;
-            }
+    return NGX_OK;
+
+#else
+
+    u->err = "the unix domain sockets are not supported on this platform";
+
+    return NGX_ERROR;
+
+#endif
+}
+
+
+static ngx_int_t
+ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
+{
+    u_char          *p, *host, *port, *last, *uri;
+    size_t           len;
+    ngx_int_t        n;
+    struct hostent  *h;
+
+    u->family = AF_INET;
+
+    host = u->url.data;
+
+    last = host + u->url.len;
+
+    port = ngx_strlchr(host, last, ':');
+
+    uri = ngx_strlchr(port ? port : host, last, '/');
+
+    if (uri) {
+        if (u->listen || !u->uri_part) {
+            u->err = "invalid host";
+            return NGX_ERROR;
         }
 
-        port = ngx_atoi(port_start, port_len);
+        u->uri.len = last - uri;
+        u->uri.data = uri;
+
+        last = uri;
+    }
 
-        if (port == NGX_ERROR || port < 1 || port > 65536) {
+    if (port) {
+        port++;
+
+        len = last - port;
+
+        if (len == 0) {
             u->err = "invalid port";
             return NGX_ERROR;
         }
 
-        u->port_text.len = port_len;
-        u->port_text.data = port_start;
-
-    } else {
-        port = ngx_atoi(p, len);
-
-        if (port == NGX_ERROR) {
-            u->host.len = len;
-            u->no_port = 1;
-
-            goto no_port;
-        }
-
-        u->wildcard = 1;
-    }
+        n = ngx_atoi(port, len);
 
-    u->port = (in_port_t) port;
-
-no_port:
-
-    if (u->listen) {
-
-        if (u->port == 0) {
-            if (u->default_port == 0) {
-                u->err = "no port";
-                return NGX_ERROR;
-            }
-
-            u->port = u->default_port;
-        }
-
-        if (u->host.len == 1 && u->host.data[0] == '*') {
-            u->host.len = 0;
+        if (n < 1 || n > 65536) {
+            u->err = "invalid port";
+            return NGX_ERROR;
         }
 
-        /* AF_INET only */
+        u->port = (in_port_t) n;
 
-        if (u->host.len) {
+        u->port_text.len = len;
+        u->port_text.data = port;
+
+        last = port - 1;
 
-            host = ngx_alloc(u->host.len + 1, pool->log);
-            if (host == NULL) {
-                return NGX_ERROR;
-            }
+    } else {
+        if (uri == NULL) {
 
-            (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
+            if (u->listen) {
 
-            u->addr.in_addr = inet_addr((const char *) host);
+                /* test value as port only */
+
+                n = ngx_atoi(host, last - host);
 
-            if (u->addr.in_addr == INADDR_NONE) {
-                h = gethostbyname((const char *) host);
+                if (n != NGX_ERROR) {
+
+                    if (n < 1 || n > 65536) {
+                        u->err = "invalid port";
+                        return NGX_ERROR;
+                    }
 
-                if (h == NULL || h->h_addr_list[0] == NULL) {
-                    ngx_free(host);
-                    u->err = "host not found";
-                    return NGX_ERROR;
+                    u->port = (in_port_t) n;
+
+                    u->port_text.len = last - host;
+                    u->port_text.data = host;
+
+                    return NGX_OK;
                 }
-
-                u->addr.in_addr = *(in_addr_t *) (h->h_addr_list[0]);
             }
-
-            ngx_free(host);
-
-        } else {
-            u->addr.in_addr = INADDR_ANY;
         }
 
-        return NGX_OK;
+        u->no_port = 1;
     }
 
-    if (u->host.len == 0) {
+    len = last - host;
+
+    if (len == 0) {
         u->err = "no host";
         return NGX_ERROR;
     }
 
+    if (len == 1 && *host == '*') {
+        len = 0;
+    }
+
+    u->host.len = len;
+    u->host.data = host;
+
     if (u->no_resolve) {
         return NGX_OK;
     }
 
+    if (len++) {
+
+        p = ngx_alloc(len, pool->log);
+        if (p == NULL) {
+            return NGX_ERROR;
+        }
+
+        (void) ngx_cpystrn(p, host, len);
+
+        u->addr.in_addr = inet_addr((const char *) p);
+
+        if (u->addr.in_addr == INADDR_NONE) {
+            h = gethostbyname((const char *) p);
+
+            if (h == NULL || h->h_addr_list[0] == NULL) {
+                ngx_free(p);
+                u->err = "host not found";
+                return NGX_ERROR;
+            }
+
+            u->addr.in_addr = *(in_addr_t *) (h->h_addr_list[0]);
+        }
+
+        ngx_free(p);
+
+    } else {
+        u->addr.in_addr = INADDR_ANY;
+    }
+
     if (u->no_port) {
         u->port = u->default_port;
     }
 
-    if (u->port == 0) {
-        u->err = "no port";
-        return NGX_ERROR;
+    if (u->listen) {
+        return NGX_OK;
     }
 
     if (ngx_inet_resolve_host(pool, u) != NGX_OK) {
@@ -576,14 +455,14 @@ ngx_inet_resolve_host(ngx_pool_t *pool, 
             u->addrs[i].sockaddr = (struct sockaddr *) sin;
             u->addrs[i].socklen = sizeof(struct sockaddr_in);
 
-            len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1;
+            len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;
 
             p = ngx_pnalloc(pool, len);
             if (p == NULL) {
                 return NGX_ERROR;
             }
 
-            len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin, p, len);
+            len = ngx_sock_ntop((struct sockaddr *) sin, p, len);
 
             u->addrs[i].name.len = ngx_sprintf(&p[len], ":%d", u->port) - p;
             u->addrs[i].name.data = p;
--- a/src/core/ngx_inet.h
+++ b/src/core/ngx_inet.h
@@ -12,6 +12,9 @@
 #include <ngx_core.h>
 
 
+#define NGX_INET_ADDRSTRLEN  (sizeof("255.255.255.255") - 1)
+
+
 typedef struct {
     in_addr_t         addr;
     in_addr_t         mask;
@@ -31,8 +34,6 @@ typedef struct {
 
 
 typedef struct {
-    ngx_int_t         type;
-
     ngx_str_t         url;
     ngx_str_t         host;
     ngx_str_t         port_text;
@@ -40,15 +41,14 @@ typedef struct {
 
     in_port_t         port;
     in_port_t         default_port;
+    int               family;
 
     unsigned          listen:1;
     unsigned          uri_part:1;
     unsigned          no_resolve:1;
     unsigned          one_addr:1;
 
-    unsigned          wildcard:1;
     unsigned          no_port:1;
-    unsigned          unix_socket:1;
 
     ngx_url_addr_t    addr;
 
@@ -60,7 +60,7 @@ typedef struct {
 
 
 in_addr_t ngx_inet_addr(u_char *text, size_t len);
-size_t ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, size_t len);
+size_t ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len);
 size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
 ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr);
 ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u);
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -54,8 +54,24 @@ void ngx_strlow(u_char *dst, u_char *src
 
 
 #define ngx_strstr(s1, s2)  strstr((const char *) s1, (const char *) s2)
+#define ngx_strlen(s)       strlen((const char *) s)
+
 #define ngx_strchr(s1, c)   strchr((const char *) s1, (int) c)
-#define ngx_strlen(s)       strlen((const char *) s)
+
+static ngx_inline u_char *
+ngx_strlchr(u_char *p, u_char *last, u_char c)
+{
+    while (p < last) {
+
+        if (*p == c) {
+            return p;
+        }
+
+        p++;
+    }
+
+    return NULL;
+}
 
 
 /*
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -1051,13 +1051,6 @@ ngx_event_debug_connection(ngx_conf_t *c
         return NGX_CONF_ERROR;
     }
 
-    dc->addr = inet_addr((char *) value[1].data);
-
-    if (dc->addr != INADDR_NONE) {
-        dc->mask = 0xffffffff;
-        return NGX_CONF_OK;
-    }
-
     rc = ngx_ptocidr(&value[1], &in_cidr);
 
     if (rc == NGX_DONE) {
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -207,8 +207,7 @@ ngx_event_accept(ngx_event_t *ev)
                 return;
             }
 
-            c->addr_text.len = ngx_sock_ntop(ls->family, c->sockaddr,
-                                             c->addr_text.data,
+            c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->addr_text.data,
                                              ls->addr_text_max_len);
             if (c->addr_text.len == 0) {
                 ngx_close_accepted_connection(c);
--- a/src/http/modules/ngx_http_access_module.c
+++ b/src/http/modules/ngx_http_access_module.c
@@ -166,14 +166,6 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx
         return NGX_CONF_OK;
     }
 
-    rule->addr = inet_addr((char *) value[1].data);
-
-    if (rule->addr != INADDR_NONE) {
-        rule->mask = 0xffffffff;
-
-        return NGX_CONF_OK;
-    }
-
     rc = ngx_ptocidr(&value[1], &in_cidr);
 
     if (rc == NGX_ERROR) {
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -2546,7 +2546,7 @@ static ngx_int_t
 ngx_http_proxy_set_vars(ngx_pool_t *pool, ngx_url_t *u,
     ngx_http_proxy_vars_t *v)
 {
-    if (!u->unix_socket) {
+    if (u->family != AF_UNIX) {
         if (u->no_port || u->port == u->default_port) {
             v->host_header = u->host;
 
--- a/src/http/modules/ngx_http_realip_module.c
+++ b/src/http/modules/ngx_http_realip_module.c
@@ -251,14 +251,6 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx
 
     value = cf->args->elts;
 
-    from->addr = inet_addr((char *) value[1].data);
-
-    if (from->addr != INADDR_NONE) {
-        from->mask = 0xffffffff;
-
-        return NGX_CONF_OK;
-    }
-
     rc = ngx_ptocidr(&value[1], &in_cidr);
 
     if (rc == NGX_ERROR) {
--- a/src/http/modules/ngx_http_xslt_filter_module.c
+++ b/src/http/modules/ngx_http_xslt_filter_module.c
@@ -136,6 +136,7 @@ static void *ngx_http_xslt_filter_create
 static char *ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent,
     void *child);
 static ngx_int_t ngx_http_xslt_filter_init(ngx_conf_t *cf);
+static void ngx_http_xslt_filter_exit(ngx_cycle_t *cycle);
 
 
 ngx_str_t  ngx_http_xslt_default_types[] = {
@@ -196,8 +197,8 @@ ngx_module_t  ngx_http_xslt_filter_modul
     NULL,                                  /* init process */
     NULL,                                  /* init thread */
     NULL,                                  /* exit thread */
-    NULL,                                  /* exit process */
-    NULL,                                  /* exit master */
+    ngx_http_xslt_filter_exit,            /* exit process */
+    ngx_http_xslt_filter_exit,             /* exit master */
     NGX_MODULE_V1_PADDING
 };
 
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
     HTTP_INSUFFICIENT_STORAGE
 );
 
-our $VERSION = '0.7.11';
+our $VERSION = '0.7.12';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1625,8 +1625,8 @@ ngx_http_server_addr(ngx_http_request_t 
         return NGX_OK;
     }
 
-    s->len = ngx_inet_ntop(c->listening->family, &r->in_addr,
-                           s->data, INET_ADDRSTRLEN);
+    s->len = ngx_sock_ntop((struct sockaddr *) &sin, s->data,
+                           NGX_INET_ADDRSTRLEN);
 
     return NGX_OK;
 }
@@ -1672,6 +1672,10 @@ ngx_http_gzip_ok(ngx_http_request_t *r)
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
+    if (r->headers_in.msie6 && clcf->gzip_disable_msie6) {
+        return NGX_DECLINED;
+    }
+
     if (r->http_version < clcf->gzip_http_version) {
         return NGX_DECLINED;
     }
@@ -2677,6 +2681,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t
     lcf->gzip_http_version = NGX_CONF_UNSET_UINT;
 #if (NGX_PCRE)
     lcf->gzip_disable = NGX_CONF_UNSET_PTR;
+    lcf->gzip_disable_msie6 = 3;
 #endif
 #endif
 
@@ -2914,6 +2919,11 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
     ngx_conf_merge_ptr_value(conf->gzip_disable, prev->gzip_disable, NULL);
 #endif
 
+    if (conf->gzip_disable_msie6 == 3) {
+        conf->gzip_disable_msie6 =
+            (prev->gzip_disable_msie6 == 3) ? 0 : prev->gzip_disable_msie6;
+    }
+
 #endif
 
     return NGX_CONF_OK;
@@ -2962,7 +2972,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
 
     ngx_memzero(ls, sizeof(ngx_http_listen_t));
 
-    ls->family = AF_INET;
+    ls->family = u.family;
     ls->addr = u.addr.in_addr;
     ls->port = u.port;
     ls->file_name = cf->conf_file->file.name.data;
@@ -2971,7 +2981,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
     ls->conf.rcvbuf = -1;
     ls->conf.sndbuf = -1;
 
-    n = ngx_inet_ntop(AF_INET, &ls->addr, ls->conf.addr, INET_ADDRSTRLEN + 6);
+    n = ngx_inet_ntop(AF_INET, &ls->addr, ls->conf.addr, NGX_INET_ADDRSTRLEN);
     ngx_sprintf(&ls->conf.addr[n], ":%ui", ls->port);
 
     if (cf->args->nelts == 2) {
@@ -3094,17 +3104,24 @@ ngx_http_core_server_name(ngx_conf_t *cf
 
     ch = value[1].data[0];
 
-    if (cscf->server_name.data == NULL && value[1].len) {
-        name = value[1];
-
-        if (ch == '.') {
-            name.len--;
-            name.data++;
-        }
-
-        cscf->server_name.len = name.len;
-        cscf->server_name.data = ngx_pstrdup(cf->pool, &name);
-        if (cscf->server_name.data == NULL) {
+    if (cscf->server_name.data == NULL) {
+        if (value[1].len) {
+            name = value[1];
+
+            if (ch == '.') {
+                name.len--;
+                name.data++;
+            }
+
+            cscf->server_name.len = name.len;
+            cscf->server_name.data = ngx_pstrdup(cf->pool, &name);
+            if (cscf->server_name.data == NULL) {
+                return NGX_CONF_ERROR;
+            }
+
+        } else {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "the first server name must not be empty");
             return NGX_CONF_ERROR;
         }
     }
@@ -3113,8 +3130,7 @@ ngx_http_core_server_name(ngx_conf_t *cf
 
         ch = value[i].data[0];
 
-        if (value[i].len == 0
-            || (ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
+        if ((ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
             || (ch == '.' && value[i].len < 2))
         {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -3747,8 +3763,9 @@ ngx_http_core_resolver(ngx_conf_t *cf, n
 static char *
 ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
+    ngx_http_core_loc_conf_t  *clcf = conf;
+
 #if (NGX_PCRE)
-    ngx_http_core_loc_conf_t  *clcf = conf;
 
     ngx_str_t         err, *value;
     ngx_uint_t        i;
@@ -3770,6 +3787,11 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ng
 
     for (i = 1; i < cf->args->nelts; i++) {
 
+        if (ngx_strcmp(value[1].data, "msie6") == 0) {
+            clcf->gzip_disable_msie6 = 1;
+            continue;
+        }
+
         re = ngx_array_push(clcf->gzip_disable);
         if (re == NULL) {
             return NGX_CONF_ERROR;
@@ -3789,8 +3811,18 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ng
     return NGX_CONF_OK;
 
 #else
+    ngx_str_t  *value;
+
+    value = cf->args->elts;
+
+    if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "msie6") == 0) {
+        clcf->gzip_disable_msie6 = 1;
+        return NGX_CONF_OK;
+    }
+
     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                       "\"gzip_disable\" requires PCRE library");
+                       "without PCRE library \"gzip_disable\" supports "
+                       "builtin \"msie6\" mask only");
 
     return NGX_CONF_ERROR;
 #endif
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -47,7 +47,7 @@ typedef struct {
     ngx_uint_t                 deferred_accept;
 #endif
 
-    u_char                     addr[INET_ADDRSTRLEN + 6];
+    u_char                     addr[NGX_INET_ADDRSTRLEN + sizeof(":65535")];
 
 } ngx_http_listen_conf_t;
 
@@ -242,6 +242,9 @@ struct ngx_http_core_loc_conf_s {
 
     unsigned      auto_redirect:1;
     unsigned      alias:1;
+#if (NGX_HTTP_GZIP)
+    unsigned      gzip_disable_msie6:2;
+#endif
 
     ngx_http_location_tree_node_t   *static_locations;
     ngx_http_core_loc_conf_t       **regex_locations;
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -162,7 +162,7 @@ ngx_http_header_filter(ngx_http_request_
     ngx_http_core_loc_conf_t  *clcf;
     ngx_http_core_srv_conf_t  *cscf;
     /* AF_INET only */
-    u_char                     addr[INET_ADDRSTRLEN];
+    u_char                     addr[NGX_INET_ADDRSTRLEN];
 
     r->header_sent = 1;
 
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -74,15 +74,18 @@ static char *ngx_http_client_errors[] = 
 
 
 ngx_http_header_t  ngx_http_headers_in[] = {
-    { ngx_string("Host"), 0, ngx_http_process_host },
-
-    { ngx_string("Connection"), 0, ngx_http_process_connection },
+    { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
+                 ngx_http_process_host },
+
+    { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
+                 ngx_http_process_connection },
 
     { ngx_string("If-Modified-Since"),
                  offsetof(ngx_http_headers_in_t, if_modified_since),
                  ngx_http_process_unique_header_line },
 
-    { ngx_string("User-Agent"), 0, ngx_http_process_user_agent },
+    { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
+                 ngx_http_process_user_agent },
 
     { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer),
                  ngx_http_process_header_line },
@@ -568,6 +571,7 @@ ngx_http_ssl_handshake_handler(ngx_conne
 int
 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
 {
+    size_t                    len;
     const char               *servername;
     ngx_connection_t         *c;
     ngx_http_request_t       *r;
@@ -584,12 +588,15 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "SSL server name: \"%s\"", servername);
 
+    len = ngx_strlen(servername);
+
+    if (len == 0) {
+        return SSL_TLSEXT_ERR_NOACK;
+    }
+
     r = c->data;
 
-    if (ngx_http_find_virtual_server(r, (u_char *) servername,
-                                     ngx_strlen(servername))
-        != NGX_OK)
-    {
+    if (ngx_http_find_virtual_server(r, (u_char *) servername, len) != NGX_OK) {
         return SSL_TLSEXT_ERR_NOACK;
     }
 
@@ -1283,7 +1290,7 @@ static ngx_int_t
 ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
-    u_char  *ua, *user_agent;
+    u_char  *user_agent, *msie;
 
     if (r->headers_in.user_agent) {
         return NGX_OK;
@@ -1295,14 +1302,22 @@ ngx_http_process_user_agent(ngx_http_req
 
     user_agent = h->value.data;
 
-    ua = ngx_strstrn(user_agent, "MSIE", 4 - 1);
-
-    if (ua && ua + 8 < user_agent + h->value.len) {
+    msie = ngx_strstrn(user_agent, "MSIE ", 5 - 1);
+
+    if (msie && msie + 7 < user_agent + h->value.len) {
 
         r->headers_in.msie = 1;
 
-        if (ua[4] == ' ' && ua[5] == '4' && ua[6] == '.') {
-            r->headers_in.msie4 = 1;
+        if (msie[6] == '.') {
+
+            switch (msie[5]) {
+            case '4':
+                r->headers_in.msie4 = 1;
+                /* fall through */
+            case '5':
+            case '6':
+                r->headers_in.msie6 = 1;
+            }
         }
 
 #if 0
@@ -1317,6 +1332,7 @@ ngx_http_process_user_agent(ngx_http_req
         r->headers_in.opera = 1;
         r->headers_in.msie = 0;
         r->headers_in.msie4 = 0;
+        r->headers_in.msie6 = 0;
     }
 
     if (!r->headers_in.msie && !r->headers_in.opera) {
@@ -1556,7 +1572,7 @@ ngx_http_find_virtual_server(ngx_http_re
     ngx_http_core_srv_conf_t  *cscf;
     u_char                     buf[32];
 
-    if (len == 0 || r->virtual_names == NULL) {
+    if (r->virtual_names == NULL) {
         return NGX_DECLINED;
     }
 
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -214,6 +214,7 @@ typedef struct {
     unsigned                          connection_type:2;
     unsigned                          msie:1;
     unsigned                          msie4:1;
+    unsigned                          msie6:1;
     unsigned                          opera:1;
     unsigned                          gecko:1;
     unsigned                          konqueror:1;
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -327,7 +327,6 @@ static ngx_str_t  ngx_http_get_name = { 
 ngx_int_t
 ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
 {
-    ngx_int_t                  rc;
     ngx_uint_t                 i, err;
     ngx_http_err_page_t       *err_page;
     ngx_http_core_loc_conf_t  *clcf;
@@ -336,12 +335,6 @@ ngx_http_special_response_handler(ngx_ht
                    "http special response: %d, \"%V?%V\"",
                    error, &r->uri, &r->args);
 
-    rc = ngx_http_discard_request_body(r);
-
-    if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
-        error = NGX_HTTP_INTERNAL_SERVER_ERROR;
-    }
-
     r->err_status = error;
 
     if (r->keepalive) {
@@ -386,6 +379,10 @@ ngx_http_special_response_handler(ngx_ht
         }
     }
 
+    if (ngx_http_discard_request_body(r) != NGX_OK) {
+        error = NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
     if (clcf->msie_refresh
         && r->headers_in.msie
         && (error == NGX_HTTP_MOVED_PERMANENTLY
@@ -493,8 +490,10 @@ ngx_http_send_error_page(ngx_http_reques
 
     if (uri->data[0] == '/') {
 
-        r->method = NGX_HTTP_GET;
-        r->method_name = ngx_http_get_name;
+        if (r->method != NGX_HTTP_HEAD) {
+            r->method = NGX_HTTP_GET;
+            r->method_name = ngx_http_get_name;
+        }
 
         return ngx_http_internal_redirect(r, uri, args);
     }
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -281,14 +281,14 @@ ngx_http_upstream_create_round_robin_pee
 
     for (i = 0; i < ur->naddrs; i++) {
 
-        len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1;
+        len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;
 
         p = ngx_pnalloc(r->pool, len);
         if (p == NULL) {
             return NGX_ERROR;
         }
 
-        len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, INET_ADDRSTRLEN);
+        len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN);
         len = ngx_sprintf(&p[len], ":%d", ur->port) - p;
 
         sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in));
@@ -645,7 +645,9 @@ ngx_http_upstream_free_round_robin_peer(
         peer->fails++;
         peer->accessed = now;
 
-        peer->current_weight -= peer->weight / peer->max_fails;
+        if (peer->max_fails) {
+            peer->current_weight -= peer->weight / peer->max_fails;
+        }
 
         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                        "free rr peer failed: %ui %i",
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -872,7 +872,7 @@ ngx_http_variable_server_addr(ngx_http_r
 {
     ngx_str_t  s;
 
-    s.data = ngx_pnalloc(r->pool, INET_ADDRSTRLEN);
+    s.data = ngx_pnalloc(r->pool, NGX_INET_ADDRSTRLEN);
     if (s.data == NULL) {
         return NGX_ERROR;
     }
--- a/src/mail/ngx_mail.c
+++ b/src/mail/ngx_mail.c
@@ -358,13 +358,13 @@ ngx_mail_block(ngx_conf_t *cf, ngx_comma
                 imip->addrs[i].ctx = in_addr[i].ctx;
 
                 text = ngx_pnalloc(cf->pool,
-                                   INET_ADDRSTRLEN - 1 + sizeof(":65535") - 1);
+                                   NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1);
                 if (text == NULL) {
                     return NGX_CONF_ERROR;
                 }
 
                 len = ngx_inet_ntop(AF_INET, &in_addr[i].addr, text,
-                                    INET_ADDRSTRLEN);
+                                    NGX_INET_ADDRSTRLEN);
 
                 len = ngx_sprintf(text + len, ":%d", in_port[p].port) - text;
 
--- a/src/mail/ngx_mail_core_module.c
+++ b/src/mail/ngx_mail_core_module.c
@@ -329,7 +329,7 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx
 
     imls->addr = u.addr.in_addr;
     imls->port = u.port;
-    imls->family = AF_INET;
+    imls->family = u.family;
     imls->ctx = cf->ctx;
 
     for (m = 0; ngx_modules[m]; m++) {
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -265,10 +265,14 @@ ngx_open_glob(ngx_glob_t *gl)
         return NGX_OK;
     }
 
+#ifdef GLOB_NOMATCH
+
     if (n == GLOB_NOMATCH && gl->test) {
         return NGX_OK;
     }
 
+#endif
+
     return NGX_ERROR;
 }
 
@@ -276,7 +280,7 @@ ngx_open_glob(ngx_glob_t *gl)
 ngx_int_t
 ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
 {
-    if (gl->n < (size_t) gl->pglob.gl_pathc) {
+    if (gl->n < (size_t) gl->pglob.gl_matchc) {
 
         name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]);
         name->data = (u_char *) gl->pglob.gl_pathv[gl->n];