changeset 477:ad1e9ebf93bb release-0.1.13

nginx-0.1.13-RELEASE import *) Feature: the server_names_hash and server_names_hash_threshold directives. *) Bugfix: the *.domain.tld names in the "server_name" directive did not work. *) Bugfix: the %request_length log parameter logged the incorrect length.
author Igor Sysoev <igor@sysoev.ru>
date Tue, 21 Dec 2004 12:30:30 +0000
parents 7e8b84ab09e9
children e6576f690993
files auto/lib/conf auto/lib/md5/conf auto/modules auto/options auto/os/conf auto/os/linux auto/sources auto/summary auto/unix docs/xml/nginx/changes.xml src/core/nginx.h src/core/ngx_config.h src/core/ngx_connection.c src/core/ngx_palloc.c src/core/ngx_string.c src/core/ngx_string.h src/core/ngx_times.c src/core/ngx_times.h src/event/ngx_event_accept.c src/http/modules/ngx_http_charset_filter.c src/http/modules/ngx_http_headers_filter.c src/http/modules/proxy/ngx_http_proxy_handler.c src/http/ngx_http.c src/http/ngx_http.h src/http/ngx_http_cache.c src/http/ngx_http_cache.h src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_file_cache.c src/http/ngx_http_header_filter.c src/http/ngx_http_log_handler.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/http/ngx_http_special_response.c src/os/unix/ngx_aio_write_chain.c src/os/unix/ngx_freebsd_sendfile_chain.c src/os/unix/ngx_linux_sendfile_chain.c src/os/unix/ngx_posix_init.c src/os/unix/ngx_process.c src/os/unix/ngx_process_cycle.c src/os/unix/ngx_process_cycle.h src/os/unix/ngx_solaris_sendfilev_chain.c src/os/unix/ngx_writev_chain.c src/os/win32/ngx_win32_config.h
diffstat 44 files changed, 748 insertions(+), 307 deletions(-) [+]
line wrap: on
line diff
--- a/auto/lib/conf
+++ b/auto/lib/conf
@@ -6,12 +6,21 @@ if [ $USE_PCRE = YES ]; then
     . auto/lib/pcre/conf
 fi
 
-if [ $USE_MD5 = YES ]; then
-    . auto/lib/md5/conf
+if [ $USE_OPENSSL = YES ]; then
+    . auto/lib/openssl/conf
 fi
 
-if [ $USE_OPENSSL = YES ]; then
-    . auto/lib/openssl/conf
+if [ $USE_MD5 = YES ]; then
+
+    if [ $OPENSSL != NONE -a $OPENSSL != NO ]; then
+        have=NGX_HAVE_OPENSSL_MD5_H . auto/have
+        have=NGX_OPENSSL_MD5 . auto/have
+        MD5=YES
+
+    else
+        . auto/lib/md5/conf
+    fi
+
 fi
 
 if [ $USE_ZLIB = YES ]; then
--- a/auto/lib/md5/conf
+++ b/auto/lib/md5/conf
@@ -8,6 +8,7 @@ if [ $MD5 != NONE ]; then
         # OpenSSL md5
         OPENSSL_MD5=YES
         have=NGX_HAVE_OPENSSL_MD5 . auto/have
+        have=NGX_OPENSSL_MD5 . auto/have
     else
         # rsaref md5
         OPENSSL_MD5=NO
--- a/auto/modules
+++ b/auto/modules
@@ -141,6 +141,8 @@ if [ $HTTP_PROXY = YES ]; then
 fi
 
 # STUB
+#USE_MD5=YES
+#HTTP_SRCS="$HTTP_SRCS $HTPP_CACHE_SRCS"
 #HTTP_SRCS="$HTTP_SRCS $HTPP_FILE_CACHE_SRCS"
 
 if [ -r $NGX_OBJS/auto ]; then
--- a/auto/options
+++ b/auto/options
@@ -209,9 +209,7 @@ if [ ".$NGX_PLATFORM" = ".win32" ]; then
 fi
 
 
-if test -z "$NGX_PREFIX"; then
-    NGX_PREFIX=/usr/local/nginx
-fi
+NGX_PREFIX=${NGX_PREFIX:-/usr/local/nginx}
 
 
 case ".$NGX_SBIN_PATH" in
--- a/auto/os/conf
+++ b/auto/os/conf
@@ -45,9 +45,7 @@ esac
 
 if [ $NGX_PLATFORM != win32 ]; then
 
-    if test -z "$NGX_USER"; then
-        NGX_USER=nobody
-    fi
+     NGX_USER=${NGX_USER:-nobody}
 
     if [ -z "$NGX_GROUP" -a $NGX_USER = nobody ] ; then
        if grep nobody /etc/group 2>&1 >/dev/null; then
--- a/auto/os/linux
+++ b/auto/os/linux
@@ -26,6 +26,8 @@ CC_AUX_FLAGS="-D_GNU_SOURCE -D_FILE_OFFS
 version=`grep "#define LINUX_VERSION_CODE" /usr/include/linux/version.h \
          | sed -e 's/^.* \(.*\)$/\1/'`
 
+version=${version:-0}
+
 
 # enable the rt signals on Linux 2.2.19 and onward
 
--- a/auto/sources
+++ b/auto/sources
@@ -207,7 +207,7 @@ HTTP_MODULES="ngx_http_module \
               ngx_http_core_module \
               ngx_http_log_module"
 
-HTTP_FILE_CACHE_MODULE=ngx_http_cache_module
+HTTP_CACHE_MODULE=ngx_http_cache_module
 
 HTTP_WRITE_FILTER_MODULE="ngx_http_write_filter_module"
 HTTP_HEADER_FILTER_MODULE="ngx_http_header_filter_module"
--- a/auto/summary
+++ b/auto/summary
@@ -28,13 +28,6 @@ else
     esac
 fi
 
-case $MD5 in
-    YES)   echo "  + md5: using system $MD5_LIB library" ;;
-    NONE)  echo "  + md5 library is not used" ;;
-    NO)    echo "  + md5 library is not found" ;;
-    *)     echo "  + using md5 library: $MD5" ;;
-esac
-
 case $OPENSSL in
     YES)   echo "  + using system OpenSSL library" ;;
     NONE)  echo "  + OpenSSL library is not used" ;;
@@ -42,6 +35,19 @@ case $OPENSSL in
     *)     echo "  + using OpenSSL library: $OPENSSL" ;;
 esac
 
+case $MD5 in
+    YES)
+        case $OPENSSL in
+            NONE|NO)  echo "  + md5: using system $MD5_LIB library" ;;
+            *)        echo "  + md5: using OpenSSL library" ;;
+        esac
+        ;;
+
+    NONE)  echo "  + md5 library is not used" ;;
+    NO)    echo "  + md5 library is not found" ;;
+    *)     echo "  + using md5 library: $MD5" ;;
+esac
+
 case $ZLIB in
     YES)   echo "  + using system zlib library" ;;
     NONE)  echo "  + zlib library is not used" ;;
--- a/auto/unix
+++ b/auto/unix
@@ -29,7 +29,7 @@ ngx_type="uint64_t"; ngx_types="u_int64_
 
 ngx_type="sig_atomic_t"; ngx_types="int"; . auto/types/typedef
 . auto/types/sizeof
-ngx_param=SIG_ATOMIC_T_SIZE; ngx_value=$ngx_size; . auto/types/value
+ngx_param=NGX_SIG_ATOMIC_T_SIZE; ngx_value=$ngx_size; . auto/types/value
 
 ngx_type="socklen_t"; ngx_types="uint32_t"; . auto/types/typedef
 
@@ -44,14 +44,16 @@ ngx_type="rlim_t"; ngx_types="int"; . au
 . auto/endianess
 
 ngx_type="size_t"; . auto/types/sizeof
-ngx_param=MAX_SIZE_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
+ngx_param=NGX_MAX_SIZE_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
+ngx_param=NGX_SIZE_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
 
 ngx_type="off_t"; . auto/types/sizeof
-ngx_param=MAX_OFF_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
+ngx_param=NGX_MAX_OFF_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
+ngx_param=NGX_OFF_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
 
 ngx_type="time_t"; . auto/types/sizeof
-ngx_param=TIME_T_SIZE; ngx_value=$ngx_size; . auto/types/value
-ngx_param=TIME_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
+ngx_param=NGX_TIME_T_SIZE; ngx_value=$ngx_size; . auto/types/value
+ngx_param=NGX_TIME_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
 
 
 # syscalls, libc calls and some features
--- a/docs/xml/nginx/changes.xml
+++ b/docs/xml/nginx/changes.xml
@@ -6,6 +6,38 @@
             title="nginx">
 
 
+<changes ver="0.1.13" date="21.12.2004">
+
+<change type="feature">
+<para lang="ru">
+директивы server_names_hash и server_names_hash_threshold.
+</para>
+<para lang="en">
+the server_names_hash and server_names_hash_threshold directives.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+имена *.domain.tld в директиве server_name не работали.
+</para>
+<para lang="en">
+the *.domain.tld names in the server_name directive did not work.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+параметр лога %request_length записывал неверную длину.
+</para>
+<para lang="en">
+the %request_length log parameter logged the incorrect length.
+</para>
+</change>
+
+</changes>
+
+
 <changes ver="0.1.12" date="06.12.2004">
 
 <change type="feature">
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VER          "nginx/0.1.12"
+#define NGINX_VER          "nginx/0.1.13"
 
 #define NGINX_VAR          "NGINX"
 #define NGX_NEWPID_EXT     ".newbin"
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -87,12 +87,8 @@ typedef long               ngx_flag_t;
 
 #endif
 
-/* TODO: auto */
 #define NGX_INT32_LEN      sizeof("-2147483648") - 1
 #define NGX_INT64_LEN      sizeof("-9223372036854775808") - 1
-#define NGX_OFF_T_LEN      sizeof("-9223372036854775808") - 1
-
-#define NGX_MAX_INT_LEN    (sizeof("-9223372036854775808") - 1)
 
 
 #if (NGX_SOLARIS)
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -253,7 +253,7 @@ ngx_int_t ngx_open_listening_sockets(ngx
     }
 
     if (failed) {
-        ngx_log_error(NGX_LOG_EMERG, log, 0, "still can not bind()");
+        ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()");
         return NGX_ERROR;
     }
 
--- a/src/core/ngx_palloc.c
+++ b/src/core/ngx_palloc.c
@@ -36,7 +36,7 @@ void ngx_destroy_pool(ngx_pool_t *pool)
         ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
 
         if (l->alloc) {
-            free(l->alloc);
+            ngx_free(l->alloc);
         }
     }
 
@@ -59,7 +59,7 @@ void ngx_destroy_pool(ngx_pool_t *pool)
 #endif
 
     for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
-        free(p);
+        ngx_free(p);
 
         if (n == NULL) {
             break;
@@ -163,7 +163,7 @@ ngx_int_t ngx_pfree(ngx_pool_t *pool, vo
         if (p == l->alloc) {
             ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
                            "free: %p", l->alloc);
-            free(l->alloc);
+            ngx_free(l->alloc);
             l->alloc = NULL;
 
             return NGX_OK;
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -86,7 +86,7 @@ u_char *ngx_snprintf(u_char *buf, size_t
 
 u_char *ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
 {
-    u_char         *p, zero, *last, temp[NGX_MAX_INT_LEN];
+    u_char         *p, zero, *last, temp[NGX_INT64_LEN];
     int             d;
     size_t          len;
     uint32_t        ui32;
@@ -120,7 +120,7 @@ u_char *ngx_vsnprintf(u_char *buf, size_
             sign = 1;
             hexadecimal = 0;
 
-            p = temp + NGX_MAX_INT_LEN;
+            p = temp + NGX_INT64_LEN;
 
             while (*fmt >= '0' && *fmt <= '9') {
                 width = width * 10 + *fmt++ - '0';
@@ -337,13 +337,13 @@ u_char *ngx_vsnprintf(u_char *buf, size_
                 } while (ui64 /= 10);
             }
 
-            len = (temp + NGX_MAX_INT_LEN) - p;
+            len = (temp + NGX_INT64_LEN) - p;
 
             while (len++ < width && buf < last) {
                 *buf++ = zero;
             }
 
-            len = (temp + NGX_MAX_INT_LEN) - p;
+            len = (temp + NGX_INT64_LEN) - p;
             if (buf + len > last) {
                 len = last - buf;
             }
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -22,6 +22,9 @@ typedef struct {
 #define ngx_null_string  { 0, NULL }
 
 
+#define ngx_tolower(c)     (u_char) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c)
+
+
 #if (NGX_WIN32)
 
 #define ngx_strncasecmp(s1, s2, n)                                           \
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -41,7 +41,7 @@ static ngx_mutex_t     *ngx_time_mutex;
 #endif
 
 
-#if (NGX_THREADS && (TIME_T_SIZE > SIG_ATOMIC_T_SIZE))
+#if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE))
 
 volatile time_t  *ngx_cached_time;
 static time_t     cached_time[NGX_TIME_SLOTS];
@@ -84,7 +84,7 @@ void ngx_time_init()
     ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1;
     ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1;
 
-#if (NGX_THREADS && (TIME_T_SIZE > SIG_ATOMIC_T_SIZE))
+#if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE))
     ngx_cached_time = &cached_time[0];
 #endif
 
@@ -137,7 +137,7 @@ void ngx_time_update(time_t s)
         slot++;
     }
 
-#if (NGX_THREADS && (TIME_T_SIZE > SIG_ATOMIC_T_SIZE))
+#if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE))
     ngx_cached_time = &cached_time[slot];
 #endif
 
--- a/src/core/ngx_times.h
+++ b/src/core/ngx_times.h
@@ -22,7 +22,7 @@ void ngx_gmtime(time_t t, ngx_tm_t *tp);
 ngx_int_t ngx_time_mutex_init(ngx_log_t *log);
 #endif
 
-#if (NGX_THREADS && (TIME_T_SIZE > SIG_ATOMIC_T_SIZE))
+#if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE))
 
 #define ngx_time()        *ngx_cached_time
 extern volatile time_t    *ngx_cached_time;
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -96,6 +96,7 @@ void ngx_event_accept(ngx_event_t *ev)
         len = ls->listening->socklen;
 
         s = accept(ls->fd, sa, &len);
+
         if (s == -1) {
             err = ngx_socket_errno;
 
--- a/src/http/modules/ngx_http_charset_filter.c
+++ b/src/http/modules/ngx_http_charset_filter.c
@@ -147,12 +147,6 @@ static ngx_int_t ngx_http_charset_header
         return ngx_http_next_header_filter(r);
     }
 
-#if 0
-    if (lcf->default_charset.len == 0) {
-        return ngx_http_next_header_filter(r);
-    }
-#endif
-
     if (r->headers_out.content_type == NULL) {
         return ngx_http_next_header_filter(r);
     }
@@ -559,12 +553,36 @@ static char *ngx_http_charset_merge_loc_
     ngx_conf_merge_value(conf->enable, prev->enable, 0);
     ngx_conf_merge_value(conf->autodetect, prev->autodetect, 0);
 
+
+    if (conf->default_charset == NGX_CONF_UNSET) {
+        conf->default_charset = prev->default_charset;
+    }
+
     if (conf->source_charset == NGX_CONF_UNSET) {
         conf->source_charset = prev->source_charset;
     }
 
-    ngx_conf_merge_value(conf->default_charset, prev->default_charset,
-                         conf->source_charset);
+    if (conf->default_charset == NGX_CONF_UNSET
+        && conf->source_charset != NGX_CONF_UNSET)
+    {
+        conf->default_charset = conf->source_charset;
+    }
+
+    if (conf->source_charset == NGX_CONF_UNSET
+        && conf->default_charset != NGX_CONF_UNSET)
+    {
+        conf->source_charset = conf->default_charset;
+    }
+
+    if (conf->enable
+        && (conf->default_charset == NGX_CONF_UNSET
+            || conf->source_charset == NGX_CONF_UNSET))
+    {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "the \"source_charset\" or \"default_charset\" "
+                           "must be specified when \"charset\" is on");
+        return NGX_CONF_ERROR;
+    }
 
     return NGX_CONF_OK;
 }
--- a/src/http/modules/ngx_http_headers_filter.c
+++ b/src/http/modules/ngx_http_headers_filter.c
@@ -128,8 +128,8 @@ static ngx_int_t ngx_http_headers_filter
                     cc->value.data = (u_char *) "no-cache";
 
                 } else {
-                    cc->value.data = ngx_palloc(r->pool,
-                                          sizeof("max-age=") + TIME_T_LEN + 1);
+                    cc->value.data = ngx_palloc(r->pool, sizeof("max-age=")
+                                                         + NGX_TIME_T_LEN + 1);
                     if (cc->value.data == NULL) {
                         return NGX_ERROR;
                     }
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -11,6 +11,7 @@
 
 
 static ngx_int_t ngx_http_proxy_handler(ngx_http_request_t *r);
+static ngx_int_t ngx_http_proxy_cache_get(ngx_http_proxy_ctx_t *p);
 
 static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r,
                                               u_char *buf, uintptr_t data);
@@ -147,14 +148,14 @@ static ngx_command_t  ngx_http_proxy_com
       offsetof(ngx_http_proxy_loc_conf_t, busy_buffers_size),
       NULL },
 
-#if (NGX_HTTP_FILE_CACHE)
+#if 0
 
     { ngx_string("proxy_cache_path"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
       ngx_conf_set_path_slot,
       NGX_HTTP_LOC_CONF_OFFSET,
       offsetof(ngx_http_proxy_loc_conf_t, cache_path),
-      ngx_garbage_collector_http_cache_handler },
+      (void *) ngx_http_cache_cleaner_handler },
 
 #endif
 
@@ -351,17 +352,19 @@ static ngx_int_t ngx_http_proxy_handler(
     /* TODO: we currently support reverse proxy only */
     p->accel = 1;
 
-    ngx_init_array(p->states, r->pool, p->lcf->peers->number,
-                   sizeof(ngx_http_proxy_state_t),
-                   NGX_HTTP_INTERNAL_SERVER_ERROR);
+    if (ngx_array_init(&p->states, r->pool, p->lcf->peers->number,
+                                  sizeof(ngx_http_proxy_state_t)) == NGX_ERROR)
+    {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
 
-    if (!(p->state = ngx_push_array(&p->states))) {
+    if (!(p->state = ngx_array_push(&p->states))) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
     ngx_memzero(p->state, sizeof(ngx_http_proxy_state_t));
 
-#if (NGX_HTTP_FILE_CACHE)
+#if 0
 
     if (!p->lcf->cache
         || (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD))
@@ -387,7 +390,7 @@ static ngx_int_t ngx_http_proxy_handler(
         return ngx_http_proxy_request_upstream(p);
     }
 
-    return ngx_http_proxy_get_cached_response(p);
+    return ngx_http_proxy_cache_get(p);
 
 #else
 
@@ -399,6 +402,52 @@ static ngx_int_t ngx_http_proxy_handler(
 }
 
 
+#if 0
+
+static ngx_int_t ngx_http_proxy_cache_get(ngx_http_proxy_ctx_t *p)
+{
+    u_char                          *last;
+    ngx_http_request_t              *r;
+    ngx_http_cache_ctx_t             ctx;
+    ngx_http_proxy_upstream_conf_t  *u;
+
+    r = p->request;
+    u = p->lcf->upstream;
+
+    ctx.key.len = u->url.len + r->uri.len - u->location->len + r->args.len;
+    if (!(ctx.key.data = ngx_palloc(r->pool, ctx.key.len))) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    last = ngx_cpymem(ctx.key.data, u->url.data, u->url.len);
+
+    last = ngx_cpymem(last, r->uri.data + u->location->len,
+                      r->uri.len - u->location->len);
+
+    if (r->args.len > 0) {
+        *(last++) = '?';
+        last = ngx_cpymem(last, r->args.data, r->args.len);
+    }
+
+    p->header_in = ngx_create_temp_buf(r->pool, p->lcf->header_buffer_size);
+    if (p->header_in == NULL) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+    p->header_in->tag = (ngx_buf_tag_t) &ngx_http_proxy_module;
+
+    ctx.buf = p->header_in;
+    ctx.path = p->lcf->cache_path;
+    ctx.file = 1;
+    ctx.primary = 1;
+
+    ngx_http_cache_get(r, &ctx);
+
+    return ngx_http_proxy_request_upstream(p);
+}
+
+#endif
+
+
 void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
 {
     int                    n;
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -11,6 +11,7 @@
 
 
 static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+static int ngx_cmp_server_names(const void *one, const void *two);
 static ngx_int_t ngx_http_add_address(ngx_conf_t *cf,
                                       ngx_http_in_port_t *in_port,
                                       ngx_http_listen_t *lscf,
@@ -69,7 +70,7 @@ static char *ngx_http_block(ngx_conf_t *
 {
     char                        *rv;
     ngx_uint_t                   mi, m, s, l, p, a, n;
-    ngx_uint_t                   port_found, addr_found, virtual_names;
+    ngx_uint_t                   port_found, addr_found, virtual_names, key;
     ngx_conf_t                   pcf;
     ngx_array_t                  in_ports;
     ngx_listening_t             *ls;
@@ -92,7 +93,9 @@ static char *ngx_http_block(ngx_conf_t *
     ngx_memzero(&in_ports, sizeof(ngx_array_t));
 #endif
 
+
     /* the main http context */
+
     ngx_test_null(ctx,
                   ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
                   NGX_CONF_ERROR);
@@ -111,6 +114,7 @@ static char *ngx_http_block(ngx_conf_t *
     }
 
     /* the main http main_conf, it's the same in the all http contexts */
+
     ngx_test_null(ctx->main_conf,
                   ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
                   NGX_CONF_ERROR);
@@ -376,6 +380,8 @@ static char *ngx_http_block(ngx_conf_t *
 
                             in_addr[a].addr = lscf[l].addr;
                             in_addr[a].names.elts = NULL;
+                            in_addr[a].hash = NULL;
+                            in_addr[a].wildcards.elts = NULL;
                             in_addr[a].default_server = lscf[l].default_server;
                             in_addr[a].core_srv_conf = cscfp[s];
 
@@ -464,6 +470,19 @@ static char *ngx_http_block(ngx_conf_t *
                 }
             }
 
+            if (!virtual_names) {
+                name = in_addr[a].wildcards.elts;
+                for (n = 0; n < in_addr[a].wildcards.nelts; n++) {
+                    if (in_addr[a].core_srv_conf != name[n].core_srv_conf
+                        || name[n].core_srv_conf->restrict_host_names
+                                                 != NGX_HTTP_RESTRICT_HOST_OFF)
+                    {
+                        virtual_names = 1;
+                        break;
+                    }
+                }
+            }
+
             /*
              * if all name-based servers have the same configuration
              * as the default server, and no servers restrict the host names
@@ -472,12 +491,50 @@ static char *ngx_http_block(ngx_conf_t *
 
             if (!virtual_names) {
                 in_addr[a].names.nelts = 0;
+                continue;
+            }
+
+
+            ngx_qsort(in_addr[a].names.elts, in_addr[a].names.nelts,
+                      sizeof(ngx_http_server_name_t), ngx_cmp_server_names);
+
+
+            /* create a hash for many names */
+
+            if (in_addr[a].names.nelts > cmcf->server_names_hash_threshold) {
+                in_addr[a].hash = ngx_palloc(cf->pool,
+                                             cmcf->server_names_hash
+                                                        * sizeof(ngx_array_t));
+                if (in_addr[a].hash == NULL) {
+                    return NGX_CONF_ERROR;
+                }
+
+                for (n = 0; n < cmcf->server_names_hash; n++) {
+                    if (ngx_array_init(&in_addr[a].hash[n], cf->pool, 5,
+                                  sizeof(ngx_http_server_name_t)) == NGX_ERROR)
+                    {
+                        return NGX_CONF_ERROR;
+                    }
+                }
+
+                name = in_addr[a].names.elts;
+                for (s = 0; s < in_addr[a].names.nelts; s++) {
+                    ngx_http_server_names_hash_key(key, name[s].name.data,
+                                                   name[s].name.len,
+                                                   cmcf->server_names_hash);
+
+                    if (!(s_name = ngx_array_push(&in_addr[a].hash[key]))) {
+                        return NGX_CONF_ERROR;
+                    }
+
+                    *s_name = name[s];
+                }
             }
         }
 
         /*
-         * if there's the binding to "*:port" then we need to bind()
-         * to "*:port" only and ignore the other bindings
+         * if there is the binding to the "*:port" then we need to bind()
+         * to the "*:port" only and ignore the other bindings
          */
 
         if (in_addr[a - 1].addr == INADDR_ANY) {
@@ -604,6 +661,15 @@ static char *ngx_http_block(ngx_conf_t *
 }
 
 
+static int ngx_cmp_server_names(const void *one, const void *two)
+{
+    ngx_http_server_name_t *first = (ngx_http_server_name_t *) one;
+    ngx_http_server_name_t *second = (ngx_http_server_name_t *) two;
+
+    return ngx_strcmp(first->name.data, second->name.data);
+}
+
+
 /*
  * add the server address, the server names and the server core module
  * configurations to the port (in_port)
@@ -630,6 +696,8 @@ static ngx_int_t ngx_http_add_address(ng
 
     in_addr->addr = lscf->addr;
     in_addr->names.elts = NULL;
+    in_addr->hash = NULL;
+    in_addr->wildcards.elts = NULL;
     in_addr->default_server = lscf->default_server;
     in_addr->core_srv_conf = cscf;
 
@@ -655,7 +723,8 @@ static ngx_int_t ngx_http_add_names(ngx_
                                     ngx_http_in_addr_t *in_addr,
                                     ngx_http_core_srv_conf_t *cscf)
 {
-    ngx_uint_t               i;
+    ngx_uint_t               i, n;
+    ngx_array_t             *array;
     ngx_http_server_name_t  *server_names, *name;
 
     if (in_addr->names.elts == NULL) {
@@ -666,15 +735,36 @@ static ngx_int_t ngx_http_add_names(ngx_
         }
     }
 
+    if (in_addr->wildcards.elts == NULL) {
+        if (ngx_array_init(&in_addr->wildcards, cf->pool, 10,
+                                  sizeof(ngx_http_server_name_t)) == NGX_ERROR)
+        {
+            return NGX_ERROR;
+        }
+    }
+
     server_names = cscf->server_names.elts;
     for (i = 0; i < cscf->server_names.nelts; i++) {
 
+        for (n = 0; n < server_names[i].name.len; n++) {
+            server_names[i].name.data[n] =
+                                     ngx_tolower(server_names[i].name.data[n]);
+        }
+
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
                        "name: %V", &server_names[i].name);
 
         /* TODO: duplicate names can be checked here */
 
-        if (!(name = ngx_array_push(&in_addr->names))) {
+
+        if (server_names[i].wildcard) {
+            array = &in_addr->wildcards;
+
+        } else {
+            array = &in_addr->names;
+        }
+
+        if (!(name = ngx_array_push(array))) {
             return NGX_ERROR;
         }
 
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -14,6 +14,7 @@
 
 typedef struct ngx_http_request_s  ngx_http_request_t;
 typedef struct ngx_http_cleanup_s  ngx_http_cleanup_t;
+typedef struct ngx_http_in_addr_s  ngx_http_in_addr_t;
 
 #if (NGX_HTTP_CACHE)
 #include <ngx_http_cache.h>
--- a/src/http/ngx_http_cache.c
+++ b/src/http/ngx_http_cache.c
@@ -9,6 +9,7 @@
 #include <ngx_http.h>
 
 
+#if 0
 
 static ngx_http_module_t  ngx_http_cache_module_ctx = {
     NULL,                                  /* pre conf */
@@ -30,9 +31,101 @@ ngx_module_t  ngx_http_cache_module = {
     NULL,                                  /* module directives */
     NGX_HTTP_MODULE,                       /* module type */
     NULL,                                  /* init module */
-    NULL                                   /* init child */
+    NULL                                   /* init process */
 };
 
+#endif
+
+
+static ngx_int_t ngx_http_cache_create(ngx_http_request_t *r)
+{
+    ngx_str_t  *key;
+
+    if (!(r->cache = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)))) {
+        return NGX_ERROR;
+    }
+
+    if (ngx_array_init(&r->cache->key, r->pool, 5, sizeof(ngx_str_t))
+                                                                  == NGX_ERROR)
+    {
+        return NGX_ERROR;
+    }
+
+    /* preallocate the primary key */
+
+    if (!(key = ngx_array_push(&r->cache->key))) {
+        return NGX_ERROR;
+    }
+
+    key->len = 0;
+    key->data = NULL;
+
+    /*
+     * we use offsetof() because sizeof() pads the struct size to the int size
+     */
+
+    r->cache->header_size = offsetof(ngx_http_cache_header_t, key);
+
+    r->cache->log = r->connection->log;
+    r->cache->file.log = r->connection->log;
+
+    return NGX_OK;
+}
+
+
+ngx_int_t ngx_http_cache_get(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx)
+{
+    ngx_str_t         *key;
+    ngx_http_cache_t  *c;
+
+    if (r->cache == NULL) {
+        if (ngx_http_cache_create(r) == NGX_ERROR) {
+            return NGX_ABORT;
+        }
+    }
+
+    c = r->cache;
+    key = c->key.elts;
+
+    if (ctx->primary) {
+        key[0] = ctx->key;
+        c->header_size += ctx->key.len;
+        c->key_len += ctx->key.len;
+        c->buf = ctx->buf;
+
+    } else {
+        if (key[0].len == 0) {
+            key[0] = r->uri;
+            c->header_size += r->uri.len;
+            c->key_len += ctx->key.len;
+        }
+
+        if (!(key = ngx_array_push(&r->cache->key))) {
+            return NGX_ABORT;
+        }
+
+        c->header_size += ctx->key.len;
+        c->key_len += ctx->key.len;
+    }
+
+#if 0
+
+    if (ctx->memory) {
+        ngx_http_memory_cache_get(r, ctx);
+    }
+
+#endif
+
+    if (ctx->file) {
+        return ngx_http_file_cache_get(r, ctx);
+    }
+
+    return NGX_DECLINED;
+}
+
+
+#if 0
+
 
 ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *hash,
                                      ngx_http_cleanup_t *cleanup,
@@ -478,3 +571,6 @@ char *ngx_http_set_cache_slot(ngx_conf_t
 
     return NGX_CONF_OK;
 }
+
+
+#endif
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -88,18 +88,25 @@ typedef struct {
     time_t                    last_modified;
     time_t                    date;
     off_t                     length;
-    ssize_t                   header_size;
+    size_t                    key_len;
     size_t                    file_start;
+    ngx_file_uniq_t           uniq;
     ngx_log_t                *log;
 
     /* STUB */
+    ssize_t                   header_size;
     ngx_str_t                 key0;
 } ngx_http_cache_t;
 
 
 typedef struct {
-    ngx_path_t                path;
+    ngx_path_t               *path;
     ngx_str_t                 key;
+    ngx_buf_t                *buf;
+
+    unsigned                  file:1;
+    unsigned                  memory:1;
+    unsigned                  primary:1;
 } ngx_http_cache_ctx_t;
 
 
@@ -108,6 +115,17 @@ typedef struct {
 #define NGX_HTTP_CACHE_THE_SAME  3
 
 
+ngx_int_t ngx_http_cache_get(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx);
+
+ngx_int_t ngx_http_file_cache_get(ngx_http_request_t *r,
+                                  ngx_http_cache_ctx_t *ctx);
+
+ngx_int_t ngx_http_file_cache_open(ngx_http_cache_t *c);
+
+ngx_int_t ngx_http_cache_cleaner_handler(ngx_gc_t *gc, ngx_str_t *name,
+                                         ngx_dir_t *dir);
+
+
 #if 0
 
 ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *cache,
@@ -125,17 +143,12 @@ void ngx_http_cache_lock(ngx_http_cache_
 void ngx_http_cache_unlock(ngx_http_cache_hash_t *hash,
                            ngx_http_cache_t *cache, ngx_log_t *log);
 
-int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx);
-int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq);
 int ngx_http_cache_update_file(ngx_http_request_t *r,ngx_http_cache_ctx_t *ctx,
                                ngx_str_t *temp_file);
 
 int ngx_http_send_cached(ngx_http_request_t *r);
 
 
-int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name,
-                                             ngx_dir_t *dir);
-
 char *ngx_http_set_cache_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 
 #endif
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -60,6 +60,20 @@ static ngx_conf_enum_t  ngx_http_restric
 
 static ngx_command_t  ngx_http_core_commands[] = {
 
+    { ngx_string("server_names_hash"),
+      NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_HTTP_MAIN_CONF_OFFSET,
+      offsetof(ngx_http_core_main_conf_t, server_names_hash),
+      NULL },
+
+    { ngx_string("server_names_hash_threshold"),
+      NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_HTTP_MAIN_CONF_OFFSET,
+      offsetof(ngx_http_core_main_conf_t, server_names_hash_threshold),
+      NULL },
+
     { ngx_string("server"),
       NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
       ngx_server_block,
@@ -1244,17 +1258,24 @@ static void *ngx_http_core_create_main_c
                    5, sizeof(ngx_http_core_srv_conf_t *),
                    NGX_CONF_ERROR);
 
+    cmcf->server_names_hash = NGX_CONF_UNSET_UINT;
+    cmcf->server_names_hash_threshold = NGX_CONF_UNSET_UINT;
+
     return cmcf;
 }
 
 
 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
 {
-#if 0
     ngx_http_core_main_conf_t *cmcf = conf;
 
-    /* TODO: remove it if no directives */
-#endif
+    if (cmcf->server_names_hash == NGX_CONF_UNSET_UINT) {
+        cmcf->server_names_hash = 1009;
+    }
+
+    if (cmcf->server_names_hash_threshold == NGX_CONF_UNSET_UINT) {
+        cmcf->server_names_hash_threshold = 50;
+    }
 
     return NGX_CONF_OK;
 }
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -14,13 +14,13 @@
 
 
 typedef struct {
-    in_addr_t  addr;
-    in_port_t  port;
-    int        family;
-    ngx_str_t  file_name;
-    int        line;
+    in_addr_t                  addr;
+    in_port_t                  port;
+    int                        family;
+    ngx_str_t                  file_name;
+    ngx_int_t                  line;
 
-    unsigned   default_server:1;
+    unsigned                   default_server:1;
 } ngx_http_listen_t;
 
 
@@ -37,18 +37,21 @@ typedef enum {
 
 
 typedef struct {
-    ngx_array_t          handlers;
-    ngx_int_t            type;                /* NGX_OK, NGX_DECLINED */
+    ngx_array_t                handlers;
+    ngx_int_t                  type;                /* NGX_OK, NGX_DECLINED */
 } ngx_http_phase_t;
 
 
 typedef struct {
-    ngx_array_t       servers;         /* array of ngx_http_core_srv_conf_t */
+    ngx_array_t                servers; /* array of ngx_http_core_srv_conf_t */
+
+    ngx_http_phase_t           phases[NGX_HTTP_LAST_PHASE];
+    ngx_array_t                index_handlers;
 
-    ngx_http_phase_t  phases[NGX_HTTP_LAST_PHASE];
-    ngx_array_t       index_handlers;
+    ngx_uint_t                 server_names_hash;
+    ngx_uint_t                 server_names_hash_threshold;
 
-    size_t            max_server_name_len;
+    size_t                     max_server_name_len;
 } ngx_http_core_main_conf_t;
 
 
@@ -57,62 +60,76 @@ typedef struct {
      * array of ngx_http_core_loc_conf_t, used in the translation handler
      * and in the merge phase
      */
-    ngx_array_t           locations;
+    ngx_array_t                locations;
 
     /* "listen", array of ngx_http_listen_t */
-    ngx_array_t           listen;
+    ngx_array_t                listen;
 
     /* "server_name", array of ngx_http_server_name_t */
-    ngx_array_t           server_names;
+    ngx_array_t                server_names;
 
     /* server ctx */
-    ngx_http_conf_ctx_t  *ctx;
+    ngx_http_conf_ctx_t       *ctx;
 
-    size_t                connection_pool_size;
-    size_t                request_pool_size;
-    size_t                client_header_buffer_size;
+    size_t                     connection_pool_size;
+    size_t                     request_pool_size;
+    size_t                     client_header_buffer_size;
 
-    ngx_bufs_t            large_client_header_buffers;
+    ngx_bufs_t                 large_client_header_buffers;
 
-    ngx_msec_t            post_accept_timeout;
-    ngx_msec_t            client_header_timeout;
+    ngx_msec_t                 post_accept_timeout;
+    ngx_msec_t                 client_header_timeout;
 
-    ngx_uint_t            restrict_host_names;
+    ngx_uint_t                 restrict_host_names;
 } ngx_http_core_srv_conf_t;
 
 
 /* list of structures to find core_srv_conf quickly at run time */
 
 typedef struct {
-    in_port_t     port;
-    ngx_str_t     port_text;
-    ngx_array_t   addrs;       /* array of ngx_http_in_addr_t */
+    in_port_t                  port;
+    ngx_str_t                  port_text;
+    ngx_array_t                addrs;       /* array of ngx_http_in_addr_t */
 } ngx_http_in_port_t;
 
 
-typedef struct {
+struct ngx_http_in_addr_s {
     in_addr_t                  addr;
+
     ngx_array_t                names;     /* array of ngx_http_server_name_t */
-    ngx_http_core_srv_conf_t  *core_srv_conf;  /* default server conf
-                                                  for this address:port */
+    ngx_array_t               *hash;      /* hash of ngx_http_server_name_t */
+    ngx_array_t                wildcards;  /* array of ngx_http_server_name_t */
+
+    /* the default server configuration for this address:port */
+    ngx_http_core_srv_conf_t  *core_srv_conf;
 
     ngx_uint_t                 default_server; /* unsigned  default_server:1; */
-} ngx_http_in_addr_t;
+};
 
 
 typedef struct {
     ngx_str_t                  name;
     ngx_http_core_srv_conf_t  *core_srv_conf; /* virtual name server conf */
 
-    ngx_uint_t                 wildcard;  /*unsigned  wildcard:1; */
+    ngx_uint_t                 wildcard;  /* unsigned  wildcard:1 */
 } ngx_http_server_name_t;
 
 
+#define ngx_http_server_names_hash_key(key, name, len, prime)               \
+        {                                                                   \
+            ngx_uint_t  n;                                                  \
+            for (key = 0, n = 0; n < len; n++) {                            \
+                key += name[n];                                             \
+            }                                                               \
+            key %= prime;                                                   \
+        }
+
+
 #define NGX_HTTP_TYPES_HASH_PRIME  13
 
 #define ngx_http_types_hash_key(key, ext)                                   \
         {                                                                   \
-            u_int n;                                                        \
+            ngx_uint_t  n;                                                  \
             for (key = 0, n = 0; n < ext.len; n++) {                        \
                 key += ext.data[n];                                         \
             }                                                               \
@@ -120,15 +137,15 @@ typedef struct {
         }
 
 typedef struct {
-    ngx_str_t  exten;
-    ngx_str_t  type;
+    ngx_str_t     exten;
+    ngx_str_t     type;
 } ngx_http_type_t;
 
 
 typedef struct {
-    ngx_int_t  status;
-    ngx_int_t  overwrite;
-    ngx_str_t  uri;
+    ngx_int_t     status;
+    ngx_int_t     overwrite;
+    ngx_str_t     uri;
 } ngx_http_err_page_t;
 
 
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -22,138 +22,151 @@
 #endif
 
 
-#if 0
-
-int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx)
+ngx_int_t ngx_http_file_cache_get(ngx_http_request_t *r,
+                                  ngx_http_cache_ctx_t *ctx)
 {
-    MD5_CTX  md5;
+    ngx_uint_t         i;
+    ngx_str_t         *key;
+    ngx_http_cache_t  *c;
+    MD5_CTX            md5;
 
-    /* we use offsetof() because sizeof() pads struct size to int size */
-    ctx->header_size = offsetof(ngx_http_cache_header_t, key)
-                                                            + ctx->key.len + 1;
+    c = r->cache;
 
-    ctx->file.name.len = ctx->path->name.len + 1 + ctx->path->len + 32;
-    if (!(ctx->file.name.data = ngx_palloc(r->pool, ctx->file.name.len + 1))) {
-        return NGX_ERROR;
+    c->file.name.len = ctx->path->name.len + 1 + ctx->path->len + 32;
+    if (!(c->file.name.data = ngx_palloc(r->pool, c->file.name.len + 1))) {
+        return NGX_ABORT;
     }
 
-    ngx_memcpy(ctx->file.name.data, ctx->path->name.data, ctx->path->name.len);
-
     MD5Init(&md5);
-    MD5Update(&md5, (u_char *) ctx->key.data, ctx->key.len);
-    MD5Final(ctx->md5, &md5);
+
+    key = c->key.elts;
+    for (i = 0; i < c->key.nelts; i++) {
+        MD5Update(&md5, key[i].data, key[i].len);
+    }
 
-    ngx_md5_text(ctx->file.name.data + ctx->path->name.len + 1 + ctx->path->len,
-                 ctx->md5);
+    MD5Update(&md5, ctx->key.data, ctx->key.len);
+
+    MD5Final(c->md5, &md5);
+
+    ngx_memcpy(c->file.name.data, ctx->path->name.data, ctx->path->name.len);
+
+    ngx_md5_text(c->file.name.data + ctx->path->name.len + 1 + ctx->path->len,
+                 c->md5);
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-               "file cache uri: %s, md5: %s", ctx->key.data,
-               ctx->file.name.data + ctx->path->name.len + 1 + ctx->path->len);
+                  "file cache key: %V, md5: %s", &ctx->key,
+                  c->file.name.data + ctx->path->name.len + 1 + ctx->path->len);
 
-    ngx_create_hashed_filename(&ctx->file, ctx->path);
+    ngx_create_hashed_filename(&c->file, ctx->path);
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "file cache name: %s", ctx->file.name.data);
+                   "file cache name: %s", c->file.name.data);
 
-    /* TODO: look open files cache */
-
-    return ngx_http_cache_open_file(ctx, 0);
+    return ngx_http_file_cache_open(r->cache);
 }
 
 
-int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq)
+ngx_int_t ngx_http_file_cache_open(ngx_http_cache_t *c)
 {
     ssize_t                   n;
     ngx_err_t                 err;
     ngx_http_cache_header_t  *h;
 
-    ctx->file.fd = ngx_open_file(ctx->file.name.data,
-                                 NGX_FILE_RDONLY, NGX_FILE_OPEN);
+    c->file.fd = ngx_open_file(c->file.name.data,
+                               NGX_FILE_RDONLY, NGX_FILE_OPEN);
 
-    if (ctx->file.fd == NGX_INVALID_FILE) {
+    if (c->file.fd == NGX_INVALID_FILE) {
         err = ngx_errno;
 
         if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
             return NGX_DECLINED;
         }
 
-        ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
-                      ngx_open_file_n " \"%s\" failed", ctx->file.name.data);
+        ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno,
+                      ngx_open_file_n " \"%s\" failed", c->file.name.data);
         return NGX_ERROR;
     }
 
-    if (uniq) {
-        if (ngx_fd_info(ctx->file.fd, &ctx->file.info) == NGX_FILE_ERROR) {
-            ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
-                          ngx_fd_info_n " \"%s\" failed", ctx->file.name.data);
+    if (c->uniq) {
+        if (ngx_fd_info(c->file.fd, &c->file.info) == NGX_FILE_ERROR) {
+            ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno,
+                          ngx_fd_info_n " \"%s\" failed", c->file.name.data);
 
             return NGX_ERROR;
         }
 
-        if (ngx_file_uniq(&ctx->file.info) == uniq) {
-            if (ngx_close_file(ctx->file.fd) == NGX_FILE_ERROR) {
-                ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
+        if (ngx_file_uniq(&c->file.info) == c->uniq) {
+            if (ngx_close_file(c->file.fd) == NGX_FILE_ERROR) {
+                ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
                               ngx_close_file_n " \"%s\" failed",
-                              ctx->file.name.data);
+                              c->file.name.data);
             }
 
             return NGX_HTTP_CACHE_THE_SAME;
         }
     }
 
-    n = ngx_read_file(&ctx->file, ctx->buf->pos,
-                      ctx->buf->end - ctx->buf->last, 0);
+    n = ngx_read_file(&c->file, c->buf->pos, c->buf->end - c->buf->last, 0);
 
     if (n == NGX_ERROR || n == NGX_AGAIN) {
         return n;
     }
 
-    if (n <= ctx->header_size) {
-        ngx_log_error(NGX_LOG_CRIT, ctx->log, 0,
-                      "cache file \"%s\" is too small", ctx->file.name.data);
+    if (n <= c->header_size) {
+        ngx_log_error(NGX_LOG_CRIT, c->log, 0,
+                      "cache file \"%s\" is too small", c->file.name.data);
         return NGX_ERROR;
     }
 
-    h = (ngx_http_cache_header_t *) ctx->buf->pos;
-    ctx->expires = h->expires;
-    ctx->last_modified= h->last_modified;
-    ctx->date = h->date;
-    ctx->length = h->length;
+    h = (ngx_http_cache_header_t *) c->buf->pos;
+    c->expires = h->expires;
+    c->last_modified= h->last_modified;
+    c->date = h->date;
+    c->length = h->length;
 
-    if (h->key_len > (size_t) (ctx->buf->end - ctx->buf->pos)) {
-        ngx_log_error(NGX_LOG_ALERT, ctx->log, 0,
+    if (h->key_len > (size_t) (c->buf->end - c->buf->pos)) {
+        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                       "cache file \"%s\" is probably invalid",
-                      ctx->file.name.data);
+                      c->file.name.data);
         return NGX_DECLINED;
     }
 
-    if (ctx->key.len
-        && (h->key_len != ctx->key.len
-            || ngx_strncmp(h->key, ctx->key.data, h->key_len) != 0))
-    {
+#if 0
+
+    /* TODO */
+
+    if (c->key_len && h->key_len != c->key_len)  {
+
+        ngx_strncmp(h->key, c->key_data, h->key_len) != 0))
+
         h->key[h->key_len] = '\0';
-        ngx_log_error(NGX_LOG_ALERT, ctx->log, 0,
+        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                           "md5 collision: \"%s\" and \"%s\"",
-                          h->key, ctx->key.data);
+                          h->key, c->key.data);
         return NGX_DECLINED;
     }
 
-    ctx->buf->last += n;
+#endif
 
-    if (ctx->expires < ngx_time()) {
+    c->buf->last += n;
 
-        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
+    if (c->expires < ngx_time()) {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                        "http file cache expired");
-
         return NGX_HTTP_CACHE_STALE;
     }
 
     /* TODO: NGX_HTTP_CACHE_AGED */
 
+    /* STUB */ return NGX_DECLINED;
+
     return NGX_OK;
 }
 
 
+#if 0
+
+
 int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx,
                                ngx_str_t *temp_file)
 {
@@ -196,39 +209,45 @@ int ngx_http_cache_update_file(ngx_http_
 }
 
 
-int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name,
-                                             ngx_dir_t *dir)
+#endif
+
+
+ngx_int_t ngx_http_cache_cleaner_handler(ngx_gc_t *gc, ngx_str_t *name,
+                                         ngx_dir_t *dir)
 {
-    int                   rc;
-    char                  data[sizeof(ngx_http_cache_header_t)];
-    ngx_hunk_t            buf;
-    ngx_http_cache_ctx_t  ctx;
+    int               rc;
+    ngx_buf_t         buf;
+    ngx_http_cache_t  c;
+    u_char            data[sizeof(ngx_http_cache_header_t)];
 
-    ctx.file.fd = NGX_INVALID_FILE;
-    ctx.file.name = *name;
-    ctx.file.log = gc->log;
+    ngx_memzero(&c, sizeof(ngx_http_cache_t));
+
+    c.file.fd = NGX_INVALID_FILE;
+    c.file.name = *name;
+    c.file.log = gc->log;
 
-    ctx.header_size = sizeof(ngx_http_cache_header_t);
-    ctx.buf = &buf;
-    ctx.log = gc->log;
-    ctx.key.len = 0;
+    c.header_size = sizeof(ngx_http_cache_header_t);
+    c.buf = &buf;
+    c.log = gc->log;
+    c.key_len = 0;
 
-    buf.type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
+    buf.memory = 1;
+    buf.temporary = 1;
     buf.pos = data;
     buf.last = data;
     buf.start = data;
     buf.end = data + sizeof(ngx_http_cache_header_t);
 
-    rc = ngx_http_cache_open_file(&ctx, 0);
+    rc = ngx_http_file_cache_open(&c);
 
     /* TODO: NGX_AGAIN */
 
-    if (rc != NGX_ERROR && rc != NGX_DECLINED && rc != NGX_HTTP_CACHE_STALE) {
+    if (rc != NGX_ERROR&& rc != NGX_DECLINED && rc != NGX_HTTP_CACHE_STALE) {
         return NGX_OK;
     }
 
     if (ngx_delete_file(name->data) == NGX_FILE_ERROR) {
-        ngx_log_error(NGX_LOG_CRIT, gc->log, ngx_errno,
+        ngx_log_error(NGX_LOG_CRIT, c.log, ngx_errno,
                       ngx_delete_file_n " \"%s\" failed", name->data);
         return NGX_ERROR;
     }
@@ -238,5 +257,3 @@ int ngx_garbage_collector_http_cache_han
 
     return NGX_OK;
 }
-
-#endif
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -253,7 +253,7 @@ static ngx_int_t ngx_http_header_filter(
          */
 
         if (clcf->keepalive_header) {
-            len += sizeof("Keep-Alive: timeout=") - 1 + TIME_T_LEN + 2;
+            len += sizeof("Keep-Alive: timeout=") - 1 + NGX_TIME_T_LEN + 2;
         }
 
     } else {
--- a/src/http/ngx_http_log_handler.c
+++ b/src/http/ngx_http_log_handler.c
@@ -115,12 +115,12 @@ ngx_http_log_op_name_t ngx_http_log_fmt_
     { ngx_string("pipe"), 1, ngx_http_log_pipe },
     { ngx_string("time"), sizeof("28/Sep/1970:12:00:00") - 1,
                           ngx_http_log_time },
-    { ngx_string("msec"), TIME_T_LEN + 4, ngx_http_log_msec },
+    { ngx_string("msec"), NGX_TIME_T_LEN + 4, ngx_http_log_msec },
     { ngx_string("request"), 0, ngx_http_log_request },
     { ngx_string("status"), 3, ngx_http_log_status },
     { ngx_string("length"), NGX_OFF_T_LEN, ngx_http_log_length },
     { ngx_string("apache_length"), NGX_OFF_T_LEN, ngx_http_log_apache_length },
-    { ngx_string("request_length"), NGX_OFF_T_LEN,
+    { ngx_string("request_length"), NGX_SIZE_T_LEN,
                                     ngx_http_log_request_length },
     { ngx_string("i"), NGX_HTTP_LOG_ARG, ngx_http_log_header_in },
     { ngx_string("o"), NGX_HTTP_LOG_ARG, ngx_http_log_header_out },
@@ -290,7 +290,7 @@ static u_char *ngx_http_log_apache_lengt
 static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf,
                                            uintptr_t data)
 {
-    return ngx_sprintf(buf, "%O", r->request_length);
+    return ngx_sprintf(buf, "%z", r->request_length);
 }
 
 
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -20,6 +20,7 @@ static ssize_t ngx_http_read_request_hea
 static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
                                                     ngx_uint_t request_line);
 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
+static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r);
 
 static void ngx_http_set_write_handler(ngx_http_request_t *r);
 
@@ -246,7 +247,7 @@ static void ngx_http_init_request(ngx_ev
     }
 
 #if (NGX_STAT_STUB)
-    r->stat_reading = 1;
+    (*ngx_stat_reading)--;
 #endif
 
     c->data = r;
@@ -310,7 +311,7 @@ static void ngx_http_init_request(ngx_ev
         r->in_addr = in_addr[0].addr;
     }
 
-    r->virtual_names = &in_addr[i].names;
+    r->virtual_names = &in_addr[i];
 
     /* the default server configuration for the address:port */
     cscf = in_addr[i].core_srv_conf;
@@ -334,6 +335,8 @@ static void ngx_http_init_request(ngx_ev
                 return;
             }
 
+            rev->event_handler = ngx_http_ssl_handshake;
+
             /*
              * The majority of browsers do not send the "close notify" alert.
              * Among them are MSIE, Mozilla, Netscape 4, Konqueror, and Links.
@@ -343,7 +346,6 @@ static void ngx_http_init_request(ngx_ev
              */
 
             c->ssl->no_rcv_shut = 1;
-            rev->event_handler = ngx_http_ssl_handshake;
         }
 
         r->filter_need_in_memory = 1;
@@ -416,6 +418,8 @@ static void ngx_http_init_request(ngx_ev
     r->http_state = NGX_HTTP_READING_REQUEST_STATE;
 
 #if (NGX_STAT_STUB)
+    (*ngx_stat_reading)++;
+    r->stat_reading = 1;
     (*ngx_stat_requests)++;
 #endif
 
@@ -1054,81 +1058,23 @@ static ngx_int_t ngx_http_alloc_large_he
 
 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r)
 {
-    u_char                    *ua, *user_agent;
-    size_t                     len;
-    ngx_uint_t                 i;
-    ngx_http_server_name_t    *name;
-    ngx_http_core_srv_conf_t  *cscf;
-    ngx_http_core_loc_conf_t  *clcf;
+    u_char  *ua, *user_agent, ch;
+    size_t   len;
 
     if (r->headers_in.host) {
         for (len = 0; len < r->headers_in.host->value.len; len++) {
-            if (r->headers_in.host->value.data[len] == ':') {
+            ch = r->headers_in.host->value.data[len];
+
+            if (ch == ':') {
                 break;
             }
+
+            r->headers_in.host->value.data[len] = ngx_tolower(ch);
         }
         r->headers_in.host_name_len = len;
 
-        /* find the name based server configuration */
-
-        name = r->virtual_names->elts;
-        for (i = 0; i < r->virtual_names->nelts; i++) {
-
-            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                           "server name: %V", &name[i].name);
-
-            if (name[i].wildcard) {
-                if (r->headers_in.host_name_len <= name[i].name.len) {
-                    continue;
-                }
-
-                if (ngx_rstrncasecmp(r->headers_in.host->value.data,
-                                     name[i].name.data,
-                                     name[i].name.len) == 0)
-                {
-                    continue;
-                }
-
-            } else {
-                if (r->headers_in.host_name_len != name[i].name.len) {
-                    continue;
-                }
-
-                if (ngx_strncasecmp(r->headers_in.host->value.data,
-                                    name[i].name.data,
-                                    name[i].name.len) != 0)
-                {
-                    continue;
-                }
-            }
-
-            r->srv_conf = name[i].core_srv_conf->ctx->srv_conf;
-            r->loc_conf = name[i].core_srv_conf->ctx->loc_conf;
-
-            if (name[i].wildcard) {
-                r->server_name.len = r->headers_in.host_name_len;
-                r->server_name.data = r->headers_in.host->value.data;
-
-            } else {
-                r->server_name = name[i].name;
-            }
-
-            clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-            r->connection->log->file = clcf->err_log->file;
-
-            if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
-                r->connection->log->log_level = clcf->err_log->log_level;
-            }
-
-            break;
-        }
-
-        if (i == r->virtual_names->nelts) {
-            cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
-            if (cscf->restrict_host_names != NGX_HTTP_RESTRICT_HOST_OFF) {
-                return NGX_HTTP_PARSE_INVALID_HOST;
-            }
+        if (ngx_http_find_virtual_server(r) != NGX_OK) {
+            return NGX_HTTP_PARSE_INVALID_HOST;
         }
 
     } else {
@@ -1225,11 +1171,117 @@ static ngx_int_t ngx_http_process_reques
 }
 
 
+static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r)
+{
+    ngx_int_t                   rc;
+    ngx_uint_t                  i, n, key, found;
+    ngx_http_server_name_t     *name;
+    ngx_http_core_main_conf_t  *cmcf;
+    ngx_http_core_srv_conf_t   *cscf;
+    ngx_http_core_loc_conf_t   *clcf;
+
+    if (r->virtual_names->hash) {
+        cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+
+        ngx_http_server_names_hash_key(key,
+                                       r->headers_in.host->value.data,
+                                       r->headers_in.host_name_len,
+                                       cmcf->server_names_hash);
+
+        name = r->virtual_names->hash[key].elts;
+        n = r->virtual_names->hash[key].nelts;
+
+    } else {
+        name = r->virtual_names->names.elts;
+        n = r->virtual_names->names.nelts;
+    }
+
+    found = 0;
+
+    for (i = 0; i < n; i++) {
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "server name: %V", &name[i].name);
+
+        if (r->headers_in.host_name_len != name[i].name.len) {
+            continue;
+        }
+
+        rc = ngx_strncmp(r->headers_in.host->value.data,
+                         name[i].name.data, name[i].name.len);
+
+        if (rc == 0) {
+            r->server_name = name[i].name;
+
+            found = 1;
+            break;
+        }
+
+        if (rc < 0) {
+            /* the server names are lexicographically sorted */ 
+            break;
+        }
+    }
+
+    if (!found && r->virtual_names->wildcards.nelts) {
+
+        name = r->virtual_names->wildcards.elts;
+        for (i = 0; i < r->virtual_names->wildcards.nelts; i++) {
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "server name: %V", &name[i].name);
+
+            if (r->headers_in.host_name_len <= name[i].name.len) {
+                continue;
+            }
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "server name: %s",
+                           r->headers_in.host->value.data
+                           + (r->headers_in.host_name_len - name[i].name.len));
+
+            if (ngx_strncmp(r->headers_in.host->value.data
+                            + (r->headers_in.host_name_len - name[i].name.len),
+                            name[i].name.data, name[i].name.len) == 0)
+            {
+                r->server_name.len = r->headers_in.host_name_len;
+                r->server_name.data = r->headers_in.host->value.data;
+
+                found = 1;
+                break;
+            }
+        }
+    }
+
+    if (found) {
+        r->srv_conf = name[i].core_srv_conf->ctx->srv_conf;
+        r->loc_conf = name[i].core_srv_conf->ctx->loc_conf;
+
+        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+        r->connection->log->file = clcf->err_log->file;
+
+        if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
+            r->connection->log->log_level = clcf->err_log->log_level;
+        }
+
+        return NGX_OK;
+    }
+
+    cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+    if (cscf->restrict_host_names != NGX_HTTP_RESTRICT_HOST_OFF) {
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+}
+
+
 void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
 {
     ngx_http_core_loc_conf_t  *clcf;
 
-    /* r can be already destroyed when rc == NGX_DONE */
+    /* r may be already destroyed when rc == NGX_DONE */
 
     if (rc == NGX_DONE || r->main) {
         return;
@@ -1587,6 +1639,7 @@ static void ngx_http_set_keepalive(ngx_h
                   cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
 
                 if (hc->free == NULL) {
+                    ngx_http_close_request(r, 0);
                     ngx_http_close_connection(c);
                     return;
                 }
@@ -1604,10 +1657,11 @@ static void ngx_http_set_keepalive(ngx_h
         }
     }
 
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
     ngx_http_close_request(r, 0);
     c->data = hc;
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
     ngx_add_timer(rev, clcf->keepalive_timeout);
 
     if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
@@ -1877,12 +1931,14 @@ static void ngx_http_set_lingering_close
             if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT)
                                                                   == NGX_ERROR)
             {
+                ngx_http_close_request(r, 0);
                 ngx_http_close_connection(c);
                 return;
             }
 
         } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
             if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
+                ngx_http_close_request(r, 0);
                 ngx_http_close_connection(c);
                 return;
             }
@@ -1945,6 +2001,7 @@ static void ngx_http_lingering_close_han
     } while (rev->ready);
 
     if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
+        ngx_http_close_request(r, 0);
         ngx_http_close_connection(c);
         return;
     }
@@ -1958,8 +2015,6 @@ static void ngx_http_lingering_close_han
     }
 
     ngx_add_timer(rev, timer);
-
-    return;
 }
 
 
@@ -2093,8 +2148,6 @@ void ngx_http_close_request(ngx_http_req
     r->request_line.len = 0;
 
     ngx_destroy_pool(r->pool);
-
-    return;
 }
 
 
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -254,7 +254,7 @@ struct ngx_http_request_s {
     void                    **srv_conf;
     void                    **loc_conf;
 
-    ngx_http_cache_entry_t   *cache;
+    ngx_http_cache_t         *cache;
 
     ngx_file_t                file;
 
@@ -287,7 +287,7 @@ struct ngx_http_request_s {
     ngx_uint_t           port;
     ngx_str_t           *port_text;    /* ":80" */
     ngx_str_t            server_name;
-    ngx_array_t         *virtual_names;
+    ngx_http_in_addr_t  *virtual_names;
 
     ngx_uint_t           phase;
     ngx_int_t            phase_handler;
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -232,15 +232,21 @@ ngx_int_t ngx_http_special_response_hand
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
     if (r->err_ctx == NULL && clcf->error_pages) {
+
         err_page = clcf->error_pages->elts;
+
         for (i = 0; i < clcf->error_pages->nelts; i++) {
+
             if (err_page[i].status == error) {
+
                 if (err_page[i].overwrite) {
                     r->err_status = err_page[i].overwrite;
                 } else {
                     r->err_status = error;
                 }
+
                 r->err_ctx = r->ctx;
+
                 return ngx_http_internal_redirect(r, &err_page[i].uri, NULL);
             }
         }
--- a/src/os/unix/ngx_aio_write_chain.c
+++ b/src/os/unix/ngx_aio_write_chain.c
@@ -22,8 +22,8 @@ ngx_chain_t *ngx_aio_write_chain(ngx_con
 
     /* the maximum limit size is the maximum size_t value - the page size */
 
-    if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) {
-        limit = MAX_SIZE_T_VALUE - ngx_pagesize;
+    if (limit == 0 || limit > NGX_MAX_SIZE_T_VALUE - ngx_pagesize) {
+        limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
     }
 
     send = 0;
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -68,8 +68,8 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
 
     /* the maximum limit size is the maximum size_t value - the page size */
 
-    if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) {
-        limit = MAX_SIZE_T_VALUE - ngx_pagesize;
+    if (limit == 0 || limit > NGX_MAX_SIZE_T_VALUE - ngx_pagesize) {
+        limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
     }
 
     send = 0;
--- a/src/os/unix/ngx_linux_sendfile_chain.c
+++ b/src/os/unix/ngx_linux_sendfile_chain.c
@@ -51,8 +51,8 @@ ngx_chain_t *ngx_linux_sendfile_chain(ng
 
     /* the maximum limit size is the maximum size_t value - the page size */
 
-    if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) {
-        limit = MAX_SIZE_T_VALUE - ngx_pagesize;
+    if (limit == 0 || limit > NGX_MAX_SIZE_T_VALUE - ngx_pagesize) {
+        limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
     }
 
 
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -192,7 +192,7 @@ void ngx_signal_handler(int signo)
 
         case ngx_signal_value(NGX_REOPEN_SIGNAL):
             ngx_reopen = 1;
-            action = ", reopen logs";
+            action = ", reopening logs";
             break;
 
         case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
@@ -236,6 +236,8 @@ void ngx_signal_handler(int signo)
     case NGX_PROCESS_WORKER:
         switch (signo) {
 
+        case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
+            ngx_debug_quit = 1;
         case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
             ngx_quit = 1;
             action = ", shutting down";
@@ -249,11 +251,10 @@ void ngx_signal_handler(int signo)
 
         case ngx_signal_value(NGX_REOPEN_SIGNAL):
             ngx_reopen = 1;
-            action = ", reopen logs";
+            action = ", reopening logs";
             break;
 
         case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
-        case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
         case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
         case SIGIO:
             action = ", ignoring";
@@ -263,7 +264,7 @@ void ngx_signal_handler(int signo)
         break;
     }
 
-    ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
+    ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
                   "signal %d (%s) received%s", signo, sig->signame, action);
 
     if (ignore) {
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -142,8 +142,7 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t 
         break;
     }
 
-    ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
-                   "spawn %s: %P", name, pid);
+    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start %s %P", name, pid);
 
     ngx_processes[s].pid = pid;
     ngx_processes[s].exited = 0;
@@ -216,6 +215,7 @@ void ngx_process_get_status()
     ngx_int_t        i;
     ngx_uint_t       one;
     struct timeval   tv;
+
     one = 0;
 
     for ( ;; ) {
@@ -287,7 +287,7 @@ void ngx_process_get_status()
                           WCOREDUMP(status) ? " (core dumped)" : "");
 
         } else {
-            ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
+            ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
                           "%s %P exited with code %d",
                           process, pid, WEXITSTATUS(status));
         }
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -35,6 +35,7 @@ sig_atomic_t  ngx_timer;
 sig_atomic_t  ngx_sigio;
 sig_atomic_t  ngx_terminate;
 sig_atomic_t  ngx_quit;
+sig_atomic_t  ngx_debug_quit;
 ngx_uint_t    ngx_exiting;
 sig_atomic_t  ngx_reconfigure;
 sig_atomic_t  ngx_reopen;
@@ -194,8 +195,6 @@ void ngx_master_process_cycle(ngx_cycle_
             ngx_reconfigure = 0;
 
             if (ngx_new_binary) {
-                ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "start new workers");
-
                 ngx_start_worker_processes(cycle, ccf->worker_processes,
                                            NGX_PROCESS_RESPAWN);
                 ngx_start_garbage_collector(cycle, NGX_PROCESS_RESPAWN);
@@ -204,7 +203,7 @@ void ngx_master_process_cycle(ngx_cycle_
                 continue;
             }
 
-            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reconfiguring");
+            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
 
             cycle = ngx_init_cycle(cycle);
             if (cycle == NULL) {
@@ -233,7 +232,7 @@ void ngx_master_process_cycle(ngx_cycle_
 
         if (ngx_reopen) {
             ngx_reopen = 0;
-            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopening logs");
+            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
             ngx_reopen_files(cycle, ccf->user);
             ngx_signal_worker_processes(cycle,
                                         ngx_signal_value(NGX_REOPEN_SIGNAL));
@@ -241,7 +240,7 @@ void ngx_master_process_cycle(ngx_cycle_
 
         if (ngx_change_binary) {
             ngx_change_binary = 0;
-            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "changing binary");
+            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "changing binary");
             ngx_new_binary = ngx_exec_new_binary(cycle, ngx_argv);
         }
 
@@ -281,7 +280,7 @@ void ngx_single_process_cycle(ngx_cycle_
 
         if (ngx_reconfigure) {
             ngx_reconfigure = 0;
-            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reconfiguring");
+            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
 
             cycle = ngx_init_cycle(cycle);
             if (cycle == NULL) {
@@ -294,7 +293,7 @@ void ngx_single_process_cycle(ngx_cycle_
 
         if (ngx_reopen) {
             ngx_reopen = 0;
-            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopening logs");
+            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
             ngx_reopen_files(cycle, (ngx_uid_t) -1);
         }
     }
@@ -308,7 +307,7 @@ static void ngx_start_worker_processes(n
     ngx_channel_t     ch;
     struct itimerval  itv;
 
-    ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "start worker processes");
+    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
 
     ch.command = NGX_CMD_OPEN_CHANNEL;
 
@@ -367,7 +366,7 @@ static void ngx_start_garbage_collector(
 
     return;
 
-    ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "start garbage collector");
+    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start garbage collector");
 
     ch.command = NGX_CMD_OPEN_CHANNEL;
 
@@ -624,7 +623,7 @@ static void ngx_master_exit(ngx_cycle_t 
 {
     ngx_delete_pidfile(cycle);
 
-    ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exit");
+    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit");
 
     ngx_destroy_pool(cycle->pool);
 
@@ -690,7 +689,7 @@ static void ngx_worker_process_cycle(ngx
         if (ngx_exiting
             && ngx_event_timer_rbtree == &ngx_event_timer_sentinel)
         {
-            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
+            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
 
 
 #if (NGX_THREADS)
@@ -699,6 +698,10 @@ static void ngx_worker_process_cycle(ngx
             ngx_wakeup_worker_threads(cycle);
 #endif
 
+            if (ngx_debug_quit) {
+                ngx_debug_point();
+            }
+
             /*
              * we do not destroy cycle->pool here because a signal handler
              * that uses cycle->log can be called at this point
@@ -711,7 +714,7 @@ static void ngx_worker_process_cycle(ngx
         ngx_process_events(cycle);
 
         if (ngx_terminate) {
-            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
+            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
 
 #if (NGX_THREADS)
             ngx_wakeup_worker_threads(cycle);
@@ -726,7 +729,7 @@ static void ngx_worker_process_cycle(ngx
 
         if (ngx_quit) {
             ngx_quit = 0;
-            ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
+            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
                           "gracefully shutting down");
             ngx_setproctitle("worker process is shutting down");
 
@@ -738,7 +741,7 @@ static void ngx_worker_process_cycle(ngx
 
         if (ngx_reopen) {
             ngx_reopen = 0;
-            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs");
+            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
             ngx_reopen_files(cycle, -1);
         }
     }
@@ -1096,13 +1099,13 @@ static void ngx_garbage_collector_cycle(
     for ( ;; ) {
 
         if (ngx_terminate || ngx_quit) {
-            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
+            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
             exit(0);
         }
 
         if (ngx_reopen) {
             ngx_reopen = 0;
-            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopen logs");
+            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
             ngx_reopen_files(cycle, -1);
         }
 
--- a/src/os/unix/ngx_process_cycle.h
+++ b/src/os/unix/ngx_process_cycle.h
@@ -40,6 +40,7 @@ extern sig_atomic_t    ngx_reap;
 extern sig_atomic_t    ngx_timer;
 extern sig_atomic_t    ngx_sigio;
 extern sig_atomic_t    ngx_quit;
+extern sig_atomic_t    ngx_debug_quit;
 extern sig_atomic_t    ngx_terminate;
 extern sig_atomic_t    ngx_noaccept;
 extern sig_atomic_t    ngx_reconfigure;
--- a/src/os/unix/ngx_solaris_sendfilev_chain.c
+++ b/src/os/unix/ngx_solaris_sendfilev_chain.c
@@ -62,8 +62,8 @@ ngx_chain_t *ngx_solaris_sendfilev_chain
 
     /* the maximum limit size is the maximum size_t value - the page size */
 
-    if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) {
-        limit = MAX_SIZE_T_VALUE - ngx_pagesize;
+    if (limit == 0 || limit > NGX_MAX_SIZE_T_VALUE - ngx_pagesize) {
+        limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
     }
 
 
--- a/src/os/unix/ngx_writev_chain.c
+++ b/src/os/unix/ngx_writev_chain.c
@@ -44,8 +44,8 @@ ngx_chain_t *ngx_writev_chain(ngx_connec
 
     /* the maximum limit size is the maximum size_t value - the page size */
 
-    if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) {
-        limit = MAX_SIZE_T_VALUE - ngx_pagesize;
+    if (limit == 0 || limit > NGX_MAX_SIZE_T_VALUE - ngx_pagesize) {
+        limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
     }
 
     send = 0;
--- a/src/os/win32/ngx_win32_config.h
+++ b/src/os/win32/ngx_win32_config.h
@@ -114,8 +114,13 @@ typedef int               sig_atomic_t;
 typedef uint32_t          ngx_atomic_t;
 
 
-#define TIME_T_LEN        sizeof("-2147483648") - 1
-#define OFF_T_MAX_VALUE   9223372036854775807
+#define NGX_SIZE_T_LEN          sizeof("-2147483648") - 1
+#define NGX_TIME_T_LEN          sizeof("-2147483648") - 1
+#define NGX_TIME_T_SIZE         4
+#define NGX_OFF_T_LEN           sizeof("-9223372036854775807") - 1
+#define NGX_MAX_OFF_T_VALUE     9223372036854775807
+#define NGX_SIG_ATOMIC_T_SIZE   4
+
 #define NGX_HAVE_LITTLE_ENDIAN  1
 
 #define NGX_THREADS       1