Merge branch 'nginx' (nginx-1.13.1).

Change-Id: Id9f0a292d34c1e8e50bfee06f28729e8c7ae608f
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..3650a92
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,1472 @@
+# Copyright (C) 2015-2017 Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+licenses(["notice"])  # BSD license
+
+exports_files(["LICENSE"])
+
+load(":build.bzl", "nginx_copts")
+load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_deb", "pkg_tar")
+
+package(
+    default_visibility = [
+        "//visibility:public",
+    ],
+)
+
+config_setting(
+    name = "debug",
+    values = {
+        "compilation_mode": "dbg",
+    },
+)
+
+config_setting(
+    name = "darwin",
+    values = {
+        "cpu": "darwin",
+    },
+)
+
+config_setting(
+    name = "freebsd",
+    values = {
+        "cpu": "freebsd",
+    },
+)
+
+filegroup(
+    name = "config_includes",
+    srcs = [
+        "conf/fastcgi_params",
+        "conf/koi-utf",
+        "conf/koi-win",
+        "conf/mime.types",
+        "conf/scgi_params",
+        "conf/uwsgi_params",
+        "conf/win-utf",
+    ],
+)
+
+filegroup(
+    name = "html_files",
+    srcs = [
+        "docs/html/50x.html",
+        "docs/html/index.html",
+    ],
+)
+
+filegroup(
+    name = "man_sources",
+    srcs = [
+        "docs/man/nginx.8",
+    ],
+)
+
+genrule(
+    name = "configure",
+    srcs = [
+        "auto/cc/clang",
+        "auto/cc/conf",
+        "auto/cc/gcc",
+        "auto/cc/name",
+        "auto/configure",
+        "auto/define",
+        "auto/endianness",
+        "auto/feature",
+        "auto/have",
+        "auto/have_headers",
+        "auto/headers",
+        "auto/include",
+        "auto/init",
+        "auto/install",
+        "auto/lib/conf",
+        "auto/lib/make",
+        "auto/make",
+        "auto/module",
+        "auto/modules",
+        "auto/nohave",
+        "auto/options",
+        "auto/os/conf",
+        "auto/sources",
+        "auto/stubs",
+        "auto/summary",
+        "auto/threads",
+        "auto/types/sizeof",
+        "auto/types/typedef",
+        "auto/types/uintptr_t",
+        "auto/types/value",
+        "auto/unix",
+    ] + select({
+        ":darwin": [
+            "auto/os/darwin",
+        ],
+        ":freebsd": [
+            "auto/os/freebsd",
+        ],
+        "//conditions:default": [
+            "auto/os/linux",
+        ],
+    }),
+    outs = [
+        "bazel-objs/autoconf.err",
+        "bazel-objs/autoconf.log",
+        "bazel-objs/ngx_auto_config.h",
+        "bazel-objs/ngx_auto_headers.h",
+    ],
+    cmd = "$(location auto/configure)" +
+          " --builddir=\"$(@D)/bazel-objs\"" +
+          " --with-cc=\"$(CC)\"" +
+          " --with-cc-opt=\"$(CC_FLAGS)\"" +
+          " --prefix=/etc/nginx" +
+          " --conf-path=/etc/nginx/nginx.conf" +
+          " --error-log-path=/var/log/nginx/error.log" +
+          " --pid-path=/var/run/nginx.pid" +
+          " --lock-path=/var/run/nginx.lock" +
+          " --user=nginx" +
+          " --group=nginx" +
+          " --http-log-path=/var/log/nginx/access.log" +
+          " --http-client-body-temp-path=/var/cache/nginx/client_temp" +
+          " --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp" +
+          " --http-proxy-temp-path=/var/cache/nginx/proxy_temp" +
+          " --http-scgi-temp-path=/var/cache/nginx/scgi_temp" +
+          " --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp" +
+          " --without-http" +
+          " --without-http-cache" +
+          " --without-http_auth_basic_module" +
+          " --without-http_upstream_zone_module" +
+          " 2>&1 >$(@D)/bazel-objs/autoconf.log",
+    tools = [
+        "//tools/defaults:crosstool",
+    ],
+    visibility = [
+        "//visibility:private",
+    ],
+)
+
+cc_library(
+    name = "core",
+    srcs = [
+        "bazel-objs/ngx_auto_config.h",
+        "bazel-objs/ngx_auto_headers.h",
+        "src/core/nginx.c",
+        "src/core/ngx_array.c",
+        "src/core/ngx_array.h",
+        "src/core/ngx_buf.c",
+        "src/core/ngx_buf.h",
+        "src/core/ngx_conf_file.c",
+        "src/core/ngx_conf_file.h",
+        "src/core/ngx_connection.c",
+        "src/core/ngx_connection.h",
+        "src/core/ngx_cpuinfo.c",
+        "src/core/ngx_crc32.c",
+        "src/core/ngx_crc32.h",
+        "src/core/ngx_crypt.c",
+        "src/core/ngx_cycle.c",
+        "src/core/ngx_cycle.h",
+        "src/core/ngx_file.c",
+        "src/core/ngx_file.h",
+        "src/core/ngx_hash.c",
+        "src/core/ngx_hash.h",
+        "src/core/ngx_inet.c",
+        "src/core/ngx_inet.h",
+        "src/core/ngx_list.c",
+        "src/core/ngx_list.h",
+        "src/core/ngx_log.c",
+        "src/core/ngx_log.h",
+        "src/core/ngx_module.c",
+        "src/core/ngx_module.h",
+        "src/core/ngx_murmurhash.c",
+        "src/core/ngx_murmurhash.h",
+        "src/core/ngx_open_file_cache.c",
+        "src/core/ngx_open_file_cache.h",
+        "src/core/ngx_output_chain.c",
+        "src/core/ngx_palloc.c",
+        "src/core/ngx_palloc.h",
+        "src/core/ngx_parse.c",
+        "src/core/ngx_parse.h",
+        "src/core/ngx_parse_time.c",
+        "src/core/ngx_parse_time.h",
+        "src/core/ngx_proxy_protocol.c",
+        "src/core/ngx_proxy_protocol.h",
+        "src/core/ngx_queue.c",
+        "src/core/ngx_queue.h",
+        "src/core/ngx_radix_tree.c",
+        "src/core/ngx_radix_tree.h",
+        "src/core/ngx_rbtree.c",
+        "src/core/ngx_rbtree.h",
+        "src/core/ngx_regex.c",
+        "src/core/ngx_regex.h",
+        "src/core/ngx_resolver.c",
+        "src/core/ngx_resolver.h",
+        "src/core/ngx_rwlock.c",
+        "src/core/ngx_rwlock.h",
+        "src/core/ngx_shmtx.c",
+        "src/core/ngx_shmtx.h",
+        "src/core/ngx_slab.c",
+        "src/core/ngx_slab.h",
+        "src/core/ngx_spinlock.c",
+        "src/core/ngx_string.c",
+        "src/core/ngx_string.h",
+        "src/core/ngx_syslog.c",
+        "src/core/ngx_syslog.h",
+        "src/core/ngx_thread_pool.c",
+        "src/core/ngx_thread_pool.h",
+        "src/core/ngx_times.c",
+        "src/core/ngx_times.h",
+        "src/event/modules/ngx_poll_module.c",
+        "src/event/modules/ngx_select_module.c",
+        "src/event/ngx_event.c",
+        "src/event/ngx_event_accept.c",
+        "src/event/ngx_event_connect.c",
+        "src/event/ngx_event_openssl.c",
+        "src/event/ngx_event_openssl.h",
+        "src/event/ngx_event_openssl_stapling.c",
+        "src/event/ngx_event_pipe.c",
+        "src/event/ngx_event_posted.c",
+        "src/event/ngx_event_posted.h",
+        "src/event/ngx_event_timer.c",
+        "src/event/ngx_event_timer.h",
+        "src/os/unix/ngx_alloc.c",
+        "src/os/unix/ngx_alloc.h",
+        "src/os/unix/ngx_atomic.h",
+        "src/os/unix/ngx_channel.c",
+        "src/os/unix/ngx_channel.h",
+        "src/os/unix/ngx_daemon.c",
+        "src/os/unix/ngx_dlopen.c",
+        "src/os/unix/ngx_dlopen.h",
+        "src/os/unix/ngx_errno.c",
+        "src/os/unix/ngx_errno.h",
+        "src/os/unix/ngx_files.c",
+        "src/os/unix/ngx_files.h",
+        "src/os/unix/ngx_os.h",
+        "src/os/unix/ngx_posix_init.c",
+        "src/os/unix/ngx_process.c",
+        "src/os/unix/ngx_process.h",
+        "src/os/unix/ngx_process_cycle.c",
+        "src/os/unix/ngx_process_cycle.h",
+        "src/os/unix/ngx_readv_chain.c",
+        "src/os/unix/ngx_recv.c",
+        "src/os/unix/ngx_send.c",
+        "src/os/unix/ngx_setaffinity.h",
+        "src/os/unix/ngx_setproctitle.c",
+        "src/os/unix/ngx_setproctitle.h",
+        "src/os/unix/ngx_shmem.c",
+        "src/os/unix/ngx_shmem.h",
+        "src/os/unix/ngx_socket.c",
+        "src/os/unix/ngx_socket.h",
+        "src/os/unix/ngx_thread.h",
+        "src/os/unix/ngx_thread_cond.c",
+        "src/os/unix/ngx_thread_id.c",
+        "src/os/unix/ngx_thread_mutex.c",
+        "src/os/unix/ngx_time.c",
+        "src/os/unix/ngx_time.h",
+        "src/os/unix/ngx_udp_recv.c",
+        "src/os/unix/ngx_udp_send.c",
+        "src/os/unix/ngx_udp_sendmsg_chain.c",
+        "src/os/unix/ngx_user.c",
+        "src/os/unix/ngx_user.h",
+        "src/os/unix/ngx_writev_chain.c",
+    ] + select({
+        ":darwin": [
+            "src/event/modules/ngx_kqueue_module.c",
+            "src/os/unix/ngx_darwin.h",
+            "src/os/unix/ngx_darwin_config.h",
+            "src/os/unix/ngx_darwin_init.c",
+            "src/os/unix/ngx_darwin_sendfile_chain.c",
+        ],
+        ":freebsd": [
+            "src/event/modules/ngx_kqueue_module.c",
+            "src/os/unix/ngx_freebsd.h",
+            "src/os/unix/ngx_freebsd_config.h",
+            "src/os/unix/ngx_freebsd_init.c",
+            "src/os/unix/ngx_freebsd_sendfile_chain.c",
+            "src/os/unix/ngx_setaffinity.c",
+        ],
+        "//conditions:default": [
+            "src/event/modules/ngx_epoll_module.c",
+            "src/os/unix/ngx_linux.h",
+            "src/os/unix/ngx_linux_config.h",
+            "src/os/unix/ngx_linux_init.c",
+            "src/os/unix/ngx_linux_sendfile_chain.c",
+            "src/os/unix/ngx_setaffinity.c",
+        ],
+    }),
+    hdrs = [
+        "src/core/nginx.h",
+        "src/core/ngx_config.h",
+        "src/core/ngx_core.h",
+        "src/core/ngx_crypt.h",
+        "src/core/ngx_md5.h",
+        "src/core/ngx_sha1.h",
+        "src/event/ngx_event.h",
+        "src/event/ngx_event_connect.h",
+        "src/event/ngx_event_pipe.h",
+        "src/ngx_modules.h",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_BAZEL",
+        "NGX_COMPAT",
+        "NGX_CRYPT",
+        "NGX_HAVE_POLL",
+        "NGX_HAVE_SELECT",
+        "NGX_STAT_STUB",
+        "NGX_THREADS",
+        # BoringSSL
+        "NGX_HAVE_OPENSSL_MD5_H",
+        "NGX_HAVE_OPENSSL_SHA1_H",
+        "NGX_OPENSSL",
+        "NGX_SSL",
+        # PCRE
+        "NGX_HAVE_PCRE_JIT",
+        "NGX_PCRE",
+    ] + select({
+        ":debug": [
+            "NGX_DEBUG",
+        ],
+        "//conditions:default": [],
+    }),
+    includes = [
+        "bazel-objs",
+        "src",
+        "src/core",
+        "src/event",
+        "src/os/unix",
+    ],
+    linkopts = select({
+        ":darwin": [],
+        ":freebsd": [
+            "-lcrypt",
+            "-lpthread",
+        ],
+        "//conditions:default": [
+            "-lcrypt",
+            "-ldl",
+            "-lpthread",
+        ],
+    }),
+    deps = [
+        "//external:boringssl_crypto",
+        "//external:boringssl_ssl",
+        "//external:pcre",
+    ],
+)
+
+cc_library(
+    name = "http",
+    srcs = [
+        "src/http/modules/ngx_http_chunked_filter_module.c",
+        "src/http/modules/ngx_http_headers_filter_module.c",
+        "src/http/modules/ngx_http_index_module.c",
+        "src/http/modules/ngx_http_log_module.c",
+        "src/http/modules/ngx_http_not_modified_filter_module.c",
+        "src/http/modules/ngx_http_range_filter_module.c",
+        "src/http/modules/ngx_http_ssl_module.c",
+        "src/http/modules/ngx_http_ssl_module.h",
+        "src/http/modules/ngx_http_static_module.c",
+        "src/http/modules/ngx_http_upstream_zone_module.c",
+        "src/http/ngx_http.c",
+        "src/http/ngx_http_cache.h",
+        "src/http/ngx_http_config.h",
+        "src/http/ngx_http_copy_filter_module.c",
+        "src/http/ngx_http_core_module.c",
+        "src/http/ngx_http_core_module.h",
+        "src/http/ngx_http_file_cache.c",
+        "src/http/ngx_http_header_filter_module.c",
+        "src/http/ngx_http_parse.c",
+        "src/http/ngx_http_request.c",
+        "src/http/ngx_http_request.h",
+        "src/http/ngx_http_request_body.c",
+        "src/http/ngx_http_script.c",
+        "src/http/ngx_http_script.h",
+        "src/http/ngx_http_special_response.c",
+        "src/http/ngx_http_upstream.c",
+        "src/http/ngx_http_upstream.h",
+        "src/http/ngx_http_upstream_round_robin.c",
+        "src/http/ngx_http_upstream_round_robin.h",
+        "src/http/ngx_http_variables.c",
+        "src/http/ngx_http_variables.h",
+        "src/http/ngx_http_write_filter_module.c",
+        "src/http/v2/ngx_http_v2.c",
+        "src/http/v2/ngx_http_v2.h",
+        "src/http/v2/ngx_http_v2_filter_module.c",
+        "src/http/v2/ngx_http_v2_huff_decode.c",
+        "src/http/v2/ngx_http_v2_huff_encode.c",
+        "src/http/v2/ngx_http_v2_module.c",
+        "src/http/v2/ngx_http_v2_module.h",
+        "src/http/v2/ngx_http_v2_table.c",
+    ],
+    hdrs = [
+        "src/http/ngx_http.h",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP",
+        "NGX_HTTP_CACHE",
+        "NGX_HTTP_GZIP",
+        "NGX_HTTP_SSL",
+        "NGX_HTTP_UPSTREAM_ZONE",
+        "NGX_HTTP_V2",
+        "NGX_ZLIB",
+    ],
+    includes = [
+        "src/http",
+        "src/http/modules",
+        "src/http/v2",
+    ],
+    deps = [
+        ":core",
+        "//external:zlib",
+    ],
+)
+
+cc_library(
+    name = "http_access",
+    srcs = [
+        "src/http/modules/ngx_http_access_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_ACCESS",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_addition",
+    srcs = [
+        "src/http/modules/ngx_http_addition_filter_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_ADDITION",
+    ],
+    deps = [
+        ":core",
+        ":http",
+        ":http_postpone",
+    ],
+)
+
+cc_library(
+    name = "http_auth_basic",
+    srcs = [
+        "src/http/modules/ngx_http_auth_basic_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_AUTH_BASIC",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_auth_request",
+    srcs = [
+        "src/http/modules/ngx_http_auth_request_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_AUTH_REQUEST",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_autoindex",
+    srcs = [
+        "src/http/modules/ngx_http_autoindex_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_AUTOINDEX",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_browser",
+    srcs = [
+        "src/http/modules/ngx_http_browser_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_BROWSER",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_charset",
+    srcs = [
+        "src/http/modules/ngx_http_charset_filter_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_CHARSET",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_dav",
+    srcs = [
+        "src/http/modules/ngx_http_dav_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_DAV",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_empty_gif",
+    srcs = [
+        "src/http/modules/ngx_http_empty_gif_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_EMPTY_GIF",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_fastcgi",
+    srcs = [
+        "src/http/modules/ngx_http_fastcgi_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_FASTCGI",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_flv",
+    srcs = [
+        "src/http/modules/ngx_http_flv_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_FLV",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_geo",
+    srcs = [
+        "src/http/modules/ngx_http_geo_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_GEO",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_gunzip",
+    srcs = [
+        "src/http/modules/ngx_http_gunzip_filter_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_GUNZIP",
+    ],
+    deps = [
+        ":core",
+        ":http",
+        "//external:zlib",
+    ],
+)
+
+cc_library(
+    name = "http_gzip_filter",
+    srcs = [
+        "src/http/modules/ngx_http_gzip_filter_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_GZIP_FILTER",
+    ],
+    deps = [
+        ":core",
+        ":http",
+        "//external:zlib",
+    ],
+)
+
+cc_library(
+    name = "http_gzip_static",
+    srcs = [
+        "src/http/modules/ngx_http_gzip_static_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_GZIP_STATIC",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_limit_conn",
+    srcs = [
+        "src/http/modules/ngx_http_limit_conn_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_LIMIT_CONN",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_limit_req",
+    srcs = [
+        "src/http/modules/ngx_http_limit_req_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_LIMIT_REQ",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_map",
+    srcs = [
+        "src/http/modules/ngx_http_map_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_MAP",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_memcached",
+    srcs = [
+        "src/http/modules/ngx_http_memcached_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_MEMCACHED",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_mp4",
+    srcs = [
+        "src/http/modules/ngx_http_mp4_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_MP4",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_postpone",
+    srcs = [
+        "src/http/ngx_http_postpone_filter_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_POSTPONE",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_proxy",
+    srcs = [
+        "src/http/modules/ngx_http_proxy_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_PROXY",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_random_index",
+    srcs = [
+        "src/http/modules/ngx_http_random_index_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_RANDOM_INDEX",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_realip",
+    srcs = [
+        "src/http/modules/ngx_http_realip_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_REALIP",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_referer",
+    srcs = [
+        "src/http/modules/ngx_http_referer_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_REFERER",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_rewrite",
+    srcs = [
+        "src/http/modules/ngx_http_rewrite_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_REWRITE",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_scgi",
+    srcs = [
+        "src/http/modules/ngx_http_scgi_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_SCGI",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_secure_link",
+    srcs = [
+        "src/http/modules/ngx_http_secure_link_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_SECURE_LINK",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_slice",
+    srcs = [
+        "src/http/modules/ngx_http_slice_filter_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_SLICE",
+    ],
+    deps = [
+        ":core",
+        ":http",
+        ":http_postpone",
+    ],
+)
+
+cc_library(
+    name = "http_split_clients",
+    srcs = [
+        "src/http/modules/ngx_http_split_clients_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_SPLIT_CLIENTS",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_ssi",
+    srcs = [
+        "src/http/modules/ngx_http_ssi_filter_module.c",
+        "src/http/modules/ngx_http_ssi_filter_module.h",
+    ],
+    copts = nginx_copts + [
+        "-Wno-format-nonliteral",
+    ],
+    defines = [
+        "NGX_HTTP_SSI",
+    ],
+    deps = [
+        ":core",
+        ":http",
+        ":http_postpone",
+    ],
+)
+
+cc_library(
+    name = "http_stub_status",
+    srcs = [
+        "src/http/modules/ngx_http_stub_status_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_STUB_STATUS",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_sub",
+    srcs = [
+        "src/http/modules/ngx_http_sub_filter_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_SUB",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_upstream_hash",
+    srcs = [
+        "src/http/modules/ngx_http_upstream_hash_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_UPSTREAM_HASH",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_upstream_ip_hash",
+    srcs = [
+        "src/http/modules/ngx_http_upstream_ip_hash_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_UPSTREAM_IP_HASH",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_upstream_keepalive",
+    srcs = [
+        "src/http/modules/ngx_http_upstream_keepalive_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_UPSTREAM_KEEPALIVE",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_upstream_least_conn",
+    srcs = [
+        "src/http/modules/ngx_http_upstream_least_conn_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_UPSTREAM_LEAST_CONN",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_userid",
+    srcs = [
+        "src/http/modules/ngx_http_userid_filter_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_USERID",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "http_uwsgi",
+    srcs = [
+        "src/http/modules/ngx_http_uwsgi_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_UWSGI",
+    ],
+    deps = [
+        ":core",
+        ":http",
+    ],
+)
+
+cc_library(
+    name = "mail",
+    srcs = [
+        "src/mail/ngx_mail.c",
+        "src/mail/ngx_mail_auth_http_module.c",
+        "src/mail/ngx_mail_core_module.c",
+        "src/mail/ngx_mail_handler.c",
+        "src/mail/ngx_mail_proxy_module.c",
+        "src/mail/ngx_mail_ssl_module.c",
+        "src/mail/ngx_mail_ssl_module.h",
+    ],
+    hdrs = [
+        "src/mail/ngx_mail.h",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_MAIL",
+        "NGX_MAIL_SSL",
+    ],
+    includes = [
+        "src/mail",
+    ],
+    deps = [
+        ":core",
+    ],
+)
+
+cc_library(
+    name = "mail_parse",
+    srcs = [
+        "src/mail/ngx_mail_parse.c",
+    ],
+    hdrs = [
+        "src/mail/ngx_mail_imap_module.h",
+        "src/mail/ngx_mail_pop3_module.h",
+        "src/mail/ngx_mail_smtp_module.h",
+    ],
+    copts = nginx_copts,
+    deps = [
+        ":core",
+        ":mail",
+    ],
+)
+
+cc_library(
+    name = "mail_imap",
+    srcs = [
+        "src/mail/ngx_mail_imap_handler.c",
+        "src/mail/ngx_mail_imap_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_MAIL_IMAP",
+    ],
+    deps = [
+        ":core",
+        ":mail",
+        ":mail_parse",
+    ],
+)
+
+cc_library(
+    name = "mail_pop3",
+    srcs = [
+        "src/mail/ngx_mail_pop3_handler.c",
+        "src/mail/ngx_mail_pop3_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_MAIL_POP3",
+    ],
+    deps = [
+        ":core",
+        ":mail",
+        ":mail_parse",
+    ],
+)
+
+cc_library(
+    name = "mail_smtp",
+    srcs = [
+        "src/mail/ngx_mail_smtp_handler.c",
+        "src/mail/ngx_mail_smtp_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_MAIL_SMTP",
+    ],
+    deps = [
+        ":core",
+        ":mail",
+        ":mail_parse",
+    ],
+)
+
+cc_library(
+    name = "stream",
+    srcs = [
+        "src/stream/ngx_stream.c",
+        "src/stream/ngx_stream_core_module.c",
+        "src/stream/ngx_stream_handler.c",
+        "src/stream/ngx_stream_log_module.c",
+        "src/stream/ngx_stream_proxy_module.c",
+        "src/stream/ngx_stream_script.c",
+        "src/stream/ngx_stream_script.h",
+        "src/stream/ngx_stream_ssl_module.c",
+        "src/stream/ngx_stream_ssl_module.h",
+        "src/stream/ngx_stream_upstream.c",
+        "src/stream/ngx_stream_upstream.h",
+        "src/stream/ngx_stream_upstream_round_robin.c",
+        "src/stream/ngx_stream_upstream_round_robin.h",
+        "src/stream/ngx_stream_upstream_zone_module.c",
+        "src/stream/ngx_stream_variables.c",
+        "src/stream/ngx_stream_variables.h",
+        "src/stream/ngx_stream_write_filter_module.c",
+    ],
+    hdrs = [
+        "src/stream/ngx_stream.h",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_STREAM",
+        "NGX_STREAM_SSL",
+        "NGX_STREAM_UPSTREAM_ZONE",
+        "NGX_ZLIB",
+    ],
+    includes = [
+        "src/stream",
+    ],
+    deps = [
+        ":core",
+        "//external:zlib",
+    ],
+)
+
+cc_library(
+    name = "stream_access",
+    srcs = [
+        "src/stream/ngx_stream_access_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_STREAM_ACCESS",
+    ],
+    deps = [
+        ":core",
+        ":stream",
+    ],
+)
+
+cc_library(
+    name = "stream_geo",
+    srcs = [
+        "src/stream/ngx_stream_geo_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_STREAM_GEO",
+    ],
+    deps = [
+        ":core",
+        ":stream",
+    ],
+)
+
+cc_library(
+    name = "stream_limit_conn",
+    srcs = [
+        "src/stream/ngx_stream_limit_conn_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_STREAM_LIMIT_CONN",
+    ],
+    deps = [
+        ":core",
+        ":stream",
+    ],
+)
+
+cc_library(
+    name = "stream_map",
+    srcs = [
+        "src/stream/ngx_stream_map_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_STREAM_MAP",
+    ],
+    deps = [
+        ":core",
+        ":stream",
+    ],
+)
+
+cc_library(
+    name = "stream_realip",
+    srcs = [
+        "src/stream/ngx_stream_realip_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_STREAM_REALIP",
+    ],
+    deps = [
+        ":core",
+        ":stream",
+    ],
+)
+
+cc_library(
+    name = "stream_return",
+    srcs = [
+        "src/stream/ngx_stream_return_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_STREAM_RETURN",
+    ],
+    deps = [
+        ":core",
+        ":stream",
+    ],
+)
+
+cc_library(
+    name = "stream_split_clients",
+    srcs = [
+        "src/stream/ngx_stream_split_clients_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_STREAM_SPLIT_CLIENTS",
+    ],
+    deps = [
+        ":core",
+        ":stream",
+    ],
+)
+
+cc_library(
+    name = "stream_ssl_preread",
+    srcs = [
+        "src/stream/ngx_stream_ssl_preread_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_STREAM_SSL_PREREAD",
+    ],
+    deps = [
+        ":core",
+        ":stream",
+    ],
+)
+
+cc_library(
+    name = "stream_upstream_hash",
+    srcs = [
+        "src/stream/ngx_stream_upstream_hash_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_STREAM_UPSTREAM_HASH",
+    ],
+    deps = [
+        ":core",
+        ":stream",
+    ],
+)
+
+cc_library(
+    name = "stream_upstream_least_conn",
+    srcs = [
+        "src/stream/ngx_stream_upstream_least_conn_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_STREAM_UPSTREAM_LEAST_CONN",
+    ],
+    deps = [
+        ":core",
+        ":stream",
+    ],
+)
+
+filegroup(
+    name = "modules",
+    srcs = [
+        "src/ngx_modules.c",
+    ],
+)
+
+cc_binary(
+    name = "nginx",
+    srcs = [
+        ":modules",
+    ],
+    copts = nginx_copts,
+    linkstatic = 1,
+    deps = [
+        ":core",
+        ":http",
+        ":http_access",
+        ":http_addition",
+        ":http_auth_basic",
+        ":http_auth_request",
+        ":http_autoindex",
+        ":http_browser",
+        ":http_charset",
+        ":http_dav",
+        ":http_empty_gif",
+        ":http_fastcgi",
+        ":http_flv",
+        ":http_geo",
+        ":http_gunzip",
+        ":http_gzip_filter",
+        ":http_gzip_static",
+        ":http_limit_conn",
+        ":http_limit_req",
+        ":http_map",
+        ":http_memcached",
+        ":http_mp4",
+        ":http_proxy",
+        ":http_random_index",
+        ":http_realip",
+        ":http_referer",
+        ":http_rewrite",
+        ":http_scgi",
+        ":http_secure_link",
+        ":http_slice",
+        ":http_split_clients",
+        ":http_ssi",
+        ":http_stub_status",
+        ":http_sub",
+        ":http_upstream_hash",
+        ":http_upstream_ip_hash",
+        ":http_upstream_keepalive",
+        ":http_upstream_least_conn",
+        ":http_userid",
+        ":http_uwsgi",
+        ":mail",
+        ":mail_imap",
+        ":mail_pop3",
+        ":mail_smtp",
+        ":stream",
+        ":stream_access",
+        ":stream_geo",
+        ":stream_limit_conn",
+        ":stream_map",
+        ":stream_realip",
+        ":stream_return",
+        ":stream_split_clients",
+        ":stream_ssl_preread",
+        ":stream_upstream_hash",
+        ":stream_upstream_least_conn",
+        "@ngx_brotli//:http_brotli_filter",
+        "@ngx_brotli//:http_brotli_static",
+    ],
+)
+
+genrule(
+    name = "nginx-google-copyright",
+    srcs = [
+        ":LICENSE",
+        "@boringssl//:LICENSE",
+        "@nginx_pcre//:LICENCE",
+        "@nginx_zlib//:README",
+        "@org_brotli//:LICENSE",
+    ],
+    outs = [
+        "usr/share/doc/nginx-google/copyright",
+    ],
+    cmd = "cat $(location :LICENSE) > $(@);" +
+          "echo \"\n\" >> $(@);" +
+          "echo \"This NGINX binary is statically linked against:\" >> $(@);" +
+          "echo \"BoringSSL, Brotli, PCRE & zlib.\" >> $(@);" +
+          "echo \"\n\nBoringSSL license:\n==================\n\" >> $(@);" +
+          "cat $(location @boringssl//:LICENSE) >> $(@);" +
+          "echo \"\n\nBrotli license:\n===============\n\" >> $(@);" +
+          "cat $(location @org_brotli//:LICENSE) >> $(@);" +
+          "echo \"\n\nPCRE license:\n=============\n\" >> $(@);" +
+          "cat $(location @nginx_pcre//:LICENCE) >> $(@);" +
+          "echo \"\n\nzlib license:\n=============\n\" >> $(@);" +
+          "cat $(location @nginx_zlib//:README) | grep -A99 Copyright >> $(@)",
+)
+
+pkg_tar(
+    name = "nginx-google-sbin",
+    files = [
+        ":nginx",
+    ],
+    mode = "0755",
+    package_dir = "/usr/sbin",
+    strip_prefix = "/",
+)
+
+pkg_tar(
+    name = "nginx-google-data",
+    extension = "tar.gz",
+    files = [
+        "usr/share/doc/nginx-google/copyright",
+    ],
+    mode = "0644",
+    strip_prefix = "/",
+    deps = [
+        ":nginx-google-sbin",
+        "@nginx_pkgoss//:debian_overlay",
+    ],
+)
+
+pkg_deb(
+    name = "nginx-google",
+    architecture = "amd64",
+    conflicts = [
+        "nginx",
+        "nginx-common",
+        "endpoints-server-proxy",
+    ],
+    data = ":nginx-google-data.tar.gz",
+    depends = [
+        "libc6 (>= 2.10)",
+        "lsb-base",
+        "adduser",
+    ],
+    description = "high-performance web server and reverse proxy",
+    homepage = "https://nginx.googlesource.com",
+    maintainer = "Piotr Sikora <piotrsikora@google.com>",
+    package = "nginx-google",
+    postinst = "@nginx_pkgoss//:debian_postinst",
+    postrm = "@nginx_pkgoss//:debian_postrm",
+    preinst = "@nginx_pkgoss//:debian_preinst",
+    prerm = "@nginx_pkgoss//:debian_prerm",
+    section = "httpd",
+    version = "1.13.1",
+)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..342f125
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2002-2017 Igor Sysoev
+ * Copyright (C) 2011-2017 Nginx, Inc.
+ * Copyright (C) 2015-2017 Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..cfd05ea
--- /dev/null
+++ b/README.md
@@ -0,0 +1,57 @@
+## About
+
+[NGINX] + [BoringSSL] + [Brotli].
+
+## Building
+
+To build `nginx` binary with [Bazel]:
+
+    $ bazel build :nginx
+
+To build Debian package:
+
+    $ bazel build :nginx-google.deb
+
+## Contributing
+
+This repository is currently maintained by Google developers.
+
+Any code changes should be submitted to upstream
+[NGINX](https://nginx.org/en/docs/contributing_changes.html).
+
+## License
+
+    Copyright (C) 2002-2017 Igor Sysoev
+    Copyright (C) 2011-2017 Nginx, Inc.
+    Copyright (C) 2015-2017 Google Inc.
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+## Disclaimer
+
+This is not an official Google product.
+
+[NGINX]: https://nginx.org
+[BoringSSL]: https://boringssl.googlesource.com/boringssl
+[Brotli]: https://github.com/google/brotli
+[Bazel]: https://bazel.build
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..bfffb7d
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,33 @@
+# Copyright (C) 2015-2017 Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+workspace(name = "nginx")
+
+load(":build.bzl", "nginx_repositories")
+
+nginx_repositories(
+    bind = True,
+    nginx = "@//",
+    ngx_brotli = True,
+)
diff --git a/auto/cc/acc b/auto/cc/acc
index 64fa671..2b87710 100644
--- a/auto/cc/acc
+++ b/auto/cc/acc
@@ -8,7 +8,7 @@
 # C89 mode
 
 CFLAGS="$CFLAGS -Ae"
-CC_TEST_FLAGS="-Ae"
+CC_TEST_FLAGS="$CC_TEST_FLAGS -Ae"
 
 PCRE_OPT="$PCRE_OPT -Ae"
 ZLIB_OPT="$ZLIB_OPT -Ae"
diff --git a/auto/cc/clang b/auto/cc/clang
index 19bdaaa..a82aeb9 100644
--- a/auto/cc/clang
+++ b/auto/cc/clang
@@ -10,10 +10,10 @@
 
 echo " + clang version: $NGX_CLANG_VER"
 
-have=NGX_COMPILER value="\"clang $NGX_CLANG_VER\"" . auto/define
+have=NGX_COMPILER value="\"clang $NGX_CLANG_VER\"" . $NGX_AUTO/define
 
 
-CC_TEST_FLAGS="-pipe"
+CC_TEST_FLAGS="$CC_TEST_FLAGS -pipe"
 
 
 # optimizations
diff --git a/auto/cc/conf b/auto/cc/conf
index afbca62..5d6179f 100644
--- a/auto/cc/conf
+++ b/auto/cc/conf
@@ -34,12 +34,12 @@
 ngx_long_regex_cont=$ngx_regex_cont
 ngx_long_cont=$ngx_cont
 
-. auto/cc/name
+CC_TEST_FLAGS="$CFLAGS $NGX_CC_OPT"
+
+. $NGX_AUTO/cc/name
 
 if test -n "$CFLAGS"; then
 
-    CC_TEST_FLAGS="$CFLAGS $NGX_CC_OPT"
-
     case $NGX_CC_NAME in
 
         ccc)
@@ -84,61 +84,59 @@
             #     3.0.4, 3.1.1, 3.2.3, 3.3.2, 3.3.3, 3.3.4, 3.4.0, 3.4.2
             #     4.0.0, 4.0.1, 4.1.0
 
-            . auto/cc/gcc
+            . $NGX_AUTO/cc/gcc
         ;;
 
         clang)
             # Clang C compiler
 
-            . auto/cc/clang
+            . $NGX_AUTO/cc/clang
         ;;
 
         icc)
             # Intel C++ compiler 7.1, 8.0, 8.1
 
-            . auto/cc/icc
+            . $NGX_AUTO/cc/icc
         ;;
 
         sunc)
             # Sun C 5.7 Patch 117837-04 2005/05/11
 
-            . auto/cc/sunc
+            . $NGX_AUTO/cc/sunc
         ;;
 
         ccc)
             # Compaq C V6.5-207
 
-            . auto/cc/ccc
+            . $NGX_AUTO/cc/ccc
         ;;
 
         acc)
             # aCC: HP ANSI C++ B3910B A.03.55.02
 
-            . auto/cc/acc
+            . $NGX_AUTO/cc/acc
         ;;
 
         msvc*)
             # MSVC++ 6.0 SP2, MSVC++ Toolkit 2003
 
-            . auto/cc/msvc
+            . $NGX_AUTO/cc/msvc
         ;;
 
         owc)
             # Open Watcom C 1.0, 1.2
 
-            . auto/cc/owc
+            . $NGX_AUTO/cc/owc
         ;;
 
         bcc)
             # Borland C++ 5.5
 
-            . auto/cc/bcc
+            . $NGX_AUTO/cc/bcc
         ;;
 
     esac
 
-    CC_TEST_FLAGS="$CC_TEST_FLAGS $NGX_CC_OPT"
-
 fi
 
 CFLAGS="$CFLAGS $NGX_CC_OPT"
@@ -154,7 +152,7 @@
         ngx_feature_path=
         ngx_feature_libs=
         ngx_feature_test=
-        . auto/feature
+        . $NGX_AUTO/feature
 
         if [ $ngx_found = no ]; then
             echo $0: error: the invalid value in --with-ld-opt=\"$NGX_LD_OPT\"
@@ -171,7 +169,7 @@
     ngx_feature_path=
     ngx_feature_libs=-Wl,-E
     ngx_feature_test=
-    . auto/feature
+    . $NGX_AUTO/feature
 
     if [ $ngx_found = yes ]; then
         MAIN_LINK="-Wl,-E"
@@ -179,9 +177,9 @@
 
 
     if [ "$NGX_CC_NAME" = "sunc" ]; then
-        echo "checking for gcc builtin atomic operations ... disabled"
+        echo "checking for gcc builtin __sync operations ... disabled"
     else
-        ngx_feature="gcc builtin atomic operations"
+        ngx_feature="gcc builtin __sync operations"
         ngx_feature_name=NGX_HAVE_GCC_ATOMIC
         ngx_feature_run=yes
         ngx_feature_incs=
@@ -195,7 +193,24 @@
                           if (n != 2)
                               return 1;
                           __sync_synchronize();"
-        . auto/feature
+        . $NGX_AUTO/feature
+    fi
+
+
+    if [ "$NGX_CC_NAME" = "sunc" ]; then
+        echo "checking for gcc builtin __atomic operations ... disabled"
+    else
+        ngx_feature="gcc builtin __atomic operations"
+        ngx_feature_name=NGX_HAVE_GCC_ATOMIC_STORE_AND_LOAD
+        ngx_feature_run=yes
+        ngx_feature_incs=
+        ngx_feature_path=
+        ngx_feature_libs=
+        ngx_feature_test="long  n = 0;
+                          __atomic_store_n(&n, 1, __ATOMIC_RELEASE);
+                          if (__atomic_load_n(&n, __ATOMIC_ACQUIRE) != 1)
+                              return 1"
+        . $NGX_AUTO/feature
     fi
 
 
@@ -212,7 +227,7 @@
         ngx_feature_test="char  buf[30]; buf[0] = '0';
                           var(0, buf, \"%d\", 1);
                           if (buf[0] != '1') return 1"
-        . auto/feature
+        . $NGX_AUTO/feature
     fi
 
 
@@ -226,7 +241,7 @@
     ngx_feature_test="char  buf[30]; buf[0] = '0';
                       var(0, buf, \"%d\", 1);
                       if (buf[0] != '1') return 1"
-    . auto/feature
+    . $NGX_AUTO/feature
 
 
     ngx_feature="gcc builtin 64 bit byteswap"
@@ -236,7 +251,7 @@
     ngx_feature_path=
     ngx_feature_libs=
     ngx_feature_test="if (__builtin_bswap64(0)) return 1"
-    . auto/feature
+    . $NGX_AUTO/feature
 
 
 #    ngx_feature="inline"
@@ -246,7 +261,7 @@
 #    ngx_feature_path=
 #    ngx_feature_libs=
 #    ngx_feature_test=
-#    . auto/feature
+#    . $NGX_AUTO/feature
 #
 #    if [ $ngx_found = yes ]; then
 #    fi
diff --git a/auto/cc/gcc b/auto/cc/gcc
index a5c5c18..b750e1f 100644
--- a/auto/cc/gcc
+++ b/auto/cc/gcc
@@ -13,12 +13,12 @@
 
 echo " + gcc version: $NGX_GCC_VER"
 
-have=NGX_COMPILER value="\"gcc $NGX_GCC_VER\"" . auto/define
+have=NGX_COMPILER value="\"gcc $NGX_GCC_VER\"" . $NGX_AUTO/define
 
 
 # Solaris 7's /usr/ccs/bin/as does not support "-pipe"
 
-CC_TEST_FLAGS="-pipe"
+CC_TEST_FLAGS="$CC_TEST_FLAGS -pipe"
 
 ngx_feature="gcc -pipe switch"
 ngx_feature_name=
@@ -27,12 +27,12 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test=
-. auto/feature
-
-CC_TEST_FLAGS=
+. $NGX_AUTO/feature
 
 if [ $ngx_found = yes ]; then
     PIPE="-pipe"
+else
+    CC_TEST_FLAGS="$CFLAGS $NGX_CC_OPT"
 fi
 
 
diff --git a/auto/cc/icc b/auto/cc/icc
index c47f6e4..076b664 100644
--- a/auto/cc/icc
+++ b/auto/cc/icc
@@ -10,7 +10,7 @@
 
 echo " + icc version: $NGX_ICC_VER"
 
-have=NGX_COMPILER value="\"Intel C Compiler $NGX_ICC_VER\"" . auto/define
+have=NGX_COMPILER value="\"Intel C Compiler $NGX_ICC_VER\"" . $NGX_AUTO/define
 
 
 # optimizations
diff --git a/auto/cc/msvc b/auto/cc/msvc
index 4eef101..de5d325 100644
--- a/auto/cc/msvc
+++ b/auto/cc/msvc
@@ -16,7 +16,7 @@
 
 echo " + cl version: $NGX_MSVC_VER"
 
-have=NGX_COMPILER value="\"cl $NGX_MSVC_VER\"" . auto/define
+have=NGX_COMPILER value="\"cl $NGX_MSVC_VER\"" . $NGX_AUTO/define
 
 
 ngx_msvc_ver=`echo $NGX_MSVC_VER | sed -e 's/^\([0-9]*\).*/\1/'`
@@ -115,7 +115,7 @@
 
 # MSVC 2005 supports C99 variadic macros
 if [ "$ngx_msvc_ver" -ge 14 ]; then
-    have=NGX_HAVE_C99_VARIADIC_MACROS . auto/have
+    have=NGX_HAVE_C99_VARIADIC_MACROS . $NGX_AUTO/have
 fi
 
 
diff --git a/auto/cc/name b/auto/cc/name
index 35d319e..d7943bc 100644
--- a/auto/cc/name
+++ b/auto/cc/name
@@ -12,7 +12,7 @@
     ngx_feature_path=
     ngx_feature_libs=
     ngx_feature_test=
-    . auto/feature
+    . $NGX_AUTO/feature
 
     if [ $ngx_found = no ]; then
         echo
diff --git a/auto/cc/owc b/auto/cc/owc
index a063aa3..ebb877d 100644
--- a/auto/cc/owc
+++ b/auto/cc/owc
@@ -61,7 +61,7 @@
 CFLAGS="$CFLAGS -zq"
 
 # Open Watcom C 1.2
-have=NGX_HAVE_C99_VARIADIC_MACROS . auto/have
+have=NGX_HAVE_C99_VARIADIC_MACROS . $NGX_AUTO/have
 
 
 # the precompiled headers
diff --git a/auto/cc/sunc b/auto/cc/sunc
index 552c2d3..6dd9303 100644
--- a/auto/cc/sunc
+++ b/auto/cc/sunc
@@ -18,7 +18,7 @@
 
 echo " + Sun C version: $NGX_SUNC_VER"
 
-have=NGX_COMPILER value="\"Sun C $NGX_SUNC_VER\"" . auto/define
+have=NGX_COMPILER value="\"Sun C $NGX_SUNC_VER\"" . $NGX_AUTO/define
 
 
 cat << END > $NGX_AUTOTEST.c
diff --git a/auto/configure b/auto/configure
index ceff15e..7625305 100755
--- a/auto/configure
+++ b/auto/configure
@@ -7,9 +7,12 @@
 LC_ALL=C
 export LC_ALL
 
-. auto/options
-. auto/init
-. auto/sources
+NGX_ROOT=`dirname $0 | sed -e "s/auto$//" -e "s/\/$//" -e "s/^$/\./"`
+NGX_AUTO=$NGX_ROOT/auto
+
+. $NGX_AUTO/options
+. $NGX_AUTO/init
+. $NGX_AUTO/sources
 
 test -d $NGX_OBJS || mkdir -p $NGX_OBJS
 
@@ -20,7 +23,7 @@
 
 
 if [ $NGX_DEBUG = YES ]; then
-    have=NGX_DEBUG . auto/have
+    have=NGX_DEBUG . $NGX_AUTO/have
 fi
 
 
@@ -46,26 +49,26 @@
     NGX_SYSTEM=$NGX_PLATFORM
 fi
 
-. auto/cc/conf
+. $NGX_AUTO/cc/conf
 
 if [ "$NGX_PLATFORM" != win32 ]; then
-    . auto/headers
+    . $NGX_AUTO/headers
 fi
 
-. auto/os/conf
+. $NGX_AUTO/os/conf
 
 if [ "$NGX_PLATFORM" != win32 ]; then
-    . auto/unix
+    . $NGX_AUTO/unix
 fi
 
-. auto/threads
-. auto/modules
-. auto/lib/conf
+. $NGX_AUTO/threads
+. $NGX_AUTO/modules
+. $NGX_AUTO/lib/conf
 
 case ".$NGX_PREFIX" in
     .)
         NGX_PREFIX=${NGX_PREFIX:-/usr/local/nginx}
-        have=NGX_PREFIX value="\"$NGX_PREFIX/\"" . auto/define
+        have=NGX_PREFIX value="\"$NGX_PREFIX/\"" . $NGX_AUTO/define
     ;;
 
     .!)
@@ -73,44 +76,46 @@
     ;;
 
     *)
-        have=NGX_PREFIX value="\"$NGX_PREFIX/\"" . auto/define
+        have=NGX_PREFIX value="\"$NGX_PREFIX/\"" . $NGX_AUTO/define
     ;;
 esac
 
 if [ ".$NGX_CONF_PREFIX" != "." ]; then
-    have=NGX_CONF_PREFIX value="\"$NGX_CONF_PREFIX/\"" . auto/define
+    have=NGX_CONF_PREFIX value="\"$NGX_CONF_PREFIX/\"" . $NGX_AUTO/define
 fi
 
-have=NGX_SBIN_PATH value="\"$NGX_SBIN_PATH\"" . auto/define
-have=NGX_CONF_PATH value="\"$NGX_CONF_PATH\"" . auto/define
-have=NGX_PID_PATH value="\"$NGX_PID_PATH\"" . auto/define
-have=NGX_LOCK_PATH value="\"$NGX_LOCK_PATH\"" . auto/define
-have=NGX_ERROR_LOG_PATH value="\"$NGX_ERROR_LOG_PATH\"" . auto/define
+have=NGX_SBIN_PATH value="\"$NGX_SBIN_PATH\"" . $NGX_AUTO/define
+have=NGX_CONF_PATH value="\"$NGX_CONF_PATH\"" . $NGX_AUTO/define
+have=NGX_PID_PATH value="\"$NGX_PID_PATH\"" . $NGX_AUTO/define
+have=NGX_LOCK_PATH value="\"$NGX_LOCK_PATH\"" . $NGX_AUTO/define
+have=NGX_ERROR_LOG_PATH value="\"$NGX_ERROR_LOG_PATH\"" . $NGX_AUTO/define
 
-have=NGX_HTTP_LOG_PATH value="\"$NGX_HTTP_LOG_PATH\"" . auto/define
+have=NGX_HTTP_LOG_PATH value="\"$NGX_HTTP_LOG_PATH\"" . $NGX_AUTO/define
 have=NGX_HTTP_CLIENT_TEMP_PATH value="\"$NGX_HTTP_CLIENT_TEMP_PATH\""
-. auto/define
+. $NGX_AUTO/define
 have=NGX_HTTP_PROXY_TEMP_PATH value="\"$NGX_HTTP_PROXY_TEMP_PATH\""
-. auto/define
+. $NGX_AUTO/define
 have=NGX_HTTP_FASTCGI_TEMP_PATH value="\"$NGX_HTTP_FASTCGI_TEMP_PATH\""
-. auto/define
+. $NGX_AUTO/define
 have=NGX_HTTP_UWSGI_TEMP_PATH value="\"$NGX_HTTP_UWSGI_TEMP_PATH\""
-. auto/define
+. $NGX_AUTO/define
 have=NGX_HTTP_SCGI_TEMP_PATH value="\"$NGX_HTTP_SCGI_TEMP_PATH\""
-. auto/define
+. $NGX_AUTO/define
 
-. auto/make
-. auto/lib/make
-. auto/install
+if [ "$NGX_ROOT" = "." ]; then
+    . $NGX_AUTO/make
+    . $NGX_AUTO/lib/make
+    . $NGX_AUTO/install
+fi
 
 # STUB
-. auto/stubs
+. $NGX_AUTO/stubs
 
-have=NGX_USER value="\"$NGX_USER\"" . auto/define
-have=NGX_GROUP value="\"$NGX_GROUP\"" . auto/define
+have=NGX_USER value="\"$NGX_USER\"" . $NGX_AUTO/define
+have=NGX_GROUP value="\"$NGX_GROUP\"" . $NGX_AUTO/define
 
 if [ ".$NGX_BUILD" != "." ]; then
-    have=NGX_BUILD value="\"$NGX_BUILD\"" . auto/define
+    have=NGX_BUILD value="\"$NGX_BUILD\"" . $NGX_AUTO/define
 fi
 
-. auto/summary
+. $NGX_AUTO/summary
diff --git a/auto/endianness b/auto/endianness
index 1b552b6..3f6d957 100644
--- a/auto/endianness
+++ b/auto/endianness
@@ -34,7 +34,7 @@
 if [ -x $NGX_AUTOTEST ]; then
     if $NGX_AUTOTEST >/dev/null 2>&1; then
         echo " little endian"
-        have=NGX_HAVE_LITTLE_ENDIAN . auto/have
+        have=NGX_HAVE_LITTLE_ENDIAN . $NGX_AUTO/have
     else
         echo " big endian"
     fi
diff --git a/auto/feature b/auto/feature
index 3561f59..78863f7 100644
--- a/auto/feature
+++ b/auto/feature
@@ -58,7 +58,7 @@
                 ngx_found=yes
 
                 if test -n "$ngx_feature_name"; then
-                    have=$ngx_have_feature . auto/have
+                    have=$ngx_have_feature . $NGX_AUTO/have
                 fi
 
             else
@@ -94,7 +94,7 @@
                 ngx_found=yes
 
                 if test -n "$ngx_feature_name"; then
-                    have=$ngx_have_feature . auto/have
+                    have=$ngx_have_feature . $NGX_AUTO/have
                 fi
             fi
         ;;
@@ -104,7 +104,7 @@
             ngx_found=yes
 
             if test -n "$ngx_feature_name"; then
-                have=$ngx_have_feature . auto/have
+                have=$ngx_have_feature . $NGX_AUTO/have
             fi
         ;;
 
diff --git a/auto/headers b/auto/headers
index 5a2e6b9..6caee39 100644
--- a/auto/headers
+++ b/auto/headers
@@ -3,11 +3,11 @@
 # Copyright (C) Nginx, Inc.
 
 
-ngx_include="unistd.h";      . auto/include
-ngx_include="inttypes.h";    . auto/include
-ngx_include="limits.h";      . auto/include
-ngx_include="sys/filio.h";   . auto/include
-ngx_include="sys/param.h";   . auto/include
-ngx_include="sys/mount.h";   . auto/include
-ngx_include="sys/statvfs.h"; . auto/include
-ngx_include="crypt.h";       . auto/include
+ngx_include="unistd.h";      . $NGX_AUTO/include
+ngx_include="inttypes.h";    . $NGX_AUTO/include
+ngx_include="limits.h";      . $NGX_AUTO/include
+ngx_include="sys/filio.h";   . $NGX_AUTO/include
+ngx_include="sys/param.h";   . $NGX_AUTO/include
+ngx_include="sys/mount.h";   . $NGX_AUTO/include
+ngx_include="sys/statvfs.h"; . $NGX_AUTO/include
+ngx_include="crypt.h";       . $NGX_AUTO/include
diff --git a/auto/include b/auto/include
index c1bd364..25e037f 100644
--- a/auto/include
+++ b/auto/include
@@ -27,7 +27,8 @@
 END
 
 
-ngx_test="$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c"
+ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
+          -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT"
 
 eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
 
@@ -41,7 +42,7 @@
               | tr abcdefghijklmnopqrstuvwxyz/. ABCDEFGHIJKLMNOPQRSTUVWXYZ__`
 
 
-    have=NGX_HAVE_$ngx_name . auto/have_headers
+    have=NGX_HAVE_$ngx_name . $NGX_AUTO/have_headers
 
     eval "NGX_INCLUDE_$ngx_name='#include <$ngx_include>'"
 
diff --git a/auto/init b/auto/init
index 910f529..71fd93f 100644
--- a/auto/init
+++ b/auto/init
@@ -42,10 +42,14 @@
 
 # create Makefile
 
-cat << END > Makefile
+if [ "$NGX_ROOT" = "." ]; then
 
-default:	build
+    cat << END > $NGX_ROOT/Makefile
+
+default:	all
 
 clean:
 	rm -rf Makefile $NGX_OBJS
 END
+
+fi
diff --git a/auto/install b/auto/install
index d884487..c97b12b 100644
--- a/auto/install
+++ b/auto/install
@@ -196,9 +196,9 @@
 
 # create Makefile
 
-cat << END >> Makefile
+cat << END >> $NGX_ROOT/Makefile
 
-build:
+all:
 	\$(MAKE) -f $NGX_MAKEFILE
 
 install:
diff --git a/auto/lib/conf b/auto/lib/conf
index 0b8545a..9926399 100644
--- a/auto/lib/conf
+++ b/auto/lib/conf
@@ -4,7 +4,7 @@
 
 
 if [ $USE_PCRE = YES -o $PCRE != NONE ]; then
-    . auto/lib/pcre/conf
+    . $NGX_AUTO/lib/pcre/conf
 
 else
     if [ $USE_PCRE = DISABLED -a $HTTP_REWRITE = YES ]; then
@@ -22,33 +22,33 @@
 
 
 if [ $USE_OPENSSL = YES ]; then
-    . auto/lib/openssl/conf
+    . $NGX_AUTO/lib/openssl/conf
 fi
 
 if [ $USE_ZLIB = YES ]; then
-    . auto/lib/zlib/conf
+    . $NGX_AUTO/lib/zlib/conf
 fi
 
 if [ $USE_LIBXSLT != NO ]; then
-    . auto/lib/libxslt/conf
+    . $NGX_AUTO/lib/libxslt/conf
 fi
 
 if [ $USE_LIBGD != NO ]; then
-    . auto/lib/libgd/conf
+    . $NGX_AUTO/lib/libgd/conf
 fi
 
 if [ $USE_PERL != NO ]; then
-    . auto/lib/perl/conf
+    . $NGX_AUTO/lib/perl/conf
 fi
 
 if [ $USE_GEOIP != NO ]; then
-    . auto/lib/geoip/conf
+    . $NGX_AUTO/lib/geoip/conf
 fi
 
 if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then
-    . auto/lib/google-perftools/conf
+    . $NGX_AUTO/lib/google-perftools/conf
 fi
 
 if [ $NGX_LIBATOMIC != NO ]; then
-    . auto/lib/libatomic/conf
+    . $NGX_AUTO/lib/libatomic/conf
 fi
diff --git a/auto/lib/geoip/conf b/auto/lib/geoip/conf
index 8302aae..0ca8e1d 100644
--- a/auto/lib/geoip/conf
+++ b/auto/lib/geoip/conf
@@ -10,7 +10,7 @@
     ngx_feature_path=
     ngx_feature_libs="-lGeoIP"
     ngx_feature_test="GeoIP_open(NULL, 0)"
-    . auto/feature
+    . $NGX_AUTO/feature
 
 
 if [ $ngx_found = no ]; then
@@ -26,7 +26,7 @@
         ngx_feature_libs="-L/usr/local/lib -lGeoIP"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -43,7 +43,7 @@
         ngx_feature_libs="-L/usr/pkg/lib -lGeoIP"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -60,7 +60,7 @@
         ngx_feature_libs="-L/opt/local/lib -lGeoIP"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -82,7 +82,7 @@
     #ngx_feature_path=
     #ngx_feature_libs=
     ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);"
-    . auto/feature
+    . $NGX_AUTO/feature
 
 else
 
diff --git a/auto/lib/google-perftools/conf b/auto/lib/google-perftools/conf
index 5d5ddae..7c350dc 100644
--- a/auto/lib/google-perftools/conf
+++ b/auto/lib/google-perftools/conf
@@ -10,7 +10,7 @@
     ngx_feature_path=
     ngx_feature_libs="-lprofiler"
     ngx_feature_test="ProfilerStop()"
-    . auto/feature
+    . $NGX_AUTO/feature
 
 
 if [ $ngx_found = no ]; then
@@ -25,7 +25,7 @@
         ngx_feature_libs="-L/usr/local/lib -lprofiler"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -41,7 +41,7 @@
         ngx_feature_libs="-L/opt/local/lib -lprofiler"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
diff --git a/auto/lib/libatomic/conf b/auto/lib/libatomic/conf
index d1e484a..28a7a22 100644
--- a/auto/lib/libatomic/conf
+++ b/auto/lib/libatomic/conf
@@ -5,7 +5,7 @@
 
 if [ $NGX_LIBATOMIC != YES ]; then
 
-    have=NGX_HAVE_LIBATOMIC . auto/have
+    have=NGX_HAVE_LIBATOMIC . $NGX_AUTO/have
     CORE_INCS="$CORE_INCS $NGX_LIBATOMIC/src"
     LINK_DEPS="$LINK_DEPS $NGX_LIBATOMIC/src/libatomic_ops.a"
     CORE_LIBS="$CORE_LIBS $NGX_LIBATOMIC/src/libatomic_ops.a"
@@ -27,7 +27,7 @@
                       if (n != 2)
                           return 1;
                       AO_nop();"
-    . auto/feature
+    . $NGX_AUTO/feature
 
     if [ $ngx_found = yes ]; then
         CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
diff --git a/auto/lib/libgd/conf b/auto/lib/libgd/conf
index 87761f1..2025396 100644
--- a/auto/lib/libgd/conf
+++ b/auto/lib/libgd/conf
@@ -10,7 +10,7 @@
     ngx_feature_path=
     ngx_feature_libs="-lgd"
     ngx_feature_test="gdImagePtr img = gdImageCreateFromGifPtr(1, NULL);"
-    . auto/feature
+    . $NGX_AUTO/feature
 
 
 if [ $ngx_found = no ]; then
@@ -26,7 +26,7 @@
         ngx_feature_libs="-L/usr/local/lib -lgd"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -43,7 +43,7 @@
         ngx_feature_libs="-L/usr/pkg/lib -lgd"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -60,7 +60,7 @@
         ngx_feature_libs="-L/opt/local/lib -lgd"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
diff --git a/auto/lib/libxslt/conf b/auto/lib/libxslt/conf
index 3a0f37b..db033d0 100644
--- a/auto/lib/libxslt/conf
+++ b/auto/lib/libxslt/conf
@@ -19,7 +19,7 @@
                       xmlDocPtr           doc;
                       doc = xmlParseChunk(ctxt, NULL, 0, 0);
                       xsltApplyStylesheet(sheet, doc, NULL);"
-    . auto/feature
+    . $NGX_AUTO/feature
 
 
 if [ $ngx_found = no ]; then
@@ -35,7 +35,7 @@
         ngx_feature_libs="-L/usr/local/lib -lxml2 -lxslt"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -52,7 +52,7 @@
         ngx_feature_libs="-L/usr/pkg/lib -lxml2 -lxslt"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -69,7 +69,7 @@
         ngx_feature_libs="-L/opt/local/lib -lxml2 -lxslt"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -103,7 +103,7 @@
     ngx_feature_path="/usr/include/libxml2"
     ngx_feature_libs="-lexslt"
     ngx_feature_test="exsltRegisterAll();"
-    . auto/feature
+    . $NGX_AUTO/feature
 
 if [ $ngx_found = no ]; then
 
@@ -118,7 +118,7 @@
         ngx_feature_libs="-L/usr/local/lib -lexslt"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -135,7 +135,7 @@
         ngx_feature_libs="-L/usr/pkg/lib -lexslt"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -152,7 +152,7 @@
         ngx_feature_libs="-L/opt/local/lib -lexslt"
     fi
 
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
diff --git a/auto/lib/make b/auto/lib/make
index b64e329..e90fd88 100644
--- a/auto/lib/make
+++ b/auto/lib/make
@@ -4,21 +4,21 @@
 
 
 if [ $PCRE != NONE -a $PCRE != NO -a $PCRE != YES ]; then
-    . auto/lib/pcre/make
+    . $NGX_AUTO/lib/pcre/make
 fi
 
 if [ $OPENSSL != NONE -a $OPENSSL != NO -a $OPENSSL != YES ]; then
-    . auto/lib/openssl/make
+    . $NGX_AUTO/lib/openssl/make
 fi
 
 if [ $ZLIB != NONE -a $ZLIB != NO -a $ZLIB != YES ]; then
-    . auto/lib/zlib/make
+    . $NGX_AUTO/lib/zlib/make
 fi
 
 if [ $NGX_LIBATOMIC != NO -a $NGX_LIBATOMIC != YES ]; then
-    . auto/lib/libatomic/make
+    . $NGX_AUTO/lib/libatomic/make
 fi
 
 if [ $USE_PERL != NO ]; then
-    . auto/lib/perl/make
+    . $NGX_AUTO/lib/perl/make
 fi
diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf
index e7d3795..d316ec7 100644
--- a/auto/lib/openssl/conf
+++ b/auto/lib/openssl/conf
@@ -8,8 +8,8 @@
     case "$CC" in
 
         cl | bcc32)
-            have=NGX_OPENSSL . auto/have
-            have=NGX_SSL . auto/have
+            have=NGX_OPENSSL . $NGX_AUTO/have
+            have=NGX_SSL . $NGX_AUTO/have
 
             CFLAGS="$CFLAGS -DNO_SYS_TYPES_H"
 
@@ -33,8 +33,8 @@
         ;;
 
         *)
-            have=NGX_OPENSSL . auto/have
-            have=NGX_SSL . auto/have
+            have=NGX_OPENSSL . $NGX_AUTO/have
+            have=NGX_SSL . $NGX_AUTO/have
 
             CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
             CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
@@ -61,7 +61,7 @@
         ngx_feature_path=
         ngx_feature_libs="-lssl -lcrypto $NGX_LIBDL"
         ngx_feature_test="SSL_CTX_set_options(NULL, 0)"
-        . auto/feature
+        . $NGX_AUTO/feature
 
         if [ $ngx_found = no ]; then
 
@@ -76,7 +76,7 @@
                 ngx_feature_libs="-L/usr/local/lib -lssl -lcrypto $NGX_LIBDL"
             fi
 
-            . auto/feature
+            . $NGX_AUTO/feature
         fi
 
         if [ $ngx_found = no ]; then
@@ -92,7 +92,7 @@
                 ngx_feature_libs="-L/usr/pkg/lib -lssl -lcrypto $NGX_LIBDL"
             fi
 
-            . auto/feature
+            . $NGX_AUTO/feature
         fi
 
         if [ $ngx_found = no ]; then
@@ -108,11 +108,11 @@
                 ngx_feature_libs="-L/opt/local/lib -lssl -lcrypto $NGX_LIBDL"
             fi
 
-            . auto/feature
+            . $NGX_AUTO/feature
         fi
 
         if [ $ngx_found = yes ]; then
-            have=NGX_SSL . auto/have
+            have=NGX_SSL . $NGX_AUTO/have
             CORE_INCS="$CORE_INCS $ngx_feature_path"
             CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
             OPENSSL=YES
diff --git a/auto/lib/openssl/make b/auto/lib/openssl/make
index a6090c6..b28470e 100644
--- a/auto/lib/openssl/make
+++ b/auto/lib/openssl/make
@@ -51,7 +51,7 @@
 $OPENSSL/.openssl/include/openssl/ssl.h:	$NGX_MAKEFILE
 	cd $OPENSSL \\
 	&& if [ -f Makefile ]; then \$(MAKE) clean; fi \\
-	&& ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\
+	&& CC="\$(CC)" ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\
 	&& \$(MAKE) \\
 	&& \$(MAKE) install_sw LIBDIR=lib
 
diff --git a/auto/lib/pcre/conf b/auto/lib/pcre/conf
index 5e3960f..347f8d2 100644
--- a/auto/lib/pcre/conf
+++ b/auto/lib/pcre/conf
@@ -9,15 +9,15 @@
     case "$NGX_CC_NAME" in
 
         msvc | owc | bcc)
-            have=NGX_PCRE . auto/have
-            have=PCRE_STATIC . auto/have
+            have=NGX_PCRE . $NGX_AUTO/have
+            have=PCRE_STATIC . $NGX_AUTO/have
             CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
             LINK_DEPS="$LINK_DEPS $PCRE/pcre.lib"
             CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
         ;;
 
         icc)
-            have=NGX_PCRE . auto/have
+            have=NGX_PCRE . $NGX_AUTO/have
             CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
 
             LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
@@ -72,10 +72,10 @@
         ;;
 
         *)
-            have=NGX_PCRE . auto/have
+            have=NGX_PCRE . $NGX_AUTO/have
 
             if [ "$NGX_PLATFORM" = win32 ]; then
-                have=PCRE_STATIC . auto/have
+                have=PCRE_STATIC . $NGX_AUTO/have
             fi
 
             CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
@@ -87,7 +87,7 @@
 
 
     if [ $PCRE_JIT = YES ]; then
-        have=NGX_HAVE_PCRE_JIT . auto/have
+        have=NGX_HAVE_PCRE_JIT . $NGX_AUTO/have
         PCRE_CONF_OPT="$PCRE_CONF_OPT --enable-jit"
     fi
 
@@ -106,7 +106,7 @@
         ngx_feature_test="pcre *re;
                           re = pcre_compile(NULL, 0, NULL, 0, NULL);
                           if (re == NULL) return 1"
-        . auto/feature
+        . $NGX_AUTO/feature
 
         if [ $ngx_found = no ]; then
 
@@ -121,7 +121,7 @@
                 ngx_feature_libs="-L/usr/local/lib -lpcre"
             fi
 
-            . auto/feature
+            . $NGX_AUTO/feature
         fi
 
         if [ $ngx_found = no ]; then
@@ -132,7 +132,7 @@
             ngx_feature_path="/usr/include/pcre"
             ngx_feature_libs="-lpcre"
 
-            . auto/feature
+            . $NGX_AUTO/feature
         fi
 
         if [ $ngx_found = no ]; then
@@ -148,7 +148,7 @@
                 ngx_feature_libs="-L/usr/pkg/lib -lpcre"
             fi
 
-            . auto/feature
+            . $NGX_AUTO/feature
         fi
 
         if [ $ngx_found = no ]; then
@@ -164,7 +164,7 @@
                 ngx_feature_libs="-L/opt/local/lib -lpcre"
             fi
 
-            . auto/feature
+            . $NGX_AUTO/feature
         fi
 
         if [ $ngx_found = yes ]; then
@@ -180,7 +180,7 @@
                               pcre_free_study(NULL);
                               pcre_config(PCRE_CONFIG_JIT, &jit);
                               if (jit != 1) return 1;"
-            . auto/feature
+            . $NGX_AUTO/feature
 
             if [ $ngx_found = yes ]; then
                 PCRE_JIT=YES
diff --git a/auto/lib/perl/conf b/auto/lib/perl/conf
index e16a1bc..8310936 100644
--- a/auto/lib/perl/conf
+++ b/auto/lib/perl/conf
@@ -47,7 +47,7 @@
     ngx_perl_module="$ngx_perl_libdir/nginx/nginx.$ngx_perl_dlext"
 
     if $NGX_PERL -V:usemultiplicity | grep define > /dev/null; then
-        have=NGX_HAVE_PERL_MULTIPLICITY . auto/have
+        have=NGX_HAVE_PERL_MULTIPLICITY . $NGX_AUTO/have
         echo " + perl interpreter multiplicity found"
     fi
 
@@ -70,7 +70,7 @@
 
     if test -n "$NGX_PERL_MODULES"; then
         have=NGX_PERL_MODULES value="(u_char *) \"$NGX_PERL_MODULES\""
-        . auto/define
+        . $NGX_AUTO/define
         NGX_PERL_MODULES_MAN=$NGX_PERL_MODULES/man3
     fi
 
diff --git a/auto/lib/zlib/conf b/auto/lib/zlib/conf
index 239592e..284d33b 100644
--- a/auto/lib/zlib/conf
+++ b/auto/lib/zlib/conf
@@ -9,13 +9,13 @@
     case "$NGX_CC_NAME" in
 
         msvc | owc | bcc)
-            have=NGX_ZLIB . auto/have
+            have=NGX_ZLIB . $NGX_AUTO/have
             LINK_DEPS="$LINK_DEPS $ZLIB/zlib.lib"
             CORE_LIBS="$CORE_LIBS $ZLIB/zlib.lib"
         ;;
 
         icc)
-            have=NGX_ZLIB . auto/have
+            have=NGX_ZLIB . $NGX_AUTO/have
             LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
 
             # to allow -ipo optimization we link with the *.o but not library
@@ -32,7 +32,7 @@
         ;;
 
         *)
-            have=NGX_ZLIB . auto/have
+            have=NGX_ZLIB . $NGX_AUTO/have
             LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
             CORE_LIBS="$CORE_LIBS $ZLIB/libz.a"
             #CORE_LIBS="$CORE_LIBS -L $ZLIB -lz"
@@ -54,7 +54,7 @@
         ngx_feature_path=
         ngx_feature_libs="-lz"
         ngx_feature_test="z_stream z; deflate(&z, Z_NO_FLUSH)"
-        . auto/feature
+        . $NGX_AUTO/feature
 
 
         if [ $ngx_found = yes ]; then
diff --git a/auto/modules b/auto/modules
index be3561e..cf95e30 100644
--- a/auto/modules
+++ b/auto/modules
@@ -8,7 +8,7 @@
 fi
 
 if [ $EVENT_SELECT = YES ]; then
-    have=NGX_HAVE_SELECT . auto/have
+    have=NGX_HAVE_SELECT . $NGX_AUTO/have
     CORE_SRCS="$CORE_SRCS $SELECT_SRCS"
     EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE"
 fi
@@ -19,39 +19,39 @@
 fi
 
 if [ $EVENT_POLL = YES ]; then
-    have=NGX_HAVE_POLL . auto/have
+    have=NGX_HAVE_POLL . $NGX_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
+    have=NGX_HAVE_DEVPOLL . $NGX_AUTO/have
+    have=NGX_TEST_BUILD_DEVPOLL . $NGX_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
+    have=NGX_HAVE_EVENTPORT . $NGX_AUTO/have
+    have=NGX_TEST_BUILD_EVENTPORT . $NGX_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_EPOLLEXCLUSIVE . auto/have
-    have=NGX_HAVE_EVENTFD . auto/have
-    have=NGX_TEST_BUILD_EPOLL . auto/have
+    have=NGX_HAVE_EPOLL . $NGX_AUTO/have
+    have=NGX_HAVE_EPOLLRDHUP . $NGX_AUTO/have
+    have=NGX_HAVE_EPOLLEXCLUSIVE . $NGX_AUTO/have
+    have=NGX_HAVE_EVENTFD . $NGX_AUTO/have
+    have=NGX_TEST_BUILD_EPOLL . $NGX_AUTO/have
     EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
     CORE_SRCS="$CORE_SRCS $EPOLL_SRCS"
 fi
 
 if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = YES ]; then
-    have=NGX_TEST_BUILD_SOLARIS_SENDFILEV . auto/have
+    have=NGX_TEST_BUILD_SOLARIS_SENDFILEV . $NGX_AUTO/have
     CORE_SRCS="$CORE_SRCS $SOLARIS_SENDFILEV_SRCS"
 fi
 
@@ -92,12 +92,12 @@
         ngx_module_libs=
         ngx_module_link=YES
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
 
     if [ $HTTP_CACHE = YES ]; then
-        have=NGX_HTTP_CACHE . auto/have
+        have=NGX_HTTP_CACHE . $NGX_AUTO/have
         HTTP_SRCS="$HTTP_SRCS $HTTP_FILE_CACHE_SRCS"
     fi
 
@@ -191,7 +191,7 @@
         ngx_module_libs=
         ngx_module_link=YES
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if :; then
@@ -202,7 +202,7 @@
         ngx_module_libs=
         ngx_module_link=YES
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if :; then
@@ -213,7 +213,7 @@
         ngx_module_libs=
         ngx_module_link=YES
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_V2 = YES ]; then
@@ -224,7 +224,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_V2
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if :; then
@@ -235,11 +235,11 @@
         ngx_module_libs=
         ngx_module_link=YES
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_GZIP = YES ]; then
-        have=NGX_HTTP_GZIP . auto/have
+        have=NGX_HTTP_GZIP . $NGX_AUTO/have
         USE_ZLIB=YES
 
         ngx_module_name=ngx_http_gzip_filter_module
@@ -249,7 +249,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_GZIP
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_POSTPONE = YES ]; then
@@ -260,11 +260,11 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_POSTPONE
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_SSI = YES ]; then
-        have=NGX_HTTP_SSI . auto/have
+        have=NGX_HTTP_SSI . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_ssi_filter_module
         ngx_module_incs=
@@ -273,7 +273,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_SSI
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_CHARSET = YES ]; then
@@ -284,7 +284,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_CHARSET
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_XSLT != NO ]; then
@@ -295,7 +295,7 @@
         ngx_module_libs=LIBXSLT
         ngx_module_link=$HTTP_XSLT
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_IMAGE_FILTER != NO ]; then
@@ -306,7 +306,7 @@
         ngx_module_libs=LIBGD
         ngx_module_link=$HTTP_IMAGE_FILTER
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_SUB = YES ]; then
@@ -317,7 +317,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_SUB
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_ADDITION = YES ]; then
@@ -328,11 +328,11 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_ADDITION
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_GUNZIP = YES ]; then
-        have=NGX_HTTP_GZIP . auto/have
+        have=NGX_HTTP_GZIP . $NGX_AUTO/have
         USE_ZLIB=YES
 
         ngx_module_name=ngx_http_gunzip_filter_module
@@ -342,7 +342,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_GUNZIP
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_USERID = YES ]; then
@@ -353,7 +353,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_USERID
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if :; then
@@ -364,7 +364,7 @@
         ngx_module_libs=
         ngx_module_link=YES
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
 
@@ -379,7 +379,7 @@
         ngx_module_libs=
         ngx_module_link=YES
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if :; then
@@ -390,7 +390,7 @@
         ngx_module_libs=
         ngx_module_link=YES
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if :; then
@@ -401,7 +401,7 @@
         ngx_module_libs=
         ngx_module_link=YES
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_SLICE = YES ]; then
@@ -412,14 +412,14 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_SLICE
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
 
     ngx_module_type=HTTP
 
     if [ $HTTP_V2 = YES ]; then
-        have=NGX_HTTP_V2 . auto/have
+        have=NGX_HTTP_V2 . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_v2_module
         ngx_module_incs=src/http/v2
@@ -433,7 +433,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_V2
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if :; then
@@ -444,11 +444,11 @@
         ngx_module_libs=
         ngx_module_link=YES
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_GZIP_STATIC = YES ]; then
-        have=NGX_HTTP_GZIP . auto/have
+        have=NGX_HTTP_GZIP . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_gzip_static_module
         ngx_module_incs=
@@ -457,11 +457,11 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_GZIP_STATIC
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_DAV = YES ]; then
-        have=NGX_HTTP_DAV . auto/have
+        have=NGX_HTTP_DAV . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_dav_module
         ngx_module_incs=
@@ -470,7 +470,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_DAV
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_AUTOINDEX = YES ]; then
@@ -481,7 +481,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_AUTOINDEX
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if :; then
@@ -492,7 +492,7 @@
         ngx_module_libs=
         ngx_module_link=YES
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_RANDOM_INDEX = YES ]; then
@@ -503,7 +503,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_RANDOM_INDEX
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_AUTH_REQUEST = YES ]; then
@@ -514,11 +514,11 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_AUTH_REQUEST
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_AUTH_BASIC = YES ]; then
-        have=NGX_CRYPT . auto/have
+        have=NGX_CRYPT . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_auth_basic_module
         ngx_module_incs=
@@ -527,7 +527,7 @@
         ngx_module_libs=$CRYPT_LIB
         ngx_module_link=$HTTP_AUTH_BASIC
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_ACCESS = YES ]; then
@@ -538,7 +538,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_ACCESS
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_LIMIT_CONN = YES ]; then
@@ -549,7 +549,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_LIMIT_CONN
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_LIMIT_REQ = YES ]; then
@@ -560,12 +560,12 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_LIMIT_REQ
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_REALIP = YES ]; then
-        have=NGX_HTTP_REALIP . auto/have
-        have=NGX_HTTP_X_FORWARDED_FOR . auto/have
+        have=NGX_HTTP_REALIP . $NGX_AUTO/have
+        have=NGX_HTTP_X_FORWARDED_FOR . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_realip_module
         ngx_module_incs=
@@ -574,7 +574,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_REALIP
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_STATUS = YES ]; then
@@ -585,11 +585,11 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_STATUS
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_GEO = YES ]; then
-        have=NGX_HTTP_X_FORWARDED_FOR . auto/have
+        have=NGX_HTTP_X_FORWARDED_FOR . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_geo_module
         ngx_module_incs=
@@ -598,11 +598,11 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_GEO
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_GEOIP != NO ]; then
-        have=NGX_HTTP_X_FORWARDED_FOR . auto/have
+        have=NGX_HTTP_X_FORWARDED_FOR . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_geoip_module
         ngx_module_incs=
@@ -611,7 +611,7 @@
         ngx_module_libs=GEOIP
         ngx_module_link=$HTTP_GEOIP
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_MAP = YES ]; then
@@ -622,7 +622,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_MAP
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_SPLIT_CLIENTS = YES ]; then
@@ -633,7 +633,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_SPLIT_CLIENTS
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_REFERER = YES ]; then
@@ -644,7 +644,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_REFERER
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_REWRITE = YES -a $USE_PCRE != DISABLED ]; then
@@ -657,12 +657,12 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_REWRITE
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_SSL = YES ]; then
         USE_OPENSSL=YES
-        have=NGX_HTTP_SSL . auto/have
+        have=NGX_HTTP_SSL . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_ssl_module
         ngx_module_incs=
@@ -671,11 +671,11 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_SSL
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_PROXY = YES ]; then
-        have=NGX_HTTP_X_FORWARDED_FOR . auto/have
+        have=NGX_HTTP_X_FORWARDED_FOR . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_proxy_module
         ngx_module_incs=
@@ -684,7 +684,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_PROXY
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_FASTCGI = YES ]; then
@@ -695,7 +695,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_FASTCGI
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_UWSGI = YES ]; then
@@ -706,7 +706,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_UWSGI
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_SCGI = YES ]; then
@@ -717,7 +717,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_SCGI
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_PERL != NO ]; then
@@ -728,7 +728,7 @@
         ngx_module_libs=PERL
         ngx_module_link=$HTTP_PERL
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_MEMCACHED = YES ]; then
@@ -739,7 +739,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_MEMCACHED
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_EMPTY_GIF = YES ]; then
@@ -750,7 +750,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_EMPTY_GIF
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_BROWSER = YES ]; then
@@ -761,7 +761,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_BROWSER
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_SECURE_LINK = YES ]; then
@@ -772,11 +772,11 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_SECURE_LINK
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_DEGRADATION = YES ]; then
-        have=NGX_HTTP_DEGRADATION . auto/have
+        have=NGX_HTTP_DEGRADATION . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_degradation_module
         ngx_module_incs=
@@ -785,7 +785,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_DEGRADATION
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_FLV = YES ]; then
@@ -796,7 +796,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_FLV
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_MP4 = YES ]; then
@@ -807,7 +807,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_MP4
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_UPSTREAM_HASH = YES ]; then
@@ -818,7 +818,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_UPSTREAM_HASH
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_UPSTREAM_IP_HASH = YES ]; then
@@ -829,7 +829,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_UPSTREAM_IP_HASH
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_UPSTREAM_LEAST_CONN = YES ]; then
@@ -840,7 +840,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_UPSTREAM_LEAST_CONN
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_UPSTREAM_KEEPALIVE = YES ]; then
@@ -851,11 +851,11 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_UPSTREAM_KEEPALIVE
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_UPSTREAM_ZONE = YES ]; then
-        have=NGX_HTTP_UPSTREAM_ZONE . auto/have
+        have=NGX_HTTP_UPSTREAM_ZONE . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_upstream_zone_module
         ngx_module_incs=
@@ -864,11 +864,11 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_UPSTREAM_ZONE
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $HTTP_STUB_STATUS = YES ]; then
-        have=NGX_STAT_STUB . auto/have
+        have=NGX_STAT_STUB . $NGX_AUTO/have
 
         ngx_module_name=ngx_http_stub_status_module
         ngx_module_incs=
@@ -877,7 +877,7 @@
         ngx_module_libs=
         ngx_module_link=$HTTP_STUB_STATUS
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 fi
 
@@ -901,19 +901,19 @@
                      src/mail/ngx_mail_handler.c \
                      src/mail/ngx_mail_parse.c"
 
-    . auto/module
+    . $NGX_AUTO/module
 
     ngx_module_incs=
 
     if [ $MAIL_SSL = YES ]; then
         USE_OPENSSL=YES
-        have=NGX_MAIL_SSL . auto/have
+        have=NGX_MAIL_SSL . $NGX_AUTO/have
 
         ngx_module_name=ngx_mail_ssl_module
         ngx_module_deps=src/mail/ngx_mail_ssl_module.h
         ngx_module_srcs=src/mail/ngx_mail_ssl_module.c
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $MAIL_POP3 = YES ]; then
@@ -922,7 +922,7 @@
         ngx_module_srcs="src/mail/ngx_mail_pop3_module.c \
                          src/mail/ngx_mail_pop3_handler.c"
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $MAIL_IMAP = YES ]; then
@@ -931,7 +931,7 @@
         ngx_module_srcs="src/mail/ngx_mail_imap_module.c \
                          src/mail/ngx_mail_imap_handler.c"
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $MAIL_SMTP = YES ]; then
@@ -940,20 +940,20 @@
         ngx_module_srcs="src/mail/ngx_mail_smtp_module.c \
                          src/mail/ngx_mail_smtp_handler.c"
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     ngx_module_name=ngx_mail_auth_http_module
     ngx_module_deps=
     ngx_module_srcs=src/mail/ngx_mail_auth_http_module.c
 
-    . auto/module
+    . $NGX_AUTO/module
 
     ngx_module_name=ngx_mail_proxy_module
     ngx_module_deps=
     ngx_module_srcs=src/mail/ngx_mail_proxy_module.c
 
-    . auto/module
+    . $NGX_AUTO/module
 fi
 
 
@@ -991,13 +991,13 @@
                      src/stream/ngx_stream_upstream_round_robin.c \
                      src/stream/ngx_stream_write_filter_module.c"
 
-    . auto/module
+    . $NGX_AUTO/module
 
     ngx_module_incs=
 
     if [ $STREAM_SSL = YES ]; then
         USE_OPENSSL=YES
-        have=NGX_STREAM_SSL . auto/have
+        have=NGX_STREAM_SSL . $NGX_AUTO/have
 
         ngx_module_name=ngx_stream_ssl_module
         ngx_module_deps=src/stream/ngx_stream_ssl_module.h
@@ -1005,7 +1005,7 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_SSL
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_REALIP = YES ]; then
@@ -1015,7 +1015,7 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_REALIP
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_LIMIT_CONN = YES ]; then
@@ -1025,7 +1025,7 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_LIMIT_CONN
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_ACCESS = YES ]; then
@@ -1035,7 +1035,7 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_ACCESS
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_GEO = YES ]; then
@@ -1045,7 +1045,7 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_GEO
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_GEOIP != NO ]; then
@@ -1055,7 +1055,7 @@
         ngx_module_libs=GEOIP
         ngx_module_link=$STREAM_GEOIP
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_MAP = YES ]; then
@@ -1065,7 +1065,7 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_MAP
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_SPLIT_CLIENTS = YES ]; then
@@ -1075,7 +1075,7 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_SPLIT_CLIENTS
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_RETURN = YES ]; then
@@ -1085,7 +1085,7 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_RETURN
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_UPSTREAM_HASH = YES ]; then
@@ -1095,7 +1095,7 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_UPSTREAM_HASH
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_UPSTREAM_LEAST_CONN = YES ]; then
@@ -1105,11 +1105,11 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_UPSTREAM_LEAST_CONN
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_UPSTREAM_ZONE = YES ]; then
-        have=NGX_STREAM_UPSTREAM_ZONE . auto/have
+        have=NGX_STREAM_UPSTREAM_ZONE . $NGX_AUTO/have
 
         ngx_module_name=ngx_stream_upstream_zone_module
         ngx_module_deps=
@@ -1117,7 +1117,7 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_UPSTREAM_ZONE
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     if [ $STREAM_SSL_PREREAD = YES ]; then
@@ -1127,7 +1127,7 @@
         ngx_module_libs=
         ngx_module_link=$STREAM_SSL_PREREAD
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 fi
 
@@ -1208,7 +1208,7 @@
     ngx_module_link=YES
     ngx_module_order=
 
-    . auto/module
+    . $NGX_AUTO/module
 fi
 
 
@@ -1222,7 +1222,7 @@
     ngx_module_link=YES
     ngx_module_order=
 
-    . auto/module
+    . $NGX_AUTO/module
 fi
 
 
@@ -1256,7 +1256,7 @@
         ngx_module_libs=
         ngx_module_link=DYNAMIC
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(MAIL_DEPS)"
@@ -1276,7 +1276,7 @@
         ngx_module_libs=
         ngx_module_link=DYNAMIC
 
-        . auto/module
+        . $NGX_AUTO/module
     fi
 
     NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(STREAM_DEPS)"
@@ -1294,7 +1294,7 @@
     ngx_module_libs=
     ngx_module_link=$NGX_GOOGLE_PERFTOOLS
 
-    . auto/module
+    . $NGX_AUTO/module
 fi
 
 if [ $NGX_CPP_TEST = YES ]; then
@@ -1305,21 +1305,21 @@
     ngx_module_libs=-lstdc++
     ngx_module_link=$NGX_CPP_TEST
 
-    . auto/module
+    . $NGX_AUTO/module
 fi
 
 modules="$modules $MISC_MODULES"
 
 
 if [ $NGX_COMPAT = YES ]; then
-    have=NGX_COMPAT . auto/have
-    have=NGX_HTTP_GZIP . auto/have
-    have=NGX_HTTP_DAV . auto/have
-    have=NGX_HTTP_REALIP . auto/have
-    have=NGX_HTTP_X_FORWARDED_FOR . auto/have
-    have=NGX_HTTP_HEADERS . auto/have
-    have=NGX_HTTP_UPSTREAM_ZONE . auto/have
-    have=NGX_STREAM_UPSTREAM_ZONE . auto/have
+    have=NGX_COMPAT . $NGX_AUTO/have
+    have=NGX_HTTP_GZIP . $NGX_AUTO/have
+    have=NGX_HTTP_DAV . $NGX_AUTO/have
+    have=NGX_HTTP_REALIP . $NGX_AUTO/have
+    have=NGX_HTTP_X_FORWARDED_FOR . $NGX_AUTO/have
+    have=NGX_HTTP_HEADERS . $NGX_AUTO/have
+    have=NGX_HTTP_UPSTREAM_ZONE . $NGX_AUTO/have
+    have=NGX_STREAM_UPSTREAM_ZONE . $NGX_AUTO/have
 fi
 
 
diff --git a/auto/options b/auto/options
index 66b822a..2311b48 100644
--- a/auto/options
+++ b/auto/options
@@ -19,7 +19,7 @@
 
 CC=${CC:-cc}
 CPP=
-NGX_OBJS=objs
+NGX_OBJS=$NGX_ROOT/objs
 
 NGX_DEBUG=NO
 NGX_CC_OPT=
diff --git a/auto/os/conf b/auto/os/conf
index 6ad0e74..b17a8ff 100644
--- a/auto/os/conf
+++ b/auto/os/conf
@@ -8,33 +8,33 @@
 case "$NGX_PLATFORM" in
 
     FreeBSD:*)
-        . auto/os/freebsd
+        . $NGX_AUTO/os/freebsd
     ;;
 
     Linux:*)
-        . auto/os/linux
+        . $NGX_AUTO/os/linux
     ;;
 
     SunOS:*)
-        . auto/os/solaris
+        . $NGX_AUTO/os/solaris
     ;;
 
     Darwin:*)
-        . auto/os/darwin
+        . $NGX_AUTO/os/darwin
     ;;
 
     win32)
-        . auto/os/win32
+        . $NGX_AUTO/os/win32
     ;;
 
     DragonFly:*)
-        have=NGX_FREEBSD . auto/have_headers
+        have=NGX_FREEBSD . $NGX_AUTO/have_headers
         CORE_INCS="$UNIX_INCS"
         CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS"
         CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS"
 
         echo " + sendfile() found"
-        have=NGX_HAVE_SENDFILE . auto/have
+        have=NGX_HAVE_SENDFILE . $NGX_AUTO/have
         CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"
 
         ngx_spacer='
@@ -43,7 +43,7 @@
 
     HP-UX:*)
         # HP/UX
-        have=NGX_HPUX . auto/have_headers
+        have=NGX_HPUX . $NGX_AUTO/have_headers
         CORE_INCS="$UNIX_INCS"
         CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
         CORE_SRCS="$UNIX_SRCS"
@@ -53,8 +53,8 @@
 
     OSF1:*)
         # Tru64 UNIX
-        have=NGX_TRU64 . auto/have_headers
-        have=NGX_HAVE_STRERROR_R . auto/nohave
+        have=NGX_TRU64 . $NGX_AUTO/have_headers
+        have=NGX_HAVE_STRERROR_R . $NGX_AUTO/nohave
         CORE_INCS="$UNIX_INCS"
         CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
         CORE_SRCS="$UNIX_SRCS"
@@ -62,7 +62,7 @@
 
     GNU:*)
         # GNU Hurd
-        have=NGX_GNU_HURD . auto/have_headers
+        have=NGX_GNU_HURD . $NGX_AUTO/have_headers
         CORE_INCS="$UNIX_INCS"
         CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
         CORE_SRCS="$UNIX_SRCS"
@@ -81,29 +81,29 @@
 case "$NGX_MACHINE" in
 
     i386 | i686 | i86pc)
-        have=NGX_HAVE_NONALIGNED . auto/have
+        have=NGX_HAVE_NONALIGNED . $NGX_AUTO/have
         NGX_MACH_CACHE_LINE=32
     ;;
 
     amd64 | x86_64)
-        have=NGX_HAVE_NONALIGNED . auto/have
+        have=NGX_HAVE_NONALIGNED . $NGX_AUTO/have
         NGX_MACH_CACHE_LINE=64
     ;;
 
     sun4u | sun4v | sparc | sparc64)
-        have=NGX_ALIGNMENT value=16 . auto/define
+        have=NGX_ALIGNMENT value=16 . $NGX_AUTO/define
         # TODO
         NGX_MACH_CACHE_LINE=64
     ;;
 
     ia64 )
-        have=NGX_ALIGNMENT value=16 . auto/define
+        have=NGX_ALIGNMENT value=16 . $NGX_AUTO/define
         # TODO
         NGX_MACH_CACHE_LINE=64
     ;;
 
     *)
-        have=NGX_ALIGNMENT value=16 . auto/define
+        have=NGX_ALIGNMENT value=16 . $NGX_AUTO/define
         NGX_MACH_CACHE_LINE=32
     ;;
 
@@ -113,4 +113,4 @@
     NGX_CPU_CACHE_LINE=$NGX_MACH_CACHE_LINE
 fi
 
-have=NGX_CPU_CACHE_LINE value=$NGX_CPU_CACHE_LINE . auto/define
+have=NGX_CPU_CACHE_LINE value=$NGX_CPU_CACHE_LINE . $NGX_AUTO/define
diff --git a/auto/os/darwin b/auto/os/darwin
index 429468f..cf472d1 100644
--- a/auto/os/darwin
+++ b/auto/os/darwin
@@ -3,7 +3,7 @@
 # Copyright (C) Nginx, Inc.
 
 
-have=NGX_DARWIN . auto/have_headers
+have=NGX_DARWIN . $NGX_AUTO/have_headers
 
 CORE_INCS="$UNIX_INCS"
 CORE_DEPS="$UNIX_DEPS $DARWIN_DEPS"
@@ -23,8 +23,8 @@
 # kqueue
 
 echo " + kqueue found"
-have=NGX_HAVE_KQUEUE . auto/have
-have=NGX_HAVE_CLEAR_EVENT . auto/have
+have=NGX_HAVE_KQUEUE . $NGX_AUTO/have
+have=NGX_HAVE_CLEAR_EVENT . $NGX_AUTO/have
 EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
 CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
 EVENT_FOUND=YES
@@ -57,7 +57,7 @@
 
                   if (kev.flags & EV_ERROR) return 1;"
 
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="Darwin 64-bit kqueue millisecond timeout bug"
@@ -84,7 +84,7 @@
 
                   if (tv.tv_sec * 1000000 + tv.tv_usec < 900000) return 1;"
 
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # sendfile()
@@ -102,7 +102,7 @@
                   off_t n; off_t off = 0;
                   n = sendfile(s, fd, off, &n, NULL, 0);
                   if (n == -1 && errno == ENOSYS) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 if [ $ngx_found = yes ]; then
     CORE_SRCS="$CORE_SRCS $DARWIN_SENDFILE_SRCS"
@@ -117,4 +117,4 @@
 ngx_feature_libs=
 ngx_feature_test="int32_t  lock = 0;
                   if (!OSAtomicCompareAndSwap32Barrier(0, 1, &lock)) return 1"
-. auto/feature
+. $NGX_AUTO/feature
diff --git a/auto/os/freebsd b/auto/os/freebsd
index 937ca20..50902dd 100644
--- a/auto/os/freebsd
+++ b/auto/os/freebsd
@@ -3,7 +3,7 @@
 # Copyright (C) Nginx, Inc.
 
 
-have=NGX_FREEBSD . auto/have_headers
+have=NGX_FREEBSD . $NGX_AUTO/have_headers
 
 CORE_INCS="$UNIX_INCS"
 CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS"
@@ -40,7 +40,7 @@
 if [ $osreldate -gt 300007 ]; then
     echo " + sendfile() found"
 
-    have=NGX_HAVE_SENDFILE . auto/have
+    have=NGX_HAVE_SENDFILE . $NGX_AUTO/have
     CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"
 fi
 
@@ -48,7 +48,7 @@
     if [ $osreldate -gt 502103 ]; then
         echo " + sendfile()'s SF_NODISKIO found"
 
-        have=NGX_HAVE_AIO_SENDFILE . auto/have
+        have=NGX_HAVE_AIO_SENDFILE . $NGX_AUTO/have
     fi
 fi
 
@@ -58,7 +58,7 @@
 if [ $osreldate -ge 701106 ]; then
     echo " + POSIX semaphores should work"
 else
-    have=NGX_HAVE_POSIX_SEM . auto/nohave
+    have=NGX_HAVE_POSIX_SEM . $NGX_AUTO/nohave
 fi
 
 
@@ -69,8 +69,8 @@
 then
     echo " + kqueue found"
 
-    have=NGX_HAVE_KQUEUE . auto/have
-    have=NGX_HAVE_CLEAR_EVENT . auto/have
+    have=NGX_HAVE_KQUEUE . $NGX_AUTO/have
+    have=NGX_HAVE_CLEAR_EVENT . $NGX_AUTO/have
     EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
     CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
     EVENT_FOUND=YES
@@ -86,7 +86,7 @@
      -o $version -ge 500018 ]
 then
     echo " + kqueue's NOTE_LOWAT found"
-    have=NGX_HAVE_LOWAT_EVENT . auto/have
+    have=NGX_HAVE_LOWAT_EVENT . $NGX_AUTO/have
 fi
 
 # kqueue's EVFILT_TIMER
@@ -95,7 +95,7 @@
      -o $version -ge 500023 ]
 then
     echo " + kqueue's EVFILT_TIMER found"
-    have=NGX_HAVE_TIMER_EVENT . auto/have
+    have=NGX_HAVE_TIMER_EVENT . $NGX_AUTO/have
 fi
 
 
@@ -103,5 +103,5 @@
 
 if [ $version -ge 701000 ]; then
     echo " + cpuset_setaffinity() found"
-    have=NGX_HAVE_CPUSET_SETAFFINITY . auto/have
+    have=NGX_HAVE_CPUSET_SETAFFINITY . $NGX_AUTO/have
 fi
diff --git a/auto/os/linux b/auto/os/linux
index a0c8795..bbd1b8d 100644
--- a/auto/os/linux
+++ b/auto/os/linux
@@ -3,7 +3,7 @@
 # Copyright (C) Nginx, Inc.
 
 
-have=NGX_LINUX . auto/have_headers
+have=NGX_LINUX . $NGX_AUTO/have_headers
 
 CORE_INCS="$UNIX_INCS"
 CORE_DEPS="$UNIX_DEPS $LINUX_DEPS"
@@ -29,7 +29,7 @@
 # posix_fadvise64() had been implemented in 2.5.60
 
 if [ $version -lt 132412 ]; then
-    have=NGX_HAVE_POSIX_FADVISE . auto/nohave
+    have=NGX_HAVE_POSIX_FADVISE . $NGX_AUTO/nohave
 fi
 
 # epoll, EPOLLET version
@@ -47,10 +47,10 @@
                   (void) ee;
                   efd = epoll_create(100);
                   if (efd == -1) return 1;"
-. auto/feature
+. $NGX_AUTO/feature
 
 if [ $ngx_found = yes ]; then
-    have=NGX_HAVE_CLEAR_EVENT . auto/have
+    have=NGX_HAVE_CLEAR_EVENT . $NGX_AUTO/have
     CORE_SRCS="$CORE_SRCS $EPOLL_SRCS"
     EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
     EVENT_FOUND=YES
@@ -69,7 +69,7 @@
                       ee.events = EPOLLIN|EPOLLRDHUP|EPOLLET;
                       ee.data.ptr = NULL;
                       epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
-    . auto/feature
+    . $NGX_AUTO/feature
 
 
     # EPOLLEXCLUSIVE appeared in Linux 4.5, glibc 2.24
@@ -85,7 +85,7 @@
                       ee.events = EPOLLIN|EPOLLEXCLUSIVE;
                       ee.data.ptr = NULL;
                       epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -102,7 +102,7 @@
 ngx_feature_test="int fd; struct stat sb;
                   fd = openat(AT_FDCWD, \".\", O_PATH|O_DIRECTORY|O_NOFOLLOW);
                   if (fstatat(fd, \"\", &sb, AT_EMPTY_PATH) != 0) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # sendfile()
@@ -119,7 +119,7 @@
                   ssize_t n; off_t off = 0;
                   n = sendfile(s, fd, &off, 1);
                   if (n == -1 && errno == ENOSYS) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 if [ $ngx_found = yes ]; then
     CORE_SRCS="$CORE_SRCS $LINUX_SENDFILE_SRCS"
@@ -140,10 +140,10 @@
                   ssize_t n; off_t off = 0;
                   n = sendfile(s, fd, &off, 1);
                   if (n == -1 && errno == ENOSYS) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 
-ngx_include="sys/prctl.h"; . auto/include
+ngx_include="sys/prctl.h"; . $NGX_AUTO/include
 
 # prctl(PR_SET_DUMPABLE)
 
@@ -154,7 +154,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # crypt_r()
@@ -167,10 +167,10 @@
 ngx_feature_libs=-lcrypt
 ngx_feature_test="struct crypt_data  cd;
                   crypt_r(\"key\", \"salt\", &cd);"
-. auto/feature
+. $NGX_AUTO/feature
 
 
-ngx_include="sys/vfs.h";     . auto/include
+ngx_include="sys/vfs.h";     . $NGX_AUTO/include
 
 
 CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
diff --git a/auto/os/solaris b/auto/os/solaris
index 1dcfe84..8b8c5a8 100644
--- a/auto/os/solaris
+++ b/auto/os/solaris
@@ -3,7 +3,7 @@
 # Copyright (C) Nginx, Inc.
 
 
-have=NGX_SOLARIS . auto/have_headers
+have=NGX_SOLARIS . $NGX_AUTO/have_headers
 
 CORE_INCS="$UNIX_INCS"
 CORE_DEPS="$UNIX_DEPS $SOLARIS_DEPS"
@@ -37,7 +37,7 @@
                   size_t sent; ssize_t n;
                   n = sendfilev(fd, vec, 1, &sent);
                   if (n == -1) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 if [ $ngx_found = yes ]; then
@@ -53,7 +53,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="(void) port_create()"
-. auto/feature
+. $NGX_AUTO/feature
 
 if [ $ngx_found = yes ]; then
     CORE_SRCS="$CORE_SRCS $EVENTPORT_SRCS"
diff --git a/auto/os/win32 b/auto/os/win32
index 650cf49..d5147ca 100644
--- a/auto/os/win32
+++ b/auto/os/win32
@@ -3,7 +3,7 @@
 # Copyright (C) Nginx, Inc.
 
 
-have=NGX_WIN32 . auto/have_headers
+have=NGX_WIN32 . $NGX_AUTO/have_headers
 
 CORE_INCS="$WIN32_INCS"
 CORE_DEPS="$WIN32_DEPS"
@@ -37,6 +37,6 @@
     EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE"
 fi
 
-have=NGX_HAVE_INET6 . auto/have
+have=NGX_HAVE_INET6 . $NGX_AUTO/have
 
-have=NGX_HAVE_IOCP . auto/have
+have=NGX_HAVE_IOCP . $NGX_AUTO/have
diff --git a/auto/sources b/auto/sources
index 1398147..71e6c37 100644
--- a/auto/sources
+++ b/auto/sources
@@ -22,7 +22,6 @@
            src/core/ngx_parse_time.h \
            src/core/ngx_inet.h \
            src/core/ngx_file.h \
-           src/core/ngx_crc.h \
            src/core/ngx_crc32.h \
            src/core/ngx_murmurhash.h \
            src/core/ngx_md5.h \
diff --git a/auto/stubs b/auto/stubs
index d8bc1f0..29247cb 100644
--- a/auto/stubs
+++ b/auto/stubs
@@ -3,6 +3,6 @@
 # Copyright (C) Nginx, Inc.
 
 
-have=NGX_SUPPRESS_WARN . auto/have
+have=NGX_SUPPRESS_WARN . $NGX_AUTO/have
 
-have=NGX_SMP . auto/have
+have=NGX_SMP . $NGX_AUTO/have
diff --git a/auto/threads b/auto/threads
index 381f07a..5ba2a0a 100644
--- a/auto/threads
+++ b/auto/threads
@@ -13,7 +13,7 @@
         exit 1
     fi
 
-    have=NGX_THREADS . auto/have
+    have=NGX_THREADS . $NGX_AUTO/have
     CORE_DEPS="$CORE_DEPS $THREAD_POOL_DEPS"
     CORE_SRCS="$CORE_SRCS $THREAD_POOL_SRCS"
     CORE_LIBS="$CORE_LIBS -lpthread"
diff --git a/auto/unix b/auto/unix
index 7c6a855..5d75639 100644
--- a/auto/unix
+++ b/auto/unix
@@ -39,7 +39,7 @@
                   pl.revents = 0;
                   n = poll(&pl, 1, 0);
                   if (n == -1) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 if [ $ngx_found = no ]; then
     EVENT_POLL=NONE
@@ -59,7 +59,7 @@
                   dvp.dp_timeout = 0;
                   n = ioctl(dp, DP_POLL, &dvp);
                   if (n == -1) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 if [ $ngx_found = yes ]; then
     CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS"
@@ -76,11 +76,11 @@
     ngx_feature_path=
     ngx_feature_libs=
     ngx_feature_test="(void) kqueue()"
-    . auto/feature
+    . $NGX_AUTO/feature
 
     if [ $ngx_found = yes ]; then
 
-        have=NGX_HAVE_CLEAR_EVENT . auto/have
+        have=NGX_HAVE_CLEAR_EVENT . $NGX_AUTO/have
         EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
         CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
         EVENT_FOUND=YES
@@ -94,7 +94,7 @@
         ngx_feature_test="struct kevent  kev;
                           kev.fflags = NOTE_LOWAT;
                           (void) kev"
-        . auto/feature
+        . $NGX_AUTO/feature
 
 
         ngx_feature="kqueue's EVFILT_TIMER"
@@ -124,7 +124,7 @@
 
                   if (kev.flags & EV_ERROR) return 1;"
 
-        . auto/feature
+        . $NGX_AUTO/feature
     fi
 fi
 
@@ -156,7 +156,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="crypt(\"test\", \"salt\");"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 if [ $ngx_found = no ]; then
@@ -167,7 +167,7 @@
     ngx_feature_incs=
     ngx_feature_path=
     ngx_feature_libs=-lcrypt
-    . auto/feature
+    . $NGX_AUTO/feature
 
     if [ $ngx_found = yes ]; then
         CRYPT_LIB="-lcrypt"
@@ -182,7 +182,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="fcntl(0, F_READAHEAD, 1);"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="posix_fadvise()"
@@ -192,7 +192,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="O_DIRECT"
@@ -202,11 +202,11 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="fcntl(0, F_SETFL, O_DIRECT);"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 if [ $ngx_found = yes -a "$NGX_SYSTEM" = "Linux" ]; then
-    have=NGX_HAVE_ALIGNED_DIRECTIO . auto/have
+    have=NGX_HAVE_ALIGNED_DIRECTIO . $NGX_AUTO/have
 fi
 
 ngx_feature="F_NOCACHE"
@@ -216,7 +216,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="fcntl(0, F_NOCACHE, 1);"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="directio()"
@@ -227,7 +227,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="directio(0, DIRECTIO_ON);"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="statfs()"
@@ -240,7 +240,7 @@
 ngx_feature_libs=
 ngx_feature_test="struct statfs  fs;
                   statfs(\".\", &fs);"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="statvfs()"
@@ -252,7 +252,7 @@
 ngx_feature_libs=
 ngx_feature_test="struct statvfs  fs;
                   statvfs(\".\", &fs);"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="dlopen()"
@@ -262,14 +262,14 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); dlsym(NULL, \"\")"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 if [ $ngx_found = no ]; then
 
     ngx_feature="dlopen() in libdl"
     ngx_feature_libs="-ldl"
-    . auto/feature
+    . $NGX_AUTO/feature
 
     if [ $ngx_found = yes ]; then
         CORE_LIBS="$CORE_LIBS -ldl"
@@ -285,14 +285,14 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="sched_yield()"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 if [ $ngx_found = no ]; then
 
     ngx_feature="sched_yield() in librt"
     ngx_feature_libs="-lrt"
-    . auto/feature
+    . $NGX_AUTO/feature
 
     if [ $ngx_found = yes ]; then
         CORE_LIBS="$CORE_LIBS -lrt"
@@ -309,7 +309,7 @@
 ngx_feature_test="cpu_set_t mask;
                   CPU_ZERO(&mask);
                   sched_setaffinity(0, sizeof(cpu_set_t), &mask)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="SO_SETFIB"
@@ -319,7 +319,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_SETFIB, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="SO_REUSEPORT"
@@ -329,7 +329,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_REUSEPORT, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="SO_ACCEPTFILTER"
@@ -339,7 +339,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # NetBSD bind to any address for transparent proxying
@@ -351,7 +351,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_BINDANY, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # Linux IP_BIND_ADDRESS_NO_PORT
@@ -364,7 +364,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # Linux transparent proxying
@@ -377,7 +377,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # FreeBSD bind to any address for transparent proxying
@@ -390,7 +390,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # BSD way to get IPv4 datagram destination address
@@ -403,7 +403,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_RECVDSTADDR, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # BSD way to set IPv4 datagram source address
@@ -416,7 +416,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_SENDSRCADDR, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # Linux way to get IPv4 datagram destination address
@@ -429,7 +429,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # RFC 3542 way to get IPv6 datagram destination address
@@ -442,7 +442,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, IPPROTO_IPV6, IPV6_RECVPKTINFO, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="TCP_DEFER_ACCEPT"
@@ -454,7 +454,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_DEFER_ACCEPT, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="TCP_KEEPIDLE"
@@ -468,7 +468,7 @@
 ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_KEEPIDLE, NULL, 0);
                   setsockopt(0, IPPROTO_TCP, TCP_KEEPINTVL, NULL, 0);
                   setsockopt(0, IPPROTO_TCP, TCP_KEEPCNT, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="TCP_FASTOPEN"
@@ -480,7 +480,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_FASTOPEN, NULL, 0)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="TCP_INFO"
@@ -498,7 +498,7 @@
                   ti.tcpi_snd_cwnd = 0;
                   ti.tcpi_rcv_space = 0;
                   getsockopt(0, IPPROTO_TCP, TCP_INFO, &ti, &optlen)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="accept4()"
@@ -508,7 +508,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="accept4(0, NULL, NULL, SOCK_NONBLOCK)"
-. auto/feature
+. $NGX_AUTO/feature
 
 if [ $NGX_FILE_AIO = YES ]; then
 
@@ -521,7 +521,7 @@
     ngx_feature_test="struct aiocb  iocb;
                       iocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
                       (void) aio_read(&iocb)"
-    . auto/feature
+    . $NGX_AUTO/feature
 
     if [ $ngx_found = yes ]; then
         CORE_SRCS="$CORE_SRCS $FILE_AIO_SRCS"
@@ -542,11 +542,11 @@
                           iocb.aio_resfd = -1;
                           (void) iocb;
                           (void) eventfd(0, 0)"
-        . auto/feature
+        . $NGX_AUTO/feature
 
         if [ $ngx_found = yes ]; then
-            have=NGX_HAVE_EVENTFD . auto/have
-            have=NGX_HAVE_SYS_EVENTFD_H . auto/have
+            have=NGX_HAVE_EVENTFD . $NGX_AUTO/have
+            have=NGX_HAVE_SYS_EVENTFD_H . $NGX_AUTO/have
             CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS"
         fi
     fi
@@ -562,10 +562,10 @@
                           iocb.aio_resfd = -1;
                           (void) iocb;
                           (void) SYS_eventfd"
-        . auto/feature
+        . $NGX_AUTO/feature
 
         if [ $ngx_found = yes ]; then
-            have=NGX_HAVE_EVENTFD . auto/have
+            have=NGX_HAVE_EVENTFD . $NGX_AUTO/have
             CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS"
         fi
     fi
@@ -589,10 +589,10 @@
     ngx_feature_path=
     ngx_feature_libs=
     ngx_feature_test="(void) eventfd(0, 0)"
-    . auto/feature
+    . $NGX_AUTO/feature
 
     if [ $ngx_found = yes ]; then
-        have=NGX_HAVE_SYS_EVENTFD_H . auto/have
+        have=NGX_HAVE_SYS_EVENTFD_H . $NGX_AUTO/have
     fi
 
     if [ $ngx_found = no ]; then
@@ -600,63 +600,63 @@
         ngx_feature="eventfd() (SYS_eventfd)"
         ngx_feature_incs="#include <sys/syscall.h>"
         ngx_feature_test="(void) SYS_eventfd"
-        . auto/feature
+        . $NGX_AUTO/feature
     fi
 fi
 
 
-have=NGX_HAVE_UNIX_DOMAIN . auto/have
+have=NGX_HAVE_UNIX_DOMAIN . $NGX_AUTO/have
 
 ngx_feature_libs=
 
 
 # C types
 
-ngx_type="int"; . auto/types/sizeof
+ngx_type="int"; . $NGX_AUTO/types/sizeof
 
-ngx_type="long"; . auto/types/sizeof
+ngx_type="long"; . $NGX_AUTO/types/sizeof
 
-ngx_type="long long"; . auto/types/sizeof
+ngx_type="long long"; . $NGX_AUTO/types/sizeof
 
-ngx_type="void *"; . auto/types/sizeof; ngx_ptr_size=$ngx_size
-ngx_param=NGX_PTR_SIZE; ngx_value=$ngx_size; . auto/types/value
+ngx_type="void *"; . $NGX_AUTO/types/sizeof; ngx_ptr_size=$ngx_size
+ngx_param=NGX_PTR_SIZE; ngx_value=$ngx_size; . $NGX_AUTO/types/value
 
 
 # POSIX types
 
 NGX_INCLUDE_AUTO_CONFIG_H="#include \"ngx_auto_config.h\""
 
-ngx_type="uint32_t"; ngx_types="u_int32_t"; . auto/types/typedef
-ngx_type="uint64_t"; ngx_types="u_int64_t"; . auto/types/typedef
+ngx_type="uint32_t"; ngx_types="u_int32_t"; . $NGX_AUTO/types/typedef
+ngx_type="uint64_t"; ngx_types="u_int64_t"; . $NGX_AUTO/types/typedef
 
-ngx_type="sig_atomic_t"; ngx_types="int"; . auto/types/typedef
-. auto/types/sizeof
-ngx_param=NGX_SIG_ATOMIC_T_SIZE; ngx_value=$ngx_size; . auto/types/value
+ngx_type="sig_atomic_t"; ngx_types="int"; . $NGX_AUTO/types/typedef
+. $NGX_AUTO/types/sizeof
+ngx_param=NGX_SIG_ATOMIC_T_SIZE; ngx_value=$ngx_size; . $NGX_AUTO/types/value
 
-ngx_type="socklen_t"; ngx_types="int"; . auto/types/typedef
+ngx_type="socklen_t"; ngx_types="int"; . $NGX_AUTO/types/typedef
 
-ngx_type="in_addr_t"; ngx_types="uint32_t u_int32_t"; . auto/types/typedef
+ngx_type="in_addr_t"; ngx_types="uint32_t u_int32_t"; . $NGX_AUTO/types/typedef
 
-ngx_type="in_port_t"; ngx_types="u_short"; . auto/types/typedef
+ngx_type="in_port_t"; ngx_types="u_short"; . $NGX_AUTO/types/typedef
 
-ngx_type="rlim_t"; ngx_types="int"; . auto/types/typedef
+ngx_type="rlim_t"; ngx_types="int"; . $NGX_AUTO/types/typedef
 
-. auto/types/uintptr_t
+. $NGX_AUTO/types/uintptr_t
 
-. auto/endianness
+. $NGX_AUTO/endianness
 
-ngx_type="size_t"; . auto/types/sizeof
-ngx_param=NGX_MAX_SIZE_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
-ngx_param=NGX_SIZE_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
+ngx_type="size_t"; . $NGX_AUTO/types/sizeof
+ngx_param=NGX_MAX_SIZE_T_VALUE; ngx_value=$ngx_max_value; . $NGX_AUTO/types/value
+ngx_param=NGX_SIZE_T_LEN; ngx_value=$ngx_max_len; . $NGX_AUTO/types/value
 
-ngx_type="off_t"; . auto/types/sizeof
-ngx_param=NGX_MAX_OFF_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
-ngx_param=NGX_OFF_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
+ngx_type="off_t"; . $NGX_AUTO/types/sizeof
+ngx_param=NGX_MAX_OFF_T_VALUE; ngx_value=$ngx_max_value; . $NGX_AUTO/types/value
+ngx_param=NGX_OFF_T_LEN; ngx_value=$ngx_max_len; . $NGX_AUTO/types/value
 
-ngx_type="time_t"; . auto/types/sizeof
-ngx_param=NGX_TIME_T_SIZE; ngx_value=$ngx_size; . auto/types/value
-ngx_param=NGX_TIME_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
-ngx_param=NGX_MAX_TIME_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
+ngx_type="time_t"; . $NGX_AUTO/types/sizeof
+ngx_param=NGX_TIME_T_SIZE; ngx_value=$ngx_size; . $NGX_AUTO/types/value
+ngx_param=NGX_TIME_T_LEN; ngx_value=$ngx_max_len; . $NGX_AUTO/types/value
+ngx_param=NGX_MAX_TIME_T_VALUE; ngx_value=$ngx_max_value; . $NGX_AUTO/types/value
 
 
 # syscalls, libc calls and some features
@@ -673,7 +673,7 @@
 ngx_feature_test="struct sockaddr_in6  sin6;
                   sin6.sin6_family = AF_INET6;
                   (void) sin6"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="setproctitle()"
@@ -683,7 +683,7 @@
 ngx_feature_path=
 ngx_feature_libs=$NGX_SETPROCTITLE_LIB
 ngx_feature_test="setproctitle(\"test\");"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="pread()"
@@ -694,7 +694,7 @@
 ngx_feature_libs=
 ngx_feature_test="char buf[1]; ssize_t n; n = pread(0, buf, 1, 0);
                   if (n == -1) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="pwrite()"
@@ -705,7 +705,7 @@
 ngx_feature_libs=
 ngx_feature_test="char buf[1]; ssize_t n; n = pwrite(1, buf, 1, 0);
                   if (n == -1) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 # pwritev() was introduced in FreeBSD 6 and Linux 2.6.30, glibc 2.10
@@ -721,7 +721,7 @@
                   vec[0].iov_len = 1;
                   n = pwritev(1, vec, 1, 0);
                   if (n == -1) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="sys_nerr"
@@ -732,7 +732,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test='printf("%d", sys_nerr);'
-. auto/feature
+. $NGX_AUTO/feature
 
 
 if [ $ngx_found = no ]; then
@@ -746,7 +746,7 @@
     ngx_feature_path=
     ngx_feature_libs=
     ngx_feature_test='printf("%d", _sys_nerr);'
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -774,7 +774,7 @@
                           }
                       }
                       printf("%d", n);'
-    . auto/feature
+    . $NGX_AUTO/feature
 fi
 
 
@@ -785,7 +785,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="struct tm t; time_t c=0; localtime_r(&c, &t)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="posix_memalign()"
@@ -796,7 +796,7 @@
 ngx_feature_libs=
 ngx_feature_test="void *p; int n; n = posix_memalign(&p, 4096, 4096);
                   if (n != 0) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="memalign()"
@@ -808,7 +808,7 @@
 ngx_feature_libs=
 ngx_feature_test="void *p; p = memalign(4096, 4096);
                   if (p == NULL) return 1"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="mmap(MAP_ANON|MAP_SHARED)"
@@ -821,7 +821,7 @@
                   p = mmap(NULL, 4096, PROT_READ|PROT_WRITE,
                            MAP_ANON|MAP_SHARED, -1, 0);
                   if (p == MAP_FAILED) return 1;"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature='mmap("/dev/zero", MAP_SHARED)'
@@ -836,7 +836,7 @@
                   fd = open("/dev/zero", O_RDWR);
                   p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
                   if (p == MAP_FAILED) return 1;'
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="System V shared memory"
@@ -850,7 +850,7 @@
                   id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT));
                   if (id == -1) return 1;
                   shmctl(id, IPC_RMID, NULL);"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="POSIX semaphores"
@@ -862,7 +862,7 @@
 ngx_feature_test="sem_t  sem;
                   if (sem_init(&sem, 1, 0) == -1) return 1;
                   sem_destroy(&sem);"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 if [ $ngx_found = no ]; then
@@ -870,7 +870,7 @@
     # Linux has POSIX semaphores in libpthread
     ngx_feature="POSIX semaphores in libpthread"
     ngx_feature_libs=-lpthread
-    . auto/feature
+    . $NGX_AUTO/feature
 
     if [ $ngx_found = yes ]; then
         CORE_LIBS="$CORE_LIBS -lpthread"
@@ -883,7 +883,7 @@
     # Solaris has POSIX semaphores in librt
     ngx_feature="POSIX semaphores in librt"
     ngx_feature_libs=-lrt
-    . auto/feature
+    . $NGX_AUTO/feature
 
     if [ $ngx_found = yes ]; then
         CORE_LIBS="$CORE_LIBS -lrt"
@@ -900,7 +900,7 @@
 ngx_feature_libs=
 ngx_feature_test="struct msghdr  msg;
                   printf(\"%d\", (int) sizeof(msg.msg_control))"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="ioctl(FIONBIO)"
@@ -912,7 +912,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="int i = FIONBIO; printf(\"%d\", i)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="struct tm.tm_gmtoff"
@@ -924,7 +924,7 @@
 ngx_feature_libs=
 ngx_feature_test="struct tm  tm; tm.tm_gmtoff = 0;
                   printf(\"%d\", (int) tm.tm_gmtoff)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="struct dirent.d_namlen"
@@ -936,7 +936,7 @@
 ngx_feature_libs=
 ngx_feature_test="struct dirent  dir; dir.d_namlen = 0;
                   printf(\"%d\", (int) dir.d_namlen)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="struct dirent.d_type"
@@ -948,7 +948,7 @@
 ngx_feature_libs=
 ngx_feature_test="struct dirent  dir; dir.d_type = DT_REG;
                   printf(\"%d\", (int) dir.d_type)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="sysconf(_SC_NPROCESSORS_ONLN)"
@@ -958,7 +958,7 @@
 ngx_feature_path=
 ngx_feature_libs=
 ngx_feature_test="sysconf(_SC_NPROCESSORS_ONLN)"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="openat(), fstatat()"
@@ -972,7 +972,7 @@
 ngx_feature_test="struct stat sb;
                   openat(AT_FDCWD, \".\", O_RDONLY|O_NOFOLLOW);
                   fstatat(AT_FDCWD, \".\", &sb, AT_SYMLINK_NOFOLLOW);"
-. auto/feature
+. $NGX_AUTO/feature
 
 
 ngx_feature="getaddrinfo()"
@@ -986,4 +986,4 @@
 ngx_feature_test='struct addrinfo *res;
                   if (getaddrinfo("localhost", NULL, NULL, &res) != 0) return 1;
                   freeaddrinfo(res)'
-. auto/feature
+. $NGX_AUTO/feature
diff --git a/build.bzl b/build.bzl
new file mode 100644
index 0000000..331b58c
--- /dev/null
+++ b/build.bzl
@@ -0,0 +1,696 @@
+# Copyright (C) 2015-2017 Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+_common_copts = [
+    "-fno-common",
+    "-fvisibility=hidden",
+    "-Wall",
+    "-Werror",
+    "-Wextra",
+    "-Wformat=2",
+    "-Wlong-long",
+    "-Wpointer-arith",
+    "-Wshadow",
+    "-Wno-deprecated-declarations",
+    "-Wno-unused-parameter",
+]
+
+nginx_copts = _common_copts + [
+    "-Wmissing-prototypes",
+    "-Wold-style-definition",
+    "-Wstrict-prototypes",
+]
+
+nginx_cxxopts = _common_copts + [
+    "-Wmissing-declarations",
+]
+
+_NGX_BROTLI_BUILD_FILE = """
+# Copyright (C) 2015-2017 Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+licenses(["notice"])  # BSD license
+
+exports_files(["LICENSE"])
+
+load("{nginx}:build.bzl", "nginx_copts")
+
+cc_library(
+    name = "http_brotli_filter",
+    srcs = [
+        "src/ngx_http_brotli_filter_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_BROTLI_FILTER",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+        "//external:brotli_enc",
+        "{nginx}:core",
+        "{nginx}:http",
+    ],
+)
+
+cc_library(
+    name = "http_brotli_static",
+    srcs = [
+        "src/ngx_http_brotli_static_module.c",
+    ],
+    copts = nginx_copts,
+    defines = [
+        "NGX_HTTP_BROTLI_STATIC",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+        "{nginx}:core",
+        "{nginx}:http",
+    ],
+)
+
+cc_binary(
+    name = "nginx",
+    srcs = [
+        "{nginx}:modules",
+    ],
+    copts = nginx_copts,
+    deps = [
+        ":http_brotli_filter",
+        ":http_brotli_static",
+        "{nginx}:core",
+    ],
+)
+"""
+
+_PCRE_BUILD_FILE = """
+# Copyright (C) 2015-2017 Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+licenses(["notice"])
+
+exports_files(["LICENCE"])
+
+genrule(
+    name = "config_h",
+    srcs = [
+        "config.h.generic",
+    ],
+    outs = [
+        "config.h",
+    ],
+    cmd = "cp -p $(<) $(@)",
+)
+
+genrule(
+    name = "pcre_h",
+    srcs = [
+        "pcre.h.generic",
+    ],
+    outs = [
+        "pcre.h",
+    ],
+    cmd = "cp -p $(<) $(@)",
+)
+
+genrule(
+    name = "pcre_chartables_c",
+    srcs = [
+        "pcre_chartables.c.dist",
+    ],
+    outs = [
+        "pcre_chartables.c",
+    ],
+    cmd = "cp -p $(<) $(@)",
+)
+
+cc_library(
+    name = "sljit",
+    srcs = [
+        "sljit/sljitConfig.h",
+        "sljit/sljitConfigInternal.h",
+        "sljit/sljitLir.h",
+    ],
+    hdrs = [
+        "sljit/sljitExecAllocator.c",
+        "sljit/sljitLir.c",
+        "sljit/sljitNativeX86_64.c",
+        "sljit/sljitNativeX86_common.c",
+        "sljit/sljitUtils.c",
+    ],
+)
+
+cc_library(
+    name = "pcre",
+    srcs = [
+        "config.h",
+        "pcre_byte_order.c",
+        "pcre_chartables.c",
+        "pcre_compile.c",
+        "pcre_config.c",
+        "pcre_dfa_exec.c",
+        "pcre_exec.c",
+        "pcre_fullinfo.c",
+        "pcre_get.c",
+        "pcre_globals.c",
+        "pcre_internal.h",
+        "pcre_jit_compile.c",
+        "pcre_maketables.c",
+        "pcre_newline.c",
+        "pcre_ord2utf8.c",
+        "pcre_refcount.c",
+        "pcre_study.c",
+        "pcre_tables.c",
+        "pcre_ucd.c",
+        "pcre_valid_utf8.c",
+        "pcre_version.c",
+        "pcre_xclass.c",
+        "ucp.h",
+    ],
+    hdrs = [
+        "pcre.h",
+    ],
+    copts = [
+        "-DHAVE_CONFIG_H",
+        "-DHAVE_MEMMOVE",
+        "-DHAVE_STDINT_H",
+        "-DNO_RECURSE",
+        "-DSUPPORT_JIT",
+        "-DSUPPORT_PCRE8",
+        "-DSUPPORT_UCP",
+        "-DSUPPORT_UTF",
+        "-Wno-maybe-uninitialized",
+        "-Wno-unknown-warning-option",
+    ],
+    includes = [
+        ".",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+        ":sljit",
+    ],
+)
+"""
+
+_PKGOSS_BUILD_FILE = """
+# Copyright (C) 2015-2017 Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+licenses(["notice"])
+
+exports_files(["README"])
+
+load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar")
+
+genrule(
+    name = "debian_nginx_preinst",
+    srcs = [
+        "debian/nginx.preinst",
+    ],
+    outs = [
+        "nginx.preinst",
+    ],
+    cmd = "sed -e 's|#DEBHELPER#||g'" +
+          " < $(<) > $(@)",
+)
+
+filegroup(
+    name = "debian_preinst",
+    srcs = [
+        "nginx.preinst",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+)
+
+genrule(
+    name = "debian_nginx_postinst",
+    srcs = [
+        "debian/nginx.postinst",
+    ],
+    outs = [
+        "nginx.postinst",
+    ],
+    cmd = "sed -e 's|#DEBHELPER#|" +
+          "if [ -x \\"/etc/init.d/nginx\\" ]; then\\\\n" +
+          "\\\\tupdate-rc.d nginx defaults >/dev/null \\|\\| exit $$?\\\\n" +
+          "fi\\\\n" +
+          "|g'" +
+          " < $(<) > $(@)",
+)
+
+filegroup(
+    name = "debian_postinst",
+    srcs = [
+        "nginx.postinst",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+)
+
+genrule(
+    name = "debian_nginx_prerm",
+    srcs = [
+        "debian/nginx.prerm",
+    ],
+    outs = [
+        "nginx.prerm",
+    ],
+    cmd = "sed -e 's|#DEBHELPER#||g'" +
+          " < $(<) > $(@)",
+)
+
+filegroup(
+    name = "debian_prerm",
+    srcs = [
+        "nginx.prerm",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+)
+
+genrule(
+    name = "debian_nginx_postrm",
+    srcs = [
+        "debian/nginx.postrm",
+    ],
+    outs = [
+        "nginx.postrm",
+    ],
+    cmd = "sed -e 's|#DEBHELPER#|" +
+          "if [ \\"$$1\\" = \\"purge\\" ] ; then\\\\n" +
+          "\\\\tupdate-rc.d nginx remove >/dev/null\\\\n" +
+          "fi\\\\n" +
+          "\\\\n" +
+          "if [ -d /run/systemd/system ] ; then\\\\n" +
+          "\\\\tsystemctl --system daemon-reload >/dev/null \\|\\| true\\\\n" +
+          "fi\\\\n" +
+          "|g'" +
+          " < $(<) > $(@)",
+)
+
+filegroup(
+    name = "debian_postrm",
+    srcs = [
+        "nginx.postrm",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+)
+
+genrule(
+    name = "debian_etc_default_nginx",
+    srcs = [
+        "debian/nginx.default",
+    ],
+    outs = [
+        "etc/default/nginx",
+    ],
+    cmd = "cp -p $(<) $(@)",
+)
+
+genrule(
+    name = "debian_etc_init_d_nginx",
+    srcs = [
+        "debian/nginx.init.in",
+    ],
+    outs = [
+        "etc/init.d/nginx",
+    ],
+    cmd = "sed -e 's|%%PROVIDES%%|nginx|g'" +
+          " -e 's|%%DEFAULTSTART%%|2 3 4 5|g'" +
+          " -e 's|%%DEFAULTSTOP%%|0 1 6|g'" +
+          " < $(<) > $(@)",
+)
+
+genrule(
+    name = "debian_etc_logrotate_d_nginx",
+    srcs = [
+        "debian/nginx.logrotate",
+    ],
+    outs = [
+        "etc/logrotate.d/nginx",
+    ],
+    cmd = "cp -p $(<) $(@)",
+)
+
+genrule(
+    name = "debian_etc_nginx_conf_d_default_conf",
+    srcs = [
+        "debian/nginx.vh.default.conf",
+    ],
+    outs = [
+        "etc/nginx/conf.d/default.conf",
+    ],
+    cmd = "cp -p $(<) $(@)",
+)
+
+genrule(
+    name = "debian_etc_nginx_nginx_conf",
+    srcs = [
+        "debian/nginx.conf",
+    ],
+    outs = [
+        "etc/nginx/nginx.conf",
+    ],
+    cmd = "cp -p $(<) $(@)",
+)
+
+genrule(
+    name = "debian_usr_share_man_man8_nginx_8",
+    srcs = [
+        "{nginx}:docs/man/nginx.8",
+    ],
+    outs = [
+        "usr/share/man/man8/nginx.8",
+    ],
+    cmd = "sed -e 's|%%PREFIX%%|/etc/nginx|g'" +
+          " -e 's|%%CONF_PATH%%|/etc/nginx/nginx.conf|g'" +
+          " -e 's|%%ERROR_LOG_PATH%%|/var/log/nginx/error.log|g'" +
+          " -e 's|%%PID_PATH%%|/var/run/nginx.pid|g'" +
+          " < $(<) > $(@)",
+)
+
+genrule(
+    name = "debian_var_cache_nginx",
+    outs = [
+        "var/cache/nginx/.empty",
+    ],
+    cmd = "touch $(@)",
+)
+
+genrule(
+    name = "debian_var_log_nginx",
+    outs = [
+        "var/log/nginx/.empty",
+    ],
+    cmd = "touch $(@)",
+)
+
+pkg_tar(
+    name = "debian_etc_nginx",
+    files = [
+        "{nginx}:config_includes",
+    ],
+    mode = "0644",
+    package_dir = "/etc/nginx",
+)
+
+pkg_tar(
+    name = "debian_usr_share_nginx_html",
+    files = [
+        "{nginx}:html_files",
+    ],
+    mode = "0644",
+    package_dir = "/usr/share/nginx/html",
+)
+
+pkg_tar(
+    name = "debian_var",
+    files = [
+        "var/cache/nginx/.empty",
+        "var/log/nginx/.empty",
+    ],
+    mode = "0644",
+    strip_prefix = ".",
+)
+"""
+
+_PKGOSS_BUILD_FILE_TAIL = """
+pkg_tar(
+    name = "debian_overlay",
+    files = [
+        "etc/default/nginx",
+        "etc/init.d/nginx",
+        "etc/logrotate.d/nginx",
+        "etc/nginx/conf.d/default.conf",
+        "etc/nginx/nginx.conf",
+        "usr/share/man/man8/nginx.8",
+    ],
+    mode = "0644",
+    modes = {
+        "etc/init.d/nginx": "0755",
+    },
+    strip_prefix = ".",
+    visibility = [
+        "//visibility:public",
+    ],
+    deps = [
+        ":debian_etc_nginx",
+        ":debian_usr_share_nginx_html",
+        ":debian_var",
+    ],
+)
+"""
+
+_ZLIB_BUILD_FILE = """
+# Copyright (C) 2015-2017 Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+licenses(["notice"])
+
+exports_files(["README"])
+
+cc_library(
+    name = "zlib",
+    srcs = [
+        "adler32.c",
+        "crc32.c",
+        "crc32.h",
+        "deflate.c",
+        "deflate.h",
+        "infback.c",
+        "inffast.c",
+        "inffast.h",
+        "inffixed.h",
+        "inflate.c",
+        "inflate.h",
+        "inftrees.c",
+        "inftrees.h",
+        "trees.c",
+        "trees.h",
+        "zconf.h",
+        "zutil.c",
+        "zutil.h",
+    ],
+    hdrs = [
+        "zlib.h",
+    ],
+    defines = [
+        "Z_SOLO",
+    ],
+    visibility = [
+        "//visibility:public",
+    ],
+)
+"""
+
+def nginx_repositories_boringssl(bind):
+    native.git_repository(
+        name = "boringssl",
+        commit = "16efcb2dba4690b9940d9b95ef703f1bbd07494d",  # 2017-03-20
+        remote = "https://boringssl.googlesource.com/boringssl",
+    )
+
+    if bind:
+        native.bind(
+            name = "boringssl_crypto",
+            actual = "@boringssl//:crypto"
+        )
+
+        native.bind(
+            name = "boringssl_ssl",
+            actual = "@boringssl//:ssl"
+        )
+
+def nginx_repositories_brotli(bind):
+    native.git_repository(
+        name = "org_brotli",
+        commit = "222564a95d9ab58865a096b8d9f7324ea5f2e03e",  # 2016-12-02
+        remote = "https://github.com/google/brotli.git",
+    )
+
+    if bind:
+        native.bind(
+            name = "brotli_enc",
+            actual = "@org_brotli//:brotlienc"
+        )
+
+        native.bind(
+            name = "brotli_dec",
+            actual = "@org_brotli//:brotlidec"
+        )
+
+def nginx_repositories_ngx_brotli(nginx):
+    native.new_git_repository(
+        name = "ngx_brotli",
+        build_file_content = _NGX_BROTLI_BUILD_FILE.format(nginx = nginx),
+        commit = "5ead1ada782b18c7b38a3c2798a40a334801c7b6",  # 2016-12-05
+        remote = "https://nginx.googlesource.com/ngx_brotli",
+    )
+
+def nginx_repositories_pcre(bind):
+    native.new_http_archive(
+        name = "nginx_pcre",
+        build_file_content = _PCRE_BUILD_FILE,
+        sha256 = "1d75ce90ea3f81ee080cdc04e68c9c25a9fb984861a0618be7bbf676b18eda3e",
+        strip_prefix = "pcre-8.40",
+        url = "http://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.40.tar.gz",
+    )
+
+    if bind:
+        native.bind(
+            name = "pcre",
+            actual = "@nginx_pcre//:pcre"
+        )
+
+def nginx_repositories_pkgoss(nginx):
+    native.new_git_repository(
+        name = "nginx_pkgoss",
+        build_file_content = _PKGOSS_BUILD_FILE.format(nginx = nginx) +
+                             _PKGOSS_BUILD_FILE_TAIL,
+        commit = "9ff23479da00823d9e0e93288f9050d6b6c8328a",  # nginx-1.13.1
+        remote = "https://nginx.googlesource.com/nginx-pkgoss",
+    )
+
+def nginx_repositories_zlib(bind):
+    native.new_git_repository(
+        name = "nginx_zlib",
+        build_file_content = _ZLIB_BUILD_FILE,
+        commit = "cacf7f1d4e3d44d871b605da3b647f07d718623f",  # v1.2.11
+        remote = "https://github.com/madler/zlib.git",
+    )
+
+    if bind:
+        native.bind(
+            name = "zlib",
+            actual = "@nginx_zlib//:zlib"
+        )
+
+def nginx_repositories(bind = False, nginx = "@nginx//", ngx_brotli = False):
+    # core dependencies
+    nginx_repositories_boringssl(bind)
+    nginx_repositories_pcre(bind)
+    nginx_repositories_zlib(bind)
+
+    # packaging
+    nginx_repositories_pkgoss(nginx)
+
+    # ngx_brotli + dependencies
+    if ngx_brotli:
+        nginx_repositories_ngx_brotli(nginx)
+        nginx_repositories_brotli(bind)
diff --git a/src/core/nginx.c b/src/core/nginx.c
index abaa50d..903d2e1 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -9,6 +9,10 @@
 #include <ngx_core.h>
 #include <nginx.h>
 
+#if (NGX_BAZEL)
+#include <ngx_modules.h>
+#endif
+
 
 static void ngx_show_version_info(void);
 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle);
@@ -192,7 +196,11 @@
 
 
 int ngx_cdecl
+#if (NGX_BAZEL || NGX_NO_MAIN)
+ngx_main(int argc, char *const *argv)
+#else
 main(int argc, char *const *argv)
+#endif
 {
     ngx_buf_t        *b;
     ngx_log_t        *log;
@@ -416,6 +424,10 @@
 
     if (ngx_show_configure) {
 
+#if (NGX_BAZEL)
+        ngx_write_stderr("built by Bazel" NGX_LINEFEED);
+#endif
+
 #ifdef NGX_COMPILER
         ngx_write_stderr("built by " NGX_COMPILER NGX_LINEFEED);
 #endif
@@ -436,7 +448,11 @@
 #endif
 #endif
 
+#if (NGX_BAZEL)
+        ngx_show_configure_options();
+#else
         ngx_write_stderr("configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
+#endif
     }
 }
 
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 8cc2d80..9386644 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -9,9 +9,13 @@
 #define _NGINX_H_INCLUDED_
 
 
+#ifndef NGINX_NAME
+#define NGINX_NAME         "nginx"
+#endif
+
 #define nginx_version      1013001
 #define NGINX_VERSION      "1.13.1"
-#define NGINX_VER          "nginx/" NGINX_VERSION
+#define NGINX_VER          NGINX_NAME "/" NGINX_VERSION
 
 #ifdef NGX_BUILD
 #define NGINX_VER_BUILD    NGINX_VER " (" NGX_BUILD ")"
diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h
index 2069373..3fc751d 100644
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -64,7 +64,6 @@
 #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)
diff --git a/src/core/ngx_crc.h b/src/core/ngx_crc.h
deleted file mode 100644
index 35981bc..0000000
--- a/src/core/ngx_crc.h
+++ /dev/null
@@ -1,39 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_CRC_H_INCLUDED_
-#define _NGX_CRC_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/* 32-bit crc16 */
-
-static ngx_inline uint32_t
-ngx_crc(u_char *data, size_t len)
-{
-    uint32_t  sum;
-
-    for (sum = 0; len; len--) {
-
-        /*
-         * gcc 2.95.2 x86 and icc 7.1.006 compile
-         * that operator into the single "rol" opcode,
-         * msvc 6.0sp2 compiles it into four opcodes.
-         */
-        sum = sum >> 1 | sum << 31;
-
-        sum += *data++;
-    }
-
-    return sum;
-}
-
-
-#endif /* _NGX_CRC_H_INCLUDED_ */
diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
index 2b48ccb..24b2add 100644
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -120,6 +120,10 @@
 #define ngx_is_init_cycle(cycle)  (cycle->conf_ctx == NULL)
 
 
+#if (NGX_BAZEL || NGX_NO_MAIN)
+int ngx_cdecl ngx_main(int argc, char *const *argv);
+#endif
+
 ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle);
 ngx_int_t ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log);
 void ngx_delete_pidfile(ngx_cycle_t *cycle);
diff --git a/src/core/ngx_md5.h b/src/core/ngx_md5.h
index 713b614..a94e39a 100644
--- a/src/core/ngx_md5.h
+++ b/src/core/ngx_md5.h
@@ -13,6 +13,22 @@
 #include <ngx_core.h>
 
 
+#if (NGX_HAVE_OPENSSL_MD5_H)
+
+#include <openssl/md5.h>
+
+
+typedef MD5_CTX  ngx_md5_t;
+
+
+#define ngx_md5_init    MD5_Init
+#define ngx_md5_update  MD5_Update
+#define ngx_md5_final   MD5_Final
+
+
+#else /* !NGX_HAVE_OPENSSL_MD5_H */
+
+
 typedef struct {
     uint64_t  bytes;
     uint32_t  a, b, c, d;
@@ -25,4 +41,6 @@
 void ngx_md5_final(u_char result[16], ngx_md5_t *ctx);
 
 
+#endif
+
 #endif /* _NGX_MD5_H_INCLUDED_ */
diff --git a/src/core/ngx_module.h b/src/core/ngx_module.h
index 8cf3210..1641aa8 100644
--- a/src/core/ngx_module.h
+++ b/src/core/ngx_module.h
@@ -147,7 +147,7 @@
 
 #define NGX_MODULE_SIGNATURE_25  "1"
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
 #define NGX_MODULE_SIGNATURE_26  "1"
 #else
 #define NGX_MODULE_SIGNATURE_26  "0"
@@ -155,25 +155,25 @@
 
 #define NGX_MODULE_SIGNATURE_27  "1"
 
-#if (NGX_HTTP_X_FORWARDED_FOR)
+#if (NGX_HTTP_X_FORWARDED_FOR || NGX_COMPAT)
 #define NGX_MODULE_SIGNATURE_28  "1"
 #else
 #define NGX_MODULE_SIGNATURE_28  "0"
 #endif
 
-#if (NGX_HTTP_REALIP)
+#if (NGX_HTTP_REALIP || NGX_COMPAT)
 #define NGX_MODULE_SIGNATURE_29  "1"
 #else
 #define NGX_MODULE_SIGNATURE_29  "0"
 #endif
 
-#if (NGX_HTTP_HEADERS)
+#if (NGX_HTTP_HEADERS || NGX_COMPAT)
 #define NGX_MODULE_SIGNATURE_30  "1"
 #else
 #define NGX_MODULE_SIGNATURE_30  "0"
 #endif
 
-#if (NGX_HTTP_DAV)
+#if (NGX_HTTP_DAV || NGX_COMPAT)
 #define NGX_MODULE_SIGNATURE_31  "1"
 #else
 #define NGX_MODULE_SIGNATURE_31  "0"
@@ -185,7 +185,7 @@
 #define NGX_MODULE_SIGNATURE_32  "0"
 #endif
 
-#if (NGX_HTTP_UPSTREAM_ZONE)
+#if (NGX_HTTP_UPSTREAM_ZONE || NGX_COMPAT)
 #define NGX_MODULE_SIGNATURE_33  "1"
 #else
 #define NGX_MODULE_SIGNATURE_33  "0"
diff --git a/src/core/ngx_rwlock.c b/src/core/ngx_rwlock.c
index 905de78..f368941 100644
--- a/src/core/ngx_rwlock.c
+++ b/src/core/ngx_rwlock.c
@@ -23,7 +23,7 @@
 
     for ( ;; ) {
 
-        if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK)) {
+        if (ngx_trylock(lock, NGX_RWLOCK_WLOCK)) {
             return;
         }
 
@@ -35,9 +35,7 @@
                     ngx_cpu_pause();
                 }
 
-                if (*lock == 0
-                    && ngx_atomic_cmp_set(lock, 0, NGX_RWLOCK_WLOCK))
-                {
+                if (ngx_trylock(lock, NGX_RWLOCK_WLOCK)) {
                     return;
                 }
             }
@@ -55,7 +53,7 @@
     ngx_atomic_uint_t  readers;
 
     for ( ;; ) {
-        readers = *lock;
+        readers = ngx_atomic_load(lock);
 
         if (readers != NGX_RWLOCK_WLOCK
             && ngx_atomic_cmp_set(lock, readers, readers + 1))
@@ -71,7 +69,7 @@
                     ngx_cpu_pause();
                 }
 
-                readers = *lock;
+                readers = ngx_atomic_load(lock);
 
                 if (readers != NGX_RWLOCK_WLOCK
                     && ngx_atomic_cmp_set(lock, readers, readers + 1))
@@ -91,10 +89,10 @@
 {
     ngx_atomic_uint_t  readers;
 
-    readers = *lock;
+    readers = ngx_atomic_load(lock);
 
     if (readers == NGX_RWLOCK_WLOCK) {
-        *lock = 0;
+        ngx_atomic_store(lock, 0);
         return;
     }
 
@@ -104,14 +102,14 @@
             return;
         }
 
-        readers = *lock;
+        readers = ngx_atomic_load(lock);
     }
 }
 
 
 #else
 
-#if (NGX_HTTP_UPSTREAM_ZONE || NGX_STREAM_UPSTREAM_ZONE)
+#if (NGX_HTTP_UPSTREAM_ZONE || NGX_STREAM_UPSTREAM_ZONE || NGX_COMPAT)
 
 #error ngx_atomic_cmp_set() is not defined!
 
diff --git a/src/core/ngx_sha1.h b/src/core/ngx_sha1.h
index 4a98f71..feb4c50 100644
--- a/src/core/ngx_sha1.h
+++ b/src/core/ngx_sha1.h
@@ -13,6 +13,22 @@
 #include <ngx_core.h>
 
 
+#if (NGX_HAVE_OPENSSL_SHA1_H)
+
+#include <openssl/sha.h>
+
+
+typedef SHA_CTX  ngx_sha1_t;
+
+
+#define ngx_sha1_init    SHA1_Init
+#define ngx_sha1_update  SHA1_Update
+#define ngx_sha1_final   SHA1_Final
+
+
+#else /* !NGX_HAVE_OPENSSL_SHA1_H */
+
+
 typedef struct {
     uint64_t  bytes;
     uint32_t  a, b, c, d, e, f;
@@ -25,4 +41,6 @@
 void ngx_sha1_final(u_char result[20], ngx_sha1_t *ctx);
 
 
+#endif
+
 #endif /* _NGX_SHA1_H_INCLUDED_ */
diff --git a/src/core/ngx_shmtx.c b/src/core/ngx_shmtx.c
index a255903..44f4917 100644
--- a/src/core/ngx_shmtx.c
+++ b/src/core/ngx_shmtx.c
@@ -62,7 +62,7 @@
 ngx_uint_t
 ngx_shmtx_trylock(ngx_shmtx_t *mtx)
 {
-    return (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid));
+    return ngx_trylock(mtx->lock, ngx_pid);
 }
 
 
@@ -75,7 +75,7 @@
 
     for ( ;; ) {
 
-        if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) {
+        if (ngx_trylock(mtx->lock, ngx_pid)) {
             return;
         }
 
@@ -87,9 +87,7 @@
                     ngx_cpu_pause();
                 }
 
-                if (*mtx->lock == 0
-                    && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid))
-                {
+                if (ngx_trylock(mtx->lock, ngx_pid)) {
                     return;
                 }
             }
@@ -100,7 +98,7 @@
         if (mtx->semaphore) {
             (void) ngx_atomic_fetch_add(mtx->wait, 1);
 
-            if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) {
+            if (ngx_trylock(mtx->lock, ngx_pid)) {
                 (void) ngx_atomic_fetch_add(mtx->wait, -1);
                 return;
             }
@@ -173,7 +171,7 @@
 
     for ( ;; ) {
 
-        wait = *mtx->wait;
+        wait = ngx_atomic_load(mtx->wait);
 
         if ((ngx_atomic_int_t) wait <= 0) {
             return;
diff --git a/src/core/ngx_spinlock.c b/src/core/ngx_spinlock.c
index 9c93afa..6bcef15 100644
--- a/src/core/ngx_spinlock.c
+++ b/src/core/ngx_spinlock.c
@@ -19,7 +19,7 @@
 
     for ( ;; ) {
 
-        if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
+        if (ngx_trylock(lock, value)) {
             return;
         }
 
@@ -31,7 +31,7 @@
                     ngx_cpu_pause();
                 }
 
-                if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
+                if (ngx_trylock(lock, value)) {
                     return;
                 }
             }
diff --git a/src/core/ngx_thread_pool.c b/src/core/ngx_thread_pool.c
index 7fb0f7f..5a6eb63 100644
--- a/src/core/ngx_thread_pool.c
+++ b/src/core/ngx_thread_pool.c
@@ -99,6 +99,7 @@
 static ngx_str_t  ngx_thread_pool_default = ngx_string("default");
 
 static ngx_uint_t               ngx_thread_pool_task_id;
+static ngx_event_t              ngx_thread_pool_notify;
 static ngx_atomic_t             ngx_thread_pool_done_lock;
 static ngx_thread_pool_queue_t  ngx_thread_pool_done;
 
@@ -111,12 +112,6 @@
     ngx_uint_t      n;
     pthread_attr_t  attr;
 
-    if (ngx_notify == NULL) {
-        ngx_log_error(NGX_LOG_ALERT, log, 0,
-               "the configured event method cannot be used with thread pools");
-        return NGX_ERROR;
-    }
-
     ngx_thread_pool_queue_init(&tp->queue);
 
     if (ngx_thread_mutex_create(&tp->mtx, log) != NGX_OK) {
@@ -171,9 +166,9 @@
 static void
 ngx_thread_pool_destroy(ngx_thread_pool_t *tp)
 {
-    ngx_uint_t           n;
-    ngx_thread_task_t    task;
-    volatile ngx_uint_t  lock;
+    ngx_uint_t         n;
+    ngx_atomic_t       lock;
+    ngx_thread_task_t  task;
 
     ngx_memzero(&task, sizeof(ngx_thread_task_t));
 
@@ -181,13 +176,13 @@
     task.ctx = (void *) &lock;
 
     for (n = 0; n < tp->threads; n++) {
-        lock = 1;
+        ngx_atomic_store(&lock, 1);
 
         if (ngx_thread_task_post(tp, &task) != NGX_OK) {
             return;
         }
 
-        while (lock) {
+        while (ngx_atomic_load(&lock) != 0) {
             ngx_sched_yield();
         }
 
@@ -203,9 +198,9 @@
 static void
 ngx_thread_pool_exit_handler(void *data, ngx_log_t *log)
 {
-    ngx_uint_t *lock = data;
+    ngx_atomic_uint_t  *lock = data;
 
-    *lock = 0;
+    ngx_atomic_store(lock, 0);
 
     pthread_exit(0);
 }
@@ -356,7 +351,7 @@
 
         ngx_unlock(&ngx_thread_pool_done_lock);
 
-        (void) ngx_notify(ngx_thread_pool_handler);
+        (void) ngx_notify(&ngx_thread_pool_notify);
     }
 }
 
@@ -595,10 +590,22 @@
     tcf = (ngx_thread_pool_conf_t *) ngx_get_conf(cycle->conf_ctx,
                                                   ngx_thread_pool_module);
 
-    if (tcf == NULL) {
+    if (tcf == NULL || tcf->pools.nelts == 0) {
         return NGX_OK;
     }
 
+    if (ngx_notify_init == NULL || ngx_notify == NULL) {
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+               "the configured event method cannot be used with thread pools");
+        return NGX_ERROR;
+    }
+
+    if (ngx_notify_init(&ngx_thread_pool_notify, ngx_thread_pool_handler, cycle)
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
     ngx_thread_pool_queue_init(&ngx_thread_pool_done);
 
     tpp = tcf->pools.elts;
@@ -629,7 +636,7 @@
     tcf = (ngx_thread_pool_conf_t *) ngx_get_conf(cycle->conf_ctx,
                                                   ngx_thread_pool_module);
 
-    if (tcf == NULL) {
+    if (tcf == NULL || tcf->pools.nelts == 0) {
         return;
     }
 
@@ -638,4 +645,8 @@
     for (i = 0; i < tcf->pools.nelts; i++) {
         ngx_thread_pool_destroy(tpp[i]);
     }
+
+    if (ngx_notify_close != NULL) {
+        ngx_notify_close(&ngx_thread_pool_notify);
+    }
 }
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c
index 843314a..558804e 100644
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -84,7 +84,7 @@
     ngx_time_t      *tp;
     struct timeval   tv;
 
-    if (!ngx_trylock(&ngx_time_lock)) {
+    if (!ngx_trylock(&ngx_time_lock, 1)) {
         return;
     }
 
@@ -200,7 +200,7 @@
     ngx_time_t      *tp;
     struct timeval   tv;
 
-    if (!ngx_trylock(&ngx_time_lock)) {
+    if (!ngx_trylock(&ngx_time_lock, 1)) {
         return;
     }
 
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c
index ee9f854..b7bf98d 100644
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -90,7 +90,9 @@
         ngx_devpoll_del_event,             /* disable an event */
         NULL,                              /* add an connection */
         NULL,                              /* delete an connection */
+        NULL,                              /* init a notify */
         NULL,                              /* trigger a notify */
+        NULL,                              /* close a notify */
         ngx_devpoll_process_events,        /* process the events */
         ngx_devpoll_init,                  /* init the events */
         ngx_devpoll_done,                  /* done the events */
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index 76aee08..09e5e48 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -103,8 +103,10 @@
 
 static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
 #if (NGX_HAVE_EVENTFD)
-static ngx_int_t ngx_epoll_notify_init(ngx_log_t *log);
+static ngx_int_t ngx_epoll_notify_init(ngx_event_t *notify_event,
+    ngx_event_handler_pt handler, ngx_cycle_t *cycle);
 static void ngx_epoll_notify_handler(ngx_event_t *ev);
+static void ngx_epoll_notify_close(ngx_event_t *notify_event);
 #endif
 #if (NGX_HAVE_EPOLLRDHUP)
 static void ngx_epoll_test_rdhup(ngx_cycle_t *cycle);
@@ -118,7 +120,7 @@
 static ngx_int_t ngx_epoll_del_connection(ngx_connection_t *c,
     ngx_uint_t flags);
 #if (NGX_HAVE_EVENTFD)
-static ngx_int_t ngx_epoll_notify(ngx_event_handler_pt handler);
+static ngx_int_t ngx_epoll_notify(ngx_event_t *notify_event);
 #endif
 static ngx_int_t ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
     ngx_uint_t flags);
@@ -134,12 +136,6 @@
 static struct epoll_event  *event_list;
 static ngx_uint_t           nevents;
 
-#if (NGX_HAVE_EVENTFD)
-static int                  notify_fd = -1;
-static ngx_event_t          notify_event;
-static ngx_connection_t     notify_conn;
-#endif
-
 #if (NGX_HAVE_FILE_AIO)
 
 int                         ngx_eventfd = -1;
@@ -189,9 +185,13 @@
         ngx_epoll_add_connection,        /* add an connection */
         ngx_epoll_del_connection,        /* delete an connection */
 #if (NGX_HAVE_EVENTFD)
+        ngx_epoll_notify_init,           /* init a notify */
         ngx_epoll_notify,                /* trigger a notify */
+        ngx_epoll_notify_close,          /* close a notify */
 #else
+        NULL,                            /* init a notify */
         NULL,                            /* trigger a notify */
+        NULL,                            /* close a notify */
 #endif
         ngx_epoll_process_events,        /* process the events */
         ngx_epoll_init,                  /* init the events */
@@ -335,12 +335,6 @@
             return NGX_ERROR;
         }
 
-#if (NGX_HAVE_EVENTFD)
-        if (ngx_epoll_notify_init(cycle->log) != NGX_OK) {
-            ngx_epoll_module_ctx.actions.notify = NULL;
-        }
-#endif
-
 #if (NGX_HAVE_FILE_AIO)
         ngx_epoll_aio_init(cycle, epcf);
 #endif
@@ -383,9 +377,17 @@
 #if (NGX_HAVE_EVENTFD)
 
 static ngx_int_t
-ngx_epoll_notify_init(ngx_log_t *log)
+ngx_epoll_notify_init(ngx_event_t *notify_event, ngx_event_handler_pt handler,
+    ngx_cycle_t *cycle)
 {
-    struct epoll_event  ee;
+    int                  notify_fd;
+    ngx_connection_t    *notify_conn;
+    struct epoll_event   ee;
+
+    notify_conn = ngx_pcalloc(cycle->pool, sizeof(ngx_connection_t));
+    if (notify_conn == NULL) {
+        return NGX_ERROR;
+    }
 
 #if (NGX_HAVE_SYS_EVENTFD_H)
     notify_fd = eventfd(0, 0);
@@ -394,31 +396,35 @@
 #endif
 
     if (notify_fd == -1) {
-        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "eventfd() failed");
+        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "eventfd() failed");
         return NGX_ERROR;
     }
 
-    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
+    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                    "notify eventfd: %d", notify_fd);
 
-    notify_event.handler = ngx_epoll_notify_handler;
-    notify_event.log = log;
-    notify_event.active = 1;
+    ngx_memzero(notify_event, sizeof(ngx_event_t));
 
-    notify_conn.fd = notify_fd;
-    notify_conn.read = &notify_event;
-    notify_conn.log = log;
+    notify_event->data = notify_conn;
+    notify_event->handler = ngx_epoll_notify_handler;
+    notify_event->log = cycle->log;
+    notify_event->active = 1;
+
+    notify_conn->data = handler;
+    notify_conn->fd = notify_fd;
+    notify_conn->read = notify_event;
+    notify_conn->log = cycle->log;
 
     ee.events = EPOLLIN|EPOLLET;
-    ee.data.ptr = &notify_conn;
+    ee.data.ptr = notify_conn;
 
     if (epoll_ctl(ep, EPOLL_CTL_ADD, notify_fd, &ee) == -1) {
-        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                       "epoll_ctl(EPOLL_CTL_ADD, eventfd) failed");
 
         if (close(notify_fd) == -1) {
-            ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
-                            "eventfd close() failed");
+            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                          "close() eventfd %d failed", notify_fd);
         }
 
         return NGX_ERROR;
@@ -431,31 +437,45 @@
 static void
 ngx_epoll_notify_handler(ngx_event_t *ev)
 {
-    ssize_t               n;
-    uint64_t              count;
-    ngx_err_t             err;
-    ngx_event_handler_pt  handler;
+    ngx_connection_t      *c = ev->data;
+
+    ssize_t                n;
+    uint64_t               count;
+    ngx_err_t              err;
+    ngx_event_handler_pt   handler;
 
     if (++ev->index == NGX_MAX_UINT32_VALUE) {
         ev->index = 0;
 
-        n = read(notify_fd, &count, sizeof(uint64_t));
+        n = read(c->fd, &count, sizeof(uint64_t));
 
         err = ngx_errno;
 
         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
-                       "read() eventfd %d: %z count:%uL", notify_fd, n, count);
+                       "read() eventfd %d: %z count:%uL", c->fd, n, count);
 
         if ((size_t) n != sizeof(uint64_t)) {
             ngx_log_error(NGX_LOG_ALERT, ev->log, err,
-                          "read() eventfd %d failed", notify_fd);
+                          "read() eventfd %d failed", c->fd);
         }
     }
 
-    handler = ev->data;
+    handler = c->data;
     handler(ev);
 }
 
+
+static void
+ngx_epoll_notify_close(ngx_event_t *notify_event)
+{
+    ngx_connection_t  *c = notify_event->data;
+
+    if (close(c->fd) == -1) {
+        ngx_log_error(NGX_LOG_ALERT, notify_event->log, ngx_errno,
+                      "close() eventfd %d failed", c->fd);
+    }
+}
+
 #endif
 
 
@@ -536,17 +556,6 @@
 
     ep = -1;
 
-#if (NGX_HAVE_EVENTFD)
-
-    if (close(notify_fd) == -1) {
-        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
-                      "eventfd close() failed");
-    }
-
-    notify_fd = -1;
-
-#endif
-
 #if (NGX_HAVE_FILE_AIO)
 
     if (ngx_eventfd != -1) {
@@ -762,15 +771,14 @@
 #if (NGX_HAVE_EVENTFD)
 
 static ngx_int_t
-ngx_epoll_notify(ngx_event_handler_pt handler)
+ngx_epoll_notify(ngx_event_t *notify_event)
 {
-    static uint64_t inc = 1;
+    static uint64_t    inc = 1;
+    ngx_connection_t  *c = notify_event->data;
 
-    notify_event.data = handler;
-
-    if ((size_t) write(notify_fd, &inc, sizeof(uint64_t)) != sizeof(uint64_t)) {
-        ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno,
-                      "write() to eventfd %d failed", notify_fd);
+    if ((size_t) write(c->fd, &inc, sizeof(uint64_t)) != sizeof(uint64_t)) {
+        ngx_log_error(NGX_LOG_ALERT, notify_event->log, ngx_errno,
+                      "write() to eventfd %d failed", c->fd);
         return NGX_ERROR;
     }
 
diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c
index e723f92..31c4f23 100644
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -140,7 +140,9 @@
     ngx_uint_t flags);
 static ngx_int_t ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event,
     ngx_uint_t flags);
-static ngx_int_t ngx_eventport_notify(ngx_event_handler_pt handler);
+static ngx_int_t ngx_eventport_notify_init(ngx_event_t *notify_event,
+    ngx_event_handler_pt handler, ngx_cycle_t *cycle);
+static ngx_int_t ngx_eventport_notify(ngx_event_t *notify_event);
 static ngx_int_t ngx_eventport_process_events(ngx_cycle_t *cycle,
     ngx_msec_t timer, ngx_uint_t flags);
 
@@ -151,7 +153,6 @@
 static port_event_t  *event_list;
 static ngx_uint_t     nevents;
 static timer_t        event_timer = (timer_t) -1;
-static ngx_event_t    notify_event;
 
 static ngx_str_t      eventport_name = ngx_string("eventport");
 
@@ -181,7 +182,9 @@
         ngx_eventport_del_event,           /* disable an event */
         NULL,                              /* add an connection */
         NULL,                              /* delete an connection */
+        ngx_eventport_notify_init,         /* init a notify */
         ngx_eventport_notify,              /* trigger a notify */
+        NULL,                              /* close a notify */
         ngx_eventport_process_events,      /* process the events */
         ngx_eventport_init,                /* init the events */
         ngx_eventport_done,                /* done the events */
@@ -223,9 +226,6 @@
                           "port_create() failed");
             return NGX_ERROR;
         }
-
-        notify_event.active = 1;
-        notify_event.log = cycle->log;
     }
 
     if (nevents < epcf->events) {
@@ -418,12 +418,24 @@
 
 
 static ngx_int_t
-ngx_eventport_notify(ngx_event_handler_pt handler)
+ngx_eventport_notify_init(ngx_event_t *notify_event,
+    ngx_event_handler_pt handler, ngx_cycle_t *cycle)
 {
-    notify_event.handler = handler;
+    ngx_memzero(notify_event, sizeof(ngx_event_t));
 
-    if (port_send(ep, 0, &notify_event) != 0) {
-        ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno,
+    notify_event->handler = handler;
+    notify_event->active = 1;
+    notify_event->log = cycle->log;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_eventport_notify(ngx_event_t *notify_event)
+{
+    if (port_send(ep, 0, notify_event) != 0) {
+        ngx_log_error(NGX_LOG_ALERT, notify_event->log, ngx_errno,
                       "port_send() failed");
         return NGX_ERROR;
     }
diff --git a/src/event/modules/ngx_iocp_module.c b/src/event/modules/ngx_iocp_module.c
index b03944b..7b21a39 100644
--- a/src/event/modules/ngx_iocp_module.c
+++ b/src/event/modules/ngx_iocp_module.c
@@ -64,7 +64,9 @@
         NULL,                              /* disable an event */
         NULL,                              /* add an connection */
         ngx_iocp_del_connection,           /* delete an connection */
+        NULL,                              /* init a notify */
         NULL,                              /* trigger a notify */
+        NULL,                              /* close a notify */
         ngx_iocp_process_events,           /* process the events */
         ngx_iocp_init,                     /* init the events */
         ngx_iocp_done                      /* done the events */
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 9c7244c..255c3e4 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -18,7 +18,8 @@
 
 static ngx_int_t ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer);
 #ifdef EVFILT_USER
-static ngx_int_t ngx_kqueue_notify_init(ngx_log_t *log);
+static ngx_int_t ngx_kqueue_notify_init(ngx_event_t *notify_event,
+    ngx_event_handler_pt handler, ngx_cycle_t *cycle);
 #endif
 static void ngx_kqueue_done(ngx_cycle_t *cycle);
 static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event,
@@ -28,7 +29,7 @@
 static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter,
     ngx_uint_t flags);
 #ifdef EVFILT_USER
-static ngx_int_t ngx_kqueue_notify(ngx_event_handler_pt handler);
+static ngx_int_t ngx_kqueue_notify(ngx_event_t *notify_event);
 #endif
 static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
     ngx_uint_t flags);
@@ -45,11 +46,6 @@
 static struct kevent  *event_list;
 static ngx_uint_t      max_changes, nchanges, nevents;
 
-#ifdef EVFILT_USER
-static ngx_event_t     notify_event;
-static struct kevent   notify_kev;
-#endif
-
 
 static ngx_str_t      kqueue_name = ngx_string("kqueue");
 
@@ -86,9 +82,13 @@
         NULL,                              /* add an connection */
         NULL,                              /* delete an connection */
 #ifdef EVFILT_USER
+        ngx_kqueue_notify_init,            /* init a notify */
         ngx_kqueue_notify,                 /* trigger a notify */
+        NULL,                              /* close a notify */
 #else
+        NULL,                              /* init a notify */
         NULL,                              /* trigger a notify */
+        NULL,                              /* close a notify */
 #endif
         ngx_kqueue_process_events,         /* process the events */
         ngx_kqueue_init,                   /* init the events */
@@ -132,12 +132,6 @@
                           "kqueue() failed");
             return NGX_ERROR;
         }
-
-#ifdef EVFILT_USER
-        if (ngx_kqueue_notify_init(cycle->log) != NGX_OK) {
-            return NGX_ERROR;
-        }
-#endif
     }
 
     if (max_changes < kcf->changes) {
@@ -230,27 +224,39 @@
 #ifdef EVFILT_USER
 
 static ngx_int_t
-ngx_kqueue_notify_init(ngx_log_t *log)
+ngx_kqueue_notify_init(ngx_event_t *notify_event, ngx_event_handler_pt handler,
+    ngx_cycle_t *cycle)
 {
-    notify_kev.ident = 0;
-    notify_kev.filter = EVFILT_USER;
-    notify_kev.data = 0;
-    notify_kev.flags = EV_ADD|EV_CLEAR;
-    notify_kev.fflags = 0;
-    notify_kev.udata = 0;
+    struct kevent  *notify_kev;
 
-    if (kevent(ngx_kqueue, &notify_kev, 1, NULL, 0, NULL) == -1) {
-        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+    notify_kev = ngx_pcalloc(cycle->pool, sizeof(struct kevent));
+    if (notify_kev == NULL) {
+        return NGX_ERROR;
+    }
+
+    notify_kev->ident = (uintptr_t) notify_event;
+    notify_kev->filter = EVFILT_USER;
+    notify_kev->data = 0;
+    notify_kev->flags = EV_ADD|EV_CLEAR;
+    notify_kev->fflags = 0;
+    notify_kev->udata = 0;
+
+    if (kevent(ngx_kqueue, notify_kev, 1, NULL, 0, NULL) == -1) {
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                       "kevent(EVFILT_USER, EV_ADD) failed");
         return NGX_ERROR;
     }
 
-    notify_event.active = 1;
-    notify_event.log = log;
+    ngx_memzero(notify_event, sizeof(ngx_event_t));
 
-    notify_kev.flags = 0;
-    notify_kev.fflags = NOTE_TRIGGER;
-    notify_kev.udata = NGX_KQUEUE_UDATA_T ((uintptr_t) &notify_event);
+    notify_event->data = notify_kev;
+    notify_event->handler = handler;
+    notify_event->active = 1;
+    notify_event->log = cycle->log;
+
+    notify_kev->flags = 0;
+    notify_kev->fflags = NOTE_TRIGGER;
+    notify_kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) notify_event);
 
     return NGX_OK;
 }
@@ -478,12 +484,12 @@
 #ifdef EVFILT_USER
 
 static ngx_int_t
-ngx_kqueue_notify(ngx_event_handler_pt handler)
+ngx_kqueue_notify(ngx_event_t *notify_event)
 {
-    notify_event.handler = handler;
+    struct kevent  *notify_kev = notify_event->data;
 
-    if (kevent(ngx_kqueue, &notify_kev, 1, NULL, 0, NULL) == -1) {
-        ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno,
+    if (kevent(ngx_kqueue, notify_kev, 1, NULL, 0, NULL) == -1) {
+        ngx_log_error(NGX_LOG_ALERT, notify_event->log, ngx_errno,
                       "kevent(EVFILT_USER, NOTE_TRIGGER) failed");
         return NGX_ERROR;
     }
diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c
index 4e03dab..83e5f8d 100644
--- a/src/event/modules/ngx_poll_module.c
+++ b/src/event/modules/ngx_poll_module.c
@@ -39,7 +39,9 @@
         ngx_poll_del_event,                /* disable an event */
         NULL,                              /* add an connection */
         NULL,                              /* delete an connection */
+        NULL,                              /* init a notify */
         NULL,                              /* trigger a notify */
+        NULL,                              /* close a notify */
         ngx_poll_process_events,           /* process the events */
         ngx_poll_init,                     /* init the events */
         ngx_poll_done                      /* done the events */
diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c
index 0644621..59810f6 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -47,7 +47,9 @@
         ngx_select_del_event,              /* disable an event */
         NULL,                              /* add an connection */
         NULL,                              /* delete an connection */
+        NULL,                              /* init a notify */
         NULL,                              /* trigger a notify */
+        NULL,                              /* close a notify */
         ngx_select_process_events,         /* process the events */
         ngx_select_init,                   /* init the events */
         ngx_select_done                    /* done the events */
diff --git a/src/event/modules/ngx_win32_select_module.c b/src/event/modules/ngx_win32_select_module.c
index a98a83f..ba98f07 100644
--- a/src/event/modules/ngx_win32_select_module.c
+++ b/src/event/modules/ngx_win32_select_module.c
@@ -48,7 +48,9 @@
         ngx_select_del_event,              /* disable an event */
         NULL,                              /* add an connection */
         NULL,                              /* delete an connection */
+        NULL,                              /* init a notify */
         NULL,                              /* trigger a notify */
+        NULL,                              /* close a notify */
         ngx_select_process_events,         /* process the events */
         ngx_select_init,                   /* init the events */
         ngx_select_done                    /* done the events */
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 57af813..8237fef 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -170,7 +170,7 @@
     ngx_event_core_create_conf,            /* create configuration */
     ngx_event_core_init_conf,              /* init configuration */
 
-    { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+    { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
 };
 
 
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 053bd16..1336999 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -184,7 +184,10 @@
     ngx_int_t  (*add_conn)(ngx_connection_t *c);
     ngx_int_t  (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);
 
-    ngx_int_t  (*notify)(ngx_event_handler_pt handler);
+    ngx_int_t  (*notify_init)(ngx_event_t *notify_event,
+                              ngx_event_handler_pt handler, ngx_cycle_t *cycle);
+    ngx_int_t  (*notify)(ngx_event_t *notify_event);
+    void       (*notify_close)(ngx_event_t *notify_event);
 
     ngx_int_t  (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
                                  ngx_uint_t flags);
@@ -416,7 +419,9 @@
 #define ngx_add_conn         ngx_event_actions.add_conn
 #define ngx_del_conn         ngx_event_actions.del_conn
 
+#define ngx_notify_init      ngx_event_actions.notify_init
 #define ngx_notify           ngx_event_actions.notify
+#define ngx_notify_close     ngx_event_actions.notify_close
 
 #define ngx_add_timer        ngx_event_add_timer
 #define ngx_del_timer        ngx_event_del_timer
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 2c4e114..9965b10 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -654,6 +654,29 @@
 
 
 ngx_int_t
+ngx_ssl_alpn_protos(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *protos)
+{
+#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
+
+    if (SSL_CTX_set_alpn_protos(ssl->ctx, protos->data, protos->len) != 0) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "SSL_CTX_set_alpn_protos() failed");
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+
+#else
+
+    ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+                  "nginx was built with OpenSSL that lacks ALPN support");
+    return NGX_ERROR;
+
+#endif
+}
+
+
+ngx_int_t
 ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
     ngx_int_t depth)
 {
@@ -2087,6 +2110,9 @@
 #ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED
             || n == SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED       /*  338 */
 #endif
+#ifdef SSL_R_NO_RENEGOTIATION
+            || n == SSL_R_NO_RENEGOTIATION                           /*  339 */
+#endif
 #ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING
             || n == SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING           /*  345 */
 #endif
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index 2a14980..4db5704 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -153,6 +153,8 @@
     ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords);
 ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
     ngx_uint_t prefer_server_ciphers);
+ngx_int_t ngx_ssl_alpn_protos(ngx_conf_t *cf, ngx_ssl_t *ssl,
+    ngx_str_t *protos);
 ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
     ngx_str_t *cert, ngx_int_t depth);
 ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
diff --git a/src/http/modules/ngx_http_chunked_filter_module.c b/src/http/modules/ngx_http_chunked_filter_module.c
index ac2e3e8..ffa1dd2 100644
--- a/src/http/modules/ngx_http_chunked_filter_module.c
+++ b/src/http/modules/ngx_http_chunked_filter_module.c
@@ -17,6 +17,7 @@
 
 
 static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf);
+static ngx_chain_t *ngx_http_chunked_get_trailers(ngx_http_request_t *r);
 
 
 static ngx_http_module_t  ngx_http_chunked_filter_module_ctx = {
@@ -69,30 +70,35 @@
         return ngx_http_next_header_filter(r);
     }
 
-    if (r->headers_out.content_length_n == -1) {
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    if (clcf->chunked_transfer_encoding
+        && r->allow_trailers && r->expect_trailers)
+    {
+        ngx_http_clear_content_length(r);
+        r->chunked = 1;
+
+    } else if (r->headers_out.content_length_n == -1) {
         if (r->http_version < NGX_HTTP_VERSION_11) {
             r->keepalive = 0;
 
+        } else if (clcf->chunked_transfer_encoding) {
+            r->chunked = 1;
+
         } else {
-            clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
-            if (clcf->chunked_transfer_encoding) {
-                r->chunked = 1;
-
-                ctx = ngx_pcalloc(r->pool,
-                                  sizeof(ngx_http_chunked_filter_ctx_t));
-                if (ctx == NULL) {
-                    return NGX_ERROR;
-                }
-
-                ngx_http_set_ctx(r, ctx, ngx_http_chunked_filter_module);
-
-            } else {
-                r->keepalive = 0;
-            }
+            r->keepalive = 0;
         }
     }
 
+    if (r->chunked) {
+        ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_filter_ctx_t));
+        if (ctx == NULL) {
+            return NGX_ERROR;
+        }
+
+        ngx_http_set_ctx(r, ctx, ngx_http_chunked_filter_module);
+    }
+
     return ngx_http_next_header_filter(r);
 }
 
@@ -201,6 +207,15 @@
             b->pos += 2;
         }
 
+        if (r->allow_trailers && r->expect_trailers) {
+            tl->next = ngx_http_chunked_get_trailers(r);
+
+            if (tl->next != NULL) {
+                b->last -= 2;
+                b->last_buf = 0;
+            }
+        }
+
     } else if (size > 0) {
         tl = ngx_chain_get_free_buf(r->pool, &ctx->free);
         if (tl == NULL) {
@@ -230,6 +245,112 @@
 }
 
 
+static ngx_chain_t *
+ngx_http_chunked_get_trailers(ngx_http_request_t *r)
+{
+    size_t                          len;
+    ngx_buf_t                      *b;
+    ngx_uint_t                      i;
+    ngx_chain_t                    *cl;
+    ngx_list_part_t                *part;
+    ngx_table_elt_t                *header;
+    ngx_http_chunked_filter_ctx_t  *ctx;
+
+    if (ngx_http_eval_trailers(r) != NGX_OK) {
+        return NULL;
+    }
+
+    len = 0;
+
+    part = &r->headers_out.trailers.part;
+    header = part->elts;
+
+    for (i = 0; /* void */; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+
+            part = part->next;
+            header = part->elts;
+            i = 0;
+        }
+
+        if (header[i].hash == 0) {
+            continue;
+        }
+
+        len += header[i].key.len + sizeof(": ") - 1 + header[i].value.len
+               + sizeof(CRLF) - 1;
+    }
+
+    if (len == 0) {
+        return NULL;
+    }
+
+    len += sizeof(CRLF) - 1;
+
+    ctx = ngx_http_get_module_ctx(r, ngx_http_chunked_filter_module);
+
+    cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
+    if (cl == NULL) {
+        return NULL;
+    }
+
+    b = cl->buf;
+
+    b->tag = (ngx_buf_tag_t) &ngx_http_chunked_filter_module;
+    b->temporary = 0;
+    b->memory = 1;
+    b->last_buf = 1;
+
+    b->start = ngx_palloc(r->pool, len);
+    if (b->start == NULL) {
+        return NULL;
+    }
+
+    b->end = b->last + len;
+    b->pos = b->start;
+    b->last = b->start;
+
+    part = &r->headers_out.trailers.part;
+    header = part->elts;
+
+    for (i = 0; /* void */; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+
+            part = part->next;
+            header = part->elts;
+            i = 0;
+        }
+
+        if (header[i].hash == 0) {
+            continue;
+        }
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "http trailer: \"%V: %V\"",
+                       &header[i].key, &header[i].value);
+
+        b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len);
+        *b->last++ = ':'; *b->last++ = ' ';
+
+        b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len);
+        *b->last++ = CR; *b->last++ = LF;
+    }
+
+    /* the end of HTTP trailer */
+    *b->last++ = CR; *b->last++ = LF;
+
+    return cl;
+}
+
+
 static ngx_int_t
 ngx_http_chunked_filter_init(ngx_conf_t *cf)
 {
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 741e577..7bbe843 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -2788,10 +2788,10 @@
 
     conf->upstream.intercept_errors = NGX_CONF_UNSET;
 
-    /* "fastcgi_cyclic_temp_file" is disabled */
+    /* the hardcoded values */
     conf->upstream.cyclic_temp_file = 0;
-
     conf->upstream.change_buffering = 1;
+    conf->upstream.pass_trailers = 0;
 
     conf->catch_stderr = NGX_CONF_UNSET_PTR;
 
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
index 94dc51e..47ce779 100644
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -48,6 +48,7 @@
     time_t                     expires_time;
     ngx_http_complex_value_t  *expires_value;
     ngx_array_t               *headers;
+    ngx_array_t               *trailers;
 } ngx_http_headers_conf_t;
 
 
@@ -72,6 +73,8 @@
     void *conf);
 static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
+static char *ngx_http_headers_add_trailer(ngx_conf_t *cf, ngx_command_t *cmd,
+    void *conf);
 
 
 static ngx_http_set_header_t  ngx_http_set_headers[] = {
@@ -108,6 +111,14 @@
       0,
       NULL},
 
+    { ngx_string("add_trailer"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
+                        |NGX_CONF_TAKE23,
+      ngx_http_headers_add_trailer,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      0,
+      NULL},
+
       ngx_null_command
 };
 
@@ -149,15 +160,24 @@
 static ngx_int_t
 ngx_http_headers_filter(ngx_http_request_t *r)
 {
-    ngx_str_t                 value;
-    ngx_uint_t                i, safe_status;
-    ngx_http_header_val_t    *h;
-    ngx_http_headers_conf_t  *conf;
+    u_char                    *p, *data;
+    size_t                     len;
+    ngx_str_t                  value;
+    ngx_uint_t                 i, safe_status;
+    ngx_table_elt_t           *t;
+    ngx_http_header_val_t     *h;
+    ngx_http_headers_conf_t   *conf;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    if (r != r->main) {
+        return ngx_http_next_header_filter(r);
+    }
 
     conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module);
 
-    if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL)
-        || r != r->main)
+    if (conf->expires == NGX_HTTP_EXPIRES_OFF
+         && conf->headers == NULL
+         && conf->trailers == NULL)
     {
         return ngx_http_next_header_filter(r);
     }
@@ -206,6 +226,84 @@
         }
     }
 
+    if (conf->trailers && r->allow_trailers) {
+
+        if (r->http_version < NGX_HTTP_VERSION_20) {
+            if (r->header_only
+                || r->headers_out.status == NGX_HTTP_NOT_MODIFIED
+                || r->headers_out.status == NGX_HTTP_NO_CONTENT
+                || r->headers_out.status < NGX_HTTP_OK
+                || r->method == NGX_HTTP_HEAD)
+            {
+               return ngx_http_next_header_filter(r);
+            }
+
+            clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+            if (!clcf->chunked_transfer_encoding) {
+                return ngx_http_next_header_filter(r);
+            }
+        }
+
+        len = 0;
+
+        h = conf->trailers->elts;
+        for (i = 0; i < conf->trailers->nelts; i++) {
+
+            if (!safe_status && !h[i].always) {
+                continue;
+            }
+
+            if (h[i].value.value.len) {
+                len += h[i].key.len + sizeof(", ") - 1;
+            }
+        }
+
+        if (len == 0) {
+            return ngx_http_next_header_filter(r);
+        }
+
+        len -= sizeof(", ") - 1;
+
+        t = ngx_list_push(&r->headers_out.headers);
+        if (t == NULL) {
+            return NGX_ERROR;
+        }
+
+        data = ngx_pnalloc(r->pool, len);
+        if (data == NULL) {
+            return NGX_ERROR;
+        }
+
+        p = data;
+
+        h = conf->trailers->elts;
+        for (i = 0; i < conf->trailers->nelts; i++) {
+
+            if (!safe_status && !h[i].always) {
+                continue;
+            }
+
+            if (h[i].value.value.len) {
+                p = ngx_copy(p, h[i].key.data, h[i].key.len);
+
+                if (p == data + len) {
+                    break;
+                }
+
+                *p++ = ','; *p++ = ' ';
+            }
+        }
+
+        ngx_str_set(&t->key, "Trailer");
+        t->value.data = data;
+        t->value.len = len;
+        t->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(ngx_hash(
+                           ngx_hash('t', 'r'), 'a'), 'i'), 'l'), 'e'), 'r');
+
+        r->expect_trailers = 1;
+    }
+
     return ngx_http_next_header_filter(r);
 }
 
@@ -543,6 +641,67 @@
 }
 
 
+ngx_int_t
+ngx_http_eval_trailers(ngx_http_request_t *r)
+{
+    ngx_str_t                 value;
+    ngx_uint_t                i, safe_status;
+    ngx_table_elt_t          *t;
+    ngx_http_header_val_t    *h;
+    ngx_http_headers_conf_t  *conf;
+
+    conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module);
+
+    if (conf->trailers == NULL) {
+        return NGX_OK;
+    }
+
+    switch (r->headers_out.status) {
+
+    case NGX_HTTP_OK:
+    case NGX_HTTP_CREATED:
+    case NGX_HTTP_NO_CONTENT:
+    case NGX_HTTP_PARTIAL_CONTENT:
+    case NGX_HTTP_MOVED_PERMANENTLY:
+    case NGX_HTTP_MOVED_TEMPORARILY:
+    case NGX_HTTP_SEE_OTHER:
+    case NGX_HTTP_NOT_MODIFIED:
+    case NGX_HTTP_TEMPORARY_REDIRECT:
+        safe_status = 1;
+        break;
+
+    default:
+        safe_status = 0;
+        break;
+    }
+
+    h = conf->trailers->elts;
+    for (i = 0; i < conf->trailers->nelts; i++) {
+
+        if (!safe_status && !h[i].always) {
+            continue;
+        }
+
+        if (ngx_http_complex_value(r, &h[i].value, &value) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
+        if (value.len) {
+            t = ngx_list_push(&r->headers_out.trailers);
+            if (t == NULL) {
+                return NGX_ERROR;
+            }
+
+            t->key = h[i].key;
+            t->value = value;
+            t->hash = 1;
+        }
+    }
+
+    return NGX_OK;
+}
+
+
 static void *
 ngx_http_headers_create_conf(ngx_conf_t *cf)
 {
@@ -557,6 +716,7 @@
      * set by ngx_pcalloc():
      *
      *     conf->headers = NULL;
+     *     conf->trailers = NULL;
      *     conf->expires_time = 0;
      *     conf->expires_value = NULL;
      */
@@ -587,6 +747,10 @@
         conf->headers = prev->headers;
     }
 
+    if (conf->trailers == NULL) {
+        conf->trailers = prev->trailers;
+    }
+
     return NGX_CONF_OK;
 }
 
@@ -741,3 +905,63 @@
 
     return NGX_CONF_OK;
 }
+
+
+static char *
+ngx_http_headers_add_trailer(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+    ngx_http_headers_conf_t *hcf = conf;
+
+    ngx_str_t                         *value;
+    ngx_http_header_val_t             *hv;
+    ngx_http_compile_complex_value_t   ccv;
+
+    value = cf->args->elts;
+
+    if (hcf->trailers == NULL) {
+        hcf->trailers = ngx_array_create(cf->pool, 1,
+                                         sizeof(ngx_http_header_val_t));
+        if (hcf->trailers == NULL) {
+            return NGX_CONF_ERROR;
+        }
+    }
+
+    hv = ngx_array_push(hcf->trailers);
+    if (hv == NULL) {
+        return NGX_CONF_ERROR;
+    }
+
+    hv->key = value[1];
+    hv->handler = NULL;
+    hv->offset = 0;
+    hv->always = 0;
+
+    if (value[2].len == 0) {
+        ngx_memzero(&hv->value, sizeof(ngx_http_complex_value_t));
+
+    } else {
+        ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+
+        ccv.cf = cf;
+        ccv.value = &value[2];
+        ccv.complex_value = &hv->value;
+
+        if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+            return NGX_CONF_ERROR;
+        }
+    }
+
+    if (cf->args->nelts == 3) {
+        return NGX_CONF_OK;
+    }
+
+    if (ngx_strcmp(value[3].data, "always") != 0) {
+        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                           "invalid parameter \"%V\"", &value[3]);
+        return NGX_CONF_ERROR;
+    }
+
+    hv->always = 1;
+
+    return NGX_CONF_OK;
+}
diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c
index 579b13c..9e7def8 100644
--- a/src/http/modules/ngx_http_limit_req_module.c
+++ b/src/http/modules/ngx_http_limit_req_module.c
@@ -712,7 +712,7 @@
                                 NGX_LOG_INFO : conf->limit_log_level + 1;
 
     ngx_conf_merge_uint_value(conf->status_code, prev->status_code,
-                              NGX_HTTP_SERVICE_UNAVAILABLE);
+                              NGX_HTTP_TOO_MANY_REQUESTS);
 
     return NGX_CONF_OK;
 }
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index 69f28fa..b681e45 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -619,6 +619,7 @@
     conf->upstream.pass_request_headers = 0;
     conf->upstream.pass_request_body = 0;
     conf->upstream.force_ranges = 1;
+    conf->upstream.pass_trailers = 0;
 
     conf->index = NGX_CONF_UNSET;
     conf->gzip_flag = NGX_CONF_UNSET_UINT;
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 839d479..bc8d2a7 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -652,6 +652,13 @@
       offsetof(ngx_http_proxy_loc_conf_t, ssl_ciphers),
       NULL },
 
+    { ngx_string("proxy_ssl_alpn"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_alpn),
+      NULL },
+
     { ngx_string("proxy_ssl_name"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_http_set_complex_value_slot,
@@ -1144,6 +1151,7 @@
 ngx_http_proxy_create_request(ngx_http_request_t *r)
 {
     size_t                        len, uri_len, loc_len, body_len;
+    size_t                        key_len, val_len;
     uintptr_t                     escape;
     ngx_buf_t                    *b;
     ngx_str_t                     method;
@@ -1258,10 +1266,17 @@
     le.flushed = 1;
 
     while (*(uintptr_t *) le.ip) {
-        while (*(uintptr_t *) le.ip) {
+        lcode = *(ngx_http_script_len_code_pt *) le.ip;
+        key_len = lcode(&le);
+
+        for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
             lcode = *(ngx_http_script_len_code_pt *) le.ip;
-            len += lcode(&le);
         }
+
+        if (val_len) {
+            len += key_len + sizeof(": ") - 1 + val_len + sizeof(CRLF) - 1;
+        }
+
         le.ip += sizeof(uintptr_t);
     }
 
@@ -1363,28 +1378,32 @@
 
     while (*(uintptr_t *) le.ip) {
         lcode = *(ngx_http_script_len_code_pt *) le.ip;
-
-        /* skip the header line name length */
         (void) lcode(&le);
 
-        if (*(ngx_http_script_len_code_pt *) le.ip) {
-
-            for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) {
-                lcode = *(ngx_http_script_len_code_pt *) le.ip;
-            }
-
-            e.skip = (len == sizeof(CRLF) - 1) ? 1 : 0;
-
-        } else {
-            e.skip = 0;
+        for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
+            lcode = *(ngx_http_script_len_code_pt *) le.ip;
         }
 
         le.ip += sizeof(uintptr_t);
 
+        e.skip = (val_len == 0) ? 1 : 0;
+
+        code = *(ngx_http_script_code_pt *) e.ip;
+        code((ngx_http_script_engine_t *) &e);
+
+        if (!e.skip) {
+            *e.pos++ = ':'; *e.pos++ = ' ';
+        }
+
         while (*(uintptr_t *) e.ip) {
             code = *(ngx_http_script_code_pt *) e.ip;
             code((ngx_http_script_engine_t *) &e);
         }
+
+        if (!e.skip) {
+            *e.pos++ = CR; *e.pos++ = LF;
+        }
+
         e.ip += sizeof(uintptr_t);
     }
 
@@ -2882,6 +2901,7 @@
     conf->upstream.intercept_errors = NGX_CONF_UNSET;
 
 #if (NGX_HTTP_SSL)
+    conf->upstream.ssl_alpn = NGX_CONF_UNSET;
     conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
     conf->upstream.ssl_server_name = NGX_CONF_UNSET;
     conf->upstream.ssl_verify = NGX_CONF_UNSET;
@@ -2889,11 +2909,12 @@
     conf->ssl_passwords = NGX_CONF_UNSET_PTR;
 #endif
 
-    /* "proxy_cyclic_temp_file" is disabled */
+    /* the hardcoded values */
     conf->upstream.cyclic_temp_file = 0;
+    conf->upstream.change_buffering = 1;
+    conf->upstream.pass_trailers = 0;
 
     conf->redirect = NGX_CONF_UNSET;
-    conf->upstream.change_buffering = 1;
 
     conf->cookie_domains = NGX_CONF_UNSET_PTR;
     conf->cookie_paths = NGX_CONF_UNSET_PTR;
@@ -3212,6 +3233,8 @@
         conf->upstream.ssl_name = prev->upstream.ssl_name;
     }
 
+    ngx_conf_merge_value(conf->upstream.ssl_alpn,
+                              prev->upstream.ssl_alpn, 0);
     ngx_conf_merge_value(conf->upstream.ssl_server_name,
                               prev->upstream.ssl_server_name, 0);
     ngx_conf_merge_value(conf->upstream.ssl_verify,
@@ -3412,7 +3435,7 @@
     uintptr_t                    *code;
     ngx_uint_t                    i;
     ngx_array_t                   headers_names, headers_merged;
-    ngx_keyval_t                 *src, *s, *h;
+    ngx_keyval_t                 *host, *src, *s, *h;
     ngx_hash_key_t               *hk;
     ngx_hash_init_t               hash;
     ngx_http_script_compile_t     sc;
@@ -3444,11 +3467,33 @@
         return NGX_ERROR;
     }
 
+    h = default_headers;
+
+    if (h->key.len != sizeof("Host") - 1
+        || ngx_strcasecmp(h->key.data, (u_char *) "Host") != 0)
+    {
+        return NGX_ERROR;
+    }
+
+    host = ngx_array_push(&headers_merged);
+    if (host == NULL) {
+        return NGX_ERROR;
+    }
+
+    *host = *h++;
+
     if (conf->headers_source) {
 
         src = conf->headers_source->elts;
         for (i = 0; i < conf->headers_source->nelts; i++) {
 
+            if (src[i].key.len == sizeof("Host") - 1
+                && ngx_strcasecmp(src[i].key.data, (u_char *) "Host") == 0)
+            {
+                *host = src[i];
+                continue;
+            }
+
             s = ngx_array_push(&headers_merged);
             if (s == NULL) {
                 return NGX_ERROR;
@@ -3458,8 +3503,6 @@
         }
     }
 
-    h = default_headers;
-
     while (h->key.len) {
 
         src = headers_merged.elts;
@@ -3498,6 +3541,30 @@
             continue;
         }
 
+        copy = ngx_array_push_n(headers->lengths,
+                                sizeof(ngx_http_script_copy_code_t));
+        if (copy == NULL) {
+            return NGX_ERROR;
+        }
+
+        copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
+        copy->len = src[i].key.len;
+
+        size = (sizeof(ngx_http_script_copy_code_t)
+                + src[i].key.len + sizeof(uintptr_t) - 1)
+                & ~(sizeof(uintptr_t) - 1);
+
+        copy = ngx_array_push_n(headers->values, size);
+        if (copy == NULL) {
+            return NGX_ERROR;
+        }
+
+        copy->code = ngx_http_script_copy_code;
+        copy->len = src[i].key.len;
+
+        p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
+        ngx_memcpy(p, src[i].key.data, src[i].key.len);
+
         if (ngx_http_script_variables_count(&src[i].value) == 0) {
             copy = ngx_array_push_n(headers->lengths,
                                     sizeof(ngx_http_script_copy_code_t));
@@ -3507,14 +3574,10 @@
 
             copy->code = (ngx_http_script_code_pt)
                                                  ngx_http_script_copy_len_code;
-            copy->len = src[i].key.len + sizeof(": ") - 1
-                        + src[i].value.len + sizeof(CRLF) - 1;
-
+            copy->len = src[i].value.len;
 
             size = (sizeof(ngx_http_script_copy_code_t)
-                       + src[i].key.len + sizeof(": ") - 1
-                       + src[i].value.len + sizeof(CRLF) - 1
-                       + sizeof(uintptr_t) - 1)
+                    + src[i].value.len + sizeof(uintptr_t) - 1)
                     & ~(sizeof(uintptr_t) - 1);
 
             copy = ngx_array_push_n(headers->values, size);
@@ -3523,45 +3586,12 @@
             }
 
             copy->code = ngx_http_script_copy_code;
-            copy->len = src[i].key.len + sizeof(": ") - 1
-                        + src[i].value.len + sizeof(CRLF) - 1;
+            copy->len = src[i].value.len;
 
             p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
-
-            p = ngx_cpymem(p, src[i].key.data, src[i].key.len);
-            *p++ = ':'; *p++ = ' ';
-            p = ngx_cpymem(p, src[i].value.data, src[i].value.len);
-            *p++ = CR; *p = LF;
+            ngx_memcpy(p, src[i].value.data, src[i].value.len);
 
         } else {
-            copy = ngx_array_push_n(headers->lengths,
-                                    sizeof(ngx_http_script_copy_code_t));
-            if (copy == NULL) {
-                return NGX_ERROR;
-            }
-
-            copy->code = (ngx_http_script_code_pt)
-                                                 ngx_http_script_copy_len_code;
-            copy->len = src[i].key.len + sizeof(": ") - 1;
-
-
-            size = (sizeof(ngx_http_script_copy_code_t)
-                    + src[i].key.len + sizeof(": ") - 1 + sizeof(uintptr_t) - 1)
-                    & ~(sizeof(uintptr_t) - 1);
-
-            copy = ngx_array_push_n(headers->values, size);
-            if (copy == NULL) {
-                return NGX_ERROR;
-            }
-
-            copy->code = ngx_http_script_copy_code;
-            copy->len = src[i].key.len + sizeof(": ") - 1;
-
-            p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
-            p = ngx_cpymem(p, src[i].key.data, src[i].key.len);
-            *p++ = ':'; *p = ' ';
-
-
             ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
 
             sc.cf = cf;
@@ -3573,33 +3603,6 @@
             if (ngx_http_script_compile(&sc) != NGX_OK) {
                 return NGX_ERROR;
             }
-
-
-            copy = ngx_array_push_n(headers->lengths,
-                                    sizeof(ngx_http_script_copy_code_t));
-            if (copy == NULL) {
-                return NGX_ERROR;
-            }
-
-            copy->code = (ngx_http_script_code_pt)
-                                                 ngx_http_script_copy_len_code;
-            copy->len = sizeof(CRLF) - 1;
-
-
-            size = (sizeof(ngx_http_script_copy_code_t)
-                    + sizeof(CRLF) - 1 + sizeof(uintptr_t) - 1)
-                    & ~(sizeof(uintptr_t) - 1);
-
-            copy = ngx_array_push_n(headers->values, size);
-            if (copy == NULL) {
-                return NGX_ERROR;
-            }
-
-            copy->code = ngx_http_script_copy_code;
-            copy->len = sizeof(CRLF) - 1;
-
-            p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
-            *p++ = CR; *p = LF;
         }
 
         code = ngx_array_push_n(headers->lengths, sizeof(uintptr_t));
@@ -4320,6 +4323,7 @@
 static ngx_int_t
 ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf)
 {
+    ngx_str_t            alpn;
     ngx_pool_cleanup_t  *cln;
 
     plcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
@@ -4366,6 +4370,24 @@
         return NGX_ERROR;
     }
 
+    if (plcf->upstream.ssl_alpn) {
+
+        switch (plcf->http_version) {
+
+        case NGX_HTTP_VERSION_10:
+            ngx_str_set(&alpn, NGX_HTTP_10_ALPN_ADVERTISE);
+            break;
+
+        case NGX_HTTP_VERSION_11:
+            ngx_str_set(&alpn, NGX_HTTP_11_ALPN_ADVERTISE);
+            break;
+        }
+
+        if (ngx_ssl_alpn_protos(cf, plcf->upstream.ssl, &alpn) != NGX_OK) {
+            return NGX_ERROR;
+        }
+    }
+
     if (plcf->upstream.ssl_verify) {
         if (plcf->ssl_trusted_certificate.len == 0) {
             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
index 9204af4..c8bead7 100644
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -1236,10 +1236,10 @@
 
     conf->upstream.intercept_errors = NGX_CONF_UNSET;
 
-    /* "scgi_cyclic_temp_file" is disabled */
+    /* the hardcoded values */
     conf->upstream.cyclic_temp_file = 0;
-
     conf->upstream.change_buffering = 1;
+    conf->upstream.pass_trailers = 0;
 
     ngx_str_set(&conf->upstream.module, "scgi");
 
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 6fb1fbe..0fbd6e1 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -8,6 +8,7 @@
 #include <ngx_config.h>
 #include <ngx_core.h>
 #include <ngx_http.h>
+#include <ngx_http_ssi_filter_module.h>
 
 #define NGX_HTTP_SSI_ERROR          1
 
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index b466e5d..57693c6 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -17,8 +17,6 @@
 #define NGX_DEFAULT_CIPHERS     "HIGH:!aNULL:!MD5"
 #define NGX_DEFAULT_ECDH_CURVE  "auto"
 
-#define NGX_HTTP_NPN_ADVERTISE  "\x08http/1.1"
-
 
 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
 static int ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn,
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
index a2bec4c..6f0583c 100644
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -1451,10 +1451,10 @@
     conf->ssl_passwords = NGX_CONF_UNSET_PTR;
 #endif
 
-    /* "uwsgi_cyclic_temp_file" is disabled */
+    /* the hardcoded values */
     conf->upstream.cyclic_temp_file = 0;
-
     conf->upstream.change_buffering = 1;
+    conf->upstream.pass_trailers = 0;
 
     ngx_str_set(&conf->upstream.module, "uwsgi");
 
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index ad12632..9f847b3 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -264,7 +264,7 @@
             sep = ';';
             goto multi;
         }
-#if (NGX_HTTP_X_FORWARDED_FOR)
+#if (NGX_HTTP_X_FORWARDED_FOR || NGX_COMPAT)
         if (hh->offset == offsetof(ngx_http_headers_in_t, x_forwarded_for)) {
             sep = ',';
             goto multi;
diff --git a/src/http/modules/perl/ngx_http_perl_module.h b/src/http/modules/perl/ngx_http_perl_module.h
index 5e60b03..d15f546 100644
--- a/src/http/modules/perl/ngx_http_perl_module.h
+++ b/src/http/modules/perl/ngx_http_perl_module.h
@@ -14,6 +14,10 @@
 #include <ngx_http.h>
 #include <nginx.h>
 
+#if (NGX_HTTP_SSI)
+#include <ngx_http_ssi_filter_module.h>
+#endif
+
 #include <EXTERN.h>
 #include <perl.h>
 
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index afab4f6..e5306ef 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -13,6 +13,11 @@
 #include <ngx_core.h>
 
 
+#define NGX_HTTP_10_ALPN_ADVERTISE  "\x08http/1.0"
+#define NGX_HTTP_11_ALPN_ADVERTISE  "\x08http/1.1"
+#define NGX_HTTP_NPN_ADVERTISE      NGX_HTTP_11_ALPN_ADVERTISE
+
+
 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;
@@ -41,9 +46,6 @@
 #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
@@ -143,6 +145,7 @@
 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);
+ngx_int_t ngx_http_eval_trailers(ngx_http_request_t *r);
 
 
 ngx_int_t ngx_http_discard_request_body(ngx_http_request_t *r);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 7e40e78..83f9016 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -73,7 +73,7 @@
     void *conf);
 static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
 static ngx_int_t ngx_http_gzip_accept_encoding(ngx_str_t *ae);
 static ngx_uint_t ngx_http_gzip_quantity(u_char *p, u_char *last);
 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
@@ -149,7 +149,7 @@
 };
 
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
 
 static ngx_conf_enum_t  ngx_http_gzip_http_version[] = {
     { ngx_string("1.0"), NGX_HTTP_VERSION_10 },
@@ -720,7 +720,7 @@
       offsetof(ngx_http_core_loc_conf_t, resolver_timeout),
       NULL },
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
 
     { ngx_string("gzip_vary"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
@@ -833,7 +833,7 @@
     }
 
     r->valid_location = 1;
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     r->gzip_tested = 0;
     r->gzip_ok = 0;
     r->gzip_vary = 0;
@@ -2141,7 +2141,7 @@
 }
 
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
 
 ngx_int_t
 ngx_http_gzip_ok(ngx_http_request_t *r)
@@ -2484,6 +2484,13 @@
         return NGX_ERROR;
     }
 
+    if (ngx_list_init(&sr->headers_out.trailers, r->pool, 4,
+                      sizeof(ngx_table_elt_t))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
     sr->main_conf = cscf->ctx->main_conf;
     sr->srv_conf = cscf->ctx->srv_conf;
@@ -3618,7 +3625,7 @@
     clcf->open_file_cache_errors = NGX_CONF_UNSET;
     clcf->open_file_cache_events = NGX_CONF_UNSET;
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     clcf->gzip_vary = NGX_CONF_UNSET;
     clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
 #if (NGX_PCRE)
@@ -3893,7 +3900,7 @@
 
     ngx_conf_merge_sec_value(conf->open_file_cache_events,
                               prev->open_file_cache_events, 0);
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
 
     ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
     ngx_conf_merge_uint_value(conf->gzip_http_version, prev->gzip_http_version,
@@ -5116,7 +5123,7 @@
 }
 
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
 
 static char *
 ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 5018da0..b0af759 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -321,7 +321,7 @@
     unsigned      noregex:1;
 
     unsigned      auto_redirect:1;
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     unsigned      gzip_disable_msie6:2;
     unsigned      gzip_disable_degradation:2;
 #endif
@@ -403,7 +403,7 @@
     ngx_flag_t    chunked_transfer_encoding; /* chunked_transfer_encoding */
     ngx_flag_t    etag;                    /* etag */
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     ngx_flag_t    gzip_vary;               /* gzip_vary */
 
     ngx_uint_t    gzip_http_version;       /* gzip_http_version */
@@ -502,7 +502,7 @@
 u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name,
     size_t *root_length, size_t reserved);
 ngx_int_t ngx_http_auth_basic_user(ngx_http_request_t *r);
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
 ngx_int_t ngx_http_gzip_ok(ngx_http_request_t *r);
 #endif
 
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index 9b89405..a69e98f 100644
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -46,7 +46,7 @@
 };
 
 
-static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
+static u_char ngx_http_server_string[] = "Server: " NGINX_NAME CRLF;
 static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
 static u_char ngx_http_server_build_string[] = "Server: " NGINX_VER_BUILD CRLF;
 
@@ -397,7 +397,7 @@
         len += sizeof("Connection: close" CRLF) - 1;
     }
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     if (r->gzip_vary) {
         if (clcf->gzip_vary) {
             len += sizeof("Vary: Accept-Encoding" CRLF) - 1;
@@ -569,7 +569,7 @@
                              sizeof("Connection: close" CRLF) - 1);
     }
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     if (r->gzip_vary) {
         b->last = ngx_cpymem(b->last, "Vary: Accept-Encoding" CRLF,
                              sizeof("Vary: Accept-Encoding" CRLF) - 1);
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index cc3722f..0dd7427 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -29,6 +29,8 @@
     ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
+static ngx_int_t ngx_http_process_te(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);
@@ -128,6 +130,10 @@
                  offsetof(ngx_http_headers_in_t, if_range),
                  ngx_http_process_unique_header_line },
 
+    { ngx_string("TE"),
+                 offsetof(ngx_http_headers_in_t, te),
+                 ngx_http_process_te },
+
     { ngx_string("Transfer-Encoding"),
                  offsetof(ngx_http_headers_in_t, transfer_encoding),
                  ngx_http_process_header_line },
@@ -140,7 +146,7 @@
                  offsetof(ngx_http_headers_in_t, upgrade),
                  ngx_http_process_header_line },
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     { ngx_string("Accept-Encoding"),
                  offsetof(ngx_http_headers_in_t, accept_encoding),
                  ngx_http_process_header_line },
@@ -156,19 +162,19 @@
     { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
                  ngx_http_process_header_line },
 
-#if (NGX_HTTP_X_FORWARDED_FOR)
+#if (NGX_HTTP_X_FORWARDED_FOR || NGX_COMPAT)
     { 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)
+#if (NGX_HTTP_REALIP || NGX_COMPAT)
     { ngx_string("X-Real-IP"),
                  offsetof(ngx_http_headers_in_t, x_real_ip),
                  ngx_http_process_header_line },
 #endif
 
-#if (NGX_HTTP_HEADERS)
+#if (NGX_HTTP_HEADERS || NGX_COMPAT)
     { ngx_string("Accept"), offsetof(ngx_http_headers_in_t, accept),
                  ngx_http_process_header_line },
 
@@ -177,7 +183,7 @@
                  ngx_http_process_header_line },
 #endif
 
-#if (NGX_HTTP_DAV)
+#if (NGX_HTTP_DAV || NGX_COMPAT)
     { ngx_string("Depth"), offsetof(ngx_http_headers_in_t, depth),
                  ngx_http_process_header_line },
 
@@ -562,6 +568,14 @@
         return NULL;
     }
 
+    if (ngx_list_init(&r->headers_out.trailers, r->pool, 4,
+                      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);
@@ -1678,6 +1692,22 @@
 ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
+    if (r->headers_in.connection == NULL) {
+        r->headers_in.connection = h;
+    }
+
+#if (NGX_HTTP_V2)
+
+    if (r->http_version >= NGX_HTTP_VERSION_20) {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent HTTP/2 request with \"Connection\" header");
+
+        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+        return NGX_ERROR;
+    }
+
+#endif
+
     if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) {
         r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
 
@@ -1763,6 +1793,63 @@
 
 
 static ngx_int_t
+ngx_http_process_te(ngx_http_request_t *r, ngx_table_elt_t *h,
+    ngx_uint_t offset)
+{
+    u_char  *p;
+
+    if (ngx_http_process_multi_header_lines(r, h, offset) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    if (r->http_version < NGX_HTTP_VERSION_11) {
+        return NGX_OK;
+    }
+
+    if (h->value.len == sizeof("trailers") - 1
+        && ngx_memcmp(h->value.data, "trailers", sizeof("trailers") - 1) == 0)
+    {
+        r->allow_trailers = 1;
+        return NGX_OK;
+    }
+
+#if (NGX_HTTP_V2)
+
+    if (r->http_version >= NGX_HTTP_VERSION_20) {
+        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                      "client sent HTTP/2 request with invalid value \"%V\" "
+                      "in \"TE\" header", &h->value);
+
+        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+        return NGX_ERROR;
+    }
+
+#endif
+
+    if (h->value.len < sizeof("trailers") - 1) {
+        return NGX_OK;
+    }
+
+    p = ngx_strcasestrn(h->value.data, "trailers", sizeof("trailers") - 2);
+    if (p == NULL) {
+        return NGX_OK;
+    }
+
+    if (p == h->value.data || *(p - 1) == ',' || *(p - 1) == ' ') {
+
+        p += sizeof("trailers") - 1;
+
+        if (p == h->value.data + h->value.len || *p == ',' || *p == ' ') {
+            r->allow_trailers = 1;
+            return NGX_OK;
+        }
+    }
+
+    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)
 {
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 283c582..e9fa52f 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -196,11 +196,12 @@
     ngx_table_elt_t                  *range;
     ngx_table_elt_t                  *if_range;
 
+    ngx_array_t                       te;
     ngx_table_elt_t                  *transfer_encoding;
     ngx_table_elt_t                  *expect;
     ngx_table_elt_t                  *upgrade;
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     ngx_table_elt_t                  *accept_encoding;
     ngx_table_elt_t                  *via;
 #endif
@@ -209,20 +210,20 @@
 
     ngx_table_elt_t                  *keep_alive;
 
-#if (NGX_HTTP_X_FORWARDED_FOR)
+#if (NGX_HTTP_X_FORWARDED_FOR || NGX_COMPAT)
     ngx_array_t                       x_forwarded_for;
 #endif
 
-#if (NGX_HTTP_REALIP)
+#if (NGX_HTTP_REALIP || NGX_COMPAT)
     ngx_table_elt_t                  *x_real_ip;
 #endif
 
-#if (NGX_HTTP_HEADERS)
+#if (NGX_HTTP_HEADERS || NGX_COMPAT)
     ngx_table_elt_t                  *accept;
     ngx_table_elt_t                  *accept_language;
 #endif
 
-#if (NGX_HTTP_DAV)
+#if (NGX_HTTP_DAV || NGX_COMPAT)
     ngx_table_elt_t                  *depth;
     ngx_table_elt_t                  *destination;
     ngx_table_elt_t                  *overwrite;
@@ -252,6 +253,7 @@
 
 typedef struct {
     ngx_list_t                        headers;
+    ngx_list_t                        trailers;
 
     ngx_uint_t                        status;
     ngx_str_t                         status_line;
@@ -489,7 +491,7 @@
     unsigned                          cached:1;
 #endif
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     unsigned                          gzip_tested:1;
     unsigned                          gzip_ok:1;
     unsigned                          gzip_vary:1;
@@ -514,6 +516,8 @@
     unsigned                          pipeline:1;
     unsigned                          chunked:1;
     unsigned                          header_only:1;
+    unsigned                          allow_trailers:1;
+    unsigned                          expect_trailers:1;
     unsigned                          keepalive:1;
     unsigned                          lingering_close:1;
     unsigned                          discard_body:1;
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 2c1ff17..a19318b 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -33,7 +33,7 @@
 
 
 static u_char ngx_http_error_tail[] =
-"<hr><center>nginx</center>" CRLF
+"<hr><center>" NGINX_NAME "</center>" CRLF
 "</body>" CRLF
 "</html>" CRLF
 ;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 0fc5ab5..026458f 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -55,6 +55,8 @@
 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
 static ngx_int_t ngx_http_upstream_process_headers(ngx_http_request_t *r,
     ngx_http_upstream_t *u);
+static ngx_int_t ngx_http_upstream_process_trailers(ngx_http_request_t *r,
+    ngx_http_upstream_t *u);
 static void ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
     ngx_http_upstream_t *u);
 static void ngx_http_upstream_send_response(ngx_http_request_t *r,
@@ -149,8 +151,10 @@
     ngx_table_elt_t *h, ngx_uint_t offset);
 static ngx_int_t ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
+static ngx_int_t ngx_http_upstream_copy_trailer(ngx_http_request_t *r,
+    ngx_table_elt_t *h, ngx_uint_t offset);
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
 static ngx_int_t ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r,
     ngx_table_elt_t *h, ngx_uint_t offset);
 #endif
@@ -162,10 +166,12 @@
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_upstream_response_length_variable(
-    ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_upstream_bytes_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_upstream_trailer_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 
@@ -307,11 +313,15 @@
                  ngx_http_upstream_process_charset, 0,
                  ngx_http_upstream_copy_header_line, 0, 0 },
 
+    { ngx_string("Trailer"),
+                 ngx_http_upstream_ignore_header_line, 0,
+                 ngx_http_upstream_copy_trailer, 0, 0 },
+
     { ngx_string("Transfer-Encoding"),
                  ngx_http_upstream_process_transfer_encoding, 0,
                  ngx_http_upstream_ignore_header_line, 0, 0 },
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     { ngx_string("Content-Encoding"),
                  ngx_http_upstream_process_header_line,
                  offsetof(ngx_http_upstream_headers_in_t, content_encoding),
@@ -396,11 +406,15 @@
       NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("upstream_response_length"), NULL,
-      ngx_http_upstream_response_length_variable, 0,
+      ngx_http_upstream_bytes_variable, 0,
       NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("upstream_bytes_received"), NULL,
-      ngx_http_upstream_response_length_variable, 1,
+      ngx_http_upstream_bytes_variable, 1,
+      NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
+    { ngx_string("upstream_bytes_sent"), NULL,
+      ngx_http_upstream_bytes_variable, 2,
       NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
 #if (NGX_HTTP_CACHE)
@@ -422,6 +436,9 @@
     { ngx_string("upstream_http_"), NULL, ngx_http_upstream_header_variable,
       0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
 
+    { ngx_string("upstream_trailer_"), NULL, ngx_http_upstream_trailer_variable,
+      0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
+
     { ngx_string("upstream_cookie_"), NULL, ngx_http_upstream_cookie_variable,
       0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
 
@@ -1042,6 +1059,13 @@
         return NGX_ERROR;
     }
 
+    if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
+                      sizeof(ngx_table_elt_t))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
     rc = u->process_header(r);
 
     if (rc == NGX_OK) {
@@ -1854,6 +1878,13 @@
         return NGX_ERROR;
     }
 
+    if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
+                      sizeof(ngx_table_elt_t))
+        != NGX_OK)
+    {
+        return NGX_ERROR;
+    }
+
     /* reinit the request chain */
 
     file_pos = 0;
@@ -2179,8 +2210,12 @@
         return;
     }
 
-    if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {
-        ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
+    if (!u->request_sent) {
+        if (ngx_http_upstream_test_connect(c) != NGX_OK) {
+            ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
+            return;
+        }
+
         return;
     }
 
@@ -2208,6 +2243,15 @@
             return;
         }
 
+        if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
+                          sizeof(ngx_table_elt_t))
+            != NGX_OK)
+        {
+            ngx_http_upstream_finalize_request(r, u,
+                                               NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
+
 #if (NGX_HTTP_CACHE)
 
         if (r->cache) {
@@ -2715,6 +2759,44 @@
 }
 
 
+static ngx_int_t
+ngx_http_upstream_process_trailers(ngx_http_request_t *r, ngx_http_upstream_t *u)
+{
+    ngx_uint_t       i;
+    ngx_list_part_t  *part;
+    ngx_table_elt_t  *h, *ho;
+
+    if (!u->conf->pass_trailers || !r->allow_trailers || !r->expect_trailers) {
+        return NGX_OK;
+    }
+
+    part = &u->headers_in.trailers.part;
+    h = part->elts;
+
+    for (i = 0; /* void */; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+
+            part = part->next;
+            h = part->elts;
+            i = 0;
+        }
+
+        ho = ngx_list_push(&r->headers_out.trailers);
+        if (ho == NULL) {
+            return NGX_ERROR;
+        }
+
+        *ho = h[i];
+    }
+
+    return NGX_OK;
+}
+
+
 static void
 ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
     ngx_http_upstream_t *u)
@@ -4022,6 +4104,10 @@
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http next upstream, %xi", ft_type);
 
+    if (u->state && u->state->bytes_sent == 0 && u->peer.connection) {
+        u->state->bytes_sent = u->peer.connection->sent;
+    }
+
     if (u->peer.sockaddr) {
 
         if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_403
@@ -4191,6 +4277,10 @@
                                         - u->pipe->preread_size;
             u->state->response_length = u->pipe->read_length;
         }
+
+        if (u->state->bytes_sent == 0 && u->peer.connection) {
+            u->state->bytes_sent = u->peer.connection->sent;
+        }
     }
 
     u->finalize_request(r, rc);
@@ -4310,6 +4400,13 @@
     }
 
     if (rc == 0) {
+        if (ngx_http_upstream_process_trailers(r, u) != NGX_OK) {
+            rc = NGX_ERROR;
+            flush = 1;
+        }
+    }
+
+    if (rc == 0) {
         rc = ngx_http_send_special(r, NGX_HTTP_LAST);
 
     } else if (flush) {
@@ -5096,7 +5193,30 @@
 }
 
 
-#if (NGX_HTTP_GZIP)
+static ngx_int_t
+ngx_http_upstream_copy_trailer(ngx_http_request_t *r,
+    ngx_table_elt_t *h, ngx_uint_t offset)
+{
+    ngx_table_elt_t  *ho;
+
+    if (!r->upstream->conf->pass_trailers
+        || !r->allow_trailers || !r->expect_trailers)
+    {
+        return NGX_OK;
+    }
+
+    ho = ngx_list_push(&r->headers_out.headers);
+    if (ho == NULL) {
+        return NGX_ERROR;
+    }
+
+    *ho = *h;
+
+    return NGX_OK;
+}
+
+
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
 
 static ngx_int_t
 ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r,
@@ -5353,7 +5473,7 @@
 
 
 static ngx_int_t
-ngx_http_upstream_response_length_variable(ngx_http_request_t *r,
+ngx_http_upstream_bytes_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {
     u_char                     *p;
@@ -5384,7 +5504,10 @@
 
     for ( ;; ) {
 
-        if (data == 1) {
+        if (data == 2) {
+            p = ngx_sprintf(p, "%O", state[i].bytes_sent);
+
+        } else if (data == 1) {
             p = ngx_sprintf(p, "%O", state[i].bytes_received);
 
         } else {
@@ -5434,6 +5557,21 @@
 
 
 static ngx_int_t
+ngx_http_upstream_trailer_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    if (r->upstream == NULL) {
+        v->not_found = 1;
+        return NGX_OK;
+    }
+
+    return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
+                                        &r->upstream->headers_in.trailers.part,
+                                        sizeof("upstream_trailer_") - 1);
+}
+
+
+static ngx_int_t
 ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index c552ac0..ec4cb97 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -63,6 +63,7 @@
     ngx_msec_t                       header_time;
     off_t                            response_length;
     off_t                            bytes_received;
+    off_t                            bytes_sent;
 
     ngx_str_t                       *peer;
 } ngx_http_upstream_state_t;
@@ -129,7 +130,7 @@
     in_port_t                        port;
     ngx_uint_t                       no_port;  /* unsigned no_port:1 */
 
-#if (NGX_HTTP_UPSTREAM_ZONE)
+#if (NGX_HTTP_UPSTREAM_ZONE || NGX_COMPAT)
     ngx_shm_zone_t                  *shm_zone;
 #endif
 };
@@ -186,6 +187,8 @@
     ngx_array_t                     *hide_headers;
     ngx_array_t                     *pass_headers;
 
+    ngx_flag_t                       pass_trailers;
+
     ngx_http_upstream_local_t       *local;
 
 #if (NGX_HTTP_CACHE)
@@ -224,6 +227,7 @@
 
 #if (NGX_HTTP_SSL || NGX_COMPAT)
     ngx_ssl_t                       *ssl;
+    ngx_flag_t                       ssl_alpn;
     ngx_flag_t                       ssl_session_reuse;
 
     ngx_http_complex_value_t        *ssl_name;
@@ -250,6 +254,7 @@
 
 typedef struct {
     ngx_list_t                       headers;
+    ngx_list_t                       trailers;
 
     ngx_uint_t                       status_n;
     ngx_str_t                        status_line;
@@ -275,7 +280,7 @@
     ngx_table_elt_t                 *transfer_encoding;
     ngx_table_elt_t                 *vary;
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     ngx_table_elt_t                 *content_encoding;
 #endif
 
diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c
index f6051ae..d4e5a6d 100644
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -667,7 +667,7 @@
     ngx_int_t                      rc;
     ngx_ssl_session_t             *ssl_session;
     ngx_http_upstream_rr_peer_t   *peer;
-#if (NGX_HTTP_UPSTREAM_ZONE)
+#if (NGX_HTTP_UPSTREAM_ZONE || NGX_COMPAT)
     int                            len;
 #if OPENSSL_VERSION_NUMBER >= 0x0090707fL
     const
@@ -679,7 +679,7 @@
 
     peer = rrp->current;
 
-#if (NGX_HTTP_UPSTREAM_ZONE)
+#if (NGX_HTTP_UPSTREAM_ZONE || NGX_COMPAT)
     peers = rrp->peers;
 
     if (peers->shpool) {
@@ -732,14 +732,14 @@
 
     ngx_ssl_session_t             *old_ssl_session, *ssl_session;
     ngx_http_upstream_rr_peer_t   *peer;
-#if (NGX_HTTP_UPSTREAM_ZONE)
+#if (NGX_HTTP_UPSTREAM_ZONE || NGX_COMPAT)
     int                            len;
     u_char                        *p;
     ngx_http_upstream_rr_peers_t  *peers;
     u_char                         buf[NGX_SSL_MAX_SESSION_SIZE];
 #endif
 
-#if (NGX_HTTP_UPSTREAM_ZONE)
+#if (NGX_HTTP_UPSTREAM_ZONE || NGX_COMPAT)
     peers = rrp->peers;
 
     if (peers->shpool) {
diff --git a/src/http/ngx_http_upstream_round_robin.h b/src/http/ngx_http_upstream_round_robin.h
index 45f258d..8b5060f 100644
--- a/src/http/ngx_http_upstream_round_robin.h
+++ b/src/http/ngx_http_upstream_round_robin.h
@@ -45,7 +45,7 @@
     int                             ssl_session_len;
 #endif
 
-#if (NGX_HTTP_UPSTREAM_ZONE)
+#if (NGX_HTTP_UPSTREAM_ZONE || NGX_COMPAT)
     ngx_atomic_t                    lock;
 #endif
 
@@ -61,7 +61,7 @@
 struct ngx_http_upstream_rr_peers_s {
     ngx_uint_t                      number;
 
-#if (NGX_HTTP_UPSTREAM_ZONE)
+#if (NGX_HTTP_UPSTREAM_ZONE || NGX_COMPAT)
     ngx_slab_pool_t                *shpool;
     ngx_atomic_t                    rwlock;
     ngx_http_upstream_rr_peers_t   *zone_next;
@@ -80,7 +80,7 @@
 };
 
 
-#if (NGX_HTTP_UPSTREAM_ZONE)
+#if (NGX_HTTP_UPSTREAM_ZONE || NGX_COMPAT)
 
 #define ngx_http_upstream_rr_peers_rlock(peers)                               \
                                                                               \
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index 6138819..4be6550 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -38,6 +38,8 @@
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_unknown_header_out(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_unknown_trailer_out(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_request_line(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_cookie(ngx_http_request_t *r,
@@ -168,12 +170,12 @@
     { ngx_string("http_referer"), NULL, ngx_http_variable_header,
       offsetof(ngx_http_request_t, headers_in.referer), 0, 0 },
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     { ngx_string("http_via"), NULL, ngx_http_variable_header,
       offsetof(ngx_http_request_t, headers_in.via), 0, 0 },
 #endif
 
-#if (NGX_HTTP_X_FORWARDED_FOR)
+#if (NGX_HTTP_X_FORWARDED_FOR || NGX_COMPAT)
     { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_headers,
       offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 },
 #endif
@@ -365,6 +367,9 @@
     { ngx_string("sent_http_"), NULL, ngx_http_variable_unknown_header_out,
       0, NGX_HTTP_VAR_PREFIX, 0 },
 
+    { ngx_string("sent_trailer_"), NULL, ngx_http_variable_unknown_trailer_out,
+      0, NGX_HTTP_VAR_PREFIX, 0 },
+
     { ngx_string("cookie_"), NULL, ngx_http_variable_cookie,
       0, NGX_HTTP_VAR_PREFIX, 0 },
 
@@ -934,6 +939,16 @@
 }
 
 
+static ngx_int_t
+ngx_http_variable_unknown_trailer_out(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
+                                            &r->headers_out.trailers.part,
+                                            sizeof("sent_trailer_") - 1);
+}
+
+
 ngx_int_t
 ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var,
     ngx_list_part_t *part, size_t prefix)
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
index ed78638..6301161 100644
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -36,13 +36,16 @@
 
 #define NGX_HTTP_V2_STREAM_ID_SIZE               4
 
+#define NGX_HTTP_V2_SETTINGS_ACK_SIZE            0
 #define NGX_HTTP_V2_SETTINGS_PARAM_SIZE          6
 
 /* settings fields */
 #define NGX_HTTP_V2_HEADER_TABLE_SIZE_SETTING    0x1
+#define NGX_HTTP_V2_ENABLE_PUSH_SETTING          0x2
 #define NGX_HTTP_V2_MAX_STREAMS_SETTING          0x3
 #define NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING     0x4
 #define NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING       0x5
+#define NGX_HTTP_V2_HEADER_LIST_SIZE_SETTING     0x6
 
 #define NGX_HTTP_V2_FRAME_BUFFER_SIZE            24
 
@@ -128,8 +131,7 @@
 #define ngx_http_v2_index_size(h2scf)  (h2scf->streams_index_mask + 1)
 #define ngx_http_v2_index(h2scf, sid)  ((sid >> 1) & h2scf->streams_index_mask)
 
-static ngx_int_t ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c,
-    ngx_uint_t ack);
+static ngx_int_t ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c);
 static ngx_int_t ngx_http_v2_settings_frame_handler(
     ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame);
 static ngx_int_t ngx_http_v2_send_window_update(ngx_http_v2_connection_t *h2c,
@@ -269,7 +271,7 @@
         return;
     }
 
-    if (ngx_http_v2_send_settings(h2c, 0) == NGX_ERROR) {
+    if (ngx_http_v2_send_settings(h2c) == NGX_ERROR) {
         ngx_http_close_connection(c);
         return;
     }
@@ -1568,6 +1570,10 @@
         rc = ngx_http_v2_pseudo_header(r, header);
 
         if (rc == NGX_OK) {
+            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "http2 http header: \":%V: %V\"",
+                           &header->name, &header->value);
+
             return ngx_http_v2_state_header_complete(h2c, pos, end);
         }
 
@@ -1899,6 +1905,11 @@
 
     switch (status) {
 
+    case NGX_HTTP_V2_NO_ERROR:
+        ngx_log_error(NGX_LOG_INFO, fc->log, 0,
+                      "client closed stream %ui", h2c->state.sid);
+        break;
+
     case NGX_HTTP_V2_CANCEL:
         ngx_log_error(NGX_LOG_INFO, fc->log, 0,
                       "client canceled stream %ui", h2c->state.sid);
@@ -1938,6 +1949,9 @@
             return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
         }
 
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                       "http2 SETTINGS frame ack:1");
+
         h2c->settings_ack = 1;
 
         return ngx_http_v2_state_complete(h2c, pos, end);
@@ -1951,7 +1965,9 @@
         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
     }
 
-    ngx_http_v2_send_settings(h2c, 1);
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                   "http2 SETTINGS frame params:%uz",
+                   h2c->state.length / NGX_HTTP_V2_SETTINGS_PARAM_SIZE);
 
     return ngx_http_v2_state_settings_params(h2c, pos, end);
 }
@@ -1961,7 +1977,10 @@
 ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos,
     u_char *end)
 {
-    ngx_uint_t  id, value;
+    ngx_uint_t                id, value, adjustment;
+    ngx_http_v2_out_frame_t  *frame;
+
+    adjustment = 0;
 
     while (h2c->state.length) {
         if (end - pos < NGX_HTTP_V2_SETTINGS_PARAM_SIZE) {
@@ -1976,6 +1995,36 @@
 
         switch (id) {
 
+        case NGX_HTTP_V2_HEADER_TABLE_SIZE_SETTING:
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                           "http2 SETTINGS frame HEADER_TABLE_SIZE:%ui "
+                           "(ignored)", value);
+            break;
+
+        case NGX_HTTP_V2_ENABLE_PUSH_SETTING:
+
+            if (value != 0 && value != 1) {
+                ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
+                              "client sent SETTINGS frame with incorrect "
+                              "ENABLE_PUSH value %ui", value);
+
+                return ngx_http_v2_connection_error(h2c,
+                                                    NGX_HTTP_V2_PROTOCOL_ERROR);
+            }
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                           "http2 SETTINGS frame ENABLE_PUSH:%ui "
+                           "(ignored)", value);
+            break;
+
+        case NGX_HTTP_V2_MAX_STREAMS_SETTING:
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                           "http2 SETTINGS frame MAX_CONCURRENT_STREAMS:%ui "
+                           "(ignored)", value);
+            break;
+
         case NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING:
 
             if (value > NGX_HTTP_V2_MAX_WINDOW) {
@@ -1987,13 +2036,11 @@
                                                   NGX_HTTP_V2_FLOW_CTRL_ERROR);
             }
 
-            if (ngx_http_v2_adjust_windows(h2c, value - h2c->init_window)
-                != NGX_OK)
-            {
-                return ngx_http_v2_connection_error(h2c,
-                                                    NGX_HTTP_V2_INTERNAL_ERROR);
-            }
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                           "http2 SETTINGS frame INITIAL_WINDOW_SIZE:%ui",
+                           value);
 
+            adjustment = value - h2c->init_window;
             h2c->init_window = value;
             break;
 
@@ -2010,16 +2057,50 @@
                                                     NGX_HTTP_V2_PROTOCOL_ERROR);
             }
 
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                           "http2 SETTINGS frame MAX_FRAME_SIZE:%ui",
+                           value);
+
             h2c->frame_size = value;
             break;
 
+        case NGX_HTTP_V2_HEADER_LIST_SIZE_SETTING:
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                           "http2 SETTINGS frame MAX_HEADER_LIST_SIZE:%ui "
+                           "(ignored)", value);
+            break;
+
         default:
+
+            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                           "http2 SETTINGS frame 0x%Xi:%ui "
+                           "(ignored)", id, value);
             break;
         }
 
         pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE;
     }
 
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                   "http2 send SETTINGS frame ack:1");
+
+    frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_SETTINGS_ACK_SIZE,
+                                  NGX_HTTP_V2_SETTINGS_FRAME,
+                                  NGX_HTTP_V2_ACK_FLAG, 0);
+    if (frame == NULL) {
+        return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
+    }
+
+    ngx_http_v2_queue_ordered_frame(h2c, frame);
+
+    if (adjustment) {
+        if (ngx_http_v2_adjust_windows(h2c, adjustment) != NGX_OK) {
+            return ngx_http_v2_connection_error(h2c,
+                                                NGX_HTTP_V2_INTERNAL_ERROR);
+        }
+    }
+
     return ngx_http_v2_state_complete(h2c, pos, end);
 }
 
@@ -2054,12 +2135,16 @@
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
-                   "http2 PING frame, flags: %ud", h2c->state.flags);
+                   "http2 PING frame ack:%ud",
+                   h2c->state.flags & NGX_HTTP_V2_ACK_FLAG ? 1 : 0);
 
     if (h2c->state.flags & NGX_HTTP_V2_ACK_FLAG) {
         return ngx_http_v2_state_skip(h2c, pos, end);
     }
 
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                   "http2 send PING frame ack:1");
+
     frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_PING_SIZE,
                                   NGX_HTTP_V2_PING_FRAME,
                                   NGX_HTTP_V2_ACK_FLAG, 0);
@@ -2463,7 +2548,7 @@
 
 
 static ngx_int_t
-ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c, ngx_uint_t ack)
+ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c)
 {
     size_t                    len;
     ngx_buf_t                *buf;
@@ -2471,8 +2556,10 @@
     ngx_http_v2_srv_conf_t   *h2scf;
     ngx_http_v2_out_frame_t  *frame;
 
-    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
-                   "http2 send SETTINGS frame ack:%ui", ack);
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                   "http2 send SETTINGS frame params:3");
+
+    len = NGX_HTTP_V2_SETTINGS_PARAM_SIZE * 3;
 
     frame = ngx_palloc(h2c->pool, sizeof(ngx_http_v2_out_frame_t));
     if (frame == NULL) {
@@ -2484,8 +2571,6 @@
         return NGX_ERROR;
     }
 
-    len = ack ? 0 : (sizeof(uint16_t) + sizeof(uint32_t)) * 3;
-
     buf = ngx_create_temp_buf(h2c->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE + len);
     if (buf == NULL) {
         return NGX_ERROR;
@@ -2508,28 +2593,38 @@
     buf->last = ngx_http_v2_write_len_and_type(buf->last, len,
                                                NGX_HTTP_V2_SETTINGS_FRAME);
 
-    *buf->last++ = ack ? NGX_HTTP_V2_ACK_FLAG : NGX_HTTP_V2_NO_FLAG;
+    *buf->last++ = NGX_HTTP_V2_NO_FLAG;
 
     buf->last = ngx_http_v2_write_sid(buf->last, 0);
 
-    if (!ack) {
-        h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
-                                             ngx_http_v2_module);
+    h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
+                                         ngx_http_v2_module);
 
-        buf->last = ngx_http_v2_write_uint16(buf->last,
-                                             NGX_HTTP_V2_MAX_STREAMS_SETTING);
-        buf->last = ngx_http_v2_write_uint32(buf->last,
-                                             h2scf->concurrent_streams);
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                   "http2 send SETTINGS frame MAX_CONCURRENT_STREAMS:%ui",
+                   h2scf->concurrent_streams);
 
-        buf->last = ngx_http_v2_write_uint16(buf->last,
+    buf->last = ngx_http_v2_write_uint16(buf->last,
+                                         NGX_HTTP_V2_MAX_STREAMS_SETTING);
+    buf->last = ngx_http_v2_write_uint32(buf->last,
+                                         h2scf->concurrent_streams);
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                   "http2 send SETTINGS frame INITIAL_WINDOW_SIZE:%uz",
+                   h2scf->preread_size);
+
+    buf->last = ngx_http_v2_write_uint16(buf->last,
                                          NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING);
-        buf->last = ngx_http_v2_write_uint32(buf->last, h2scf->preread_size);
+    buf->last = ngx_http_v2_write_uint32(buf->last, h2scf->preread_size);
 
-        buf->last = ngx_http_v2_write_uint16(buf->last,
-                                           NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING);
-        buf->last = ngx_http_v2_write_uint32(buf->last,
-                                             NGX_HTTP_V2_MAX_FRAME_SIZE);
-    }
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+                   "http2 send SETTINGS frame MAX_FRAME_SIZE:%ud",
+                   NGX_HTTP_V2_MAX_FRAME_SIZE);
+
+    buf->last = ngx_http_v2_write_uint16(buf->last,
+                                         NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING);
+    buf->last = ngx_http_v2_write_uint32(buf->last,
+                                         NGX_HTTP_V2_MAX_FRAME_SIZE);
 
     ngx_http_v2_queue_blocked_frame(h2c, frame);
 
@@ -3313,7 +3408,8 @@
     static const u_char ending[] = " HTTP/2.0";
 
     if (r->method_name.len == 0
-        || r->unparsed_uri.len == 0)
+        || r->unparsed_uri.len == 0
+        || r->schema_start == NULL)
     {
         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
         return NGX_ERROR;
diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h
index be34a09..4804658 100644
--- a/src/http/v2/ngx_http_v2.h
+++ b/src/http/v2/ngx_http_v2.h
@@ -261,6 +261,15 @@
 }
 
 
+static ngx_inline void
+ngx_http_v2_queue_ordered_frame(ngx_http_v2_connection_t *h2c,
+    ngx_http_v2_out_frame_t *frame)
+{
+    frame->next = h2c->last_out;
+    h2c->last_out = frame;
+}
+
+
 void ngx_http_v2_init(ngx_event_t *rev);
 void ngx_http_v2_request_headers_init(void);
 
diff --git a/src/http/v2/ngx_http_v2_filter_module.c b/src/http/v2/ngx_http_v2_filter_module.c
index 7276531..29b07b6 100644
--- a/src/http/v2/ngx_http_v2_filter_module.c
+++ b/src/http/v2/ngx_http_v2_filter_module.c
@@ -50,13 +50,17 @@
 #define NGX_HTTP_V2_SERVER_INDEX          54
 #define NGX_HTTP_V2_VARY_INDEX            59
 
+#define NGX_HTTP_V2_FRAME_ERROR           (ngx_http_v2_out_frame_t *) -1
+
 
 static u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
     u_char *tmp, ngx_uint_t lower);
 static u_char *ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix,
     ngx_uint_t value);
 static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame(
-    ngx_http_request_t *r, u_char *pos, u_char *end);
+    ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin);
+static ngx_http_v2_out_frame_t *ngx_http_v2_create_trailers_frame(
+    ngx_http_request_t *r);
 
 static ngx_chain_t *ngx_http_v2_send_chain(ngx_connection_t *fc,
     ngx_chain_t *in, off_t limit);
@@ -129,22 +133,24 @@
     u_char                     status, *pos, *start, *p, *tmp;
     size_t                     len, tmp_len;
     ngx_str_t                  host, location;
-    ngx_uint_t                 i, port;
+    ngx_uint_t                 i, port, fin;
     ngx_list_part_t           *part;
     ngx_table_elt_t           *header;
     ngx_connection_t          *fc;
     ngx_http_cleanup_t        *cln;
-    ngx_http_v2_out_frame_t   *frame;
+    ngx_http_v2_out_frame_t   *headers, *trailers;
     ngx_http_core_loc_conf_t  *clcf;
     ngx_http_core_srv_conf_t  *cscf;
     u_char                     addr[NGX_SOCKADDR_STRLEN];
 
-    static const u_char nginx[5] = "\x84\xaa\x63\x55\xe7";
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     static const u_char accept_encoding[12] =
         "\x8b\x84\x84\x2d\x69\x5b\x05\x44\x3c\x86\xaa\x6f";
 #endif
 
+    static size_t nginx_name_len = ngx_http_v2_literal_size(NGINX_NAME);
+    static u_char nginx_name[ngx_http_v2_literal_size(NGINX_NAME)];
+
     static size_t nginx_ver_len = ngx_http_v2_literal_size(NGINX_VER);
     static u_char nginx_ver[ngx_http_v2_literal_size(NGINX_VER)];
 
@@ -244,7 +250,7 @@
             len += 1 + nginx_ver_build_len;
 
         } else {
-            len += 1 + sizeof(nginx);
+            len += 1 + nginx_name_len;
         }
     }
 
@@ -354,7 +360,7 @@
 
     tmp_len = len;
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     if (r->gzip_vary) {
         if (clcf->gzip_vary) {
             len += 1 + sizeof(accept_encoding);
@@ -445,8 +451,9 @@
                            NGINX_VER_BUILD);
 
         } else {
-            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
-                           "http2 output header: \"server: nginx\"");
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
+                           "http2 output header: \"server: %s\"",
+                           NGINX_NAME);
         }
 
         *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_SERVER_INDEX);
@@ -471,7 +478,13 @@
             pos = ngx_cpymem(pos, nginx_ver_build, nginx_ver_build_len);
 
         } else {
-            pos = ngx_cpymem(pos, nginx, sizeof(nginx));
+            if (nginx_name[0] == '\0') {
+                p = ngx_http_v2_write_value(nginx_name, (u_char *) NGINX_NAME,
+                                            sizeof(NGINX_NAME) - 1, tmp);
+                nginx_name_len = p - nginx_name;
+            }
+
+            pos = ngx_cpymem(pos, nginx_name, nginx_name_len);
         }
     }
 
@@ -564,7 +577,7 @@
                                       r->headers_out.location->value.len, tmp);
     }
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_COMPAT)
     if (r->gzip_vary) {
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
                        "http2 output header: \"vary: Accept-Encoding\"");
@@ -612,15 +625,6 @@
                                       header[i].value.len, tmp);
     }
 
-    frame = ngx_http_v2_create_headers_frame(r, start, pos);
-    if (frame == NULL) {
-        return NGX_ERROR;
-    }
-
-    ngx_http_v2_queue_blocked_frame(r->stream->connection, frame);
-
-    r->stream->queued = 1;
-
     cln = ngx_http_cleanup_add(r, 0);
     if (cln == NULL) {
         return NGX_ERROR;
@@ -629,6 +633,32 @@
     cln->handler = ngx_http_v2_filter_cleanup;
     cln->data = r->stream;
 
+    if (r->header_only && r->allow_trailers && r->expect_trailers) {
+        trailers = ngx_http_v2_create_trailers_frame(r);
+        if (trailers == NGX_HTTP_V2_FRAME_ERROR) {
+            return NGX_ERROR;
+        }
+
+        fin = trailers ? 0 : 1;
+
+    } else {
+        trailers = NULL;
+        fin = r->header_only;
+    }
+
+    headers = ngx_http_v2_create_headers_frame(r, start, pos, fin);
+    if (headers == NULL) {
+        return NGX_ERROR;
+    }
+
+    ngx_http_v2_queue_blocked_frame(r->stream->connection, headers);
+    r->stream->queued = 1;
+
+    if (trailers) {
+        ngx_http_v2_queue_blocked_frame(r->stream->connection, trailers);
+        r->stream->queued++;
+    }
+
     fc->send_chain = ngx_http_v2_send_chain;
     fc->need_last_buf = 1;
 
@@ -636,6 +666,133 @@
 }
 
 
+static ngx_http_v2_out_frame_t *
+ngx_http_v2_create_trailers_frame(ngx_http_request_t *r)
+{
+    u_char                   *pos, *start, *tmp;
+    size_t                    len, tmp_len;
+    ngx_uint_t                i;
+    ngx_list_part_t          *part;
+    ngx_table_elt_t          *header;
+    ngx_http_v2_out_frame_t  *frame;
+
+    if (ngx_http_eval_trailers(r) != NGX_OK) {
+        return NGX_HTTP_V2_FRAME_ERROR;
+    }
+
+    len = 0;
+    tmp_len = 0;
+
+    part = &r->headers_out.trailers.part;
+    header = part->elts;
+
+    for (i = 0; /* void */; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+
+            part = part->next;
+            header = part->elts;
+            i = 0;
+        }
+
+        if (header[i].hash == 0) {
+            continue;
+        }
+
+        if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) {
+            ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
+                          "too long response trailer name: \"%V\"",
+                          &header[i].key);
+
+            return NGX_HTTP_V2_FRAME_ERROR;
+        }
+
+        if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) {
+            ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
+                          "too long response trailer value: \"%V: %V\"",
+                          &header[i].key, &header[i].value);
+
+            return NGX_HTTP_V2_FRAME_ERROR;
+        }
+
+        len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len
+                 + NGX_HTTP_V2_INT_OCTETS + header[i].value.len;
+
+        if (header[i].key.len > tmp_len) {
+            tmp_len = header[i].key.len;
+        }
+
+        if (header[i].value.len > tmp_len) {
+            tmp_len = header[i].value.len;
+        }
+    }
+
+    if (len == 0) {
+        return NULL;
+    }
+
+    tmp = ngx_palloc(r->pool, tmp_len);
+    pos = ngx_pnalloc(r->pool, len);
+
+    if (pos == NULL || tmp == NULL) {
+        return NGX_HTTP_V2_FRAME_ERROR;
+    }
+
+    start = pos;
+
+    part = &r->headers_out.trailers.part;
+    header = part->elts;
+
+    for (i = 0; /* void */; i++) {
+
+        if (i >= part->nelts) {
+            if (part->next == NULL) {
+                break;
+            }
+
+            part = part->next;
+            header = part->elts;
+            i = 0;
+        }
+
+        if (header[i].hash == 0
+            || header[i].key.len > NGX_HTTP_V2_MAX_FIELD
+            || header[i].value.len > NGX_HTTP_V2_MAX_FIELD)
+        {
+            continue;
+        }
+
+#if (NGX_DEBUG)
+        if (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP) {
+            ngx_strlow(tmp, header[i].key.data, header[i].key.len);
+
+            ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "http2 output trailer: \"%*s: %V\"",
+                           header[i].key.len, tmp, &header[i].value);
+        }
+#endif
+
+        *pos++ = 0;
+
+        pos = ngx_http_v2_write_name(pos, header[i].key.data,
+                                     header[i].key.len, tmp);
+
+        pos = ngx_http_v2_write_value(pos, header[i].value.data,
+                                      header[i].value.len, tmp);
+    }
+
+    frame = ngx_http_v2_create_headers_frame(r, start, pos, 1);
+    if (frame == NULL) {
+        return NGX_HTTP_V2_FRAME_ERROR;
+    }
+
+    return frame;
+}
+
+
 static u_char *
 ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp,
     ngx_uint_t lower)
@@ -686,7 +843,7 @@
 
 static ngx_http_v2_out_frame_t *
 ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
-    u_char *end)
+    u_char *end, ngx_uint_t fin)
 {
     u_char                    type, flags;
     size_t                    rest, frame_size;
@@ -707,12 +864,12 @@
     frame->stream = stream;
     frame->length = rest;
     frame->blocked = 1;
-    frame->fin = r->header_only;
+    frame->fin = fin;
 
     ll = &frame->first;
 
     type = NGX_HTTP_V2_HEADERS_FRAME;
-    flags = r->header_only ? NGX_HTTP_V2_END_STREAM_FLAG : NGX_HTTP_V2_NO_FLAG;
+    flags = fin ? NGX_HTTP_V2_END_STREAM_FLAG : NGX_HTTP_V2_NO_FLAG;
     frame_size = stream->connection->frame_size;
 
     for ( ;; ) {
@@ -776,7 +933,7 @@
             continue;
         }
 
-        b->last_buf = r->header_only;
+        b->last_buf = fin;
         cl->next = NULL;
         frame->last = cl;
 
@@ -798,7 +955,7 @@
     ngx_http_request_t        *r;
     ngx_http_v2_stream_t      *stream;
     ngx_http_v2_loc_conf_t    *h2lcf;
-    ngx_http_v2_out_frame_t   *frame;
+    ngx_http_v2_out_frame_t   *frame, *trailers;
     ngx_http_v2_connection_t  *h2c;
 
     r = fc->data;
@@ -872,6 +1029,8 @@
     frame_size = (h2lcf->chunk_size < h2c->frame_size)
                  ? h2lcf->chunk_size : h2c->frame_size;
 
+    trailers = NULL;
+
 #if (NGX_SUPPRESS_WARN)
     cl = NULL;
 #endif
@@ -934,17 +1093,35 @@
             size -= rest;
         }
 
-        frame = ngx_http_v2_filter_get_data_frame(stream, frame_size, out, cl);
-        if (frame == NULL) {
-            return NGX_CHAIN_ERROR;
+        if (cl->buf->last_buf && r->allow_trailers && r->expect_trailers) {
+            trailers = ngx_http_v2_create_trailers_frame(r);
+            if (trailers == NGX_HTTP_V2_FRAME_ERROR) {
+                return NGX_CHAIN_ERROR;
+            }
+
+            if (trailers) {
+                cl->buf->last_buf = 0;
+            }
         }
 
-        ngx_http_v2_queue_frame(h2c, frame);
+        if (frame_size || cl->buf->last_buf) {
+            frame = ngx_http_v2_filter_get_data_frame(stream, frame_size, out, cl);
+            if (frame == NULL) {
+                return NGX_CHAIN_ERROR;
+            }
 
-        h2c->send_window -= frame_size;
+            ngx_http_v2_queue_frame(h2c, frame);
 
-        stream->send_window -= frame_size;
-        stream->queued++;
+            h2c->send_window -= frame_size;
+
+            stream->send_window -= frame_size;
+            stream->queued++;
+        }
+
+        if (trailers) {
+            ngx_http_v2_queue_frame(h2c, trailers);
+            stream->queued++;
+        }
 
         if (in == NULL) {
             break;
diff --git a/src/ngx_modules.c b/src/ngx_modules.c
new file mode 100644
index 0000000..34b19b1
--- /dev/null
+++ b/src/ngx_modules.c
@@ -0,0 +1,1143 @@
+
+/*
+ * Copyright (C) Google Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_modules.h>
+
+
+extern ngx_module_t  ngx_core_module;
+extern ngx_module_t  ngx_errlog_module;
+extern ngx_module_t  ngx_conf_module;
+#if (NGX_SSL)
+extern ngx_module_t  ngx_openssl_module;
+#endif
+#if (NGX_PCRE)
+extern ngx_module_t  ngx_regex_module;
+#endif
+extern ngx_module_t  ngx_events_module;
+extern ngx_module_t  ngx_event_core_module;
+#if (NGX_HAVE_EPOLL)
+extern ngx_module_t  ngx_epoll_module;
+#endif
+#if (NGX_HAVE_KQUEUE)
+extern ngx_module_t  ngx_kqueue_module;
+#endif
+#if (NGX_HAVE_SELECT)
+extern ngx_module_t  ngx_select_module;
+#endif
+#if (NGX_HAVE_POLL)
+extern ngx_module_t  ngx_poll_module;
+#endif
+#if (NGX_THREADS)
+extern ngx_module_t  ngx_thread_pool_module;
+#endif
+
+#if (NGX_HTTP)
+extern ngx_module_t  ngx_http_module;
+extern ngx_module_t  ngx_http_core_module;
+extern ngx_module_t  ngx_http_log_module;
+extern ngx_module_t  ngx_http_upstream_module;
+#endif
+#if (NGX_HTTP_V2)
+extern ngx_module_t  ngx_http_v2_module;
+#endif
+#if (NGX_HTTP)
+extern ngx_module_t  ngx_http_static_module;
+#endif
+#if (NGX_HTTP_GZIP_STATIC)
+extern ngx_module_t  ngx_http_gzip_static_module;
+#endif
+#if (NGX_HTTP_BROTLI_STATIC)
+extern ngx_module_t  ngx_http_brotli_static_module;
+#endif
+#if (NGX_HTTP_DAV)
+extern ngx_module_t  ngx_http_dav_module;
+#endif
+#if (NGX_HTTP_AUTOINDEX)
+extern ngx_module_t  ngx_http_autoindex_module;
+#endif
+#if (NGX_HTTP)
+extern ngx_module_t  ngx_http_index_module;
+#endif
+#if (NGX_HTTP_RANDOM_INDEX)
+extern ngx_module_t  ngx_http_random_index_module;
+#endif
+#if (NGX_HTTP_AUTH_REQUEST)
+extern ngx_module_t  ngx_http_auth_request_module;
+#endif
+#if (NGX_HTTP_AUTH_BASIC)
+extern ngx_module_t  ngx_http_auth_basic_module;
+#endif
+#if (NGX_HTTP_ACCESS)
+extern ngx_module_t  ngx_http_access_module;
+#endif
+#if (NGX_HTTP_LIMIT_CONN)
+extern ngx_module_t  ngx_http_limit_conn_module;
+#endif
+#if (NGX_HTTP_LIMIT_REQ)
+extern ngx_module_t  ngx_http_limit_req_module;
+#endif
+#if (NGX_HTTP_REALIP)
+extern ngx_module_t  ngx_http_realip_module;
+#endif
+#if (NGX_HTTP_GEO)
+extern ngx_module_t  ngx_http_geo_module;
+#endif
+#if 0
+extern ngx_module_t  ngx_http_geoip_module;
+#endif
+#if (NGX_HTTP_MAP)
+extern ngx_module_t  ngx_http_map_module;
+#endif
+#if (NGX_HTTP_SPLIT_CLIENTS)
+extern ngx_module_t  ngx_http_split_clients_module;
+#endif
+#if (NGX_HTTP_REFERER)
+extern ngx_module_t  ngx_http_referer_module;
+#endif
+#if (NGX_HTTP_REWRITE)
+extern ngx_module_t  ngx_http_rewrite_module;
+#endif
+#if (NGX_HTTP_SSL)
+extern ngx_module_t  ngx_http_ssl_module;
+#endif
+#if (NGX_HTTP_PROXY)
+extern ngx_module_t  ngx_http_proxy_module;
+#endif
+#if (NGX_HTTP_FASTCGI)
+extern ngx_module_t  ngx_http_fastcgi_module;
+#endif
+#if (NGX_HTTP_UWSGI)
+extern ngx_module_t  ngx_http_uwsgi_module;
+#endif
+#if (NGX_HTTP_SCGI)
+extern ngx_module_t  ngx_http_scgi_module;
+#endif
+#if 0
+extern ngx_module_t  ngx_http_perl_module;
+#endif
+#if (NGX_HTTP_MEMCACHED)
+extern ngx_module_t  ngx_http_memcached_module;
+#endif
+#if (NGX_HTTP_EMPTY_GIF)
+extern ngx_module_t  ngx_http_empty_gif_module;
+#endif
+#if (NGX_HTTP_BROWSER)
+extern ngx_module_t  ngx_http_browser_module;
+#endif
+#if (NGX_HTTP_SECURE_LINK)
+extern ngx_module_t  ngx_http_secure_link_module;
+#endif
+#if 0
+extern ngx_module_t  ngx_http_degradation_module;
+#endif
+#if (NGX_HTTP_FLV)
+extern ngx_module_t  ngx_http_flv_module;
+#endif
+#if (NGX_HTTP_MP4)
+extern ngx_module_t  ngx_http_mp4_module;
+#endif
+#if (NGX_HTTP_UPSTREAM_HASH)
+extern ngx_module_t  ngx_http_upstream_hash_module;
+#endif
+#if (NGX_HTTP_UPSTREAM_IP_HASH)
+extern ngx_module_t  ngx_http_upstream_ip_hash_module;
+#endif
+#if (NGX_HTTP_UPSTREAM_LEAST_CONN)
+extern ngx_module_t  ngx_http_upstream_least_conn_module;
+#endif
+#if (NGX_HTTP_UPSTREAM_KEEPALIVE)
+extern ngx_module_t  ngx_http_upstream_keepalive_module;
+#endif
+#if (NGX_HTTP_UPSTREAM_ZONE)
+extern ngx_module_t  ngx_http_upstream_zone_module;
+#endif
+#if (NGX_HTTP_STUB_STATUS)
+extern ngx_module_t  ngx_http_stub_status_module;
+#endif
+#if (NGX_HTTP)
+extern ngx_module_t  ngx_http_write_filter_module;
+extern ngx_module_t  ngx_http_header_filter_module;
+extern ngx_module_t  ngx_http_chunked_filter_module;
+#endif
+#if (NGX_HTTP_V2)
+extern ngx_module_t  ngx_http_v2_filter_module;
+#endif
+#if (NGX_HTTP)
+extern ngx_module_t  ngx_http_range_header_filter_module;
+#endif
+#if (NGX_HTTP_GZIP_FILTER)
+extern ngx_module_t  ngx_http_gzip_filter_module;
+#endif
+#if (NGX_HTTP_BROTLI_FILTER)
+extern ngx_module_t  ngx_http_brotli_filter_module;
+#endif
+#if (NGX_HTTP_POSTPONE)
+extern ngx_module_t  ngx_http_postpone_filter_module;
+#endif
+#if (NGX_HTTP_SSI)
+extern ngx_module_t  ngx_http_ssi_filter_module;
+#endif
+#if (NGX_HTTP_CHARSET)
+extern ngx_module_t  ngx_http_charset_filter_module;
+#endif
+#if 0
+extern ngx_module_t  ngx_http_xslt_filter_module;
+extern ngx_module_t  ngx_http_image_filter_module;
+#endif
+#if (NGX_HTTP_SUB)
+extern ngx_module_t  ngx_http_sub_filter_module;
+#endif
+#if (NGX_HTTP_ADDITION)
+extern ngx_module_t  ngx_http_addition_filter_module;
+#endif
+#if (NGX_HTTP_GUNZIP)
+extern ngx_module_t  ngx_http_gunzip_filter_module;
+#endif
+#if (NGX_HTTP_USERID)
+extern ngx_module_t  ngx_http_userid_filter_module;
+#endif
+#if (NGX_HTTP)
+extern ngx_module_t  ngx_http_headers_filter_module;
+extern ngx_module_t  ngx_http_copy_filter_module;
+extern ngx_module_t  ngx_http_range_body_filter_module;
+extern ngx_module_t  ngx_http_not_modified_filter_module;
+#endif
+#if (NGX_HTTP_SLICE)
+extern ngx_module_t  ngx_http_slice_filter_module;
+#endif
+
+#if (NGX_MAIL)
+extern ngx_module_t  ngx_mail_module;
+extern ngx_module_t  ngx_mail_core_module;
+#endif
+#if (NGX_MAIL_SSL)
+extern ngx_module_t  ngx_mail_ssl_module;
+#endif
+#if (NGX_MAIL_POP3)
+extern ngx_module_t  ngx_mail_pop3_module;
+#endif
+#if (NGX_MAIL_IMAP)
+extern ngx_module_t  ngx_mail_imap_module;
+#endif
+#if (NGX_MAIL_SMTP)
+extern ngx_module_t  ngx_mail_smtp_module;
+#endif
+#if (NGX_MAIL)
+extern ngx_module_t  ngx_mail_auth_http_module;
+extern ngx_module_t  ngx_mail_proxy_module;
+#endif
+
+#if (NGX_STREAM)
+extern ngx_module_t  ngx_stream_module;
+extern ngx_module_t  ngx_stream_core_module;
+extern ngx_module_t  ngx_stream_log_module;
+extern ngx_module_t  ngx_stream_proxy_module;
+extern ngx_module_t  ngx_stream_upstream_module;
+extern ngx_module_t  ngx_stream_write_filter_module;
+#endif
+#if (NGX_STREAM_SSL)
+extern ngx_module_t  ngx_stream_ssl_module;
+#endif
+#if (NGX_STREAM_REALIP)
+extern ngx_module_t  ngx_stream_realip_module;
+#endif
+#if (NGX_STREAM_LIMIT_CONN)
+extern ngx_module_t  ngx_stream_limit_conn_module;
+#endif
+#if (NGX_STREAM_ACCESS)
+extern ngx_module_t  ngx_stream_access_module;
+#endif
+#if (NGX_STREAM_GEO)
+extern ngx_module_t  ngx_stream_geo_module;
+#endif
+#if (NGX_STREAM_MAP)
+extern ngx_module_t  ngx_stream_map_module;
+#endif
+#if (NGX_STREAM_SPLIT_CLIENTS)
+extern ngx_module_t  ngx_stream_split_clients_module;
+#endif
+#if (NGX_STREAM_RETURN)
+extern ngx_module_t  ngx_stream_return_module;
+#endif
+#if (NGX_STREAM_UPSTREAM_HASH)
+extern ngx_module_t  ngx_stream_upstream_hash_module;
+#endif
+#if (NGX_STREAM_UPSTREAM_LEAST_CONN)
+extern ngx_module_t  ngx_stream_upstream_least_conn_module;
+#endif
+#if (NGX_STREAM_UPSTREAM_ZONE)
+extern ngx_module_t  ngx_stream_upstream_zone_module;
+#endif
+#if (NGX_STREAM_SSL_PREREAD)
+extern ngx_module_t  ngx_stream_ssl_preread_module;
+#endif
+
+#if 0
+extern ngx_module_t  ngx_google_perftools_module;
+#endif
+
+
+ngx_module_t *ngx_modules[] = {
+    &ngx_core_module,
+    &ngx_errlog_module,
+    &ngx_conf_module,
+#if (NGX_SSL)
+    &ngx_openssl_module,
+#endif
+#if (NGX_PCRE)
+    &ngx_regex_module,
+#endif
+    &ngx_events_module,
+    &ngx_event_core_module,
+#if (NGX_HAVE_EPOLL)
+    &ngx_epoll_module,
+#endif
+#if (NGX_HAVE_KQUEUE)
+    &ngx_kqueue_module,
+#endif
+#if (NGX_HAVE_SELECT)
+    &ngx_select_module,
+#endif
+#if (NGX_HAVE_POLL)
+    &ngx_poll_module,
+#endif
+#if (NGX_THREADS)
+    &ngx_thread_pool_module,
+#endif
+
+#if (NGX_HTTP)
+    &ngx_http_module,
+    &ngx_http_core_module,
+    &ngx_http_log_module,
+    &ngx_http_upstream_module,
+#endif
+#if (NGX_HTTP_V2)
+    &ngx_http_v2_module,
+#endif
+#if (NGX_HTTP)
+    &ngx_http_static_module,
+#endif
+#if (NGX_HTTP_GZIP_STATIC)
+    &ngx_http_gzip_static_module,
+#endif
+#if (NGX_HTTP_BROTLI_STATIC)
+    &ngx_http_brotli_static_module,
+#endif
+#if (NGX_HTTP_DAV)
+    &ngx_http_dav_module,
+#endif
+#if (NGX_HTTP_AUTOINDEX)
+    &ngx_http_autoindex_module,
+#endif
+#if (NGX_HTTP)
+    &ngx_http_index_module,
+#endif
+#if (NGX_HTTP_RANDOM_INDEX)
+    &ngx_http_random_index_module,
+#endif
+#if (NGX_HTTP_AUTH_REQUEST)
+    &ngx_http_auth_request_module,
+#endif
+#if (NGX_HTTP_AUTH_BASIC)
+    &ngx_http_auth_basic_module,
+#endif
+#if (NGX_HTTP_ACCESS)
+    &ngx_http_access_module,
+#endif
+#if (NGX_HTTP_LIMIT_CONN)
+    &ngx_http_limit_conn_module,
+#endif
+#if (NGX_HTTP_LIMIT_REQ)
+    &ngx_http_limit_req_module,
+#endif
+#if (NGX_HTTP_REALIP)
+    &ngx_http_realip_module,
+#endif
+#if (NGX_HTTP_GEO)
+    &ngx_http_geo_module,
+#endif
+#if 0
+    &ngx_http_geoip_module,
+#endif
+#if (NGX_HTTP_MAP)
+    &ngx_http_map_module,
+#endif
+#if (NGX_HTTP_SPLIT_CLIENTS)
+    &ngx_http_split_clients_module,
+#endif
+#if (NGX_HTTP_REFERER)
+    &ngx_http_referer_module,
+#endif
+#if (NGX_HTTP_REWRITE)
+    &ngx_http_rewrite_module,
+#endif
+#if (NGX_HTTP_SSL)
+    &ngx_http_ssl_module,
+#endif
+#if (NGX_HTTP_PROXY)
+    &ngx_http_proxy_module,
+#endif
+#if (NGX_HTTP_FASTCGI)
+    &ngx_http_fastcgi_module,
+#endif
+#if (NGX_HTTP_UWSGI)
+    &ngx_http_uwsgi_module,
+#endif
+#if (NGX_HTTP_SCGI)
+    &ngx_http_scgi_module,
+#endif
+#if 0
+    &ngx_http_perl_module,
+#endif
+#if (NGX_HTTP_MEMCACHED)
+    &ngx_http_memcached_module,
+#endif
+#if (NGX_HTTP_EMPTY_GIF)
+    &ngx_http_empty_gif_module,
+#endif
+#if (NGX_HTTP_BROWSER)
+    &ngx_http_browser_module,
+#endif
+#if (NGX_HTTP_SECURE_LINK)
+    &ngx_http_secure_link_module,
+#endif
+#if 0
+    &ngx_http_degradation_module,
+#endif
+#if (NGX_HTTP_FLV)
+    &ngx_http_flv_module,
+#endif
+#if (NGX_HTTP_MP4)
+    &ngx_http_mp4_module,
+#endif
+#if (NGX_HTTP_UPSTREAM_HASH)
+    &ngx_http_upstream_hash_module,
+#endif
+#if (NGX_HTTP_UPSTREAM_IP_HASH)
+    &ngx_http_upstream_ip_hash_module,
+#endif
+#if (NGX_HTTP_UPSTREAM_LEAST_CONN)
+    &ngx_http_upstream_least_conn_module,
+#endif
+#if (NGX_HTTP_UPSTREAM_KEEPALIVE)
+    &ngx_http_upstream_keepalive_module,
+#endif
+#if (NGX_HTTP_UPSTREAM_ZONE)
+    &ngx_http_upstream_zone_module,
+#endif
+#if (NGX_HTTP_STUB_STATUS)
+    &ngx_http_stub_status_module,
+#endif
+#if (NGX_HTTP)
+    &ngx_http_write_filter_module,
+    &ngx_http_header_filter_module,
+    &ngx_http_chunked_filter_module,
+#endif
+#if (NGX_HTTP_V2)
+    &ngx_http_v2_filter_module,
+#endif
+#if (NGX_HTTP)
+    &ngx_http_range_header_filter_module,
+#endif
+#if (NGX_HTTP_GZIP_FILTER)
+    &ngx_http_gzip_filter_module,
+#endif
+#if (NGX_HTTP_BROTLI_FILTER)
+    &ngx_http_brotli_filter_module,
+#endif
+#if (NGX_HTTP_POSTPONE)
+    &ngx_http_postpone_filter_module,
+#endif
+#if (NGX_HTTP_SSI)
+    &ngx_http_ssi_filter_module,
+#endif
+#if (NGX_HTTP_CHARSET)
+    &ngx_http_charset_filter_module,
+#endif
+#if 0
+    &ngx_http_xslt_filter_module,
+    &ngx_http_image_filter_module,
+#endif
+#if (NGX_HTTP_SUB)
+    &ngx_http_sub_filter_module,
+#endif
+#if (NGX_HTTP_ADDITION)
+    &ngx_http_addition_filter_module,
+#endif
+#if (NGX_HTTP_GUNZIP)
+    &ngx_http_gunzip_filter_module,
+#endif
+#if (NGX_HTTP_USERID)
+    &ngx_http_userid_filter_module,
+#endif
+#if (NGX_HTTP)
+    &ngx_http_headers_filter_module,
+    &ngx_http_copy_filter_module,
+    &ngx_http_range_body_filter_module,
+    &ngx_http_not_modified_filter_module,
+#endif
+#if (NGX_HTTP_SLICE)
+    &ngx_http_slice_filter_module,
+#endif
+
+#if (NGX_MAIL)
+    &ngx_mail_module,
+    &ngx_mail_core_module,
+#endif
+#if (NGX_MAIL_SSL)
+    &ngx_mail_ssl_module,
+#endif
+#if (NGX_MAIL_POP3)
+    &ngx_mail_pop3_module,
+#endif
+#if (NGX_MAIL_IMAP)
+    &ngx_mail_imap_module,
+#endif
+#if (NGX_MAIL_SMTP)
+    &ngx_mail_smtp_module,
+#endif
+#if (NGX_MAIL)
+    &ngx_mail_auth_http_module,
+    &ngx_mail_proxy_module,
+#endif
+
+#if (NGX_STREAM)
+    &ngx_stream_module,
+    &ngx_stream_core_module,
+    &ngx_stream_log_module,
+    &ngx_stream_proxy_module,
+    &ngx_stream_upstream_module,
+    &ngx_stream_write_filter_module,
+#endif
+#if (NGX_STREAM_SSL)
+    &ngx_stream_ssl_module,
+#endif
+#if (NGX_STREAM_REALIP)
+    &ngx_stream_realip_module,
+#endif
+#if (NGX_STREAM_LIMIT_CONN)
+    &ngx_stream_limit_conn_module,
+#endif
+#if (NGX_STREAM_ACCESS)
+    &ngx_stream_access_module,
+#endif
+#if (NGX_STREAM_GEO)
+    &ngx_stream_geo_module,
+#endif
+#if (NGX_STREAM_MAP)
+    &ngx_stream_map_module,
+#endif
+#if (NGX_STREAM_SPLIT_CLIENTS)
+    &ngx_stream_split_clients_module,
+#endif
+#if (NGX_STREAM_RETURN)
+    &ngx_stream_return_module,
+#endif
+#if (NGX_STREAM_UPSTREAM_HASH)
+    &ngx_stream_upstream_hash_module,
+#endif
+#if (NGX_STREAM_UPSTREAM_LEAST_CONN)
+    &ngx_stream_upstream_least_conn_module,
+#endif
+#if (NGX_STREAM_UPSTREAM_ZONE)
+    &ngx_stream_upstream_zone_module,
+#endif
+#if (NGX_STREAM_SSL_PREREAD)
+    &ngx_stream_ssl_preread_module,
+#endif
+
+#if 0
+    &ngx_google_perftools_module,
+#endif
+    NULL
+};
+
+
+char *ngx_module_names[] = {
+    "ngx_core_module",
+    "ngx_errlog_module",
+    "ngx_conf_module",
+#if (NGX_SSL)
+    "ngx_openssl_module",
+#endif
+#if (NGX_PCRE)
+    "ngx_regex_module",
+#endif
+    "ngx_events_module",
+    "ngx_event_core_module",
+#if (NGX_HAVE_EPOLL)
+    "ngx_epoll_module",
+#endif
+#if (NGX_HAVE_KQUEUE)
+    "ngx_kqueue_module",
+#endif
+#if (NGX_HAVE_SELECT)
+    "ngx_select_module",
+#endif
+#if (NGX_HAVE_POLL)
+    "ngx_poll_module",
+#endif
+#if (NGX_THREADS)
+    "ngx_thread_pool_module",
+#endif
+
+#if (NGX_HTTP)
+    "ngx_http_module",
+    "ngx_http_core_module",
+    "ngx_http_log_module",
+    "ngx_http_upstream_module",
+#endif
+#if (NGX_HTTP_V2)
+    "ngx_http_v2_module",
+#endif
+#if (NGX_HTTP)
+    "ngx_http_static_module",
+#endif
+#if (NGX_HTTP_GZIP_STATIC)
+    "ngx_http_gzip_static_module",
+#endif
+#if (NGX_HTTP_BROTLI_STATIC)
+    "ngx_http_brotli_static_module",
+#endif
+#if (NGX_HTTP_DAV)
+    "ngx_http_dav_module",
+#endif
+#if (NGX_HTTP_AUTOINDEX)
+    "ngx_http_autoindex_module",
+#endif
+#if (NGX_HTTP)
+    "ngx_http_index_module",
+#endif
+#if (NGX_HTTP_RANDOM_INDEX)
+    "ngx_http_random_index_module",
+#endif
+#if (NGX_HTTP_AUTH_REQUEST)
+    "ngx_http_auth_request_module",
+#endif
+#if (NGX_HTTP_AUTH_BASIC)
+    "ngx_http_auth_basic_module",
+#endif
+#if (NGX_HTTP_ACCESS)
+    "ngx_http_access_module",
+#endif
+#if (NGX_HTTP_LIMIT_CONN)
+    "ngx_http_limit_conn_module",
+#endif
+#if (NGX_HTTP_LIMIT_REQ)
+    "ngx_http_limit_req_module",
+#endif
+#if (NGX_HTTP_REALIP)
+    "ngx_http_realip_module",
+#endif
+#if (NGX_HTTP_GEO)
+    "ngx_http_geo_module",
+#endif
+#if 0
+    "ngx_http_geoip_module",
+#endif
+#if (NGX_HTTP_MAP)
+    "ngx_http_map_module",
+#endif
+#if (NGX_HTTP_SPLIT_CLIENTS)
+    "ngx_http_split_clients_module",
+#endif
+#if (NGX_HTTP_REFERER)
+    "ngx_http_referer_module",
+#endif
+#if (NGX_HTTP_REWRITE)
+    "ngx_http_rewrite_module",
+#endif
+#if (NGX_HTTP_SSL)
+    "ngx_http_ssl_module",
+#endif
+#if (NGX_HTTP_PROXY)
+    "ngx_http_proxy_module",
+#endif
+#if (NGX_HTTP_FASTCGI)
+    "ngx_http_fastcgi_module",
+#endif
+#if (NGX_HTTP_UWSGI)
+    "ngx_http_uwsgi_module",
+#endif
+#if (NGX_HTTP_SCGI)
+    "ngx_http_scgi_module",
+#endif
+#if 0
+    "ngx_http_perl_module",
+#endif
+#if (NGX_HTTP_MEMCACHED)
+    "ngx_http_memcached_module",
+#endif
+#if (NGX_HTTP_EMPTY_GIF)
+    "ngx_http_empty_gif_module",
+#endif
+#if (NGX_HTTP_BROWSER)
+    "ngx_http_browser_module",
+#endif
+#if (NGX_HTTP_SECURE_LINK)
+    "ngx_http_secure_link_module",
+#endif
+#if 0
+    "ngx_http_degradation_module",
+#endif
+#if (NGX_HTTP_FLV)
+    "ngx_http_flv_module",
+#endif
+#if (NGX_HTTP_MP4)
+    "ngx_http_mp4_module",
+#endif
+#if (NGX_HTTP_UPSTREAM_HASH)
+    "ngx_http_upstream_hash_module",
+#endif
+#if (NGX_HTTP_UPSTREAM_IP_HASH)
+    "ngx_http_upstream_ip_hash_module",
+#endif
+#if (NGX_HTTP_UPSTREAM_LEAST_CONN)
+    "ngx_http_upstream_least_conn_module",
+#endif
+#if (NGX_HTTP_UPSTREAM_KEEPALIVE)
+    "ngx_http_upstream_keepalive_module",
+#endif
+#if (NGX_HTTP_UPSTREAM_ZONE)
+    "ngx_http_upstream_zone_module",
+#endif
+#if (NGX_HTTP_STUB_STATUS)
+    "ngx_http_stub_status_module",
+#endif
+#if (NGX_HTTP)
+    "ngx_http_write_filter_module",
+    "ngx_http_header_filter_module",
+    "ngx_http_chunked_filter_module",
+#endif
+#if (NGX_HTTP_V2)
+    "ngx_http_v2_filter_module",
+#endif
+#if (NGX_HTTP)
+    "ngx_http_range_header_filter_module",
+#endif
+#if (NGX_HTTP_GZIP_FILTER)
+    "ngx_http_gzip_filter_module",
+#endif
+#if (NGX_HTTP_BROTLI_FILTER)
+    "ngx_http_brotli_filter_module",
+#endif
+#if (NGX_HTTP_POSTPONE)
+    "ngx_http_postpone_filter_module",
+#endif
+#if (NGX_HTTP_SSI)
+    "ngx_http_ssi_filter_module",
+#endif
+#if (NGX_HTTP_CHARSET)
+    "ngx_http_charset_filter_module",
+#endif
+#if 0
+    "ngx_http_xslt_filter_module",
+    "ngx_http_image_filter_module",
+#endif
+#if (NGX_HTTP_SUB)
+    "ngx_http_sub_filter_module",
+#endif
+#if (NGX_HTTP_ADDITION)
+    "ngx_http_addition_filter_module",
+#endif
+#if (NGX_HTTP_GUNZIP)
+    "ngx_http_gunzip_filter_module",
+#endif
+#if (NGX_HTTP_USERID)
+    "ngx_http_userid_filter_module",
+#endif
+#if (NGX_HTTP)
+    "ngx_http_headers_filter_module",
+    "ngx_http_copy_filter_module",
+    "ngx_http_range_body_filter_module",
+    "ngx_http_not_modified_filter_module",
+#endif
+#if (NGX_HTTP_SLICE)
+    "ngx_http_slice_filter_module",
+#endif
+
+#if (NGX_MAIL)
+    "ngx_mail_module",
+    "ngx_mail_core_module",
+#endif
+#if (NGX_MAIL_SSL)
+    "ngx_mail_ssl_module",
+#endif
+#if (NGX_MAIL_POP3)
+    "ngx_mail_pop3_module",
+#endif
+#if (NGX_MAIL_IMAP)
+    "ngx_mail_imap_module",
+#endif
+#if (NGX_MAIL_SMTP)
+    "ngx_mail_smtp_module",
+#endif
+#if (NGX_MAIL)
+    "ngx_mail_auth_http_module",
+    "ngx_mail_proxy_module",
+#endif
+
+#if (NGX_STREAM)
+    "ngx_stream_module",
+    "ngx_stream_core_module",
+    "ngx_stream_log_module",
+    "ngx_stream_proxy_module",
+    "ngx_stream_upstream_module",
+    "ngx_stream_write_filter_module",
+#endif
+#if (NGX_STREAM_SSL)
+    "ngx_stream_ssl_module",
+#endif
+#if (NGX_STREAM_REALIP)
+    "ngx_stream_realip_module",
+#endif
+#if (NGX_STREAM_LIMIT_CONN)
+    "ngx_stream_limit_conn_module",
+#endif
+#if (NGX_STREAM_ACCESS)
+    "ngx_stream_access_module",
+#endif
+#if (NGX_STREAM_GEO)
+    "ngx_stream_geo_module",
+#endif
+#if (NGX_STREAM_MAP)
+    "ngx_stream_map_module",
+#endif
+#if (NGX_STREAM_SPLIT_CLIENTS)
+    "ngx_stream_split_clients_module",
+#endif
+#if (NGX_STREAM_RETURN)
+    "ngx_stream_return_module",
+#endif
+#if (NGX_STREAM_UPSTREAM_HASH)
+    "ngx_stream_upstream_hash_module",
+#endif
+#if (NGX_STREAM_UPSTREAM_LEAST_CONN)
+    "ngx_stream_upstream_least_conn_module",
+#endif
+#if (NGX_STREAM_UPSTREAM_ZONE)
+    "ngx_stream_upstream_zone_module",
+#endif
+#if (NGX_STREAM_SSL_PREREAD)
+    "ngx_stream_ssl_preread_module",
+#endif
+
+#if 0
+    "ngx_google_perftools_module",
+#endif
+    NULL
+};
+
+
+void
+ngx_show_configure_options(void)
+{
+    ngx_write_stderr("configure arguments:");
+
+#ifdef NGX_PREFIX
+    ngx_write_stderr(" --prefix=");
+    (void) ngx_write_fd(ngx_stderr, NGX_PREFIX, ngx_strlen(NGX_PREFIX) - 1);
+#endif
+#ifdef NGX_CONF_PATH
+    ngx_write_stderr(" --conf-path=" NGX_CONF_PATH);
+#endif
+#ifdef NGX_ERROR_LOG_PATH
+    ngx_write_stderr(" --error-log-path=" NGX_ERROR_LOG_PATH);
+#endif
+#ifdef NGX_PID_PATH
+    ngx_write_stderr(" --pid-path=" NGX_PID_PATH);
+#endif
+#ifdef NGX_LOCK_PATH
+    ngx_write_stderr(" --lock-path=" NGX_LOCK_PATH);
+#endif
+#ifdef NGX_USER
+    ngx_write_stderr(" --user=" NGX_USER);
+#endif
+#ifdef NGX_GROUP
+    ngx_write_stderr(" --group=" NGX_GROUP);
+#endif
+
+#if (NGX_HTTP)
+#ifdef NGX_HTTP_LOG_PATH
+    ngx_write_stderr(" --http-log-path=" NGX_HTTP_LOG_PATH);
+#endif
+#ifdef NGX_HTTP_CLIENT_TEMP_PATH
+    ngx_write_stderr(" --http-client-body-temp-path="
+                     NGX_HTTP_CLIENT_TEMP_PATH);
+#endif
+#ifdef NGX_HTTP_FASTCGI_TEMP_PATH
+    ngx_write_stderr(" --http-fastcgi-temp-path=" NGX_HTTP_FASTCGI_TEMP_PATH);
+#endif
+#ifdef NGX_HTTP_PROXY_TEMP_PATH
+    ngx_write_stderr(" --http-proxy-temp-path=" NGX_HTTP_PROXY_TEMP_PATH);
+#endif
+#ifdef NGX_HTTP_SCGI_TEMP_PATH
+    ngx_write_stderr(" --http-scgi-temp-path=" NGX_HTTP_SCGI_TEMP_PATH);
+#endif
+#ifdef NGX_HTTP_UWSGI_TEMP_PATH
+    ngx_write_stderr(" --http-uwsgi-temp-path=" NGX_HTTP_UWSGI_TEMP_PATH);
+#endif
+#endif
+
+#if (NGX_COMPAT)
+    ngx_write_stderr(" --with-compat");
+#endif
+#if (NGX_DEBUG)
+    ngx_write_stderr(" --with-debug");
+#endif
+#if (NGX_HAVE_FILE_AIO)
+    ngx_write_stderr(" --with-file-aio");
+#endif
+#if (NGX_THREADS)
+    ngx_write_stderr(" --with-threads");
+#endif
+
+#if (NGX_HAVE_POLL)
+    ngx_write_stderr(" --with-poll_module");
+#endif
+#if (NGX_HAVE_SELECT)
+    ngx_write_stderr(" --with-select_module");
+#endif
+
+#if (NGX_HTTP)
+#if (NGX_HTTP_ADDITION)
+    ngx_write_stderr(" --with-http_addition_module");
+#endif
+#if (NGX_HTTP_AUTH_REQUEST)
+    ngx_write_stderr(" --with-http_auth_request_module");
+#endif
+#if (NGX_HTTP_DAV)
+    ngx_write_stderr(" --with-http_dav_module");
+#endif
+#if 0
+    ngx_write_stderr(" --with-http_degradation_module");
+#endif
+#if (NGX_HTTP_FLV)
+    ngx_write_stderr(" --with-http_flv_module");
+#endif
+#if 0
+    ngx_write_stderr(" --with-http_geoip_module");
+#endif
+#if (NGX_HTTP_GUNZIP)
+    ngx_write_stderr(" --with-http_gunzip_module");
+#endif
+#if (NGX_HTTP_GZIP_STATIC)
+    ngx_write_stderr(" --with-http_gzip_static_module");
+#endif
+#if 0
+    ngx_write_stderr(" --with-http_image_filter_module");
+#endif
+#if (NGX_HTTP_MP4)
+    ngx_write_stderr(" --with-http_mp4_module");
+#endif
+#if 0
+    ngx_write_stderr(" --with-http_perl_module");
+#endif
+#if (NGX_HTTP_RANDOM_INDEX)
+    ngx_write_stderr(" --with-http_random_index_module");
+#endif
+#if (NGX_HTTP_REALIP)
+    ngx_write_stderr(" --with-http_realip_module");
+#endif
+#if (NGX_HTTP_SECURE_LINK)
+    ngx_write_stderr(" --with-http_secure_link_module");
+#endif
+#if (NGX_HTTP_SLICE)
+    ngx_write_stderr(" --with-http_slice_module");
+#endif
+#if (NGX_HTTP_SSL)
+    ngx_write_stderr(" --with-http_ssl_module");
+#endif
+#if (NGX_HTTP_STUB_STATUS)
+    ngx_write_stderr(" --with-http_stub_status_module");
+#endif
+#if (NGX_HTTP_SUB)
+    ngx_write_stderr(" --with-http_sub_module");
+#endif
+#if (NGX_HTTP_V2)
+    ngx_write_stderr(" --with-http_v2_module");
+#endif
+#if 0
+    ngx_write_stderr(" --with-http_xslt_module");
+#endif
+#if !(NGX_HTTP_ACCESS)
+    ngx_write_stderr(" --without-http_access_module");
+#endif
+#if !(NGX_HTTP_AUTH_BASIC)
+    ngx_write_stderr(" --without-http_auth_basic_module");
+#endif
+#if !(NGX_HTTP_AUTOINDEX)
+    ngx_write_stderr(" --without-http_autoindex_module");
+#endif
+#if !(NGX_HTTP_BROWSER)
+    ngx_write_stderr(" --without-http_browser_module");
+#endif
+#if !(NGX_HTTP_CACHE)
+    ngx_write_stderr(" --without-http-cache");
+#endif
+#if !(NGX_HTTP_CHARSET)
+    ngx_write_stderr(" --without-http_charset_module");
+#endif
+#if !(NGX_HTTP_EMPTY_GIF)
+    ngx_write_stderr(" --without-http_empty_gif_module");
+#endif
+#if !(NGX_HTTP_FASTCGI)
+    ngx_write_stderr(" --without-http_fastcgi_module");
+#endif
+#if !(NGX_HTTP_GEO)
+    ngx_write_stderr(" --without-http_geo_module");
+#endif
+#if !(NGX_HTTP_GZIP_FILTER)
+    ngx_write_stderr(" --without-http_gzip_module");
+#endif
+#if !(NGX_HTTP_LIMIT_CONN)
+    ngx_write_stderr(" --without-http_limit_conn_module");
+#endif
+#if !(NGX_HTTP_LIMIT_REQ)
+    ngx_write_stderr(" --without-http_limit_req_module");
+#endif
+#if !(NGX_HTTP_MAP)
+    ngx_write_stderr(" --without-http_map_module");
+#endif
+#if !(NGX_HTTP_MEMCACHED)
+    ngx_write_stderr(" --without-http_memcached_module");
+#endif
+#if !(NGX_HTTP_PROXY)
+    ngx_write_stderr(" --without-http_proxy_module");
+#endif
+#if !(NGX_HTTP_REFERER)
+    ngx_write_stderr(" --without-http_referer_module");
+#endif
+#if !(NGX_HTTP_REWRITE)
+    ngx_write_stderr(" --without-http_rewrite_module");
+#endif
+#if !(NGX_HTTP_SCGI)
+    ngx_write_stderr(" --without-http_scgi_module");
+#endif
+#if !(NGX_HTTP_SPLIT_CLIENTS)
+    ngx_write_stderr(" --without-http_split_clients_module");
+#endif
+#if !(NGX_HTTP_SSI)
+    ngx_write_stderr(" --without-http_ssi_module");
+#endif
+#if !(NGX_HTTP_UPSTREAM_HASH)
+    ngx_write_stderr(" --without-http_upstream_hash_module");
+#endif
+#if !(NGX_HTTP_UPSTREAM_IP_HASH)
+    ngx_write_stderr(" --without-http_upstream_ip_hash_module");
+#endif
+#if !(NGX_HTTP_UPSTREAM_KEEPALIVE)
+    ngx_write_stderr(" --without-http_upstream_keepalive_module");
+#endif
+#if !(NGX_HTTP_UPSTREAM_LEAST_CONN)
+    ngx_write_stderr(" --without-http_upstream_least_conn_module");
+#endif
+#if !(NGX_HTTP_UPSTREAM_ZONE)
+    ngx_write_stderr(" --without-http_upstream_zone_module");
+#endif
+#if !(NGX_HTTP_USERID)
+    ngx_write_stderr(" --without-http_userid_module");
+#endif
+#if !(NGX_HTTP_UWSGI)
+    ngx_write_stderr(" --without-http_uwsgi_module");
+#endif
+#else
+    ngx_write_stderr(" --without-http");
+#endif
+
+#if (NGX_MAIL)
+    ngx_write_stderr(" --with-mail");
+#if (NGX_MAIL_SSL)
+    ngx_write_stderr(" --with-mail_ssl_module");
+#endif
+#if !(NGX_MAIL_IMAP)
+    ngx_write_stderr(" --without-mail_imap_module");
+#endif
+#if !(NGX_MAIL_POP3)
+    ngx_write_stderr(" --without-mail_pop3_module");
+#endif
+#if !(NGX_MAIL_SMTP)
+    ngx_write_stderr(" --without-mail_smtp_module");
+#endif
+#endif
+
+#if (NGX_STREAM)
+    ngx_write_stderr(" --with-stream");
+#if (NGX_STREAM_REALIP)
+    ngx_write_stderr(" --with-stream_realip_module");
+#endif
+#if (NGX_STREAM_SSL)
+    ngx_write_stderr(" --with-stream_ssl_module");
+#endif
+#if (NGX_STREAM_SSL_PREREAD)
+    ngx_write_stderr(" --with-stream_ssl_preread_module");
+#endif
+#if !(NGX_STREAM_ACCESS)
+    ngx_write_stderr(" --without-stream_access_module");
+#endif
+#if !(NGX_STREAM_GEO)
+    ngx_write_stderr(" --without-stream_geo_module");
+#endif
+#if !(NGX_STREAM_LIMIT_CONN)
+    ngx_write_stderr(" --without-stream_limit_conn_module");
+#endif
+#if !(NGX_STREAM_MAP)
+    ngx_write_stderr(" --without-stream_map_module");
+#endif
+#if !(NGX_STREAM_RETURN)
+    ngx_write_stderr(" --without-stream_return_module");
+#endif
+#if !(NGX_STREAM_SPLIT_CLIENTS)
+    ngx_write_stderr(" --without-stream_split_clients_module");
+#endif
+#if !(NGX_STREAM_UPSTREAM_HASH)
+    ngx_write_stderr(" --without-stream_upstream_hash_module");
+#endif
+#if !(NGX_STREAM_UPSTREAM_LEAST_CONN)
+    ngx_write_stderr(" --without-stream_upstream_least_conn_module");
+#endif
+#if !(NGX_STREAM_UPSTREAM_ZONE)
+    ngx_write_stderr(" --without-stream_upstream_zone_module");
+#endif
+#endif
+
+#if 0
+    ngx_write_stderr(" --with-google_perftools_module");
+#endif
+
+#if (NGX_SSL)
+    ngx_write_stderr(" --with-openssl=//external:boringssl");
+#endif
+#if (NGX_PCRE)
+    ngx_write_stderr(" --with-pcre=//external:pcre");
+    ngx_write_stderr(" --with-pcre-jit");
+#endif
+#if (NGX_ZLIB)
+    ngx_write_stderr(" --with-zlib=//external:zlib");
+#endif
+
+#if (NGX_HTTP_BROTLI_FILTER)
+    ngx_write_stderr(" --add-module=//ngx_brotli:http_brotli_filter");
+#endif
+#if (NGX_HTTP_BROTLI_STATIC)
+    ngx_write_stderr(" --add-module=//ngx_brotli:http_brotli_static");
+#endif
+
+    ngx_write_stderr(NGX_LINEFEED);
+}
+
+
+#if !(NGX_NO_MAIN)
+
+int ngx_cdecl
+main(int argc, char *const *argv)
+{
+    return ngx_main(argc, argv);
+}
+
+#endif
diff --git a/src/ngx_modules.h b/src/ngx_modules.h
new file mode 100644
index 0000000..048b45b
--- /dev/null
+++ b/src/ngx_modules.h
@@ -0,0 +1,14 @@
+
+/*
+ * Copyright (C) Google Inc.
+ */
+
+
+#ifndef _NGX_MODULES_H_INCLUDED_
+#define _NGX_MODULES_H_INCLUDED_
+
+
+void ngx_show_configure_options(void);
+
+
+#endif /* _NGX_MODULES_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_atomic.h b/src/os/unix/ngx_atomic.h
index 74b8b7f..8a86a30 100644
--- a/src/os/unix/ngx_atomic.h
+++ b/src/os/unix/ngx_atomic.h
@@ -304,10 +304,25 @@
 #endif
 
 
+#if (NGX_HAVE_GCC_ATOMIC_STORE_AND_LOAD)
+
+#define ngx_atomic_store(x, value)  __atomic_store_n(x, value, __ATOMIC_RELEASE)
+#define ngx_atomic_load(x)          __atomic_load_n(x, __ATOMIC_ACQUIRE)
+
+#else
+
+#define ngx_atomic_store(x, value)  *(x) = value
+#define ngx_atomic_load(x)          *(x)
+
+#endif
+
+
 void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);
 
-#define ngx_trylock(lock)  (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
-#define ngx_unlock(lock)    *(lock) = 0
+#define ngx_trylock(lock, value)                                              \
+    (ngx_atomic_load(lock) == 0 && ngx_atomic_cmp_set(lock, 0, value))
+
+#define ngx_unlock(lock)    ngx_atomic_store(lock, 0)
 
 
 #endif /* _NGX_ATOMIC_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c
index 583ea4f..4bd14a6 100644
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -34,6 +34,7 @@
 ngx_int_t
 ngx_os_init(ngx_log_t *log)
 {
+    long         value;
     ngx_time_t  *tp;
     ngx_uint_t   n;
 
@@ -47,7 +48,14 @@
         return NGX_ERROR;
     }
 
-    ngx_pagesize = getpagesize();
+    value = sysconf(_SC_PAGESIZE);
+    if (value == -1) {
+        ngx_log_error(NGX_LOG_ALERT, log, errno,
+                      "sysconf(_SC_PAGESIZE) failed");
+        return NGX_ERROR;
+    }
+
+    ngx_pagesize = (ngx_uint_t) value;
     ngx_cacheline_size = NGX_CPU_CACHE_LINE;
 
     for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }
diff --git a/src/os/win32/ngx_atomic.h b/src/os/win32/ngx_atomic.h
index 113f561..c051a0b 100644
--- a/src/os/win32/ngx_atomic.h
+++ b/src/os/win32/ngx_atomic.h
@@ -60,10 +60,16 @@
 #endif
 
 
+#define ngx_atomic_store(x, value)  *(x) = value
+#define ngx_atomic_load(x)          *(x)
+
+
 void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);
 
-#define ngx_trylock(lock)  (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
-#define ngx_unlock(lock)    *(lock) = 0
+#define ngx_trylock(lock, value)                                              \
+    (ngx_atomic_load(lock) == 0 && ngx_atomic_cmp_set(lock, 0, value))
+
+#define ngx_unlock(lock)    ngx_atomic_store(lock, 0)
 
 
 #endif /* _NGX_ATOMIC_H_INCLUDED_ */
diff --git a/src/stream/ngx_stream_upstream.h b/src/stream/ngx_stream_upstream.h
index 90076e0..283ffd8 100644
--- a/src/stream/ngx_stream_upstream.h
+++ b/src/stream/ngx_stream_upstream.h
@@ -81,7 +81,7 @@
     in_port_t                          port;
     ngx_uint_t                         no_port;  /* unsigned no_port:1 */
 
-#if (NGX_STREAM_UPSTREAM_ZONE)
+#if (NGX_STREAM_UPSTREAM_ZONE || NGX_COMPAT)
     ngx_shm_zone_t                    *shm_zone;
 #endif
 };
diff --git a/src/stream/ngx_stream_upstream_round_robin.c b/src/stream/ngx_stream_upstream_round_robin.c
index 526de3a..e4a6e76 100644
--- a/src/stream/ngx_stream_upstream_round_robin.c
+++ b/src/stream/ngx_stream_upstream_round_robin.c
@@ -699,7 +699,7 @@
     ngx_int_t                        rc;
     ngx_ssl_session_t               *ssl_session;
     ngx_stream_upstream_rr_peer_t   *peer;
-#if (NGX_STREAM_UPSTREAM_ZONE)
+#if (NGX_STREAM_UPSTREAM_ZONE || NGX_COMPAT)
     int                              len;
 #if OPENSSL_VERSION_NUMBER >= 0x0090707fL
     const
@@ -711,7 +711,7 @@
 
     peer = rrp->current;
 
-#if (NGX_STREAM_UPSTREAM_ZONE)
+#if (NGX_STREAM_UPSTREAM_ZONE || NGX_COMPAT)
     peers = rrp->peers;
 
     if (peers->shpool) {
@@ -764,14 +764,14 @@
 
     ngx_ssl_session_t               *old_ssl_session, *ssl_session;
     ngx_stream_upstream_rr_peer_t   *peer;
-#if (NGX_STREAM_UPSTREAM_ZONE)
+#if (NGX_STREAM_UPSTREAM_ZONE || NGX_COMPAT)
     int                              len;
     u_char                          *p;
     ngx_stream_upstream_rr_peers_t  *peers;
     u_char                           buf[NGX_SSL_MAX_SESSION_SIZE];
 #endif
 
-#if (NGX_STREAM_UPSTREAM_ZONE)
+#if (NGX_STREAM_UPSTREAM_ZONE || NGX_COMPAT)
     peers = rrp->peers;
 
     if (peers->shpool) {
diff --git a/src/stream/ngx_stream_upstream_round_robin.h b/src/stream/ngx_stream_upstream_round_robin.h
index 35d9fce..01bfe53 100644
--- a/src/stream/ngx_stream_upstream_round_robin.h
+++ b/src/stream/ngx_stream_upstream_round_robin.h
@@ -43,7 +43,7 @@
     void                            *ssl_session;
     int                              ssl_session_len;
 
-#if (NGX_STREAM_UPSTREAM_ZONE)
+#if (NGX_STREAM_UPSTREAM_ZONE || NGX_COMPAT)
     ngx_atomic_t                     lock;
 #endif
 
@@ -59,7 +59,7 @@
 struct ngx_stream_upstream_rr_peers_s {
     ngx_uint_t                       number;
 
-#if (NGX_STREAM_UPSTREAM_ZONE)
+#if (NGX_STREAM_UPSTREAM_ZONE || NGX_COMPAT)
     ngx_slab_pool_t                 *shpool;
     ngx_atomic_t                     rwlock;
     ngx_stream_upstream_rr_peers_t  *zone_next;
@@ -78,7 +78,7 @@
 };
 
 
-#if (NGX_STREAM_UPSTREAM_ZONE)
+#if (NGX_STREAM_UPSTREAM_ZONE || NGX_COMPAT)
 
 #define ngx_stream_upstream_rr_peers_rlock(peers)                             \
                                                                               \