view auto/modules @ 6891:749bcfdf097a stable-1.10

HTTP/2: fixed posted streams handling. A bug was introduced by 82efcedb310b that could lead to timing out of responses or segmentation fault, when accept_mutex was enabled. The output queue in HTTP/2 can contain frames from different streams. When the queue is sent, all related write handlers need to be called. In order to do so, the streams were added to the h2c->posted queue after handling sent frames. Then this queue was processed in ngx_http_v2_write_handler(). If accept_mutex is enabled, the event's "ready" flag is set but its handler is not called immediately. Instead, the event is added to the ngx_posted_events queue. At the same time in this queue can be events from upstream connections. Such events can result in sending output queue before ngx_http_v2_write_handler() is triggered. And at the time ngx_http_v2_write_handler() is called, the output queue can be already empty with some streams added to h2c->posted. But after 82efcedb310b, these streams weren't processed if all frames have already been sent and the output queue was empty. This might lead to a situation when a number of streams were get stuck in h2c->posted queue for a long time. Eventually these streams might get closed by the send timeout. In the worst case this might also lead to a segmentation fault, if already freed stream was left in the h2c->posted queue. This could happen if one of the streams was terminated but wasn't closed, due to the HEADERS frame or a partially sent DATA frame left in the output queue. If this happened the ngx_http_v2_filter_cleanup() handler removed the stream from the h2c->waiting or h2c->posted queue on termination stage, before the frame has been sent, and the stream was again added to the h2c->posted queue after the frame was sent. In order to fix all these problems and simplify the code, write events of fake stream connections are now added to ngx_posted_events instead of using a custom h2c->posted queue.
author Valentin Bartenev <vbart@nginx.com>
date Mon, 28 Nov 2016 20:58:14 +0300
parents 39a806ccf21e
children 9eefb38f0005
line wrap: on
line source


# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.


if [ $EVENT_SELECT = NO -a $EVENT_FOUND = NO ]; then
    EVENT_SELECT=YES
fi

if [ $EVENT_SELECT = YES ]; then
    have=NGX_HAVE_SELECT . auto/have
    CORE_SRCS="$CORE_SRCS $SELECT_SRCS"
    EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE"
fi


if [ $EVENT_POLL = NO -a $EVENT_FOUND = NO ]; then
    EVENT_POLL=YES
fi

if [ $EVENT_POLL = YES ]; then
    have=NGX_HAVE_POLL . auto/have
    CORE_SRCS="$CORE_SRCS $POLL_SRCS"
    EVENT_MODULES="$EVENT_MODULES $POLL_MODULE"
fi


if [ $NGX_TEST_BUILD_DEVPOLL = YES ]; then
    have=NGX_HAVE_DEVPOLL . auto/have
    have=NGX_TEST_BUILD_DEVPOLL . auto/have
    EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE"
    CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS"
fi


if [ $NGX_TEST_BUILD_EVENTPORT = YES ]; then
    have=NGX_HAVE_EVENTPORT . auto/have
    have=NGX_TEST_BUILD_EVENTPORT . auto/have
    EVENT_MODULES="$EVENT_MODULES $EVENTPORT_MODULE"
    CORE_SRCS="$CORE_SRCS $EVENTPORT_SRCS"
fi

if [ $NGX_TEST_BUILD_EPOLL = YES ]; then
    have=NGX_HAVE_EPOLL . auto/have
    have=NGX_HAVE_EPOLLRDHUP . auto/have
    have=NGX_HAVE_EVENTFD . auto/have
    have=NGX_TEST_BUILD_EPOLL . auto/have
    EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
    CORE_SRCS="$CORE_SRCS $EPOLL_SRCS"
fi

if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = YES ]; then
    have=NGX_TEST_BUILD_SOLARIS_SENDFILEV . auto/have
    CORE_SRCS="$CORE_SRCS $SOLARIS_SENDFILEV_SRCS"
fi


HTTP_MODULES=
HTTP_DEPS=
HTTP_INCS=

ngx_module_type=HTTP

if :; then
    ngx_module_name="ngx_http_module \
                     ngx_http_core_module \
                     ngx_http_log_module \
                     ngx_http_upstream_module"
    ngx_module_incs="src/http src/http/modules"
    ngx_module_deps="src/http/ngx_http.h \
                     src/http/ngx_http_request.h \
                     src/http/ngx_http_config.h \
                     src/http/ngx_http_core_module.h \
                     src/http/ngx_http_cache.h \
                     src/http/ngx_http_variables.h \
                     src/http/ngx_http_script.h \
                     src/http/ngx_http_upstream.h \
                     src/http/ngx_http_upstream_round_robin.h"
    ngx_module_srcs="src/http/ngx_http.c \
                     src/http/ngx_http_core_module.c \
                     src/http/ngx_http_special_response.c \
                     src/http/ngx_http_request.c \
                     src/http/ngx_http_parse.c \
                     src/http/modules/ngx_http_log_module.c \
                     src/http/ngx_http_request_body.c \
                     src/http/ngx_http_variables.c \
                     src/http/ngx_http_script.c \
                     src/http/ngx_http_upstream.c \
                     src/http/ngx_http_upstream_round_robin.c"
    ngx_module_libs=
    ngx_module_link=YES

    . auto/module
fi


if [ $HTTP != YES ]; then
    have=NGX_CRYPT . auto/nohave
    CRYPT_LIB=
fi


if [ $HTTP_CACHE = YES ]; then
    USE_MD5=YES
    have=NGX_HTTP_CACHE . auto/have
    HTTP_SRCS="$HTTP_SRCS $HTTP_FILE_CACHE_SRCS"
fi


if [ $HTTP_SSI = YES ]; then
    HTTP_POSTPONE=YES
fi


if [ $HTTP_SLICE = YES ]; then
    HTTP_POSTPONE=YES
fi


if [ $HTTP_ADDITION = YES ]; then
    HTTP_POSTPONE=YES
fi


# the module order is important
#     ngx_http_static_module
#     ngx_http_gzip_static_module
#     ngx_http_dav_module
#     ngx_http_autoindex_module
#     ngx_http_index_module
#     ngx_http_random_index_module
#
#     ngx_http_access_module
#     ngx_http_realip_module
#
#
# the filter order is important
#     ngx_http_write_filter
#     ngx_http_header_filter
#     ngx_http_chunked_filter
#     ngx_http_v2_filter
#     ngx_http_range_header_filter
#     ngx_http_gzip_filter
#     ngx_http_postpone_filter
#     ngx_http_ssi_filter
#     ngx_http_charset_filter
#         ngx_http_xslt_filter
#         ngx_http_image_filter
#         ngx_http_sub_filter
#         ngx_http_addition_filter
#         ngx_http_gunzip_filter
#         ngx_http_userid_filter
#         ngx_http_headers_filter
#     ngx_http_copy_filter
#     ngx_http_range_body_filter
#     ngx_http_not_modified_filter
#     ngx_http_slice_filter

ngx_module_type=HTTP_FILTER
HTTP_FILTER_MODULES=

ngx_module_order="ngx_http_static_module \
                  ngx_http_gzip_static_module \
                  ngx_http_dav_module \
                  ngx_http_autoindex_module \
                  ngx_http_index_module \
                  ngx_http_random_index_module \
                  ngx_http_access_module \
                  ngx_http_realip_module \
                  ngx_http_write_filter_module \
                  ngx_http_header_filter_module \
                  ngx_http_chunked_filter_module \
                  ngx_http_v2_filter_module \
                  ngx_http_range_header_filter_module \
                  ngx_http_gzip_filter_module \
                  ngx_http_postpone_filter_module \
                  ngx_http_ssi_filter_module \
                  ngx_http_charset_filter_module \
                  ngx_http_xslt_filter_module \
                  ngx_http_image_filter_module \
                  ngx_http_sub_filter_module \
                  ngx_http_addition_filter_module \
                  ngx_http_gunzip_filter_module \
                  ngx_http_userid_filter_module \
                  ngx_http_headers_filter_module \
                  ngx_http_copy_filter_module \
                  ngx_http_range_body_filter_module \
                  ngx_http_not_modified_filter_module \
                  ngx_http_slice_filter_module"

if :; then
    ngx_module_name=ngx_http_write_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/ngx_http_write_filter_module.c
    ngx_module_libs=
    ngx_module_link=YES

    . auto/module
fi

if :; then
    ngx_module_name=ngx_http_header_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/ngx_http_header_filter_module.c
    ngx_module_libs=
    ngx_module_link=YES

    . auto/module
fi

if :; then
    ngx_module_name=ngx_http_chunked_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_chunked_filter_module.c
    ngx_module_libs=
    ngx_module_link=YES

    . auto/module
fi

if [ $HTTP_V2 = YES ]; then
    ngx_module_name=ngx_http_v2_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/v2/ngx_http_v2_filter_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_V2

    . auto/module
fi

if :; then
    ngx_module_name=ngx_http_range_header_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_range_filter_module.c
    ngx_module_libs=
    ngx_module_link=YES

    . auto/module
fi

if [ $HTTP_GZIP = YES ]; then
    have=NGX_HTTP_GZIP . auto/have
    USE_ZLIB=YES

    ngx_module_name=ngx_http_gzip_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_gzip_filter_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_GZIP

    . auto/module
fi

if [ $HTTP_POSTPONE = YES ]; then
    ngx_module_name=ngx_http_postpone_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/ngx_http_postpone_filter_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_POSTPONE

    . auto/module
fi

if [ $HTTP_SSI = YES ]; then
    have=NGX_HTTP_SSI . auto/have

    ngx_module_name=ngx_http_ssi_filter_module
    ngx_module_incs=
    ngx_module_deps=src/http/modules/ngx_http_ssi_filter_module.h
    ngx_module_srcs=src/http/modules/ngx_http_ssi_filter_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_SSI

    . auto/module
fi

if [ $HTTP_CHARSET = YES ]; then
    ngx_module_name=ngx_http_charset_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_charset_filter_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_CHARSET

    . auto/module
fi

if [ $HTTP_XSLT != NO ]; then
    ngx_module_name=ngx_http_xslt_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_xslt_filter_module.c
    ngx_module_libs=LIBXSLT
    ngx_module_link=$HTTP_XSLT

    . auto/module
fi

if [ $HTTP_IMAGE_FILTER != NO ]; then
    ngx_module_name=ngx_http_image_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_image_filter_module.c
    ngx_module_libs=LIBGD
    ngx_module_link=$HTTP_IMAGE_FILTER

    . auto/module
fi

if [ $HTTP_SUB = YES ]; then
    ngx_module_name=ngx_http_sub_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_sub_filter_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_SUB

    . auto/module
fi

if [ $HTTP_ADDITION = YES ]; then
    ngx_module_name=ngx_http_addition_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_addition_filter_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_ADDITION

    . auto/module
fi

if [ $HTTP_GUNZIP = YES ]; then
    have=NGX_HTTP_GZIP . auto/have
    USE_ZLIB=YES

    ngx_module_name=ngx_http_gunzip_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_gunzip_filter_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_GUNZIP

    . auto/module
fi

if [ $HTTP_USERID = YES ]; then
    ngx_module_name=ngx_http_userid_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_userid_filter_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_USERID

    . auto/module
fi

if :; then
    ngx_module_name=ngx_http_headers_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_headers_filter_module.c
    ngx_module_libs=
    ngx_module_link=YES

    . auto/module
fi


ngx_module_type=HTTP_INIT_FILTER
HTTP_INIT_FILTER_MODULES=

if :; then
    ngx_module_name=ngx_http_copy_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/ngx_http_copy_filter_module.c
    ngx_module_libs=
    ngx_module_link=YES

    . auto/module
fi

if :; then
    ngx_module_name=ngx_http_range_body_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=
    ngx_module_libs=
    ngx_module_link=YES

    . auto/module
fi

if :; then
    ngx_module_name=ngx_http_not_modified_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_not_modified_filter_module.c
    ngx_module_libs=
    ngx_module_link=YES

    . auto/module
fi

if [ $HTTP_SLICE = YES ]; then
    ngx_module_name=ngx_http_slice_filter_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_slice_filter_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_SLICE

    . auto/module
fi


ngx_module_type=HTTP

if [ $HTTP_V2 = YES ]; then
    have=NGX_HTTP_V2 . auto/have

    ngx_module_name=ngx_http_v2_module
    ngx_module_incs=src/http/v2
    ngx_module_deps="src/http/v2/ngx_http_v2.h src/http/v2/ngx_http_v2_module.h"
    ngx_module_srcs="src/http/v2/ngx_http_v2.c \
                     src/http/v2/ngx_http_v2_table.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"
    ngx_module_libs=
    ngx_module_link=$HTTP_V2

    . auto/module
fi

if :; then
    ngx_module_name=ngx_http_static_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_static_module.c
    ngx_module_libs=
    ngx_module_link=YES

    . auto/module
fi

if [ $HTTP_GZIP_STATIC = YES ]; then
    have=NGX_HTTP_GZIP . auto/have

    ngx_module_name=ngx_http_gzip_static_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_gzip_static_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_GZIP_STATIC

    . auto/module
fi

if [ $HTTP_DAV = YES ]; then
    have=NGX_HTTP_DAV . auto/have

    ngx_module_name=ngx_http_dav_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_dav_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_DAV

    . auto/module
fi

if [ $HTTP_AUTOINDEX = YES ]; then
    ngx_module_name=ngx_http_autoindex_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_autoindex_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_AUTOINDEX

    . auto/module
fi

if :; then
    ngx_module_name=ngx_http_index_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_index_module.c
    ngx_module_libs=
    ngx_module_link=YES

    . auto/module
fi

if [ $HTTP_RANDOM_INDEX = YES ]; then
    ngx_module_name=ngx_http_random_index_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_random_index_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_RANDOM_INDEX

    . auto/module
fi

if [ $HTTP_AUTH_REQUEST = YES ]; then
    ngx_module_name=ngx_http_auth_request_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_auth_request_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_AUTH_REQUEST

    . auto/module
fi

if [ $HTTP_AUTH_BASIC = YES ]; then
    USE_MD5=YES
    USE_SHA1=YES
    have=NGX_CRYPT . auto/have

    ngx_module_name=ngx_http_auth_basic_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_auth_basic_module.c
    ngx_module_libs=$CRYPT_LIB
    ngx_module_link=$HTTP_AUTH_BASIC

    . auto/module
fi

if [ $HTTP_ACCESS = YES ]; then
    ngx_module_name=ngx_http_access_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_access_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_ACCESS

    . auto/module
fi

if [ $HTTP_LIMIT_CONN = YES ]; then
    ngx_module_name=ngx_http_limit_conn_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_limit_conn_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_LIMIT_CONN

    . auto/module
fi

if [ $HTTP_LIMIT_REQ = YES ]; then
    ngx_module_name=ngx_http_limit_req_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_limit_req_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_LIMIT_REQ

    . auto/module
fi

if [ $HTTP_REALIP = YES ]; then
    have=NGX_HTTP_REALIP . auto/have
    have=NGX_HTTP_X_FORWARDED_FOR . auto/have

    ngx_module_name=ngx_http_realip_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_realip_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_REALIP

    . auto/module
fi

if [ $HTTP_STATUS = YES ]; then
    ngx_module_name=ngx_http_status_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_status_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_STATUS

    . auto/module
fi

if [ $HTTP_GEO = YES ]; then
    have=NGX_HTTP_X_FORWARDED_FOR . auto/have

    ngx_module_name=ngx_http_geo_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_geo_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_GEO

    . auto/module
fi

if [ $HTTP_GEOIP != NO ]; then
    have=NGX_HTTP_X_FORWARDED_FOR . auto/have

    ngx_module_name=ngx_http_geoip_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_geoip_module.c
    ngx_module_libs=GEOIP
    ngx_module_link=$HTTP_GEOIP

    . auto/module
fi

if [ $HTTP_MAP = YES ]; then
    ngx_module_name=ngx_http_map_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_map_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_MAP

    . auto/module
fi

if [ $HTTP_SPLIT_CLIENTS = YES ]; then
    ngx_module_name=ngx_http_split_clients_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_split_clients_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_SPLIT_CLIENTS

    . auto/module
fi

if [ $HTTP_REFERER = YES ]; then
    ngx_module_name=ngx_http_referer_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_referer_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_REFERER

    . auto/module
fi

if [ $HTTP_REWRITE = YES -a $USE_PCRE != DISABLED ]; then
    USE_PCRE=YES

    ngx_module_name=ngx_http_rewrite_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_rewrite_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_REWRITE

    . auto/module
fi

if [ $HTTP_SSL = YES ]; then
    USE_OPENSSL=YES
    have=NGX_HTTP_SSL . auto/have

    ngx_module_name=ngx_http_ssl_module
    ngx_module_incs=
    ngx_module_deps=src/http/modules/ngx_http_ssl_module.h
    ngx_module_srcs=src/http/modules/ngx_http_ssl_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_SSL

    . auto/module
fi

if [ $HTTP_PROXY = YES ]; then
    have=NGX_HTTP_X_FORWARDED_FOR . auto/have
    #USE_MD5=YES

    ngx_module_name=ngx_http_proxy_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_proxy_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_PROXY

    . auto/module
fi

if [ $HTTP_FASTCGI = YES ]; then
    ngx_module_name=ngx_http_fastcgi_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_fastcgi_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_FASTCGI

    . auto/module
fi

if [ $HTTP_UWSGI = YES ]; then
    ngx_module_name=ngx_http_uwsgi_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_uwsgi_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_UWSGI

    . auto/module
fi

if [ $HTTP_SCGI = YES ]; then
    ngx_module_name=ngx_http_scgi_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_scgi_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_SCGI

    . auto/module
fi

if [ $HTTP_PERL != NO ]; then
    ngx_module_name=ngx_http_perl_module
    ngx_module_incs=src/http/modules/perl
    ngx_module_deps=src/http/modules/perl/ngx_http_perl_module.h
    ngx_module_srcs=src/http/modules/perl/ngx_http_perl_module.c
    ngx_module_libs=PERL
    ngx_module_link=$HTTP_PERL

    . auto/module
fi

if [ $HTTP_MEMCACHED = YES ]; then
    ngx_module_name=ngx_http_memcached_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_memcached_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_MEMCACHED

    . auto/module
fi

if [ $HTTP_EMPTY_GIF = YES ]; then
    ngx_module_name=ngx_http_empty_gif_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_empty_gif_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_EMPTY_GIF

    . auto/module
fi

if [ $HTTP_BROWSER = YES ]; then
    ngx_module_name=ngx_http_browser_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_browser_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_BROWSER

    . auto/module
fi

if [ $HTTP_SECURE_LINK = YES ]; then
    USE_MD5=YES

    ngx_module_name=ngx_http_secure_link_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_secure_link_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_SECURE_LINK

    . auto/module
fi

if [ $HTTP_DEGRADATION = YES ]; then
    have=NGX_HTTP_DEGRADATION . auto/have

    ngx_module_name=ngx_http_degradation_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_degradation_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_DEGRADATION

    . auto/module
fi

if [ $HTTP_FLV = YES ]; then
    ngx_module_name=ngx_http_flv_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_flv_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_FLV

    . auto/module
fi

if [ $HTTP_MP4 = YES ]; then
    ngx_module_name=ngx_http_mp4_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_mp4_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_MP4

    . auto/module
fi

if [ $HTTP_UPSTREAM_HASH = YES ]; then
    ngx_module_name=ngx_http_upstream_hash_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_upstream_hash_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_UPSTREAM_HASH

    . auto/module
fi

if [ $HTTP_UPSTREAM_IP_HASH = YES ]; then
    ngx_module_name=ngx_http_upstream_ip_hash_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_upstream_ip_hash_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_UPSTREAM_IP_HASH

    . auto/module
fi

if [ $HTTP_UPSTREAM_LEAST_CONN = YES ]; then
    ngx_module_name=ngx_http_upstream_least_conn_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_upstream_least_conn_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_UPSTREAM_LEAST_CONN

    . auto/module
fi

if [ $HTTP_UPSTREAM_KEEPALIVE = YES ]; then
    ngx_module_name=ngx_http_upstream_keepalive_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_upstream_keepalive_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_UPSTREAM_KEEPALIVE

    . auto/module
fi

if [ $HTTP_UPSTREAM_ZONE = YES ]; then
    have=NGX_HTTP_UPSTREAM_ZONE . auto/have

    ngx_module_name=ngx_http_upstream_zone_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_upstream_zone_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_UPSTREAM_ZONE

    . auto/module
fi

if [ $HTTP_STUB_STATUS = YES ]; then
    have=NGX_STAT_STUB . auto/have

    ngx_module_name=ngx_http_stub_status_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/http/modules/ngx_http_stub_status_module.c
    ngx_module_libs=
    ngx_module_link=$HTTP_STUB_STATUS

    . auto/module
fi


if [ $MAIL != NO ]; then
    MAIL_MODULES=
    MAIL_DEPS=
    MAIL_INCS=

    ngx_module_type=MAIL
    ngx_module_libs=
    ngx_module_link=YES

    ngx_module_order=

    ngx_module_name="ngx_mail_module ngx_mail_core_module"
    ngx_module_incs="src/mail"
    ngx_module_deps="src/mail/ngx_mail.h"
    ngx_module_srcs="src/mail/ngx_mail.c \
                     src/mail/ngx_mail_core_module.c \
                     src/mail/ngx_mail_handler.c \
                     src/mail/ngx_mail_parse.c"

    . auto/module

    ngx_module_incs=

    if [ $MAIL_SSL = YES ]; then
        USE_OPENSSL=YES
        have=NGX_MAIL_SSL . 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
    fi

    if [ $MAIL_POP3 = YES ]; then
        ngx_module_name=ngx_mail_pop3_module
        ngx_module_deps=src/mail/ngx_mail_pop3_module.h
        ngx_module_srcs="src/mail/ngx_mail_pop3_module.c \
                         src/mail/ngx_mail_pop3_handler.c"

        . auto/module
    fi

    if [ $MAIL_IMAP = YES ]; then
        ngx_module_name=ngx_mail_imap_module
        ngx_module_deps=src/mail/ngx_mail_imap_module.h
        ngx_module_srcs="src/mail/ngx_mail_imap_module.c \
                         src/mail/ngx_mail_imap_handler.c"

        . auto/module
    fi

    if [ $MAIL_SMTP = YES ]; then
        ngx_module_name=ngx_mail_smtp_module
        ngx_module_deps=src/mail/ngx_mail_smtp_module.h
        ngx_module_srcs="src/mail/ngx_mail_smtp_module.c \
                         src/mail/ngx_mail_smtp_handler.c"

        . 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_module_name=ngx_mail_proxy_module
    ngx_module_deps=
    ngx_module_srcs=src/mail/ngx_mail_proxy_module.c

    . auto/module
fi


if [ $STREAM != NO ]; then
    STREAM_MODULES=
    STREAM_DEPS=
    STREAM_INCS=

    ngx_module_type=STREAM
    ngx_module_libs=
    ngx_module_link=YES

    ngx_module_order=

    ngx_module_name="ngx_stream_module \
                     ngx_stream_core_module \
                     ngx_stream_proxy_module \
                     ngx_stream_upstream_module"
    ngx_module_incs="src/stream"
    ngx_module_deps="src/stream/ngx_stream.h \
                     src/stream/ngx_stream_upstream.h \
                     src/stream/ngx_stream_upstream_round_robin.h"
    ngx_module_srcs="src/stream/ngx_stream.c \
                     src/stream/ngx_stream_handler.c \
                     src/stream/ngx_stream_core_module.c \
                     src/stream/ngx_stream_proxy_module.c \
                     src/stream/ngx_stream_upstream.c \
                     src/stream/ngx_stream_upstream_round_robin.c"

    . auto/module

    ngx_module_incs=

    if [ $STREAM_SSL = YES ]; then
        USE_OPENSSL=YES
        have=NGX_STREAM_SSL . auto/have

        ngx_module_name=ngx_stream_ssl_module
        ngx_module_deps=src/stream/ngx_stream_ssl_module.h
        ngx_module_srcs=src/stream/ngx_stream_ssl_module.c

        . auto/module
    fi

    if [ $STREAM_LIMIT_CONN = YES ]; then
        ngx_module_name=ngx_stream_limit_conn_module
        ngx_module_deps=
        ngx_module_srcs=src/stream/ngx_stream_limit_conn_module.c

        . auto/module
    fi

    if [ $STREAM_ACCESS = YES ]; then
        ngx_module_name=ngx_stream_access_module
        ngx_module_deps=
        ngx_module_srcs=src/stream/ngx_stream_access_module.c

        . auto/module
    fi

    if [ $STREAM_UPSTREAM_HASH = YES ]; then
        ngx_module_name=ngx_stream_upstream_hash_module
        ngx_module_deps=
        ngx_module_srcs=src/stream/ngx_stream_upstream_hash_module.c

        . auto/module
    fi

    if [ $STREAM_UPSTREAM_LEAST_CONN = YES ]; then
        ngx_module_name=ngx_stream_upstream_least_conn_module
        ngx_module_deps=
        ngx_module_srcs=src/stream/ngx_stream_upstream_least_conn_module.c

        . auto/module
    fi

    if [ $STREAM_UPSTREAM_ZONE = YES ]; then
        have=NGX_STREAM_UPSTREAM_ZONE . auto/have

        ngx_module_name=ngx_stream_upstream_zone_module
        ngx_module_deps=
        ngx_module_srcs=src/stream/ngx_stream_upstream_zone_module.c

        . auto/module
    fi
fi


#if [ -r $NGX_OBJS/auto ]; then
#    . $NGX_OBJS/auto
#fi


if test -n "$NGX_ADDONS"; then

    echo configuring additional modules

    for ngx_addon_dir in $NGX_ADDONS
    do
        echo "adding module in $ngx_addon_dir"

        ngx_module_type=
        ngx_module_name=
        ngx_module_incs=
        ngx_module_deps=
        ngx_module_srcs=
        ngx_module_libs=
        ngx_module_order=
        ngx_module_link=ADDON

        if test -f $ngx_addon_dir/config; then
            . $ngx_addon_dir/config

            echo " + $ngx_addon_name was configured"

        else
            echo "$0: error: no $ngx_addon_dir/config was found"
            exit 1
        fi
    done
fi


if test -n "$DYNAMIC_ADDONS"; then

    echo configuring additional dynamic modules

    for ngx_addon_dir in $DYNAMIC_ADDONS
    do
        echo "adding module in $ngx_addon_dir"

        ngx_module_type=
        ngx_module_name=
        ngx_module_incs=
        ngx_module_deps=
        ngx_module_srcs=
        ngx_module_libs=
        ngx_module_order=
        ngx_module_link=DYNAMIC

        if test -f $ngx_addon_dir/config; then
            . $ngx_addon_dir/config

            echo " + $ngx_addon_name was configured"

        else
            echo "$0: error: no $ngx_addon_dir/config was found"
            exit 1
        fi
    done
fi


if [ $USE_OPENSSL = YES ]; then
    ngx_module_type=CORE
    ngx_module_name=ngx_openssl_module
    ngx_module_incs=
    ngx_module_deps=src/event/ngx_event_openssl.h
    ngx_module_srcs="src/event/ngx_event_openssl.c
                     src/event/ngx_event_openssl_stapling.c"
    ngx_module_libs=
    ngx_module_link=YES
    ngx_module_order=

    . auto/module
fi


if [ $USE_PCRE = YES ]; then
    ngx_module_type=CORE
    ngx_module_name=ngx_regex_module
    ngx_module_incs=
    ngx_module_deps=src/core/ngx_regex.h
    ngx_module_srcs=src/core/ngx_regex.c
    ngx_module_libs=
    ngx_module_link=YES
    ngx_module_order=

    . auto/module
fi


modules="$CORE_MODULES $EVENT_MODULES"


# thread pool module should be initialized after events
if [ $USE_THREADS = YES ]; then
    modules="$modules $THREAD_POOL_MODULE"
fi


if [ $HTTP = YES ]; then
    modules="$modules $HTTP_MODULES $HTTP_FILTER_MODULES \
             $HTTP_AUX_FILTER_MODULES $HTTP_INIT_FILTER_MODULES"

    NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(HTTP_DEPS)"
fi


if [ $MAIL != NO ]; then

    if [ $MAIL = YES ]; then
        modules="$modules $MAIL_MODULES"

    elif [ $MAIL = DYNAMIC ]; then
        ngx_module_name=$MAIL_MODULES
        ngx_module_incs=
        ngx_module_deps=$MAIL_DEPS
        ngx_module_srcs=$MAIL_SRCS
        ngx_module_libs=
        ngx_module_link=DYNAMIC

        . auto/module
    fi

    NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(MAIL_DEPS)"
fi


if [ $STREAM != NO ]; then

    if [ $STREAM = YES ]; then
        modules="$modules $STREAM_MODULES"

    elif [ $STREAM = DYNAMIC ]; then
        ngx_module_name=$STREAM_MODULES
        ngx_module_incs=
        ngx_module_deps=$STREAM_DEPS
        ngx_module_srcs=$STREAM_SRCS
        ngx_module_libs=
        ngx_module_link=DYNAMIC

        . auto/module
    fi

    NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(STREAM_DEPS)"
fi


ngx_module_type=MISC
MISC_MODULES=

if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then
    ngx_module_name=ngx_google_perftools_module
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/misc/ngx_google_perftools_module.c
    ngx_module_libs=
    ngx_module_link=$NGX_GOOGLE_PERFTOOLS

    . auto/module
fi

if [ $NGX_CPP_TEST = YES ]; then
    ngx_module_name=
    ngx_module_incs=
    ngx_module_deps=
    ngx_module_srcs=src/misc/ngx_cpp_test_module.cpp
    ngx_module_libs=-lstdc++
    ngx_module_link=$NGX_CPP_TEST

    . auto/module
fi

modules="$modules $MISC_MODULES"


cat << END                                    > $NGX_MODULES_C

#include <ngx_config.h>
#include <ngx_core.h>

$NGX_PRAGMA

END

for mod in $modules
do
    echo "extern ngx_module_t  $mod;"         >> $NGX_MODULES_C
done

echo                                          >> $NGX_MODULES_C
echo 'ngx_module_t *ngx_modules[] = {'        >> $NGX_MODULES_C

for mod in $modules
do
    echo "    &$mod,"                         >> $NGX_MODULES_C
done

cat << END                                    >> $NGX_MODULES_C
    NULL
};

END

echo 'char *ngx_module_names[] = {'           >> $NGX_MODULES_C

for mod in $modules
do
    echo "    \"$mod\","                      >> $NGX_MODULES_C
done

cat << END                                    >> $NGX_MODULES_C
    NULL
};

END