diff -rupN nginx-1.7.1/auto/modules nginx-1.7.1-statpatch/auto/modules
--- nginx-1.7.1/auto/modules	2014-05-27 15:58:09.000000000 +0200
+++ nginx-1.7.1-statpatch/auto/modules	2014-06-16 17:59:46.124122700 +0200
@@ -392,6 +392,12 @@ if [ $HTTP_STUB_STATUS = YES ]; then
     HTTP_SRCS="$HTTP_SRCS src/http/modules/ngx_http_stub_status_module.c"
 fi
 
+if [ $HTTP_FULL_STATUS = YES ]; then
+    have=NGX_FULL_STATUS . auto/have
+    HTTP_MODULES="$HTTP_MODULES ngx_http_full_status_module"
+    HTTP_SRCS="$HTTP_SRCS src/http/modules/ngx_http_full_status_module.c"
+fi
+
 #if [ -r $NGX_OBJS/auto ]; then
 #    . $NGX_OBJS/auto
 #fi
diff -rupN nginx-1.7.1/auto/modules.orig nginx-1.7.1-statpatch/auto/modules.orig
--- nginx-1.7.1/auto/modules.orig	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.7.1-statpatch/auto/modules.orig	2014-05-27 15:58:09.000000000 +0200
@@ -0,0 +1,529 @@
+
+# Copyright (C) Igor Sysoev
+# Copyright (C) Nginx, Inc.
+
+
+if [ $EVENT_SELECT = NO -a $EVENT_FOUND = NO ]; then
+    EVENT_SELECT=YES
+fi
+
+if [ $EVENT_SELECT = YES ]; then
+    have=NGX_HAVE_SELECT . auto/have
+    CORE_SRCS="$CORE_SRCS $SELECT_SRCS"
+    EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE"
+fi
+
+
+if [ $EVENT_POLL = NO -a $EVENT_FOUND = NO ]; then
+    EVENT_POLL=YES
+fi
+
+if [ $EVENT_POLL = YES ]; then
+    have=NGX_HAVE_POLL . auto/have
+    CORE_SRCS="$CORE_SRCS $POLL_SRCS"
+    EVENT_MODULES="$EVENT_MODULES $POLL_MODULE"
+fi
+
+
+if [ $NGX_TEST_BUILD_DEVPOLL = YES ]; then
+    have=NGX_HAVE_DEVPOLL . auto/have
+    have=NGX_TEST_BUILD_DEVPOLL . auto/have
+    EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE"
+    CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS"
+fi
+
+
+if [ $NGX_TEST_BUILD_EVENTPORT = YES ]; then
+    have=NGX_HAVE_EVENTPORT . auto/have
+    have=NGX_TEST_BUILD_EVENTPORT . auto/have
+    EVENT_MODULES="$EVENT_MODULES $EVENTPORT_MODULE"
+    CORE_SRCS="$CORE_SRCS $EVENTPORT_SRCS"
+fi
+
+if [ $NGX_TEST_BUILD_EPOLL = YES ]; then
+    have=NGX_HAVE_EPOLL . auto/have
+    have=NGX_HAVE_EPOLLRDHUP . auto/have
+    have=NGX_HAVE_EVENTFD . auto/have
+    have=NGX_TEST_BUILD_EPOLL . auto/have
+    EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
+    CORE_SRCS="$CORE_SRCS $EPOLL_SRCS"
+fi
+
+if [ $NGX_TEST_BUILD_RTSIG = YES ]; then
+    have=NGX_HAVE_RTSIG . auto/have
+    have=NGX_TEST_BUILD_RTSIG . auto/have
+    EVENT_MODULES="$EVENT_MODULES $RTSIG_MODULE"
+    CORE_SRCS="$CORE_SRCS $RTSIG_SRCS"
+fi
+
+if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = YES ]; then
+    have=NGX_TEST_BUILD_SOLARIS_SENDFILEV . auto/have
+    CORE_SRCS="$CORE_SRCS $SOLARIS_SENDFILEV_SRCS"
+fi
+
+
+if [ $HTTP != YES ]; then
+    have=NGX_CRYPT . auto/nohave
+    CRYPT_LIB=
+fi
+
+
+if [ $HTTP_CACHE = YES ]; then
+    USE_MD5=YES
+    have=NGX_HTTP_CACHE . auto/have
+    HTTP_SRCS="$HTTP_SRCS $HTTP_FILE_CACHE_SRCS"
+fi
+
+
+if [ $HTTP_SSI = YES ]; then
+    HTTP_POSTPONE=YES
+fi
+
+
+if [ $HTTP_ADDITION = YES ]; then
+    HTTP_POSTPONE=YES
+fi
+
+
+# the module order is important
+#     ngx_http_static_module
+#     ngx_http_gzip_static_module
+#     ngx_http_dav_module
+#     ngx_http_autoindex_module
+#     ngx_http_index_module
+#     ngx_http_random_index_module
+#
+#     ngx_http_access_module
+#     ngx_http_realip_module
+#
+#
+# the filter order is important
+#     ngx_http_write_filter
+#     ngx_http_header_filter
+#     ngx_http_chunked_filter
+#     ngx_http_spdy_filter
+#     ngx_http_range_header_filter
+#     ngx_http_gzip_filter
+#     ngx_http_postpone_filter
+#     ngx_http_ssi_filter
+#     ngx_http_charset_filter
+#         ngx_http_xslt_filter
+#         ngx_http_image_filter
+#         ngx_http_sub_filter
+#         ngx_http_addition_filter
+#         ngx_http_gunzip_filter
+#         ngx_http_userid_filter
+#         ngx_http_headers_filter
+#     ngx_http_copy_filter
+#     ngx_http_range_body_filter
+#     ngx_http_not_modified_filter
+
+HTTP_FILTER_MODULES="$HTTP_WRITE_FILTER_MODULE \
+                     $HTTP_HEADER_FILTER_MODULE \
+                     $HTTP_CHUNKED_FILTER_MODULE"
+
+if [ $HTTP_SPDY = YES ]; then
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SPDY_FILTER_MODULE"
+fi
+
+HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_RANGE_HEADER_FILTER_MODULE"
+
+if [ $HTTP_GZIP = YES ]; then
+    have=NGX_HTTP_GZIP . auto/have
+    USE_ZLIB=YES
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_GZIP_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_SRCS"
+fi
+
+if [ $HTTP_POSTPONE = YES ]; then
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_POSTPONE_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_POSTPONE_FILTER_SRCS"
+fi
+
+if [ $HTTP_SSI = YES ]; then
+    have=NGX_HTTP_SSI . auto/have
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SSI_FILTER_MODULE"
+    HTTP_DEPS="$HTTP_DEPS $HTTP_SSI_DEPS"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_SSI_SRCS"
+fi
+
+if [ $HTTP_CHARSET = YES ]; then
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_CHARSET_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_CHARSET_SRCS"
+fi
+
+if [ $HTTP_XSLT = YES ]; then
+    USE_LIBXSLT=YES
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_XSLT_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_XSLT_SRCS"
+fi
+
+if [ $HTTP_IMAGE_FILTER = YES ]; then
+    USE_LIBGD=YES
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_IMAGE_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_IMAGE_SRCS"
+fi
+
+if [ $HTTP_SUB = YES ]; then
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SUB_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_SUB_SRCS"
+fi
+
+if [ $HTTP_ADDITION = YES ]; then
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_ADDITION_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_ADDITION_SRCS"
+fi
+
+if [ $HTTP_GUNZIP = YES ]; then
+    have=NGX_HTTP_GZIP . auto/have
+    USE_ZLIB=YES
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_GUNZIP_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_GUNZIP_SRCS"
+fi
+
+if [ $HTTP_USERID = YES ]; then
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_USERID_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_USERID_SRCS"
+fi
+
+
+if [ $HTTP_SPDY = YES ]; then
+    have=NGX_HTTP_SPDY . auto/have
+    USE_ZLIB=YES
+    HTTP_MODULES="$HTTP_MODULES $HTTP_SPDY_MODULE"
+    HTTP_DEPS="$HTTP_DEPS $HTTP_SPDY_DEPS"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_SPDY_SRCS"
+fi
+
+HTTP_MODULES="$HTTP_MODULES $HTTP_STATIC_MODULE"
+
+if [ $HTTP_GZIP_STATIC = YES ]; then
+    have=NGX_HTTP_GZIP . auto/have
+    HTTP_MODULES="$HTTP_MODULES $HTTP_GZIP_STATIC_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_STATIC_SRCS"
+fi
+
+if [ $HTTP_DAV = YES ]; then
+    have=NGX_HTTP_DAV . auto/have
+    HTTP_MODULES="$HTTP_MODULES $HTTP_DAV_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_DAV_SRCS"
+fi
+
+if [ $HTTP_AUTOINDEX = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_AUTOINDEX_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_AUTOINDEX_SRCS"
+fi
+
+HTTP_MODULES="$HTTP_MODULES $HTTP_INDEX_MODULE"
+
+if [ $HTTP_RANDOM_INDEX = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_RANDOM_INDEX_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_RANDOM_INDEX_SRCS"
+fi
+
+if [ $HTTP_AUTH_REQUEST = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_AUTH_REQUEST_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_AUTH_REQUEST_SRCS"
+fi
+
+if [ $HTTP_AUTH_BASIC = YES ]; then
+    USE_MD5=YES
+    USE_SHA1=YES
+    have=NGX_CRYPT . auto/have
+    HTTP_MODULES="$HTTP_MODULES $HTTP_AUTH_BASIC_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_AUTH_BASIC_SRCS"
+    CORE_LIBS="$CORE_LIBS $CRYPT_LIB"
+fi
+
+if [ $HTTP_ACCESS = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_ACCESS_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_ACCESS_SRCS"
+fi
+
+if [ $HTTP_LIMIT_CONN = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_LIMIT_CONN_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_LIMIT_CONN_SRCS"
+fi
+
+if [ $HTTP_LIMIT_REQ = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_LIMIT_REQ_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_LIMIT_REQ_SRCS"
+fi
+
+if [ $HTTP_REALIP = YES ]; then
+    have=NGX_HTTP_REALIP . auto/have
+    have=NGX_HTTP_X_FORWARDED_FOR . auto/have
+    HTTP_MODULES="$HTTP_MODULES $HTTP_REALIP_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_REALIP_SRCS"
+fi
+
+if [ $HTTP_STATUS = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_STATUS_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_STATUS_SRCS"
+fi
+
+if [ $HTTP_GEO = YES ]; then
+    have=NGX_HTTP_X_FORWARDED_FOR . auto/have
+    HTTP_MODULES="$HTTP_MODULES $HTTP_GEO_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_GEO_SRCS"
+fi
+
+if [ $HTTP_GEOIP = YES ]; then
+    have=NGX_HTTP_X_FORWARDED_FOR . auto/have
+    HTTP_MODULES="$HTTP_MODULES $HTTP_GEOIP_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_GEOIP_SRCS"
+fi
+
+if [ $HTTP_MAP = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_MAP_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_MAP_SRCS"
+fi
+
+if [ $HTTP_SPLIT_CLIENTS = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_SPLIT_CLIENTS_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_SPLIT_CLIENTS_SRCS"
+fi
+
+if [ $HTTP_REFERER = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_REFERER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_REFERER_SRCS"
+fi
+
+if [ $HTTP_REWRITE = YES -a $USE_PCRE != DISABLED ]; then
+    USE_PCRE=YES
+    HTTP_MODULES="$HTTP_MODULES $HTTP_REWRITE_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_REWRITE_SRCS"
+fi
+
+if [ $HTTP_SSL = YES ]; then
+    USE_OPENSSL=YES
+    have=NGX_HTTP_SSL . auto/have
+    HTTP_MODULES="$HTTP_MODULES $HTTP_SSL_MODULE"
+    HTTP_DEPS="$HTTP_DEPS $HTTP_SSL_DEPS"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_SSL_SRCS"
+fi
+
+if [ $HTTP_PROXY = YES ]; then
+    have=NGX_HTTP_X_FORWARDED_FOR . auto/have
+    #USE_MD5=YES
+    HTTP_MODULES="$HTTP_MODULES $HTTP_PROXY_MODULE"
+    HTTP_DEPS="$HTTP_DEPS $HTTP_PROXY_DEPS"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_PROXY_SRCS"
+fi
+
+if [ $HTTP_FASTCGI = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_FASTCGI_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_FASTCGI_SRCS"
+fi
+
+if [ $HTTP_UWSGI = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_UWSGI_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_UWSGI_SRCS"
+fi
+
+if [ $HTTP_SCGI = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_SCGI_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_SCGI_SRCS"
+fi
+
+if [ $HTTP_PERL = YES ]; then
+    USE_PERL=YES
+    HTTP_MODULES="$HTTP_MODULES $HTTP_PERL_MODULE"
+    HTTP_INCS="$HTTP_INCS $HTTP_PERL_INCS"
+    HTTP_DEPS="$HTTP_DEPS $HTTP_PERL_DEPS"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_PERL_SRCS"
+fi
+
+if [ $HTTP_MEMCACHED = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_MEMCACHED_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_MEMCACHED_SRCS"
+fi
+
+if [ $HTTP_EMPTY_GIF = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_EMPTY_GIF_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_EMPTY_GIF_SRCS"
+fi
+
+if [ $HTTP_BROWSER = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_BROWSER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_BROWSER_SRCS"
+fi
+
+if [ $HTTP_SECURE_LINK = YES ]; then
+    USE_MD5=YES
+    HTTP_MODULES="$HTTP_MODULES $HTTP_SECURE_LINK_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_SECURE_LINK_SRCS"
+fi
+
+if [ $HTTP_DEGRADATION = YES ]; then
+    have=NGX_HTTP_DEGRADATION . auto/have
+    HTTP_MODULES="$HTTP_MODULES $HTTP_DEGRADATION_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_DEGRADATION_SRCS"
+fi
+
+if [ $HTTP_FLV = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_FLV_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_FLV_SRCS"
+fi
+
+if [ $HTTP_MP4 = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_MP4_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_MP4_SRCS"
+fi
+
+if [ $HTTP_UPSTREAM_IP_HASH = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_IP_HASH_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_IP_HASH_SRCS"
+fi
+
+if [ $HTTP_UPSTREAM_LEAST_CONN = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_LEAST_CONN_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_LEAST_CONN_SRCS"
+fi
+
+if [ $HTTP_UPSTREAM_KEEPALIVE = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_KEEPALIVE_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_KEEPALIVE_SRCS"
+fi
+
+if [ $HTTP_STUB_STATUS = YES ]; then
+    have=NGX_STAT_STUB . auto/have
+    HTTP_MODULES="$HTTP_MODULES ngx_http_stub_status_module"
+    HTTP_SRCS="$HTTP_SRCS src/http/modules/ngx_http_stub_status_module.c"
+fi
+
+#if [ -r $NGX_OBJS/auto ]; then
+#    . $NGX_OBJS/auto
+#fi
+
+
+if test -n "$NGX_ADDONS"; then
+
+    echo configuring additional modules
+
+    for ngx_addon_dir in $NGX_ADDONS
+    do
+        echo "adding module in $ngx_addon_dir"
+
+        if test -f $ngx_addon_dir/config; then
+            . $ngx_addon_dir/config
+
+            echo " + $ngx_addon_name was configured"
+
+        else
+            echo "$0: error: no $ngx_addon_dir/config was found"
+            exit 1
+        fi
+    done
+fi
+
+
+if [ $MAIL_SSL = YES ]; then
+    have=NGX_MAIL_SSL . auto/have
+    USE_OPENSSL=YES
+fi
+
+
+modules="$CORE_MODULES $EVENT_MODULES"
+
+
+if [ $USE_OPENSSL = YES ]; then
+    modules="$modules $OPENSSL_MODULE"
+    CORE_DEPS="$CORE_DEPS $OPENSSL_DEPS"
+    CORE_SRCS="$CORE_SRCS $OPENSSL_SRCS"
+fi
+
+if [ $USE_PCRE = YES ]; then
+    modules="$modules $REGEX_MODULE"
+    CORE_DEPS="$CORE_DEPS $REGEX_DEPS"
+    CORE_SRCS="$CORE_SRCS $REGEX_SRCS"
+fi
+
+if [ $HTTP = YES ]; then
+    modules="$modules $HTTP_MODULES $HTTP_FILTER_MODULES \
+             $HTTP_HEADERS_FILTER_MODULE \
+             $HTTP_AUX_FILTER_MODULES \
+             $HTTP_COPY_FILTER_MODULE \
+             $HTTP_RANGE_BODY_FILTER_MODULE \
+             $HTTP_NOT_MODIFIED_FILTER_MODULE"
+
+    NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(HTTP_DEPS)"
+fi
+
+
+if [ $MAIL = YES ]; then
+    modules="$modules $MAIL_MODULES"
+
+    if [ $MAIL_SSL = YES ]; then
+        modules="$modules $MAIL_SSL_MODULE"
+        MAIL_DEPS="$MAIL_DEPS $MAIL_SSL_DEPS"
+        MAIL_SRCS="$MAIL_SRCS $MAIL_SSL_SRCS"
+    fi
+
+    if [ $MAIL_POP3 = YES ]; then
+        modules="$modules $MAIL_POP3_MODULE"
+        MAIL_DEPS="$MAIL_DEPS $MAIL_POP3_DEPS"
+        MAIL_SRCS="$MAIL_SRCS $MAIL_POP3_SRCS"
+    fi
+
+    if [ $MAIL_IMAP = YES ]; then
+        modules="$modules $MAIL_IMAP_MODULE"
+        MAIL_DEPS="$MAIL_DEPS $MAIL_IMAP_DEPS"
+        MAIL_SRCS="$MAIL_SRCS $MAIL_IMAP_SRCS"
+    fi
+
+    if [ $MAIL_SMTP = YES ]; then
+        modules="$modules $MAIL_SMTP_MODULE"
+        MAIL_DEPS="$MAIL_DEPS $MAIL_SMTP_DEPS"
+        MAIL_SRCS="$MAIL_SRCS $MAIL_SMTP_SRCS"
+    fi
+
+    modules="$modules $MAIL_AUTH_HTTP_MODULE"
+    MAIL_SRCS="$MAIL_SRCS $MAIL_AUTH_HTTP_SRCS"
+
+    modules="$modules $MAIL_PROXY_MODULE"
+    MAIL_SRCS="$MAIL_SRCS $MAIL_PROXY_SRCS"
+
+    NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(MAIL_DEPS)"
+fi
+
+
+if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then
+    modules="$modules $NGX_GOOGLE_PERFTOOLS_MODULE"
+    NGX_MISC_SRCS="$NGX_MISC_SRCS $NGX_GOOGLE_PERFTOOLS_SRCS"
+fi
+
+
+if [ $NGX_CPP_TEST = YES ]; then
+    NGX_MISC_SRCS="$NGX_MISC_SRCS $NGX_CPP_TEST_SRCS"
+    CORE_LIBS="$CORE_LIBS -lstdc++"
+fi
+
+
+cat << END                                    > $NGX_MODULES_C
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+$NGX_PRAGMA
+
+END
+
+for mod in $modules
+do
+    echo "extern ngx_module_t  $mod;"         >> $NGX_MODULES_C
+done
+
+echo                                          >> $NGX_MODULES_C
+echo 'ngx_module_t *ngx_modules[] = {'        >> $NGX_MODULES_C
+
+for mod in $modules
+do
+    echo "    &$mod,"                         >> $NGX_MODULES_C
+done
+
+cat << END                                    >> $NGX_MODULES_C
+    NULL
+};
+
+END
diff -rupN nginx-1.7.1/auto/options nginx-1.7.1-statpatch/auto/options
--- nginx-1.7.1/auto/options	2014-05-27 15:58:09.000000000 +0200
+++ nginx-1.7.1-statpatch/auto/options	2014-06-16 17:59:46.127122900 +0200
@@ -105,6 +105,7 @@ HTTP_UPSTREAM_KEEPALIVE=YES
 
 # STUB
 HTTP_STUB_STATUS=NO
+HTTP_FULL_STATUS=YES
 
 MAIL=NO
 MAIL_SSL=NO
@@ -262,7 +263,9 @@ use the \"--without-http_limit_conn_modu
 
         # STUB
         --with-http_stub_status_module)  HTTP_STUB_STATUS=YES       ;;
-
+        # FULL STATUS
+        --with-http_full_status_module)  HTTP_FULL_STATUS=YES       ;;
+	
         --with-mail)                     MAIL=YES                   ;;
         --with-mail_ssl_module)          MAIL_SSL=YES               ;;
         # STUB
@@ -373,7 +376,8 @@ cat << END
   --with-http_secure_link_module     enable ngx_http_secure_link_module
   --with-http_degradation_module     enable ngx_http_degradation_module
   --with-http_stub_status_module     enable ngx_http_stub_status_module
-
+  --with-http_full_status_module     enable ngx_http_full_status_module
+  
   --without-http_charset_module      disable ngx_http_charset_module
   --without-http_gzip_module         disable ngx_http_gzip_module
   --without-http_ssi_module          disable ngx_http_ssi_module
diff -rupN nginx-1.7.1/auto/options.orig nginx-1.7.1-statpatch/auto/options.orig
--- nginx-1.7.1/auto/options.orig	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.7.1-statpatch/auto/options.orig	2014-05-27 15:58:09.000000000 +0200
@@ -0,0 +1,523 @@
+
+# Copyright (C) Igor Sysoev
+# Copyright (C) Nginx, Inc.
+
+
+help=no
+
+NGX_PREFIX=
+NGX_SBIN_PATH=
+NGX_CONF_PREFIX=
+NGX_CONF_PATH=
+NGX_ERROR_LOG_PATH=
+NGX_PID_PATH=
+NGX_LOCK_PATH=
+NGX_USER=
+NGX_GROUP=
+NGX_BUILD=
+
+CC=${CC:-cc}
+CPP=
+NGX_OBJS=objs
+
+NGX_DEBUG=NO
+NGX_CC_OPT=
+NGX_LD_OPT=
+CPU=NO
+
+NGX_RPATH=NO
+
+NGX_TEST_BUILD_DEVPOLL=NO
+NGX_TEST_BUILD_EVENTPORT=NO
+NGX_TEST_BUILD_EPOLL=NO
+NGX_TEST_BUILD_RTSIG=NO
+NGX_TEST_BUILD_SOLARIS_SENDFILEV=NO
+
+NGX_PLATFORM=
+NGX_WINE=
+
+EVENT_FOUND=NO
+
+EVENT_RTSIG=NO
+EVENT_SELECT=NO
+EVENT_POLL=NO
+EVENT_AIO=NO
+
+USE_THREADS=NO
+
+NGX_FILE_AIO=NO
+NGX_IPV6=NO
+
+HTTP=YES
+
+NGX_HTTP_LOG_PATH=
+NGX_HTTP_CLIENT_TEMP_PATH=
+NGX_HTTP_PROXY_TEMP_PATH=
+NGX_HTTP_FASTCGI_TEMP_PATH=
+NGX_HTTP_UWSGI_TEMP_PATH=
+NGX_HTTP_SCGI_TEMP_PATH=
+
+HTTP_CACHE=YES
+HTTP_CHARSET=YES
+HTTP_GZIP=YES
+HTTP_SSL=NO
+HTTP_SPDY=NO
+HTTP_SSI=YES
+HTTP_POSTPONE=NO
+HTTP_REALIP=NO
+HTTP_XSLT=NO
+HTTP_IMAGE_FILTER=NO
+HTTP_SUB=NO
+HTTP_ADDITION=NO
+HTTP_DAV=NO
+HTTP_ACCESS=YES
+HTTP_AUTH_BASIC=YES
+HTTP_AUTH_REQUEST=NO
+HTTP_USERID=YES
+HTTP_AUTOINDEX=YES
+HTTP_RANDOM_INDEX=NO
+HTTP_STATUS=NO
+HTTP_GEO=YES
+HTTP_GEOIP=NO
+HTTP_MAP=YES
+HTTP_SPLIT_CLIENTS=YES
+HTTP_REFERER=YES
+HTTP_REWRITE=YES
+HTTP_PROXY=YES
+HTTP_FASTCGI=YES
+HTTP_UWSGI=YES
+HTTP_SCGI=YES
+HTTP_PERL=NO
+HTTP_MEMCACHED=YES
+HTTP_LIMIT_CONN=YES
+HTTP_LIMIT_REQ=YES
+HTTP_EMPTY_GIF=YES
+HTTP_BROWSER=YES
+HTTP_SECURE_LINK=NO
+HTTP_DEGRADATION=NO
+HTTP_FLV=NO
+HTTP_MP4=NO
+HTTP_GUNZIP=NO
+HTTP_GZIP_STATIC=NO
+HTTP_UPSTREAM_IP_HASH=YES
+HTTP_UPSTREAM_LEAST_CONN=YES
+HTTP_UPSTREAM_KEEPALIVE=YES
+
+# STUB
+HTTP_STUB_STATUS=NO
+
+MAIL=NO
+MAIL_SSL=NO
+MAIL_POP3=YES
+MAIL_IMAP=YES
+MAIL_SMTP=YES
+
+NGX_ADDONS=
+
+USE_PCRE=NO
+PCRE=NONE
+PCRE_OPT=
+PCRE_CONF_OPT=
+PCRE_JIT=NO
+
+USE_OPENSSL=NO
+OPENSSL=NONE
+
+USE_MD5=NO
+MD5=NONE
+MD5_OPT=
+MD5_ASM=NO
+
+USE_SHA1=NO
+SHA1=NONE
+SHA1_OPT=
+SHA1_ASM=NO
+
+USE_ZLIB=NO
+ZLIB=NONE
+ZLIB_OPT=
+ZLIB_ASM=NO
+
+USE_PERL=NO
+NGX_PERL=perl
+
+USE_LIBXSLT=NO
+USE_LIBGD=NO
+
+NGX_GOOGLE_PERFTOOLS=NO
+NGX_CPP_TEST=NO
+
+NGX_LIBATOMIC=NO
+
+NGX_CPU_CACHE_LINE=
+
+NGX_POST_CONF_MSG=
+
+opt=
+
+for option
+do
+    opt="$opt `echo $option | sed -e \"s/\(--[^=]*=\)\(.* .*\)/\1'\2'/\"`"
+
+    case "$option" in
+        -*=*) value=`echo "$option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+           *) value="" ;;
+    esac
+
+    case "$option" in
+        --help)                          help=yes                   ;;
+
+        --prefix=)                       NGX_PREFIX="!"             ;;
+        --prefix=*)                      NGX_PREFIX="$value"        ;;
+        --sbin-path=*)                   NGX_SBIN_PATH="$value"     ;;
+        --conf-path=*)                   NGX_CONF_PATH="$value"     ;;
+        --error-log-path=*)              NGX_ERROR_LOG_PATH="$value";;
+        --pid-path=*)                    NGX_PID_PATH="$value"      ;;
+        --lock-path=*)                   NGX_LOCK_PATH="$value"     ;;
+        --user=*)                        NGX_USER="$value"          ;;
+        --group=*)                       NGX_GROUP="$value"         ;;
+
+        --crossbuild=*)                  NGX_PLATFORM="$value"      ;;
+
+        --build=*)                       NGX_BUILD="$value"         ;;
+        --builddir=*)                    NGX_OBJS="$value"          ;;
+
+        --with-rtsig_module)             EVENT_RTSIG=YES            ;;
+        --with-select_module)            EVENT_SELECT=YES           ;;
+        --without-select_module)         EVENT_SELECT=NONE          ;;
+        --with-poll_module)              EVENT_POLL=YES             ;;
+        --without-poll_module)           EVENT_POLL=NONE            ;;
+        --with-aio_module)               EVENT_AIO=YES              ;;
+
+        #--with-threads=*)                USE_THREADS="$value"       ;;
+        #--with-threads)                  USE_THREADS="pthreads"     ;;
+
+        --with-file-aio)                 NGX_FILE_AIO=YES           ;;
+        --with-ipv6)                     NGX_IPV6=YES               ;;
+
+        --without-http)                  HTTP=NO                    ;;
+        --without-http-cache)            HTTP_CACHE=NO              ;;
+
+        --http-log-path=*)               NGX_HTTP_LOG_PATH="$value" ;;
+        --http-client-body-temp-path=*)  NGX_HTTP_CLIENT_TEMP_PATH="$value" ;;
+        --http-proxy-temp-path=*)        NGX_HTTP_PROXY_TEMP_PATH="$value" ;;
+        --http-fastcgi-temp-path=*)      NGX_HTTP_FASTCGI_TEMP_PATH="$value" ;;
+        --http-uwsgi-temp-path=*)        NGX_HTTP_UWSGI_TEMP_PATH="$value" ;;
+        --http-scgi-temp-path=*)         NGX_HTTP_SCGI_TEMP_PATH="$value" ;;
+
+        --with-http_ssl_module)          HTTP_SSL=YES               ;;
+        --with-http_spdy_module)         HTTP_SPDY=YES              ;;
+        --with-http_realip_module)       HTTP_REALIP=YES            ;;
+        --with-http_addition_module)     HTTP_ADDITION=YES          ;;
+        --with-http_xslt_module)         HTTP_XSLT=YES              ;;
+        --with-http_image_filter_module) HTTP_IMAGE_FILTER=YES      ;;
+        --with-http_geoip_module)        HTTP_GEOIP=YES             ;;
+        --with-http_sub_module)          HTTP_SUB=YES               ;;
+        --with-http_dav_module)          HTTP_DAV=YES               ;;
+        --with-http_flv_module)          HTTP_FLV=YES               ;;
+        --with-http_mp4_module)          HTTP_MP4=YES               ;;
+        --with-http_gunzip_module)       HTTP_GUNZIP=YES            ;;
+        --with-http_gzip_static_module)  HTTP_GZIP_STATIC=YES       ;;
+        --with-http_auth_request_module) HTTP_AUTH_REQUEST=YES      ;;
+        --with-http_random_index_module) HTTP_RANDOM_INDEX=YES      ;;
+        --with-http_secure_link_module)  HTTP_SECURE_LINK=YES       ;;
+        --with-http_degradation_module)  HTTP_DEGRADATION=YES       ;;
+
+        --without-http_charset_module)   HTTP_CHARSET=NO            ;;
+        --without-http_gzip_module)      HTTP_GZIP=NO               ;;
+        --without-http_ssi_module)       HTTP_SSI=NO                ;;
+        --without-http_userid_module)    HTTP_USERID=NO             ;;
+        --without-http_access_module)    HTTP_ACCESS=NO             ;;
+        --without-http_auth_basic_module) HTTP_AUTH_BASIC=NO        ;;
+        --without-http_autoindex_module) HTTP_AUTOINDEX=NO          ;;
+        --without-http_status_module)    HTTP_STATUS=NO             ;;
+        --without-http_geo_module)       HTTP_GEO=NO                ;;
+        --without-http_map_module)       HTTP_MAP=NO                ;;
+        --without-http_split_clients_module) HTTP_SPLIT_CLIENTS=NO  ;;
+        --without-http_referer_module)   HTTP_REFERER=NO            ;;
+        --without-http_rewrite_module)   HTTP_REWRITE=NO            ;;
+        --without-http_proxy_module)     HTTP_PROXY=NO              ;;
+        --without-http_fastcgi_module)   HTTP_FASTCGI=NO            ;;
+        --without-http_uwsgi_module)     HTTP_UWSGI=NO              ;;
+        --without-http_scgi_module)      HTTP_SCGI=NO               ;;
+        --without-http_memcached_module) HTTP_MEMCACHED=NO          ;;
+        --without-http_limit_zone_module)
+            HTTP_LIMIT_CONN=NO
+            NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG
+$0: warning: the \"--without-http_limit_zone_module\" option is deprecated, \
+use the \"--without-http_limit_conn_module\" option instead"
+        ;;
+        --without-http_limit_conn_module) HTTP_LIMIT_CONN=NO        ;;
+        --without-http_limit_req_module) HTTP_LIMIT_REQ=NO         ;;
+        --without-http_empty_gif_module) HTTP_EMPTY_GIF=NO          ;;
+        --without-http_browser_module)   HTTP_BROWSER=NO            ;;
+        --without-http_upstream_ip_hash_module) HTTP_UPSTREAM_IP_HASH=NO ;;
+        --without-http_upstream_least_conn_module)
+                                         HTTP_UPSTREAM_LEAST_CONN=NO ;;
+        --without-http_upstream_keepalive_module) HTTP_UPSTREAM_KEEPALIVE=NO ;;
+
+        --with-http_perl_module)         HTTP_PERL=YES              ;;
+        --with-perl_modules_path=*)      NGX_PERL_MODULES="$value"  ;;
+        --with-perl=*)                   NGX_PERL="$value"          ;;
+
+        # STUB
+        --with-http_stub_status_module)  HTTP_STUB_STATUS=YES       ;;
+
+        --with-mail)                     MAIL=YES                   ;;
+        --with-mail_ssl_module)          MAIL_SSL=YES               ;;
+        # STUB
+        --with-imap)                     MAIL=YES                   ;;
+        --with-imap_ssl_module)          MAIL_SSL=YES               ;;
+        --without-mail_pop3_module)      MAIL_POP3=NO               ;;
+        --without-mail_imap_module)      MAIL_IMAP=NO               ;;
+        --without-mail_smtp_module)      MAIL_SMTP=NO               ;;
+
+        --with-google_perftools_module)  NGX_GOOGLE_PERFTOOLS=YES   ;;
+        --with-cpp_test_module)          NGX_CPP_TEST=YES           ;;
+
+        --add-module=*)                  NGX_ADDONS="$NGX_ADDONS $value" ;;
+
+        --with-cc=*)                     CC="$value"                ;;
+        --with-cpp=*)                    CPP="$value"               ;;
+        --with-cc-opt=*)                 NGX_CC_OPT="$value"        ;;
+        --with-ld-opt=*)                 NGX_LD_OPT="$value"        ;;
+        --with-cpu-opt=*)                CPU="$value"               ;;
+        --with-debug)                    NGX_DEBUG=YES              ;;
+
+        --without-pcre)                  USE_PCRE=DISABLED          ;;
+        --with-pcre)                     USE_PCRE=YES               ;;
+        --with-pcre=*)                   PCRE="$value"              ;;
+        --with-pcre-opt=*)               PCRE_OPT="$value"          ;;
+        --with-pcre-jit)                 PCRE_JIT=YES               ;;
+
+        --with-openssl=*)                OPENSSL="$value"           ;;
+        --with-openssl-opt=*)            OPENSSL_OPT="$value"       ;;
+
+        --with-md5=*)                    MD5="$value"               ;;
+        --with-md5-opt=*)                MD5_OPT="$value"           ;;
+        --with-md5-asm)                  MD5_ASM=YES                ;;
+
+        --with-sha1=*)                   SHA1="$value"              ;;
+        --with-sha1-opt=*)               SHA1_OPT="$value"          ;;
+        --with-sha1-asm)                 SHA1_ASM=YES               ;;
+
+        --with-zlib=*)                   ZLIB="$value"              ;;
+        --with-zlib-opt=*)               ZLIB_OPT="$value"          ;;
+        --with-zlib-asm=*)               ZLIB_ASM="$value"          ;;
+
+        --with-libatomic)                NGX_LIBATOMIC=YES          ;;
+        --with-libatomic=*)              NGX_LIBATOMIC="$value"     ;;
+
+        --test-build-devpoll)            NGX_TEST_BUILD_DEVPOLL=YES ;;
+        --test-build-eventport)          NGX_TEST_BUILD_EVENTPORT=YES ;;
+        --test-build-epoll)              NGX_TEST_BUILD_EPOLL=YES   ;;
+        --test-build-rtsig)              NGX_TEST_BUILD_RTSIG=YES   ;;
+        --test-build-solaris-sendfilev)  NGX_TEST_BUILD_SOLARIS_SENDFILEV=YES ;;
+
+        *)
+            echo "$0: error: invalid option \"$option\""
+            exit 1
+        ;;
+    esac
+done
+
+
+NGX_CONFIGURE="$opt"
+
+
+if [ $help = yes ]; then
+
+cat << END
+
+  --help                             print this message
+
+  --prefix=PATH                      set installation prefix
+  --sbin-path=PATH                   set nginx binary pathname
+  --conf-path=PATH                   set nginx.conf pathname
+  --error-log-path=PATH              set error log pathname
+  --pid-path=PATH                    set nginx.pid pathname
+  --lock-path=PATH                   set nginx.lock pathname
+
+  --user=USER                        set non-privileged user for
+                                     worker processes
+  --group=GROUP                      set non-privileged group for
+                                     worker processes
+
+  --build=NAME                       set build name
+  --builddir=DIR                     set build directory
+
+  --with-rtsig_module                enable rtsig module
+  --with-select_module               enable select module
+  --without-select_module            disable select module
+  --with-poll_module                 enable poll module
+  --without-poll_module              disable poll module
+
+  --with-file-aio                    enable file AIO support
+  --with-ipv6                        enable IPv6 support
+
+  --with-http_ssl_module             enable ngx_http_ssl_module
+  --with-http_spdy_module            enable ngx_http_spdy_module
+  --with-http_realip_module          enable ngx_http_realip_module
+  --with-http_addition_module        enable ngx_http_addition_module
+  --with-http_xslt_module            enable ngx_http_xslt_module
+  --with-http_image_filter_module    enable ngx_http_image_filter_module
+  --with-http_geoip_module           enable ngx_http_geoip_module
+  --with-http_sub_module             enable ngx_http_sub_module
+  --with-http_dav_module             enable ngx_http_dav_module
+  --with-http_flv_module             enable ngx_http_flv_module
+  --with-http_mp4_module             enable ngx_http_mp4_module
+  --with-http_gunzip_module          enable ngx_http_gunzip_module
+  --with-http_gzip_static_module     enable ngx_http_gzip_static_module
+  --with-http_auth_request_module    enable ngx_http_auth_request_module
+  --with-http_random_index_module    enable ngx_http_random_index_module
+  --with-http_secure_link_module     enable ngx_http_secure_link_module
+  --with-http_degradation_module     enable ngx_http_degradation_module
+  --with-http_stub_status_module     enable ngx_http_stub_status_module
+
+  --without-http_charset_module      disable ngx_http_charset_module
+  --without-http_gzip_module         disable ngx_http_gzip_module
+  --without-http_ssi_module          disable ngx_http_ssi_module
+  --without-http_userid_module       disable ngx_http_userid_module
+  --without-http_access_module       disable ngx_http_access_module
+  --without-http_auth_basic_module   disable ngx_http_auth_basic_module
+  --without-http_autoindex_module    disable ngx_http_autoindex_module
+  --without-http_geo_module          disable ngx_http_geo_module
+  --without-http_map_module          disable ngx_http_map_module
+  --without-http_split_clients_module disable ngx_http_split_clients_module
+  --without-http_referer_module      disable ngx_http_referer_module
+  --without-http_rewrite_module      disable ngx_http_rewrite_module
+  --without-http_proxy_module        disable ngx_http_proxy_module
+  --without-http_fastcgi_module      disable ngx_http_fastcgi_module
+  --without-http_uwsgi_module        disable ngx_http_uwsgi_module
+  --without-http_scgi_module         disable ngx_http_scgi_module
+  --without-http_memcached_module    disable ngx_http_memcached_module
+  --without-http_limit_conn_module   disable ngx_http_limit_conn_module
+  --without-http_limit_req_module    disable ngx_http_limit_req_module
+  --without-http_empty_gif_module    disable ngx_http_empty_gif_module
+  --without-http_browser_module      disable ngx_http_browser_module
+  --without-http_upstream_ip_hash_module
+                                     disable ngx_http_upstream_ip_hash_module
+  --without-http_upstream_least_conn_module
+                                     disable ngx_http_upstream_least_conn_module
+  --without-http_upstream_keepalive_module
+                                     disable ngx_http_upstream_keepalive_module
+
+  --with-http_perl_module            enable ngx_http_perl_module
+  --with-perl_modules_path=PATH      set Perl modules path
+  --with-perl=PATH                   set perl binary pathname
+
+  --http-log-path=PATH               set http access log pathname
+  --http-client-body-temp-path=PATH  set path to store
+                                     http client request body temporary files
+  --http-proxy-temp-path=PATH        set path to store
+                                     http proxy temporary files
+  --http-fastcgi-temp-path=PATH      set path to store
+                                     http fastcgi temporary files
+  --http-uwsgi-temp-path=PATH        set path to store
+                                     http uwsgi temporary files
+  --http-scgi-temp-path=PATH         set path to store
+                                     http scgi temporary files
+
+  --without-http                     disable HTTP server
+  --without-http-cache               disable HTTP cache
+
+  --with-mail                        enable POP3/IMAP4/SMTP proxy module
+  --with-mail_ssl_module             enable ngx_mail_ssl_module
+  --without-mail_pop3_module         disable ngx_mail_pop3_module
+  --without-mail_imap_module         disable ngx_mail_imap_module
+  --without-mail_smtp_module         disable ngx_mail_smtp_module
+
+  --with-google_perftools_module     enable ngx_google_perftools_module
+  --with-cpp_test_module             enable ngx_cpp_test_module
+
+  --add-module=PATH                  enable an external module
+
+  --with-cc=PATH                     set C compiler pathname
+  --with-cpp=PATH                    set C preprocessor pathname
+  --with-cc-opt=OPTIONS              set additional C compiler options
+  --with-ld-opt=OPTIONS              set additional linker options
+  --with-cpu-opt=CPU                 build for the specified CPU, valid values:
+                                     pentium, pentiumpro, pentium3, pentium4,
+                                     athlon, opteron, sparc32, sparc64, ppc64
+
+  --without-pcre                     disable PCRE library usage
+  --with-pcre                        force PCRE library usage
+  --with-pcre=DIR                    set path to PCRE library sources
+  --with-pcre-opt=OPTIONS            set additional build options for PCRE
+  --with-pcre-jit                    build PCRE with JIT compilation support
+
+  --with-md5=DIR                     set path to md5 library sources
+  --with-md5-opt=OPTIONS             set additional build options for md5
+  --with-md5-asm                     use md5 assembler sources
+
+  --with-sha1=DIR                    set path to sha1 library sources
+  --with-sha1-opt=OPTIONS            set additional build options for sha1
+  --with-sha1-asm                    use sha1 assembler sources
+
+  --with-zlib=DIR                    set path to zlib library sources
+  --with-zlib-opt=OPTIONS            set additional build options for zlib
+  --with-zlib-asm=CPU                use zlib assembler sources optimized
+                                     for the specified CPU, valid values:
+                                     pentium, pentiumpro
+
+  --with-libatomic                   force libatomic_ops library usage
+  --with-libatomic=DIR               set path to libatomic_ops library sources
+
+  --with-openssl=DIR                 set path to OpenSSL library sources
+  --with-openssl-opt=OPTIONS         set additional build options for OpenSSL
+
+  --with-debug                       enable debug logging
+
+END
+
+    exit 1
+fi
+
+
+if [ $HTTP = NO ]; then
+    HTTP_CHARSET=NO
+    HTTP_GZIP=NO
+    HTTP_SSI=NO
+    HTTP_USERID=NO
+    HTTP_ACCESS=NO
+    HTTP_STATUS=NO
+    HTTP_REWRITE=NO
+    HTTP_PROXY=NO
+    HTTP_FASTCGI=NO
+fi
+
+
+if [ ".$NGX_PLATFORM" = ".win32" ]; then
+    NGX_WINE=$WINE
+fi
+
+
+NGX_CONF_PATH=${NGX_CONF_PATH:-conf/nginx.conf}
+NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH`
+NGX_PID_PATH=${NGX_PID_PATH:-logs/nginx.pid}
+NGX_LOCK_PATH=${NGX_LOCK_PATH:-logs/nginx.lock}
+
+if [ ".$NGX_ERROR_LOG_PATH" = ".stderr" ]; then
+    NGX_ERROR_LOG_PATH=
+else
+    NGX_ERROR_LOG_PATH=${NGX_ERROR_LOG_PATH:-logs/error.log}
+fi
+
+NGX_HTTP_LOG_PATH=${NGX_HTTP_LOG_PATH:-logs/access.log}
+NGX_HTTP_CLIENT_TEMP_PATH=${NGX_HTTP_CLIENT_TEMP_PATH:-client_body_temp}
+NGX_HTTP_PROXY_TEMP_PATH=${NGX_HTTP_PROXY_TEMP_PATH:-proxy_temp}
+NGX_HTTP_FASTCGI_TEMP_PATH=${NGX_HTTP_FASTCGI_TEMP_PATH:-fastcgi_temp}
+NGX_HTTP_UWSGI_TEMP_PATH=${NGX_HTTP_UWSGI_TEMP_PATH:-uwsgi_temp}
+NGX_HTTP_SCGI_TEMP_PATH=${NGX_HTTP_SCGI_TEMP_PATH:-scgi_temp}
+
+case ".$NGX_PERL_MODULES" in
+    ./*)
+    ;;
+
+    .)
+    ;;
+
+    *)
+        NGX_PERL_MODULES=$NGX_PREFIX/$NGX_PERL_MODULES
+    ;;
+esac
diff -rupN nginx-1.7.1/src/core/ngx_core.h nginx-1.7.1-statpatch/src/core/ngx_core.h
--- nginx-1.7.1/src/core/ngx_core.h	2014-05-27 15:58:09.000000000 +0200
+++ nginx-1.7.1-statpatch/src/core/ngx_core.h	2014-06-16 18:01:23.570696300 +0200
@@ -80,7 +80,30 @@ typedef void (*ngx_connection_handler_pt
 #include <ngx_syslog.h>
 #include <ngx_proxy_protocol.h>
 
+#if (NGX_FULL_STATUS)
+/* 
+ * As we do not check hostname is one of defined in nginx.conf,
+ * we should not dynamicly relocate shared memory for statistics. That's
+ * why statistic is a static array.
+ */
+
+#define MAX_VIHOST_COUNT 4096
+#define MAX_VIHOST_NAME_LEN 64
+
+typedef struct {
+    u_char         server_name[MAX_VIHOST_NAME_LEN];
+    ngx_atomic_t   ngx_stat_time;    
+    ngx_atomic_t   ngx_stat_requests; 
+    ngx_atomic_t   ngx_stat_traf;
+} ngx_server_stat_t;
+
+typedef struct {
+    ngx_server_stat_t server_stat[MAX_VIHOST_COUNT];
+    size_t            server_stat_count;   
+} ngx_servers_stat_t;
 
+ngx_server_stat_t *find_stat(ngx_str_t server_name);
+#endif
 #define LF     (u_char) '\n'
 #define CR     (u_char) '\r'
 #define CRLF   "\r\n"
@@ -89,6 +112,7 @@ typedef void (*ngx_connection_handler_pt
 #define ngx_abs(value)       (((value) >= 0) ? (value) : - (value))
 #define ngx_max(val1, val2)  ((val1 < val2) ? (val2) : (val1))
 #define ngx_min(val1, val2)  ((val1 > val2) ? (val2) : (val1))
+#define min(a, b)  ( (a > b) ? b : a )
 
 void ngx_cpuinfo(void);
 
diff -rupN nginx-1.7.1/src/core/ngx_core.h.orig nginx-1.7.1-statpatch/src/core/ngx_core.h.orig
--- nginx-1.7.1/src/core/ngx_core.h.orig	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.7.1-statpatch/src/core/ngx_core.h.orig	2014-05-27 15:58:09.000000000 +0200
@@ -0,0 +1,101 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_CORE_H_INCLUDED_
+#define _NGX_CORE_H_INCLUDED_
+
+
+typedef struct ngx_module_s      ngx_module_t;
+typedef struct ngx_conf_s        ngx_conf_t;
+typedef struct ngx_cycle_s       ngx_cycle_t;
+typedef struct ngx_pool_s        ngx_pool_t;
+typedef struct ngx_chain_s       ngx_chain_t;
+typedef struct ngx_log_s         ngx_log_t;
+typedef struct ngx_open_file_s   ngx_open_file_t;
+typedef struct ngx_command_s     ngx_command_t;
+typedef struct ngx_file_s        ngx_file_t;
+typedef struct ngx_event_s       ngx_event_t;
+typedef struct ngx_event_aio_s   ngx_event_aio_t;
+typedef struct ngx_connection_s  ngx_connection_t;
+
+typedef void (*ngx_event_handler_pt)(ngx_event_t *ev);
+typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
+
+
+#define  NGX_OK          0
+#define  NGX_ERROR      -1
+#define  NGX_AGAIN      -2
+#define  NGX_BUSY       -3
+#define  NGX_DONE       -4
+#define  NGX_DECLINED   -5
+#define  NGX_ABORT      -6
+
+
+#include <ngx_errno.h>
+#include <ngx_atomic.h>
+#include <ngx_thread.h>
+#include <ngx_rbtree.h>
+#include <ngx_time.h>
+#include <ngx_socket.h>
+#include <ngx_string.h>
+#include <ngx_files.h>
+#include <ngx_shmem.h>
+#include <ngx_process.h>
+#include <ngx_user.h>
+#include <ngx_parse.h>
+#include <ngx_log.h>
+#include <ngx_alloc.h>
+#include <ngx_palloc.h>
+#include <ngx_buf.h>
+#include <ngx_queue.h>
+#include <ngx_array.h>
+#include <ngx_list.h>
+#include <ngx_hash.h>
+#include <ngx_file.h>
+#include <ngx_crc.h>
+#include <ngx_crc32.h>
+#include <ngx_murmurhash.h>
+#if (NGX_PCRE)
+#include <ngx_regex.h>
+#endif
+#include <ngx_radix_tree.h>
+#include <ngx_times.h>
+#include <ngx_shmtx.h>
+#include <ngx_slab.h>
+#include <ngx_inet.h>
+#include <ngx_cycle.h>
+#include <ngx_resolver.h>
+#if (NGX_OPENSSL)
+#include <ngx_event_openssl.h>
+#endif
+#include <ngx_process_cycle.h>
+#include <ngx_conf_file.h>
+#include <ngx_open_file_cache.h>
+#include <ngx_os.h>
+#include <ngx_connection.h>
+#include <ngx_syslog.h>
+#include <ngx_proxy_protocol.h>
+
+
+#define LF     (u_char) '\n'
+#define CR     (u_char) '\r'
+#define CRLF   "\r\n"
+
+
+#define ngx_abs(value)       (((value) >= 0) ? (value) : - (value))
+#define ngx_max(val1, val2)  ((val1 < val2) ? (val2) : (val1))
+#define ngx_min(val1, val2)  ((val1 > val2) ? (val2) : (val1))
+
+void ngx_cpuinfo(void);
+
+#if (NGX_HAVE_OPENAT)
+#define NGX_DISABLE_SYMLINKS_OFF        0
+#define NGX_DISABLE_SYMLINKS_ON         1
+#define NGX_DISABLE_SYMLINKS_NOTOWNER   2
+#endif
+
+#endif /* _NGX_CORE_H_INCLUDED_ */
diff -rupN nginx-1.7.1/src/core/ngx_core.h.rej nginx-1.7.1-statpatch/src/core/ngx_core.h.rej
--- nginx-1.7.1/src/core/ngx_core.h.rej	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.7.1-statpatch/src/core/ngx_core.h.rej	2014-06-16 17:59:46.131123100 +0200
@@ -0,0 +1,11 @@
+--- src/core/ngx_core.h	2008-09-05 19:43:34.000000000 +0400
++++ src/core/ngx_core.h	2010-06-26 20:03:18.000000000 +0400
+@@ -107,7 +131,7 @@
+ 
+ 
+ #define ngx_abs(value)   (((value) >= 0) ? (value) : - (value))
+-
++#define min(a, b)  ( (a > b) ? b : a )
+ void ngx_cpuinfo(void);
+ 
+ 
diff -rupN nginx-1.7.1/src/core/ngx_core.h~ nginx-1.7.1-statpatch/src/core/ngx_core.h~
--- nginx-1.7.1/src/core/ngx_core.h~	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.7.1-statpatch/src/core/ngx_core.h~	2014-06-16 17:59:46.000000000 +0200
@@ -0,0 +1,125 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_CORE_H_INCLUDED_
+#define _NGX_CORE_H_INCLUDED_
+
+
+typedef struct ngx_module_s      ngx_module_t;
+typedef struct ngx_conf_s        ngx_conf_t;
+typedef struct ngx_cycle_s       ngx_cycle_t;
+typedef struct ngx_pool_s        ngx_pool_t;
+typedef struct ngx_chain_s       ngx_chain_t;
+typedef struct ngx_log_s         ngx_log_t;
+typedef struct ngx_open_file_s   ngx_open_file_t;
+typedef struct ngx_command_s     ngx_command_t;
+typedef struct ngx_file_s        ngx_file_t;
+typedef struct ngx_event_s       ngx_event_t;
+typedef struct ngx_event_aio_s   ngx_event_aio_t;
+typedef struct ngx_connection_s  ngx_connection_t;
+
+typedef void (*ngx_event_handler_pt)(ngx_event_t *ev);
+typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
+
+
+#define  NGX_OK          0
+#define  NGX_ERROR      -1
+#define  NGX_AGAIN      -2
+#define  NGX_BUSY       -3
+#define  NGX_DONE       -4
+#define  NGX_DECLINED   -5
+#define  NGX_ABORT      -6
+
+
+#include <ngx_errno.h>
+#include <ngx_atomic.h>
+#include <ngx_thread.h>
+#include <ngx_rbtree.h>
+#include <ngx_time.h>
+#include <ngx_socket.h>
+#include <ngx_string.h>
+#include <ngx_files.h>
+#include <ngx_shmem.h>
+#include <ngx_process.h>
+#include <ngx_user.h>
+#include <ngx_parse.h>
+#include <ngx_log.h>
+#include <ngx_alloc.h>
+#include <ngx_palloc.h>
+#include <ngx_buf.h>
+#include <ngx_queue.h>
+#include <ngx_array.h>
+#include <ngx_list.h>
+#include <ngx_hash.h>
+#include <ngx_file.h>
+#include <ngx_crc.h>
+#include <ngx_crc32.h>
+#include <ngx_murmurhash.h>
+#if (NGX_PCRE)
+#include <ngx_regex.h>
+#endif
+#include <ngx_radix_tree.h>
+#include <ngx_times.h>
+#include <ngx_shmtx.h>
+#include <ngx_slab.h>
+#include <ngx_inet.h>
+#include <ngx_cycle.h>
+#include <ngx_resolver.h>
+#if (NGX_OPENSSL)
+#include <ngx_event_openssl.h>
+#endif
+#include <ngx_process_cycle.h>
+#include <ngx_conf_file.h>
+#include <ngx_open_file_cache.h>
+#include <ngx_os.h>
+#include <ngx_connection.h>
+#include <ngx_syslog.h>
+#include <ngx_proxy_protocol.h>
+
+#if (NGX_FULL_STATUS)
+/* 
+ * As we do not check hostname is one of defined in nginx.conf,
+ * we should not dynamicly relocate shared memory for statistics. That's
+ * why statistic is a static array.
+ */
+
+#define MAX_VIHOST_COUNT 4096
+#define MAX_VIHOST_NAME_LEN 64
+
+typedef struct {
+    u_char         server_name[MAX_VIHOST_NAME_LEN];
+    ngx_atomic_t   ngx_stat_time;    
+    ngx_atomic_t   ngx_stat_requests; 
+    ngx_atomic_t   ngx_stat_traf;
+} ngx_server_stat_t;
+
+typedef struct {
+    ngx_server_stat_t server_stat[MAX_VIHOST_COUNT];
+    size_t            server_stat_count;   
+} ngx_servers_stat_t;
+
+ngx_server_stat_t *find_stat(ngx_str_t server_name);
+#endif
+
+#define LF     (u_char) '\n'
+#define CR     (u_char) '\r'
+#define CRLF   "\r\n"
+
+
+#define ngx_abs(value)       (((value) >= 0) ? (value) : - (value))
+#define ngx_max(val1, val2)  ((val1 < val2) ? (val2) : (val1))
+#define ngx_min(val1, val2)  ((val1 > val2) ? (val2) : (val1))
+
+void ngx_cpuinfo(void);
+
+#if (NGX_HAVE_OPENAT)
+#define NGX_DISABLE_SYMLINKS_OFF        0
+#define NGX_DISABLE_SYMLINKS_ON         1
+#define NGX_DISABLE_SYMLINKS_NOTOWNER   2
+#endif
+
+#endif /* _NGX_CORE_H_INCLUDED_ */
diff -rupN nginx-1.7.1/src/http/modules/ngx_http_full_status_module.c nginx-1.7.1-statpatch/src/http/modules/ngx_http_full_status_module.c
--- nginx-1.7.1/src/http/modules/ngx_http_full_status_module.c	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.7.1-statpatch/src/http/modules/ngx_http_full_status_module.c	2014-06-16 17:59:46.135123300 +0200
@@ -0,0 +1,266 @@
+/*
+ * Rebrikov Alexander, pgriffin@reg.ru
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+static ngx_int_t ngx_status_module_init(ngx_cycle_t *cycle);
+ngx_servers_stat_t *ngx_servers_stat;
+
+ngx_int_t init_stat_server(ngx_server_stat_t *new_server, ngx_str_t server_name);
+
+static char *ngx_http_set_full_status(ngx_conf_t *cf, ngx_command_t *cmd,
+                                 void *conf);
+
+static ngx_command_t  ngx_http_full_status_commands[] = {
+
+    { ngx_string("full_status"),
+      NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_http_set_full_status,
+      0,
+      0,
+      NULL },
+
+      ngx_null_command
+};
+
+
+
+static ngx_http_module_t  ngx_http_full_status_module_ctx = {
+    NULL,                                  /* preconfiguration */
+    NULL,                                  /* postconfiguration */
+
+    NULL,                                  /* create main configuration */
+    NULL,                                  /* init main configuration */
+
+    NULL,                                  /* create server configuration */
+    NULL,                                  /* merge server configuration */
+
+    NULL,                                  /* create location configuration */
+    NULL                                   /* merge location configuration */
+};
+
+
+ngx_module_t  ngx_http_full_status_module = {
+    NGX_MODULE_V1,
+    &ngx_http_full_status_module_ctx,      /* module context */
+    ngx_http_full_status_commands,              /* module directives */
+    NGX_HTTP_MODULE,                       /* module type */
+    NULL,                                  /* init master */
+    ngx_status_module_init,                /* init module */
+    NULL,                                  /* init process */
+    NULL,                                  /* init thread */
+    NULL,                                  /* exit thread */
+    NULL,                                  /* exit process */
+    NULL,                                  /* exit master */
+    NGX_MODULE_V1_PADDING
+};
+
+static ngx_int_t
+ngx_status_module_init(ngx_cycle_t *cycle) {
+    u_char              *shared;
+    size_t               cl;
+    ngx_shm_t            shm;
+    
+    size_t server_stat_size = sizeof( ngx_servers_stat_t );
+    cl = 128;
+    int div = server_stat_size / cl;
+    int mod = server_stat_size % cl;
+    server_stat_size = (div + (mod ? 1 : 0)) * cl;
+
+    shm.size = server_stat_size;
+    shm.name.len = sizeof("nginx_stat_shared_zone");
+    shm.name.data = (u_char *) "nginx_stat_shared_zone";
+    shm.log = cycle->log;
+
+    if (ngx_shm_alloc(&shm) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    shared = shm.addr;
+
+    ngx_servers_stat = (ngx_servers_stat_t *) shared;
+    ngx_servers_stat->server_stat_count = 0;
+    return NGX_OK;
+}
+
+ngx_int_t compare_servers( const void *s1, const void *s2 ) {
+    return ngx_strcmp( 
+	((ngx_server_stat_t *) s1)->server_name, 
+	((ngx_server_stat_t *) s2)->server_name 
+    );
+}
+
+static ngx_int_t ngx_http_full_status_handler(ngx_http_request_t *r)
+{
+    size_t             size;
+    ngx_int_t          rc;
+    ngx_buf_t         *b;
+    ngx_chain_t        out;
+    ngx_atomic_int_t   rq, at;
+
+    if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
+        return NGX_HTTP_NOT_ALLOWED;
+    }
+
+    rc = ngx_http_discard_request_body(r);
+
+    if (rc != NGX_OK) {
+        return rc;
+    }
+
+    r->headers_out.content_type.len = sizeof("text/plain") - 1;
+    r->headers_out.content_type.data = (u_char *) "text/plain";
+
+    if (r->method == NGX_HTTP_HEAD) {
+        r->headers_out.status = NGX_HTTP_OK;
+
+        rc = ngx_http_send_header(r);
+
+        if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
+            return rc;
+        }
+    }
+    
+    size_t server_count = ngx_servers_stat->server_stat_count;
+    size = sizeof("vihost\t\t\t\trequests\t\tactive_time(msec) \t\ttraf\n") + // ýòî íà çàãîëîâîê
+           3 * 11  * server_count +                                        // ýòî íà ÷èñëîâûå õàðàêòåðèñòèêè
+           (sizeof("  \n")) * 20 * server_count;                           // ýòî íà ïðîáåëû  
+                                                            
+    size_t i;
+    ngx_server_stat_t *tmp = (ngx_server_stat_t *) 
+	malloc( server_count * sizeof( ngx_server_stat_t ) );
+    for ( i = 0; i < server_count; i++ ) {
+	tmp[i] = ngx_servers_stat->server_stat[i];
+    }
+    
+    ngx_sort( 
+	(void *)tmp,
+	server_count,
+	sizeof( ngx_server_stat_t ),
+	compare_servers
+    );
+    
+    for (i = 0; i < server_count; i++) {
+        ngx_server_stat_t *stat_server = tmp + i;
+        size += strlen((char *)stat_server->server_name) + 1;
+    }
+     
+    b = ngx_create_temp_buf(r->pool, size);
+    if (b == NULL) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    out.buf = b;
+    out.next = NULL;
+    
+    b->last = ngx_cpymem(b->last, 
+	"vihost\t\t\t\trequests\t\tactive_time(msec)\t\ttraf\n", 
+        sizeof("vihost\t\t\t\trequests\t\tactive_time(msec)\t\ttraf\n") - 1);
+    for (i = 0; i < server_count; i++) {
+        ngx_server_stat_t * server = tmp + i;
+        rq = server->ngx_stat_requests;
+        at = server->ngx_stat_time;
+
+        b->last = ngx_cpymem(b->last, server->server_name, strlen((char *)server->server_name));
+        b->last = ngx_sprintf(b->last, "\t\t\t%uA\t\t\t%uA\t\t\t\t%uA\n",  rq, at,
+	    server->ngx_stat_traf);
+    }
+    
+    free( (void *) tmp );
+    
+    b->last = ngx_sprintf(b->last, "\0");
+    r->headers_out.status = NGX_HTTP_OK;
+    r->headers_out.content_length_n = b->last - b->pos;
+
+    b->last_buf = 1;
+
+    rc = ngx_http_send_header(r);
+
+    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
+        return rc;
+    }
+
+    return ngx_http_output_filter(r, &out);
+}
+
+
+static char *ngx_http_set_full_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+    ngx_http_core_loc_conf_t  *clcf;
+
+    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
+    clcf->handler = ngx_http_full_status_handler;
+
+    return NGX_CONF_OK;
+}
+
+ngx_str_t to_lower_and_cleanup_www(ngx_str_t server_name) {
+    unsigned i = 0;
+    ngx_str_t s;
+    ngx_str_t www = ngx_string( "www." );
+            
+    s.len = server_name.len;
+    s.data = (u_char *) malloc( server_name.len + 1 );
+    ngx_strlow( s.data, server_name.data, s.len );
+    
+    if ( !ngx_strncmp( www.data, s.data, 4 ) ) {
+	u_char *to_lower = s.data;
+	
+	s.data = (u_char *) malloc( server_name.len - 3 );
+	for ( i = 4; i <= s.len; i++ ) {
+	    s.data[i - 4] = to_lower[i];
+	} 
+	s.len -= 4;
+	s.data[s.len] = '\0';
+	free( (void *)to_lower );
+    }
+    
+    return s;
+}
+
+ngx_server_stat_t *find_stat(ngx_str_t cname) {
+    size_t i;
+    
+    ngx_str_t server_name = to_lower_and_cleanup_www( cname );
+    for (i = 0; i < ngx_servers_stat->server_stat_count; i++) {
+        ngx_server_stat_t *stat_server = &(ngx_servers_stat->server_stat[i]);
+                                   
+        if (
+	    strlen( (char *) stat_server->server_name ) == server_name.len &&
+	    !ngx_strncmp(stat_server->server_name, server_name.data, server_name.len)
+	) {
+	    free( (void *) server_name.data );
+	    return stat_server;
+	}
+    }
+
+    if ( ngx_servers_stat->server_stat_count == MAX_VIHOST_COUNT ) {
+	free( (void *) server_name.data );
+	return NULL;
+    }
+    
+    ngx_server_stat_t *new_server = 
+	&(ngx_servers_stat->server_stat[ngx_servers_stat->server_stat_count]);
+    ngx_servers_stat->server_stat_count++;
+    
+    if ( init_stat_server(new_server, server_name) == NGX_OK ) {
+	free( (void *) server_name.data );
+        return new_server;
+    }
+    else {
+	free( (void *) server_name.data );
+        return NULL;
+    }
+}
+
+ngx_int_t init_stat_server(ngx_server_stat_t *new_server, ngx_str_t server_name) {
+    ngx_cpystrn(new_server->server_name, server_name.data, min(server_name.len + 1, MAX_VIHOST_NAME_LEN));
+    new_server->ngx_stat_time = 0;
+    new_server->ngx_stat_requests = 0;
+    new_server->ngx_stat_traf = 0;
+    return NGX_OK;
+}
diff -rupN nginx-1.7.1/src/http/ngx_http.c nginx-1.7.1-statpatch/src/http/ngx_http.c
--- nginx-1.7.1/src/http/ngx_http.c	2014-05-27 15:58:10.000000000 +0200
+++ nginx-1.7.1-statpatch/src/http/ngx_http.c	2014-06-16 17:59:46.137123400 +0200
@@ -9,7 +9,6 @@
 #include <ngx_core.h>
 #include <ngx_http.h>
 
-
 static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 static ngx_int_t ngx_http_init_phases(ngx_conf_t *cf,
     ngx_http_core_main_conf_t *cmcf);
@@ -98,7 +97,6 @@ static ngx_core_module_t  ngx_http_modul
     NULL
 };
 
-
 ngx_module_t  ngx_http_module = {
     NGX_MODULE_V1,
     &ngx_http_module_ctx,                  /* module context */
@@ -114,7 +112,6 @@ ngx_module_t  ngx_http_module = {
     NGX_MODULE_V1_PADDING
 };
 
-
 static char *
 ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
@@ -126,7 +123,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma
     ngx_http_core_loc_conf_t    *clcf;
     ngx_http_core_srv_conf_t   **cscfp;
     ngx_http_core_main_conf_t   *cmcf;
-
+    
     /* the main http context */
 
     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
diff -rupN nginx-1.7.1/src/http/ngx_http.c.orig nginx-1.7.1-statpatch/src/http/ngx_http.c.orig
--- nginx-1.7.1/src/http/ngx_http.c.orig	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.7.1-statpatch/src/http/ngx_http.c.orig	2014-05-27 15:58:10.000000000 +0200
@@ -0,0 +1,2118 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+static ngx_int_t ngx_http_init_phases(ngx_conf_t *cf,
+    ngx_http_core_main_conf_t *cmcf);
+static ngx_int_t ngx_http_init_headers_in_hash(ngx_conf_t *cf,
+    ngx_http_core_main_conf_t *cmcf);
+static ngx_int_t ngx_http_init_phase_handlers(ngx_conf_t *cf,
+    ngx_http_core_main_conf_t *cmcf);
+
+static ngx_int_t ngx_http_add_addresses(ngx_conf_t *cf,
+    ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port,
+    ngx_http_listen_opt_t *lsopt);
+static ngx_int_t ngx_http_add_address(ngx_conf_t *cf,
+    ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port,
+    ngx_http_listen_opt_t *lsopt);
+static ngx_int_t ngx_http_add_server(ngx_conf_t *cf,
+    ngx_http_core_srv_conf_t *cscf, ngx_http_conf_addr_t *addr);
+
+static char *ngx_http_merge_servers(ngx_conf_t *cf,
+    ngx_http_core_main_conf_t *cmcf, ngx_http_module_t *module,
+    ngx_uint_t ctx_index);
+static char *ngx_http_merge_locations(ngx_conf_t *cf,
+    ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module,
+    ngx_uint_t ctx_index);
+static ngx_int_t ngx_http_init_locations(ngx_conf_t *cf,
+    ngx_http_core_srv_conf_t *cscf, ngx_http_core_loc_conf_t *pclcf);
+static ngx_int_t ngx_http_init_static_location_trees(ngx_conf_t *cf,
+    ngx_http_core_loc_conf_t *pclcf);
+static ngx_int_t ngx_http_cmp_locations(const ngx_queue_t *one,
+    const ngx_queue_t *two);
+static ngx_int_t ngx_http_join_exact_locations(ngx_conf_t *cf,
+    ngx_queue_t *locations);
+static void ngx_http_create_locations_list(ngx_queue_t *locations,
+    ngx_queue_t *q);
+static ngx_http_location_tree_node_t *
+    ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations,
+    size_t prefix);
+
+static ngx_int_t ngx_http_optimize_servers(ngx_conf_t *cf,
+    ngx_http_core_main_conf_t *cmcf, ngx_array_t *ports);
+static ngx_int_t ngx_http_server_names(ngx_conf_t *cf,
+    ngx_http_core_main_conf_t *cmcf, ngx_http_conf_addr_t *addr);
+static ngx_int_t ngx_http_cmp_conf_addrs(const void *one, const void *two);
+static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one,
+    const void *two);
+
+static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf,
+    ngx_http_conf_port_t *port);
+static ngx_listening_t *ngx_http_add_listening(ngx_conf_t *cf,
+    ngx_http_conf_addr_t *addr);
+static ngx_int_t ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
+    ngx_http_conf_addr_t *addr);
+#if (NGX_HAVE_INET6)
+static ngx_int_t ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
+    ngx_http_conf_addr_t *addr);
+#endif
+
+ngx_uint_t   ngx_http_max_module;
+
+
+ngx_int_t  (*ngx_http_top_header_filter) (ngx_http_request_t *r);
+ngx_int_t  (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
+
+
+ngx_str_t  ngx_http_html_default_types[] = {
+    ngx_string("text/html"),
+    ngx_null_string
+};
+
+
+static ngx_command_t  ngx_http_commands[] = {
+
+    { ngx_string("http"),
+      NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
+      ngx_http_block,
+      0,
+      0,
+      NULL },
+
+      ngx_null_command
+};
+
+
+static ngx_core_module_t  ngx_http_module_ctx = {
+    ngx_string("http"),
+    NULL,
+    NULL
+};
+
+
+ngx_module_t  ngx_http_module = {
+    NGX_MODULE_V1,
+    &ngx_http_module_ctx,                  /* module context */
+    ngx_http_commands,                     /* module directives */
+    NGX_CORE_MODULE,                       /* module type */
+    NULL,                                  /* init master */
+    NULL,                                  /* init module */
+    NULL,                                  /* init process */
+    NULL,                                  /* init thread */
+    NULL,                                  /* exit thread */
+    NULL,                                  /* exit process */
+    NULL,                                  /* exit master */
+    NGX_MODULE_V1_PADDING
+};
+
+
+static char *
+ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+    char                        *rv;
+    ngx_uint_t                   mi, m, s;
+    ngx_conf_t                   pcf;
+    ngx_http_module_t           *module;
+    ngx_http_conf_ctx_t         *ctx;
+    ngx_http_core_loc_conf_t    *clcf;
+    ngx_http_core_srv_conf_t   **cscfp;
+    ngx_http_core_main_conf_t   *cmcf;
+
+    /* the main http context */
+
+    ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
+    if (ctx == NULL) {
+        return NGX_CONF_ERROR;
+    }
+
+    *(ngx_http_conf_ctx_t **) conf = ctx;
+
+
+    /* count the number of the http modules and set up their indices */
+
+    ngx_http_max_module = 0;
+    for (m = 0; ngx_modules[m]; m++) {
+        if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
+            continue;
+        }
+
+        ngx_modules[m]->ctx_index = ngx_http_max_module++;
+    }
+
+
+    /* the http main_conf context, it is the same in the all http contexts */
+
+    ctx->main_conf = ngx_pcalloc(cf->pool,
+                                 sizeof(void *) * ngx_http_max_module);
+    if (ctx->main_conf == NULL) {
+        return NGX_CONF_ERROR;
+    }
+
+
+    /*
+     * the http null srv_conf context, it is used to merge
+     * the server{}s' srv_conf's
+     */
+
+    ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
+    if (ctx->srv_conf == NULL) {
+        return NGX_CONF_ERROR;
+    }
+
+
+    /*
+     * the http null loc_conf context, it is used to merge
+     * the server{}s' loc_conf's
+     */
+
+    ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
+    if (ctx->loc_conf == NULL) {
+        return NGX_CONF_ERROR;
+    }
+
+
+    /*
+     * create the main_conf's, the null srv_conf's, and the null loc_conf's
+     * of the all http modules
+     */
+
+    for (m = 0; ngx_modules[m]; m++) {
+        if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
+            continue;
+        }
+
+        module = ngx_modules[m]->ctx;
+        mi = ngx_modules[m]->ctx_index;
+
+        if (module->create_main_conf) {
+            ctx->main_conf[mi] = module->create_main_conf(cf);
+            if (ctx->main_conf[mi] == NULL) {
+                return NGX_CONF_ERROR;
+            }
+        }
+
+        if (module->create_srv_conf) {
+            ctx->srv_conf[mi] = module->create_srv_conf(cf);
+            if (ctx->srv_conf[mi] == NULL) {
+                return NGX_CONF_ERROR;
+            }
+        }
+
+        if (module->create_loc_conf) {
+            ctx->loc_conf[mi] = module->create_loc_conf(cf);
+            if (ctx->loc_conf[mi] == NULL) {
+                return NGX_CONF_ERROR;
+            }
+        }
+    }
+
+    pcf = *cf;
+    cf->ctx = ctx;
+
+    for (m = 0; ngx_modules[m]; m++) {
+        if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
+            continue;
+        }
+
+        module = ngx_modules[m]->ctx;
+
+        if (module->preconfiguration) {
+            if (module->preconfiguration(cf) != NGX_OK) {
+                return NGX_CONF_ERROR;
+            }
+        }
+    }
+
+    /* parse inside the http{} block */
+
+    cf->module_type = NGX_HTTP_MODULE;
+    cf->cmd_type = NGX_HTTP_MAIN_CONF;
+    rv = ngx_conf_parse(cf, NULL);
+
+    if (rv != NGX_CONF_OK) {
+        goto failed;
+    }
+
+    /*
+     * init http{} main_conf's, merge the server{}s' srv_conf's
+     * and its location{}s' loc_conf's
+     */
+
+    cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
+    cscfp = cmcf->servers.elts;
+
+    for (m = 0; ngx_modules[m]; m++) {
+        if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
+            continue;
+        }
+
+        module = ngx_modules[m]->ctx;
+        mi = ngx_modules[m]->ctx_index;
+
+        /* init http{} main_conf's */
+
+        if (module->init_main_conf) {
+            rv = module->init_main_conf(cf, ctx->main_conf[mi]);
+            if (rv != NGX_CONF_OK) {
+                goto failed;
+            }
+        }
+
+        rv = ngx_http_merge_servers(cf, cmcf, module, mi);
+        if (rv != NGX_CONF_OK) {
+            goto failed;
+        }
+    }
+
+
+    /* create location trees */
+
+    for (s = 0; s < cmcf->servers.nelts; s++) {
+
+        clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
+
+        if (ngx_http_init_locations(cf, cscfp[s], clcf) != NGX_OK) {
+            return NGX_CONF_ERROR;
+        }
+
+        if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {
+            return NGX_CONF_ERROR;
+        }
+    }
+
+
+    if (ngx_http_init_phases(cf, cmcf) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
+    if (ngx_http_init_headers_in_hash(cf, cmcf) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
+
+    for (m = 0; ngx_modules[m]; m++) {
+        if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
+            continue;
+        }
+
+        module = ngx_modules[m]->ctx;
+
+        if (module->postconfiguration) {
+            if (module->postconfiguration(cf) != NGX_OK) {
+                return NGX_CONF_ERROR;
+            }
+        }
+    }
+
+    if (ngx_http_variables_init_vars(cf) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
+    /*
+     * http{}'s cf->ctx was needed while the configuration merging
+     * and in postconfiguration process
+     */
+
+    *cf = pcf;
+
+
+    if (ngx_http_init_phase_handlers(cf, cmcf) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
+
+    /* optimize the lists of ports, addresses and server names */
+
+    if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
+    return NGX_CONF_OK;
+
+failed:
+
+    *cf = pcf;
+
+    return rv;
+}
+
+
+static ngx_int_t
+ngx_http_init_phases(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
+{
+    if (ngx_array_init(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers,
+                       cf->pool, 1, sizeof(ngx_http_handler_pt))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
+    if (ngx_array_init(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers,
+                       cf->pool, 1, sizeof(ngx_http_handler_pt))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
+    if (ngx_array_init(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers,
+                       cf->pool, 1, sizeof(ngx_http_handler_pt))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
+    if (ngx_array_init(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers,
+                       cf->pool, 1, sizeof(ngx_http_handler_pt))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
+    if (ngx_array_init(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers,
+                       cf->pool, 2, sizeof(ngx_http_handler_pt))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
+    if (ngx_array_init(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers,
+                       cf->pool, 4, sizeof(ngx_http_handler_pt))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
+    if (ngx_array_init(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers,
+                       cf->pool, 1, sizeof(ngx_http_handler_pt))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_init_headers_in_hash(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
+{
+    ngx_array_t         headers_in;
+    ngx_hash_key_t     *hk;
+    ngx_hash_init_t     hash;
+    ngx_http_header_t  *header;
+
+    if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
+    for (header = ngx_http_headers_in; header->name.len; header++) {
+        hk = ngx_array_push(&headers_in);
+        if (hk == NULL) {
+            return NGX_ERROR;
+        }
+
+        hk->key = header->name;
+        hk->key_hash = ngx_hash_key_lc(header->name.data, header->name.len);
+        hk->value = header;
+    }
+
+    hash.hash = &cmcf->headers_in_hash;
+    hash.key = ngx_hash_key_lc;
+    hash.max_size = 512;
+    hash.bucket_size = ngx_align(64, ngx_cacheline_size);
+    hash.name = "headers_in_hash";
+    hash.pool = cf->pool;
+    hash.temp_pool = NULL;
+
+    if (ngx_hash_init(&hash, headers_in.elts, headers_in.nelts) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_init_phase_handlers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
+{
+    ngx_int_t                   j;
+    ngx_uint_t                  i, n;
+    ngx_uint_t                  find_config_index, use_rewrite, use_access;
+    ngx_http_handler_pt        *h;
+    ngx_http_phase_handler_t   *ph;
+    ngx_http_phase_handler_pt   checker;
+
+    cmcf->phase_engine.server_rewrite_index = (ngx_uint_t) -1;
+    cmcf->phase_engine.location_rewrite_index = (ngx_uint_t) -1;
+    find_config_index = 0;
+    use_rewrite = cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers.nelts ? 1 : 0;
+    use_access = cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.nelts ? 1 : 0;
+
+    n = use_rewrite + use_access + cmcf->try_files + 1 /* find config phase */;
+
+    for (i = 0; i < NGX_HTTP_LOG_PHASE; i++) {
+        n += cmcf->phases[i].handlers.nelts;
+    }
+
+    ph = ngx_pcalloc(cf->pool,
+                     n * sizeof(ngx_http_phase_handler_t) + sizeof(void *));
+    if (ph == NULL) {
+        return NGX_ERROR;
+    }
+
+    cmcf->phase_engine.handlers = ph;
+    n = 0;
+
+    for (i = 0; i < NGX_HTTP_LOG_PHASE; i++) {
+        h = cmcf->phases[i].handlers.elts;
+
+        switch (i) {
+
+        case NGX_HTTP_SERVER_REWRITE_PHASE:
+            if (cmcf->phase_engine.server_rewrite_index == (ngx_uint_t) -1) {
+                cmcf->phase_engine.server_rewrite_index = n;
+            }
+            checker = ngx_http_core_rewrite_phase;
+
+            break;
+
+        case NGX_HTTP_FIND_CONFIG_PHASE:
+            find_config_index = n;
+
+            ph->checker = ngx_http_core_find_config_phase;
+            n++;
+            ph++;
+
+            continue;
+
+        case NGX_HTTP_REWRITE_PHASE:
+            if (cmcf->phase_engine.location_rewrite_index == (ngx_uint_t) -1) {
+                cmcf->phase_engine.location_rewrite_index = n;
+            }
+            checker = ngx_http_core_rewrite_phase;
+
+            break;
+
+        case NGX_HTTP_POST_REWRITE_PHASE:
+            if (use_rewrite) {
+                ph->checker = ngx_http_core_post_rewrite_phase;
+                ph->next = find_config_index;
+                n++;
+                ph++;
+            }
+
+            continue;
+
+        case NGX_HTTP_ACCESS_PHASE:
+            checker = ngx_http_core_access_phase;
+            n++;
+            break;
+
+        case NGX_HTTP_POST_ACCESS_PHASE:
+            if (use_access) {
+                ph->checker = ngx_http_core_post_access_phase;
+                ph->next = n;
+                ph++;
+            }
+
+            continue;
+
+        case NGX_HTTP_TRY_FILES_PHASE:
+            if (cmcf->try_files) {
+                ph->checker = ngx_http_core_try_files_phase;
+                n++;
+                ph++;
+            }
+
+            continue;
+
+        case NGX_HTTP_CONTENT_PHASE:
+            checker = ngx_http_core_content_phase;
+            break;
+
+        default:
+            checker = ngx_http_core_generic_phase;
+        }
+
+        n += cmcf->phases[i].handlers.nelts;
+
+        for (j = cmcf->phases[i].handlers.nelts - 1; j >=0; j--) {
+            ph->checker = checker;
+            ph->handler = h[j];
+            ph->next = n;
+            ph++;
+        }
+    }
+
+    return NGX_OK;
+}
+
+
+static char *
+ngx_http_merge_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
+    ngx_http_module_t *module, ngx_uint_t ctx_index)
+{
+    char                        *rv;
+    ngx_uint_t                   s;
+    ngx_http_conf_ctx_t         *ctx, saved;
+    ngx_http_core_loc_conf_t    *clcf;
+    ngx_http_core_srv_conf_t   **cscfp;
+
+    cscfp = cmcf->servers.elts;
+    ctx = (ngx_http_conf_ctx_t *) cf->ctx;
+    saved = *ctx;
+    rv = NGX_CONF_OK;
+
+    for (s = 0; s < cmcf->servers.nelts; s++) {
+
+        /* merge the server{}s' srv_conf's */
+
+        ctx->srv_conf = cscfp[s]->ctx->srv_conf;
+
+        if (module->merge_srv_conf) {
+            rv = module->merge_srv_conf(cf, saved.srv_conf[ctx_index],
+                                        cscfp[s]->ctx->srv_conf[ctx_index]);
+            if (rv != NGX_CONF_OK) {
+                goto failed;
+            }
+        }
+
+        if (module->merge_loc_conf) {
+
+            /* merge the server{}'s loc_conf */
+
+            ctx->loc_conf = cscfp[s]->ctx->loc_conf;
+
+            rv = module->merge_loc_conf(cf, saved.loc_conf[ctx_index],
+                                        cscfp[s]->ctx->loc_conf[ctx_index]);
+            if (rv != NGX_CONF_OK) {
+                goto failed;
+            }
+
+            /* merge the locations{}' loc_conf's */
+
+            clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
+
+            rv = ngx_http_merge_locations(cf, clcf->locations,
+                                          cscfp[s]->ctx->loc_conf,
+                                          module, ctx_index);
+            if (rv != NGX_CONF_OK) {
+                goto failed;
+            }
+        }
+    }
+
+failed:
+
+    *ctx = saved;
+
+    return rv;
+}
+
+
+static char *
+ngx_http_merge_locations(ngx_conf_t *cf, ngx_queue_t *locations,
+    void **loc_conf, ngx_http_module_t *module, ngx_uint_t ctx_index)
+{
+    char                       *rv;
+    ngx_queue_t                *q;
+    ngx_http_conf_ctx_t        *ctx, saved;
+    ngx_http_core_loc_conf_t   *clcf;
+    ngx_http_location_queue_t  *lq;
+
+    if (locations == NULL) {
+        return NGX_CONF_OK;
+    }
+
+    ctx = (ngx_http_conf_ctx_t *) cf->ctx;
+    saved = *ctx;
+
+    for (q = ngx_queue_head(locations);
+         q != ngx_queue_sentinel(locations);
+         q = ngx_queue_next(q))
+    {
+        lq = (ngx_http_location_queue_t *) q;
+
+        clcf = lq->exact ? lq->exact : lq->inclusive;
+        ctx->loc_conf = clcf->loc_conf;
+
+        rv = module->merge_loc_conf(cf, loc_conf[ctx_index],
+                                    clcf->loc_conf[ctx_index]);
+        if (rv != NGX_CONF_OK) {
+            return rv;
+        }
+
+        rv = ngx_http_merge_locations(cf, clcf->locations, clcf->loc_conf,
+                                      module, ctx_index);
+        if (rv != NGX_CONF_OK) {
+            return rv;
+        }
+    }
+
+    *ctx = saved;
+
+    return NGX_CONF_OK;
+}
+
+
+static ngx_int_t
+ngx_http_init_locations(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
+    ngx_http_core_loc_conf_t *pclcf)
+{
+    ngx_uint_t                   n;
+    ngx_queue_t                 *q, *locations, *named, tail;
+    ngx_http_core_loc_conf_t    *clcf;
+    ngx_http_location_queue_t   *lq;
+    ngx_http_core_loc_conf_t   **clcfp;
+#if (NGX_PCRE)
+    ngx_uint_t                   r;
+    ngx_queue_t                 *regex;
+#endif
+
+    locations = pclcf->locations;
+
+    if (locations == NULL) {
+        return NGX_OK;
+    }
+
+    ngx_queue_sort(locations, ngx_http_cmp_locations);
+
+    named = NULL;
+    n = 0;
+#if (NGX_PCRE)
+    regex = NULL;
+    r = 0;
+#endif
+
+    for (q = ngx_queue_head(locations);
+         q != ngx_queue_sentinel(locations);
+         q = ngx_queue_next(q))
+    {
+        lq = (ngx_http_location_queue_t *) q;
+
+        clcf = lq->exact ? lq->exact : lq->inclusive;
+
+        if (ngx_http_init_locations(cf, NULL, clcf) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
+#if (NGX_PCRE)
+
+        if (clcf->regex) {
+            r++;
+
+            if (regex == NULL) {
+                regex = q;
+            }
+
+            continue;
+        }
+
+#endif
+
+        if (clcf->named) {
+            n++;
+
+            if (named == NULL) {
+                named = q;
+            }
+
+            continue;
+        }
+
+        if (clcf->noname) {
+            break;
+        }
+    }
+
+    if (q != ngx_queue_sentinel(locations)) {
+        ngx_queue_split(locations, q, &tail);
+    }
+
+    if (named) {
+        clcfp = ngx_palloc(cf->pool,
+                           (n + 1) * sizeof(ngx_http_core_loc_conf_t **));
+        if (clcfp == NULL) {
+            return NGX_ERROR;
+        }
+
+        cscf->named_locations = clcfp;
+
+        for (q = named;
+             q != ngx_queue_sentinel(locations);
+             q = ngx_queue_next(q))
+        {
+            lq = (ngx_http_location_queue_t *) q;
+
+            *(clcfp++) = lq->exact;
+        }
+
+        *clcfp = NULL;
+
+        ngx_queue_split(locations, named, &tail);
+    }
+
+#if (NGX_PCRE)
+
+    if (regex) {
+
+        clcfp = ngx_palloc(cf->pool,
+                           (r + 1) * sizeof(ngx_http_core_loc_conf_t **));
+        if (clcfp == NULL) {
+            return NGX_ERROR;
+        }
+
+        pclcf->regex_locations = clcfp;
+
+        for (q = regex;
+             q != ngx_queue_sentinel(locations);
+             q = ngx_queue_next(q))
+        {
+            lq = (ngx_http_location_queue_t *) q;
+
+            *(clcfp++) = lq->exact;
+        }
+
+        *clcfp = NULL;
+
+        ngx_queue_split(locations, regex, &tail);
+    }
+
+#endif
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_init_static_location_trees(ngx_conf_t *cf,
+    ngx_http_core_loc_conf_t *pclcf)
+{
+    ngx_queue_t                *q, *locations;
+    ngx_http_core_loc_conf_t   *clcf;
+    ngx_http_location_queue_t  *lq;
+
+    locations = pclcf->locations;
+
+    if (locations == NULL) {
+        return NGX_OK;
+    }
+
+    if (ngx_queue_empty(locations)) {
+        return NGX_OK;
+    }
+
+    for (q = ngx_queue_head(locations);
+         q != ngx_queue_sentinel(locations);
+         q = ngx_queue_next(q))
+    {
+        lq = (ngx_http_location_queue_t *) q;
+
+        clcf = lq->exact ? lq->exact : lq->inclusive;
+
+        if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {
+            return NGX_ERROR;
+        }
+    }
+
+    if (ngx_http_join_exact_locations(cf, locations) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    ngx_http_create_locations_list(locations, ngx_queue_head(locations));
+
+    pclcf->static_locations = ngx_http_create_locations_tree(cf, locations, 0);
+    if (pclcf->static_locations == NULL) {
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
+    ngx_http_core_loc_conf_t *clcf)
+{
+    ngx_http_location_queue_t  *lq;
+
+    if (*locations == NULL) {
+        *locations = ngx_palloc(cf->temp_pool,
+                                sizeof(ngx_http_location_queue_t));
+        if (*locations == NULL) {
+            return NGX_ERROR;
+        }
+
+        ngx_queue_init(*locations);
+    }
+
+    lq = ngx_palloc(cf->temp_pool, sizeof(ngx_http_location_queue_t));
+    if (lq == NULL) {
+        return NGX_ERROR;
+    }
+
+    if (clcf->exact_match
+#if (NGX_PCRE)
+        || clcf->regex
+#endif
+        || clcf->named || clcf->noname)
+    {
+        lq->exact = clcf;
+        lq->inclusive = NULL;
+
+    } else {
+        lq->exact = NULL;
+        lq->inclusive = clcf;
+    }
+
+    lq->name = &clcf->name;
+    lq->file_name = cf->conf_file->file.name.data;
+    lq->line = cf->conf_file->line;
+
+    ngx_queue_init(&lq->list);
+
+    ngx_queue_insert_tail(*locations, &lq->queue);
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_cmp_locations(const ngx_queue_t *one, const ngx_queue_t *two)
+{
+    ngx_int_t                   rc;
+    ngx_http_core_loc_conf_t   *first, *second;
+    ngx_http_location_queue_t  *lq1, *lq2;
+
+    lq1 = (ngx_http_location_queue_t *) one;
+    lq2 = (ngx_http_location_queue_t *) two;
+
+    first = lq1->exact ? lq1->exact : lq1->inclusive;
+    second = lq2->exact ? lq2->exact : lq2->inclusive;
+
+    if (first->noname && !second->noname) {
+        /* shift no named locations to the end */
+        return 1;
+    }
+
+    if (!first->noname && second->noname) {
+        /* shift no named locations to the end */
+        return -1;
+    }
+
+    if (first->noname || second->noname) {
+        /* do not sort no named locations */
+        return 0;
+    }
+
+    if (first->named && !second->named) {
+        /* shift named locations to the end */
+        return 1;
+    }
+
+    if (!first->named && second->named) {
+        /* shift named locations to the end */
+        return -1;
+    }
+
+    if (first->named && second->named) {
+        return ngx_strcmp(first->name.data, second->name.data);
+    }
+
+#if (NGX_PCRE)
+
+    if (first->regex && !second->regex) {
+        /* shift the regex matches to the end */
+        return 1;
+    }
+
+    if (!first->regex && second->regex) {
+        /* shift the regex matches to the end */
+        return -1;
+    }
+
+    if (first->regex || second->regex) {
+        /* do not sort the regex matches */
+        return 0;
+    }
+
+#endif
+
+    rc = ngx_filename_cmp(first->name.data, second->name.data,
+                          ngx_min(first->name.len, second->name.len) + 1);
+
+    if (rc == 0 && !first->exact_match && second->exact_match) {
+        /* an exact match must be before the same inclusive one */
+        return 1;
+    }
+
+    return rc;
+}
+
+
+static ngx_int_t
+ngx_http_join_exact_locations(ngx_conf_t *cf, ngx_queue_t *locations)
+{
+    ngx_queue_t                *q, *x;
+    ngx_http_location_queue_t  *lq, *lx;
+
+    q = ngx_queue_head(locations);
+
+    while (q != ngx_queue_last(locations)) {
+
+        x = ngx_queue_next(q);
+
+        lq = (ngx_http_location_queue_t *) q;
+        lx = (ngx_http_location_queue_t *) x;
+
+        if (lq->name->len == lx->name->len
+            && ngx_filename_cmp(lq->name->data, lx->name->data, lx->name->len)
+               == 0)
+        {
+            if ((lq->exact && lx->exact) || (lq->inclusive && lx->inclusive)) {
+                ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+                              "duplicate location \"%V\" in %s:%ui",
+                              lx->name, lx->file_name, lx->line);
+
+                return NGX_ERROR;
+            }
+
+            lq->inclusive = lx->inclusive;
+
+            ngx_queue_remove(x);
+
+            continue;
+        }
+
+        q = ngx_queue_next(q);
+    }
+
+    return NGX_OK;
+}
+
+
+static void
+ngx_http_create_locations_list(ngx_queue_t *locations, ngx_queue_t *q)
+{
+    u_char                     *name;
+    size_t                      len;
+    ngx_queue_t                *x, tail;
+    ngx_http_location_queue_t  *lq, *lx;
+
+    if (q == ngx_queue_last(locations)) {
+        return;
+    }
+
+    lq = (ngx_http_location_queue_t *) q;
+
+    if (lq->inclusive == NULL) {
+        ngx_http_create_locations_list(locations, ngx_queue_next(q));
+        return;
+    }
+
+    len = lq->name->len;
+    name = lq->name->data;
+
+    for (x = ngx_queue_next(q);
+         x != ngx_queue_sentinel(locations);
+         x = ngx_queue_next(x))
+    {
+        lx = (ngx_http_location_queue_t *) x;
+
+        if (len > lx->name->len
+            || ngx_filename_cmp(name, lx->name->data, len) != 0)
+        {
+            break;
+        }
+    }
+
+    q = ngx_queue_next(q);
+
+    if (q == x) {
+        ngx_http_create_locations_list(locations, x);
+        return;
+    }
+
+    ngx_queue_split(locations, q, &tail);
+    ngx_queue_add(&lq->list, &tail);
+
+    if (x == ngx_queue_sentinel(locations)) {
+        ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list));
+        return;
+    }
+
+    ngx_queue_split(&lq->list, x, &tail);
+    ngx_queue_add(locations, &tail);
+
+    ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list));
+
+    ngx_http_create_locations_list(locations, x);
+}
+
+
+/*
+ * to keep cache locality for left leaf nodes, allocate nodes in following
+ * order: node, left subtree, right subtree, inclusive subtree
+ */
+
+static ngx_http_location_tree_node_t *
+ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations,
+    size_t prefix)
+{
+    size_t                          len;
+    ngx_queue_t                    *q, tail;
+    ngx_http_location_queue_t      *lq;
+    ngx_http_location_tree_node_t  *node;
+
+    q = ngx_queue_middle(locations);
+
+    lq = (ngx_http_location_queue_t *) q;
+    len = lq->name->len - prefix;
+
+    node = ngx_palloc(cf->pool,
+                      offsetof(ngx_http_location_tree_node_t, name) + len);
+    if (node == NULL) {
+        return NULL;
+    }
+
+    node->left = NULL;
+    node->right = NULL;
+    node->tree = NULL;
+    node->exact = lq->exact;
+    node->inclusive = lq->inclusive;
+
+    node->auto_redirect = (u_char) ((lq->exact && lq->exact->auto_redirect)
+                           || (lq->inclusive && lq->inclusive->auto_redirect));
+
+    node->len = (u_char) len;
+    ngx_memcpy(node->name, &lq->name->data[prefix], len);
+
+    ngx_queue_split(locations, q, &tail);
+
+    if (ngx_queue_empty(locations)) {
+        /*
+         * ngx_queue_split() insures that if left part is empty,
+         * then right one is empty too
+         */
+        goto inclusive;
+    }
+
+    node->left = ngx_http_create_locations_tree(cf, locations, prefix);
+    if (node->left == NULL) {
+        return NULL;
+    }
+
+    ngx_queue_remove(q);
+
+    if (ngx_queue_empty(&tail)) {
+        goto inclusive;
+    }
+
+    node->right = ngx_http_create_locations_tree(cf, &tail, prefix);
+    if (node->right == NULL) {
+        return NULL;
+    }
+
+inclusive:
+
+    if (ngx_queue_empty(&lq->list)) {
+        return node;
+    }
+
+    node->tree = ngx_http_create_locations_tree(cf, &lq->list, prefix + len);
+    if (node->tree == NULL) {
+        return NULL;
+    }
+
+    return node;
+}
+
+
+ngx_int_t
+ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
+    ngx_http_listen_opt_t *lsopt)
+{
+    in_port_t                   p;
+    ngx_uint_t                  i;
+    struct sockaddr            *sa;
+    struct sockaddr_in         *sin;
+    ngx_http_conf_port_t       *port;
+    ngx_http_core_main_conf_t  *cmcf;
+#if (NGX_HAVE_INET6)
+    struct sockaddr_in6        *sin6;
+#endif
+
+    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
+
+    if (cmcf->ports == NULL) {
+        cmcf->ports = ngx_array_create(cf->temp_pool, 2,
+                                       sizeof(ngx_http_conf_port_t));
+        if (cmcf->ports == NULL) {
+            return NGX_ERROR;
+        }
+    }
+
+    sa = &lsopt->u.sockaddr;
+
+    switch (sa->sa_family) {
+
+#if (NGX_HAVE_INET6)
+    case AF_INET6:
+        sin6 = &lsopt->u.sockaddr_in6;
+        p = sin6->sin6_port;
+        break;
+#endif
+
+#if (NGX_HAVE_UNIX_DOMAIN)
+    case AF_UNIX:
+        p = 0;
+        break;
+#endif
+
+    default: /* AF_INET */
+        sin = &lsopt->u.sockaddr_in;
+        p = sin->sin_port;
+        break;
+    }
+
+    port = cmcf->ports->elts;
+    for (i = 0; i < cmcf->ports->nelts; i++) {
+
+        if (p != port[i].port || sa->sa_family != port[i].family) {
+            continue;
+        }
+
+        /* a port is already in the port list */
+
+        return ngx_http_add_addresses(cf, cscf, &port[i], lsopt);
+    }
+
+    /* add a port to the port list */
+
+    port = ngx_array_push(cmcf->ports);
+    if (port == NULL) {
+        return NGX_ERROR;
+    }
+
+    port->family = sa->sa_family;
+    port->port = p;
+    port->addrs.elts = NULL;
+
+    return ngx_http_add_address(cf, cscf, port, lsopt);
+}
+
+
+static ngx_int_t
+ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
+    ngx_http_conf_port_t *port, ngx_http_listen_opt_t *lsopt)
+{
+    u_char                *p;
+    size_t                 len, off;
+    ngx_uint_t             i, default_server;
+    struct sockaddr       *sa;
+    ngx_http_conf_addr_t  *addr;
+#if (NGX_HAVE_UNIX_DOMAIN)
+    struct sockaddr_un    *saun;
+#endif
+#if (NGX_HTTP_SSL)
+    ngx_uint_t             ssl;
+#endif
+#if (NGX_HTTP_SPDY)
+    ngx_uint_t             spdy;
+#endif
+
+    /*
+     * we cannot compare whole sockaddr struct's as kernel
+     * may fill some fields in inherited sockaddr struct's
+     */
+
+    sa = &lsopt->u.sockaddr;
+
+    switch (sa->sa_family) {
+
+#if (NGX_HAVE_INET6)
+    case AF_INET6:
+        off = offsetof(struct sockaddr_in6, sin6_addr);
+        len = 16;
+        break;
+#endif
+
+#if (NGX_HAVE_UNIX_DOMAIN)
+    case AF_UNIX:
+        off = offsetof(struct sockaddr_un, sun_path);
+        len = sizeof(saun->sun_path);
+        break;
+#endif
+
+    default: /* AF_INET */
+        off = offsetof(struct sockaddr_in, sin_addr);
+        len = 4;
+        break;
+    }
+
+    p = lsopt->u.sockaddr_data + off;
+
+    addr = port->addrs.elts;
+
+    for (i = 0; i < port->addrs.nelts; i++) {
+
+        if (ngx_memcmp(p, addr[i].opt.u.sockaddr_data + off, len) != 0) {
+            continue;
+        }
+
+        /* the address is already in the address list */
+
+        if (ngx_http_add_server(cf, cscf, &addr[i]) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
+        /* preserve default_server bit during listen options overwriting */
+        default_server = addr[i].opt.default_server;
+
+#if (NGX_HTTP_SSL)
+        ssl = lsopt->ssl || addr[i].opt.ssl;
+#endif
+#if (NGX_HTTP_SPDY)
+        spdy = lsopt->spdy || addr[i].opt.spdy;
+#endif
+
+        if (lsopt->set) {
+
+            if (addr[i].opt.set) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                        "duplicate listen options for %s", addr[i].opt.addr);
+                return NGX_ERROR;
+            }
+
+            addr[i].opt = *lsopt;
+        }
+
+        /* check the duplicate "default" server for this address:port */
+
+        if (lsopt->default_server) {
+
+            if (default_server) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                        "a duplicate default server for %s", addr[i].opt.addr);
+                return NGX_ERROR;
+            }
+
+            default_server = 1;
+            addr[i].default_server = cscf;
+        }
+
+        addr[i].opt.default_server = default_server;
+#if (NGX_HTTP_SSL)
+        addr[i].opt.ssl = ssl;
+#endif
+#if (NGX_HTTP_SPDY)
+        addr[i].opt.spdy = spdy;
+#endif
+
+        return NGX_OK;
+    }
+
+    /* add the address to the addresses list that bound to this port */
+
+    return ngx_http_add_address(cf, cscf, port, lsopt);
+}
+
+
+/*
+ * add the server address, the server names and the server core module
+ * configurations to the port list
+ */
+
+static ngx_int_t
+ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
+    ngx_http_conf_port_t *port, ngx_http_listen_opt_t *lsopt)
+{
+    ngx_http_conf_addr_t  *addr;
+
+    if (port->addrs.elts == NULL) {
+        if (ngx_array_init(&port->addrs, cf->temp_pool, 4,
+                           sizeof(ngx_http_conf_addr_t))
+            != NGX_OK)
+        {
+            return NGX_ERROR;
+        }
+    }
+
+#if (NGX_HTTP_SPDY && NGX_HTTP_SSL                                            \
+     && !defined TLSEXT_TYPE_application_layer_protocol_negotiation           \
+     && !defined TLSEXT_TYPE_next_proto_neg)
+    if (lsopt->spdy && lsopt->ssl) {
+        ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+                           "nginx was built without OpenSSL ALPN or NPN "
+                           "support, SPDY is not enabled for %s", lsopt->addr);
+    }
+#endif
+
+    addr = ngx_array_push(&port->addrs);
+    if (addr == NULL) {
+        return NGX_ERROR;
+    }
+
+    addr->opt = *lsopt;
+    addr->hash.buckets = NULL;
+    addr->hash.size = 0;
+    addr->wc_head = NULL;
+    addr->wc_tail = NULL;
+#if (NGX_PCRE)
+    addr->nregex = 0;
+    addr->regex = NULL;
+#endif
+    addr->default_server = cscf;
+    addr->servers.elts = NULL;
+
+    return ngx_http_add_server(cf, cscf, addr);
+}
+
+
+/* add the server core module configuration to the address:port */
+
+static ngx_int_t
+ngx_http_add_server(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
+    ngx_http_conf_addr_t *addr)
+{
+    ngx_uint_t                  i;
+    ngx_http_core_srv_conf_t  **server;
+
+    if (addr->servers.elts == NULL) {
+        if (ngx_array_init(&addr->servers, cf->temp_pool, 4,
+                           sizeof(ngx_http_core_srv_conf_t *))
+            != NGX_OK)
+        {
+            return NGX_ERROR;
+        }
+
+    } else {
+        server = addr->servers.elts;
+        for (i = 0; i < addr->servers.nelts; i++) {
+            if (server[i] == cscf) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "a duplicate listen %s", addr->opt.addr);
+                return NGX_ERROR;
+            }
+        }
+    }
+
+    server = ngx_array_push(&addr->servers);
+    if (server == NULL) {
+        return NGX_ERROR;
+    }
+
+    *server = cscf;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
+    ngx_array_t *ports)
+{
+    ngx_uint_t             p, a;
+    ngx_http_conf_port_t  *port;
+    ngx_http_conf_addr_t  *addr;
+
+    if (ports == NULL) {
+        return NGX_OK;
+    }
+
+    port = ports->elts;
+    for (p = 0; p < ports->nelts; p++) {
+
+        ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts,
+                 sizeof(ngx_http_conf_addr_t), ngx_http_cmp_conf_addrs);
+
+        /*
+         * check whether all name-based servers have the same
+         * configuration as a default server for given address:port
+         */
+
+        addr = port[p].addrs.elts;
+        for (a = 0; a < port[p].addrs.nelts; a++) {
+
+            if (addr[a].servers.nelts > 1
+#if (NGX_PCRE)
+                || addr[a].default_server->captures
+#endif
+               )
+            {
+                if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) {
+                    return NGX_ERROR;
+                }
+            }
+        }
+
+        if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) {
+            return NGX_ERROR;
+        }
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
+    ngx_http_conf_addr_t *addr)
+{
+    ngx_int_t                   rc;
+    ngx_uint_t                  n, s;
+    ngx_hash_init_t             hash;
+    ngx_hash_keys_arrays_t      ha;
+    ngx_http_server_name_t     *name;
+    ngx_http_core_srv_conf_t  **cscfp;
+#if (NGX_PCRE)
+    ngx_uint_t                  regex, i;
+
+    regex = 0;
+#endif
+
+    ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t));
+
+    ha.temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
+    if (ha.temp_pool == NULL) {
+        return NGX_ERROR;
+    }
+
+    ha.pool = cf->pool;
+
+    if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) {
+        goto failed;
+    }
+
+    cscfp = addr->servers.elts;
+
+    for (s = 0; s < addr->servers.nelts; s++) {
+
+        name = cscfp[s]->server_names.elts;
+
+        for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
+
+#if (NGX_PCRE)
+            if (name[n].regex) {
+                regex++;
+                continue;
+            }
+#endif
+
+            rc = ngx_hash_add_key(&ha, &name[n].name, name[n].server,
+                                  NGX_HASH_WILDCARD_KEY);
+
+            if (rc == NGX_ERROR) {
+                return NGX_ERROR;
+            }
+
+            if (rc == NGX_DECLINED) {
+                ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+                              "invalid server name or wildcard \"%V\" on %s",
+                              &name[n].name, addr->opt.addr);
+                return NGX_ERROR;
+            }
+
+            if (rc == NGX_BUSY) {
+                ngx_log_error(NGX_LOG_WARN, cf->log, 0,
+                              "conflicting server name \"%V\" on %s, ignored",
+                              &name[n].name, addr->opt.addr);
+            }
+        }
+    }
+
+    hash.key = ngx_hash_key_lc;
+    hash.max_size = cmcf->server_names_hash_max_size;
+    hash.bucket_size = cmcf->server_names_hash_bucket_size;
+    hash.name = "server_names_hash";
+    hash.pool = cf->pool;
+
+    if (ha.keys.nelts) {
+        hash.hash = &addr->hash;
+        hash.temp_pool = NULL;
+
+        if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK) {
+            goto failed;
+        }
+    }
+
+    if (ha.dns_wc_head.nelts) {
+
+        ngx_qsort(ha.dns_wc_head.elts, (size_t) ha.dns_wc_head.nelts,
+                  sizeof(ngx_hash_key_t), ngx_http_cmp_dns_wildcards);
+
+        hash.hash = NULL;
+        hash.temp_pool = ha.temp_pool;
+
+        if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts,
+                                   ha.dns_wc_head.nelts)
+            != NGX_OK)
+        {
+            goto failed;
+        }
+
+        addr->wc_head = (ngx_hash_wildcard_t *) hash.hash;
+    }
+
+    if (ha.dns_wc_tail.nelts) {
+
+        ngx_qsort(ha.dns_wc_tail.elts, (size_t) ha.dns_wc_tail.nelts,
+                  sizeof(ngx_hash_key_t), ngx_http_cmp_dns_wildcards);
+
+        hash.hash = NULL;
+        hash.temp_pool = ha.temp_pool;
+
+        if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts,
+                                   ha.dns_wc_tail.nelts)
+            != NGX_OK)
+        {
+            goto failed;
+        }
+
+        addr->wc_tail = (ngx_hash_wildcard_t *) hash.hash;
+    }
+
+    ngx_destroy_pool(ha.temp_pool);
+
+#if (NGX_PCRE)
+
+    if (regex == 0) {
+        return NGX_OK;
+    }
+
+    addr->nregex = regex;
+    addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t));
+    if (addr->regex == NULL) {
+        return NGX_ERROR;
+    }
+
+    i = 0;
+
+    for (s = 0; s < addr->servers.nelts; s++) {
+
+        name = cscfp[s]->server_names.elts;
+
+        for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
+            if (name[n].regex) {
+                addr->regex[i++] = name[n];
+            }
+        }
+    }
+
+#endif
+
+    return NGX_OK;
+
+failed:
+
+    ngx_destroy_pool(ha.temp_pool);
+
+    return NGX_ERROR;
+}
+
+
+static ngx_int_t
+ngx_http_cmp_conf_addrs(const void *one, const void *two)
+{
+    ngx_http_conf_addr_t  *first, *second;
+
+    first = (ngx_http_conf_addr_t *) one;
+    second = (ngx_http_conf_addr_t *) two;
+
+    if (first->opt.wildcard) {
+        /* a wildcard address must be the last resort, shift it to the end */
+        return 1;
+    }
+
+    if (second->opt.wildcard) {
+        /* a wildcard address must be the last resort, shift it to the end */
+        return -1;
+    }
+
+    if (first->opt.bind && !second->opt.bind) {
+        /* shift explicit bind()ed addresses to the start */
+        return -1;
+    }
+
+    if (!first->opt.bind && second->opt.bind) {
+        /* shift explicit bind()ed addresses to the start */
+        return 1;
+    }
+
+    /* do not sort by default */
+
+    return 0;
+}
+
+
+static int ngx_libc_cdecl
+ngx_http_cmp_dns_wildcards(const void *one, const void *two)
+{
+    ngx_hash_key_t  *first, *second;
+
+    first = (ngx_hash_key_t *) one;
+    second = (ngx_hash_key_t *) two;
+
+    return ngx_dns_strcmp(first->key.data, second->key.data);
+}
+
+
+static ngx_int_t
+ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port)
+{
+    ngx_uint_t                 i, last, bind_wildcard;
+    ngx_listening_t           *ls;
+    ngx_http_port_t           *hport;
+    ngx_http_conf_addr_t      *addr;
+
+    addr = port->addrs.elts;
+    last = port->addrs.nelts;
+
+    /*
+     * If there is a binding to an "*:port" then we need to bind() to
+     * the "*:port" only and ignore other implicit bindings.  The bindings
+     * have been already sorted: explicit bindings are on the start, then
+     * implicit bindings go, and wildcard binding is in the end.
+     */
+
+    if (addr[last - 1].opt.wildcard) {
+        addr[last - 1].opt.bind = 1;
+        bind_wildcard = 1;
+
+    } else {
+        bind_wildcard = 0;
+    }
+
+    i = 0;
+
+    while (i < last) {
+
+        if (bind_wildcard && !addr[i].opt.bind) {
+            i++;
+            continue;
+        }
+
+        ls = ngx_http_add_listening(cf, &addr[i]);
+        if (ls == NULL) {
+            return NGX_ERROR;
+        }
+
+        hport = ngx_pcalloc(cf->pool, sizeof(ngx_http_port_t));
+        if (hport == NULL) {
+            return NGX_ERROR;
+        }
+
+        ls->servers = hport;
+
+        if (i == last - 1) {
+            hport->naddrs = last;
+
+        } else {
+            hport->naddrs = 1;
+            i = 0;
+        }
+
+        switch (ls->sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+        case AF_INET6:
+            if (ngx_http_add_addrs6(cf, hport, addr) != NGX_OK) {
+                return NGX_ERROR;
+            }
+            break;
+#endif
+        default: /* AF_INET */
+            if (ngx_http_add_addrs(cf, hport, addr) != NGX_OK) {
+                return NGX_ERROR;
+            }
+            break;
+        }
+
+        addr++;
+        last--;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_listening_t *
+ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
+{
+    ngx_listening_t           *ls;
+    ngx_http_core_loc_conf_t  *clcf;
+    ngx_http_core_srv_conf_t  *cscf;
+
+    ls = ngx_create_listening(cf, &addr->opt.u.sockaddr, addr->opt.socklen);
+    if (ls == NULL) {
+        return NULL;
+    }
+
+    ls->addr_ntop = 1;
+
+    ls->handler = ngx_http_init_connection;
+
+    cscf = addr->default_server;
+    ls->pool_size = cscf->connection_pool_size;
+    ls->post_accept_timeout = cscf->client_header_timeout;
+
+    clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
+
+    ls->logp = clcf->error_log;
+    ls->log.data = &ls->addr_text;
+    ls->log.handler = ngx_accept_log_error;
+
+#if (NGX_WIN32)
+    {
+    ngx_iocp_conf_t  *iocpcf = NULL;
+
+    if (ngx_get_conf(cf->cycle->conf_ctx, ngx_events_module)) {
+        iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
+    }
+    if (iocpcf && iocpcf->acceptex_read) {
+        ls->post_accept_buffer_size = cscf->client_header_buffer_size;
+    }
+    }
+#endif
+
+    ls->backlog = addr->opt.backlog;
+    ls->rcvbuf = addr->opt.rcvbuf;
+    ls->sndbuf = addr->opt.sndbuf;
+
+    ls->keepalive = addr->opt.so_keepalive;
+#if (NGX_HAVE_KEEPALIVE_TUNABLE)
+    ls->keepidle = addr->opt.tcp_keepidle;
+    ls->keepintvl = addr->opt.tcp_keepintvl;
+    ls->keepcnt = addr->opt.tcp_keepcnt;
+#endif
+
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
+    ls->accept_filter = addr->opt.accept_filter;
+#endif
+
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
+    ls->deferred_accept = addr->opt.deferred_accept;
+#endif
+
+#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
+    ls->ipv6only = addr->opt.ipv6only;
+#endif
+
+#if (NGX_HAVE_SETFIB)
+    ls->setfib = addr->opt.setfib;
+#endif
+
+#if (NGX_HAVE_TCP_FASTOPEN)
+    ls->fastopen = addr->opt.fastopen;
+#endif
+
+    return ls;
+}
+
+
+static ngx_int_t
+ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
+    ngx_http_conf_addr_t *addr)
+{
+    ngx_uint_t                 i;
+    ngx_http_in_addr_t        *addrs;
+    struct sockaddr_in        *sin;
+    ngx_http_virtual_names_t  *vn;
+
+    hport->addrs = ngx_pcalloc(cf->pool,
+                               hport->naddrs * sizeof(ngx_http_in_addr_t));
+    if (hport->addrs == NULL) {
+        return NGX_ERROR;
+    }
+
+    addrs = hport->addrs;
+
+    for (i = 0; i < hport->naddrs; i++) {
+
+        sin = &addr[i].opt.u.sockaddr_in;
+        addrs[i].addr = sin->sin_addr.s_addr;
+        addrs[i].conf.default_server = addr[i].default_server;
+#if (NGX_HTTP_SSL)
+        addrs[i].conf.ssl = addr[i].opt.ssl;
+#endif
+#if (NGX_HTTP_SPDY)
+        addrs[i].conf.spdy = addr[i].opt.spdy;
+#endif
+        addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
+
+        if (addr[i].hash.buckets == NULL
+            && (addr[i].wc_head == NULL
+                || addr[i].wc_head->hash.buckets == NULL)
+            && (addr[i].wc_tail == NULL
+                || addr[i].wc_tail->hash.buckets == NULL)
+#if (NGX_PCRE)
+            && addr[i].nregex == 0
+#endif
+            )
+        {
+            continue;
+        }
+
+        vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
+        if (vn == NULL) {
+            return NGX_ERROR;
+        }
+
+        addrs[i].conf.virtual_names = vn;
+
+        vn->names.hash = addr[i].hash;
+        vn->names.wc_head = addr[i].wc_head;
+        vn->names.wc_tail = addr[i].wc_tail;
+#if (NGX_PCRE)
+        vn->nregex = addr[i].nregex;
+        vn->regex = addr[i].regex;
+#endif
+    }
+
+    return NGX_OK;
+}
+
+
+#if (NGX_HAVE_INET6)
+
+static ngx_int_t
+ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
+    ngx_http_conf_addr_t *addr)
+{
+    ngx_uint_t                 i;
+    ngx_http_in6_addr_t       *addrs6;
+    struct sockaddr_in6       *sin6;
+    ngx_http_virtual_names_t  *vn;
+
+    hport->addrs = ngx_pcalloc(cf->pool,
+                               hport->naddrs * sizeof(ngx_http_in6_addr_t));
+    if (hport->addrs == NULL) {
+        return NGX_ERROR;
+    }
+
+    addrs6 = hport->addrs;
+
+    for (i = 0; i < hport->naddrs; i++) {
+
+        sin6 = &addr[i].opt.u.sockaddr_in6;
+        addrs6[i].addr6 = sin6->sin6_addr;
+        addrs6[i].conf.default_server = addr[i].default_server;
+#if (NGX_HTTP_SSL)
+        addrs6[i].conf.ssl = addr[i].opt.ssl;
+#endif
+#if (NGX_HTTP_SPDY)
+        addrs6[i].conf.spdy = addr[i].opt.spdy;
+#endif
+
+        if (addr[i].hash.buckets == NULL
+            && (addr[i].wc_head == NULL
+                || addr[i].wc_head->hash.buckets == NULL)
+            && (addr[i].wc_tail == NULL
+                || addr[i].wc_tail->hash.buckets == NULL)
+#if (NGX_PCRE)
+            && addr[i].nregex == 0
+#endif
+            )
+        {
+            continue;
+        }
+
+        vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
+        if (vn == NULL) {
+            return NGX_ERROR;
+        }
+
+        addrs6[i].conf.virtual_names = vn;
+
+        vn->names.hash = addr[i].hash;
+        vn->names.wc_head = addr[i].wc_head;
+        vn->names.wc_tail = addr[i].wc_tail;
+#if (NGX_PCRE)
+        vn->nregex = addr[i].nregex;
+        vn->regex = addr[i].regex;
+#endif
+    }
+
+    return NGX_OK;
+}
+
+#endif
+
+
+char *
+ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+    char  *p = conf;
+
+    ngx_array_t     **types;
+    ngx_str_t        *value, *default_type;
+    ngx_uint_t        i, n, hash;
+    ngx_hash_key_t   *type;
+
+    types = (ngx_array_t **) (p + cmd->offset);
+
+    if (*types == (void *) -1) {
+        return NGX_CONF_OK;
+    }
+
+    default_type = cmd->post;
+
+    if (*types == NULL) {
+        *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
+        if (*types == NULL) {
+            return NGX_CONF_ERROR;
+        }
+
+        if (default_type) {
+            type = ngx_array_push(*types);
+            if (type == NULL) {
+                return NGX_CONF_ERROR;
+            }
+
+            type->key = *default_type;
+            type->key_hash = ngx_hash_key(default_type->data,
+                                          default_type->len);
+            type->value = (void *) 4;
+        }
+    }
+
+    value = cf->args->elts;
+
+    for (i = 1; i < cf->args->nelts; i++) {
+
+        if (value[i].len == 1 && value[i].data[0] == '*') {
+            *types = (void *) -1;
+            return NGX_CONF_OK;
+        }
+
+        hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
+        value[i].data[value[i].len] = '\0';
+
+        type = (*types)->elts;
+        for (n = 0; n < (*types)->nelts; n++) {
+
+            if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
+                ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+                                   "duplicate MIME type \"%V\"", &value[i]);
+                continue;
+            }
+        }
+
+        type = ngx_array_push(*types);
+        if (type == NULL) {
+            return NGX_CONF_ERROR;
+        }
+
+        type->key = value[i];
+        type->key_hash = hash;
+        type->value = (void *) 4;
+    }
+
+    return NGX_CONF_OK;
+}
+
+
+char *
+ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t **keys, ngx_hash_t *types_hash,
+    ngx_array_t **prev_keys, ngx_hash_t *prev_types_hash,
+    ngx_str_t *default_types)
+{
+    ngx_hash_init_t  hash;
+
+    if (*keys) {
+
+        if (*keys == (void *) -1) {
+            return NGX_CONF_OK;
+        }
+
+        hash.hash = types_hash;
+        hash.key = NULL;
+        hash.max_size = 2048;
+        hash.bucket_size = 64;
+        hash.name = "test_types_hash";
+        hash.pool = cf->pool;
+        hash.temp_pool = NULL;
+
+        if (ngx_hash_init(&hash, (*keys)->elts, (*keys)->nelts) != NGX_OK) {
+            return NGX_CONF_ERROR;
+        }
+
+        return NGX_CONF_OK;
+    }
+
+    if (prev_types_hash->buckets == NULL) {
+
+        if (*prev_keys == NULL) {
+
+            if (ngx_http_set_default_types(cf, prev_keys, default_types)
+                != NGX_OK)
+            {
+                return NGX_CONF_ERROR;
+            }
+
+        } else if (*prev_keys == (void *) -1) {
+            *keys = *prev_keys;
+            return NGX_CONF_OK;
+        }
+
+        hash.hash = prev_types_hash;
+        hash.key = NULL;
+        hash.max_size = 2048;
+        hash.bucket_size = 64;
+        hash.name = "test_types_hash";
+        hash.pool = cf->pool;
+        hash.temp_pool = NULL;
+
+        if (ngx_hash_init(&hash, (*prev_keys)->elts, (*prev_keys)->nelts)
+            != NGX_OK)
+        {
+            return NGX_CONF_ERROR;
+        }
+    }
+
+    *types_hash = *prev_types_hash;
+
+    return NGX_CONF_OK;
+
+}
+
+
+ngx_int_t
+ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types,
+    ngx_str_t *default_type)
+{
+    ngx_hash_key_t  *type;
+
+    *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
+    if (*types == NULL) {
+        return NGX_ERROR;
+    }
+
+    while (default_type->len) {
+
+        type = ngx_array_push(*types);
+        if (type == NULL) {
+            return NGX_ERROR;
+        }
+
+        type->key = *default_type;
+        type->key_hash = ngx_hash_key(default_type->data,
+                                      default_type->len);
+        type->value = (void *) 4;
+
+        default_type++;
+    }
+
+    return NGX_OK;
+}
diff -rupN nginx-1.7.1/src/http/ngx_http.h nginx-1.7.1-statpatch/src/http/ngx_http.h
--- nginx-1.7.1/src/http/ngx_http.h	2014-05-27 15:58:10.000000000 +0200
+++ nginx-1.7.1-statpatch/src/http/ngx_http.h	2014-06-16 17:59:46.140123600 +0200
@@ -12,7 +12,6 @@
 #include <ngx_config.h>
 #include <ngx_core.h>
 
-
 typedef struct ngx_http_request_s     ngx_http_request_t;
 typedef struct ngx_http_upstream_s    ngx_http_upstream_t;
 typedef struct ngx_http_cache_s       ngx_http_cache_t;
diff -rupN nginx-1.7.1/src/http/ngx_http.h.orig nginx-1.7.1-statpatch/src/http/ngx_http.h.orig
--- nginx-1.7.1/src/http/ngx_http.h.orig	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.7.1-statpatch/src/http/ngx_http.h.orig	2014-05-27 15:58:10.000000000 +0200
@@ -0,0 +1,186 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_HTTP_H_INCLUDED_
+#define _NGX_HTTP_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+typedef struct ngx_http_request_s     ngx_http_request_t;
+typedef struct ngx_http_upstream_s    ngx_http_upstream_t;
+typedef struct ngx_http_cache_s       ngx_http_cache_t;
+typedef struct ngx_http_file_cache_s  ngx_http_file_cache_t;
+typedef struct ngx_http_log_ctx_s     ngx_http_log_ctx_t;
+typedef struct ngx_http_chunked_s     ngx_http_chunked_t;
+
+#if (NGX_HTTP_SPDY)
+typedef struct ngx_http_spdy_stream_s  ngx_http_spdy_stream_t;
+#endif
+
+typedef ngx_int_t (*ngx_http_header_handler_pt)(ngx_http_request_t *r,
+    ngx_table_elt_t *h, ngx_uint_t offset);
+typedef u_char *(*ngx_http_log_handler_pt)(ngx_http_request_t *r,
+    ngx_http_request_t *sr, u_char *buf, size_t len);
+
+
+#include <ngx_http_variables.h>
+#include <ngx_http_config.h>
+#include <ngx_http_request.h>
+#include <ngx_http_script.h>
+#include <ngx_http_upstream.h>
+#include <ngx_http_upstream_round_robin.h>
+#include <ngx_http_busy_lock.h>
+#include <ngx_http_core_module.h>
+
+#if (NGX_HTTP_SPDY)
+#include <ngx_http_spdy.h>
+#endif
+#if (NGX_HTTP_CACHE)
+#include <ngx_http_cache.h>
+#endif
+#if (NGX_HTTP_SSI)
+#include <ngx_http_ssi_filter_module.h>
+#endif
+#if (NGX_HTTP_SSL)
+#include <ngx_http_ssl_module.h>
+#endif
+
+
+struct ngx_http_log_ctx_s {
+    ngx_connection_t    *connection;
+    ngx_http_request_t  *request;
+    ngx_http_request_t  *current_request;
+};
+
+
+struct ngx_http_chunked_s {
+    ngx_uint_t           state;
+    off_t                size;
+    off_t                length;
+};
+
+
+typedef struct {
+    ngx_uint_t           http_version;
+    ngx_uint_t           code;
+    ngx_uint_t           count;
+    u_char              *start;
+    u_char              *end;
+} ngx_http_status_t;
+
+
+#define ngx_http_get_module_ctx(r, module)  (r)->ctx[module.ctx_index]
+#define ngx_http_set_ctx(r, c, module)      r->ctx[module.ctx_index] = c;
+
+
+ngx_int_t ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
+    ngx_http_core_loc_conf_t *clcf);
+ngx_int_t ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
+    ngx_http_listen_opt_t *lsopt);
+
+
+void ngx_http_init_connection(ngx_connection_t *c);
+void ngx_http_close_connection(ngx_connection_t *c);
+
+#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
+int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg);
+#endif
+
+ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b);
+ngx_int_t ngx_http_parse_uri(ngx_http_request_t *r);
+ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r,
+    ngx_uint_t merge_slashes);
+ngx_int_t ngx_http_parse_status_line(ngx_http_request_t *r, ngx_buf_t *b,
+    ngx_http_status_t *status);
+ngx_int_t ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
+    ngx_str_t *args, ngx_uint_t *flags);
+ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
+    ngx_uint_t allow_underscores);
+ngx_int_t ngx_http_parse_multi_header_lines(ngx_array_t *headers,
+    ngx_str_t *name, ngx_str_t *value);
+ngx_int_t ngx_http_parse_set_cookie_lines(ngx_array_t *headers,
+    ngx_str_t *name, ngx_str_t *value);
+ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len,
+    ngx_str_t *value);
+void ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri,
+    ngx_str_t *args);
+ngx_int_t ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
+    ngx_http_chunked_t *ctx);
+
+
+ngx_http_request_t *ngx_http_create_request(ngx_connection_t *c);
+ngx_int_t ngx_http_process_request_uri(ngx_http_request_t *r);
+ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
+void ngx_http_process_request(ngx_http_request_t *r);
+void ngx_http_update_location_config(ngx_http_request_t *r);
+void ngx_http_handler(ngx_http_request_t *r);
+void ngx_http_run_posted_requests(ngx_connection_t *c);
+ngx_int_t ngx_http_post_request(ngx_http_request_t *r,
+    ngx_http_posted_request_t *pr);
+void ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
+void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc);
+
+void ngx_http_empty_handler(ngx_event_t *wev);
+void ngx_http_request_empty_handler(ngx_http_request_t *r);
+
+
+#define ngx_http_ephemeral(r)  (void *) (&r->uri_start)
+
+
+#define NGX_HTTP_LAST   1
+#define NGX_HTTP_FLUSH  2
+
+ngx_int_t ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags);
+
+
+ngx_int_t ngx_http_read_client_request_body(ngx_http_request_t *r,
+    ngx_http_client_body_handler_pt post_handler);
+
+ngx_int_t ngx_http_send_header(ngx_http_request_t *r);
+ngx_int_t ngx_http_special_response_handler(ngx_http_request_t *r,
+    ngx_int_t error);
+ngx_int_t ngx_http_filter_finalize_request(ngx_http_request_t *r,
+    ngx_module_t *m, ngx_int_t error);
+void ngx_http_clean_header(ngx_http_request_t *r);
+
+
+time_t ngx_http_parse_time(u_char *value, size_t len);
+size_t ngx_http_get_time(char *buf, time_t t);
+
+
+
+ngx_int_t ngx_http_discard_request_body(ngx_http_request_t *r);
+void ngx_http_discarded_request_body_handler(ngx_http_request_t *r);
+void ngx_http_block_reading(ngx_http_request_t *r);
+void ngx_http_test_reading(ngx_http_request_t *r);
+
+
+char *ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+char *ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t **keys,
+    ngx_hash_t *types_hash, ngx_array_t **prev_keys,
+    ngx_hash_t *prev_types_hash, ngx_str_t *default_types);
+ngx_int_t ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types,
+    ngx_str_t *default_type);
+
+#if (NGX_HTTP_DEGRADATION)
+ngx_uint_t  ngx_http_degraded(ngx_http_request_t *);
+#endif
+
+
+extern ngx_module_t  ngx_http_module;
+
+extern ngx_str_t  ngx_http_html_default_types[];
+
+
+extern ngx_http_output_header_filter_pt  ngx_http_top_header_filter;
+extern ngx_http_output_body_filter_pt    ngx_http_top_body_filter;
+
+
+#endif /* _NGX_HTTP_H_INCLUDED_ */
diff -rupN nginx-1.7.1/src/http/ngx_http_request.c nginx-1.7.1-statpatch/src/http/ngx_http_request.c
--- nginx-1.7.1/src/http/ngx_http_request.c	2014-05-27 15:58:10.000000000 +0200
+++ nginx-1.7.1-statpatch/src/http/ngx_http_request.c	2014-06-16 17:59:46.146123900 +0200
@@ -2772,6 +2772,27 @@ ngx_http_test_reading(ngx_http_request_t
     }
 
 #endif
+#if (NGX_FULL_STATUS)
+    if (r->headers_in.host) {
+        ngx_str_t vihost_name = r->headers_in.host->value;
+        ngx_server_stat_t *cserver = find_stat(vihost_name);    
+
+        if (cserver) {
+            ngx_time_t      *tp;
+            ngx_msec_int_t   ms;
+            
+            tp = ngx_timeofday();
+            ms = (ngx_msec_int_t)
+                ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));			    
+            ms = (ms >= 0) ? ms : 0;
+            ngx_atomic_fetch_add(&(cserver->ngx_stat_time), ms);
+            ngx_atomic_fetch_add(&(cserver->ngx_stat_requests), 1);
+	    ngx_atomic_fetch_add(&(cserver->ngx_stat_traf), r->request_length);
+        }
+    }
+
+#endif
+
 
     n = recv(c->fd, buf, 1, MSG_PEEK);
 
@@ -3531,7 +3552,6 @@ ngx_http_close_connection(ngx_connection
 #if (NGX_STAT_STUB)
     (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
 #endif
-
     c->destroyed = 1;
 
     pool = c->pool;
diff -rupN nginx-1.7.1/src/http/ngx_http_request.c.orig nginx-1.7.1-statpatch/src/http/ngx_http_request.c.orig
--- nginx-1.7.1/src/http/ngx_http_request.c.orig	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.7.1-statpatch/src/http/ngx_http_request.c.orig	2014-05-27 15:58:10.000000000 +0200
@@ -0,0 +1,3648 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+static void ngx_http_wait_request_handler(ngx_event_t *ev);
+static void ngx_http_process_request_line(ngx_event_t *rev);
+static void ngx_http_process_request_headers(ngx_event_t *rev);
+static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
+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_header_line(ngx_http_request_t *r,
+    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_multi_header_lines(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_validate_host(ngx_str_t *host, ngx_pool_t *pool,
+    ngx_uint_t alloc);
+static ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r,
+    ngx_str_t *host);
+static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
+    ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
+    ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp);
+
+static void ngx_http_request_handler(ngx_event_t *ev);
+static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc);
+static void ngx_http_terminate_handler(ngx_http_request_t *r);
+static void ngx_http_finalize_connection(ngx_http_request_t *r);
+static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);
+static void ngx_http_writer(ngx_http_request_t *r);
+static void ngx_http_request_finalizer(ngx_http_request_t *r);
+
+static void ngx_http_set_keepalive(ngx_http_request_t *r);
+static void ngx_http_keepalive_handler(ngx_event_t *ev);
+static void ngx_http_set_lingering_close(ngx_http_request_t *r);
+static void ngx_http_lingering_close_handler(ngx_event_t *ev);
+static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
+static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
+static void ngx_http_log_request(ngx_http_request_t *r);
+
+static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len);
+static u_char *ngx_http_log_error_handler(ngx_http_request_t *r,
+    ngx_http_request_t *sr, u_char *buf, size_t len);
+
+#if (NGX_HTTP_SSL)
+static void ngx_http_ssl_handshake(ngx_event_t *rev);
+static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);
+#endif
+
+
+static char *ngx_http_client_errors[] = {
+
+    /* NGX_HTTP_PARSE_INVALID_METHOD */
+    "client sent invalid method",
+
+    /* NGX_HTTP_PARSE_INVALID_REQUEST */
+    "client sent invalid request",
+
+    /* NGX_HTTP_PARSE_INVALID_09_METHOD */
+    "client sent invalid method in HTTP/0.9 request"
+};
+
+
+ngx_http_header_t  ngx_http_headers_in[] = {
+    { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
+                 ngx_http_process_host },
+
+    { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
+                 ngx_http_process_connection },
+
+    { ngx_string("If-Modified-Since"),
+                 offsetof(ngx_http_headers_in_t, if_modified_since),
+                 ngx_http_process_unique_header_line },
+
+    { ngx_string("If-Unmodified-Since"),
+                 offsetof(ngx_http_headers_in_t, if_unmodified_since),
+                 ngx_http_process_unique_header_line },
+
+    { ngx_string("If-Match"),
+                 offsetof(ngx_http_headers_in_t, if_match),
+                 ngx_http_process_unique_header_line },
+
+    { ngx_string("If-None-Match"),
+                 offsetof(ngx_http_headers_in_t, if_none_match),
+                 ngx_http_process_unique_header_line },
+
+    { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
+                 ngx_http_process_user_agent },
+
+    { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer),
+                 ngx_http_process_header_line },
+
+    { ngx_string("Content-Length"),
+                 offsetof(ngx_http_headers_in_t, content_length),
+                 ngx_http_process_unique_header_line },
+
+    { ngx_string("Content-Type"),
+                 offsetof(ngx_http_headers_in_t, content_type),
+                 ngx_http_process_header_line },
+
+    { ngx_string("Range"), offsetof(ngx_http_headers_in_t, range),
+                 ngx_http_process_header_line },
+
+    { ngx_string("If-Range"),
+                 offsetof(ngx_http_headers_in_t, if_range),
+                 ngx_http_process_unique_header_line },
+
+    { ngx_string("Transfer-Encoding"),
+                 offsetof(ngx_http_headers_in_t, transfer_encoding),
+                 ngx_http_process_header_line },
+
+    { ngx_string("Expect"),
+                 offsetof(ngx_http_headers_in_t, expect),
+                 ngx_http_process_unique_header_line },
+
+    { ngx_string("Upgrade"),
+                 offsetof(ngx_http_headers_in_t, upgrade),
+                 ngx_http_process_header_line },
+
+#if (NGX_HTTP_GZIP)
+    { ngx_string("Accept-Encoding"),
+                 offsetof(ngx_http_headers_in_t, accept_encoding),
+                 ngx_http_process_header_line },
+
+    { ngx_string("Via"), offsetof(ngx_http_headers_in_t, via),
+                 ngx_http_process_header_line },
+#endif
+
+    { ngx_string("Authorization"),
+                 offsetof(ngx_http_headers_in_t, authorization),
+                 ngx_http_process_unique_header_line },
+
+    { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
+                 ngx_http_process_header_line },
+
+#if (NGX_HTTP_X_FORWARDED_FOR)
+    { ngx_string("X-Forwarded-For"),
+                 offsetof(ngx_http_headers_in_t, x_forwarded_for),
+                 ngx_http_process_multi_header_lines },
+#endif
+
+#if (NGX_HTTP_REALIP)
+    { ngx_string("X-Real-IP"),
+                 offsetof(ngx_http_headers_in_t, x_real_ip),
+                 ngx_http_process_header_line },
+#endif
+
+#if (NGX_HTTP_HEADERS)
+    { ngx_string("Accept"), offsetof(ngx_http_headers_in_t, accept),
+                 ngx_http_process_header_line },
+
+    { ngx_string("Accept-Language"),
+                 offsetof(ngx_http_headers_in_t, accept_language),
+                 ngx_http_process_header_line },
+#endif
+
+#if (NGX_HTTP_DAV)
+    { ngx_string("Depth"), offsetof(ngx_http_headers_in_t, depth),
+                 ngx_http_process_header_line },
+
+    { ngx_string("Destination"), offsetof(ngx_http_headers_in_t, destination),
+                 ngx_http_process_header_line },
+
+    { ngx_string("Overwrite"), offsetof(ngx_http_headers_in_t, overwrite),
+                 ngx_http_process_header_line },
+
+    { ngx_string("Date"), offsetof(ngx_http_headers_in_t, date),
+                 ngx_http_process_header_line },
+#endif
+
+    { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookies),
+                 ngx_http_process_multi_header_lines },
+
+    { ngx_null_string, 0, NULL }
+};
+
+
+void
+ngx_http_init_connection(ngx_connection_t *c)
+{
+    ngx_uint_t              i;
+    ngx_event_t            *rev;
+    struct sockaddr_in     *sin;
+    ngx_http_port_t        *port;
+    ngx_http_in_addr_t     *addr;
+    ngx_http_log_ctx_t     *ctx;
+    ngx_http_connection_t  *hc;
+#if (NGX_HAVE_INET6)
+    struct sockaddr_in6    *sin6;
+    ngx_http_in6_addr_t    *addr6;
+#endif
+
+    hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
+    if (hc == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    c->data = hc;
+
+    /* find the server configuration for the address:port */
+
+    port = c->listening->servers;
+
+    if (port->naddrs > 1) {
+
+        /*
+         * there are several addresses on this port and one of them
+         * is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
+         * is required to determine a server address
+         */
+
+        if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        switch (c->local_sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+        case AF_INET6:
+            sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
+
+            addr6 = port->addrs;
+
+            /* the last address is "*" */
+
+            for (i = 0; i < port->naddrs - 1; i++) {
+                if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) {
+                    break;
+                }
+            }
+
+            hc->addr_conf = &addr6[i].conf;
+
+            break;
+#endif
+
+        default: /* AF_INET */
+            sin = (struct sockaddr_in *) c->local_sockaddr;
+
+            addr = port->addrs;
+
+            /* the last address is "*" */
+
+            for (i = 0; i < port->naddrs - 1; i++) {
+                if (addr[i].addr == sin->sin_addr.s_addr) {
+                    break;
+                }
+            }
+
+            hc->addr_conf = &addr[i].conf;
+
+            break;
+        }
+
+    } else {
+
+        switch (c->local_sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+        case AF_INET6:
+            addr6 = port->addrs;
+            hc->addr_conf = &addr6[0].conf;
+            break;
+#endif
+
+        default: /* AF_INET */
+            addr = port->addrs;
+            hc->addr_conf = &addr[0].conf;
+            break;
+        }
+    }
+
+    /* the default server configuration for the address:port */
+    hc->conf_ctx = hc->addr_conf->default_server->ctx;
+
+    ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
+    if (ctx == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    ctx->connection = c;
+    ctx->request = NULL;
+    ctx->current_request = NULL;
+
+    c->log->connection = c->number;
+    c->log->handler = ngx_http_log_error;
+    c->log->data = ctx;
+    c->log->action = "waiting for request";
+
+    c->log_error = NGX_ERROR_INFO;
+
+    rev = c->read;
+    rev->handler = ngx_http_wait_request_handler;
+    c->write->handler = ngx_http_empty_handler;
+
+#if (NGX_HTTP_SPDY)
+    if (hc->addr_conf->spdy) {
+        rev->handler = ngx_http_spdy_init;
+    }
+#endif
+
+#if (NGX_HTTP_SSL)
+    {
+    ngx_http_ssl_srv_conf_t  *sscf;
+
+    sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
+
+    if (sscf->enable || hc->addr_conf->ssl) {
+
+        c->log->action = "SSL handshaking";
+
+        if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) {
+            ngx_log_error(NGX_LOG_ERR, c->log, 0,
+                          "no \"ssl_certificate\" is defined "
+                          "in server listening on SSL port");
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        hc->ssl = 1;
+
+        rev->handler = ngx_http_ssl_handshake;
+    }
+    }
+#endif
+
+    if (hc->addr_conf->proxy_protocol) {
+        hc->proxy_protocol = 1;
+        c->log->action = "reading PROXY protocol";
+    }
+
+    if (rev->ready) {
+        /* the deferred accept(), rtsig, aio, iocp */
+
+        if (ngx_use_accept_mutex) {
+            ngx_post_event(rev, &ngx_posted_events);
+            return;
+        }
+
+        rev->handler(rev);
+        return;
+    }
+
+    ngx_add_timer(rev, c->listening->post_accept_timeout);
+    ngx_reusable_connection(c, 1);
+
+    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+        ngx_http_close_connection(c);
+        return;
+    }
+}
+
+
+static void
+ngx_http_wait_request_handler(ngx_event_t *rev)
+{
+    u_char                    *p;
+    size_t                     size;
+    ssize_t                    n;
+    ngx_buf_t                 *b;
+    ngx_connection_t          *c;
+    ngx_http_connection_t     *hc;
+    ngx_http_core_srv_conf_t  *cscf;
+
+    c = rev->data;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http wait request handler");
+
+    if (rev->timedout) {
+        ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    if (c->close) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    hc = c->data;
+    cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
+
+    size = cscf->client_header_buffer_size;
+
+    b = c->buffer;
+
+    if (b == NULL) {
+        b = ngx_create_temp_buf(c->pool, size);
+        if (b == NULL) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        c->buffer = b;
+
+    } else if (b->start == NULL) {
+
+        b->start = ngx_palloc(c->pool, size);
+        if (b->start == NULL) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        b->pos = b->start;
+        b->last = b->start;
+        b->end = b->last + size;
+    }
+
+    n = c->recv(c, b->last, size);
+
+    if (n == NGX_AGAIN) {
+
+        if (!rev->timer_set) {
+            ngx_add_timer(rev, c->listening->post_accept_timeout);
+            ngx_reusable_connection(c, 1);
+        }
+
+        if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        /*
+         * We are trying to not hold c->buffer's memory for an idle connection.
+         */
+
+        if (ngx_pfree(c->pool, b->start) == NGX_OK) {
+            b->start = NULL;
+        }
+
+        return;
+    }
+
+    if (n == NGX_ERROR) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    if (n == 0) {
+        ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                      "client closed connection");
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    b->last += n;
+
+    if (hc->proxy_protocol) {
+        hc->proxy_protocol = 0;
+
+        p = ngx_proxy_protocol_parse(c, b->pos, b->last);
+
+        if (p == NULL) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        b->pos = p;
+
+        if (b->pos == b->last) {
+            c->log->action = "waiting for request";
+            b->pos = b->start;
+            b->last = b->start;
+            ngx_post_event(rev, &ngx_posted_events);
+            return;
+        }
+    }
+
+    c->log->action = "reading client request line";
+
+    ngx_reusable_connection(c, 0);
+
+    c->data = ngx_http_create_request(c);
+    if (c->data == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    rev->handler = ngx_http_process_request_line;
+    ngx_http_process_request_line(rev);
+}
+
+
+ngx_http_request_t *
+ngx_http_create_request(ngx_connection_t *c)
+{
+    ngx_pool_t                 *pool;
+    ngx_time_t                 *tp;
+    ngx_http_request_t         *r;
+    ngx_http_log_ctx_t         *ctx;
+    ngx_http_connection_t      *hc;
+    ngx_http_core_srv_conf_t   *cscf;
+    ngx_http_core_loc_conf_t   *clcf;
+    ngx_http_core_main_conf_t  *cmcf;
+
+    c->requests++;
+
+    hc = c->data;
+
+    cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
+
+    pool = ngx_create_pool(cscf->request_pool_size, c->log);
+    if (pool == NULL) {
+        return NULL;
+    }
+
+    r = ngx_pcalloc(pool, sizeof(ngx_http_request_t));
+    if (r == NULL) {
+        ngx_destroy_pool(pool);
+        return NULL;
+    }
+
+    r->pool = pool;
+
+    r->http_connection = hc;
+    r->signature = NGX_HTTP_MODULE;
+    r->connection = c;
+
+    r->main_conf = hc->conf_ctx->main_conf;
+    r->srv_conf = hc->conf_ctx->srv_conf;
+    r->loc_conf = hc->conf_ctx->loc_conf;
+
+    r->read_event_handler = ngx_http_block_reading;
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    ngx_http_set_connection_log(r->connection, clcf->error_log);
+
+    r->header_in = hc->nbusy ? hc->busy[0] : c->buffer;
+
+    if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
+                      sizeof(ngx_table_elt_t))
+        != NGX_OK)
+    {
+        ngx_destroy_pool(r->pool);
+        return NULL;
+    }
+
+    r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
+    if (r->ctx == NULL) {
+        ngx_destroy_pool(r->pool);
+        return NULL;
+    }
+
+    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+
+    r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
+                                        * sizeof(ngx_http_variable_value_t));
+    if (r->variables == NULL) {
+        ngx_destroy_pool(r->pool);
+        return NULL;
+    }
+
+#if (NGX_HTTP_SSL)
+    if (c->ssl) {
+        r->main_filter_need_in_memory = 1;
+    }
+#endif
+
+    r->main = r;
+    r->count = 1;
+
+    tp = ngx_timeofday();
+    r->start_sec = tp->sec;
+    r->start_msec = tp->msec;
+
+    r->method = NGX_HTTP_UNKNOWN;
+    r->http_version = NGX_HTTP_VERSION_10;
+
+    r->headers_in.content_length_n = -1;
+    r->headers_in.keep_alive_n = -1;
+    r->headers_out.content_length_n = -1;
+    r->headers_out.last_modified_time = -1;
+
+    r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
+    r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1;
+
+    r->http_state = NGX_HTTP_READING_REQUEST_STATE;
+
+    ctx = c->log->data;
+    ctx->request = r;
+    ctx->current_request = r;
+    r->log_handler = ngx_http_log_error_handler;
+
+#if (NGX_STAT_STUB)
+    (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
+    r->stat_reading = 1;
+    (void) ngx_atomic_fetch_add(ngx_stat_requests, 1);
+#endif
+
+    return r;
+}
+
+
+#if (NGX_HTTP_SSL)
+
+static void
+ngx_http_ssl_handshake(ngx_event_t *rev)
+{
+    u_char                   *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1];
+    size_t                    size;
+    ssize_t                   n;
+    ngx_err_t                 err;
+    ngx_int_t                 rc;
+    ngx_connection_t         *c;
+    ngx_http_connection_t    *hc;
+    ngx_http_ssl_srv_conf_t  *sscf;
+
+    c = rev->data;
+    hc = c->data;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
+                   "http check ssl handshake");
+
+    if (rev->timedout) {
+        ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    if (c->close) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    size = hc->proxy_protocol ? sizeof(buf) : 1;
+
+    n = recv(c->fd, (char *) buf, size, MSG_PEEK);
+
+    err = ngx_socket_errno;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %d", n);
+
+    if (n == -1) {
+        if (err == NGX_EAGAIN) {
+
+            if (!rev->timer_set) {
+                ngx_add_timer(rev, c->listening->post_accept_timeout);
+                ngx_reusable_connection(c, 1);
+            }
+
+            if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+                ngx_http_close_connection(c);
+            }
+
+            return;
+        }
+
+        ngx_connection_error(c, err, "recv() failed");
+        ngx_http_close_connection(c);
+
+        return;
+    }
+
+    if (hc->proxy_protocol) {
+        hc->proxy_protocol = 0;
+
+        p = ngx_proxy_protocol_parse(c, buf, buf + n);
+
+        if (p == NULL) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        size = p - buf;
+
+        if (c->recv(c, buf, size) != (ssize_t) size) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        c->log->action = "SSL handshaking";
+
+        if (n == (ssize_t) size) {
+            ngx_post_event(rev, &ngx_posted_events);
+            return;
+        }
+
+        n = 1;
+        buf[0] = *p;
+    }
+
+    if (n == 1) {
+        if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) {
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0,
+                           "https ssl handshake: 0x%02Xd", buf[0]);
+
+            sscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
+                                                ngx_http_ssl_module);
+
+            if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
+                != NGX_OK)
+            {
+                ngx_http_close_connection(c);
+                return;
+            }
+
+            rc = ngx_ssl_handshake(c);
+
+            if (rc == NGX_AGAIN) {
+
+                if (!rev->timer_set) {
+                    ngx_add_timer(rev, c->listening->post_accept_timeout);
+                }
+
+                ngx_reusable_connection(c, 0);
+
+                c->ssl->handler = ngx_http_ssl_handshake_handler;
+                return;
+            }
+
+            ngx_http_ssl_handshake_handler(c);
+
+            return;
+        }
+
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "plain http");
+
+        c->log->action = "waiting for request";
+
+        rev->handler = ngx_http_wait_request_handler;
+        ngx_http_wait_request_handler(rev);
+
+        return;
+    }
+
+    ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed connection");
+    ngx_http_close_connection(c);
+}
+
+
+static void
+ngx_http_ssl_handshake_handler(ngx_connection_t *c)
+{
+    if (c->ssl->handshaked) {
+
+        /*
+         * The majority of browsers do not send the "close notify" alert.
+         * Among them are MSIE, old Mozilla, Netscape 4, Konqueror,
+         * and Links.  And what is more, MSIE ignores the server's alert.
+         *
+         * Opera and recent Mozilla send the alert.
+         */
+
+        c->ssl->no_wait_shutdown = 1;
+
+#if (NGX_HTTP_SPDY                                                            \
+     && (defined TLSEXT_TYPE_application_layer_protocol_negotiation           \
+         || defined TLSEXT_TYPE_next_proto_neg))
+        {
+        unsigned int             len;
+        const unsigned char     *data;
+        static const ngx_str_t   spdy = ngx_string(NGX_SPDY_NPN_NEGOTIATED);
+
+#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
+        SSL_get0_alpn_selected(c->ssl->connection, &data, &len);
+
+#ifdef TLSEXT_TYPE_next_proto_neg
+        if (len == 0) {
+            SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
+        }
+#endif
+
+#else /* TLSEXT_TYPE_next_proto_neg */
+        SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
+#endif
+
+        if (len == spdy.len && ngx_strncmp(data, spdy.data, spdy.len) == 0) {
+            ngx_http_spdy_init(c->read);
+            return;
+        }
+        }
+#endif
+
+        c->log->action = "waiting for request";
+
+        c->read->handler = ngx_http_wait_request_handler;
+        /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler;
+
+        ngx_reusable_connection(c, 1);
+
+        ngx_http_wait_request_handler(c->read);
+
+        return;
+    }
+
+    if (c->read->timedout) {
+        ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+    }
+
+    ngx_http_close_connection(c);
+}
+
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+
+int
+ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
+{
+    ngx_str_t                  host;
+    const char                *servername;
+    ngx_connection_t          *c;
+    ngx_http_connection_t     *hc;
+    ngx_http_ssl_srv_conf_t   *sscf;
+    ngx_http_core_loc_conf_t  *clcf;
+    ngx_http_core_srv_conf_t  *cscf;
+
+    servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
+
+    if (servername == NULL) {
+        return SSL_TLSEXT_ERR_NOACK;
+    }
+
+    c = ngx_ssl_get_connection(ssl_conn);
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "SSL server name: \"%s\"", servername);
+
+    host.len = ngx_strlen(servername);
+
+    if (host.len == 0) {
+        return SSL_TLSEXT_ERR_NOACK;
+    }
+
+    host.data = (u_char *) servername;
+
+    if (ngx_http_validate_host(&host, c->pool, 1) != NGX_OK) {
+        return SSL_TLSEXT_ERR_NOACK;
+    }
+
+    hc = c->data;
+
+    if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host,
+                                     NULL, &cscf)
+        != NGX_OK)
+    {
+        return SSL_TLSEXT_ERR_NOACK;
+    }
+
+    hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
+    if (hc->ssl_servername == NULL) {
+        return SSL_TLSEXT_ERR_NOACK;
+    }
+
+    *hc->ssl_servername = host;
+
+    hc->conf_ctx = cscf->ctx;
+
+    clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);
+
+    ngx_http_set_connection_log(c, clcf->error_log);
+
+    sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
+
+    if (sscf->ssl.ctx) {
+        SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
+
+        /*
+         * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
+         * adjust other things we care about
+         */
+
+        SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
+                       SSL_CTX_get_verify_callback(sscf->ssl.ctx));
+
+        SSL_set_verify_depth(ssl_conn, SSL_CTX_get_verify_depth(sscf->ssl.ctx));
+
+#ifdef SSL_CTRL_CLEAR_OPTIONS
+        /* only in 0.9.8m+ */
+        SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
+                                    ~SSL_CTX_get_options(sscf->ssl.ctx));
+#endif
+
+        SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));
+    }
+
+    return SSL_TLSEXT_ERR_OK;
+}
+
+#endif
+
+#endif
+
+
+static void
+ngx_http_process_request_line(ngx_event_t *rev)
+{
+    ssize_t              n;
+    ngx_int_t            rc, rv;
+    ngx_str_t            host;
+    ngx_connection_t    *c;
+    ngx_http_request_t  *r;
+
+    c = rev->data;
+    r = c->data;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
+                   "http process request line");
+
+    if (rev->timedout) {
+        ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+        c->timedout = 1;
+        ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
+        return;
+    }
+
+    rc = NGX_AGAIN;
+
+    for ( ;; ) {
+
+        if (rc == NGX_AGAIN) {
+            n = ngx_http_read_request_header(r);
+
+            if (n == NGX_AGAIN || n == NGX_ERROR) {
+                return;
+            }
+        }
+
+        rc = ngx_http_parse_request_line(r, r->header_in);
+
+        if (rc == NGX_OK) {
+
+            /* the request line has been parsed successfully */
+
+            r->request_line.len = r->request_end - r->request_start;
+            r->request_line.data = r->request_start;
+            r->request_length = r->header_in->pos - r->request_start;
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                           "http request line: \"%V\"", &r->request_line);
+
+            r->method_name.len = r->method_end - r->request_start + 1;
+            r->method_name.data = r->request_line.data;
+
+            if (r->http_protocol.data) {
+                r->http_protocol.len = r->request_end - r->http_protocol.data;
+            }
+
+            if (ngx_http_process_request_uri(r) != NGX_OK) {
+                return;
+            }
+
+            if (r->host_start && r->host_end) {
+
+                host.len = r->host_end - r->host_start;
+                host.data = r->host_start;
+
+                rc = ngx_http_validate_host(&host, r->pool, 0);
+
+                if (rc == NGX_DECLINED) {
+                    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;
+                }
+
+                if (rc == NGX_ERROR) {
+                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                    return;
+                }
+
+                if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
+                    return;
+                }
+
+                r->headers_in.server = host;
+            }
+
+            if (r->http_version < NGX_HTTP_VERSION_10) {
+
+                if (r->headers_in.server.len == 0
+                    && ngx_http_set_virtual_server(r, &r->headers_in.server)
+                       == NGX_ERROR)
+                {
+                    return;
+                }
+
+                ngx_http_process_request(r);
+                return;
+            }
+
+
+            if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
+                              sizeof(ngx_table_elt_t))
+                != NGX_OK)
+            {
+                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return;
+            }
+
+            c->log->action = "reading client request headers";
+
+            rev->handler = ngx_http_process_request_headers;
+            ngx_http_process_request_headers(rev);
+
+            return;
+        }
+
+        if (rc != NGX_AGAIN) {
+
+            /* there was error while a request line parsing */
+
+            ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                          ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
+            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+            return;
+        }
+
+        /* NGX_AGAIN: a request line parsing is still incomplete */
+
+        if (r->header_in->pos == r->header_in->end) {
+
+            rv = ngx_http_alloc_large_header_buffer(r, 1);
+
+            if (rv == NGX_ERROR) {
+                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return;
+            }
+
+            if (rv == NGX_DECLINED) {
+                r->request_line.len = r->header_in->end - r->request_start;
+                r->request_line.data = r->request_start;
+
+                ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                              "client sent too long URI");
+                ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
+                return;
+            }
+        }
+    }
+}
+
+
+ngx_int_t
+ngx_http_process_request_uri(ngx_http_request_t *r)
+{
+    ngx_http_core_srv_conf_t  *cscf;
+
+    if (r->args_start) {
+        r->uri.len = r->args_start - 1 - r->uri_start;
+    } else {
+        r->uri.len = r->uri_end - r->uri_start;
+    }
+
+    if (r->complex_uri || r->quoted_uri) {
+
+        r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1);
+        if (r->uri.data == NULL) {
+            ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return NGX_ERROR;
+        }
+
+        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+        if (ngx_http_parse_complex_uri(r, cscf->merge_slashes) != NGX_OK) {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent invalid request");
+            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+            return NGX_ERROR;
+        }
+
+    } else {
+        r->uri.data = r->uri_start;
+    }
+
+    r->unparsed_uri.len = r->uri_end - r->uri_start;
+    r->unparsed_uri.data = r->uri_start;
+
+    r->valid_unparsed_uri = r->space_in_uri ? 0 : 1;
+
+    if (r->uri_ext) {
+        if (r->args_start) {
+            r->exten.len = r->args_start - 1 - r->uri_ext;
+        } else {
+            r->exten.len = r->uri_end - r->uri_ext;
+        }
+
+        r->exten.data = r->uri_ext;
+    }
+
+    if (r->args_start && r->uri_end > r->args_start) {
+        r->args.len = r->uri_end - r->args_start;
+        r->args.data = r->args_start;
+    }
+
+#if (NGX_WIN32)
+    {
+    u_char  *p, *last;
+
+    p = r->uri.data;
+    last = r->uri.data + r->uri.len;
+
+    while (p < last) {
+
+        if (*p++ == ':') {
+
+            /*
+             * this check covers "::$data", "::$index_allocation" and
+             * ":$i30:$index_allocation"
+             */
+
+            if (p < last && *p == '$') {
+                ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                              "client sent unsafe win32 URI");
+                ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+                return NGX_ERROR;
+            }
+        }
+    }
+
+    p = r->uri.data + r->uri.len - 1;
+
+    while (p > r->uri.data) {
+
+        if (*p == ' ') {
+            p--;
+            continue;
+        }
+
+        if (*p == '.') {
+            p--;
+            continue;
+        }
+
+        break;
+    }
+
+    if (p != r->uri.data + r->uri.len - 1) {
+        r->uri.len = p + 1 - r->uri.data;
+        ngx_http_set_exten(r);
+    }
+
+    }
+#endif
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http uri: \"%V\"", &r->uri);
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http args: \"%V\"", &r->args);
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http exten: \"%V\"", &r->exten);
+
+    return NGX_OK;
+}
+
+
+static void
+ngx_http_process_request_headers(ngx_event_t *rev)
+{
+    u_char                     *p;
+    size_t                      len;
+    ssize_t                     n;
+    ngx_int_t                   rc, rv;
+    ngx_table_elt_t            *h;
+    ngx_connection_t           *c;
+    ngx_http_header_t          *hh;
+    ngx_http_request_t         *r;
+    ngx_http_core_srv_conf_t   *cscf;
+    ngx_http_core_main_conf_t  *cmcf;
+
+    c = rev->data;
+    r = c->data;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
+                   "http process request header line");
+
+    if (rev->timedout) {
+        ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+        c->timedout = 1;
+        ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
+        return;
+    }
+
+    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+
+    rc = NGX_AGAIN;
+
+    for ( ;; ) {
+
+        if (rc == NGX_AGAIN) {
+
+            if (r->header_in->pos == r->header_in->end) {
+
+                rv = ngx_http_alloc_large_header_buffer(r, 0);
+
+                if (rv == NGX_ERROR) {
+                    ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                    return;
+                }
+
+                if (rv == NGX_DECLINED) {
+                    p = r->header_name_start;
+
+                    r->lingering_close = 1;
+
+                    if (p == NULL) {
+                        ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                                      "client sent too large request");
+                        ngx_http_finalize_request(r,
+                                            NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
+                        return;
+                    }
+
+                    len = r->header_in->end - p;
+
+                    if (len > NGX_MAX_ERROR_STR - 300) {
+                        len = NGX_MAX_ERROR_STR - 300;
+                        p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
+                    }
+
+                    ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                                  "client sent too long header line: \"%*s\"",
+                                  len, r->header_name_start);
+
+                    ngx_http_finalize_request(r,
+                                            NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
+                    return;
+                }
+            }
+
+            n = ngx_http_read_request_header(r);
+
+            if (n == NGX_AGAIN || n == NGX_ERROR) {
+                return;
+            }
+        }
+
+        /* the host header could change the server configuration context */
+        cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+        rc = ngx_http_parse_header_line(r, r->header_in,
+                                        cscf->underscores_in_headers);
+
+        if (rc == NGX_OK) {
+
+            r->request_length += r->header_in->pos - r->header_name_start;
+
+            if (r->invalid_header && cscf->ignore_invalid_headers) {
+
+                /* there was error while a header line parsing */
+
+                ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                              "client sent invalid header line: \"%*s\"",
+                              r->header_end - r->header_name_start,
+                              r->header_name_start);
+                continue;
+            }
+
+            /* a header line has been parsed successfully */
+
+            h = ngx_list_push(&r->headers_in.headers);
+            if (h == NULL) {
+                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return;
+            }
+
+            h->hash = r->header_hash;
+
+            h->key.len = r->header_name_end - r->header_name_start;
+            h->key.data = r->header_name_start;
+            h->key.data[h->key.len] = '\0';
+
+            h->value.len = r->header_end - r->header_start;
+            h->value.data = r->header_start;
+            h->value.data[h->value.len] = '\0';
+
+            h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
+            if (h->lowcase_key == NULL) {
+                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return;
+            }
+
+            if (h->key.len == r->lowcase_index) {
+                ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
+
+            } else {
+                ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
+            }
+
+            hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
+                               h->lowcase_key, h->key.len);
+
+            if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
+                return;
+            }
+
+            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "http header: \"%V: %V\"",
+                           &h->key, &h->value);
+
+            continue;
+        }
+
+        if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
+
+            /* a whole header has been parsed successfully */
+
+            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "http header done");
+
+            r->request_length += r->header_in->pos - r->header_name_start;
+
+            r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
+
+            rc = ngx_http_process_request_header(r);
+
+            if (rc != NGX_OK) {
+                return;
+            }
+
+            ngx_http_process_request(r);
+
+            return;
+        }
+
+        if (rc == NGX_AGAIN) {
+
+            /* a header line parsing is still not complete */
+
+            continue;
+        }
+
+        /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */
+
+        ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                      "client sent invalid header line: \"%*s\\r...\"",
+                      r->header_end - r->header_name_start,
+                      r->header_name_start);
+        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+        return;
+    }
+}
+
+
+static ssize_t
+ngx_http_read_request_header(ngx_http_request_t *r)
+{
+    ssize_t                    n;
+    ngx_event_t               *rev;
+    ngx_connection_t          *c;
+    ngx_http_core_srv_conf_t  *cscf;
+
+    c = r->connection;
+    rev = c->read;
+
+    n = r->header_in->last - r->header_in->pos;
+
+    if (n > 0) {
+        return n;
+    }
+
+    if (rev->ready) {
+        n = c->recv(c, r->header_in->last,
+                    r->header_in->end - r->header_in->last);
+    } else {
+        n = NGX_AGAIN;
+    }
+
+    if (n == NGX_AGAIN) {
+        if (!rev->timer_set) {
+            cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+            ngx_add_timer(rev, cscf->client_header_timeout);
+        }
+
+        if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+            ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return NGX_ERROR;
+        }
+
+        return NGX_AGAIN;
+    }
+
+    if (n == 0) {
+        ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                      "client prematurely closed connection");
+    }
+
+    if (n == 0 || n == NGX_ERROR) {
+        c->error = 1;
+        c->log->action = "reading client request headers";
+
+        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+        return NGX_ERROR;
+    }
+
+    r->header_in->last += n;
+
+    return n;
+}
+
+
+static ngx_int_t
+ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
+    ngx_uint_t request_line)
+{
+    u_char                    *old, *new;
+    ngx_buf_t                 *b;
+    ngx_http_connection_t     *hc;
+    ngx_http_core_srv_conf_t  *cscf;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http alloc large header buffer");
+
+    if (request_line && r->state == 0) {
+
+        /* the client fills up the buffer with "\r\n" */
+
+        r->header_in->pos = r->header_in->start;
+        r->header_in->last = r->header_in->start;
+
+        return NGX_OK;
+    }
+
+    old = request_line ? r->request_start : r->header_name_start;
+
+    cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+    if (r->state != 0
+        && (size_t) (r->header_in->pos - old)
+                                     >= cscf->large_client_header_buffers.size)
+    {
+        return NGX_DECLINED;
+    }
+
+    hc = r->http_connection;
+
+    if (hc->nfree) {
+        b = hc->free[--hc->nfree];
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "http large header free: %p %uz",
+                       b->pos, b->end - b->last);
+
+    } else if (hc->nbusy < cscf->large_client_header_buffers.num) {
+
+        if (hc->busy == NULL) {
+            hc->busy = ngx_palloc(r->connection->pool,
+                  cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
+            if (hc->busy == NULL) {
+                return NGX_ERROR;
+            }
+        }
+
+        b = ngx_create_temp_buf(r->connection->pool,
+                                cscf->large_client_header_buffers.size);
+        if (b == NULL) {
+            return NGX_ERROR;
+        }
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "http large header alloc: %p %uz",
+                       b->pos, b->end - b->last);
+
+    } else {
+        return NGX_DECLINED;
+    }
+
+    hc->busy[hc->nbusy++] = b;
+
+    if (r->state == 0) {
+        /*
+         * r->state == 0 means that a header line was parsed successfully
+         * and we do not need to copy incomplete header line and
+         * to relocate the parser header pointers
+         */
+
+        r->header_in = b;
+
+        return NGX_OK;
+    }
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http large header copy: %d", r->header_in->pos - old);
+
+    new = b->start;
+
+    ngx_memcpy(new, old, r->header_in->pos - old);
+
+    b->pos = new + (r->header_in->pos - old);
+    b->last = new + (r->header_in->pos - old);
+
+    if (request_line) {
+        r->request_start = new;
+
+        if (r->request_end) {
+            r->request_end = new + (r->request_end - old);
+        }
+
+        r->method_end = new + (r->method_end - old);
+
+        r->uri_start = new + (r->uri_start - old);
+        r->uri_end = new + (r->uri_end - old);
+
+        if (r->schema_start) {
+            r->schema_start = new + (r->schema_start - old);
+            r->schema_end = new + (r->schema_end - old);
+        }
+
+        if (r->host_start) {
+            r->host_start = new + (r->host_start - old);
+            if (r->host_end) {
+                r->host_end = new + (r->host_end - old);
+            }
+        }
+
+        if (r->port_start) {
+            r->port_start = new + (r->port_start - old);
+            r->port_end = new + (r->port_end - old);
+        }
+
+        if (r->uri_ext) {
+            r->uri_ext = new + (r->uri_ext - old);
+        }
+
+        if (r->args_start) {
+            r->args_start = new + (r->args_start - old);
+        }
+
+        if (r->http_protocol.data) {
+            r->http_protocol.data = new + (r->http_protocol.data - old);
+        }
+
+    } else {
+        r->header_name_start = new;
+        r->header_name_end = new + (r->header_name_end - old);
+        r->header_start = new + (r->header_start - old);
+        r->header_end = new + (r->header_end - old);
+    }
+
+    r->header_in = b;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
+    ngx_uint_t offset)
+{
+    ngx_table_elt_t  **ph;
+
+    ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
+
+    if (*ph == NULL) {
+        *ph = h;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
+    ngx_uint_t offset)
+{
+    ngx_table_elt_t  **ph;
+
+    ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
+
+    if (*ph == NULL) {
+        *ph = h;
+        return NGX_OK;
+    }
+
+    ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                  "client sent duplicate header line: \"%V: %V\", "
+                  "previous value: \"%V: %V\"",
+                  &h->key, &h->value, &(*ph)->key, &(*ph)->value);
+
+    ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+
+    return NGX_ERROR;
+}
+
+
+static ngx_int_t
+ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
+    ngx_uint_t offset)
+{
+    ngx_int_t  rc;
+    ngx_str_t  host;
+
+    if (r->headers_in.host == NULL) {
+        r->headers_in.host = h;
+    }
+
+    host = h->value;
+
+    rc = ngx_http_validate_host(&host, r->pool, 0);
+
+    if (rc == NGX_DECLINED) {
+        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 (rc == NGX_ERROR) {
+        ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return NGX_ERROR;
+    }
+
+    if (r->headers_in.server.len) {
+        return NGX_OK;
+    }
+
+    if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
+        return NGX_ERROR;
+    }
+
+    r->headers_in.server = host;
+
+    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)
+{
+    if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) {
+        r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
+
+    } else if (ngx_strcasestrn(h->value.data, "keep-alive", 10 - 1)) {
+        r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
+    }
+
+    return NGX_OK;
+}
+
+
+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  *user_agent, *msie;
+
+    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;
+
+    msie = ngx_strstrn(user_agent, "MSIE ", 5 - 1);
+
+    if (msie && msie + 7 < user_agent + h->value.len) {
+
+        r->headers_in.msie = 1;
+
+        if (msie[6] == '.') {
+
+            switch (msie[5]) {
+            case '4':
+            case '5':
+                r->headers_in.msie6 = 1;
+                break;
+            case '6':
+                if (ngx_strstrn(msie + 8, "SV1", 3 - 1) == NULL) {
+                    r->headers_in.msie6 = 1;
+                }
+                break;
+            }
+        }
+
+#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.msie6 = 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, "Chrome/", 7 - 1)) {
+            r->headers_in.chrome = 1;
+
+        } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)
+                   && ngx_strstrn(user_agent, "Mac OS X", 8 - 1))
+        {
+            r->headers_in.safari = 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_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h,
+    ngx_uint_t offset)
+{
+    ngx_array_t       *headers;
+    ngx_table_elt_t  **ph;
+
+    headers = (ngx_array_t *) ((char *) &r->headers_in + offset);
+
+    if (headers->elts == NULL) {
+        if (ngx_array_init(headers, r->pool, 1, sizeof(ngx_table_elt_t *))
+            != NGX_OK)
+        {
+            ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return NGX_ERROR;
+        }
+    }
+
+    ph = ngx_array_push(headers);
+    if (ph == NULL) {
+        ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return NGX_ERROR;
+    }
+
+    *ph = h;
+    return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_http_process_request_header(ngx_http_request_t *r)
+{
+    if (r->headers_in.server.len == 0
+        && ngx_http_set_virtual_server(r, &r->headers_in.server)
+           == NGX_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) {
+        r->headers_in.content_length_n =
+                            ngx_atoof(r->headers_in.content_length->value.data,
+                                      r->headers_in.content_length->value.len);
+
+        if (r->headers_in.content_length_n == NGX_ERROR) {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent invalid \"Content-Length\" header");
+            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+            return NGX_ERROR;
+        }
+    }
+
+    if (r->method & NGX_HTTP_TRACE) {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent TRACE method");
+        ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
+        return NGX_ERROR;
+    }
+
+    if (r->headers_in.transfer_encoding) {
+        if (r->headers_in.transfer_encoding->value.len == 7
+            && ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
+                               (u_char *) "chunked", 7) == 0)
+        {
+            r->headers_in.content_length = NULL;
+            r->headers_in.content_length_n = -1;
+            r->headers_in.chunked = 1;
+
+        } else if (r->headers_in.transfer_encoding->value.len != 8
+            || ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
+                               (u_char *) "identity", 8) != 0)
+        {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent unknown \"Transfer-Encoding\": \"%V\"",
+                          &r->headers_in.transfer_encoding->value);
+            ngx_http_finalize_request(r, NGX_HTTP_NOT_IMPLEMENTED);
+            return NGX_ERROR;
+        }
+    }
+
+    if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
+        if (r->headers_in.keep_alive) {
+            r->headers_in.keep_alive_n =
+                            ngx_atotm(r->headers_in.keep_alive->value.data,
+                                      r->headers_in.keep_alive->value.len);
+        }
+    }
+
+    return NGX_OK;
+}
+
+
+void
+ngx_http_process_request(ngx_http_request_t *r)
+{
+    ngx_connection_t  *c;
+
+    c = r->connection;
+
+#if (NGX_HTTP_SSL)
+
+    if (r->http_connection->ssl) {
+        long                      rc;
+        X509                     *cert;
+        ngx_http_ssl_srv_conf_t  *sscf;
+
+        if (c->ssl == NULL) {
+            ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                          "client sent plain HTTP request to HTTPS port");
+            ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
+            return;
+        }
+
+        sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
+
+        if (sscf->verify) {
+            rc = SSL_get_verify_result(c->ssl->connection);
+
+            if (rc != X509_V_OK
+                && (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
+            {
+                ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                              "client SSL certificate verify error: (%l:%s)",
+                              rc, X509_verify_cert_error_string(rc));
+
+                ngx_ssl_remove_cached_session(sscf->ssl.ctx,
+                                       (SSL_get0_session(c->ssl->connection)));
+
+                ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
+                return;
+            }
+
+            if (sscf->verify == 1) {
+                cert = SSL_get_peer_certificate(c->ssl->connection);
+
+                if (cert == NULL) {
+                    ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                                  "client sent no required SSL certificate");
+
+                    ngx_ssl_remove_cached_session(sscf->ssl.ctx,
+                                       (SSL_get0_session(c->ssl->connection)));
+
+                    ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
+                    return;
+                }
+
+                X509_free(cert);
+            }
+        }
+    }
+
+#endif
+
+    if (c->read->timer_set) {
+        ngx_del_timer(c->read);
+    }
+
+#if (NGX_STAT_STUB)
+    (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
+    r->stat_reading = 0;
+    (void) ngx_atomic_fetch_add(ngx_stat_writing, 1);
+    r->stat_writing = 1;
+#endif
+
+    c->read->handler = ngx_http_request_handler;
+    c->write->handler = ngx_http_request_handler;
+    r->read_event_handler = ngx_http_block_reading;
+
+    ngx_http_handler(r);
+
+    ngx_http_run_posted_requests(c);
+}
+
+
+static ngx_int_t
+ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc)
+{
+    u_char  *h, ch;
+    size_t   i, dot_pos, host_len;
+
+    enum {
+        sw_usual = 0,
+        sw_literal,
+        sw_rest
+    } state;
+
+    dot_pos = host->len;
+    host_len = host->len;
+
+    h = host->data;
+
+    state = sw_usual;
+
+    for (i = 0; i < host->len; i++) {
+        ch = h[i];
+
+        switch (ch) {
+
+        case '.':
+            if (dot_pos == i - 1) {
+                return NGX_DECLINED;
+            }
+            dot_pos = i;
+            break;
+
+        case ':':
+            if (state == sw_usual) {
+                host_len = i;
+                state = sw_rest;
+            }
+            break;
+
+        case '[':
+            if (i == 0) {
+                state = sw_literal;
+            }
+            break;
+
+        case ']':
+            if (state == sw_literal) {
+                host_len = i + 1;
+                state = sw_rest;
+            }
+            break;
+
+        case '\0':
+            return NGX_DECLINED;
+
+        default:
+
+            if (ngx_path_separator(ch)) {
+                return NGX_DECLINED;
+            }
+
+            if (ch >= 'A' && ch <= 'Z') {
+                alloc = 1;
+            }
+
+            break;
+        }
+    }
+
+    if (dot_pos == host_len - 1) {
+        host_len--;
+    }
+
+    if (host_len == 0) {
+        return NGX_DECLINED;
+    }
+
+    if (alloc) {
+        host->data = ngx_pnalloc(pool, host_len);
+        if (host->data == NULL) {
+            return NGX_ERROR;
+        }
+
+        ngx_strlow(host->data, h, host_len);
+    }
+
+    host->len = host_len;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host)
+{
+    ngx_int_t                  rc;
+    ngx_http_connection_t     *hc;
+    ngx_http_core_loc_conf_t  *clcf;
+    ngx_http_core_srv_conf_t  *cscf;
+
+#if (NGX_SUPPRESS_WARN)
+    cscf = NULL;
+#endif
+
+    hc = r->http_connection;
+
+#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
+
+    if (hc->ssl_servername) {
+        if (hc->ssl_servername->len == host->len
+            && ngx_strncmp(hc->ssl_servername->data,
+                           host->data, host->len) == 0)
+        {
+#if (NGX_PCRE)
+            if (hc->ssl_servername_regex
+                && ngx_http_regex_exec(r, hc->ssl_servername_regex,
+                                          hc->ssl_servername) != NGX_OK)
+            {
+                ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return NGX_ERROR;
+            }
+#endif
+            return NGX_OK;
+        }
+    }
+
+#endif
+
+    rc = ngx_http_find_virtual_server(r->connection,
+                                      hc->addr_conf->virtual_names,
+                                      host, r, &cscf);
+
+    if (rc == NGX_ERROR) {
+        ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return NGX_ERROR;
+    }
+
+#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
+
+    if (hc->ssl_servername) {
+        ngx_http_ssl_srv_conf_t  *sscf;
+
+        if (rc == NGX_DECLINED) {
+            cscf = hc->addr_conf->default_server;
+            rc = NGX_OK;
+        }
+
+        sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module);
+
+        if (sscf->verify) {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client attempted to request the server name "
+                          "different from that one was negotiated");
+            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+            return NGX_ERROR;
+        }
+    }
+
+#endif
+
+    if (rc == NGX_DECLINED) {
+        return NGX_OK;
+    }
+
+    r->srv_conf = cscf->ctx->srv_conf;
+    r->loc_conf = cscf->ctx->loc_conf;
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    ngx_http_set_connection_log(r->connection, clcf->error_log);
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_find_virtual_server(ngx_connection_t *c,
+    ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
+    ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp)
+{
+    ngx_http_core_srv_conf_t  *cscf;
+
+    if (virtual_names == NULL) {
+        return NGX_DECLINED;
+    }
+
+    cscf = ngx_hash_find_combined(&virtual_names->names,
+                                  ngx_hash_key(host->data, host->len),
+                                  host->data, host->len);
+
+    if (cscf) {
+        *cscfp = cscf;
+        return NGX_OK;
+    }
+
+#if (NGX_PCRE)
+
+    if (host->len && virtual_names->nregex) {
+        ngx_int_t                n;
+        ngx_uint_t               i;
+        ngx_http_server_name_t  *sn;
+
+        sn = virtual_names->regex;
+
+#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
+
+        if (r == NULL) {
+            ngx_http_connection_t  *hc;
+
+            for (i = 0; i < virtual_names->nregex; i++) {
+
+                n = ngx_regex_exec(sn[i].regex->regex, host, NULL, 0);
+
+                if (n == NGX_REGEX_NO_MATCHED) {
+                    continue;
+                }
+
+                if (n >= 0) {
+                    hc = c->data;
+                    hc->ssl_servername_regex = sn[i].regex;
+
+                    *cscfp = sn[i].server;
+                    return NGX_OK;
+                }
+
+                ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                              ngx_regex_exec_n " failed: %i "
+                              "on \"%V\" using \"%V\"",
+                              n, host, &sn[i].regex->name);
+
+                return NGX_ERROR;
+            }
+
+            return NGX_DECLINED;
+        }
+
+#endif /* NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME */
+
+        for (i = 0; i < virtual_names->nregex; i++) {
+
+            n = ngx_http_regex_exec(r, sn[i].regex, host);
+
+            if (n == NGX_DECLINED) {
+                continue;
+            }
+
+            if (n == NGX_OK) {
+                *cscfp = sn[i].server;
+                return NGX_OK;
+            }
+
+            return NGX_ERROR;
+        }
+    }
+
+#endif /* NGX_PCRE */
+
+    return NGX_DECLINED;
+}
+
+
+static void
+ngx_http_request_handler(ngx_event_t *ev)
+{
+    ngx_connection_t    *c;
+    ngx_http_request_t  *r;
+    ngx_http_log_ctx_t  *ctx;
+
+    c = ev->data;
+    r = c->data;
+
+    ctx = c->log->data;
+    ctx->current_request = r;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http run request: \"%V?%V\"", &r->uri, &r->args);
+
+    if (ev->write) {
+        r->write_event_handler(r);
+
+    } else {
+        r->read_event_handler(r);
+    }
+
+    ngx_http_run_posted_requests(c);
+}
+
+
+void
+ngx_http_run_posted_requests(ngx_connection_t *c)
+{
+    ngx_http_request_t         *r;
+    ngx_http_log_ctx_t         *ctx;
+    ngx_http_posted_request_t  *pr;
+
+    for ( ;; ) {
+
+        if (c->destroyed) {
+            return;
+        }
+
+        r = c->data;
+        pr = r->main->posted_requests;
+
+        if (pr == NULL) {
+            return;
+        }
+
+        r->main->posted_requests = pr->next;
+
+        r = pr->request;
+
+        ctx = c->log->data;
+        ctx->current_request = r;
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http posted request: \"%V?%V\"", &r->uri, &r->args);
+
+        r->write_event_handler(r);
+    }
+}
+
+
+ngx_int_t
+ngx_http_post_request(ngx_http_request_t *r, ngx_http_posted_request_t *pr)
+{
+    ngx_http_posted_request_t  **p;
+
+    if (pr == NULL) {
+        pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
+        if (pr == NULL) {
+            return NGX_ERROR;
+        }
+    }
+
+    pr->request = r;
+    pr->next = NULL;
+
+    for (p = &r->main->posted_requests; *p; p = &(*p)->next) { /* void */ }
+
+    *p = pr;
+
+    return NGX_OK;
+}
+
+
+void
+ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
+{
+    ngx_connection_t          *c;
+    ngx_http_request_t        *pr;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    c = r->connection;
+
+    ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http finalize request: %d, \"%V?%V\" a:%d, c:%d",
+                   rc, &r->uri, &r->args, r == c->data, r->main->count);
+
+    if (rc == NGX_DONE) {
+        ngx_http_finalize_connection(r);
+        return;
+    }
+
+    if (rc == NGX_OK && r->filter_finalize) {
+        c->error = 1;
+    }
+
+    if (rc == NGX_DECLINED) {
+        r->content_handler = NULL;
+        r->write_event_handler = ngx_http_core_run_phases;
+        ngx_http_core_run_phases(r);
+        return;
+    }
+
+    if (r != r->main && r->post_subrequest) {
+        rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
+    }
+
+    if (rc == NGX_ERROR
+        || rc == NGX_HTTP_REQUEST_TIME_OUT
+        || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
+        || c->error)
+    {
+        if (ngx_http_post_action(r) == NGX_OK) {
+            return;
+        }
+
+        if (r->main->blocked) {
+            r->write_event_handler = ngx_http_request_finalizer;
+        }
+
+        ngx_http_terminate_request(r, rc);
+        return;
+    }
+
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE
+        || rc == NGX_HTTP_CREATED
+        || rc == NGX_HTTP_NO_CONTENT)
+    {
+        if (rc == NGX_HTTP_CLOSE) {
+            ngx_http_terminate_request(r, rc);
+            return;
+        }
+
+        if (r == r->main) {
+            if (c->read->timer_set) {
+                ngx_del_timer(c->read);
+            }
+
+            if (c->write->timer_set) {
+                ngx_del_timer(c->write);
+            }
+        }
+
+        c->read->handler = ngx_http_request_handler;
+        c->write->handler = ngx_http_request_handler;
+
+        ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
+        return;
+    }
+
+    if (r != r->main) {
+
+        if (r->buffered || r->postponed) {
+
+            if (ngx_http_set_write_handler(r) != NGX_OK) {
+                ngx_http_terminate_request(r, 0);
+            }
+
+            return;
+        }
+
+        pr = r->parent;
+
+        if (r == c->data) {
+
+            r->main->count--;
+            r->main->subrequests++;
+
+            if (!r->logged) {
+
+                clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+                if (clcf->log_subrequest) {
+                    ngx_http_log_request(r);
+                }
+
+                r->logged = 1;
+
+            } else {
+                ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                              "subrequest: \"%V?%V\" logged again",
+                              &r->uri, &r->args);
+            }
+
+            r->done = 1;
+
+            if (pr->postponed && pr->postponed->request == r) {
+                pr->postponed = pr->postponed->next;
+            }
+
+            c->data = pr;
+
+        } else {
+
+            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                           "http finalize non-active request: \"%V?%V\"",
+                           &r->uri, &r->args);
+
+            r->write_event_handler = ngx_http_request_finalizer;
+
+            if (r->waited) {
+                r->done = 1;
+            }
+        }
+
+        if (ngx_http_post_request(pr, NULL) != NGX_OK) {
+            r->main->count++;
+            ngx_http_terminate_request(r, 0);
+            return;
+        }
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http wake parent request: \"%V?%V\"",
+                       &pr->uri, &pr->args);
+
+        return;
+    }
+
+    if (r->buffered || c->buffered || r->postponed || r->blocked) {
+
+        if (ngx_http_set_write_handler(r) != NGX_OK) {
+            ngx_http_terminate_request(r, 0);
+        }
+
+        return;
+    }
+
+    if (r != c->data) {
+        ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                      "http finalize non-active request: \"%V?%V\"",
+                      &r->uri, &r->args);
+        return;
+    }
+
+    r->done = 1;
+    r->write_event_handler = ngx_http_request_empty_handler;
+
+    if (!r->post_action) {
+        r->request_complete = 1;
+    }
+
+    if (ngx_http_post_action(r) == NGX_OK) {
+        return;
+    }
+
+    if (c->read->timer_set) {
+        ngx_del_timer(c->read);
+    }
+
+    if (c->write->timer_set) {
+        c->write->delayed = 0;
+        ngx_del_timer(c->write);
+    }
+
+    if (c->read->eof) {
+        ngx_http_close_request(r, 0);
+        return;
+    }
+
+    ngx_http_finalize_connection(r);
+}
+
+
+static void
+ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
+{
+    ngx_http_cleanup_t    *cln;
+    ngx_http_request_t    *mr;
+    ngx_http_ephemeral_t  *e;
+
+    mr = r->main;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http terminate request count:%d", mr->count);
+
+    if (rc > 0 && (mr->headers_out.status == 0 || mr->connection->sent == 0)) {
+        mr->headers_out.status = rc;
+    }
+
+    cln = mr->cleanup;
+    mr->cleanup = NULL;
+
+    while (cln) {
+        if (cln->handler) {
+            cln->handler(cln->data);
+        }
+
+        cln = cln->next;
+    }
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http terminate cleanup count:%d blk:%d",
+                   mr->count, mr->blocked);
+
+    if (mr->write_event_handler) {
+
+        if (mr->blocked) {
+            return;
+        }
+
+        e = ngx_http_ephemeral(mr);
+        mr->posted_requests = NULL;
+        mr->write_event_handler = ngx_http_terminate_handler;
+        (void) ngx_http_post_request(mr, &e->terminal_posted_request);
+        return;
+    }
+
+    ngx_http_close_request(mr, rc);
+}
+
+
+static void
+ngx_http_terminate_handler(ngx_http_request_t *r)
+{
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http terminate handler count:%d", r->count);
+
+    r->count = 1;
+
+    ngx_http_close_request(r, 0);
+}
+
+
+static void
+ngx_http_finalize_connection(ngx_http_request_t *r)
+{
+    ngx_http_core_loc_conf_t  *clcf;
+
+#if (NGX_HTTP_SPDY)
+    if (r->spdy_stream) {
+        ngx_http_close_request(r, 0);
+        return;
+    }
+#endif
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    if (r->main->count != 1) {
+
+        if (r->discard_body) {
+            r->read_event_handler = ngx_http_discarded_request_body_handler;
+            ngx_add_timer(r->connection->read, clcf->lingering_timeout);
+
+            if (r->lingering_time == 0) {
+                r->lingering_time = ngx_time()
+                                      + (time_t) (clcf->lingering_time / 1000);
+            }
+        }
+
+        ngx_http_close_request(r, 0);
+        return;
+    }
+
+    if (!ngx_terminate
+         && !ngx_exiting
+         && r->keepalive
+         && clcf->keepalive_timeout > 0)
+    {
+        ngx_http_set_keepalive(r);
+        return;
+    }
+
+    if (clcf->lingering_close == NGX_HTTP_LINGERING_ALWAYS
+        || (clcf->lingering_close == NGX_HTTP_LINGERING_ON
+            && (r->lingering_close
+                || r->header_in->pos < r->header_in->last
+                || r->connection->read->ready)))
+    {
+        ngx_http_set_lingering_close(r);
+        return;
+    }
+
+    ngx_http_close_request(r, 0);
+}
+
+
+static ngx_int_t
+ngx_http_set_write_handler(ngx_http_request_t *r)
+{
+    ngx_event_t               *wev;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;
+
+    r->read_event_handler = r->discard_body ?
+                                ngx_http_discarded_request_body_handler:
+                                ngx_http_test_reading;
+    r->write_event_handler = ngx_http_writer;
+
+#if (NGX_HTTP_SPDY)
+    if (r->spdy_stream) {
+        return NGX_OK;
+    }
+#endif
+
+    wev = r->connection->write;
+
+    if (wev->ready && wev->delayed) {
+        return NGX_OK;
+    }
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+    if (!wev->delayed) {
+        ngx_add_timer(wev, clcf->send_timeout);
+    }
+
+    if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
+        ngx_http_close_request(r, 0);
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+}
+
+
+static void
+ngx_http_writer(ngx_http_request_t *r)
+{
+    int                        rc;
+    ngx_event_t               *wev;
+    ngx_connection_t          *c;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    c = r->connection;
+    wev = c->write;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,
+                   "http writer handler: \"%V?%V\"", &r->uri, &r->args);
+
+    clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module);
+
+    if (wev->timedout) {
+        if (!wev->delayed) {
+            ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
+                          "client timed out");
+            c->timedout = 1;
+
+            ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
+            return;
+        }
+
+        wev->timedout = 0;
+        wev->delayed = 0;
+
+        if (!wev->ready) {
+            ngx_add_timer(wev, clcf->send_timeout);
+
+            if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
+                ngx_http_close_request(r, 0);
+            }
+
+            return;
+        }
+
+    }
+
+    if (wev->delayed || r->aio) {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
+                       "http writer delayed");
+
+        if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
+            ngx_http_close_request(r, 0);
+        }
+
+        return;
+    }
+
+    rc = ngx_http_output_filter(r, NULL);
+
+    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http writer output filter: %d, \"%V?%V\"",
+                   rc, &r->uri, &r->args);
+
+    if (rc == NGX_ERROR) {
+        ngx_http_finalize_request(r, rc);
+        return;
+    }
+
+    if (r->buffered || r->postponed || (r == r->main && c->buffered)) {
+
+        if (!wev->delayed) {
+            ngx_add_timer(wev, clcf->send_timeout);
+        }
+
+        if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
+            ngx_http_close_request(r, 0);
+        }
+
+        return;
+    }
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,
+                   "http writer done: \"%V?%V\"", &r->uri, &r->args);
+
+    r->write_event_handler = ngx_http_request_empty_handler;
+
+    ngx_http_finalize_request(r, rc);
+}
+
+
+static void
+ngx_http_request_finalizer(ngx_http_request_t *r)
+{
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http finalizer done: \"%V?%V\"", &r->uri, &r->args);
+
+    ngx_http_finalize_request(r, 0);
+}
+
+
+void
+ngx_http_block_reading(ngx_http_request_t *r)
+{
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http reading blocked");
+
+    /* aio does not call this handler */
+
+    if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
+        && r->connection->read->active)
+    {
+        if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0) != NGX_OK) {
+            ngx_http_close_request(r, 0);
+        }
+    }
+}
+
+
+void
+ngx_http_test_reading(ngx_http_request_t *r)
+{
+    int                n;
+    char               buf[1];
+    ngx_err_t          err;
+    ngx_event_t       *rev;
+    ngx_connection_t  *c;
+
+    c = r->connection;
+    rev = c->read;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test reading");
+
+#if (NGX_HTTP_SPDY)
+
+    if (r->spdy_stream) {
+        if (c->error) {
+            err = 0;
+            goto closed;
+        }
+
+        return;
+    }
+
+#endif
+
+#if (NGX_HAVE_KQUEUE)
+
+    if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
+
+        if (!rev->pending_eof) {
+            return;
+        }
+
+        rev->eof = 1;
+        c->error = 1;
+        err = rev->kq_errno;
+
+        goto closed;
+    }
+
+#endif
+
+#if (NGX_HAVE_EPOLLRDHUP)
+
+    if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) && rev->pending_eof) {
+        socklen_t  len;
+
+        rev->eof = 1;
+        c->error = 1;
+
+        err = 0;
+        len = sizeof(ngx_err_t);
+
+        /*
+         * BSDs and Linux return 0 and set a pending error in err
+         * Solaris returns -1 and sets errno
+         */
+
+        if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
+            == -1)
+        {
+            err = ngx_socket_errno;
+        }
+
+        goto closed;
+    }
+
+#endif
+
+    n = recv(c->fd, buf, 1, MSG_PEEK);
+
+    if (n == 0) {
+        rev->eof = 1;
+        c->error = 1;
+        err = 0;
+
+        goto closed;
+
+    } else if (n == -1) {
+        err = ngx_socket_errno;
+
+        if (err != NGX_EAGAIN) {
+            rev->eof = 1;
+            c->error = 1;
+
+            goto closed;
+        }
+    }
+
+    /* aio does not call this handler */
+
+    if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && rev->active) {
+
+        if (ngx_del_event(rev, NGX_READ_EVENT, 0) != NGX_OK) {
+            ngx_http_close_request(r, 0);
+        }
+    }
+
+    return;
+
+closed:
+
+    if (err) {
+        rev->error = 1;
+    }
+
+    ngx_log_error(NGX_LOG_INFO, c->log, err,
+                  "client prematurely closed connection");
+
+    ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST);
+}
+
+
+static void
+ngx_http_set_keepalive(ngx_http_request_t *r)
+{
+    int                        tcp_nodelay;
+    ngx_int_t                  i;
+    ngx_buf_t                 *b, *f;
+    ngx_event_t               *rev, *wev;
+    ngx_connection_t          *c;
+    ngx_http_connection_t     *hc;
+    ngx_http_core_srv_conf_t  *cscf;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    c = r->connection;
+    rev = c->read;
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler");
+
+    if (r->discard_body) {
+        r->write_event_handler = ngx_http_request_empty_handler;
+        r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
+        ngx_add_timer(rev, clcf->lingering_timeout);
+        return;
+    }
+
+    c->log->action = "closing request";
+
+    hc = r->http_connection;
+    b = r->header_in;
+
+    if (b->pos < b->last) {
+
+        /* the pipelined request */
+
+        if (b != c->buffer) {
+
+            /*
+             * If the large header buffers were allocated while the previous
+             * request processing then we do not use c->buffer for
+             * the pipelined request (see ngx_http_create_request()).
+             *
+             * Now we would move the large header buffers to the free list.
+             */
+
+            cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+            if (hc->free == NULL) {
+                hc->free = ngx_palloc(c->pool,
+                  cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
+
+                if (hc->free == NULL) {
+                    ngx_http_close_request(r, 0);
+                    return;
+                }
+            }
+
+            for (i = 0; i < hc->nbusy - 1; i++) {
+                f = hc->busy[i];
+                hc->free[hc->nfree++] = f;
+                f->pos = f->start;
+                f->last = f->start;
+            }
+
+            hc->busy[0] = b;
+            hc->nbusy = 1;
+        }
+    }
+
+    /* guard against recursive call from ngx_http_finalize_connection() */
+    r->keepalive = 0;
+
+    ngx_http_free_request(r, 0);
+
+    c->data = hc;
+
+    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    wev = c->write;
+    wev->handler = ngx_http_empty_handler;
+
+    if (b->pos < b->last) {
+
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");
+
+        c->log->action = "reading client pipelined request line";
+
+        r = ngx_http_create_request(c);
+        if (r == NULL) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        r->pipeline = 1;
+
+        c->data = r;
+
+        c->sent = 0;
+        c->destroyed = 0;
+
+        if (rev->timer_set) {
+            ngx_del_timer(rev);
+        }
+
+        rev->handler = ngx_http_process_request_line;
+        ngx_post_event(rev, &ngx_posted_events);
+        return;
+    }
+
+    /*
+     * To keep a memory footprint as small as possible for an idle keepalive
+     * connection we try to free c->buffer's memory if it was allocated outside
+     * the c->pool.  The large header buffers are always allocated outside the
+     * c->pool and are freed too.
+     */
+
+    b = c->buffer;
+
+    if (ngx_pfree(c->pool, b->start) == NGX_OK) {
+
+        /*
+         * the special note for ngx_http_keepalive_handler() that
+         * c->buffer's memory was freed
+         */
+
+        b->pos = NULL;
+
+    } else {
+        b->pos = b->start;
+        b->last = b->start;
+    }
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p %d",
+                   hc->free, hc->nfree);
+
+    if (hc->free) {
+        for (i = 0; i < hc->nfree; i++) {
+            ngx_pfree(c->pool, hc->free[i]->start);
+            hc->free[i] = NULL;
+        }
+
+        hc->nfree = 0;
+    }
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %d",
+                   hc->busy, hc->nbusy);
+
+    if (hc->busy) {
+        for (i = 0; i < hc->nbusy; i++) {
+            ngx_pfree(c->pool, hc->busy[i]->start);
+            hc->busy[i] = NULL;
+        }
+
+        hc->nbusy = 0;
+    }
+
+#if (NGX_HTTP_SSL)
+    if (c->ssl) {
+        ngx_ssl_free_buffer(c);
+    }
+#endif
+
+    rev->handler = ngx_http_keepalive_handler;
+
+    if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
+        if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
+            ngx_http_close_connection(c);
+            return;
+        }
+    }
+
+    c->log->action = "keepalive";
+
+    if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
+        if (ngx_tcp_push(c->fd) == -1) {
+            ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
+        tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
+
+    } else {
+        tcp_nodelay = 1;
+    }
+
+    if (tcp_nodelay
+        && clcf->tcp_nodelay
+        && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
+    {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
+
+        if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
+                       (const void *) &tcp_nodelay, sizeof(int))
+            == -1)
+        {
+#if (NGX_SOLARIS)
+            /* Solaris returns EINVAL if a socket has been shut down */
+            c->log_error = NGX_ERROR_IGNORE_EINVAL;
+#endif
+
+            ngx_connection_error(c, ngx_socket_errno,
+                                 "setsockopt(TCP_NODELAY) failed");
+
+            c->log_error = NGX_ERROR_INFO;
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        c->tcp_nodelay = NGX_TCP_NODELAY_SET;
+    }
+
+#if 0
+    /* if ngx_http_request_t was freed then we need some other place */
+    r->http_state = NGX_HTTP_KEEPALIVE_STATE;
+#endif
+
+    c->idle = 1;
+    ngx_reusable_connection(c, 1);
+
+    ngx_add_timer(rev, clcf->keepalive_timeout);
+
+    if (rev->ready) {
+        ngx_post_event(rev, &ngx_posted_events);
+    }
+}
+
+
+static void
+ngx_http_keepalive_handler(ngx_event_t *rev)
+{
+    size_t             size;
+    ssize_t            n;
+    ngx_buf_t         *b;
+    ngx_connection_t  *c;
+
+    c = rev->data;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http keepalive handler");
+
+    if (rev->timedout || c->close) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+#if (NGX_HAVE_KQUEUE)
+
+    if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
+        if (rev->pending_eof) {
+            c->log->handler = NULL;
+            ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
+                          "kevent() reported that client %V closed "
+                          "keepalive connection", &c->addr_text);
+#if (NGX_HTTP_SSL)
+            if (c->ssl) {
+                c->ssl->no_send_shutdown = 1;
+            }
+#endif
+            ngx_http_close_connection(c);
+            return;
+        }
+    }
+
+#endif
+
+    b = c->buffer;
+    size = b->end - b->start;
+
+    if (b->pos == NULL) {
+
+        /*
+         * The c->buffer's memory was freed by ngx_http_set_keepalive().
+         * However, the c->buffer->start and c->buffer->end were not changed
+         * to keep the buffer size.
+         */
+
+        b->pos = ngx_palloc(c->pool, size);
+        if (b->pos == NULL) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        b->start = b->pos;
+        b->last = b->pos;
+        b->end = b->pos + size;
+    }
+
+    /*
+     * MSIE closes a keepalive connection with RST flag
+     * so we ignore ECONNRESET here.
+     */
+
+    c->log_error = NGX_ERROR_IGNORE_ECONNRESET;
+    ngx_set_socket_errno(0);
+
+    n = c->recv(c, b->last, size);
+    c->log_error = NGX_ERROR_INFO;
+
+    if (n == NGX_AGAIN) {
+        if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        /*
+         * Like ngx_http_set_keepalive() we are trying to not hold
+         * c->buffer's memory for a keepalive connection.
+         */
+
+        if (ngx_pfree(c->pool, b->start) == NGX_OK) {
+
+            /*
+             * the special note that c->buffer's memory was freed
+             */
+
+            b->pos = NULL;
+        }
+
+        return;
+    }
+
+    if (n == NGX_ERROR) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    c->log->handler = NULL;
+
+    if (n == 0) {
+        ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno,
+                      "client %V closed keepalive connection", &c->addr_text);
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    b->last += n;
+
+    c->log->handler = ngx_http_log_error;
+    c->log->action = "reading client request line";
+
+    c->idle = 0;
+    ngx_reusable_connection(c, 0);
+
+    c->data = ngx_http_create_request(c);
+    if (c->data == NULL) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
+    c->sent = 0;
+    c->destroyed = 0;
+
+    ngx_del_timer(rev);
+
+    rev->handler = ngx_http_process_request_line;
+    ngx_http_process_request_line(rev);
+}
+
+
+static void
+ngx_http_set_lingering_close(ngx_http_request_t *r)
+{
+    ngx_event_t               *rev, *wev;
+    ngx_connection_t          *c;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    c = r->connection;
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    rev = c->read;
+    rev->handler = ngx_http_lingering_close_handler;
+
+    r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
+    ngx_add_timer(rev, clcf->lingering_timeout);
+
+    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+        ngx_http_close_request(r, 0);
+        return;
+    }
+
+    wev = c->write;
+    wev->handler = ngx_http_empty_handler;
+
+    if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
+        if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
+            ngx_http_close_request(r, 0);
+            return;
+        }
+    }
+
+    if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
+        ngx_connection_error(c, ngx_socket_errno,
+                             ngx_shutdown_socket_n " failed");
+        ngx_http_close_request(r, 0);
+        return;
+    }
+
+    if (rev->ready) {
+        ngx_http_lingering_close_handler(rev);
+    }
+}
+
+
+static void
+ngx_http_lingering_close_handler(ngx_event_t *rev)
+{
+    ssize_t                    n;
+    ngx_msec_t                 timer;
+    ngx_connection_t          *c;
+    ngx_http_request_t        *r;
+    ngx_http_core_loc_conf_t  *clcf;
+    u_char                     buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];
+
+    c = rev->data;
+    r = c->data;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http lingering close handler");
+
+    if (rev->timedout) {
+        ngx_http_close_request(r, 0);
+        return;
+    }
+
+    timer = (ngx_msec_t) r->lingering_time - (ngx_msec_t) ngx_time();
+    if ((ngx_msec_int_t) timer <= 0) {
+        ngx_http_close_request(r, 0);
+        return;
+    }
+
+    do {
+        n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n);
+
+        if (n == NGX_ERROR || n == 0) {
+            ngx_http_close_request(r, 0);
+            return;
+        }
+
+    } while (rev->ready);
+
+    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+        ngx_http_close_request(r, 0);
+        return;
+    }
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    timer *= 1000;
+
+    if (timer > clcf->lingering_timeout) {
+        timer = clcf->lingering_timeout;
+    }
+
+    ngx_add_timer(rev, timer);
+}
+
+
+void
+ngx_http_empty_handler(ngx_event_t *wev)
+{
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler");
+
+    return;
+}
+
+
+void
+ngx_http_request_empty_handler(ngx_http_request_t *r)
+{
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http request empty handler");
+
+    return;
+}
+
+
+ngx_int_t
+ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags)
+{
+    ngx_buf_t    *b;
+    ngx_chain_t   out;
+
+    b = ngx_calloc_buf(r->pool);
+    if (b == NULL) {
+        return NGX_ERROR;
+    }
+
+    if (flags & NGX_HTTP_LAST) {
+
+        if (r == r->main && !r->post_action) {
+            b->last_buf = 1;
+
+        } else {
+            b->sync = 1;
+            b->last_in_chain = 1;
+        }
+    }
+
+    if (flags & NGX_HTTP_FLUSH) {
+        b->flush = 1;
+    }
+
+    out.buf = b;
+    out.next = NULL;
+
+    return ngx_http_output_filter(r, &out);
+}
+
+
+static ngx_int_t
+ngx_http_post_action(ngx_http_request_t *r)
+{
+    ngx_http_core_loc_conf_t  *clcf;
+
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    if (clcf->post_action.data == NULL) {
+        return NGX_DECLINED;
+    }
+
+    if (r->post_action && r->uri_changes == 0) {
+        return NGX_DECLINED;
+    }
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "post action: \"%V\"", &clcf->post_action);
+
+    r->main->count--;
+
+    r->http_version = NGX_HTTP_VERSION_9;
+    r->header_only = 1;
+    r->post_action = 1;
+
+    r->read_event_handler = ngx_http_block_reading;
+
+    if (clcf->post_action.data[0] == '/') {
+        ngx_http_internal_redirect(r, &clcf->post_action, NULL);
+
+    } else {
+        ngx_http_named_location(r, &clcf->post_action);
+    }
+
+    return NGX_OK;
+}
+
+
+static void
+ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
+{
+    ngx_connection_t  *c;
+
+    r = r->main;
+    c = r->connection;
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http request count:%d blk:%d", r->count, r->blocked);
+
+    if (r->count == 0) {
+        ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero");
+    }
+
+    r->count--;
+
+    if (r->count || r->blocked) {
+        return;
+    }
+
+#if (NGX_HTTP_SPDY)
+    if (r->spdy_stream) {
+        ngx_http_spdy_close_stream(r->spdy_stream, rc);
+        return;
+    }
+#endif
+
+    ngx_http_free_request(r, rc);
+    ngx_http_close_connection(c);
+}
+
+
+void
+ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
+{
+    ngx_log_t                 *log;
+    ngx_pool_t                *pool;
+    struct linger              linger;
+    ngx_http_cleanup_t        *cln;
+    ngx_http_log_ctx_t        *ctx;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    log = r->connection->log;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http close request");
+
+    if (r->pool == NULL) {
+        ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed");
+        return;
+    }
+
+    cln = r->cleanup;
+    r->cleanup = NULL;
+
+    while (cln) {
+        if (cln->handler) {
+            cln->handler(cln->data);
+        }
+
+        cln = cln->next;
+    }
+
+#if (NGX_STAT_STUB)
+
+    if (r->stat_reading) {
+        (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
+    }
+
+    if (r->stat_writing) {
+        (void) ngx_atomic_fetch_add(ngx_stat_writing, -1);
+    }
+
+#endif
+
+    if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) {
+        r->headers_out.status = rc;
+    }
+
+    log->action = "logging request";
+
+    ngx_http_log_request(r);
+
+    log->action = "closing request";
+
+    if (r->connection->timedout) {
+        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+        if (clcf->reset_timedout_connection) {
+            linger.l_onoff = 1;
+            linger.l_linger = 0;
+
+            if (setsockopt(r->connection->fd, SOL_SOCKET, SO_LINGER,
+                           (const void *) &linger, sizeof(struct linger)) == -1)
+            {
+                ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
+                              "setsockopt(SO_LINGER) failed");
+            }
+        }
+    }
+
+    /* the various request strings were allocated from r->pool */
+    ctx = log->data;
+    ctx->request = NULL;
+
+    r->request_line.len = 0;
+
+    r->connection->destroyed = 1;
+
+    /*
+     * Setting r->pool to NULL will increase probability to catch double close
+     * of request since the request object is allocated from its own pool.
+     */
+
+    pool = r->pool;
+    r->pool = NULL;
+
+    ngx_destroy_pool(pool);
+}
+
+
+static void
+ngx_http_log_request(ngx_http_request_t *r)
+{
+    ngx_uint_t                  i, n;
+    ngx_http_handler_pt        *log_handler;
+    ngx_http_core_main_conf_t  *cmcf;
+
+    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+
+    log_handler = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.elts;
+    n = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.nelts;
+
+    for (i = 0; i < n; i++) {
+        log_handler[i](r);
+    }
+}
+
+
+void
+ngx_http_close_connection(ngx_connection_t *c)
+{
+    ngx_pool_t  *pool;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "close http connection: %d", c->fd);
+
+#if (NGX_HTTP_SSL)
+
+    if (c->ssl) {
+        if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
+            c->ssl->handler = ngx_http_close_connection;
+            return;
+        }
+    }
+
+#endif
+
+#if (NGX_STAT_STUB)
+    (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
+#endif
+
+    c->destroyed = 1;
+
+    pool = c->pool;
+
+    ngx_close_connection(c);
+
+    ngx_destroy_pool(pool);
+}
+
+
+static u_char *
+ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len)
+{
+    u_char              *p;
+    ngx_http_request_t  *r;
+    ngx_http_log_ctx_t  *ctx;
+
+    if (log->action) {
+        p = ngx_snprintf(buf, len, " while %s", log->action);
+        len -= p - buf;
+        buf = p;
+    }
+
+    ctx = log->data;
+
+    p = ngx_snprintf(buf, len, ", client: %V", &ctx->connection->addr_text);
+    len -= p - buf;
+
+    r = ctx->request;
+
+    if (r) {
+        return r->log_handler(r, ctx->current_request, p, len);
+
+    } else {
+        p = ngx_snprintf(p, len, ", server: %V",
+                         &ctx->connection->listening->addr_text);
+    }
+
+    return p;
+}
+
+
+static u_char *
+ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
+    u_char *buf, size_t len)
+{
+    char                      *uri_separator;
+    u_char                    *p;
+    ngx_http_upstream_t       *u;
+    ngx_http_core_srv_conf_t  *cscf;
+
+    cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+    p = ngx_snprintf(buf, len, ", server: %V", &cscf->server_name);
+    len -= p - buf;
+    buf = p;
+
+    if (r->request_line.data == NULL && r->request_start) {
+        for (p = r->request_start; p < r->header_in->last; p++) {
+            if (*p == CR || *p == LF) {
+                break;
+            }
+        }
+
+        r->request_line.len = p - r->request_start;
+        r->request_line.data = r->request_start;
+    }
+
+    if (r->request_line.len) {
+        p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
+        len -= p - buf;
+        buf = p;
+    }
+
+    if (r != sr) {
+        p = ngx_snprintf(buf, len, ", subrequest: \"%V\"", &sr->uri);
+        len -= p - buf;
+        buf = p;
+    }
+
+    u = sr->upstream;
+
+    if (u && u->peer.name) {
+
+        uri_separator = "";
+
+#if (NGX_HAVE_UNIX_DOMAIN)
+        if (u->peer.sockaddr && u->peer.sockaddr->sa_family == AF_UNIX) {
+            uri_separator = ":";
+        }
+#endif
+
+        p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
+                         &u->schema, u->peer.name,
+                         uri_separator, &u->uri);
+        len -= p - buf;
+        buf = p;
+    }
+
+    if (r->headers_in.host) {
+        p = ngx_snprintf(buf, len, ", host: \"%V\"",
+                         &r->headers_in.host->value);
+        len -= p - buf;
+        buf = p;
+    }
+
+    if (r->headers_in.referer) {
+        p = ngx_snprintf(buf, len, ", referrer: \"%V\"",
+                         &r->headers_in.referer->value);
+        buf = p;
+    }
+
+    return buf;
+}
diff -rupN nginx-1.7.1/src/http/ngx_http_request.c.rej nginx-1.7.1-statpatch/src/http/ngx_http_request.c.rej
--- nginx-1.7.1/src/http/ngx_http_request.c.rej	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.7.1-statpatch/src/http/ngx_http_request.c.rej	2014-06-16 17:59:46.148124100 +0200
@@ -0,0 +1,11 @@
+--- src/http/ngx_http_request.c	2010-02-01 18:06:25.000000000 +0300
++++ src/http/ngx_http_request.c	2010-06-26 20:03:18.000000000 +0400
+@@ -252,7 +252,7 @@
+ #endif
+ 
+     c = rev->data;
+-
++    
+     if (rev->timedout) {
+         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
+ 
diff -rupN nginx-1.7.1/src/http/ngx_http_request.h nginx-1.7.1-statpatch/src/http/ngx_http_request.h
--- nginx-1.7.1/src/http/ngx_http_request.h	2014-05-27 15:58:10.000000000 +0200
+++ nginx-1.7.1-statpatch/src/http/ngx_http_request.h	2014-06-16 17:59:46.150124200 +0200
@@ -502,6 +502,10 @@ struct ngx_http_request_s {
 #if 0
     unsigned                          cacheable:1;
 #endif
+#if (NGX_FULL_STATUS)
+    unsigned                          full_stat_reading:1;
+    unsigned                          full_stat_writing:1;
+#endif
 
     unsigned                          pipeline:1;
     unsigned                          chunked:1;
diff -rupN nginx-1.7.1/src/http/ngx_http_request.h.orig nginx-1.7.1-statpatch/src/http/ngx_http_request.h.orig
--- nginx-1.7.1/src/http/ngx_http_request.h.orig	1970-01-01 01:00:00.000000000 +0100
+++ nginx-1.7.1-statpatch/src/http/ngx_http_request.h.orig	2014-05-27 15:58:10.000000000 +0200
@@ -0,0 +1,597 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_HTTP_REQUEST_H_INCLUDED_
+#define _NGX_HTTP_REQUEST_H_INCLUDED_
+
+
+#define NGX_HTTP_MAX_URI_CHANGES           10
+#define NGX_HTTP_MAX_SUBREQUESTS           200
+
+/* must be 2^n */
+#define NGX_HTTP_LC_HEADER_LEN             32
+
+
+#define NGX_HTTP_DISCARD_BUFFER_SIZE       4096
+#define NGX_HTTP_LINGERING_BUFFER_SIZE     4096
+
+
+#define NGX_HTTP_VERSION_9                 9
+#define NGX_HTTP_VERSION_10                1000
+#define NGX_HTTP_VERSION_11                1001
+
+#define NGX_HTTP_UNKNOWN                   0x0001
+#define NGX_HTTP_GET                       0x0002
+#define NGX_HTTP_HEAD                      0x0004
+#define NGX_HTTP_POST                      0x0008
+#define NGX_HTTP_PUT                       0x0010
+#define NGX_HTTP_DELETE                    0x0020
+#define NGX_HTTP_MKCOL                     0x0040
+#define NGX_HTTP_COPY                      0x0080
+#define NGX_HTTP_MOVE                      0x0100
+#define NGX_HTTP_OPTIONS                   0x0200
+#define NGX_HTTP_PROPFIND                  0x0400
+#define NGX_HTTP_PROPPATCH                 0x0800
+#define NGX_HTTP_LOCK                      0x1000
+#define NGX_HTTP_UNLOCK                    0x2000
+#define NGX_HTTP_PATCH                     0x4000
+#define NGX_HTTP_TRACE                     0x8000
+
+#define NGX_HTTP_CONNECTION_CLOSE          1
+#define NGX_HTTP_CONNECTION_KEEP_ALIVE     2
+
+
+#define NGX_NONE                           1
+
+
+#define NGX_HTTP_PARSE_HEADER_DONE         1
+
+#define NGX_HTTP_CLIENT_ERROR              10
+#define NGX_HTTP_PARSE_INVALID_METHOD      10
+#define NGX_HTTP_PARSE_INVALID_REQUEST     11
+#define NGX_HTTP_PARSE_INVALID_09_METHOD   12
+
+#define NGX_HTTP_PARSE_INVALID_HEADER      13
+
+
+/* unused                                  1 */
+#define NGX_HTTP_SUBREQUEST_IN_MEMORY      2
+#define NGX_HTTP_SUBREQUEST_WAITED         4
+#define NGX_HTTP_LOG_UNSAFE                8
+
+
+#define NGX_HTTP_CONTINUE                  100
+#define NGX_HTTP_SWITCHING_PROTOCOLS       101
+#define NGX_HTTP_PROCESSING                102
+
+#define NGX_HTTP_OK                        200
+#define NGX_HTTP_CREATED                   201
+#define NGX_HTTP_ACCEPTED                  202
+#define NGX_HTTP_NO_CONTENT                204
+#define NGX_HTTP_PARTIAL_CONTENT           206
+
+#define NGX_HTTP_SPECIAL_RESPONSE          300
+#define NGX_HTTP_MOVED_PERMANENTLY         301
+#define NGX_HTTP_MOVED_TEMPORARILY         302
+#define NGX_HTTP_SEE_OTHER                 303
+#define NGX_HTTP_NOT_MODIFIED              304
+#define NGX_HTTP_TEMPORARY_REDIRECT        307
+
+#define NGX_HTTP_BAD_REQUEST               400
+#define NGX_HTTP_UNAUTHORIZED              401
+#define NGX_HTTP_FORBIDDEN                 403
+#define NGX_HTTP_NOT_FOUND                 404
+#define NGX_HTTP_NOT_ALLOWED               405
+#define NGX_HTTP_REQUEST_TIME_OUT          408
+#define NGX_HTTP_CONFLICT                  409
+#define NGX_HTTP_LENGTH_REQUIRED           411
+#define NGX_HTTP_PRECONDITION_FAILED       412
+#define NGX_HTTP_REQUEST_ENTITY_TOO_LARGE  413
+#define NGX_HTTP_REQUEST_URI_TOO_LARGE     414
+#define NGX_HTTP_UNSUPPORTED_MEDIA_TYPE    415
+#define NGX_HTTP_RANGE_NOT_SATISFIABLE     416
+
+
+/* Our own HTTP codes */
+
+/* The special code to close connection without any response */
+#define NGX_HTTP_CLOSE                     444
+
+#define NGX_HTTP_NGINX_CODES               494
+
+#define NGX_HTTP_REQUEST_HEADER_TOO_LARGE  494
+
+#define NGX_HTTPS_CERT_ERROR               495
+#define NGX_HTTPS_NO_CERT                  496
+
+/*
+ * We use the special code for the plain HTTP requests that are sent to
+ * HTTPS port to distinguish it from 4XX in an error page redirection
+ */
+#define NGX_HTTP_TO_HTTPS                  497
+
+/* 498 is the canceled code for the requests with invalid host name */
+
+/*
+ * HTTP does not define the code for the case when a client closed
+ * the connection while we are processing its request so we introduce
+ * own code to log such situation when a client has closed the connection
+ * before we even try to send the HTTP header to it
+ */
+#define NGX_HTTP_CLIENT_CLOSED_REQUEST     499
+
+
+#define NGX_HTTP_INTERNAL_SERVER_ERROR     500
+#define NGX_HTTP_NOT_IMPLEMENTED           501
+#define NGX_HTTP_BAD_GATEWAY               502
+#define NGX_HTTP_SERVICE_UNAVAILABLE       503
+#define NGX_HTTP_GATEWAY_TIME_OUT          504
+#define NGX_HTTP_INSUFFICIENT_STORAGE      507
+
+
+#define NGX_HTTP_LOWLEVEL_BUFFERED         0xf0
+#define NGX_HTTP_WRITE_BUFFERED            0x10
+#define NGX_HTTP_GZIP_BUFFERED             0x20
+#define NGX_HTTP_SSI_BUFFERED              0x01
+#define NGX_HTTP_SUB_BUFFERED              0x02
+#define NGX_HTTP_COPY_BUFFERED             0x04
+
+
+typedef enum {
+    NGX_HTTP_INITING_REQUEST_STATE = 0,
+    NGX_HTTP_READING_REQUEST_STATE,
+    NGX_HTTP_PROCESS_REQUEST_STATE,
+
+    NGX_HTTP_CONNECT_UPSTREAM_STATE,
+    NGX_HTTP_WRITING_UPSTREAM_STATE,
+    NGX_HTTP_READING_UPSTREAM_STATE,
+
+    NGX_HTTP_WRITING_REQUEST_STATE,
+    NGX_HTTP_LINGERING_CLOSE_STATE,
+    NGX_HTTP_KEEPALIVE_STATE
+} ngx_http_state_e;
+
+
+typedef struct {
+    ngx_str_t                         name;
+    ngx_uint_t                        offset;
+    ngx_http_header_handler_pt        handler;
+} ngx_http_header_t;
+
+
+typedef struct {
+    ngx_str_t                         name;
+    ngx_uint_t                        offset;
+} ngx_http_header_out_t;
+
+
+typedef struct {
+    ngx_list_t                        headers;
+
+    ngx_table_elt_t                  *host;
+    ngx_table_elt_t                  *connection;
+    ngx_table_elt_t                  *if_modified_since;
+    ngx_table_elt_t                  *if_unmodified_since;
+    ngx_table_elt_t                  *if_match;
+    ngx_table_elt_t                  *if_none_match;
+    ngx_table_elt_t                  *user_agent;
+    ngx_table_elt_t                  *referer;
+    ngx_table_elt_t                  *content_length;
+    ngx_table_elt_t                  *content_type;
+
+    ngx_table_elt_t                  *range;
+    ngx_table_elt_t                  *if_range;
+
+    ngx_table_elt_t                  *transfer_encoding;
+    ngx_table_elt_t                  *expect;
+    ngx_table_elt_t                  *upgrade;
+
+#if (NGX_HTTP_GZIP)
+    ngx_table_elt_t                  *accept_encoding;
+    ngx_table_elt_t                  *via;
+#endif
+
+    ngx_table_elt_t                  *authorization;
+
+    ngx_table_elt_t                  *keep_alive;
+
+#if (NGX_HTTP_X_FORWARDED_FOR)
+    ngx_array_t                       x_forwarded_for;
+#endif
+
+#if (NGX_HTTP_REALIP)
+    ngx_table_elt_t                  *x_real_ip;
+#endif
+
+#if (NGX_HTTP_HEADERS)
+    ngx_table_elt_t                  *accept;
+    ngx_table_elt_t                  *accept_language;
+#endif
+
+#if (NGX_HTTP_DAV)
+    ngx_table_elt_t                  *depth;
+    ngx_table_elt_t                  *destination;
+    ngx_table_elt_t                  *overwrite;
+    ngx_table_elt_t                  *date;
+#endif
+
+    ngx_str_t                         user;
+    ngx_str_t                         passwd;
+
+    ngx_array_t                       cookies;
+
+    ngx_str_t                         server;
+    off_t                             content_length_n;
+    time_t                            keep_alive_n;
+
+    unsigned                          connection_type:2;
+    unsigned                          chunked:1;
+    unsigned                          msie:1;
+    unsigned                          msie6:1;
+    unsigned                          opera:1;
+    unsigned                          gecko:1;
+    unsigned                          chrome:1;
+    unsigned                          safari:1;
+    unsigned                          konqueror:1;
+} ngx_http_headers_in_t;
+
+
+typedef struct {
+    ngx_list_t                        headers;
+
+    ngx_uint_t                        status;
+    ngx_str_t                         status_line;
+
+    ngx_table_elt_t                  *server;
+    ngx_table_elt_t                  *date;
+    ngx_table_elt_t                  *content_length;
+    ngx_table_elt_t                  *content_encoding;
+    ngx_table_elt_t                  *location;
+    ngx_table_elt_t                  *refresh;
+    ngx_table_elt_t                  *last_modified;
+    ngx_table_elt_t                  *content_range;
+    ngx_table_elt_t                  *accept_ranges;
+    ngx_table_elt_t                  *www_authenticate;
+    ngx_table_elt_t                  *expires;
+    ngx_table_elt_t                  *etag;
+
+    ngx_str_t                        *override_charset;
+
+    size_t                            content_type_len;
+    ngx_str_t                         content_type;
+    ngx_str_t                         charset;
+    u_char                           *content_type_lowcase;
+    ngx_uint_t                        content_type_hash;
+
+    ngx_array_t                       cache_control;
+
+    off_t                             content_length_n;
+    time_t                            date_time;
+    time_t                            last_modified_time;
+} ngx_http_headers_out_t;
+
+
+typedef void (*ngx_http_client_body_handler_pt)(ngx_http_request_t *r);
+
+typedef struct {
+    ngx_temp_file_t                  *temp_file;
+    ngx_chain_t                      *bufs;
+    ngx_buf_t                        *buf;
+    off_t                             rest;
+    ngx_chain_t                      *free;
+    ngx_chain_t                      *busy;
+    ngx_http_chunked_t               *chunked;
+    ngx_http_client_body_handler_pt   post_handler;
+} ngx_http_request_body_t;
+
+
+typedef struct ngx_http_addr_conf_s  ngx_http_addr_conf_t;
+
+typedef struct {
+    ngx_http_addr_conf_t             *addr_conf;
+    ngx_http_conf_ctx_t              *conf_ctx;
+
+#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
+    ngx_str_t                        *ssl_servername;
+#if (NGX_PCRE)
+    ngx_http_regex_t                 *ssl_servername_regex;
+#endif
+#endif
+
+    ngx_buf_t                       **busy;
+    ngx_int_t                         nbusy;
+
+    ngx_buf_t                       **free;
+    ngx_int_t                         nfree;
+
+#if (NGX_HTTP_SSL)
+    unsigned                          ssl:1;
+#endif
+    unsigned                          proxy_protocol:1;
+} ngx_http_connection_t;
+
+
+typedef void (*ngx_http_cleanup_pt)(void *data);
+
+typedef struct ngx_http_cleanup_s  ngx_http_cleanup_t;
+
+struct ngx_http_cleanup_s {
+    ngx_http_cleanup_pt               handler;
+    void                             *data;
+    ngx_http_cleanup_t               *next;
+};
+
+
+typedef ngx_int_t (*ngx_http_post_subrequest_pt)(ngx_http_request_t *r,
+    void *data, ngx_int_t rc);
+
+typedef struct {
+    ngx_http_post_subrequest_pt       handler;
+    void                             *data;
+} ngx_http_post_subrequest_t;
+
+
+typedef struct ngx_http_postponed_request_s  ngx_http_postponed_request_t;
+
+struct ngx_http_postponed_request_s {
+    ngx_http_request_t               *request;
+    ngx_chain_t                      *out;
+    ngx_http_postponed_request_t     *next;
+};
+
+
+typedef struct ngx_http_posted_request_s  ngx_http_posted_request_t;
+
+struct ngx_http_posted_request_s {
+    ngx_http_request_t               *request;
+    ngx_http_posted_request_t        *next;
+};
+
+
+typedef ngx_int_t (*ngx_http_handler_pt)(ngx_http_request_t *r);
+typedef void (*ngx_http_event_handler_pt)(ngx_http_request_t *r);
+
+
+struct ngx_http_request_s {
+    uint32_t                          signature;         /* "HTTP" */
+
+    ngx_connection_t                 *connection;
+
+    void                            **ctx;
+    void                            **main_conf;
+    void                            **srv_conf;
+    void                            **loc_conf;
+
+    ngx_http_event_handler_pt         read_event_handler;
+    ngx_http_event_handler_pt         write_event_handler;
+
+#if (NGX_HTTP_CACHE)
+    ngx_http_cache_t                 *cache;
+#endif
+
+    ngx_http_upstream_t              *upstream;
+    ngx_array_t                      *upstream_states;
+                                         /* of ngx_http_upstream_state_t */
+
+    ngx_pool_t                       *pool;
+    ngx_buf_t                        *header_in;
+
+    ngx_http_headers_in_t             headers_in;
+    ngx_http_headers_out_t            headers_out;
+
+    ngx_http_request_body_t          *request_body;
+
+    time_t                            lingering_time;
+    time_t                            start_sec;
+    ngx_msec_t                        start_msec;
+
+    ngx_uint_t                        method;
+    ngx_uint_t                        http_version;
+
+    ngx_str_t                         request_line;
+    ngx_str_t                         uri;
+    ngx_str_t                         args;
+    ngx_str_t                         exten;
+    ngx_str_t                         unparsed_uri;
+
+    ngx_str_t                         method_name;
+    ngx_str_t                         http_protocol;
+
+    ngx_chain_t                      *out;
+    ngx_http_request_t               *main;
+    ngx_http_request_t               *parent;
+    ngx_http_postponed_request_t     *postponed;
+    ngx_http_post_subrequest_t       *post_subrequest;
+    ngx_http_posted_request_t        *posted_requests;
+
+    ngx_int_t                         phase_handler;
+    ngx_http_handler_pt               content_handler;
+    ngx_uint_t                        access_code;
+
+    ngx_http_variable_value_t        *variables;
+
+#if (NGX_PCRE)
+    ngx_uint_t                        ncaptures;
+    int                              *captures;
+    u_char                           *captures_data;
+#endif
+
+    size_t                            limit_rate;
+    size_t                            limit_rate_after;
+
+    /* used to learn the Apache compatible response length without a header */
+    size_t                            header_size;
+
+    off_t                             request_length;
+
+    ngx_uint_t                        err_status;
+
+    ngx_http_connection_t            *http_connection;
+#if (NGX_HTTP_SPDY)
+    ngx_http_spdy_stream_t           *spdy_stream;
+#endif
+
+    ngx_http_log_handler_pt           log_handler;
+
+    ngx_http_cleanup_t               *cleanup;
+
+    unsigned                          subrequests:8;
+    unsigned                          count:8;
+    unsigned                          blocked:8;
+
+    unsigned                          aio:1;
+
+    unsigned                          http_state:4;
+
+    /* URI with "/." and on Win32 with "//" */
+    unsigned                          complex_uri:1;
+
+    /* URI with "%" */
+    unsigned                          quoted_uri:1;
+
+    /* URI with "+" */
+    unsigned                          plus_in_uri:1;
+
+    /* URI with " " */
+    unsigned                          space_in_uri:1;
+
+    unsigned                          invalid_header:1;
+
+    unsigned                          add_uri_to_alias:1;
+    unsigned                          valid_location:1;
+    unsigned                          valid_unparsed_uri:1;
+    unsigned                          uri_changed:1;
+    unsigned                          uri_changes:4;
+
+    unsigned                          request_body_in_single_buf:1;
+    unsigned                          request_body_in_file_only:1;
+    unsigned                          request_body_in_persistent_file:1;
+    unsigned                          request_body_in_clean_file:1;
+    unsigned                          request_body_file_group_access:1;
+    unsigned                          request_body_file_log_level:3;
+
+    unsigned                          subrequest_in_memory:1;
+    unsigned                          waited:1;
+
+#if (NGX_HTTP_CACHE)
+    unsigned                          cached:1;
+#endif
+
+#if (NGX_HTTP_GZIP)
+    unsigned                          gzip_tested:1;
+    unsigned                          gzip_ok:1;
+    unsigned                          gzip_vary:1;
+#endif
+
+    unsigned                          proxy:1;
+    unsigned                          bypass_cache:1;
+    unsigned                          no_cache:1;
+
+    /*
+     * instead of using the request context data in
+     * ngx_http_limit_conn_module and ngx_http_limit_req_module
+     * we use the single bits in the request structure
+     */
+    unsigned                          limit_conn_set:1;
+    unsigned                          limit_req_set:1;
+
+#if 0
+    unsigned                          cacheable:1;
+#endif
+
+    unsigned                          pipeline:1;
+    unsigned                          chunked:1;
+    unsigned                          header_only:1;
+    unsigned                          keepalive:1;
+    unsigned                          lingering_close:1;
+    unsigned                          discard_body:1;
+    unsigned                          internal:1;
+    unsigned                          error_page:1;
+    unsigned                          filter_finalize:1;
+    unsigned                          post_action:1;
+    unsigned                          request_complete:1;
+    unsigned                          request_output:1;
+    unsigned                          header_sent:1;
+    unsigned                          expect_tested:1;
+    unsigned                          root_tested:1;
+    unsigned                          done:1;
+    unsigned                          logged:1;
+
+    unsigned                          buffered:4;
+
+    unsigned                          main_filter_need_in_memory:1;
+    unsigned                          filter_need_in_memory:1;
+    unsigned                          filter_need_temporary:1;
+    unsigned                          allow_ranges:1;
+    unsigned                          single_range:1;
+
+#if (NGX_STAT_STUB)
+    unsigned                          stat_reading:1;
+    unsigned                          stat_writing:1;
+#endif
+
+    /* used to parse HTTP headers */
+
+    ngx_uint_t                        state;
+
+    ngx_uint_t                        header_hash;
+    ngx_uint_t                        lowcase_index;
+    u_char                            lowcase_header[NGX_HTTP_LC_HEADER_LEN];
+
+    u_char                           *header_name_start;
+    u_char                           *header_name_end;
+    u_char                           *header_start;
+    u_char                           *header_end;
+
+    /*
+     * a memory that can be reused after parsing a request line
+     * via ngx_http_ephemeral_t
+     */
+
+    u_char                           *uri_start;
+    u_char                           *uri_end;
+    u_char                           *uri_ext;
+    u_char                           *args_start;
+    u_char                           *request_start;
+    u_char                           *request_end;
+    u_char                           *method_end;
+    u_char                           *schema_start;
+    u_char                           *schema_end;
+    u_char                           *host_start;
+    u_char                           *host_end;
+    u_char                           *port_start;
+    u_char                           *port_end;
+
+    unsigned                          http_minor:16;
+    unsigned                          http_major:16;
+};
+
+
+typedef struct {
+    ngx_http_posted_request_t         terminal_posted_request;
+#if (NGX_HAVE_AIO_SENDFILE)
+    u_char                            aio_preload;
+#endif
+} ngx_http_ephemeral_t;
+
+
+extern ngx_http_header_t       ngx_http_headers_in[];
+extern ngx_http_header_out_t   ngx_http_headers_out[];
+
+
+#define ngx_http_set_connection_log(c, l)                                     \
+                                                                              \
+    c->log->file = l->file;                                                   \
+    c->log->next = l->next;                                                   \
+    c->log->writer = l->writer;                                               \
+    c->log->wdata = l->wdata;                                                 \
+    if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {                    \
+        c->log->log_level = l->log_level;                                     \
+    }
+
+
+#endif /* _NGX_HTTP_REQUEST_H_INCLUDED_ */
