changeset 376:edf1cb6c328e NGINX_0_7_0

nginx 0.7.0 *) Change: now the 0x00-0x1F, '"' and '\' characters are escaped as \xXX in an access_log. Thanks to Maxim Dounin. *) Change: now nginx allows several "Host" request header line. *) Feature: the "modified" flag in the "expires" directive. *) Feature: the $uid_got and $uid_set variables may be used at any request processing stage. *) Feature: the $hostname variable. Thanks to Andrei Nigmatulin. *) Feature: DESTDIR support. Thanks to Todd A. Fisher and Andras Voroskoi. *) Bugfix: a segmentation fault might occur in worker process on Linux, if keepalive was enabled.
author Igor Sysoev <http://sysoev.ru>
date Mon, 19 May 2008 00:00:00 +0400
parents 52f3c9c7eff0
children 5d98007adb5f
files CHANGES CHANGES.ru auto/install auto/lib/conf auto/lib/md5/conf auto/lib/pcre/conf auto/lib/sha1/conf auto/summary src/core/nginx.h src/core/ngx_config.h src/core/ngx_cycle.c src/core/ngx_cycle.h src/core/ngx_open_file_cache.c src/core/ngx_resolver.c src/core/ngx_string.h src/http/modules/ngx_http_dav_module.c src/http/modules/ngx_http_headers_filter_module.c src/http/modules/ngx_http_log_module.c src/http/modules/ngx_http_userid_filter_module.c src/http/modules/perl/nginx.pm src/http/ngx_http_core_module.c src/http/ngx_http_header_filter_module.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/http/ngx_http_variables.c src/http/ngx_http_variables.h src/mail/ngx_mail_core_module.c src/os/unix/ngx_posix_config.h
diffstat 28 files changed, 737 insertions(+), 524 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,27 @@
 
+Changes with nginx 0.7.0                                         19 May 2008
+
+    *) Change: now the 0x00-0x1F, '"' and '\' characters are escaped as 
+       \xXX in an access_log.
+       Thanks to Maxim Dounin.
+
+    *) Change: now nginx allows several "Host" request header line.
+
+    *) Feature: the "modified" flag in the "expires" directive.
+
+    *) Feature: the $uid_got and $uid_set variables may be used at any 
+       request processing stage.
+
+    *) Feature: the $hostname variable.
+       Thanks to Andrei Nigmatulin.
+
+    *) Feature: DESTDIR support.
+       Thanks to Todd A. Fisher and Andras Voroskoi.
+
+    *) Bugfix: a segmentation fault might occur in worker process on Linux, 
+       if keepalive was enabled.
+
+
 Changes with nginx 0.6.31                                        12 May 2008
 
     *) Bugfix: nginx did not process FastCGI response if header was at the 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,28 @@
 
+Изменения в nginx 0.7.0                                           19.05.2008
+
+    *) Изменение: теперь символы 0x00-0x1F, '"' и '\' в access_log 
+       записываются в виде \xXX.
+       Спасибо Максиму Дунину.
+
+    *) Изменение: теперь nginx разрешает несколько строк "Host" в заголовке 
+       запроса.
+
+    *) Добавление: директива expires поддерживает флаг modified.
+
+    *) Добавление: переменные $uid_got и $uid_set можно использовать на 
+       любой стадии обработки запроса.
+
+    *) Добавление: переменная $hostname.
+       Спасибо Андрею Нигматулину.
+
+    *) Добавление: поддержка DESTDIR.
+       Спасибо Todd A. Fisher и Andras Voroskoi.
+
+    *) Исправление: при использовании keepalive на Linux в рабочем процессе 
+       мог произойти segmentation fault.
+
+
 Изменения в nginx 0.6.31                                          12.05.2008
 
     *) Исправление: nginx не обрабатывал ответ FastCGI-сервера, если строка 
--- a/auto/install
+++ b/auto/install
@@ -17,47 +17,53 @@ fi
 
 cat << END                                                    >> $NGX_MAKEFILE
 
-install:	$NGX_OBJS${ngx_dirsep}nginx${ngx_binext}	\
+install:	$NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \
 		$NGX_INSTALL_PERL_MODULES
-	test -d '$NGX_PREFIX' || mkdir -p '$NGX_PREFIX'
+	test -d '\$(DESTDIR)$NGX_PREFIX' || mkdir -p '\$(DESTDIR)$NGX_PREFIX'
 
-	test -d '`dirname "$NGX_SBIN_PATH"`' \
-		|| mkdir -p '`dirname "$NGX_SBIN_PATH"`'
-	test ! -f '$NGX_SBIN_PATH' || mv '$NGX_SBIN_PATH' '$NGX_SBIN_PATH.old'
-	cp $NGX_OBJS/nginx '$NGX_SBIN_PATH'
+	test -d '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`' \
+		|| mkdir -p '\$(DESTDIR)`dirname "$NGX_SBIN_PATH"`'
+	test ! -f '\$(DESTDIR)$NGX_SBIN_PATH' \
+		|| mv '\$(DESTDIR)$NGX_SBIN_PATH' \
+			'\$(DESTDIR)$NGX_SBIN_PATH.old'
+	cp $NGX_OBJS/nginx '\$(DESTDIR)$NGX_SBIN_PATH'
 
-	test -d '$NGX_CONF_PREFIX' || mkdir -p '$NGX_CONF_PREFIX'
+	test -d '\$(DESTDIR)$NGX_CONF_PREFIX' \
+		|| mkdir -p '\$(DESTDIR)$NGX_CONF_PREFIX'
 
-	cp conf/koi-win '$NGX_CONF_PREFIX'
-	cp conf/koi-utf '$NGX_CONF_PREFIX'
-	cp conf/win-utf '$NGX_CONF_PREFIX'
+	cp conf/koi-win '\$(DESTDIR)$NGX_CONF_PREFIX'
+	cp conf/koi-utf '\$(DESTDIR)$NGX_CONF_PREFIX'
+	cp conf/win-utf '\$(DESTDIR)$NGX_CONF_PREFIX'
 
-	test -f '$NGX_CONF_PREFIX/mime.types' \
-		|| cp conf/mime.types '$NGX_CONF_PREFIX'
-	cp conf/mime.types '$NGX_CONF_PREFIX/mime.types.default'
+	test -f '\$(DESTDIR)$NGX_CONF_PREFIX/mime.types' \
+		|| cp conf/mime.types '\$(DESTDIR)$NGX_CONF_PREFIX'
+	cp conf/mime.types '\$(DESTDIR)$NGX_CONF_PREFIX/mime.types.default'
 
-	test -f '$NGX_CONF_PREFIX/fastcgi_params' \
-		|| cp conf/fastcgi_params '$NGX_CONF_PREFIX'
-	cp conf/fastcgi_params '$NGX_CONF_PREFIX/fastcgi_params.default'
+	test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params' \
+		|| cp conf/fastcgi_params '\$(DESTDIR)$NGX_CONF_PREFIX'
+	cp conf/fastcgi_params \
+		'\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params.default'
 
-	test -f '$NGX_CONF_PATH' || cp conf/nginx.conf '$NGX_CONF_PREFIX'
-	cp conf/nginx.conf '$NGX_CONF_PREFIX/nginx.conf.default'
+	test -f '\$(DESTDIR)$NGX_CONF_PATH' \
+		|| cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PREFIX'
+	cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PREFIX/nginx.conf.default'
 
-	test -d '`dirname "$NGX_PID_PATH"`' \
-		|| mkdir -p '`dirname "$NGX_PID_PATH"`'
+	test -d '\$(DESTDIR)`dirname "$NGX_PID_PATH"`' \
+		|| mkdir -p '\$(DESTDIR)`dirname "$NGX_PID_PATH"`'
 
-	test -d '`dirname "$NGX_HTTP_LOG_PATH"`' || \
-		mkdir -p '`dirname "$NGX_HTTP_LOG_PATH"`'
+	test -d '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`' || \
+		mkdir -p '\$(DESTDIR)`dirname "$NGX_HTTP_LOG_PATH"`'
 
-	test -d '$NGX_PREFIX/html' || cp -r html '$NGX_PREFIX'
+	test -d '\$(DESTDIR)$NGX_PREFIX/html' \
+		|| cp -r html '\$(DESTDIR)$NGX_PREFIX'
 END
 
 
-if test -n "$NGX_ERROR_LOG_PATH"; then
+if test -n "\$(DESTDIR)$NGX_ERROR_LOG_PATH"; then
     cat << END                                                >> $NGX_MAKEFILE
 
-	test -d '`dirname "$NGX_ERROR_LOG_PATH"`' || \
-		mkdir -p '`dirname "$NGX_ERROR_LOG_PATH"`'
+	test -d '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`' || \
+		mkdir -p '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`'
 END
 
 fi
--- a/auto/lib/conf
+++ b/auto/lib/conf
@@ -16,6 +16,7 @@ if [ $USE_MD5 = YES ]; then
         have=NGX_HAVE_OPENSSL_MD5_H . auto/have
         have=NGX_OPENSSL_MD5 . auto/have
         MD5=YES
+        MD5_LIB=OpenSSL
 
     else
         . auto/lib/md5/conf
@@ -28,6 +29,7 @@ if [ $USE_SHA1 = YES ]; then
     if [ $OPENSSL != NONE -a $OPENSSL != NO ]; then
         have=NGX_HAVE_OPENSSL_SHA1_H . auto/have
         SHA1=YES
+        SHA1_LIB=OpenSSL
 
     else
         . auto/lib/sha1/conf
--- a/auto/lib/md5/conf
+++ b/auto/lib/md5/conf
@@ -45,6 +45,7 @@ if [ $MD5 != NONE ]; then
 else
 
     if [ "$NGX_PLATFORM" != win32 ]; then
+
         MD5=NO
 
         # Solaris 8/9
@@ -58,55 +59,43 @@ else
         ngx_feature_test="MD5_CTX md5; MD5Init(&md5)"
         . auto/feature
 
-        if [ $ngx_found = yes ]; then
-            CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
-            MD5=YES
-            MD5_LIB=md5
-            ngx_found=no
+        ngx_md5_lib="system md5"
 
-        else
+        if [ $ngx_found = no ]; then
+
             # FreeBSD
 
             ngx_feature="rsaref md library"
-            ngx_feature_name=
-            ngx_feature_run=no
-            ngx_feature_incs="#include <md5.h>"
-            ngx_feature_path=
             ngx_feature_libs="-lmd"
-            ngx_feature_test="MD5_CTX md5; MD5Init(&md5)"
             . auto/feature
+
+            ngx_md5_lib="system md"
         fi
 
+        if [ $ngx_found = no ]; then
+
+            # OpenSSL crypto library
+
+            ngx_feature="OpenSSL md5 crypto library"
+            ngx_feature_name="NGX_OPENSSL_MD5"
+            ngx_feature_incs="#include <openssl/md5.h>"
+            ngx_feature_libs="-lcrypto"
+            ngx_feature_test="MD5_CTX md5; MD5_Init(&md5)"
+            . auto/feature
+
+            ngx_md5_lib="system crypto"
+
+            if [ $ngx_found = yes ]; then
+                have=NGX_HAVE_OPENSSL_MD5_H . auto/have
+            fi
+        fi
 
         if [ $ngx_found = yes ]; then
             CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
             MD5=YES
-            MD5_LIB=md
-            ngx_found=no
-
-        else
-            if [ $MD5 = NO ]; then
-
-                # OpenSSL crypto library
-
-                ngx_feature="OpenSSL md5 crypto library"
-                ngx_feature_name="NGX_OPENSSL_MD5"
-                ngx_feature_run=no
-                ngx_feature_incs="#include <openssl/md5.h>"
-                ngx_feature_path=
-                ngx_feature_libs="-lcrypto"
-                ngx_feature_test="MD5_CTX md5; MD5_Init(&md5)"
-                . auto/feature
-            fi
+            MD5_LIB=$ngx_md5_lib
         fi
 
-
-        if [ $ngx_found = yes ]; then
-            have=NGX_HAVE_OPENSSL_MD5_H . auto/have
-            CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
-            MD5=YES
-            MD5_LIB=crypto
-        fi
     fi
 
 fi
--- a/auto/lib/pcre/conf
+++ b/auto/lib/pcre/conf
@@ -84,6 +84,7 @@ if [ $PCRE != NONE ]; then
 else
 
     if [ "$NGX_PLATFORM" != win32 ]; then
+
         PCRE=NO
 
         ngx_feature="PCRE library"
@@ -95,20 +96,11 @@ else
         ngx_feature_test="pcre *re; re = pcre_compile(NULL, 0, NULL, 0, NULL)"
         . auto/feature
 
-        if [ $ngx_found = yes ]; then
-            CORE_DEPS="$CORE_DEPS $REGEX_DEPS"
-            CORE_SRCS="$CORE_SRCS $REGEX_SRCS"
-            CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
-            PCRE=YES
-            ngx_found=no
+        if [ $ngx_found = no ]; then
 
-        else
             # FreeBSD port
 
             ngx_feature="PCRE library in /usr/local/"
-            ngx_feature_name="NGX_PCRE"
-            ngx_feature_run=no
-            ngx_feature_incs="#include <pcre.h>"
             ngx_feature_path="/usr/local/include"
 
             if [ $NGX_RPATH = YES ]; then
@@ -117,8 +109,49 @@ else
                 ngx_feature_libs="-L/usr/local/lib -lpcre"
             fi
 
-            ngx_feature_test="pcre *re;
-                              re = pcre_compile(NULL, 0, NULL, 0, NULL)"
+            . auto/feature
+        fi
+
+        if [ $ngx_found = no ]; then
+
+            # Linux package
+
+            ngx_feature="PCRE library in /usr/include/pcre/"
+            ngx_feature_path="/usr/include/pcre"
+            ngx_feature_libs="-lpcre"
+
+            . auto/feature
+        fi
+
+        if [ $ngx_found = no ]; then
+
+            # NetBSD port
+
+            ngx_feature="PCRE library in /usr/pkg/"
+            ngx_feature_path="/usr/pkg/include"
+
+            if [ $NGX_RPATH = YES ]; then
+                ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lpcre"
+            else
+                ngx_feature_libs="-L/usr/pkg/lib -lpcre"
+            fi
+
+            . auto/feature
+        fi
+
+        if [ $ngx_found = no ]; then
+
+            # MacPorts
+
+            ngx_feature="PCRE library in /opt/local/"
+            ngx_feature_path="/opt/local/include"
+
+            if [ $NGX_RPATH = YES ]; then
+                ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lpcre"
+            else
+                ngx_feature_libs="-L/opt/local/lib -lpcre"
+            fi
+
             . auto/feature
         fi
 
@@ -128,94 +161,6 @@ else
             CORE_INCS="$CORE_INCS $ngx_feature_path"
             CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
             PCRE=YES
-            ngx_found=no
-
-        else
-            # Linux package
-
-            if [ $PCRE = NO ]; then
-
-                ngx_feature="PCRE library in /usr/include/pcre/"
-                ngx_feature_name="NGX_PCRE"
-                ngx_feature_run=no
-                ngx_feature_incs="#include <pcre.h>"
-                ngx_feature_path="/usr/include/pcre"
-                ngx_feature_libs="-lpcre"
-                ngx_feature_test="pcre *re;
-                                  re = pcre_compile(NULL, 0, NULL, 0, NULL)"
-                . auto/feature
-            fi
-        fi
-
-        if [ $ngx_found = yes ]; then
-            CORE_DEPS="$CORE_DEPS $REGEX_DEPS"
-            CORE_SRCS="$CORE_SRCS $REGEX_SRCS"
-            CORE_INCS="$CORE_INCS $ngx_feature_path"
-            CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
-            PCRE=YES
-            ngx_found=no
-
-        else
-            # NetBSD port
-
-            if [ $PCRE = NO ]; then
-
-                ngx_feature="PCRE library in /usr/pkg/"
-                ngx_feature_name="NGX_PCRE"
-                ngx_feature_run=no
-                ngx_feature_incs="#include <pcre.h>"
-                ngx_feature_path="/usr/pkg/include"
-
-                if [ $NGX_RPATH = YES ]; then
-                    ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lpcre"
-                else
-                    ngx_feature_libs="-L/usr/pkg/lib -lpcre"
-                fi
-
-                ngx_feature_test="pcre *re;
-                                  re = pcre_compile(NULL, 0, NULL, 0, NULL)"
-                . auto/feature
-            fi
-        fi
-
-        if [ $ngx_found = yes ]; then
-            CORE_DEPS="$CORE_DEPS $REGEX_DEPS"
-            CORE_SRCS="$CORE_SRCS $REGEX_SRCS"
-            CORE_INCS="$CORE_INCS $ngx_feature_path"
-            CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
-            PCRE=YES
-            ngx_found=no
-
-        else
-            # MacPorts
-
-            if [ $PCRE = NO ]; then
-
-                ngx_feature="PCRE library in /opt/local/"
-                ngx_feature_name="NGX_PCRE"
-                ngx_feature_run=no
-                ngx_feature_incs="#include <pcre.h>"
-                ngx_feature_path="/opt/local/include"
-
-                if [ $NGX_RPATH = YES ]; then
-                    ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lpcre"
-                else
-                    ngx_feature_libs="-L/opt/local/lib -lpcre"
-                fi
-
-                ngx_feature_test="pcre *re;
-                                  re = pcre_compile(NULL, 0, NULL, 0, NULL)"
-                . auto/feature
-            fi
-        fi
-
-        if [ $ngx_found = yes ]; then
-            CORE_DEPS="$CORE_DEPS $REGEX_DEPS"
-            CORE_SRCS="$CORE_SRCS $REGEX_SRCS"
-            CORE_INCS="$CORE_INCS $ngx_feature_path"
-            CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
-            PCRE=YES
-            ngx_found=no
         fi
 
     fi
--- a/auto/lib/sha1/conf
+++ b/auto/lib/sha1/conf
@@ -35,6 +35,7 @@ if [ $SHA1 != NONE ]; then
 else
 
     if [ "$NGX_PLATFORM" != win32 ]; then
+
         SHA1=NO
 
         # FreeBSD
@@ -48,35 +49,28 @@ else
         ngx_feature_test="SHA_CTX sha1; SHA1_Init(&sha1)"
         . auto/feature
 
+        ngx_sha1_lib="system md"
+
+        if [ $ngx_found = no ]; then
+
+            # OpenSSL crypto library
+
+            ngx_feature="OpenSSL sha1 crypto library"
+            ngx_feature_incs="#include <openssl/sha.h>"
+            ngx_feature_libs="-lcrypto"
+            . auto/feature
+
+            ngx_sha1_lib="system crypto"
+
+            if [ $ngx_found = yes ]; then
+                have=NGX_HAVE_OPENSSL_SHA1_H . auto/have
+            fi
+        fi
 
         if [ $ngx_found = yes ]; then
             CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
             SHA1=YES
-            SHA1_LIB=md
-            ngx_found=no
-
-        else
-            if [ $SHA1 = NO ]; then
-
-                # OpenSSL crypto library
-
-                ngx_feature="OpenSSL sha1 crypto library"
-                ngx_feature_name=
-                ngx_feature_run=no
-                ngx_feature_incs="#include <openssl/sha.h>"
-                ngx_feature_path=
-                ngx_feature_libs="-lcrypto"
-                ngx_feature_test="SHA_CTX sha1; SHA1_Init(&sha1)"
-                . auto/feature
-            fi
-        fi
-
-
-        if [ $ngx_found = yes ]; then
-            have=NGX_HAVE_OPENSSL_SHA1_H . auto/have
-            CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
-            SHA1=YES
-            SHA1_LIB=crypto
+            SHA1_LIB=$ngx_sha1_lib
         fi
     fi
 
--- a/auto/summary
+++ b/auto/summary
@@ -51,26 +51,14 @@ case $OPENSSL in
 esac
 
 case $MD5 in
-    YES)
-        case $OPENSSL in
-            NONE|NO)  echo "  + md5: using system $MD5_LIB library" ;;
-            *)        echo "  + md5: using OpenSSL library" ;;
-        esac
-        ;;
-
+    YES)   echo "  + md5: using $MD5_LIB library" ;;
     NONE)  echo "  + md5 library is not used" ;;
     NO)    echo "  + md5 library is not found" ;;
     *)     echo "  + using md5 library: $MD5" ;;
 esac
 
 case $SHA1 in
-    YES)
-        case $OPENSSL in
-            NONE|NO)  echo "  + sha1: using system $SHA1_LIB library" ;;
-            *)        echo "  + sha1: using OpenSSL library" ;;
-        esac
-        ;;
-
+    YES)   echo "  + sha1: using $SHA1_LIB library" ;;
     NONE)  echo "  + sha1 library is not used" ;;
     NO)    echo "  + sha1 library is not found" ;;
     *)     echo "  + using sha1 library: $SHA1" ;;
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VERSION      "0.6.31"
+#define NGINX_VERSION      "0.7.0"
 #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,11 @@ typedef intptr_t        ngx_flag_t;
 #define INET_ADDRSTRLEN  16
 #endif
 
-#define NGX_MAXHOSTNAMELEN 64
-/*
-#define NGX_MAXHOSTNAMELEN MAXHOSTNAMELEN
-*/
+#ifdef MAXHOSTNAMELEN
+#define NGX_MAXHOSTNAMELEN  MAXHOSTNAMELEN
+#else
+#define NGX_MAXHOSTNAMELEN  256
+#endif
 
 
 #if ((__GNU__ == 2) && (__GNUC_MINOR__ < 8))
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -57,6 +57,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
     ngx_listening_t     *ls, *nls;
     ngx_core_conf_t     *ccf, *old_ccf;
     ngx_core_module_t   *module;
+    char                 hostname[NGX_MAXHOSTNAMELEN];
 
     log = old_cycle->log;
 
@@ -170,6 +171,26 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
     }
 
 
+    if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
+        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed");
+        ngx_destroy_pool(pool);
+        return NULL;
+    }
+
+    /* on Linux gethostname() silently truncates name that does not fit */
+
+    hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';
+    cycle->hostname.len = ngx_strlen(hostname);
+
+    cycle->hostname.data = ngx_palloc(pool, cycle->hostname.len);
+    if (cycle->hostname.data == NULL) {
+        ngx_destroy_pool(pool);
+        return NULL;
+    }
+
+    ngx_memcpy(cycle->hostname.data, hostname, cycle->hostname.len);
+
+
     for (i = 0; ngx_modules[i]; i++) {
         if (ngx_modules[i]->type != NGX_CORE_MODULE) {
             continue;
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -62,6 +62,7 @@ struct ngx_cycle_s {
     ngx_str_t                 conf_file;
     ngx_str_t                 root;
     ngx_str_t                 lock_file;
+    ngx_str_t                 hostname;
 };
 
 
--- a/src/core/ngx_open_file_cache.c
+++ b/src/core/ngx_open_file_cache.c
@@ -413,13 +413,13 @@ failed:
 
         if (file->count == 0) {
 
-	    if (file->fd != NGX_INVALID_FILE) {
-		if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
-		    ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
-				  ngx_close_file_n " \"%s\" failed",
+            if (file->fd != NGX_INVALID_FILE) {
+                if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
+                    ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
+                                  ngx_close_file_n " \"%s\" failed",
                                   file->name);
-		}
-	    }
+                }
+            }
 
             ngx_free(file->name);
             ngx_free(file);
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -202,7 +202,7 @@ ngx_resolver_cleanup_tree(ngx_resolver_t
         ngx_queue_remove(&rn->queue);
 
         for (ctx = rn->waiting; ctx; ctx = next) {
-            next = ctx->next; 
+            next = ctx->next;
 
             if (ctx->event) {
                 ngx_resolver_free(r, ctx->event);
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -25,11 +25,12 @@ typedef struct {
 
 
 typedef struct {
-    unsigned    len:29;
+    unsigned    len:28;
 
     unsigned    valid:1;
     unsigned    no_cacheable:1;
     unsigned    not_found:1;
+    unsigned    escape:1;
 
     u_char     *data;
 } ngx_variable_value_t;
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -512,7 +512,7 @@ ngx_http_dav_mkcol_handler(ngx_http_requ
 static ngx_int_t
 ngx_http_dav_copy_move_handler(ngx_http_request_t *r)
 {
-    u_char                   *p, *desthost, *last, ch;
+    u_char                   *p, *host, *last, ch;
     size_t                    len, root;
     ngx_err_t                 err;
     ngx_int_t                 rc, depth;
@@ -520,7 +520,7 @@ ngx_http_dav_copy_move_handler(ngx_http_
     ngx_str_t                 path, uri;
     ngx_tree_ctx_t            tree;
     ngx_file_info_t           fi;
-    ngx_table_elt_t          *host, *dest, *over;
+    ngx_table_elt_t          *dest, *over;
     ngx_http_dav_copy_ctx_t   copy;
     ngx_http_dav_loc_conf_t  *dlcf;
 
@@ -536,9 +536,9 @@ ngx_http_dav_copy_move_handler(ngx_http_
         return NGX_HTTP_BAD_REQUEST;
     }
 
-    host = r->headers_in.host;
+    len = r->headers_in.server.len;
 
-    if (host == NULL) {
+    if (len == 0) {
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                       "client sent no \"Host\" header");
         return NGX_HTTP_BAD_REQUEST;
@@ -553,7 +553,7 @@ ngx_http_dav_copy_move_handler(ngx_http_
             goto invalid_destination;
         }
 
-        desthost = dest->value.data + sizeof("https://") - 1;
+        host = dest->value.data + sizeof("https://") - 1;
 
     } else
 #endif
@@ -564,12 +564,10 @@ ngx_http_dav_copy_move_handler(ngx_http_
             goto invalid_destination;
         }
 
-        desthost = dest->value.data + sizeof("http://") - 1;
+        host = dest->value.data + sizeof("http://") - 1;
     }
 
-    len = r->headers_in.host_name_len;
-
-    if (ngx_strncmp(desthost, host->value.data, len) != 0) {
+    if (ngx_strncmp(host, r->headers_in.server.data, len) != 0) {
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                       "\"Destination\" URI \"%V\" is handled by "
                       "different repository than the source URI",
@@ -579,7 +577,7 @@ ngx_http_dav_copy_move_handler(ngx_http_
 
     last = dest->value.data + dest->value.len;
 
-    for (p = desthost + len; p < last; p++) {
+    for (p = host + len; p < last; p++) {
         if (*p == '/') {
             goto destination_done;
         }
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -31,18 +31,20 @@ struct ngx_http_header_val_s {
 };
 
 
+#define NGX_HTTP_EXPIRES_OFF       0
+#define NGX_HTTP_EXPIRES_EPOCH     1
+#define NGX_HTTP_EXPIRES_MAX       2
+#define NGX_HTTP_EXPIRES_ACCESS    3
+#define NGX_HTTP_EXPIRES_MODIFIED  4
+
+
 typedef struct {
-    time_t                   expires;
+    ngx_uint_t               expires;
+    time_t                   expires_time;
     ngx_array_t             *headers;
 } ngx_http_headers_conf_t;
 
 
-#define NGX_HTTP_EXPIRES_UNSET   -2147483647
-#define NGX_HTTP_EXPIRES_OFF     -2147483646
-#define NGX_HTTP_EXPIRES_EPOCH   -2147483645
-#define NGX_HTTP_EXPIRES_MAX     -2147483644
-
-
 static ngx_int_t ngx_http_set_expires(ngx_http_request_t *r,
     ngx_http_headers_conf_t *conf);
 static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r,
@@ -76,7 +78,7 @@ static ngx_command_t  ngx_http_headers_f
 
     { ngx_string("expires"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-                        |NGX_CONF_TAKE1,
+                        |NGX_CONF_TAKE12,
       ngx_http_headers_expires,
       NGX_HTTP_LOC_CONF_OFFSET,
       0,
@@ -185,6 +187,7 @@ static ngx_int_t
 ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
 {
     size_t            len;
+    time_t            since;
     ngx_uint_t        i;
     ngx_table_elt_t  *expires, *cc, **ccp;
 
@@ -266,7 +269,7 @@ ngx_http_set_expires(ngx_http_request_t 
         return NGX_ERROR;
     }
 
-    if (conf->expires == 0) {
+    if (conf->expires_time == 0) {
         ngx_memcpy(expires->value.data, ngx_cached_http_time.data,
                    ngx_cached_http_time.len + 1);
 
@@ -276,9 +279,18 @@ ngx_http_set_expires(ngx_http_request_t 
         return NGX_OK;
     }
 
-    ngx_http_time(expires->value.data, ngx_time() + conf->expires);
+    if (conf->expires == NGX_HTTP_EXPIRES_ACCESS
+        || r->headers_out.last_modified_time == -1)
+    {
+        since = ngx_time();
 
-    if (conf->expires < 0) {
+    } else {
+        since = r->headers_out.last_modified_time;
+    }
+
+    ngx_http_time(expires->value.data, since + conf->expires_time);
+
+    if (conf->expires_time < 0) {
         cc->value.len = sizeof("no-cache") - 1;
         cc->value.data = (u_char *) "no-cache";
 
@@ -291,7 +303,8 @@ ngx_http_set_expires(ngx_http_request_t 
         return NGX_ERROR;
     }
 
-    cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T", conf->expires)
+    cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T",
+                                since + conf->expires_time - ngx_time())
                     - cc->value.data;
 
     return NGX_OK;
@@ -413,9 +426,10 @@ ngx_http_headers_create_conf(ngx_conf_t 
      * set by ngx_pcalloc():
      *
      *     conf->headers = NULL;
+     *     conf->expires_time = 0;
      */
 
-    conf->expires = NGX_HTTP_EXPIRES_UNSET;
+    conf->expires = NGX_CONF_UNSET_UINT;
 
     return conf;
 }
@@ -427,9 +441,13 @@ ngx_http_headers_merge_conf(ngx_conf_t *
     ngx_http_headers_conf_t *prev = parent;
     ngx_http_headers_conf_t *conf = child;
 
-    if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
-        conf->expires = (prev->expires == NGX_HTTP_EXPIRES_UNSET) ?
-                            NGX_HTTP_EXPIRES_OFF : prev->expires;
+    if (conf->expires == NGX_CONF_UNSET_UINT) {
+        conf->expires = prev->expires;
+        conf->expires_time = prev->expires_time;
+
+        if (conf->expires == NGX_CONF_UNSET_UINT) {
+            conf->expires = NGX_HTTP_EXPIRES_OFF;
+        }
     }
 
     if (conf->headers == NULL) {
@@ -455,56 +473,73 @@ ngx_http_headers_expires(ngx_conf_t *cf,
 {
     ngx_http_headers_conf_t *hcf = conf;
 
-    ngx_uint_t   minus;
+    ngx_uint_t   minus, n;
     ngx_str_t   *value;
 
-    if (hcf->expires != NGX_HTTP_EXPIRES_UNSET) {
+    if (hcf->expires != NGX_CONF_UNSET_UINT) {
         return "is duplicate";
     }
 
     value = cf->args->elts;
 
-    if (ngx_strcmp(value[1].data, "epoch") == 0) {
-        hcf->expires = NGX_HTTP_EXPIRES_EPOCH;
-        return NGX_CONF_OK;
-    }
+    if (cf->args->nelts == 2) {
+
+        if (ngx_strcmp(value[1].data, "epoch") == 0) {
+            hcf->expires = NGX_HTTP_EXPIRES_EPOCH;
+            return NGX_CONF_OK;
+        }
+
+        if (ngx_strcmp(value[1].data, "max") == 0) {
+            hcf->expires = NGX_HTTP_EXPIRES_MAX;
+            return NGX_CONF_OK;
+        }
 
-    if (ngx_strcmp(value[1].data, "max") == 0) {
-        hcf->expires = NGX_HTTP_EXPIRES_MAX;
-        return NGX_CONF_OK;
+        if (ngx_strcmp(value[1].data, "off") == 0) {
+            hcf->expires = NGX_HTTP_EXPIRES_OFF;
+            return NGX_CONF_OK;
+        }
+
+        hcf->expires = NGX_HTTP_EXPIRES_ACCESS;
+
+        n = 1;
+
+    } else { /* cf->args->nelts == 3 */
+
+        if (ngx_strcmp(value[1].data, "modified") != 0) {
+            return "invalid value";
+        }
+
+        hcf->expires = NGX_HTTP_EXPIRES_MODIFIED;
+
+        n = 2;
     }
 
-    if (ngx_strcmp(value[1].data, "off") == 0) {
-        hcf->expires = NGX_HTTP_EXPIRES_OFF;
-        return NGX_CONF_OK;
-    }
-
-    if (value[1].data[0] == '+') {
-        value[1].data++;
-        value[1].len--;
+    if (value[n].data[0] == '+') {
+        value[n].data++;
+        value[n].len--;
         minus = 0;
 
-    } else if (value[1].data[0] == '-') {
-        value[1].data++;
-        value[1].len--;
+    } else if (value[n].data[0] == '-') {
+        value[n].data++;
+        value[n].len--;
         minus = 1;
 
     } else {
         minus = 0;
     }
 
-    hcf->expires = ngx_parse_time(&value[1], 1);
+    hcf->expires_time = ngx_parse_time(&value[n], 1);
 
-    if (hcf->expires == NGX_ERROR) {
+    if (hcf->expires_time == NGX_ERROR) {
         return "invalid value";
     }
 
-    if (hcf->expires == NGX_PARSE_LARGE_TIME) {
+    if (hcf->expires_time == NGX_PARSE_LARGE_TIME) {
         return "value must be less than 68 years";
     }
 
     if (minus) {
-        hcf->expires = - hcf->expires;
+        hcf->expires_time = - hcf->expires_time;
     }
 
     return NGX_CONF_OK;
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -88,6 +88,7 @@ static size_t ngx_http_log_variable_getl
     uintptr_t data);
 static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
     ngx_http_log_op_t *op);
+static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size);
 
 
 static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
@@ -478,6 +479,7 @@ ngx_http_log_variable_compile(ngx_conf_t
 static size_t
 ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data)
 {
+    uintptr_t                   len;
     ngx_http_variable_value_t  *value;
 
     value = ngx_http_get_indexed_variable(r, data);
@@ -486,7 +488,11 @@ ngx_http_log_variable_getlen(ngx_http_re
         return 1;
     }
 
-    return value->len;
+    len = ngx_http_log_escape(NULL, value->data, value->len);
+
+    value->escape = len ? 1 : 0;
+
+    return value->len + len * 3;
 }
 
 
@@ -502,7 +508,70 @@ ngx_http_log_variable(ngx_http_request_t
         return buf + 1;
     }
 
-    return ngx_cpymem(buf, value->data, value->len);
+    if (value->escape == 0) {
+        return ngx_cpymem(buf, value->data, value->len);
+
+    } else {
+        return (u_char *) ngx_http_log_escape(buf, value->data, value->len);
+    }
+}
+
+
+static uintptr_t
+ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
+{
+    ngx_uint_t      i, n;
+    static u_char   hex[] = "0123456789ABCDEF";
+
+    static uint32_t   escape[] = {
+        0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
+
+                    /* ?>=< ;:98 7654 3210  /.-, +*)( '&%$ #"!  */
+        0x00000004, /* 0000 0000 0000 0000  0000 0000 0000 0100 */
+
+                    /* _^]\ [ZYX WVUT SRQP  ONML KJIH GFED CBA@ */
+        0x10000000, /* 0001 0000 0000 0000  0000 0000 0000 0000 */
+
+                    /*  ~}| {zyx wvut srqp  onml kjih gfed cba` */
+        0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
+
+        0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
+        0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
+        0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
+        0x00000000, /* 0000 0000 0000 0000  0000 0000 0000 0000 */
+    };
+
+
+    if (dst == NULL) {
+
+        /* find the number of the characters to be escaped */
+
+        n  = 0;
+
+        for (i = 0; i < size; i++) {
+            if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
+                n++;
+            }
+            src++;
+        }
+
+        return (uintptr_t) n;
+    }
+
+    for (i = 0; i < size; i++) {
+        if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
+            *dst++ = '\\';
+            *dst++ = 'x';
+            *dst++ = hex[*src >> 4];
+            *dst++ = hex[*src & 0xf];
+            src++;
+
+        } else {
+            *dst++ = *src++;
+        }
+    }
+
+    return (uintptr_t) dst;
 }
 
 
--- a/src/http/modules/ngx_http_userid_filter_module.c
+++ b/src/http/modules/ngx_http_userid_filter_module.c
@@ -41,15 +41,14 @@ typedef struct {
 } ngx_http_userid_ctx_t;
 
 
-static void ngx_http_userid_get_uid(ngx_http_request_t *r,
-    ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf);
+static ngx_http_userid_ctx_t *ngx_http_userid_get_uid(ngx_http_request_t *r,
+    ngx_http_userid_conf_t *conf);
+static ngx_int_t ngx_http_userid_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, ngx_str_t *name, uint32_t *uid);
 static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r,
     ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf);
 
 static ngx_int_t ngx_http_userid_add_variables(ngx_conf_t *cf);
-static ngx_int_t ngx_http_userid_variable(ngx_http_request_t *r,
-    ngx_http_variable_value_t *v, uintptr_t data);
-
 static ngx_int_t ngx_http_userid_init(ngx_conf_t *cf);
 static void *ngx_http_userid_create_conf(ngx_conf_t *cf);
 static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent,
@@ -191,7 +190,6 @@ static ngx_str_t  ngx_http_userid_set = 
 static ngx_int_t
 ngx_http_userid_filter(ngx_http_request_t *r)
 {
-    ngx_int_t                rc;
     ngx_http_userid_ctx_t   *ctx;
     ngx_http_userid_conf_t  *conf;
 
@@ -201,25 +199,18 @@ ngx_http_userid_filter(ngx_http_request_
 
     conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module);
 
-    if (conf->enable == NGX_HTTP_USERID_OFF) {
+    if (conf->enable <= NGX_HTTP_USERID_LOG) {
         return ngx_http_next_header_filter(r);
     }
 
+    ctx = ngx_http_userid_get_uid(r, conf);
 
-    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_userid_ctx_t));
     if (ctx == NULL) {
         return NGX_ERROR;
     }
 
-    ngx_http_set_ctx(r, ctx, ngx_http_userid_filter_module);
-
-    ngx_http_userid_get_uid(r, ctx, conf);
+    if (ctx->uid_got[3] != 0) {
 
-    if (conf->enable == NGX_HTTP_USERID_LOG) {
-        return ngx_http_next_header_filter(r);
-    }
-
-    if (ctx->uid_got[3] != 0) {
         if (conf->mark == '\0') {
             return ngx_http_next_header_filter(r);
 
@@ -233,28 +224,95 @@ ngx_http_userid_filter(ngx_http_request_
         }
     }
 
-    rc = ngx_http_userid_set_uid(r, ctx, conf);
+    /* ctx->status == NGX_DECLINED */
 
-    if (rc != NGX_OK) {
-        return rc;
+    if (ngx_http_userid_set_uid(r, ctx, conf) == NGX_OK) {
+        return ngx_http_next_header_filter(r);
     }
 
-    return ngx_http_next_header_filter(r);
+    return NGX_ERROR;
+}
+
+
+static ngx_int_t
+ngx_http_userid_got_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    ngx_http_userid_ctx_t   *ctx;
+    ngx_http_userid_conf_t  *conf;
+
+    conf = ngx_http_get_module_loc_conf(r->main, ngx_http_userid_filter_module);
+
+    if (conf->enable == NGX_HTTP_USERID_OFF) {
+        v->not_found = 1;
+        return NGX_OK;
+    }
+
+    ctx = ngx_http_userid_get_uid(r, conf);
+
+    if (ctx == NULL) {
+        return NGX_ERROR;
+    }
+
+    if (ctx->uid_got[3] != 0) {
+        return ngx_http_userid_variable(r, v, &conf->name, ctx->uid_got);
+    }
+
+    /* ctx->status == NGX_DECLINED */
+
+    v->not_found = 1;
+
+    return NGX_OK;
 }
 
 
-static void
-ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
-    ngx_http_userid_conf_t *conf)
+static ngx_int_t
+ngx_http_userid_set_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
 {
-    ngx_int_t          n;
-    ngx_str_t          src, dst;
-    ngx_table_elt_t  **cookies;
+    ngx_http_userid_ctx_t   *ctx;
+    ngx_http_userid_conf_t  *conf;
+
+    ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module);
+
+    if (ctx == NULL || ctx->uid_set[3] == 0) {
+        v->not_found = 1;
+        return NGX_OK;
+    }
+
+    conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module);
+
+    return ngx_http_userid_variable(r, v, &conf->name, ctx->uid_set);
+}
+
+
+static ngx_http_userid_ctx_t *
+ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf)
+{
+    ngx_int_t                n;
+    ngx_str_t                src, dst;
+    ngx_table_elt_t        **cookies;
+    ngx_http_userid_ctx_t   *ctx;
+
+    ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module);
+
+    if (ctx) {
+        return ctx;
+    }
+
+    if (ctx == NULL) {
+        ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_userid_ctx_t));
+        if (ctx == NULL) {
+            return NULL;
+        }
+
+        ngx_http_set_ctx(r, ctx, ngx_http_userid_filter_module);
+    }
 
     n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &conf->name,
                                           &ctx->cookie);
     if (n == NGX_DECLINED) {
-        return;
+        return ctx;
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -265,7 +323,7 @@ ngx_http_userid_get_uid(ngx_http_request
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                       "client sent too short userid cookie \"%V\"",
                       &cookies[n]->value);
-        return;
+        return ctx;
     }
 
     src = ctx->cookie;
@@ -286,13 +344,15 @@ ngx_http_userid_get_uid(ngx_http_request
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                       "client sent invalid userid cookie \"%V\"",
                       &cookies[n]->value);
-        return;
+        return ctx;
     }
 
     ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "uid: %08XD%08XD%08XD%08XD",
                    ctx->uid_got[0], ctx->uid_got[1],
                    ctx->uid_got[2], ctx->uid_got[3]);
+
+    return ctx;
 }
 
 
@@ -304,7 +364,6 @@ ngx_http_userid_set_uid(ngx_http_request
     size_t            len;
     ngx_str_t         src, dst;
     ngx_table_elt_t  *set_cookie, *p3p;
-
     /*
      * TODO: in the threaded mode the sequencers should be in TLS and their
      * ranges should be divided between threads
@@ -433,50 +492,10 @@ ngx_http_userid_set_uid(ngx_http_request
 
 
 static ngx_int_t
-ngx_http_userid_add_variables(ngx_conf_t *cf)
+ngx_http_userid_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
+    ngx_str_t *name, uint32_t *uid)
 {
-    ngx_http_variable_t  *var;
-
-    var = ngx_http_add_variable(cf, &ngx_http_userid_got, NGX_HTTP_VAR_NOHASH);
-    if (var == NULL) {
-        return NGX_ERROR;
-    }
-
-    var->get_handler = ngx_http_userid_variable;
-    var->data = offsetof(ngx_http_userid_ctx_t, uid_got);
-
-    var = ngx_http_add_variable(cf, &ngx_http_userid_set, NGX_HTTP_VAR_NOHASH);
-    if (var == NULL) {
-        return NGX_ERROR;
-    }
-
-    var->get_handler = ngx_http_userid_variable;
-    var->data = offsetof(ngx_http_userid_ctx_t, uid_set);
-
-    return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_userid_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
-    uintptr_t data)
-{
-    uint32_t                *uid;
-    ngx_http_userid_ctx_t   *ctx;
-    ngx_http_userid_conf_t  *conf;
-
-    ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module);
-
-    uid = (uint32_t *) ((char *) ctx + data);
-
-    if (ctx == NULL || uid[3] == 0) {
-        v->not_found = 1;
-        return NGX_OK;
-    }
-
-    conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module);
-
-    v->len = conf->name.len + sizeof("=00001111222233334444555566667777") - 1;
+    v->len = name->len + sizeof("=00001111222233334444555566667777") - 1;
     v->data = ngx_palloc(r->pool, v->len);
     if (v->data == NULL) {
         return NGX_ERROR;
@@ -487,7 +506,30 @@ ngx_http_userid_variable(ngx_http_reques
     v->not_found = 0;
 
     ngx_sprintf(v->data, "%V=%08XD%08XD%08XD%08XD",
-                &conf->name, uid[0], uid[1], uid[2], uid[3]);
+                name, uid[0], uid[1], uid[2], uid[3]);
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_userid_add_variables(ngx_conf_t *cf)
+{
+    ngx_http_variable_t  *var;
+
+    var = ngx_http_add_variable(cf, &ngx_http_userid_got, NGX_HTTP_VAR_NOHASH);
+    if (var == NULL) {
+        return NGX_ERROR;
+    }
+
+    var->get_handler = ngx_http_userid_got_variable;
+
+    var = ngx_http_add_variable(cf, &ngx_http_userid_set, NGX_HTTP_VAR_NOHASH);
+    if (var == NULL) {
+        return NGX_ERROR;
+    }
+
+    var->get_handler = ngx_http_userid_set_variable;
 
     return NGX_OK;
 }
--- 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.6.31';
+our $VERSION = '0.7.0';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -2606,20 +2606,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t 
     }
 
     if (conf->server_name.data == NULL) {
-        conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN);
-        if (conf->server_name.data == NULL) {
-            return NGX_CONF_ERROR;
-        }
-
-        if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN)
-            == -1)
-        {
-            ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
-                               "gethostname() failed");
-            return NGX_CONF_ERROR;
-        }
-
-        conf->server_name.len = ngx_strlen(conf->server_name.data);
+        conf->server_name = cf->cycle->hostname;
 
         sn = ngx_array_push(&conf->server_names);
         if (sn == NULL) {
@@ -2922,7 +2909,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t 
                 return NGX_CONF_ERROR;
             }
         }
- 
+
         conf->resolver = prev->resolver;
     }
 
@@ -3216,8 +3203,7 @@ ngx_http_core_server_name(ngx_conf_t *cf
         value[i].len--;
         value[i].data++;
 
-        sn->regex = ngx_regex_compile(&value[i], NGX_REGEX_CASELESS, cf->pool,
-                                      &err);
+        sn->regex = ngx_regex_compile(&value[i], 0, cf->pool, &err);
 
         if (sn->regex == NULL) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -286,9 +286,8 @@ ngx_http_header_filter(ngx_http_request_
             cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
             host = cscf->server_name;
 
-        } else if (r->headers_in.host) {
-            host.len = r->headers_in.host_name_len;
-            host.data = r->headers_in.host->value.data;
+        } else if (r->headers_in.server.len) {
+            host = r->headers_in.server;
 
         } else {
             host.data = addr;
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -21,15 +21,20 @@ static ngx_int_t ngx_http_process_header
     ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
+static ngx_int_t ngx_http_process_host(ngx_http_request_t *r,
+    ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
+static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
+    ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
 
 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
 static void ngx_http_process_request(ngx_http_request_t *r);
-static void ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host,
-    size_t len, ngx_uint_t hash);
+static ssize_t ngx_http_validate_host(u_char *host, size_t len);
+static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r,
+    u_char *host, size_t len);
 
 static void ngx_http_request_handler(ngx_event_t *ev);
 static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);
@@ -69,18 +74,15 @@ static char *ngx_http_client_errors[] = 
 
 
 ngx_http_header_t  ngx_http_headers_in[] = {
-    { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
-                 ngx_http_process_unique_header_line },
-
-    { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
-                 ngx_http_process_connection },
+    { ngx_string("Host"), 0, ngx_http_process_host },
+
+    { ngx_string("Connection"), 0, 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"), offsetof(ngx_http_headers_in_t, user_agent),
-                 ngx_http_process_header_line },
+    { ngx_string("User-Agent"), 0, ngx_http_process_user_agent },
 
     { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer),
                  ngx_http_process_header_line },
@@ -562,8 +564,6 @@ ngx_http_ssl_handshake_handler(ngx_conne
 int
 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
 {
-    u_char                   *p;
-    ngx_uint_t                hash;
     const char               *servername;
     ngx_connection_t         *c;
     ngx_http_request_t       *r;
@@ -582,21 +582,13 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *
 
     r = c->data;
 
-    if (r->virtual_names == NULL) {
+    if (ngx_http_find_virtual_server(r, (u_char *) servername,
+                                     ngx_strlen(servername))
+        != NGX_OK)
+    {
         return SSL_TLSEXT_ERR_NOACK;
     }
 
-    /* it seems browsers send low case server name */
-
-    hash = 0;
-
-    for (p = (u_char *) servername; *p; p++) {
-        hash = ngx_hash(hash, *p);
-    }
-
-    ngx_http_find_virtual_server(r, (u_char *) servername,
-                                 p - (u_char *) servername, hash);
-
     sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
 
     SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
@@ -726,7 +718,31 @@ ngx_http_process_request_line(ngx_event_
             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                            "http exten: \"%V\"", &r->exten);
 
+            if (r->host_start && r->host_end) {
+                n = ngx_http_validate_host(r->host_start,
+                                           r->host_end - r->host_start);
+
+                if (n <= 0) {
+                    ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                                  "client sent invalid host in request line");
+                    ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+                    return;
+                }
+
+                r->headers_in.server.len = n;
+                r->headers_in.server.data = r->host_start;
+            }
+
             if (r->http_version < NGX_HTTP_VERSION_10) {
+
+                if (ngx_http_find_virtual_server(r, r->headers_in.server.data,
+                                                 r->headers_in.server.len)
+                    == NGX_ERROR)
+                {
+                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                    return;
+                }
+
                 ngx_http_process_request(r);
                 return;
             }
@@ -1217,6 +1233,36 @@ ngx_http_process_unique_header_line(ngx_
 
 
 static ngx_int_t
+ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
+    ngx_uint_t offset)
+{
+    ssize_t  len;
+
+    if (r->headers_in.host == NULL) {
+        r->headers_in.host = h;
+    }
+
+    len = ngx_http_validate_host(h->value.data, h->value.len);
+
+    if (len <= 0) {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent invalid host header");
+        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+        return NGX_ERROR;
+    }
+
+    if (r->headers_in.server.len) {
+        return NGX_OK;
+    }
+
+    r->headers_in.server.len = len;
+    r->headers_in.server.data = h->value.data;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
@@ -1232,6 +1278,60 @@ ngx_http_process_connection(ngx_http_req
 
 
 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;
+
+    if (r->headers_in.user_agent) {
+        return NGX_OK;
+    }
+
+    r->headers_in.user_agent = h;
+
+    /* check some widespread browsers while the header is in CPU cache */
+
+    user_agent = h->value.data;
+
+    ua = ngx_strstrn(user_agent, "MSIE", 4 - 1);
+
+    if (ua && ua + 8 < user_agent + h->value.len) {
+
+        r->headers_in.msie = 1;
+
+        if (ua[4] == ' ' && ua[5] == '4' && ua[6] == '.') {
+            r->headers_in.msie4 = 1;
+        }
+
+#if 0
+        /* MSIE ignores the SSL "close notify" alert */
+        if (c->ssl) {
+            c->ssl->no_send_shutdown = 1;
+        }
+#endif
+    }
+
+    if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
+        r->headers_in.opera = 1;
+        r->headers_in.msie = 0;
+        r->headers_in.msie4 = 0;
+    }
+
+    if (!r->headers_in.msie && !r->headers_in.opera) {
+
+        if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
+            r->headers_in.gecko = 1;
+
+        } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
+            r->headers_in.konqueror = 1;
+        }
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
@@ -1252,57 +1352,19 @@ ngx_http_process_cookie(ngx_http_request
 static ngx_int_t
 ngx_http_process_request_header(ngx_http_request_t *r)
 {
-    size_t       len;
-    u_char      *host, *ua, *user_agent, ch;
-    ngx_uint_t   hash;
-
-    if (r->headers_in.host) {
-
-        hash = 0;
-
-        for (len = 0; len < r->headers_in.host->value.len; len++) {
-            ch = r->headers_in.host->value.data[len];
-
-            if (ch == ':') {
-                break;
-            }
-
-            ch = ngx_tolower(ch);
-            r->headers_in.host->value.data[len] = ch;
-            hash = ngx_hash(hash, ch);
-        }
-
-        if (len && r->headers_in.host->value.data[len - 1] == '.') {
-            len--;
-            hash = ngx_hash_key(r->headers_in.host->value.data, len);
-        }
-
-        r->headers_in.host_name_len = len;
-
-        if (r->virtual_names) {
-
-            host = r->host_start;
-
-            if (host == NULL) {
-                host = r->headers_in.host->value.data;
-                len = r->headers_in.host_name_len;
-
-            } else {
-                len = r->host_end - host;
-            }
-
-            ngx_http_find_virtual_server(r, host, len, hash);
-        }
-
-    } else {
-        if (r->http_version > NGX_HTTP_VERSION_10) {
-            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
-                       "client sent HTTP/1.1 request without \"Host\" header");
-            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
-            return NGX_ERROR;
-        }
-
-        r->headers_in.host_name_len = 0;
+    if (ngx_http_find_virtual_server(r, r->headers_in.server.data,
+                                     r->headers_in.server.len)
+        == NGX_ERROR)
+    {
+        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return NGX_ERROR;
+    }
+
+    if (r->headers_in.host == NULL && r->http_version > NGX_HTTP_VERSION_10) {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                   "client sent HTTP/1.1 request without \"Host\" header");
+        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+        return NGX_ERROR;
     }
 
     if (r->headers_in.content_length) {
@@ -1353,50 +1415,6 @@ ngx_http_process_request_header(ngx_http
         }
     }
 
-    if (r->headers_in.user_agent) {
-
-        /*
-         * check some widespread browsers while the headers are still
-         * in CPU cache
-         */
-
-        user_agent = r->headers_in.user_agent->value.data;
-
-        ua = ngx_strstrn(user_agent, "MSIE", 4 - 1);
-
-        if (ua && ua + 8 < user_agent + r->headers_in.user_agent->value.len) {
-
-            r->headers_in.msie = 1;
-
-            if (ua[4] == ' ' && ua[5] == '4' && ua[6] == '.') {
-                r->headers_in.msie4 = 1;
-            }
-
-#if 0
-            /* MSIE ignores the SSL "close notify" alert */
-            if (c->ssl) {
-                c->ssl->no_send_shutdown = 1;
-            }
-#endif
-        }
-
-        if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
-            r->headers_in.opera = 1;
-            r->headers_in.msie = 0;
-            r->headers_in.msie4 = 0;
-        }
-
-        if (!r->headers_in.msie && !r->headers_in.opera) {
-
-            if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
-                r->headers_in.gecko = 1;
-
-            } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
-                r->headers_in.konqueror = 1;
-            }
-        }
-    }
-
     return NGX_OK;
 }
 
@@ -1479,14 +1497,89 @@ ngx_http_process_request(ngx_http_reques
 }
 
 
-static void
-ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len,
-    ngx_uint_t hash)
+static ssize_t
+ngx_http_validate_host(u_char *host, size_t len)
 {
+    u_char      ch;
+    size_t      i, last;
+    ngx_uint_t  dot;
+
+    last = len;
+    dot = 0;
+
+    for (i = 0; i < len; i++) {
+        ch = host[i];
+
+        if (ch == '.') {
+            if (dot) {
+                return -1;
+            }
+
+            dot = 1;
+            continue;
+        }
+
+        dot = 0;
+
+        if (ch == ':') {
+            last = i;
+            continue;
+        }
+
+        if (ch == '/' || ch == '\0') {
+            return -1;
+        }
+
+#if (NGX_WIN32)
+        if (ch == '\\') {
+            return -1;
+        }
+#endif
+    }
+
+    if (dot) {
+        last--;
+    }
+
+    return last;
+}
+
+
+static ngx_int_t
+ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
+{
+    u_char                    *server, ch;
+    ngx_uint_t                 i, hash;
     ngx_http_core_loc_conf_t  *clcf;
     ngx_http_core_srv_conf_t  *cscf;
-
-    cscf = ngx_hash_find_combined(&r->virtual_names->names, hash, host, len);
+    u_char                     buf[32];
+
+    if (len == 0 || r->virtual_names == NULL) {
+        return NGX_DECLINED;
+    }
+
+    if (len <= 32) {
+        server = buf;
+
+    } else {
+        server = ngx_palloc(r->pool, len);
+        if (server == NULL) {
+            return NGX_ERROR;
+        }
+    }
+
+    hash = 0;
+
+    for (i = 0; i < len; i++) {
+        ch = host[i];
+
+        ch = ngx_tolower(ch);
+        server[i] = ch;
+
+        hash = ngx_hash(hash, ch);
+    }
+
+    cscf = ngx_hash_find_combined(&r->virtual_names->names, hash, server, len);
 
     if (cscf) {
         goto found;
@@ -1501,7 +1594,7 @@ ngx_http_find_virtual_server(ngx_http_re
         ngx_http_server_name_t  *sn;
 
         name.len = len;
-        name.data = host;
+        name.data = server;
 
         sn = r->virtual_names->regex;
 
@@ -1518,7 +1611,7 @@ ngx_http_find_virtual_server(ngx_http_re
                               ngx_regex_exec_n
                               " failed: %d on \"%V\" using \"%V\"",
                               n, &name, &sn[i].name);
-                return;
+                return NGX_ERROR;
             }
 
             /* match */
@@ -1531,7 +1624,7 @@ ngx_http_find_virtual_server(ngx_http_re
 
 #endif
 
-    return;
+    return NGX_OK;
 
 found:
 
@@ -1545,7 +1638,7 @@ found:
         r->connection->log->log_level = clcf->err_log->log_level;
     }
 
-    return;
+    return NGX_OK;
 }
 
 
@@ -2064,7 +2157,8 @@ ngx_http_set_keepalive(ngx_http_request_
         hc->pipeline = 1;
         c->log->action = "reading client pipelined request line";
 
-        ngx_http_init_request(rev);
+        rev->handler = ngx_http_init_request;
+        ngx_post_event(rev, &ngx_posted_events);
         return;
     }
 
@@ -2180,7 +2274,7 @@ ngx_http_set_keepalive(ngx_http_request_
     c->idle = 1;
 
     if (rev->ready) {
-        ngx_http_keepalive_handler(rev);
+        ngx_post_event(rev, &ngx_posted_events);
     }
 }
 
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -206,7 +206,7 @@ typedef struct {
 
     ngx_array_t                       cookies;
 
-    size_t                            host_name_len;
+    ngx_str_t                         server;
     off_t                             content_length_n;
     time_t                            keep_alive_n;
 
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -75,6 +75,8 @@ static ngx_int_t ngx_http_variable_sent_
 
 static ngx_int_t ngx_http_variable_nginx_version(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_hostname(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 
 /*
  * TODO:
@@ -221,6 +223,9 @@ static ngx_http_variable_t  ngx_http_cor
     { ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version,
       0, 0, 0 },
 
+    { ngx_string("hostname"), NULL, ngx_http_variable_hostname,
+      0, 0, 0 },
+
     { ngx_null_string, NULL, NULL, 0, 0, 0 }
 };
 
@@ -712,26 +717,15 @@ ngx_http_variable_host(ngx_http_request_
 {
     ngx_http_core_srv_conf_t  *cscf;
 
-    if (r->host_start == NULL) {
-
-        if (r->headers_in.host) {
-            v->len = r->headers_in.host_name_len;
-            v->data = r->headers_in.host->value.data;
-
-        } else {
-            cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
-            v->len = cscf->server_name.len;
-            v->data = cscf->server_name.data;
-        }
-
-    } else if (r->host_end) {
-        v->len = r->host_end - r->host_start;
-        v->data = r->host_start;
+    if (r->headers_in.server.len) {
+        v->len = r->headers_in.server.len;
+        v->data = r->headers_in.server.data;
 
     } else {
-        v->not_found = 1;
-        return NGX_OK;
+        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+        v->len = cscf->server_name.len;
+        v->data = cscf->server_name.data;
     }
 
     v->valid = 1;
@@ -1283,6 +1277,20 @@ ngx_http_variable_nginx_version(ngx_http
 }
 
 
+static ngx_int_t
+ngx_http_variable_hostname(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    v->len = ngx_cycle->hostname.len;
+    v->valid = 1;
+    v->no_cacheable = 0;
+    v->not_found = 0;
+    v->data = ngx_cycle->hostname.data;
+
+    return NGX_OK;
+}
+
+
 ngx_int_t
 ngx_http_variables_add_core_vars(ngx_conf_t *cf)
 {
--- a/src/http/ngx_http_variables.h
+++ b/src/http/ngx_http_variables.h
@@ -16,7 +16,7 @@
 
 typedef ngx_variable_value_t  ngx_http_variable_value_t;
 
-#define ngx_http_variable(v)     { sizeof(v) - 1, 1, 0, 0, (u_char *) v }
+#define ngx_http_variable(v)     { sizeof(v) - 1, 1, 0, 0, 0, (u_char *) v }
 
 typedef struct ngx_http_variable_s  ngx_http_variable_t;
 
--- a/src/mail/ngx_mail_core_module.c
+++ b/src/mail/ngx_mail_core_module.c
@@ -185,20 +185,7 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t 
     ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
 
     if (conf->server_name.len == 0) {
-        conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN);
-        if (conf->server_name.data == NULL) {
-            return NGX_CONF_ERROR;
-        }
-
-        if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN)
-            == -1)
-        {
-            ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
-                          "gethostname() failed");
-            return NGX_CONF_ERROR;
-        }
-
-        conf->server_name.len = ngx_strlen(conf->server_name.data);
+        conf->server_name = cf->cycle->hostname;
     }
 
     if (conf->protocol == NULL) {
--- a/src/os/unix/ngx_posix_config.h
+++ b/src/os/unix/ngx_posix_config.h
@@ -110,7 +110,7 @@
 
 #include <sys/param.h>          /* ALIGN() */
 
-/* 
+/*
  * FreeBSD 3.x has no CMSG_SPACE() and CMSG_LEN() and has the broken CMSG_DATA()
  */