diff --git a/auto/cc/conf b/auto/cc/conf index b3b9f92..afbca62 100644 --- a/auto/cc/conf +++ b/auto/cc/conf @@ -178,21 +178,25 @@ if [ "$NGX_PLATFORM" != win32 ]; then fi - ngx_feature="gcc builtin atomic operations" - ngx_feature_name=NGX_HAVE_GCC_ATOMIC - ngx_feature_run=yes - ngx_feature_incs= - ngx_feature_path= - ngx_feature_libs= - ngx_feature_test="long n = 0; - if (!__sync_bool_compare_and_swap(&n, 0, 1)) - return 1; - if (__sync_fetch_and_add(&n, 1) != 1) - return 1; - if (n != 2) - return 1; - __sync_synchronize();" - . auto/feature + 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 + ngx_feature_run=yes + ngx_feature_incs= + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="long n = 0; + if (!__sync_bool_compare_and_swap(&n, 0, 1)) + return 1; + if (__sync_fetch_and_add(&n, 1) != 1) + return 1; + if (n != 2) + return 1; + __sync_synchronize();" + . auto/feature + fi if [ "$NGX_CC_NAME" = "ccc" ]; then @@ -209,7 +213,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then var(0, buf, \"%d\", 1); if (buf[0] != '1') return 1" . auto/feature - fi + fi ngx_feature="gcc variadic macros" diff --git a/auto/cc/sunc b/auto/cc/sunc index 806ccc4..552c2d3 100644 --- a/auto/cc/sunc +++ b/auto/cc/sunc @@ -8,7 +8,10 @@ # Sun C 5.9 SunOS_i386 2007/05/03 Sun Studio 12 # Sun C 5.9 SunOS_sparc 2007/05/03 # Sun C 5.10 SunOS_i386 2009/06/03 Sun Studio 12.1 -# Sun C 5.11 SunOS_i386 2010/08/13 Sun Studio 12.2 +# Sun C 5.11 SunOS_i386 2010/08/13 Oracle Solaris Studio 12.2 +# Sun C 5.12 SunOS_i386 2011/11/16 Oracle Solaris Studio 12.3 +# Sun C 5.13 SunOS_i386 2014/10/20 Oracle Solaris Studio 12.4 +# Sun C 5.14 SunOS_i386 2016/05/31 Oracle Developer Studio 12.5 NGX_SUNC_VER=`$CC -V 2>&1 | grep 'Sun C' 2>&1 \ | sed -e 's/^.* Sun C \(.*\)/\1/'` diff --git a/auto/modules b/auto/modules index c664fe3..be3561e 100644 --- a/auto/modules +++ b/auto/modules @@ -56,832 +56,829 @@ if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = YES ]; then 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 - 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 - 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 - - 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 - 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 +if [ $HTTP = YES ]; then + 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_CACHE = YES ]; then + 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 + 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 + + 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 + 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 fi @@ -966,6 +963,8 @@ if [ $STREAM != NO ]; then STREAM_INCS= ngx_module_type=STREAM + ngx_module_libs= + ngx_module_link=YES ngx_module_order= diff --git a/auto/options b/auto/options index 43724b1..66b822a 100644 --- a/auto/options +++ b/auto/options @@ -574,19 +574,6 @@ END fi -if [ $HTTP = NO ]; then - HTTP_CHARSET=NO - HTTP_GZIP=NO - HTTP_SSI=NO - HTTP_USERID=NO - HTTP_ACCESS=NO - HTTP_STATUS=NO - HTTP_REWRITE=NO - HTTP_PROXY=NO - HTTP_FASTCGI=NO -fi - - if [ ".$NGX_PLATFORM" = ".win32" ]; then NGX_WINE=$WINE fi diff --git a/auto/os/darwin b/auto/os/darwin index b4b3ad3..429468f 100644 --- a/auto/os/darwin +++ b/auto/os/darwin @@ -17,6 +17,9 @@ ngx_spacer=' MAIN_LINK= MODULE_LINK="-shared -Wl,-undefined,dynamic_lookup" +CC_AUX_FLAGS="$CC_AUX_FLAGS -D__APPLE_USE_RFC_3542" + + # kqueue echo " + kqueue found" @@ -86,7 +89,6 @@ ngx_feature_test="int kq; # sendfile() -CC_AUX_FLAGS="$CC_AUX_FLAGS" ngx_feature="sendfile()" ngx_feature_name="NGX_HAVE_SENDFILE" ngx_feature_run=yes diff --git a/auto/os/linux b/auto/os/linux index fae8842..a0c8795 100644 --- a/auto/os/linux +++ b/auto/os/linux @@ -157,20 +157,6 @@ ngx_feature_test="if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) return 1" . auto/feature -# sched_setaffinity() - -ngx_feature="sched_setaffinity()" -ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="cpu_set_t mask; - CPU_ZERO(&mask); - sched_setaffinity(0, sizeof(cpu_set_t), &mask)" -. auto/feature - - # crypt_r() ngx_feature="crypt_r()" diff --git a/auto/unix b/auto/unix old mode 100755 new mode 100644 index 5ef74d4..7c6a855 --- a/auto/unix +++ b/auto/unix @@ -300,6 +300,18 @@ if [ $ngx_found = no ]; then fi +ngx_feature="sched_setaffinity()" +ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY" +ngx_feature_run=no +ngx_feature_incs="#include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="cpu_set_t mask; + CPU_ZERO(&mask); + sched_setaffinity(0, sizeof(cpu_set_t), &mask)" +. auto/feature + + ngx_feature="SO_SETFIB" ngx_feature_name="NGX_HAVE_SETFIB" ngx_feature_run=no @@ -394,6 +406,19 @@ ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_RECVDSTADDR, NULL, 0)" . auto/feature +# BSD way to set IPv4 datagram source address + +ngx_feature="IP_SENDSRCADDR" +ngx_feature_name="NGX_HAVE_IP_SENDSRCADDR" +ngx_feature_run=no +ngx_feature_incs="#include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_SENDSRCADDR, NULL, 0)" +. auto/feature + + # Linux way to get IPv4 datagram destination address ngx_feature="IP_PKTINFO" diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim index f1fd48a..dc8c0cb 100644 --- a/contrib/vim/syntax/nginx.vim +++ b/contrib/vim/syntax/nginx.vim @@ -5,832 +5,2170 @@ if exists("b:current_syntax") finish end -setlocal iskeyword+=. -setlocal iskeyword+=/ -setlocal iskeyword+=: +" general syntax -syn match ngxVariable '\$\(\w\+\|{\w\+}\)' -syn match ngxVariableBlock '\$\(\w\+\|{\w\+}\)' contained +if has("patch-7.4.1142") + " except control characters, ";", "{", and "}" + syn iskeyword 33-58,60-122,124,126-255 +endif + +syn match ngxName '\([^;{} \t\\]\|\\.\)\+' + \ contains=@ngxDirectives + \ nextgroup=@ngxParams skipwhite skipempty +syn match ngxParam '\([^;{ \t\\]\|\\.\)\+' + \ contained + \ contains=ngxVariable + \ nextgroup=@ngxParams skipwhite skipempty +syn region ngxString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ + \ contains=ngxVariableString + \ nextgroup=@ngxParams skipwhite skipempty +syn match ngxParamComment '#.*$' + \ nextgroup=@ngxParams skipwhite skipempty +syn match ngxSemicolon ';' contained +syn region ngxBlock start=+{+ end=+}+ contained + \ contains=@ngxTopLevel +syn match ngxComment '#.*$' + +syn match ngxVariable '\$\w\+' contained syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained -syn region ngxBlock start=+^+ end=+{+ skip=+\${+ contains=ngxComment,ngxDirectiveBlock,ngxVariableBlock,ngxString oneline -syn region ngxString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString -syn match ngxComment ' *#.*$' -syn keyword ngxBoolean on -syn keyword ngxBoolean off +syn cluster ngxTopLevel + \ contains=ngxName,ngxString,ngxComment +syn cluster ngxDirectives + \ contains=ngxDirective,ngxDirectiveBlock,ngxDirectiveImportant + \ add=ngxDirectiveControl,ngxDirectiveError,ngxDirectiveDeprecated + \ add=ngxDirectiveThirdParty +syn cluster ngxParams + \ contains=ngxParam,ngxString,ngxParamComment,ngxSemicolon,ngxBlock -syn keyword ngxDirectiveBlock http contained -syn keyword ngxDirectiveBlock mail contained -syn keyword ngxDirectiveBlock events contained -syn keyword ngxDirectiveBlock server contained -syn keyword ngxDirectiveBlock types contained -syn keyword ngxDirectiveBlock location contained -syn keyword ngxDirectiveBlock upstream contained -syn keyword ngxDirectiveBlock charset_map contained -syn keyword ngxDirectiveBlock limit_except contained -syn keyword ngxDirectiveBlock if contained -syn keyword ngxDirectiveBlock geo contained -syn keyword ngxDirectiveBlock map contained -syn keyword ngxDirectiveBlock split_clients contained +" boolean parameters -syn keyword ngxDirectiveImportant include -syn keyword ngxDirectiveImportant root -syn keyword ngxDirectiveImportant server -syn keyword ngxDirectiveImportant server_name -syn keyword ngxDirectiveImportant listen -syn keyword ngxDirectiveImportant internal -syn keyword ngxDirectiveImportant proxy_pass -syn keyword ngxDirectiveImportant memcached_pass -syn keyword ngxDirectiveImportant fastcgi_pass -syn keyword ngxDirectiveImportant scgi_pass -syn keyword ngxDirectiveImportant uwsgi_pass -syn keyword ngxDirectiveImportant try_files +syn keyword ngxBoolean contained on off + \ nextgroup=@ngxParams skipwhite skipempty +syn cluster ngxParams add=ngxBoolean -syn keyword ngxDirectiveControl break -syn keyword ngxDirectiveControl return -syn keyword ngxDirectiveControl rewrite -syn keyword ngxDirectiveControl set +" listen directive -syn keyword ngxDirectiveError error_page -syn keyword ngxDirectiveError post_action +syn cluster ngxTopLevel add=ngxDirectiveListen +syn keyword ngxDirectiveListen listen + \ nextgroup=@ngxListenParams skipwhite skipempty +syn match ngxListenParam '\([^;{ \t\\]\|\\.\)\+' + \ contained + \ nextgroup=@ngxListenParams skipwhite skipempty +syn region ngxListenString start=+\z(["']\)+ end=+\z1+ skip=+\\\\\|\\\z1+ + \ contained + \ nextgroup=@ngxListenParams skipwhite skipempty +syn match ngxListenComment '#.*$' + \ contained + \ nextgroup=@ngxListenParams skipwhite skipempty +syn keyword ngxListenOptions contained + \ default_server ssl http2 spdy proxy_protocol + \ setfib fastopen backlog rcvbuf sndbuf accept_filter deferred bind + \ ipv6only reuseport so_keepalive keepidle + \ nextgroup=@ngxListenParams skipwhite skipempty +syn cluster ngxListenParams + \ contains=ngxListenParam,ngxListenString,ngxListenComment + \ add=ngxListenOptions -syn keyword ngxDirectiveDeprecated connections -syn keyword ngxDirectiveDeprecated imap -syn keyword ngxDirectiveDeprecated limit_zone -syn keyword ngxDirectiveDeprecated mysql_test -syn keyword ngxDirectiveDeprecated open_file_cache_retest -syn keyword ngxDirectiveDeprecated optimize_server_names -syn keyword ngxDirectiveDeprecated satisfy_any -syn keyword ngxDirectiveDeprecated so_keepalive +syn keyword ngxDirectiveBlock contained http +syn keyword ngxDirectiveBlock contained mail +syn keyword ngxDirectiveBlock contained events +syn keyword ngxDirectiveBlock contained server +syn keyword ngxDirectiveBlock contained types +syn keyword ngxDirectiveBlock contained location +syn keyword ngxDirectiveBlock contained upstream +syn keyword ngxDirectiveBlock contained charset_map +syn keyword ngxDirectiveBlock contained limit_except +syn keyword ngxDirectiveBlock contained if +syn keyword ngxDirectiveBlock contained geo +syn keyword ngxDirectiveBlock contained map +syn keyword ngxDirectiveBlock contained split_clients -syn keyword ngxDirective accept_mutex -syn keyword ngxDirective accept_mutex_delay -syn keyword ngxDirective acceptex_read -syn keyword ngxDirective access_log -syn keyword ngxDirective add_after_body -syn keyword ngxDirective add_before_body -syn keyword ngxDirective add_header -syn keyword ngxDirective addition_types -syn keyword ngxDirective aio -syn keyword ngxDirective alias -syn keyword ngxDirective allow -syn keyword ngxDirective ancient_browser -syn keyword ngxDirective ancient_browser_value -syn keyword ngxDirective auth_basic -syn keyword ngxDirective auth_basic_user_file -syn keyword ngxDirective auth_http -syn keyword ngxDirective auth_http_header -syn keyword ngxDirective auth_http_timeout -syn keyword ngxDirective auth_request -syn keyword ngxDirective auth_request_set -syn keyword ngxDirective autoindex -syn keyword ngxDirective autoindex_exact_size -syn keyword ngxDirective autoindex_localtime -syn keyword ngxDirective charset -syn keyword ngxDirective charset_types -syn keyword ngxDirective chunked_transfer_encoding -syn keyword ngxDirective client_body_buffer_size -syn keyword ngxDirective client_body_in_file_only -syn keyword ngxDirective client_body_in_single_buffer -syn keyword ngxDirective client_body_temp_path -syn keyword ngxDirective client_body_timeout -syn keyword ngxDirective client_header_buffer_size -syn keyword ngxDirective client_header_timeout -syn keyword ngxDirective client_max_body_size -syn keyword ngxDirective connection_pool_size -syn keyword ngxDirective create_full_put_path -syn keyword ngxDirective daemon -syn keyword ngxDirective dav_access -syn keyword ngxDirective dav_methods -syn keyword ngxDirective debug_connection -syn keyword ngxDirective debug_points -syn keyword ngxDirective default_type -syn keyword ngxDirective degradation -syn keyword ngxDirective degrade -syn keyword ngxDirective deny -syn keyword ngxDirective devpoll_changes -syn keyword ngxDirective devpoll_events -syn keyword ngxDirective directio -syn keyword ngxDirective directio_alignment -syn keyword ngxDirective disable_symlinks -syn keyword ngxDirective empty_gif -syn keyword ngxDirective env -syn keyword ngxDirective epoll_events -syn keyword ngxDirective error_log -syn keyword ngxDirective etag -syn keyword ngxDirective eventport_events -syn keyword ngxDirective expires -syn keyword ngxDirective fastcgi_bind -syn keyword ngxDirective fastcgi_buffer_size -syn keyword ngxDirective fastcgi_buffering -syn keyword ngxDirective fastcgi_buffers -syn keyword ngxDirective fastcgi_busy_buffers_size -syn keyword ngxDirective fastcgi_cache -syn keyword ngxDirective fastcgi_cache_bypass -syn keyword ngxDirective fastcgi_cache_key -syn keyword ngxDirective fastcgi_cache_lock -syn keyword ngxDirective fastcgi_cache_lock_timeout -syn keyword ngxDirective fastcgi_cache_methods -syn keyword ngxDirective fastcgi_cache_min_uses -syn keyword ngxDirective fastcgi_cache_path -syn keyword ngxDirective fastcgi_cache_revalidate -syn keyword ngxDirective fastcgi_cache_use_stale -syn keyword ngxDirective fastcgi_cache_valid -syn keyword ngxDirective fastcgi_catch_stderr -syn keyword ngxDirective fastcgi_connect_timeout -syn keyword ngxDirective fastcgi_force_ranges -syn keyword ngxDirective fastcgi_hide_header -syn keyword ngxDirective fastcgi_ignore_client_abort -syn keyword ngxDirective fastcgi_ignore_headers -syn keyword ngxDirective fastcgi_index -syn keyword ngxDirective fastcgi_intercept_errors -syn keyword ngxDirective fastcgi_keep_conn -syn keyword ngxDirective fastcgi_max_temp_file_size -syn keyword ngxDirective fastcgi_next_upstream -syn keyword ngxDirective fastcgi_next_upstream_timeout -syn keyword ngxDirective fastcgi_next_upstream_tries -syn keyword ngxDirective fastcgi_no_cache -syn keyword ngxDirective fastcgi_param -syn keyword ngxDirective fastcgi_pass_header -syn keyword ngxDirective fastcgi_pass_request_body -syn keyword ngxDirective fastcgi_pass_request_headers -syn keyword ngxDirective fastcgi_read_timeout -syn keyword ngxDirective fastcgi_send_lowat -syn keyword ngxDirective fastcgi_send_timeout -syn keyword ngxDirective fastcgi_split_path_info -syn keyword ngxDirective fastcgi_store -syn keyword ngxDirective fastcgi_store_access -syn keyword ngxDirective fastcgi_temp_file_write_size -syn keyword ngxDirective fastcgi_temp_path -syn keyword ngxDirective flv -syn keyword ngxDirective geoip_city -syn keyword ngxDirective geoip_country -syn keyword ngxDirective geoip_org -syn keyword ngxDirective geoip_proxy -syn keyword ngxDirective geoip_proxy_recursive -syn keyword ngxDirective google_perftools_profiles -syn keyword ngxDirective gunzip -syn keyword ngxDirective gunzip_buffers -syn keyword ngxDirective gzip -syn keyword ngxDirective gzip_buffers -syn keyword ngxDirective gzip_comp_level -syn keyword ngxDirective gzip_disable -syn keyword ngxDirective gzip_hash -syn keyword ngxDirective gzip_http_version -syn keyword ngxDirective gzip_min_length -syn keyword ngxDirective gzip_no_buffer -syn keyword ngxDirective gzip_proxied -syn keyword ngxDirective gzip_static -syn keyword ngxDirective gzip_types -syn keyword ngxDirective gzip_vary -syn keyword ngxDirective gzip_window -syn keyword ngxDirective hash -syn keyword ngxDirective if_modified_since -syn keyword ngxDirective ignore_invalid_headers -syn keyword ngxDirective image_filter -syn keyword ngxDirective image_filter_buffer -syn keyword ngxDirective image_filter_interlace -syn keyword ngxDirective image_filter_jpeg_quality -syn keyword ngxDirective image_filter_sharpen -syn keyword ngxDirective image_filter_transparency -syn keyword ngxDirective imap_auth -syn keyword ngxDirective imap_capabilities -syn keyword ngxDirective imap_client_buffer -syn keyword ngxDirective index -syn keyword ngxDirective iocp_threads -syn keyword ngxDirective ip_hash -syn keyword ngxDirective keepalive -syn keyword ngxDirective keepalive_disable -syn keyword ngxDirective keepalive_requests -syn keyword ngxDirective keepalive_timeout -syn keyword ngxDirective kqueue_changes -syn keyword ngxDirective kqueue_events -syn keyword ngxDirective large_client_header_buffers -syn keyword ngxDirective least_conn -syn keyword ngxDirective limit_conn -syn keyword ngxDirective limit_conn_log_level -syn keyword ngxDirective limit_conn_status -syn keyword ngxDirective limit_conn_zone -syn keyword ngxDirective limit_rate -syn keyword ngxDirective limit_rate_after -syn keyword ngxDirective limit_req -syn keyword ngxDirective limit_req_log_level -syn keyword ngxDirective limit_req_status -syn keyword ngxDirective limit_req_zone -syn keyword ngxDirective lingering_close -syn keyword ngxDirective lingering_time -syn keyword ngxDirective lingering_timeout -syn keyword ngxDirective lock_file -syn keyword ngxDirective log_format -syn keyword ngxDirective log_not_found -syn keyword ngxDirective log_subrequest -syn keyword ngxDirective map_hash_bucket_size -syn keyword ngxDirective map_hash_max_size -syn keyword ngxDirective master_process -syn keyword ngxDirective max_ranges -syn keyword ngxDirective memcached_bind -syn keyword ngxDirective memcached_buffer_size -syn keyword ngxDirective memcached_connect_timeout -syn keyword ngxDirective memcached_gzip_flag -syn keyword ngxDirective memcached_next_upstream -syn keyword ngxDirective memcached_next_upstream_timeout -syn keyword ngxDirective memcached_next_upstream_tries -syn keyword ngxDirective memcached_read_timeout -syn keyword ngxDirective memcached_send_timeout -syn keyword ngxDirective merge_slashes -syn keyword ngxDirective min_delete_depth -syn keyword ngxDirective modern_browser -syn keyword ngxDirective modern_browser_value -syn keyword ngxDirective mp4 -syn keyword ngxDirective mp4_buffer_size -syn keyword ngxDirective mp4_max_buffer_size -syn keyword ngxDirective msie_padding -syn keyword ngxDirective msie_refresh -syn keyword ngxDirective multi_accept -syn keyword ngxDirective open_file_cache -syn keyword ngxDirective open_file_cache_errors -syn keyword ngxDirective open_file_cache_events -syn keyword ngxDirective open_file_cache_min_uses -syn keyword ngxDirective open_file_cache_valid -syn keyword ngxDirective open_log_file_cache -syn keyword ngxDirective output_buffers -syn keyword ngxDirective override_charset -syn keyword ngxDirective pcre_jit -syn keyword ngxDirective perl -syn keyword ngxDirective perl_modules -syn keyword ngxDirective perl_require -syn keyword ngxDirective perl_set -syn keyword ngxDirective pid -syn keyword ngxDirective pop3_auth -syn keyword ngxDirective pop3_capabilities -syn keyword ngxDirective port_in_redirect -syn keyword ngxDirective post_acceptex -syn keyword ngxDirective postpone_gzipping -syn keyword ngxDirective postpone_output -syn keyword ngxDirective protocol -syn keyword ngxDirective proxy -syn keyword ngxDirective proxy_bind -syn keyword ngxDirective proxy_buffer -syn keyword ngxDirective proxy_buffer_size -syn keyword ngxDirective proxy_buffering -syn keyword ngxDirective proxy_buffers -syn keyword ngxDirective proxy_busy_buffers_size -syn keyword ngxDirective proxy_cache -syn keyword ngxDirective proxy_cache_bypass -syn keyword ngxDirective proxy_cache_key -syn keyword ngxDirective proxy_cache_lock -syn keyword ngxDirective proxy_cache_lock_timeout -syn keyword ngxDirective proxy_cache_methods -syn keyword ngxDirective proxy_cache_min_uses -syn keyword ngxDirective proxy_cache_path -syn keyword ngxDirective proxy_cache_revalidate -syn keyword ngxDirective proxy_cache_use_stale -syn keyword ngxDirective proxy_cache_valid -syn keyword ngxDirective proxy_connect_timeout -syn keyword ngxDirective proxy_cookie_domain -syn keyword ngxDirective proxy_cookie_path -syn keyword ngxDirective proxy_force_ranges -syn keyword ngxDirective proxy_headers_hash_bucket_size -syn keyword ngxDirective proxy_headers_hash_max_size -syn keyword ngxDirective proxy_hide_header -syn keyword ngxDirective proxy_http_version -syn keyword ngxDirective proxy_ignore_client_abort -syn keyword ngxDirective proxy_ignore_headers -syn keyword ngxDirective proxy_intercept_errors -syn keyword ngxDirective proxy_max_temp_file_size -syn keyword ngxDirective proxy_method -syn keyword ngxDirective proxy_next_upstream -syn keyword ngxDirective proxy_next_upstream_timeout -syn keyword ngxDirective proxy_next_upstream_tries -syn keyword ngxDirective proxy_no_cache -syn keyword ngxDirective proxy_pass_error_message -syn keyword ngxDirective proxy_pass_header -syn keyword ngxDirective proxy_pass_request_body -syn keyword ngxDirective proxy_pass_request_headers -syn keyword ngxDirective proxy_read_timeout -syn keyword ngxDirective proxy_redirect -syn keyword ngxDirective proxy_send_lowat -syn keyword ngxDirective proxy_send_timeout -syn keyword ngxDirective proxy_set_body -syn keyword ngxDirective proxy_set_header -syn keyword ngxDirective proxy_ssl_ciphers -syn keyword ngxDirective proxy_ssl_crl -syn keyword ngxDirective proxy_ssl_name -syn keyword ngxDirective proxy_ssl_protocols -syn keyword ngxDirective proxy_ssl_server_name -syn keyword ngxDirective proxy_ssl_session_reuse -syn keyword ngxDirective proxy_ssl_trusted_certificate -syn keyword ngxDirective proxy_ssl_verify -syn keyword ngxDirective proxy_ssl_verify_depth -syn keyword ngxDirective proxy_store -syn keyword ngxDirective proxy_store_access -syn keyword ngxDirective proxy_temp_file_write_size -syn keyword ngxDirective proxy_temp_path -syn keyword ngxDirective proxy_timeout -syn keyword ngxDirective random_index -syn keyword ngxDirective read_ahead -syn keyword ngxDirective real_ip_header -syn keyword ngxDirective real_ip_recursive -syn keyword ngxDirective recursive_error_pages -syn keyword ngxDirective referer_hash_bucket_size -syn keyword ngxDirective referer_hash_max_size -syn keyword ngxDirective request_pool_size -syn keyword ngxDirective reset_timedout_connection -syn keyword ngxDirective resolver -syn keyword ngxDirective resolver_timeout -syn keyword ngxDirective rewrite_log -syn keyword ngxDirective rtsig_overflow_events -syn keyword ngxDirective rtsig_overflow_test -syn keyword ngxDirective rtsig_overflow_threshold -syn keyword ngxDirective rtsig_signo -syn keyword ngxDirective satisfy -syn keyword ngxDirective scgi_bind -syn keyword ngxDirective scgi_buffer_size -syn keyword ngxDirective scgi_buffering -syn keyword ngxDirective scgi_buffers -syn keyword ngxDirective scgi_busy_buffers_size -syn keyword ngxDirective scgi_cache -syn keyword ngxDirective scgi_cache_bypass -syn keyword ngxDirective scgi_cache_key -syn keyword ngxDirective scgi_cache_lock -syn keyword ngxDirective scgi_cache_lock_timeout -syn keyword ngxDirective scgi_cache_methods -syn keyword ngxDirective scgi_cache_min_uses -syn keyword ngxDirective scgi_cache_path -syn keyword ngxDirective scgi_cache_revalidate -syn keyword ngxDirective scgi_cache_use_stale -syn keyword ngxDirective scgi_cache_valid -syn keyword ngxDirective scgi_connect_timeout -syn keyword ngxDirective scgi_force_ranges -syn keyword ngxDirective scgi_hide_header -syn keyword ngxDirective scgi_ignore_client_abort -syn keyword ngxDirective scgi_ignore_headers -syn keyword ngxDirective scgi_intercept_errors -syn keyword ngxDirective scgi_max_temp_file_size -syn keyword ngxDirective scgi_next_upstream -syn keyword ngxDirective scgi_next_upstream_timeout -syn keyword ngxDirective scgi_next_upstream_tries -syn keyword ngxDirective scgi_no_cache -syn keyword ngxDirective scgi_param -syn keyword ngxDirective scgi_pass_header -syn keyword ngxDirective scgi_pass_request_body -syn keyword ngxDirective scgi_pass_request_headers -syn keyword ngxDirective scgi_read_timeout -syn keyword ngxDirective scgi_send_timeout -syn keyword ngxDirective scgi_store -syn keyword ngxDirective scgi_store_access -syn keyword ngxDirective scgi_temp_file_write_size -syn keyword ngxDirective scgi_temp_path -syn keyword ngxDirective secure_link -syn keyword ngxDirective secure_link_md5 -syn keyword ngxDirective secure_link_secret -syn keyword ngxDirective send_lowat -syn keyword ngxDirective send_timeout -syn keyword ngxDirective sendfile -syn keyword ngxDirective sendfile_max_chunk -syn keyword ngxDirective server_name_in_redirect -syn keyword ngxDirective server_names_hash_bucket_size -syn keyword ngxDirective server_names_hash_max_size -syn keyword ngxDirective server_tokens -syn keyword ngxDirective set_real_ip_from -syn keyword ngxDirective smtp_auth -syn keyword ngxDirective smtp_capabilities -syn keyword ngxDirective smtp_client_buffer -syn keyword ngxDirective smtp_greeting_delay -syn keyword ngxDirective source_charset -syn keyword ngxDirective spdy_chunk_size -syn keyword ngxDirective spdy_headers_comp -syn keyword ngxDirective spdy_keepalive_timeout -syn keyword ngxDirective spdy_max_concurrent_streams -syn keyword ngxDirective spdy_pool_size -syn keyword ngxDirective spdy_recv_buffer_size -syn keyword ngxDirective spdy_recv_timeout -syn keyword ngxDirective spdy_streams_index_size -syn keyword ngxDirective ssi -syn keyword ngxDirective ssi_ignore_recycled_buffers -syn keyword ngxDirective ssi_last_modified -syn keyword ngxDirective ssi_min_file_chunk -syn keyword ngxDirective ssi_silent_errors -syn keyword ngxDirective ssi_types -syn keyword ngxDirective ssi_value_length -syn keyword ngxDirective ssl -syn keyword ngxDirective ssl_buffer_size -syn keyword ngxDirective ssl_certificate -syn keyword ngxDirective ssl_certificate_key -syn keyword ngxDirective ssl_ciphers -syn keyword ngxDirective ssl_client_certificate -syn keyword ngxDirective ssl_crl -syn keyword ngxDirective ssl_dhparam -syn keyword ngxDirective ssl_ecdh_curve -syn keyword ngxDirective ssl_engine -syn keyword ngxDirective ssl_password_file -syn keyword ngxDirective ssl_prefer_server_ciphers -syn keyword ngxDirective ssl_protocols -syn keyword ngxDirective ssl_session_cache -syn keyword ngxDirective ssl_session_ticket_key -syn keyword ngxDirective ssl_session_tickets -syn keyword ngxDirective ssl_session_timeout -syn keyword ngxDirective ssl_stapling -syn keyword ngxDirective ssl_stapling_file -syn keyword ngxDirective ssl_stapling_responder -syn keyword ngxDirective ssl_stapling_verify -syn keyword ngxDirective ssl_trusted_certificate -syn keyword ngxDirective ssl_verify_client -syn keyword ngxDirective ssl_verify_depth -syn keyword ngxDirective starttls -syn keyword ngxDirective stub_status -syn keyword ngxDirective sub_filter -syn keyword ngxDirective sub_filter_last_modified -syn keyword ngxDirective sub_filter_once -syn keyword ngxDirective sub_filter_types -syn keyword ngxDirective tcp_nodelay -syn keyword ngxDirective tcp_nopush -syn keyword ngxDirective thread_stack_size -syn keyword ngxDirective timeout -syn keyword ngxDirective timer_resolution -syn keyword ngxDirective types_hash_bucket_size -syn keyword ngxDirective types_hash_max_size -syn keyword ngxDirective underscores_in_headers -syn keyword ngxDirective uninitialized_variable_warn -syn keyword ngxDirective use -syn keyword ngxDirective user -syn keyword ngxDirective userid -syn keyword ngxDirective userid_domain -syn keyword ngxDirective userid_expires -syn keyword ngxDirective userid_mark -syn keyword ngxDirective userid_name -syn keyword ngxDirective userid_p3p -syn keyword ngxDirective userid_path -syn keyword ngxDirective userid_service -syn keyword ngxDirective uwsgi_bind -syn keyword ngxDirective uwsgi_buffer_size -syn keyword ngxDirective uwsgi_buffering -syn keyword ngxDirective uwsgi_buffers -syn keyword ngxDirective uwsgi_busy_buffers_size -syn keyword ngxDirective uwsgi_cache -syn keyword ngxDirective uwsgi_cache_bypass -syn keyword ngxDirective uwsgi_cache_key -syn keyword ngxDirective uwsgi_cache_lock -syn keyword ngxDirective uwsgi_cache_lock_timeout -syn keyword ngxDirective uwsgi_cache_methods -syn keyword ngxDirective uwsgi_cache_min_uses -syn keyword ngxDirective uwsgi_cache_path -syn keyword ngxDirective uwsgi_cache_revalidate -syn keyword ngxDirective uwsgi_cache_use_stale -syn keyword ngxDirective uwsgi_cache_valid -syn keyword ngxDirective uwsgi_connect_timeout -syn keyword ngxDirective uwsgi_force_ranges -syn keyword ngxDirective uwsgi_hide_header -syn keyword ngxDirective uwsgi_ignore_client_abort -syn keyword ngxDirective uwsgi_ignore_headers -syn keyword ngxDirective uwsgi_intercept_errors -syn keyword ngxDirective uwsgi_max_temp_file_size -syn keyword ngxDirective uwsgi_modifier1 -syn keyword ngxDirective uwsgi_modifier2 -syn keyword ngxDirective uwsgi_next_upstream -syn keyword ngxDirective uwsgi_next_upstream_timeout -syn keyword ngxDirective uwsgi_next_upstream_tries -syn keyword ngxDirective uwsgi_no_cache -syn keyword ngxDirective uwsgi_param -syn keyword ngxDirective uwsgi_pass_header -syn keyword ngxDirective uwsgi_pass_request_body -syn keyword ngxDirective uwsgi_pass_request_headers -syn keyword ngxDirective uwsgi_read_timeout -syn keyword ngxDirective uwsgi_send_timeout -syn keyword ngxDirective uwsgi_ssl_ciphers -syn keyword ngxDirective uwsgi_ssl_crl -syn keyword ngxDirective uwsgi_ssl_name -syn keyword ngxDirective uwsgi_ssl_protocols -syn keyword ngxDirective uwsgi_ssl_server_name -syn keyword ngxDirective uwsgi_ssl_session_reuse -syn keyword ngxDirective uwsgi_ssl_trusted_certificate -syn keyword ngxDirective uwsgi_ssl_verify -syn keyword ngxDirective uwsgi_ssl_verify_depth -syn keyword ngxDirective uwsgi_store -syn keyword ngxDirective uwsgi_store_access -syn keyword ngxDirective uwsgi_string -syn keyword ngxDirective uwsgi_temp_file_write_size -syn keyword ngxDirective uwsgi_temp_path -syn keyword ngxDirective valid_referers -syn keyword ngxDirective variables_hash_bucket_size -syn keyword ngxDirective variables_hash_max_size -syn keyword ngxDirective worker_aio_requests -syn keyword ngxDirective worker_connections -syn keyword ngxDirective worker_cpu_affinity -syn keyword ngxDirective worker_priority -syn keyword ngxDirective worker_processes -syn keyword ngxDirective worker_rlimit_core -syn keyword ngxDirective worker_rlimit_nofile -syn keyword ngxDirective worker_rlimit_sigpending -syn keyword ngxDirective worker_threads -syn keyword ngxDirective working_directory -syn keyword ngxDirective xclient -syn keyword ngxDirective xml_entities -syn keyword ngxDirective xslt_last_modified -syn keyword ngxDirective xslt_param -syn keyword ngxDirective xslt_string_param -syn keyword ngxDirective xslt_stylesheet -syn keyword ngxDirective xslt_types +syn keyword ngxDirectiveImportant contained include +syn keyword ngxDirectiveImportant contained root +"syn keyword ngxDirectiveImportant contained server +syn keyword ngxDirectiveImportant contained server_name +"syn keyword ngxDirectiveImportant contained listen +syn keyword ngxDirectiveImportant contained internal +syn keyword ngxDirectiveImportant contained proxy_pass +syn keyword ngxDirectiveImportant contained memcached_pass +syn keyword ngxDirectiveImportant contained fastcgi_pass +syn keyword ngxDirectiveImportant contained scgi_pass +syn keyword ngxDirectiveImportant contained uwsgi_pass +syn keyword ngxDirectiveImportant contained try_files + +syn keyword ngxDirectiveControl contained break +syn keyword ngxDirectiveControl contained return +syn keyword ngxDirectiveControl contained rewrite +syn keyword ngxDirectiveControl contained set + +syn keyword ngxDirectiveError contained error_page +syn keyword ngxDirectiveError contained post_action + +syn keyword ngxDirectiveDeprecated contained connections +syn keyword ngxDirectiveDeprecated contained imap +syn keyword ngxDirectiveDeprecated contained limit_zone +syn keyword ngxDirectiveDeprecated contained mysql_test +syn keyword ngxDirectiveDeprecated contained open_file_cache_retest +syn keyword ngxDirectiveDeprecated contained optimize_server_names +syn keyword ngxDirectiveDeprecated contained satisfy_any +syn keyword ngxDirectiveDeprecated contained so_keepalive + +syn keyword ngxDirective contained absolute_redirect +syn keyword ngxDirective contained accept_mutex +syn keyword ngxDirective contained accept_mutex_delay +syn keyword ngxDirective contained acceptex_read +syn keyword ngxDirective contained access_log +syn keyword ngxDirective contained add_after_body +syn keyword ngxDirective contained add_before_body +syn keyword ngxDirective contained add_header +syn keyword ngxDirective contained addition_types +syn keyword ngxDirective contained aio +syn keyword ngxDirective contained aio_write +syn keyword ngxDirective contained alias +syn keyword ngxDirective contained allow +syn keyword ngxDirective contained ancient_browser +syn keyword ngxDirective contained ancient_browser_value +syn keyword ngxDirective contained auth_basic +syn keyword ngxDirective contained auth_basic_user_file +syn keyword ngxDirective contained auth_http +syn keyword ngxDirective contained auth_http_header +syn keyword ngxDirective contained auth_http_pass_client_cert +syn keyword ngxDirective contained auth_http_timeout +syn keyword ngxDirective contained auth_jwt +syn keyword ngxDirective contained auth_jwt_key_file +syn keyword ngxDirective contained auth_request +syn keyword ngxDirective contained auth_request_set +syn keyword ngxDirective contained autoindex +syn keyword ngxDirective contained autoindex_exact_size +syn keyword ngxDirective contained autoindex_format +syn keyword ngxDirective contained autoindex_localtime +syn keyword ngxDirective contained charset +syn keyword ngxDirective contained charset_map +syn keyword ngxDirective contained charset_types +syn keyword ngxDirective contained chunked_transfer_encoding +syn keyword ngxDirective contained client_body_buffer_size +syn keyword ngxDirective contained client_body_in_file_only +syn keyword ngxDirective contained client_body_in_single_buffer +syn keyword ngxDirective contained client_body_temp_path +syn keyword ngxDirective contained client_body_timeout +syn keyword ngxDirective contained client_header_buffer_size +syn keyword ngxDirective contained client_header_timeout +syn keyword ngxDirective contained client_max_body_size +syn keyword ngxDirective contained connection_pool_size +syn keyword ngxDirective contained create_full_put_path +syn keyword ngxDirective contained daemon +syn keyword ngxDirective contained dav_access +syn keyword ngxDirective contained dav_methods +syn keyword ngxDirective contained debug_connection +syn keyword ngxDirective contained debug_points +syn keyword ngxDirective contained default_type +syn keyword ngxDirective contained degradation +syn keyword ngxDirective contained degrade +syn keyword ngxDirective contained deny +syn keyword ngxDirective contained devpoll_changes +syn keyword ngxDirective contained devpoll_events +syn keyword ngxDirective contained directio +syn keyword ngxDirective contained directio_alignment +syn keyword ngxDirective contained disable_symlinks +syn keyword ngxDirective contained empty_gif +syn keyword ngxDirective contained env +syn keyword ngxDirective contained epoll_events +syn keyword ngxDirective contained error_log +syn keyword ngxDirective contained etag +syn keyword ngxDirective contained eventport_events +syn keyword ngxDirective contained expires +syn keyword ngxDirective contained f4f +syn keyword ngxDirective contained f4f_buffer_size +syn keyword ngxDirective contained fastcgi_bind +syn keyword ngxDirective contained fastcgi_buffer_size +syn keyword ngxDirective contained fastcgi_buffering +syn keyword ngxDirective contained fastcgi_buffers +syn keyword ngxDirective contained fastcgi_busy_buffers_size +syn keyword ngxDirective contained fastcgi_cache +syn keyword ngxDirective contained fastcgi_cache_bypass +syn keyword ngxDirective contained fastcgi_cache_key +syn keyword ngxDirective contained fastcgi_cache_lock +syn keyword ngxDirective contained fastcgi_cache_lock_age +syn keyword ngxDirective contained fastcgi_cache_lock_timeout +syn keyword ngxDirective contained fastcgi_cache_max_range_offset +syn keyword ngxDirective contained fastcgi_cache_methods +syn keyword ngxDirective contained fastcgi_cache_min_uses +syn keyword ngxDirective contained fastcgi_cache_path +syn keyword ngxDirective contained fastcgi_cache_purge +syn keyword ngxDirective contained fastcgi_cache_revalidate +syn keyword ngxDirective contained fastcgi_cache_use_stale +syn keyword ngxDirective contained fastcgi_cache_valid +syn keyword ngxDirective contained fastcgi_catch_stderr +syn keyword ngxDirective contained fastcgi_connect_timeout +syn keyword ngxDirective contained fastcgi_force_ranges +syn keyword ngxDirective contained fastcgi_hide_header +syn keyword ngxDirective contained fastcgi_ignore_client_abort +syn keyword ngxDirective contained fastcgi_ignore_headers +syn keyword ngxDirective contained fastcgi_index +syn keyword ngxDirective contained fastcgi_intercept_errors +syn keyword ngxDirective contained fastcgi_keep_conn +syn keyword ngxDirective contained fastcgi_limit_rate +syn keyword ngxDirective contained fastcgi_max_temp_file_size +syn keyword ngxDirective contained fastcgi_next_upstream +syn keyword ngxDirective contained fastcgi_next_upstream_timeout +syn keyword ngxDirective contained fastcgi_next_upstream_tries +syn keyword ngxDirective contained fastcgi_no_cache +syn keyword ngxDirective contained fastcgi_param +syn keyword ngxDirective contained fastcgi_pass_header +syn keyword ngxDirective contained fastcgi_pass_request_body +syn keyword ngxDirective contained fastcgi_pass_request_headers +syn keyword ngxDirective contained fastcgi_read_timeout +syn keyword ngxDirective contained fastcgi_request_buffering +syn keyword ngxDirective contained fastcgi_send_lowat +syn keyword ngxDirective contained fastcgi_send_timeout +syn keyword ngxDirective contained fastcgi_split_path_info +syn keyword ngxDirective contained fastcgi_store +syn keyword ngxDirective contained fastcgi_store_access +syn keyword ngxDirective contained fastcgi_temp_file_write_size +syn keyword ngxDirective contained fastcgi_temp_path +syn keyword ngxDirective contained flv +syn keyword ngxDirective contained geoip_city +syn keyword ngxDirective contained geoip_country +syn keyword ngxDirective contained geoip_org +syn keyword ngxDirective contained geoip_proxy +syn keyword ngxDirective contained geoip_proxy_recursive +syn keyword ngxDirective contained google_perftools_profiles +syn keyword ngxDirective contained gunzip +syn keyword ngxDirective contained gunzip_buffers +syn keyword ngxDirective contained gzip +syn keyword ngxDirective contained gzip_buffers +syn keyword ngxDirective contained gzip_comp_level +syn keyword ngxDirective contained gzip_disable +syn keyword ngxDirective contained gzip_hash +syn keyword ngxDirective contained gzip_http_version +syn keyword ngxDirective contained gzip_min_length +syn keyword ngxDirective contained gzip_no_buffer +syn keyword ngxDirective contained gzip_proxied +syn keyword ngxDirective contained gzip_static +syn keyword ngxDirective contained gzip_types +syn keyword ngxDirective contained gzip_vary +syn keyword ngxDirective contained gzip_window +syn keyword ngxDirective contained hash +syn keyword ngxDirective contained health_check +syn keyword ngxDirective contained health_check_timeout +syn keyword ngxDirective contained hls +syn keyword ngxDirective contained hls_buffers +syn keyword ngxDirective contained hls_forward_args +syn keyword ngxDirective contained hls_fragment +syn keyword ngxDirective contained hls_mp4_buffer_size +syn keyword ngxDirective contained hls_mp4_max_buffer_size +syn keyword ngxDirective contained http2_chunk_size +syn keyword ngxDirective contained http2_body_preread_size +syn keyword ngxDirective contained http2_idle_timeout +syn keyword ngxDirective contained http2_max_concurrent_streams +syn keyword ngxDirective contained http2_max_field_size +syn keyword ngxDirective contained http2_max_header_size +syn keyword ngxDirective contained http2_max_requests +syn keyword ngxDirective contained http2_recv_buffer_size +syn keyword ngxDirective contained http2_recv_timeout +syn keyword ngxDirective contained if_modified_since +syn keyword ngxDirective contained ignore_invalid_headers +syn keyword ngxDirective contained image_filter +syn keyword ngxDirective contained image_filter_buffer +syn keyword ngxDirective contained image_filter_interlace +syn keyword ngxDirective contained image_filter_jpeg_quality +syn keyword ngxDirective contained image_filter_sharpen +syn keyword ngxDirective contained image_filter_transparency +syn keyword ngxDirective contained image_filter_webp_quality +syn keyword ngxDirective contained imap_auth +syn keyword ngxDirective contained imap_capabilities +syn keyword ngxDirective contained imap_client_buffer +syn keyword ngxDirective contained index +syn keyword ngxDirective contained iocp_threads +syn keyword ngxDirective contained ip_hash +syn keyword ngxDirective contained js_access +syn keyword ngxDirective contained js_content +syn keyword ngxDirective contained js_filter +syn keyword ngxDirective contained js_include +syn keyword ngxDirective contained js_preread +syn keyword ngxDirective contained js_set +syn keyword ngxDirective contained keepalive +syn keyword ngxDirective contained keepalive_disable +syn keyword ngxDirective contained keepalive_requests +syn keyword ngxDirective contained keepalive_timeout +syn keyword ngxDirective contained kqueue_changes +syn keyword ngxDirective contained kqueue_events +syn keyword ngxDirective contained large_client_header_buffers +syn keyword ngxDirective contained least_conn +syn keyword ngxDirective contained least_time +syn keyword ngxDirective contained limit_conn +syn keyword ngxDirective contained limit_conn_log_level +syn keyword ngxDirective contained limit_conn_status +syn keyword ngxDirective contained limit_conn_zone +syn keyword ngxDirective contained limit_rate +syn keyword ngxDirective contained limit_rate_after +syn keyword ngxDirective contained limit_req +syn keyword ngxDirective contained limit_req_log_level +syn keyword ngxDirective contained limit_req_status +syn keyword ngxDirective contained limit_req_zone +syn keyword ngxDirective contained lingering_close +syn keyword ngxDirective contained lingering_time +syn keyword ngxDirective contained lingering_timeout +syn keyword ngxDirective contained load_module +syn keyword ngxDirective contained lock_file +syn keyword ngxDirective contained log_format +syn keyword ngxDirective contained log_not_found +syn keyword ngxDirective contained log_subrequest +syn keyword ngxDirective contained map_hash_bucket_size +syn keyword ngxDirective contained map_hash_max_size +syn keyword ngxDirective contained match +syn keyword ngxDirective contained master_process +syn keyword ngxDirective contained max_ranges +syn keyword ngxDirective contained memcached_bind +syn keyword ngxDirective contained memcached_buffer_size +syn keyword ngxDirective contained memcached_connect_timeout +syn keyword ngxDirective contained memcached_force_ranges +syn keyword ngxDirective contained memcached_gzip_flag +syn keyword ngxDirective contained memcached_next_upstream +syn keyword ngxDirective contained memcached_next_upstream_timeout +syn keyword ngxDirective contained memcached_next_upstream_tries +syn keyword ngxDirective contained memcached_read_timeout +syn keyword ngxDirective contained memcached_send_timeout +syn keyword ngxDirective contained merge_slashes +syn keyword ngxDirective contained min_delete_depth +syn keyword ngxDirective contained modern_browser +syn keyword ngxDirective contained modern_browser_value +syn keyword ngxDirective contained mp4 +syn keyword ngxDirective contained mp4_buffer_size +syn keyword ngxDirective contained mp4_max_buffer_size +syn keyword ngxDirective contained mp4_limit_rate +syn keyword ngxDirective contained mp4_limit_rate_after +syn keyword ngxDirective contained msie_padding +syn keyword ngxDirective contained msie_refresh +syn keyword ngxDirective contained multi_accept +syn keyword ngxDirective contained ntlm +syn keyword ngxDirective contained open_file_cache +syn keyword ngxDirective contained open_file_cache_errors +syn keyword ngxDirective contained open_file_cache_events +syn keyword ngxDirective contained open_file_cache_min_uses +syn keyword ngxDirective contained open_file_cache_valid +syn keyword ngxDirective contained open_log_file_cache +syn keyword ngxDirective contained output_buffers +syn keyword ngxDirective contained override_charset +syn keyword ngxDirective contained pcre_jit +syn keyword ngxDirective contained perl +syn keyword ngxDirective contained perl_modules +syn keyword ngxDirective contained perl_require +syn keyword ngxDirective contained perl_set +syn keyword ngxDirective contained pid +syn keyword ngxDirective contained pop3_auth +syn keyword ngxDirective contained pop3_capabilities +syn keyword ngxDirective contained port_in_redirect +syn keyword ngxDirective contained post_acceptex +syn keyword ngxDirective contained postpone_gzipping +syn keyword ngxDirective contained postpone_output +syn keyword ngxDirective contained preread_buffer_size +syn keyword ngxDirective contained preread_timeout +syn keyword ngxDirective contained protocol +syn keyword ngxDirective contained proxy +syn keyword ngxDirective contained proxy_bind +syn keyword ngxDirective contained proxy_buffer +syn keyword ngxDirective contained proxy_buffer_size +syn keyword ngxDirective contained proxy_buffering +syn keyword ngxDirective contained proxy_buffers +syn keyword ngxDirective contained proxy_busy_buffers_size +syn keyword ngxDirective contained proxy_cache +syn keyword ngxDirective contained proxy_cache_bypass +syn keyword ngxDirective contained proxy_cache_convert_head +syn keyword ngxDirective contained proxy_cache_key +syn keyword ngxDirective contained proxy_cache_lock +syn keyword ngxDirective contained proxy_cache_lock_age +syn keyword ngxDirective contained proxy_cache_lock_timeout +syn keyword ngxDirective contained proxy_cache_max_range_offset +syn keyword ngxDirective contained proxy_cache_methods +syn keyword ngxDirective contained proxy_cache_min_uses +syn keyword ngxDirective contained proxy_cache_path +syn keyword ngxDirective contained proxy_cache_purge +syn keyword ngxDirective contained proxy_cache_revalidate +syn keyword ngxDirective contained proxy_cache_use_stale +syn keyword ngxDirective contained proxy_cache_valid +syn keyword ngxDirective contained proxy_connect_timeout +syn keyword ngxDirective contained proxy_cookie_domain +syn keyword ngxDirective contained proxy_cookie_path +syn keyword ngxDirective contained proxy_download_rate +syn keyword ngxDirective contained proxy_force_ranges +syn keyword ngxDirective contained proxy_headers_hash_bucket_size +syn keyword ngxDirective contained proxy_headers_hash_max_size +syn keyword ngxDirective contained proxy_hide_header +syn keyword ngxDirective contained proxy_http_version +syn keyword ngxDirective contained proxy_ignore_client_abort +syn keyword ngxDirective contained proxy_ignore_headers +syn keyword ngxDirective contained proxy_intercept_errors +syn keyword ngxDirective contained proxy_limit_rate +syn keyword ngxDirective contained proxy_max_temp_file_size +syn keyword ngxDirective contained proxy_method +syn keyword ngxDirective contained proxy_next_upstream +syn keyword ngxDirective contained proxy_next_upstream_timeout +syn keyword ngxDirective contained proxy_next_upstream_tries +syn keyword ngxDirective contained proxy_no_cache +syn keyword ngxDirective contained proxy_pass_error_message +syn keyword ngxDirective contained proxy_pass_header +syn keyword ngxDirective contained proxy_pass_request_body +syn keyword ngxDirective contained proxy_pass_request_headers +syn keyword ngxDirective contained proxy_protocol +syn keyword ngxDirective contained proxy_protocol_timeout +syn keyword ngxDirective contained proxy_read_timeout +syn keyword ngxDirective contained proxy_redirect +syn keyword ngxDirective contained proxy_request_buffering +syn keyword ngxDirective contained proxy_responses +syn keyword ngxDirective contained proxy_send_lowat +syn keyword ngxDirective contained proxy_send_timeout +syn keyword ngxDirective contained proxy_set_body +syn keyword ngxDirective contained proxy_set_header +syn keyword ngxDirective contained proxy_ssl_certificate +syn keyword ngxDirective contained proxy_ssl_certificate_key +syn keyword ngxDirective contained proxy_ssl_ciphers +syn keyword ngxDirective contained proxy_ssl_crl +syn keyword ngxDirective contained proxy_ssl_name +syn keyword ngxDirective contained proxy_ssl_password_file +syn keyword ngxDirective contained proxy_ssl_protocols +syn keyword ngxDirective contained proxy_ssl_server_name +syn keyword ngxDirective contained proxy_ssl_session_reuse +syn keyword ngxDirective contained proxy_ssl_trusted_certificate +syn keyword ngxDirective contained proxy_ssl_verify +syn keyword ngxDirective contained proxy_ssl_verify_depth +syn keyword ngxDirective contained proxy_store +syn keyword ngxDirective contained proxy_store_access +syn keyword ngxDirective contained proxy_temp_file_write_size +syn keyword ngxDirective contained proxy_temp_path +syn keyword ngxDirective contained proxy_timeout +syn keyword ngxDirective contained proxy_upload_rate +syn keyword ngxDirective contained queue +syn keyword ngxDirective contained random_index +syn keyword ngxDirective contained read_ahead +syn keyword ngxDirective contained real_ip_header +syn keyword ngxDirective contained real_ip_recursive +syn keyword ngxDirective contained recursive_error_pages +syn keyword ngxDirective contained referer_hash_bucket_size +syn keyword ngxDirective contained referer_hash_max_size +syn keyword ngxDirective contained request_pool_size +syn keyword ngxDirective contained reset_timedout_connection +syn keyword ngxDirective contained resolver +syn keyword ngxDirective contained resolver_timeout +syn keyword ngxDirective contained rewrite_log +syn keyword ngxDirective contained rtsig_overflow_events +syn keyword ngxDirective contained rtsig_overflow_test +syn keyword ngxDirective contained rtsig_overflow_threshold +syn keyword ngxDirective contained rtsig_signo +syn keyword ngxDirective contained satisfy +syn keyword ngxDirective contained scgi_bind +syn keyword ngxDirective contained scgi_buffer_size +syn keyword ngxDirective contained scgi_buffering +syn keyword ngxDirective contained scgi_buffers +syn keyword ngxDirective contained scgi_busy_buffers_size +syn keyword ngxDirective contained scgi_cache +syn keyword ngxDirective contained scgi_cache_bypass +syn keyword ngxDirective contained scgi_cache_key +syn keyword ngxDirective contained scgi_cache_lock +syn keyword ngxDirective contained scgi_cache_lock_age +syn keyword ngxDirective contained scgi_cache_lock_timeout +syn keyword ngxDirective contained scgi_cache_max_range_offset +syn keyword ngxDirective contained scgi_cache_methods +syn keyword ngxDirective contained scgi_cache_min_uses +syn keyword ngxDirective contained scgi_cache_path +syn keyword ngxDirective contained scgi_cache_purge +syn keyword ngxDirective contained scgi_cache_revalidate +syn keyword ngxDirective contained scgi_cache_use_stale +syn keyword ngxDirective contained scgi_cache_valid +syn keyword ngxDirective contained scgi_connect_timeout +syn keyword ngxDirective contained scgi_force_ranges +syn keyword ngxDirective contained scgi_hide_header +syn keyword ngxDirective contained scgi_ignore_client_abort +syn keyword ngxDirective contained scgi_ignore_headers +syn keyword ngxDirective contained scgi_intercept_errors +syn keyword ngxDirective contained scgi_limit_rate +syn keyword ngxDirective contained scgi_max_temp_file_size +syn keyword ngxDirective contained scgi_next_upstream +syn keyword ngxDirective contained scgi_next_upstream_timeout +syn keyword ngxDirective contained scgi_next_upstream_tries +syn keyword ngxDirective contained scgi_no_cache +syn keyword ngxDirective contained scgi_param +syn keyword ngxDirective contained scgi_pass_header +syn keyword ngxDirective contained scgi_pass_request_body +syn keyword ngxDirective contained scgi_pass_request_headers +syn keyword ngxDirective contained scgi_read_timeout +syn keyword ngxDirective contained scgi_request_buffering +syn keyword ngxDirective contained scgi_send_timeout +syn keyword ngxDirective contained scgi_store +syn keyword ngxDirective contained scgi_store_access +syn keyword ngxDirective contained scgi_temp_file_write_size +syn keyword ngxDirective contained scgi_temp_path +syn keyword ngxDirective contained secure_link +syn keyword ngxDirective contained secure_link_md5 +syn keyword ngxDirective contained secure_link_secret +syn keyword ngxDirective contained send_lowat +syn keyword ngxDirective contained send_timeout +syn keyword ngxDirective contained sendfile +syn keyword ngxDirective contained sendfile_max_chunk +syn keyword ngxDirective contained server_name_in_redirect +syn keyword ngxDirective contained server_names_hash_bucket_size +syn keyword ngxDirective contained server_names_hash_max_size +syn keyword ngxDirective contained server_tokens +syn keyword ngxDirective contained session_log +syn keyword ngxDirective contained session_log_format +syn keyword ngxDirective contained session_log_zone +syn keyword ngxDirective contained set_real_ip_from +syn keyword ngxDirective contained slice +syn keyword ngxDirective contained smtp_auth +syn keyword ngxDirective contained smtp_capabilities +syn keyword ngxDirective contained smtp_client_buffer +syn keyword ngxDirective contained smtp_greeting_delay +syn keyword ngxDirective contained source_charset +syn keyword ngxDirective contained spdy_chunk_size +syn keyword ngxDirective contained spdy_headers_comp +syn keyword ngxDirective contained spdy_keepalive_timeout +syn keyword ngxDirective contained spdy_max_concurrent_streams +syn keyword ngxDirective contained spdy_pool_size +syn keyword ngxDirective contained spdy_recv_buffer_size +syn keyword ngxDirective contained spdy_recv_timeout +syn keyword ngxDirective contained spdy_streams_index_size +syn keyword ngxDirective contained ssi +syn keyword ngxDirective contained ssi_ignore_recycled_buffers +syn keyword ngxDirective contained ssi_last_modified +syn keyword ngxDirective contained ssi_min_file_chunk +syn keyword ngxDirective contained ssi_silent_errors +syn keyword ngxDirective contained ssi_types +syn keyword ngxDirective contained ssi_value_length +syn keyword ngxDirective contained ssl +syn keyword ngxDirective contained ssl_buffer_size +syn keyword ngxDirective contained ssl_certificate +syn keyword ngxDirective contained ssl_certificate_key +syn keyword ngxDirective contained ssl_ciphers +syn keyword ngxDirective contained ssl_client_certificate +syn keyword ngxDirective contained ssl_crl +syn keyword ngxDirective contained ssl_dhparam +syn keyword ngxDirective contained ssl_ecdh_curve +syn keyword ngxDirective contained ssl_engine +syn keyword ngxDirective contained ssl_handshake_timeout +syn keyword ngxDirective contained ssl_password_file +syn keyword ngxDirective contained ssl_prefer_server_ciphers +syn keyword ngxDirective contained ssl_preread +syn keyword ngxDirective contained ssl_protocols +syn keyword ngxDirective contained ssl_session_cache +syn keyword ngxDirective contained ssl_session_ticket_key +syn keyword ngxDirective contained ssl_session_tickets +syn keyword ngxDirective contained ssl_session_timeout +syn keyword ngxDirective contained ssl_stapling +syn keyword ngxDirective contained ssl_stapling_file +syn keyword ngxDirective contained ssl_stapling_responder +syn keyword ngxDirective contained ssl_stapling_verify +syn keyword ngxDirective contained ssl_trusted_certificate +syn keyword ngxDirective contained ssl_verify_client +syn keyword ngxDirective contained ssl_verify_depth +syn keyword ngxDirective contained starttls +syn keyword ngxDirective contained state +syn keyword ngxDirective contained status +syn keyword ngxDirective contained status_format +syn keyword ngxDirective contained status_zone +syn keyword ngxDirective contained sticky +syn keyword ngxDirective contained sticky_cookie_insert +syn keyword ngxDirective contained stub_status +syn keyword ngxDirective contained sub_filter +syn keyword ngxDirective contained sub_filter_last_modified +syn keyword ngxDirective contained sub_filter_once +syn keyword ngxDirective contained sub_filter_types +syn keyword ngxDirective contained tcp_nodelay +syn keyword ngxDirective contained tcp_nopush +syn keyword ngxDirective contained thread_pool +syn keyword ngxDirective contained thread_stack_size +syn keyword ngxDirective contained timeout +syn keyword ngxDirective contained timer_resolution +syn keyword ngxDirective contained types_hash_bucket_size +syn keyword ngxDirective contained types_hash_max_size +syn keyword ngxDirective contained underscores_in_headers +syn keyword ngxDirective contained uninitialized_variable_warn +syn keyword ngxDirective contained upstream_conf +syn keyword ngxDirective contained use +syn keyword ngxDirective contained user +syn keyword ngxDirective contained userid +syn keyword ngxDirective contained userid_domain +syn keyword ngxDirective contained userid_expires +syn keyword ngxDirective contained userid_mark +syn keyword ngxDirective contained userid_name +syn keyword ngxDirective contained userid_p3p +syn keyword ngxDirective contained userid_path +syn keyword ngxDirective contained userid_service +syn keyword ngxDirective contained uwsgi_bind +syn keyword ngxDirective contained uwsgi_buffer_size +syn keyword ngxDirective contained uwsgi_buffering +syn keyword ngxDirective contained uwsgi_buffers +syn keyword ngxDirective contained uwsgi_busy_buffers_size +syn keyword ngxDirective contained uwsgi_cache +syn keyword ngxDirective contained uwsgi_cache_bypass +syn keyword ngxDirective contained uwsgi_cache_key +syn keyword ngxDirective contained uwsgi_cache_lock +syn keyword ngxDirective contained uwsgi_cache_lock_age +syn keyword ngxDirective contained uwsgi_cache_lock_timeout +syn keyword ngxDirective contained uwsgi_cache_methods +syn keyword ngxDirective contained uwsgi_cache_min_uses +syn keyword ngxDirective contained uwsgi_cache_path +syn keyword ngxDirective contained uwsgi_cache_purge +syn keyword ngxDirective contained uwsgi_cache_revalidate +syn keyword ngxDirective contained uwsgi_cache_use_stale +syn keyword ngxDirective contained uwsgi_cache_valid +syn keyword ngxDirective contained uwsgi_connect_timeout +syn keyword ngxDirective contained uwsgi_force_ranges +syn keyword ngxDirective contained uwsgi_hide_header +syn keyword ngxDirective contained uwsgi_ignore_client_abort +syn keyword ngxDirective contained uwsgi_ignore_headers +syn keyword ngxDirective contained uwsgi_intercept_errors +syn keyword ngxDirective contained uwsgi_limit_rate +syn keyword ngxDirective contained uwsgi_max_temp_file_size +syn keyword ngxDirective contained uwsgi_modifier1 +syn keyword ngxDirective contained uwsgi_modifier2 +syn keyword ngxDirective contained uwsgi_next_upstream +syn keyword ngxDirective contained uwsgi_next_upstream_timeout +syn keyword ngxDirective contained uwsgi_next_upstream_tries +syn keyword ngxDirective contained uwsgi_no_cache +syn keyword ngxDirective contained uwsgi_param +syn keyword ngxDirective contained uwsgi_pass +syn keyword ngxDirective contained uwsgi_pass_header +syn keyword ngxDirective contained uwsgi_pass_request_body +syn keyword ngxDirective contained uwsgi_pass_request_headers +syn keyword ngxDirective contained uwsgi_read_timeout +syn keyword ngxDirective contained uwsgi_request_buffering +syn keyword ngxDirective contained uwsgi_send_timeout +syn keyword ngxDirective contained uwsgi_ssl_certificate +syn keyword ngxDirective contained uwsgi_ssl_certificate_key +syn keyword ngxDirective contained uwsgi_ssl_ciphers +syn keyword ngxDirective contained uwsgi_ssl_crl +syn keyword ngxDirective contained uwsgi_ssl_name +syn keyword ngxDirective contained uwsgi_ssl_password_file +syn keyword ngxDirective contained uwsgi_ssl_protocols +syn keyword ngxDirective contained uwsgi_ssl_server_name +syn keyword ngxDirective contained uwsgi_ssl_session_reuse +syn keyword ngxDirective contained uwsgi_ssl_trusted_certificate +syn keyword ngxDirective contained uwsgi_ssl_verify +syn keyword ngxDirective contained uwsgi_ssl_verify_depth +syn keyword ngxDirective contained uwsgi_store +syn keyword ngxDirective contained uwsgi_store_access +syn keyword ngxDirective contained uwsgi_string +syn keyword ngxDirective contained uwsgi_temp_file_write_size +syn keyword ngxDirective contained uwsgi_temp_path +syn keyword ngxDirective contained valid_referers +syn keyword ngxDirective contained variables_hash_bucket_size +syn keyword ngxDirective contained variables_hash_max_size +syn keyword ngxDirective contained worker_aio_requests +syn keyword ngxDirective contained worker_connections +syn keyword ngxDirective contained worker_cpu_affinity +syn keyword ngxDirective contained worker_priority +syn keyword ngxDirective contained worker_processes +syn keyword ngxDirective contained worker_rlimit_core +syn keyword ngxDirective contained worker_rlimit_nofile +syn keyword ngxDirective contained worker_rlimit_sigpending +syn keyword ngxDirective contained worker_threads +syn keyword ngxDirective contained working_directory +syn keyword ngxDirective contained xclient +syn keyword ngxDirective contained xml_entities +syn keyword ngxDirective contained xslt_last_modified +syn keyword ngxDirective contained xslt_param +syn keyword ngxDirective contained xslt_string_param +syn keyword ngxDirective contained xslt_stylesheet +syn keyword ngxDirective contained xslt_types +syn keyword ngxDirective contained zone " 3rd party module list: -" http://wiki.nginx.org/Nginx3rdPartyModules +" https://www.nginx.com/resources/wiki/modules/ -" Accept Language Module +" Accept Language Module " Parses the Accept-Language header and gives the most suitable locale from a list of supported locales. -syn keyword ngxDirectiveThirdParty set_from_accept_language +syn keyword ngxDirectiveThirdParty contained set_from_accept_language -" Access Key Module +" Access Key Module (DEPRECATED) " Denies access unless the request URL contains an access key. -syn keyword ngxDirectiveThirdParty accesskey -syn keyword ngxDirectiveThirdParty accesskey_arg -syn keyword ngxDirectiveThirdParty accesskey_hashmethod -syn keyword ngxDirectiveThirdParty accesskey_signature +syn keyword ngxDirectiveDeprecated contained accesskey +syn keyword ngxDirectiveDeprecated contained accesskey_arg +syn keyword ngxDirectiveDeprecated contained accesskey_hashmethod +syn keyword ngxDirectiveDeprecated contained accesskey_signature -" Auth PAM Module -" HTTP Basic Authentication using PAM. -syn keyword ngxDirectiveThirdParty auth_pam -syn keyword ngxDirectiveThirdParty auth_pam_service_name +" Asynchronous FastCGI Module +" Primarily a modified version of the Nginx FastCGI module which implements multiplexing of connections, allowing a single FastCGI server to handle many concurrent requests. +" syn keyword ngxDirectiveThirdParty contained fastcgi_bind +" syn keyword ngxDirectiveThirdParty contained fastcgi_buffer_size +" syn keyword ngxDirectiveThirdParty contained fastcgi_buffers +" syn keyword ngxDirectiveThirdParty contained fastcgi_busy_buffers_size +" syn keyword ngxDirectiveThirdParty contained fastcgi_cache +" syn keyword ngxDirectiveThirdParty contained fastcgi_cache_key +" syn keyword ngxDirectiveThirdParty contained fastcgi_cache_methods +" syn keyword ngxDirectiveThirdParty contained fastcgi_cache_min_uses +" syn keyword ngxDirectiveThirdParty contained fastcgi_cache_path +" syn keyword ngxDirectiveThirdParty contained fastcgi_cache_use_stale +" syn keyword ngxDirectiveThirdParty contained fastcgi_cache_valid +" syn keyword ngxDirectiveThirdParty contained fastcgi_catch_stderr +" syn keyword ngxDirectiveThirdParty contained fastcgi_connect_timeout +" syn keyword ngxDirectiveThirdParty contained fastcgi_hide_header +" syn keyword ngxDirectiveThirdParty contained fastcgi_ignore_client_abort +" syn keyword ngxDirectiveThirdParty contained fastcgi_ignore_headers +" syn keyword ngxDirectiveThirdParty contained fastcgi_index +" syn keyword ngxDirectiveThirdParty contained fastcgi_intercept_errors +" syn keyword ngxDirectiveThirdParty contained fastcgi_max_temp_file_size +" syn keyword ngxDirectiveThirdParty contained fastcgi_next_upstream +" syn keyword ngxDirectiveThirdParty contained fastcgi_param +" syn keyword ngxDirectiveThirdParty contained fastcgi_pass +" syn keyword ngxDirectiveThirdParty contained fastcgi_pass_header +" syn keyword ngxDirectiveThirdParty contained fastcgi_pass_request_body +" syn keyword ngxDirectiveThirdParty contained fastcgi_pass_request_headers +" syn keyword ngxDirectiveThirdParty contained fastcgi_read_timeout +" syn keyword ngxDirectiveThirdParty contained fastcgi_send_lowat +" syn keyword ngxDirectiveThirdParty contained fastcgi_send_timeout +" syn keyword ngxDirectiveThirdParty contained fastcgi_split_path_info +" syn keyword ngxDirectiveThirdParty contained fastcgi_store +" syn keyword ngxDirectiveThirdParty contained fastcgi_store_access +" syn keyword ngxDirectiveThirdParty contained fastcgi_temp_file_write_size +" syn keyword ngxDirectiveThirdParty contained fastcgi_temp_path +syn keyword ngxDirectiveDeprecated contained fastcgi_upstream_fail_timeout +syn keyword ngxDirectiveDeprecated contained fastcgi_upstream_max_fails -" Cache Purge Module -" Module adding ability to purge content from FastCGI and proxy caches. -syn keyword ngxDirectiveThirdParty fastcgi_cache_purge -syn keyword ngxDirectiveThirdParty proxy_cache_purge +" Akamai G2O Module +" Nginx Module for Authenticating Akamai G2O requests +syn keyword ngxDirectiveThirdParty contained g2o +syn keyword ngxDirectiveThirdParty contained g2o_nonce +syn keyword ngxDirectiveThirdParty contained g2o_key -" Chunkin Module +" Lua Module +" You can be very simple to execute lua code for nginx +syn keyword ngxDirectiveThirdParty contained lua_file + +" Array Variable Module +" Add support for array-typed variables to nginx config files +syn keyword ngxDirectiveThirdParty contained array_split +syn keyword ngxDirectiveThirdParty contained array_join +syn keyword ngxDirectiveThirdParty contained array_map +syn keyword ngxDirectiveThirdParty contained array_map_op + +" Nginx Audio Track for HTTP Live Streaming +" This nginx module generates audio track for hls streams on the fly. +syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track +syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track_rootpath +syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track_output_format +syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track_output_header + +" AWS Proxy Module +" Nginx module to proxy to authenticated AWS services +syn keyword ngxDirectiveThirdParty contained aws_access_key +syn keyword ngxDirectiveThirdParty contained aws_key_scope +syn keyword ngxDirectiveThirdParty contained aws_signing_key +syn keyword ngxDirectiveThirdParty contained aws_endpoint +syn keyword ngxDirectiveThirdParty contained aws_s3_bucket +syn keyword ngxDirectiveThirdParty contained aws_sign + +" Backtrace module +" A Nginx module to dump backtrace when a worker process exits abnormally +syn keyword ngxDirectiveThirdParty contained backtrace_log +syn keyword ngxDirectiveThirdParty contained backtrace_max_stack_size + +" Brotli Module +" Nginx module for Brotli compression +syn keyword ngxDirectiveThirdParty contained brotli_static +syn keyword ngxDirectiveThirdParty contained brotli +syn keyword ngxDirectiveThirdParty contained brotli_types +syn keyword ngxDirectiveThirdParty contained brotli_buffers +syn keyword ngxDirectiveThirdParty contained brotli_comp_level +syn keyword ngxDirectiveThirdParty contained brotli_window +syn keyword ngxDirectiveThirdParty contained brotli_min_length + +" Cache Purge Module +" Adds ability to purge content from FastCGI, proxy, SCGI and uWSGI caches. +syn keyword ngxDirectiveThirdParty contained fastcgi_cache_purge +syn keyword ngxDirectiveThirdParty contained proxy_cache_purge +" syn keyword ngxDirectiveThirdParty contained scgi_cache_purge +" syn keyword ngxDirectiveThirdParty contained uwsgi_cache_purge + +" Chunkin Module (DEPRECATED) " HTTP 1.1 chunked-encoding request body support for Nginx. -syn keyword ngxDirectiveThirdParty chunkin -syn keyword ngxDirectiveThirdParty chunkin_keepalive -syn keyword ngxDirectiveThirdParty chunkin_max_chunks_per_buf -syn keyword ngxDirectiveThirdParty chunkin_resume +syn keyword ngxDirectiveDeprecated contained chunkin +syn keyword ngxDirectiveDeprecated contained chunkin_keepalive +syn keyword ngxDirectiveDeprecated contained chunkin_max_chunks_per_buf +syn keyword ngxDirectiveDeprecated contained chunkin_resume -" Circle GIF Module +" Circle GIF Module " Generates simple circle images with the colors and size specified in the URL. -syn keyword ngxDirectiveThirdParty circle_gif -syn keyword ngxDirectiveThirdParty circle_gif_max_radius -syn keyword ngxDirectiveThirdParty circle_gif_min_radius -syn keyword ngxDirectiveThirdParty circle_gif_step_radius +syn keyword ngxDirectiveThirdParty contained circle_gif +syn keyword ngxDirectiveThirdParty contained circle_gif_max_radius +syn keyword ngxDirectiveThirdParty contained circle_gif_min_radius +syn keyword ngxDirectiveThirdParty contained circle_gif_step_radius -" Drizzle Module -" Make nginx talk directly to mysql, drizzle, and sqlite3 by libdrizzle. -syn keyword ngxDirectiveThirdParty drizzle_connect_timeout -syn keyword ngxDirectiveThirdParty drizzle_dbname -syn keyword ngxDirectiveThirdParty drizzle_keepalive -syn keyword ngxDirectiveThirdParty drizzle_module_header -syn keyword ngxDirectiveThirdParty drizzle_pass -syn keyword ngxDirectiveThirdParty drizzle_query -syn keyword ngxDirectiveThirdParty drizzle_recv_cols_timeout -syn keyword ngxDirectiveThirdParty drizzle_recv_rows_timeout -syn keyword ngxDirectiveThirdParty drizzle_send_query_timeout -syn keyword ngxDirectiveThirdParty drizzle_server +" Nginx-Clojure Module +" Parses the Accept-Language header and gives the most suitable locale from a list of supported locales. +syn keyword ngxDirectiveThirdParty contained jvm_path +syn keyword ngxDirectiveThirdParty contained jvm_var +syn keyword ngxDirectiveThirdParty contained jvm_classpath +syn keyword ngxDirectiveThirdParty contained jvm_classpath_check +syn keyword ngxDirectiveThirdParty contained jvm_workers +syn keyword ngxDirectiveThirdParty contained jvm_options +syn keyword ngxDirectiveThirdParty contained jvm_handler_type +syn keyword ngxDirectiveThirdParty contained jvm_init_handler_name +syn keyword ngxDirectiveThirdParty contained jvm_init_handler_code +syn keyword ngxDirectiveThirdParty contained jvm_exit_handler_name +syn keyword ngxDirectiveThirdParty contained jvm_exit_handler_code +syn keyword ngxDirectiveThirdParty contained handlers_lazy_init +syn keyword ngxDirectiveThirdParty contained auto_upgrade_ws +syn keyword ngxDirectiveThirdParty contained content_handler_type +syn keyword ngxDirectiveThirdParty contained content_handler_name +syn keyword ngxDirectiveThirdParty contained content_handler_code +syn keyword ngxDirectiveThirdParty contained rewrite_handler_type +syn keyword ngxDirectiveThirdParty contained rewrite_handler_name +syn keyword ngxDirectiveThirdParty contained rewrite_handler_code +syn keyword ngxDirectiveThirdParty contained access_handler_type +syn keyword ngxDirectiveThirdParty contained access_handler_name +syn keyword ngxDirectiveThirdParty contained access_handler_code +syn keyword ngxDirectiveThirdParty contained header_filter_type +syn keyword ngxDirectiveThirdParty contained header_filter_name +syn keyword ngxDirectiveThirdParty contained header_filter_code +syn keyword ngxDirectiveThirdParty contained content_handler_property +syn keyword ngxDirectiveThirdParty contained rewrite_handler_property +syn keyword ngxDirectiveThirdParty contained access_handler_property +syn keyword ngxDirectiveThirdParty contained header_filter_property +syn keyword ngxDirectiveThirdParty contained always_read_body +syn keyword ngxDirectiveThirdParty contained shared_map +syn keyword ngxDirectiveThirdParty contained write_page_size -" Echo Module -" Brings 'echo', 'sleep', 'time', 'exec' and more shell-style goodies to Nginx config file. -syn keyword ngxDirectiveThirdParty echo -syn keyword ngxDirectiveThirdParty echo_after_body -syn keyword ngxDirectiveThirdParty echo_before_body -syn keyword ngxDirectiveThirdParty echo_blocking_sleep -syn keyword ngxDirectiveThirdParty echo_duplicate -syn keyword ngxDirectiveThirdParty echo_end -syn keyword ngxDirectiveThirdParty echo_exec -syn keyword ngxDirectiveThirdParty echo_flush -syn keyword ngxDirectiveThirdParty echo_foreach_split -syn keyword ngxDirectiveThirdParty echo_location -syn keyword ngxDirectiveThirdParty echo_location_async -syn keyword ngxDirectiveThirdParty echo_read_request_body -syn keyword ngxDirectiveThirdParty echo_request_body -syn keyword ngxDirectiveThirdParty echo_reset_timer -syn keyword ngxDirectiveThirdParty echo_sleep -syn keyword ngxDirectiveThirdParty echo_subrequest -syn keyword ngxDirectiveThirdParty echo_subrequest_async +" Upstream Consistent Hash +" A load balancer that uses an internal consistent hash ring to select the right backend node. +syn keyword ngxDirectiveThirdParty contained consistent_hash -" Events Module +" Nginx Development Kit +" The NDK is an Nginx module that is designed to extend the core functionality of the excellent Nginx webserver in a way that can be used as a basis of other Nginx modules. +" NDK_UPSTREAM_LIST +" This submodule provides a directive that creates a list of upstreams, with optional weighting. This list can then be used by other modules to hash over the upstreams however they choose. +syn keyword ngxDirectiveThirdParty contained upstream_list + +" Drizzle Module +" Upstream module for talking to MySQL and Drizzle directly +syn keyword ngxDirectiveThirdParty contained drizzle_server +syn keyword ngxDirectiveThirdParty contained drizzle_keepalive +syn keyword ngxDirectiveThirdParty contained drizzle_query +syn keyword ngxDirectiveThirdParty contained drizzle_pass +syn keyword ngxDirectiveThirdParty contained drizzle_connect_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_send_query_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_recv_cols_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_recv_rows_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_buffer_size +syn keyword ngxDirectiveThirdParty contained drizzle_module_header +syn keyword ngxDirectiveThirdParty contained drizzle_status + +" Dynamic ETags Module +" Attempt at handling ETag / If-None-Match on proxied content. +syn keyword ngxDirectiveThirdParty contained dynamic_etags + +" Echo Module +" Bringing the power of "echo", "sleep", "time" and more to Nginx's config file +syn keyword ngxDirectiveThirdParty contained echo +syn keyword ngxDirectiveThirdParty contained echo_duplicate +syn keyword ngxDirectiveThirdParty contained echo_flush +syn keyword ngxDirectiveThirdParty contained echo_sleep +syn keyword ngxDirectiveThirdParty contained echo_blocking_sleep +syn keyword ngxDirectiveThirdParty contained echo_reset_timer +syn keyword ngxDirectiveThirdParty contained echo_read_request_body +syn keyword ngxDirectiveThirdParty contained echo_location_async +syn keyword ngxDirectiveThirdParty contained echo_location +syn keyword ngxDirectiveThirdParty contained echo_subrequest_async +syn keyword ngxDirectiveThirdParty contained echo_subrequest +syn keyword ngxDirectiveThirdParty contained echo_foreach_split +syn keyword ngxDirectiveThirdParty contained echo_end +syn keyword ngxDirectiveThirdParty contained echo_request_body +syn keyword ngxDirectiveThirdParty contained echo_exec +syn keyword ngxDirectiveThirdParty contained echo_status +syn keyword ngxDirectiveThirdParty contained echo_before_body +syn keyword ngxDirectiveThirdParty contained echo_after_body + +" Encrypted Session Module +" Encrypt and decrypt nginx variable values +syn keyword ngxDirectiveThirdParty contained encrypted_session_key +syn keyword ngxDirectiveThirdParty contained encrypted_session_iv +syn keyword ngxDirectiveThirdParty contained encrypted_session_expires +syn keyword ngxDirectiveThirdParty contained set_encrypt_session +syn keyword ngxDirectiveThirdParty contained set_decrypt_session + +" Enhanced Memcached Module +" This module is based on the standard Nginx Memcached module, with some additonal features +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_pass +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_hash_keys_with_md5 +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_allow_put +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_allow_delete +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_stats +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_flush +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_flush_namespace +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_bind +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_connect_timeout +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_send_timeout +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_buffer_size +syn keyword ngxDirectiveThirdParty contained enhanced_memcached_read_timeout + +" Events Module (DEPRECATED) " Provides options for start/stop events. -syn keyword ngxDirectiveThirdParty on_start -syn keyword ngxDirectiveThirdParty on_stop +syn keyword ngxDirectiveDeprecated contained on_start +syn keyword ngxDirectiveDeprecated contained on_stop -" EY Balancer Module +" EY Balancer Module " Adds a request queue to Nginx that allows the limiting of concurrent requests passed to the upstream. -syn keyword ngxDirectiveThirdParty max_connections -syn keyword ngxDirectiveThirdParty max_connections_max_queue_length -syn keyword ngxDirectiveThirdParty max_connections_queue_timeout +syn keyword ngxDirectiveThirdParty contained max_connections +syn keyword ngxDirectiveThirdParty contained max_connections_max_queue_length +syn keyword ngxDirectiveThirdParty contained max_connections_queue_timeout -" Fancy Indexes Module +" Upstream Fair Balancer +" Sends an incoming request to the least-busy backend server, rather than distributing requests round-robin. +syn keyword ngxDirectiveThirdParty contained fair +syn keyword ngxDirectiveThirdParty contained upstream_fair_shm_size + +" Fancy Indexes Module " Like the built-in autoindex module, but fancier. -syn keyword ngxDirectiveThirdParty fancyindex -syn keyword ngxDirectiveThirdParty fancyindex_exact_size -syn keyword ngxDirectiveThirdParty fancyindex_footer -syn keyword ngxDirectiveThirdParty fancyindex_header -syn keyword ngxDirectiveThirdParty fancyindex_localtime -syn keyword ngxDirectiveThirdParty fancyindex_readme -syn keyword ngxDirectiveThirdParty fancyindex_readme_mode +syn keyword ngxDirectiveThirdParty contained fancyindex +syn keyword ngxDirectiveThirdParty contained fancyindex_default_sort +syn keyword ngxDirectiveThirdParty contained fancyindex_directories_first +syn keyword ngxDirectiveThirdParty contained fancyindex_css_href +syn keyword ngxDirectiveThirdParty contained fancyindex_exact_size +syn keyword ngxDirectiveThirdParty contained fancyindex_name_length +syn keyword ngxDirectiveThirdParty contained fancyindex_footer +syn keyword ngxDirectiveThirdParty contained fancyindex_header +syn keyword ngxDirectiveThirdParty contained fancyindex_show_path +syn keyword ngxDirectiveThirdParty contained fancyindex_ignore +syn keyword ngxDirectiveThirdParty contained fancyindex_hide_symlinks +syn keyword ngxDirectiveThirdParty contained fancyindex_localtime +syn keyword ngxDirectiveThirdParty contained fancyindex_time_format + +" Form Auth Module +" Provides authentication and authorization with credentials submitted via POST request +syn keyword ngxDirectiveThirdParty contained form_auth +syn keyword ngxDirectiveThirdParty contained form_auth_pam_service +syn keyword ngxDirectiveThirdParty contained form_auth_login +syn keyword ngxDirectiveThirdParty contained form_auth_password +syn keyword ngxDirectiveThirdParty contained form_auth_remote_user + +" Form Input Module +" Reads HTTP POST and PUT request body encoded in "application/x-www-form-urlencoded" and parses the arguments into nginx variables. +syn keyword ngxDirectiveThirdParty contained set_form_input +syn keyword ngxDirectiveThirdParty contained set_form_input_multi " GeoIP Module (DEPRECATED) " Country code lookups via the MaxMind GeoIP API. -syn keyword ngxDirectiveThirdParty geoip_country_file +syn keyword ngxDirectiveDeprecated contained geoip_country_file -" Headers More Module +" GeoIP 2 Module +" Creates variables with values from the maxmind geoip2 databases based on the client IP +syn keyword ngxDirectiveThirdParty contained geoip2 + +" GridFS Module +" Nginx module for serving files from MongoDB's GridFS +syn keyword ngxDirectiveThirdParty contained gridfs + +" Headers More Module " Set and clear input and output headers...more than "add"! -syn keyword ngxDirectiveThirdParty more_clear_headers -syn keyword ngxDirectiveThirdParty more_clear_input_headers -syn keyword ngxDirectiveThirdParty more_set_headers -syn keyword ngxDirectiveThirdParty more_set_input_headers +syn keyword ngxDirectiveThirdParty contained more_clear_headers +syn keyword ngxDirectiveThirdParty contained more_clear_input_headers +syn keyword ngxDirectiveThirdParty contained more_set_headers +syn keyword ngxDirectiveThirdParty contained more_set_input_headers -" HTTP Push Module -" Turn Nginx into an adept long-polling HTTP Push (Comet) server. -syn keyword ngxDirectiveThirdParty push_buffer_size -syn keyword ngxDirectiveThirdParty push_listener -syn keyword ngxDirectiveThirdParty push_message_timeout -syn keyword ngxDirectiveThirdParty push_queue_messages -syn keyword ngxDirectiveThirdParty push_sender +" Health Checks Upstreams Module +" Polls backends and if they respond with HTTP 200 + an optional request body, they are marked good. Otherwise, they are marked bad. +syn keyword ngxDirectiveThirdParty contained healthcheck_enabled +syn keyword ngxDirectiveThirdParty contained healthcheck_delay +syn keyword ngxDirectiveThirdParty contained healthcheck_timeout +syn keyword ngxDirectiveThirdParty contained healthcheck_failcount +syn keyword ngxDirectiveThirdParty contained healthcheck_send +syn keyword ngxDirectiveThirdParty contained healthcheck_expected +syn keyword ngxDirectiveThirdParty contained healthcheck_buffer +syn keyword ngxDirectiveThirdParty contained healthcheck_status -" HTTP Redis Module > -" Redis support.> -syn keyword ngxDirectiveThirdParty redis_bind -syn keyword ngxDirectiveThirdParty redis_buffer_size -syn keyword ngxDirectiveThirdParty redis_connect_timeout -syn keyword ngxDirectiveThirdParty redis_next_upstream -syn keyword ngxDirectiveThirdParty redis_pass -syn keyword ngxDirectiveThirdParty redis_read_timeout -syn keyword ngxDirectiveThirdParty redis_send_timeout +" HTTP Accounting Module +" Add traffic stat function to nginx. Useful for http accounting based on nginx configuration logic +syn keyword ngxDirectiveThirdParty contained http_accounting +syn keyword ngxDirectiveThirdParty contained http_accounting_log +syn keyword ngxDirectiveThirdParty contained http_accounting_id +syn keyword ngxDirectiveThirdParty contained http_accounting_interval +syn keyword ngxDirectiveThirdParty contained http_accounting_perturb -" HTTP JavaScript Module +" Nginx Digest Authentication module +" Digest Authentication for Nginx +syn keyword ngxDirectiveThirdParty contained auth_digest +syn keyword ngxDirectiveThirdParty contained auth_digest_user_file +syn keyword ngxDirectiveThirdParty contained auth_digest_timeout +syn keyword ngxDirectiveThirdParty contained auth_digest_expires +syn keyword ngxDirectiveThirdParty contained auth_digest_replays +syn keyword ngxDirectiveThirdParty contained auth_digest_shm_size + +" Auth PAM Module +" HTTP Basic Authentication using PAM. +syn keyword ngxDirectiveThirdParty contained auth_pam +syn keyword ngxDirectiveThirdParty contained auth_pam_service_name + +" HTTP Auth Request Module +" Implements client authorization based on the result of a subrequest +" syn keyword ngxDirectiveThirdParty contained auth_request +" syn keyword ngxDirectiveThirdParty contained auth_request_set + +" HTTP Concatenation module for Nginx +" A Nginx module for concatenating files in a given context: CSS and JS files usually +syn keyword ngxDirectiveThirdParty contained concat +syn keyword ngxDirectiveThirdParty contained concat_types +syn keyword ngxDirectiveThirdParty contained concat_unique +syn keyword ngxDirectiveThirdParty contained concat_max_files +syn keyword ngxDirectiveThirdParty contained concat_delimiter +syn keyword ngxDirectiveThirdParty contained concat_ignore_file_error + +" HTTP Dynamic Upstream Module +" Update upstreams' config by restful interface +syn keyword ngxDirectiveThirdParty contained dyups_interface +syn keyword ngxDirectiveThirdParty contained dyups_read_msg_timeout +syn keyword ngxDirectiveThirdParty contained dyups_shm_zone_size +syn keyword ngxDirectiveThirdParty contained dyups_upstream_conf +syn keyword ngxDirectiveThirdParty contained dyups_trylock + +" HTTP Footer If Filter Module +" The ngx_http_footer_if_filter_module is used to add given content to the end of the response according to the condition specified. +syn keyword ngxDirectiveThirdParty contained footer_if + +" HTTP Footer Filter Module +" This module implements a body filter that adds a given string to the page footer. +syn keyword ngxDirectiveThirdParty contained footer +syn keyword ngxDirectiveThirdParty contained footer_types + +" HTTP Internal Redirect Module +" Make an internal redirect to the uri specified according to the condition specified. +syn keyword ngxDirectiveThirdParty contained internal_redirect_if +syn keyword ngxDirectiveThirdParty contained internal_redirect_if_no_postponed + +" HTTP JavaScript Module " Embedding SpiderMonkey. Nearly full port on Perl module. -syn keyword ngxDirectiveThirdParty js -syn keyword ngxDirectiveThirdParty js_filter -syn keyword ngxDirectiveThirdParty js_filter_types -syn keyword ngxDirectiveThirdParty js_load -syn keyword ngxDirectiveThirdParty js_maxmem -syn keyword ngxDirectiveThirdParty js_require -syn keyword ngxDirectiveThirdParty js_set -syn keyword ngxDirectiveThirdParty js_utf8 +syn keyword ngxDirectiveThirdParty contained js +syn keyword ngxDirectiveThirdParty contained js_filter +syn keyword ngxDirectiveThirdParty contained js_filter_types +syn keyword ngxDirectiveThirdParty contained js_load +syn keyword ngxDirectiveThirdParty contained js_maxmem +syn keyword ngxDirectiveThirdParty contained js_require +syn keyword ngxDirectiveThirdParty contained js_set +syn keyword ngxDirectiveThirdParty contained js_utf8 -" Log Request Speed +" HTTP Push Module (DEPRECATED) +" Turn Nginx into an adept long-polling HTTP Push (Comet) server. +syn keyword ngxDirectiveDeprecated contained push_buffer_size +syn keyword ngxDirectiveDeprecated contained push_listener +syn keyword ngxDirectiveDeprecated contained push_message_timeout +syn keyword ngxDirectiveDeprecated contained push_queue_messages +syn keyword ngxDirectiveDeprecated contained push_sender + +" HTTP Redis Module +" Redis support. +syn keyword ngxDirectiveThirdParty contained redis_bind +syn keyword ngxDirectiveThirdParty contained redis_buffer_size +syn keyword ngxDirectiveThirdParty contained redis_connect_timeout +syn keyword ngxDirectiveThirdParty contained redis_next_upstream +syn keyword ngxDirectiveThirdParty contained redis_pass +syn keyword ngxDirectiveThirdParty contained redis_read_timeout +syn keyword ngxDirectiveThirdParty contained redis_send_timeout + +" Iconv Module +" A character conversion nginx module using libiconv +syn keyword ngxDirectiveThirdParty contained set_iconv +syn keyword ngxDirectiveThirdParty contained iconv_buffer_size +syn keyword ngxDirectiveThirdParty contained iconv_filter + +" IP Blocker Module +" An efficient shared memory IP blocking system for nginx. +syn keyword ngxDirectiveThirdParty contained ip_blocker + +" IP2Location Module +" Allows user to lookup for geolocation information using IP2Location database +syn keyword ngxDirectiveThirdParty contained ip2location_database + +" JS Module +" Reflect the nginx functionality in JS +syn keyword ngxDirectiveThirdParty contained js +syn keyword ngxDirectiveThirdParty contained js_access +syn keyword ngxDirectiveThirdParty contained js_load +syn keyword ngxDirectiveThirdParty contained js_set + +" Limit Upload Rate Module +" Limit client-upload rate when they are sending request bodies to you +syn keyword ngxDirectiveThirdParty contained limit_upload_rate +syn keyword ngxDirectiveThirdParty contained limit_upload_rate_after + +" Limit Upstream Module +" Limit the number of connections to upstream for NGINX +syn keyword ngxDirectiveThirdParty contained limit_upstream_zone +syn keyword ngxDirectiveThirdParty contained limit_upstream_conn +syn keyword ngxDirectiveThirdParty contained limit_upstream_log_level + +" Log If Module +" Conditional accesslog for nginx +syn keyword ngxDirectiveThirdParty contained access_log_bypass_if + +" Log Request Speed (DEPRECATED) " Log the time it took to process each request. -syn keyword ngxDirectiveThirdParty log_request_speed_filter -syn keyword ngxDirectiveThirdParty log_request_speed_filter_timeout +syn keyword ngxDirectiveDeprecated contained log_request_speed_filter +syn keyword ngxDirectiveDeprecated contained log_request_speed_filter_timeout -" Memc Module +" Log ZeroMQ Module +" ZeroMQ logger module for nginx +syn keyword ngxDirectiveThirdParty contained log_zmq_server +syn keyword ngxDirectiveThirdParty contained log_zmq_endpoint +syn keyword ngxDirectiveThirdParty contained log_zmq_format +syn keyword ngxDirectiveThirdParty contained log_zmq_off + +" Lower/UpperCase Module +" This module simply uppercases or lowercases a string and saves it into a new variable. +syn keyword ngxDirectiveThirdParty contained lower +syn keyword ngxDirectiveThirdParty contained upper + +" Lua Upstream Module +" Nginx C module to expose Lua API to ngx_lua for Nginx upstreams + +" Lua Module +" Embed the Power of Lua into NGINX HTTP servers +syn keyword ngxDirectiveThirdParty contained lua_use_default_type +syn keyword ngxDirectiveThirdParty contained lua_malloc_trim +syn keyword ngxDirectiveThirdParty contained lua_code_cache +syn keyword ngxDirectiveThirdParty contained lua_regex_cache_max_entries +syn keyword ngxDirectiveThirdParty contained lua_regex_match_limit +syn keyword ngxDirectiveThirdParty contained lua_package_path +syn keyword ngxDirectiveThirdParty contained lua_package_cpath +syn keyword ngxDirectiveThirdParty contained init_by_lua +syn keyword ngxDirectiveThirdParty contained init_by_lua_block +syn keyword ngxDirectiveThirdParty contained init_by_lua_file +syn keyword ngxDirectiveThirdParty contained init_worker_by_lua +syn keyword ngxDirectiveThirdParty contained init_worker_by_lua_block +syn keyword ngxDirectiveThirdParty contained init_worker_by_lua_file +syn keyword ngxDirectiveThirdParty contained set_by_lua +syn keyword ngxDirectiveThirdParty contained set_by_lua_block +syn keyword ngxDirectiveThirdParty contained set_by_lua_file +syn keyword ngxDirectiveThirdParty contained content_by_lua +syn keyword ngxDirectiveThirdParty contained content_by_lua_block +syn keyword ngxDirectiveThirdParty contained content_by_lua_file +syn keyword ngxDirectiveThirdParty contained rewrite_by_lua +syn keyword ngxDirectiveThirdParty contained rewrite_by_lua_block +syn keyword ngxDirectiveThirdParty contained rewrite_by_lua_file +syn keyword ngxDirectiveThirdParty contained access_by_lua +syn keyword ngxDirectiveThirdParty contained access_by_lua_block +syn keyword ngxDirectiveThirdParty contained access_by_lua_file +syn keyword ngxDirectiveThirdParty contained header_filter_by_lua +syn keyword ngxDirectiveThirdParty contained header_filter_by_lua_block +syn keyword ngxDirectiveThirdParty contained header_filter_by_lua_file +syn keyword ngxDirectiveThirdParty contained body_filter_by_lua +syn keyword ngxDirectiveThirdParty contained body_filter_by_lua_block +syn keyword ngxDirectiveThirdParty contained body_filter_by_lua_file +syn keyword ngxDirectiveThirdParty contained log_by_lua +syn keyword ngxDirectiveThirdParty contained log_by_lua_block +syn keyword ngxDirectiveThirdParty contained log_by_lua_file +syn keyword ngxDirectiveThirdParty contained balancer_by_lua_block +syn keyword ngxDirectiveThirdParty contained balancer_by_lua_file +syn keyword ngxDirectiveThirdParty contained lua_need_request_body +syn keyword ngxDirectiveThirdParty contained ssl_certificate_by_lua_block +syn keyword ngxDirectiveThirdParty contained ssl_certificate_by_lua_file +syn keyword ngxDirectiveThirdParty contained ssl_session_fetch_by_lua_block +syn keyword ngxDirectiveThirdParty contained ssl_session_fetch_by_lua_file +syn keyword ngxDirectiveThirdParty contained ssl_session_store_by_lua_block +syn keyword ngxDirectiveThirdParty contained ssl_session_store_by_lua_file +syn keyword ngxDirectiveThirdParty contained lua_shared_dict +syn keyword ngxDirectiveThirdParty contained lua_socket_connect_timeout +syn keyword ngxDirectiveThirdParty contained lua_socket_send_timeout +syn keyword ngxDirectiveThirdParty contained lua_socket_send_lowat +syn keyword ngxDirectiveThirdParty contained lua_socket_read_timeout +syn keyword ngxDirectiveThirdParty contained lua_socket_buffer_size +syn keyword ngxDirectiveThirdParty contained lua_socket_pool_size +syn keyword ngxDirectiveThirdParty contained lua_socket_keepalive_timeout +syn keyword ngxDirectiveThirdParty contained lua_socket_log_errors +syn keyword ngxDirectiveThirdParty contained lua_ssl_ciphers +syn keyword ngxDirectiveThirdParty contained lua_ssl_crl +syn keyword ngxDirectiveThirdParty contained lua_ssl_protocols +syn keyword ngxDirectiveThirdParty contained lua_ssl_trusted_certificate +syn keyword ngxDirectiveThirdParty contained lua_ssl_verify_depth +syn keyword ngxDirectiveThirdParty contained lua_http10_buffering +syn keyword ngxDirectiveThirdParty contained rewrite_by_lua_no_postpone +syn keyword ngxDirectiveThirdParty contained access_by_lua_no_postpone +syn keyword ngxDirectiveThirdParty contained lua_transform_underscores_in_response_headers +syn keyword ngxDirectiveThirdParty contained lua_check_client_abort +syn keyword ngxDirectiveThirdParty contained lua_max_pending_timers +syn keyword ngxDirectiveThirdParty contained lua_max_running_timers + +" MD5 Filter Module +" A content filter for nginx, which returns the md5 hash of the content otherwise returned. +syn keyword ngxDirectiveThirdParty contained md5_filter + +" Memc Module " An extended version of the standard memcached module that supports set, add, delete, and many more memcached commands. -syn keyword ngxDirectiveThirdParty memc_buffer_size -syn keyword ngxDirectiveThirdParty memc_cmds_allowed -syn keyword ngxDirectiveThirdParty memc_connect_timeout -syn keyword ngxDirectiveThirdParty memc_flags_to_last_modified -syn keyword ngxDirectiveThirdParty memc_next_upstream -syn keyword ngxDirectiveThirdParty memc_pass -syn keyword ngxDirectiveThirdParty memc_read_timeout -syn keyword ngxDirectiveThirdParty memc_send_timeout -syn keyword ngxDirectiveThirdParty memc_upstream_fail_timeout -syn keyword ngxDirectiveThirdParty memc_upstream_max_fails +syn keyword ngxDirectiveThirdParty contained memc_buffer_size +syn keyword ngxDirectiveThirdParty contained memc_cmds_allowed +syn keyword ngxDirectiveThirdParty contained memc_connect_timeout +syn keyword ngxDirectiveThirdParty contained memc_flags_to_last_modified +syn keyword ngxDirectiveThirdParty contained memc_next_upstream +syn keyword ngxDirectiveThirdParty contained memc_pass +syn keyword ngxDirectiveThirdParty contained memc_read_timeout +syn keyword ngxDirectiveThirdParty contained memc_send_timeout +syn keyword ngxDirectiveThirdParty contained memc_upstream_fail_timeout +syn keyword ngxDirectiveThirdParty contained memc_upstream_max_fails + +" Mod Security Module +" ModSecurity is an open source, cross platform web application firewall (WAF) engine +syn keyword ngxDirectiveThirdParty contained ModSecurityConfig +syn keyword ngxDirectiveThirdParty contained ModSecurityEnabled +syn keyword ngxDirectiveThirdParty contained pool_context +syn keyword ngxDirectiveThirdParty contained pool_context_hash_size " Mogilefs Module -" Implements a MogileFS client, provides a replace to the Perlbal reverse proxy of the original MogileFS. -syn keyword ngxDirectiveThirdParty mogilefs_connect_timeout -syn keyword ngxDirectiveThirdParty mogilefs_domain -syn keyword ngxDirectiveThirdParty mogilefs_methods -syn keyword ngxDirectiveThirdParty mogilefs_noverify -syn keyword ngxDirectiveThirdParty mogilefs_pass -syn keyword ngxDirectiveThirdParty mogilefs_read_timeout -syn keyword ngxDirectiveThirdParty mogilefs_send_timeout -syn keyword ngxDirectiveThirdParty mogilefs_tracker +" MogileFS client for nginx web server. +syn keyword ngxDirectiveThirdParty contained mogilefs_pass +syn keyword ngxDirectiveThirdParty contained mogilefs_methods +syn keyword ngxDirectiveThirdParty contained mogilefs_domain +syn keyword ngxDirectiveThirdParty contained mogilefs_class +syn keyword ngxDirectiveThirdParty contained mogilefs_tracker +syn keyword ngxDirectiveThirdParty contained mogilefs_noverify +syn keyword ngxDirectiveThirdParty contained mogilefs_connect_timeout +syn keyword ngxDirectiveThirdParty contained mogilefs_send_timeout +syn keyword ngxDirectiveThirdParty contained mogilefs_read_timeout -" MP4 Streaming Lite Module +" Mongo Module +" Upstream module that allows nginx to communicate directly with MongoDB database. +syn keyword ngxDirectiveThirdParty contained mongo_auth +syn keyword ngxDirectiveThirdParty contained mongo_pass +syn keyword ngxDirectiveThirdParty contained mongo_query +syn keyword ngxDirectiveThirdParty contained mongo_json +syn keyword ngxDirectiveThirdParty contained mongo_bind +syn keyword ngxDirectiveThirdParty contained mongo_connect_timeout +syn keyword ngxDirectiveThirdParty contained mongo_send_timeout +syn keyword ngxDirectiveThirdParty contained mongo_read_timeout +syn keyword ngxDirectiveThirdParty contained mongo_buffering +syn keyword ngxDirectiveThirdParty contained mongo_buffer_size +syn keyword ngxDirectiveThirdParty contained mongo_buffers +syn keyword ngxDirectiveThirdParty contained mongo_busy_buffers_size +syn keyword ngxDirectiveThirdParty contained mongo_next_upstream + +" MP4 Streaming Lite Module " Will seek to a certain time within H.264/MP4 files when provided with a 'start' parameter in the URL. -syn keyword ngxDirectiveThirdParty mp4 +" syn keyword ngxDirectiveThirdParty contained mp4 -" Nginx Notice Module +" NAXSI Module +" NAXSI is an open-source, high performance, low rules maintenance WAF for NGINX +syn keyword ngxDirectiveThirdParty contained DeniedUrl denied_url +syn keyword ngxDirectiveThirdParty contained LearningMode learning_mode +syn keyword ngxDirectiveThirdParty contained SecRulesEnabled rules_enabled +syn keyword ngxDirectiveThirdParty contained SecRulesDisabled rules_disabled +syn keyword ngxDirectiveThirdParty contained CheckRule check_rule +syn keyword ngxDirectiveThirdParty contained BasicRule basic_rule +syn keyword ngxDirectiveThirdParty contained MainRule main_rule +syn keyword ngxDirectiveThirdParty contained LibInjectionSql libinjection_sql +syn keyword ngxDirectiveThirdParty contained LibInjectionXss libinjection_xss + +" Nchan Module +" Fast, horizontally scalable, multiprocess pub/sub queuing server and proxy for HTTP, long-polling, Websockets and EventSource (SSE) +syn keyword ngxDirectiveThirdParty contained nchan_channel_id +syn keyword ngxDirectiveThirdParty contained nchan_channel_id_split_delimiter +syn keyword ngxDirectiveThirdParty contained nchan_eventsource_event +syn keyword ngxDirectiveThirdParty contained nchan_longpoll_multipart_response +syn keyword ngxDirectiveThirdParty contained nchan_publisher +syn keyword ngxDirectiveThirdParty contained nchan_publisher_channel_id +syn keyword ngxDirectiveThirdParty contained nchan_publisher_upstream_request +syn keyword ngxDirectiveThirdParty contained nchan_pubsub +syn keyword ngxDirectiveThirdParty contained nchan_subscribe_request +syn keyword ngxDirectiveThirdParty contained nchan_subscriber +syn keyword ngxDirectiveThirdParty contained nchan_subscriber_channel_id +syn keyword ngxDirectiveThirdParty contained nchan_subscriber_compound_etag_message_id +syn keyword ngxDirectiveThirdParty contained nchan_subscriber_first_message +syn keyword ngxDirectiveThirdParty contained nchan_subscriber_http_raw_stream_separator +syn keyword ngxDirectiveThirdParty contained nchan_subscriber_last_message_id +syn keyword ngxDirectiveThirdParty contained nchan_subscriber_message_id_custom_etag_header +syn keyword ngxDirectiveThirdParty contained nchan_subscriber_timeout +syn keyword ngxDirectiveThirdParty contained nchan_unsubscribe_request +syn keyword ngxDirectiveThirdParty contained nchan_websocket_ping_interval +syn keyword ngxDirectiveThirdParty contained nchan_authorize_request +syn keyword ngxDirectiveThirdParty contained nchan_max_reserved_memory +syn keyword ngxDirectiveThirdParty contained nchan_message_buffer_length +syn keyword ngxDirectiveThirdParty contained nchan_message_timeout +syn keyword ngxDirectiveThirdParty contained nchan_redis_idle_channel_cache_timeout +syn keyword ngxDirectiveThirdParty contained nchan_redis_namespace +syn keyword ngxDirectiveThirdParty contained nchan_redis_pass +syn keyword ngxDirectiveThirdParty contained nchan_redis_ping_interval +syn keyword ngxDirectiveThirdParty contained nchan_redis_server +syn keyword ngxDirectiveThirdParty contained nchan_redis_storage_mode +syn keyword ngxDirectiveThirdParty contained nchan_redis_url +syn keyword ngxDirectiveThirdParty contained nchan_store_messages +syn keyword ngxDirectiveThirdParty contained nchan_use_redis +syn keyword ngxDirectiveThirdParty contained nchan_access_control_allow_origin +syn keyword ngxDirectiveThirdParty contained nchan_channel_group +syn keyword ngxDirectiveThirdParty contained nchan_channel_group_accounting +syn keyword ngxDirectiveThirdParty contained nchan_group_location +syn keyword ngxDirectiveThirdParty contained nchan_group_max_channels +syn keyword ngxDirectiveThirdParty contained nchan_group_max_messages +syn keyword ngxDirectiveThirdParty contained nchan_group_max_messages_disk +syn keyword ngxDirectiveThirdParty contained nchan_group_max_messages_memory +syn keyword ngxDirectiveThirdParty contained nchan_group_max_subscribers +syn keyword ngxDirectiveThirdParty contained nchan_subscribe_existing_channels_only +syn keyword ngxDirectiveThirdParty contained nchan_channel_event_string +syn keyword ngxDirectiveThirdParty contained nchan_channel_events_channel_id +syn keyword ngxDirectiveThirdParty contained nchan_stub_status +syn keyword ngxDirectiveThirdParty contained nchan_max_channel_id_length +syn keyword ngxDirectiveThirdParty contained nchan_max_channel_subscribers +syn keyword ngxDirectiveThirdParty contained nchan_channel_timeout +syn keyword ngxDirectiveThirdParty contained nchan_storage_engine + +" Nginx Notice Module " Serve static file to POST requests. -syn keyword ngxDirectiveThirdParty notice -syn keyword ngxDirectiveThirdParty notice_type +syn keyword ngxDirectiveThirdParty contained notice +syn keyword ngxDirectiveThirdParty contained notice_type -" Phusion Passenger -" Easy and robust deployment of Ruby on Rails application on Apache and Nginx webservers. -syn keyword ngxDirectiveThirdParty passenger_base_uri -syn keyword ngxDirectiveThirdParty passenger_default_user -syn keyword ngxDirectiveThirdParty passenger_enabled -syn keyword ngxDirectiveThirdParty passenger_log_level -syn keyword ngxDirectiveThirdParty passenger_max_instances_per_app -syn keyword ngxDirectiveThirdParty passenger_max_pool_size -syn keyword ngxDirectiveThirdParty passenger_pool_idle_time -syn keyword ngxDirectiveThirdParty passenger_root -syn keyword ngxDirectiveThirdParty passenger_ruby -syn keyword ngxDirectiveThirdParty passenger_use_global_queue -syn keyword ngxDirectiveThirdParty passenger_user_switching -syn keyword ngxDirectiveThirdParty rack_env -syn keyword ngxDirectiveThirdParty rails_app_spawner_idle_time -syn keyword ngxDirectiveThirdParty rails_env -syn keyword ngxDirectiveThirdParty rails_framework_spawner_idle_time -syn keyword ngxDirectiveThirdParty rails_spawn_method +" OCSP Proxy Module +" Nginx OCSP processing module designed for response caching +syn keyword ngxDirectiveThirdParty contained ocsp_proxy +syn keyword ngxDirectiveThirdParty contained ocsp_cache_timeout -" RDS JSON Module -" Help ngx_drizzle and other DBD modules emit JSON data. -syn keyword ngxDirectiveThirdParty rds_json -syn keyword ngxDirectiveThirdParty rds_json_content_type -syn keyword ngxDirectiveThirdParty rds_json_format -syn keyword ngxDirectiveThirdParty rds_json_ret +" Eval Module +" Module for nginx web server evaluates response of proxy or memcached module into variables. +syn keyword ngxDirectiveThirdParty contained eval +syn keyword ngxDirectiveThirdParty contained eval_escalate +syn keyword ngxDirectiveThirdParty contained eval_buffer_size +syn keyword ngxDirectiveThirdParty contained eval_override_content_type +syn keyword ngxDirectiveThirdParty contained eval_subrequest_in_memory -" RRD Graph Module +" OpenSSL Version Module +" Nginx OpenSSL version check at startup +syn keyword ngxDirectiveThirdParty contained openssl_version_minimum +syn keyword ngxDirectiveThirdParty contained openssl_builddate_minimum + +" Owner Match Module +" Control access for specific owners and groups of files +syn keyword ngxDirectiveThirdParty contained omallow +syn keyword ngxDirectiveThirdParty contained omdeny + +" Accept Language Module +" Parses the Accept-Language header and gives the most suitable locale from a list of supported locales. +syn keyword ngxDirectiveThirdParty contained pagespeed + +" PHP Memcache Standard Balancer Module +" Loadbalancer that is compatible to the standard loadbalancer in the php-memcache module +syn keyword ngxDirectiveThirdParty contained hash_key + +" PHP Session Module +" Nginx module to parse php sessions +syn keyword ngxDirectiveThirdParty contained php_session_parse +syn keyword ngxDirectiveThirdParty contained php_session_strip_formatting + +" Phusion Passenger Module +" Passenger is an open source web application server. +syn keyword ngxDirectiveThirdParty contained passenger_root +syn keyword ngxDirectiveThirdParty contained passenger_enabled +syn keyword ngxDirectiveThirdParty contained passenger_base_uri +syn keyword ngxDirectiveThirdParty contained passenger_document_root +syn keyword ngxDirectiveThirdParty contained passenger_ruby +syn keyword ngxDirectiveThirdParty contained passenger_python +syn keyword ngxDirectiveThirdParty contained passenger_nodejs +syn keyword ngxDirectiveThirdParty contained passenger_meteor_app_settings +syn keyword ngxDirectiveThirdParty contained passenger_app_env +syn keyword ngxDirectiveThirdParty contained passenger_app_root +syn keyword ngxDirectiveThirdParty contained passenger_app_group_name +syn keyword ngxDirectiveThirdParty contained passenger_app_type +syn keyword ngxDirectiveThirdParty contained passenger_startup_file +syn keyword ngxDirectiveThirdParty contained passenger_restart_dir +syn keyword ngxDirectiveThirdParty contained passenger_spawn_method +syn keyword ngxDirectiveThirdParty contained passenger_env_var +syn keyword ngxDirectiveThirdParty contained passenger_load_shell_envvars +syn keyword ngxDirectiveThirdParty contained passenger_rolling_restarts +syn keyword ngxDirectiveThirdParty contained passenger_resist_deployment_errors +syn keyword ngxDirectiveThirdParty contained passenger_user_switching +syn keyword ngxDirectiveThirdParty contained passenger_user +syn keyword ngxDirectiveThirdParty contained passenger_group +syn keyword ngxDirectiveThirdParty contained passenger_default_user +syn keyword ngxDirectiveThirdParty contained passenger_default_group +syn keyword ngxDirectiveThirdParty contained passenger_show_version_in_header +syn keyword ngxDirectiveThirdParty contained passenger_friendly_error_pages +syn keyword ngxDirectiveThirdParty contained passenger_disable_security_update_check +syn keyword ngxDirectiveThirdParty contained passenger_security_update_check_proxy +syn keyword ngxDirectiveThirdParty contained passenger_max_pool_size +syn keyword ngxDirectiveThirdParty contained passenger_min_instances +syn keyword ngxDirectiveThirdParty contained passenger_max_instances +syn keyword ngxDirectiveThirdParty contained passenger_max_instances_per_app +syn keyword ngxDirectiveThirdParty contained passenger_pool_idle_time +syn keyword ngxDirectiveThirdParty contained passenger_max_preloader_idle_time +syn keyword ngxDirectiveThirdParty contained passenger_force_max_concurrent_requests_per_process +syn keyword ngxDirectiveThirdParty contained passenger_start_timeout +syn keyword ngxDirectiveThirdParty contained passenger_concurrency_model +syn keyword ngxDirectiveThirdParty contained passenger_thread_count +syn keyword ngxDirectiveThirdParty contained passenger_max_requests +syn keyword ngxDirectiveThirdParty contained passenger_max_request_time +syn keyword ngxDirectiveThirdParty contained passenger_memory_limit +syn keyword ngxDirectiveThirdParty contained passenger_stat_throttle_rate +syn keyword ngxDirectiveThirdParty contained passenger_core_file_descriptor_ulimit +syn keyword ngxDirectiveThirdParty contained passenger_app_file_descriptor_ulimit +syn keyword ngxDirectiveThirdParty contained passenger_pre_start +syn keyword ngxDirectiveThirdParty contained passenger_set_header +syn keyword ngxDirectiveThirdParty contained passenger_max_request_queue_size +syn keyword ngxDirectiveThirdParty contained passenger_request_queue_overflow_status_code +syn keyword ngxDirectiveThirdParty contained passenger_sticky_sessions +syn keyword ngxDirectiveThirdParty contained passenger_sticky_sessions_cookie_name +syn keyword ngxDirectiveThirdParty contained passenger_abort_websockets_on_process_shutdown +syn keyword ngxDirectiveThirdParty contained passenger_ignore_client_abort +syn keyword ngxDirectiveThirdParty contained passenger_intercept_errors +syn keyword ngxDirectiveThirdParty contained passenger_pass_header +syn keyword ngxDirectiveThirdParty contained passenger_ignore_headers +syn keyword ngxDirectiveThirdParty contained passenger_headers_hash_bucket_size +syn keyword ngxDirectiveThirdParty contained passenger_headers_hash_max_size +syn keyword ngxDirectiveThirdParty contained passenger_buffer_response +syn keyword ngxDirectiveThirdParty contained passenger_response_buffer_high_watermark +syn keyword ngxDirectiveThirdParty contained passenger_buffer_size, passenger_buffers, passenger_busy_buffers_size +syn keyword ngxDirectiveThirdParty contained passenger_socket_backlog +syn keyword ngxDirectiveThirdParty contained passenger_log_level +syn keyword ngxDirectiveThirdParty contained passenger_log_file +syn keyword ngxDirectiveThirdParty contained passenger_file_descriptor_log_file +syn keyword ngxDirectiveThirdParty contained passenger_debugger +syn keyword ngxDirectiveThirdParty contained passenger_instance_registry_dir +syn keyword ngxDirectiveThirdParty contained passenger_data_buffer_dir +syn keyword ngxDirectiveThirdParty contained passenger_fly_with +syn keyword ngxDirectiveThirdParty contained union_station_support +syn keyword ngxDirectiveThirdParty contained union_station_key +syn keyword ngxDirectiveThirdParty contained union_station_proxy_address +syn keyword ngxDirectiveThirdParty contained union_station_filter +syn keyword ngxDirectiveThirdParty contained union_station_gateway_address +syn keyword ngxDirectiveThirdParty contained union_station_gateway_port +syn keyword ngxDirectiveThirdParty contained union_station_gateway_cert +syn keyword ngxDirectiveDeprecated contained rails_spawn_method +syn keyword ngxDirectiveDeprecated contained passenger_debug_log_file + +" Postgres Module +" Upstream module that allows nginx to communicate directly with PostgreSQL database. +syn keyword ngxDirectiveThirdParty contained postgres_server +syn keyword ngxDirectiveThirdParty contained postgres_keepalive +syn keyword ngxDirectiveThirdParty contained postgres_pass +syn keyword ngxDirectiveThirdParty contained postgres_query +syn keyword ngxDirectiveThirdParty contained postgres_rewrite +syn keyword ngxDirectiveThirdParty contained postgres_output +syn keyword ngxDirectiveThirdParty contained postgres_set +syn keyword ngxDirectiveThirdParty contained postgres_escape +syn keyword ngxDirectiveThirdParty contained postgres_connect_timeout +syn keyword ngxDirectiveThirdParty contained postgres_result_timeout + +" Pubcookie Module +" Authorizes users using encrypted cookies +syn keyword ngxDirectiveThirdParty contained pubcookie_inactive_expire +syn keyword ngxDirectiveThirdParty contained pubcookie_hard_expire +syn keyword ngxDirectiveThirdParty contained pubcookie_app_id +syn keyword ngxDirectiveThirdParty contained pubcookie_dir_depth +syn keyword ngxDirectiveThirdParty contained pubcookie_catenate_app_ids +syn keyword ngxDirectiveThirdParty contained pubcookie_app_srv_id +syn keyword ngxDirectiveThirdParty contained pubcookie_login +syn keyword ngxDirectiveThirdParty contained pubcookie_login_method +syn keyword ngxDirectiveThirdParty contained pubcookie_post +syn keyword ngxDirectiveThirdParty contained pubcookie_domain +syn keyword ngxDirectiveThirdParty contained pubcookie_granting_cert_file +syn keyword ngxDirectiveThirdParty contained pubcookie_session_key_file +syn keyword ngxDirectiveThirdParty contained pubcookie_session_cert_file +syn keyword ngxDirectiveThirdParty contained pubcookie_crypt_key_file +syn keyword ngxDirectiveThirdParty contained pubcookie_end_session +syn keyword ngxDirectiveThirdParty contained pubcookie_encryption +syn keyword ngxDirectiveThirdParty contained pubcookie_session_reauth +syn keyword ngxDirectiveThirdParty contained pubcookie_auth_type_names +syn keyword ngxDirectiveThirdParty contained pubcookie_no_prompt +syn keyword ngxDirectiveThirdParty contained pubcookie_on_demand +syn keyword ngxDirectiveThirdParty contained pubcookie_addl_request +syn keyword ngxDirectiveThirdParty contained pubcookie_no_obscure_cookies +syn keyword ngxDirectiveThirdParty contained pubcookie_no_clean_creds +syn keyword ngxDirectiveThirdParty contained pubcookie_egd_device +syn keyword ngxDirectiveThirdParty contained pubcookie_no_blank +syn keyword ngxDirectiveThirdParty contained pubcookie_super_debug +syn keyword ngxDirectiveThirdParty contained pubcookie_set_remote_user + +" Push Stream Module +" A pure stream http push technology for your Nginx setup +syn keyword ngxDirectiveThirdParty contained push_stream_channels_statistics +syn keyword ngxDirectiveThirdParty contained push_stream_publisher +syn keyword ngxDirectiveThirdParty contained push_stream_subscriber +syn keyword ngxDirectiveThirdParty contained push_stream_shared_memory_size +syn keyword ngxDirectiveThirdParty contained push_stream_channel_deleted_message_text +syn keyword ngxDirectiveThirdParty contained push_stream_channel_inactivity_time +syn keyword ngxDirectiveThirdParty contained push_stream_ping_message_text +syn keyword ngxDirectiveThirdParty contained push_stream_timeout_with_body +syn keyword ngxDirectiveThirdParty contained push_stream_message_ttl +syn keyword ngxDirectiveThirdParty contained push_stream_max_subscribers_per_channel +syn keyword ngxDirectiveThirdParty contained push_stream_max_messages_stored_per_channel +syn keyword ngxDirectiveThirdParty contained push_stream_max_channel_id_length +syn keyword ngxDirectiveThirdParty contained push_stream_max_number_of_channels +syn keyword ngxDirectiveThirdParty contained push_stream_max_number_of_wildcard_channels +syn keyword ngxDirectiveThirdParty contained push_stream_wildcard_channel_prefix +syn keyword ngxDirectiveThirdParty contained push_stream_events_channel_id +syn keyword ngxDirectiveThirdParty contained push_stream_channels_path +syn keyword ngxDirectiveThirdParty contained push_stream_store_messages +syn keyword ngxDirectiveThirdParty contained push_stream_channel_info_on_publish +syn keyword ngxDirectiveThirdParty contained push_stream_authorized_channels_only +syn keyword ngxDirectiveThirdParty contained push_stream_header_template_file +syn keyword ngxDirectiveThirdParty contained push_stream_header_template +syn keyword ngxDirectiveThirdParty contained push_stream_message_template +syn keyword ngxDirectiveThirdParty contained push_stream_footer_template +syn keyword ngxDirectiveThirdParty contained push_stream_wildcard_channel_max_qtd +syn keyword ngxDirectiveThirdParty contained push_stream_ping_message_interval +syn keyword ngxDirectiveThirdParty contained push_stream_subscriber_connection_ttl +syn keyword ngxDirectiveThirdParty contained push_stream_longpolling_connection_ttl +syn keyword ngxDirectiveThirdParty contained push_stream_websocket_allow_publish +syn keyword ngxDirectiveThirdParty contained push_stream_last_received_message_time +syn keyword ngxDirectiveThirdParty contained push_stream_last_received_message_tag +syn keyword ngxDirectiveThirdParty contained push_stream_last_event_id +syn keyword ngxDirectiveThirdParty contained push_stream_user_agent +syn keyword ngxDirectiveThirdParty contained push_stream_padding_by_user_agent +syn keyword ngxDirectiveThirdParty contained push_stream_allowed_origins +syn keyword ngxDirectiveThirdParty contained push_stream_allow_connections_to_events_channel + +" rDNS Module +" Make a reverse DNS (rDNS) lookup for incoming connection and provides simple access control of incoming hostname by allow/deny rules +syn keyword ngxDirectiveThirdParty contained rdns +syn keyword ngxDirectiveThirdParty contained rdns_allow +syn keyword ngxDirectiveThirdParty contained rdns_deny + +" RDS CSV Module +" Nginx output filter module to convert Resty-DBD-Streams (RDS) to Comma-Separated Values (CSV) +syn keyword ngxDirectiveThirdParty contained rds_csv +syn keyword ngxDirectiveThirdParty contained rds_csv_row_terminator +syn keyword ngxDirectiveThirdParty contained rds_csv_field_separator +syn keyword ngxDirectiveThirdParty contained rds_csv_field_name_header +syn keyword ngxDirectiveThirdParty contained rds_csv_content_type +syn keyword ngxDirectiveThirdParty contained rds_csv_buffer_size + +" RDS JSON Module +" An output filter that formats Resty DBD Streams generated by ngx_drizzle and others to JSON +syn keyword ngxDirectiveThirdParty contained rds_json +syn keyword ngxDirectiveThirdParty contained rds_json_buffer_size +syn keyword ngxDirectiveThirdParty contained rds_json_format +syn keyword ngxDirectiveThirdParty contained rds_json_root +syn keyword ngxDirectiveThirdParty contained rds_json_success_property +syn keyword ngxDirectiveThirdParty contained rds_json_user_property +syn keyword ngxDirectiveThirdParty contained rds_json_errcode_key +syn keyword ngxDirectiveThirdParty contained rds_json_errstr_key +syn keyword ngxDirectiveThirdParty contained rds_json_ret +syn keyword ngxDirectiveThirdParty contained rds_json_content_type + +" Redis Module +" Use this module to perform simple caching +syn keyword ngxDirectiveThirdParty contained redis_pass +syn keyword ngxDirectiveThirdParty contained redis_bind +syn keyword ngxDirectiveThirdParty contained redis_connect_timeout +syn keyword ngxDirectiveThirdParty contained redis_read_timeout +syn keyword ngxDirectiveThirdParty contained redis_send_timeout +syn keyword ngxDirectiveThirdParty contained redis_buffer_size +syn keyword ngxDirectiveThirdParty contained redis_next_upstream +syn keyword ngxDirectiveThirdParty contained redis_gzip_flag + +" Redis 2 Module +" Nginx upstream module for the Redis 2.0 protocol +syn keyword ngxDirectiveThirdParty contained redis2_query +syn keyword ngxDirectiveThirdParty contained redis2_raw_query +syn keyword ngxDirectiveThirdParty contained redis2_raw_queries +syn keyword ngxDirectiveThirdParty contained redis2_literal_raw_query +syn keyword ngxDirectiveThirdParty contained redis2_pass +syn keyword ngxDirectiveThirdParty contained redis2_connect_timeout +syn keyword ngxDirectiveThirdParty contained redis2_send_timeout +syn keyword ngxDirectiveThirdParty contained redis2_read_timeout +syn keyword ngxDirectiveThirdParty contained redis2_buffer_size +syn keyword ngxDirectiveThirdParty contained redis2_next_upstream + +" Replace Filter Module +" Streaming regular expression replacement in response bodies +syn keyword ngxDirectiveThirdParty contained replace_filter +syn keyword ngxDirectiveThirdParty contained replace_filter_types +syn keyword ngxDirectiveThirdParty contained replace_filter_max_buffered_size +syn keyword ngxDirectiveThirdParty contained replace_filter_last_modified +syn keyword ngxDirectiveThirdParty contained replace_filter_skip + +" Roboo Module +" HTTP Robot Mitigator + +" RRD Graph Module " This module provides an HTTP interface to RRDtool's graphing facilities. -syn keyword ngxDirectiveThirdParty rrd_graph -syn keyword ngxDirectiveThirdParty rrd_graph_root +syn keyword ngxDirectiveThirdParty contained rrd_graph +syn keyword ngxDirectiveThirdParty contained rrd_graph_root -" Secure Download -" Create expiring links. -syn keyword ngxDirectiveThirdParty secure_download -syn keyword ngxDirectiveThirdParty secure_download_fail_location -syn keyword ngxDirectiveThirdParty secure_download_path_mode -syn keyword ngxDirectiveThirdParty secure_download_secret +" RTMP Module +" NGINX-based Media Streaming Server +syn keyword ngxDirectiveThirdParty contained rtmp +" syn keyword ngxDirectiveThirdParty contained server +" syn keyword ngxDirectiveThirdParty contained listen +syn keyword ngxDirectiveThirdParty contained application +" syn keyword ngxDirectiveThirdParty contained timeout +syn keyword ngxDirectiveThirdParty contained ping +syn keyword ngxDirectiveThirdParty contained ping_timeout +syn keyword ngxDirectiveThirdParty contained max_streams +syn keyword ngxDirectiveThirdParty contained ack_window +syn keyword ngxDirectiveThirdParty contained chunk_size +syn keyword ngxDirectiveThirdParty contained max_queue +syn keyword ngxDirectiveThirdParty contained max_message +syn keyword ngxDirectiveThirdParty contained out_queue +syn keyword ngxDirectiveThirdParty contained out_cork +" syn keyword ngxDirectiveThirdParty contained allow +" syn keyword ngxDirectiveThirdParty contained deny +syn keyword ngxDirectiveThirdParty contained exec_push +syn keyword ngxDirectiveThirdParty contained exec_pull +syn keyword ngxDirectiveThirdParty contained exec +syn keyword ngxDirectiveThirdParty contained exec_options +syn keyword ngxDirectiveThirdParty contained exec_static +syn keyword ngxDirectiveThirdParty contained exec_kill_signal +syn keyword ngxDirectiveThirdParty contained respawn +syn keyword ngxDirectiveThirdParty contained respawn_timeout +syn keyword ngxDirectiveThirdParty contained exec_publish +syn keyword ngxDirectiveThirdParty contained exec_play +syn keyword ngxDirectiveThirdParty contained exec_play_done +syn keyword ngxDirectiveThirdParty contained exec_publish_done +syn keyword ngxDirectiveThirdParty contained exec_record_done +syn keyword ngxDirectiveThirdParty contained live +syn keyword ngxDirectiveThirdParty contained meta +syn keyword ngxDirectiveThirdParty contained interleave +syn keyword ngxDirectiveThirdParty contained wait_key +syn keyword ngxDirectiveThirdParty contained wait_video +syn keyword ngxDirectiveThirdParty contained publish_notify +syn keyword ngxDirectiveThirdParty contained drop_idle_publisher +syn keyword ngxDirectiveThirdParty contained sync +syn keyword ngxDirectiveThirdParty contained play_restart +syn keyword ngxDirectiveThirdParty contained idle_streams +syn keyword ngxDirectiveThirdParty contained record +syn keyword ngxDirectiveThirdParty contained record_path +syn keyword ngxDirectiveThirdParty contained record_suffix +syn keyword ngxDirectiveThirdParty contained record_unique +syn keyword ngxDirectiveThirdParty contained record_append +syn keyword ngxDirectiveThirdParty contained record_lock +syn keyword ngxDirectiveThirdParty contained record_max_size +syn keyword ngxDirectiveThirdParty contained record_max_frames +syn keyword ngxDirectiveThirdParty contained record_interval +syn keyword ngxDirectiveThirdParty contained recorder +syn keyword ngxDirectiveThirdParty contained record_notify +syn keyword ngxDirectiveThirdParty contained play +syn keyword ngxDirectiveThirdParty contained play_temp_path +syn keyword ngxDirectiveThirdParty contained play_local_path +syn keyword ngxDirectiveThirdParty contained pull +syn keyword ngxDirectiveThirdParty contained push +syn keyword ngxDirectiveThirdParty contained push_reconnect +syn keyword ngxDirectiveThirdParty contained session_relay +syn keyword ngxDirectiveThirdParty contained on_connect +syn keyword ngxDirectiveThirdParty contained on_play +syn keyword ngxDirectiveThirdParty contained on_publish +syn keyword ngxDirectiveThirdParty contained on_done +syn keyword ngxDirectiveThirdParty contained on_play_done +syn keyword ngxDirectiveThirdParty contained on_publish_done +syn keyword ngxDirectiveThirdParty contained on_record_done +syn keyword ngxDirectiveThirdParty contained on_update +syn keyword ngxDirectiveThirdParty contained notify_update_timeout +syn keyword ngxDirectiveThirdParty contained notify_update_strict +syn keyword ngxDirectiveThirdParty contained notify_relay_redirect +syn keyword ngxDirectiveThirdParty contained notify_method +syn keyword ngxDirectiveThirdParty contained hls +syn keyword ngxDirectiveThirdParty contained hls_path +syn keyword ngxDirectiveThirdParty contained hls_fragment +syn keyword ngxDirectiveThirdParty contained hls_playlist_length +syn keyword ngxDirectiveThirdParty contained hls_sync +syn keyword ngxDirectiveThirdParty contained hls_continuous +syn keyword ngxDirectiveThirdParty contained hls_nested +syn keyword ngxDirectiveThirdParty contained hls_base_url +syn keyword ngxDirectiveThirdParty contained hls_cleanup +syn keyword ngxDirectiveThirdParty contained hls_fragment_naming +syn keyword ngxDirectiveThirdParty contained hls_fragment_slicing +syn keyword ngxDirectiveThirdParty contained hls_variant +syn keyword ngxDirectiveThirdParty contained hls_type +syn keyword ngxDirectiveThirdParty contained hls_keys +syn keyword ngxDirectiveThirdParty contained hls_key_path +syn keyword ngxDirectiveThirdParty contained hls_key_url +syn keyword ngxDirectiveThirdParty contained hls_fragments_per_key +syn keyword ngxDirectiveThirdParty contained dash +syn keyword ngxDirectiveThirdParty contained dash_path +syn keyword ngxDirectiveThirdParty contained dash_fragment +syn keyword ngxDirectiveThirdParty contained dash_playlist_length +syn keyword ngxDirectiveThirdParty contained dash_nested +syn keyword ngxDirectiveThirdParty contained dash_cleanup +" syn keyword ngxDirectiveThirdParty contained access_log +" syn keyword ngxDirectiveThirdParty contained log_format +syn keyword ngxDirectiveThirdParty contained max_connections +syn keyword ngxDirectiveThirdParty contained rtmp_stat +syn keyword ngxDirectiveThirdParty contained rtmp_stat_stylesheet +syn keyword ngxDirectiveThirdParty contained rtmp_auto_push +syn keyword ngxDirectiveThirdParty contained rtmp_auto_push_reconnect +syn keyword ngxDirectiveThirdParty contained rtmp_socket_dir +syn keyword ngxDirectiveThirdParty contained rtmp_control -" SlowFS Cache Module +" RTMPT Module +" Module for nginx to proxy rtmp using http protocol +syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_target +syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_rtmp_timeout +syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_http_timeout +syn keyword ngxDirectiveThirdParty contained rtmpt_proxy +syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_stat +syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_stylesheet + +" Syntactically Awesome Module +" Providing on-the-fly compiling of Sass files as an NGINX module. +syn keyword ngxDirectiveThirdParty contained sass_compile +syn keyword ngxDirectiveThirdParty contained sass_error_log +syn keyword ngxDirectiveThirdParty contained sass_include_path +syn keyword ngxDirectiveThirdParty contained sass_indent +syn keyword ngxDirectiveThirdParty contained sass_is_indented_syntax +syn keyword ngxDirectiveThirdParty contained sass_linefeed +syn keyword ngxDirectiveThirdParty contained sass_precision +syn keyword ngxDirectiveThirdParty contained sass_output_style +syn keyword ngxDirectiveThirdParty contained sass_source_comments +syn keyword ngxDirectiveThirdParty contained sass_source_map_embed + +" Secure Download Module +" Enables you to create links which are only valid until a certain datetime is reached +syn keyword ngxDirectiveThirdParty contained secure_download +syn keyword ngxDirectiveThirdParty contained secure_download_secret +syn keyword ngxDirectiveThirdParty contained secure_download_path_mode + +" Selective Cache Purge Module +" A module to purge cache by GLOB patterns. The supported patterns are the same as supported by Redis. +syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_unix_socket +syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_host +syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_port +syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_database +syn keyword ngxDirectiveThirdParty contained selective_cache_purge_query + +" Set cconv Module +" Cconv rewrite set commands +syn keyword ngxDirectiveThirdParty contained set_cconv_to_simp +syn keyword ngxDirectiveThirdParty contained set_cconv_to_trad +syn keyword ngxDirectiveThirdParty contained set_pinyin_to_normal + +" Set Hash Module +" Nginx module that allows the setting of variables to the value of a variety of hashes +syn keyword ngxDirectiveThirdParty contained set_md5 +syn keyword ngxDirectiveThirdParty contained set_md5_upper +syn keyword ngxDirectiveThirdParty contained set_murmur2 +syn keyword ngxDirectiveThirdParty contained set_murmur2_upper +syn keyword ngxDirectiveThirdParty contained set_sha1 +syn keyword ngxDirectiveThirdParty contained set_sha1_upper + +" Set Lang Module +" Provides a variety of ways for setting a variable denoting the langauge that content should be returned in. +syn keyword ngxDirectiveThirdParty contained set_lang +syn keyword ngxDirectiveThirdParty contained set_lang_method +syn keyword ngxDirectiveThirdParty contained lang_cookie +syn keyword ngxDirectiveThirdParty contained lang_get_var +syn keyword ngxDirectiveThirdParty contained lang_list +syn keyword ngxDirectiveThirdParty contained lang_post_var +syn keyword ngxDirectiveThirdParty contained lang_host +syn keyword ngxDirectiveThirdParty contained lang_referer + +" Set Misc Module +" Various set_xxx directives added to nginx's rewrite module +syn keyword ngxDirectiveThirdParty contained set_if_empty +syn keyword ngxDirectiveThirdParty contained set_quote_sql_str +syn keyword ngxDirectiveThirdParty contained set_quote_pgsql_str +syn keyword ngxDirectiveThirdParty contained set_quote_json_str +syn keyword ngxDirectiveThirdParty contained set_unescape_uri +syn keyword ngxDirectiveThirdParty contained set_escape_uri +syn keyword ngxDirectiveThirdParty contained set_hashed_upstream +syn keyword ngxDirectiveThirdParty contained set_encode_base32 +syn keyword ngxDirectiveThirdParty contained set_base32_padding +syn keyword ngxDirectiveThirdParty contained set_misc_base32_padding +syn keyword ngxDirectiveThirdParty contained set_base32_alphabet +syn keyword ngxDirectiveThirdParty contained set_decode_base32 +syn keyword ngxDirectiveThirdParty contained set_encode_base64 +syn keyword ngxDirectiveThirdParty contained set_decode_base64 +syn keyword ngxDirectiveThirdParty contained set_encode_hex +syn keyword ngxDirectiveThirdParty contained set_decode_hex +syn keyword ngxDirectiveThirdParty contained set_sha1 +syn keyword ngxDirectiveThirdParty contained set_md5 +syn keyword ngxDirectiveThirdParty contained set_hmac_sha1 +syn keyword ngxDirectiveThirdParty contained set_random +syn keyword ngxDirectiveThirdParty contained set_secure_random_alphanum +syn keyword ngxDirectiveThirdParty contained set_secure_random_lcalpha +syn keyword ngxDirectiveThirdParty contained set_rotate +syn keyword ngxDirectiveThirdParty contained set_local_today +syn keyword ngxDirectiveThirdParty contained set_formatted_gmt_time +syn keyword ngxDirectiveThirdParty contained set_formatted_local_time + +" SFlow Module +" A binary, random-sampling nginx module designed for: lightweight, centralized, continuous, real-time monitoring of very large and very busy web farms. +syn keyword ngxDirectiveThirdParty contained sflow + +" Shibboleth Module +" Shibboleth auth request module for nginx +syn keyword ngxDirectiveThirdParty contained shib_request +syn keyword ngxDirectiveThirdParty contained shib_request_set +syn keyword ngxDirectiveThirdParty contained shib_request_use_headers + +" Slice Module +" Nginx module for serving a file in slices (reverse byte-range) +" syn keyword ngxDirectiveThirdParty contained slice +syn keyword ngxDirectiveThirdParty contained slice_arg_begin +syn keyword ngxDirectiveThirdParty contained slice_arg_end +syn keyword ngxDirectiveThirdParty contained slice_header +syn keyword ngxDirectiveThirdParty contained slice_footer +syn keyword ngxDirectiveThirdParty contained slice_header_first +syn keyword ngxDirectiveThirdParty contained slice_footer_last + +" SlowFS Cache Module " Module adding ability to cache static files. -syn keyword ngxDirectiveThirdParty slowfs_big_file_size -syn keyword ngxDirectiveThirdParty slowfs_cache -syn keyword ngxDirectiveThirdParty slowfs_cache_key -syn keyword ngxDirectiveThirdParty slowfs_cache_min_uses -syn keyword ngxDirectiveThirdParty slowfs_cache_path -syn keyword ngxDirectiveThirdParty slowfs_cache_purge -syn keyword ngxDirectiveThirdParty slowfs_cache_valid -syn keyword ngxDirectiveThirdParty slowfs_temp_path +syn keyword ngxDirectiveThirdParty contained slowfs_big_file_size +syn keyword ngxDirectiveThirdParty contained slowfs_cache +syn keyword ngxDirectiveThirdParty contained slowfs_cache_key +syn keyword ngxDirectiveThirdParty contained slowfs_cache_min_uses +syn keyword ngxDirectiveThirdParty contained slowfs_cache_path +syn keyword ngxDirectiveThirdParty contained slowfs_cache_purge +syn keyword ngxDirectiveThirdParty contained slowfs_cache_valid +syn keyword ngxDirectiveThirdParty contained slowfs_temp_path -" Strip Module +" Small Light Module +" Dynamic Image Transformation Module For nginx. +syn keyword ngxDirectiveThirdParty contained small_light +syn keyword ngxDirectiveThirdParty contained small_light_getparam_mode +syn keyword ngxDirectiveThirdParty contained small_light_material_dir +syn keyword ngxDirectiveThirdParty contained small_light_pattern_define +syn keyword ngxDirectiveThirdParty contained small_light_radius_max +syn keyword ngxDirectiveThirdParty contained small_light_sigma_max +syn keyword ngxDirectiveThirdParty contained small_light_imlib2_temp_dir +syn keyword ngxDirectiveThirdParty contained small_light_buffer + +" Sorted Querystring Filter Module +" Nginx module to expose querystring parameters sorted in a variable to be used on cache_key as example +syn keyword ngxDirectiveThirdParty contained sorted_querystring_filter_parameter + +" Sphinx2 Module +" Nginx upstream module for Sphinx 2.x +syn keyword ngxDirectiveThirdParty contained sphinx2_pass +syn keyword ngxDirectiveThirdParty contained sphinx2_bind +syn keyword ngxDirectiveThirdParty contained sphinx2_connect_timeout +syn keyword ngxDirectiveThirdParty contained sphinx2_send_timeout +syn keyword ngxDirectiveThirdParty contained sphinx2_buffer_size +syn keyword ngxDirectiveThirdParty contained sphinx2_read_timeout +syn keyword ngxDirectiveThirdParty contained sphinx2_next_upstream + +" HTTP SPNEGO auth Module +" This module implements adds SPNEGO support to nginx(http://nginx.org). It currently supports only Kerberos authentication via GSSAPI +syn keyword ngxDirectiveThirdParty contained auth_gss +syn keyword ngxDirectiveThirdParty contained auth_gss_keytab +syn keyword ngxDirectiveThirdParty contained auth_gss_realm +syn keyword ngxDirectiveThirdParty contained auth_gss_service_name +syn keyword ngxDirectiveThirdParty contained auth_gss_authorized_principal +syn keyword ngxDirectiveThirdParty contained auth_gss_allow_basic_fallback + +" SR Cache Module +" Transparent subrequest-based caching layout for arbitrary nginx locations +syn keyword ngxDirectiveThirdParty contained srcache_fetch +syn keyword ngxDirectiveThirdParty contained srcache_fetch_skip +syn keyword ngxDirectiveThirdParty contained srcache_store +syn keyword ngxDirectiveThirdParty contained srcache_store_max_size +syn keyword ngxDirectiveThirdParty contained srcache_store_skip +syn keyword ngxDirectiveThirdParty contained srcache_store_statuses +syn keyword ngxDirectiveThirdParty contained srcache_store_ranges +syn keyword ngxDirectiveThirdParty contained srcache_header_buffer_size +syn keyword ngxDirectiveThirdParty contained srcache_store_hide_header +syn keyword ngxDirectiveThirdParty contained srcache_store_pass_header +syn keyword ngxDirectiveThirdParty contained srcache_methods +syn keyword ngxDirectiveThirdParty contained srcache_ignore_content_encoding +syn keyword ngxDirectiveThirdParty contained srcache_request_cache_control +syn keyword ngxDirectiveThirdParty contained srcache_response_cache_control +syn keyword ngxDirectiveThirdParty contained srcache_store_no_store +syn keyword ngxDirectiveThirdParty contained srcache_store_no_cache +syn keyword ngxDirectiveThirdParty contained srcache_store_private +syn keyword ngxDirectiveThirdParty contained srcache_default_expire +syn keyword ngxDirectiveThirdParty contained srcache_max_expire + +" SSSD Info Module +" Retrives additional attributes from SSSD for current authentizated user +syn keyword ngxDirectiveThirdParty contained sssd_info +syn keyword ngxDirectiveThirdParty contained sssd_info_output_to +syn keyword ngxDirectiveThirdParty contained sssd_info_groups +syn keyword ngxDirectiveThirdParty contained sssd_info_group +syn keyword ngxDirectiveThirdParty contained sssd_info_group_separator +syn keyword ngxDirectiveThirdParty contained sssd_info_attributes +syn keyword ngxDirectiveThirdParty contained sssd_info_attribute +syn keyword ngxDirectiveThirdParty contained sssd_info_attribute_separator + +" Static Etags Module +" Generate etags for static content +syn keyword ngxDirectiveThirdParty contained FileETag + +" Statsd Module +" An nginx module for sending statistics to statsd +syn keyword ngxDirectiveThirdParty contained statsd_server +syn keyword ngxDirectiveThirdParty contained statsd_sample_rate +syn keyword ngxDirectiveThirdParty contained statsd_count +syn keyword ngxDirectiveThirdParty contained statsd_timing + +" Sticky Module +" Add a sticky cookie to be always forwarded to the same upstream server +" syn keyword ngxDirectiveThirdParty contained sticky + +" Stream Echo Module +" TCP/stream echo module for NGINX (a port of ngx_http_echo_module) +syn keyword ngxDirectiveThirdParty contained echo +syn keyword ngxDirectiveThirdParty contained echo_duplicate +syn keyword ngxDirectiveThirdParty contained echo_flush_wait +syn keyword ngxDirectiveThirdParty contained echo_sleep +syn keyword ngxDirectiveThirdParty contained echo_send_timeout +syn keyword ngxDirectiveThirdParty contained echo_read_bytes +syn keyword ngxDirectiveThirdParty contained echo_read_line +syn keyword ngxDirectiveThirdParty contained echo_request_data +syn keyword ngxDirectiveThirdParty contained echo_discard_request +syn keyword ngxDirectiveThirdParty contained echo_read_buffer_size +syn keyword ngxDirectiveThirdParty contained echo_read_timeout +syn keyword ngxDirectiveThirdParty contained echo_client_error_log_level +syn keyword ngxDirectiveThirdParty contained echo_lingering_close +syn keyword ngxDirectiveThirdParty contained echo_lingering_time +syn keyword ngxDirectiveThirdParty contained echo_lingering_timeout + +" Stream Lua Module +" Embed the power of Lua into Nginx stream/TCP Servers. +syn keyword ngxDirectiveThirdParty contained lua_resolver +syn keyword ngxDirectiveThirdParty contained lua_resolver_timeout +syn keyword ngxDirectiveThirdParty contained lua_lingering_close +syn keyword ngxDirectiveThirdParty contained lua_lingering_time +syn keyword ngxDirectiveThirdParty contained lua_lingering_timeout + +" Stream Upsync Module +" Sync upstreams from consul or others, dynamiclly modify backend-servers attribute(weight, max_fails,...), needn't reload nginx. +syn keyword ngxDirectiveThirdParty contained upsync +syn keyword ngxDirectiveThirdParty contained upsync_dump_path +syn keyword ngxDirectiveThirdParty contained upsync_lb +syn keyword ngxDirectiveThirdParty contained upsync_show + +" Strip Module " Whitespace remover. -syn keyword ngxDirectiveThirdParty strip +syn keyword ngxDirectiveThirdParty contained strip -" Substitutions Module +" Subrange Module +" Split one big HTTP/Range request to multiple subrange requesets +syn keyword ngxDirectiveThirdParty contained subrange + +" Substitutions Module " A filter module which can do both regular expression and fixed string substitutions on response bodies. -syn keyword ngxDirectiveThirdParty subs_filter -syn keyword ngxDirectiveThirdParty subs_filter_types +syn keyword ngxDirectiveThirdParty contained subs_filter +syn keyword ngxDirectiveThirdParty contained subs_filter_types -" Supervisord Module +" Summarizer Module +" Upstream nginx module to get summaries of documents using the summarizer daemon service +syn keyword ngxDirectiveThirdParty contained smrzr_filename +syn keyword ngxDirectiveThirdParty contained smrzr_ratio + +" Supervisord Module " Module providing nginx with API to communicate with supervisord and manage (start/stop) backends on-demand. -syn keyword ngxDirectiveThirdParty supervisord -syn keyword ngxDirectiveThirdParty supervisord_inherit_backend_status -syn keyword ngxDirectiveThirdParty supervisord_name -syn keyword ngxDirectiveThirdParty supervisord_start -syn keyword ngxDirectiveThirdParty supervisord_stop +syn keyword ngxDirectiveThirdParty contained supervisord +syn keyword ngxDirectiveThirdParty contained supervisord_inherit_backend_status +syn keyword ngxDirectiveThirdParty contained supervisord_name +syn keyword ngxDirectiveThirdParty contained supervisord_start +syn keyword ngxDirectiveThirdParty contained supervisord_stop -" Upload Module -" Parses multipart/form-data allowing arbitrary handling of uploaded files. -syn keyword ngxDirectiveThirdParty upload_aggregate_form_field -syn keyword ngxDirectiveThirdParty upload_buffer_size -syn keyword ngxDirectiveThirdParty upload_cleanup -syn keyword ngxDirectiveThirdParty upload_limit_rate -syn keyword ngxDirectiveThirdParty upload_max_file_size -syn keyword ngxDirectiveThirdParty upload_max_output_body_len -syn keyword ngxDirectiveThirdParty upload_max_part_header_len -syn keyword ngxDirectiveThirdParty upload_pass -syn keyword ngxDirectiveThirdParty upload_pass_args -syn keyword ngxDirectiveThirdParty upload_pass_form_field -syn keyword ngxDirectiveThirdParty upload_set_form_field -syn keyword ngxDirectiveThirdParty upload_store -syn keyword ngxDirectiveThirdParty upload_store_access +" Tarantool Upstream Module +" Tarantool NginX upstream module (REST, JSON API, websockets, load balancing) +syn keyword ngxDirectiveThirdParty contained tnt_pass +syn keyword ngxDirectiveThirdParty contained tnt_http_methods +syn keyword ngxDirectiveThirdParty contained tnt_http_rest_methods +syn keyword ngxDirectiveThirdParty contained tnt_pass_http_request +syn keyword ngxDirectiveThirdParty contained tnt_pass_http_request_buffer_size +syn keyword ngxDirectiveThirdParty contained tnt_method +syn keyword ngxDirectiveThirdParty contained tnt_http_allowed_methods - experemental +syn keyword ngxDirectiveThirdParty contained tnt_send_timeout +syn keyword ngxDirectiveThirdParty contained tnt_read_timeout +syn keyword ngxDirectiveThirdParty contained tnt_buffer_size +syn keyword ngxDirectiveThirdParty contained tnt_next_upstream +syn keyword ngxDirectiveThirdParty contained tnt_connect_timeout +syn keyword ngxDirectiveThirdParty contained tnt_next_upstream +syn keyword ngxDirectiveThirdParty contained tnt_next_upstream_tries +syn keyword ngxDirectiveThirdParty contained tnt_next_upstream_timeout -" Upload Progress Module -" Tracks and reports upload progress. -syn keyword ngxDirectiveThirdParty report_uploads -syn keyword ngxDirectiveThirdParty track_uploads -syn keyword ngxDirectiveThirdParty upload_progress -syn keyword ngxDirectiveThirdParty upload_progress_content_type -syn keyword ngxDirectiveThirdParty upload_progress_header -syn keyword ngxDirectiveThirdParty upload_progress_json_output -syn keyword ngxDirectiveThirdParty upload_progress_template +" TCP Proxy Module +" Add the feature of tcp proxy with nginx, with health check and status monitor +syn keyword ngxDirectiveBlock contained tcp +" syn keyword ngxDirectiveThirdParty contained server +" syn keyword ngxDirectiveThirdParty contained listen +" syn keyword ngxDirectiveThirdParty contained allow +" syn keyword ngxDirectiveThirdParty contained deny +" syn keyword ngxDirectiveThirdParty contained so_keepalive +" syn keyword ngxDirectiveThirdParty contained tcp_nodelay +" syn keyword ngxDirectiveThirdParty contained timeout +" syn keyword ngxDirectiveThirdParty contained server_name +" syn keyword ngxDirectiveThirdParty contained resolver +" syn keyword ngxDirectiveThirdParty contained resolver_timeout +" syn keyword ngxDirectiveThirdParty contained upstream +syn keyword ngxDirectiveThirdParty contained check +syn keyword ngxDirectiveThirdParty contained check_http_send +syn keyword ngxDirectiveThirdParty contained check_http_expect_alive +syn keyword ngxDirectiveThirdParty contained check_smtp_send +syn keyword ngxDirectiveThirdParty contained check_smtp_expect_alive +syn keyword ngxDirectiveThirdParty contained check_shm_size +syn keyword ngxDirectiveThirdParty contained check_status +" syn keyword ngxDirectiveThirdParty contained ip_hash +" syn keyword ngxDirectiveThirdParty contained proxy_pass +" syn keyword ngxDirectiveThirdParty contained proxy_buffer +" syn keyword ngxDirectiveThirdParty contained proxy_connect_timeout +" syn keyword ngxDirectiveThirdParty contained proxy_read_timeout +syn keyword ngxDirectiveThirdParty contained proxy_write_timeout -" Upstream Fair Balancer -" Sends an incoming request to the least-busy backend server, rather than distributing requests round-robin. -syn keyword ngxDirectiveThirdParty fair -syn keyword ngxDirectiveThirdParty upstream_fair_shm_size +" Testcookie Module +" NGINX module for L7 DDoS attack mitigation +syn keyword ngxDirectiveThirdParty contained testcookie +syn keyword ngxDirectiveThirdParty contained testcookie_name +syn keyword ngxDirectiveThirdParty contained testcookie_domain +syn keyword ngxDirectiveThirdParty contained testcookie_expires +syn keyword ngxDirectiveThirdParty contained testcookie_path +syn keyword ngxDirectiveThirdParty contained testcookie_secret +syn keyword ngxDirectiveThirdParty contained testcookie_session +syn keyword ngxDirectiveThirdParty contained testcookie_arg +syn keyword ngxDirectiveThirdParty contained testcookie_max_attempts +syn keyword ngxDirectiveThirdParty contained testcookie_p3p +syn keyword ngxDirectiveThirdParty contained testcookie_fallback +syn keyword ngxDirectiveThirdParty contained testcookie_whitelist +syn keyword ngxDirectiveThirdParty contained testcookie_pass +syn keyword ngxDirectiveThirdParty contained testcookie_redirect_via_refresh +syn keyword ngxDirectiveThirdParty contained testcookie_refresh_template +syn keyword ngxDirectiveThirdParty contained testcookie_refresh_status +syn keyword ngxDirectiveThirdParty contained testcookie_deny_keepalive +syn keyword ngxDirectiveThirdParty contained testcookie_get_only +syn keyword ngxDirectiveThirdParty contained testcookie_https_location +syn keyword ngxDirectiveThirdParty contained testcookie_refresh_encrypt_cookie +syn keyword ngxDirectiveThirdParty contained testcookie_refresh_encrypt_cookie_key +syn keyword ngxDirectiveThirdParty contained testcookie_refresh_encrypt_iv +syn keyword ngxDirectiveThirdParty contained testcookie_internal +syn keyword ngxDirectiveThirdParty contained testcookie_httponly_flag +syn keyword ngxDirectiveThirdParty contained testcookie_secure_flag -" Upstream Consistent Hash -" Select backend based on Consistent hash ring. -syn keyword ngxDirectiveThirdParty consistent_hash +" Types Filter Module +" Change the `Content-Type` output header depending on an extension variable according to a condition specified in the 'if' clause. +syn keyword ngxDirectiveThirdParty contained types_filter +syn keyword ngxDirectiveThirdParty contained types_filter_use_default -" Upstream Hash Module +" Unzip Module +" Enabling fetching of files that are stored in zipped archives. +syn keyword ngxDirectiveThirdParty contained file_in_unzip_archivefile +syn keyword ngxDirectiveThirdParty contained file_in_unzip_extract +syn keyword ngxDirectiveThirdParty contained file_in_unzip + +" Upload Progress Module +" An upload progress system, that monitors RFC1867 POST upload as they are transmitted to upstream servers +syn keyword ngxDirectiveThirdParty contained upload_progress +syn keyword ngxDirectiveThirdParty contained track_uploads +syn keyword ngxDirectiveThirdParty contained report_uploads +syn keyword ngxDirectiveThirdParty contained upload_progress_content_type +syn keyword ngxDirectiveThirdParty contained upload_progress_header +syn keyword ngxDirectiveThirdParty contained upload_progress_jsonp_parameter +syn keyword ngxDirectiveThirdParty contained upload_progress_json_output +syn keyword ngxDirectiveThirdParty contained upload_progress_jsonp_output +syn keyword ngxDirectiveThirdParty contained upload_progress_template + +" Upload Module +" Parses request body storing all files being uploaded to a directory specified by upload_store directive +syn keyword ngxDirectiveThirdParty contained upload_pass +syn keyword ngxDirectiveThirdParty contained upload_resumable +syn keyword ngxDirectiveThirdParty contained upload_store +syn keyword ngxDirectiveThirdParty contained upload_state_store +syn keyword ngxDirectiveThirdParty contained upload_store_access +syn keyword ngxDirectiveThirdParty contained upload_set_form_field +syn keyword ngxDirectiveThirdParty contained upload_aggregate_form_field +syn keyword ngxDirectiveThirdParty contained upload_pass_form_field +syn keyword ngxDirectiveThirdParty contained upload_cleanup +syn keyword ngxDirectiveThirdParty contained upload_buffer_size +syn keyword ngxDirectiveThirdParty contained upload_max_part_header_len +syn keyword ngxDirectiveThirdParty contained upload_max_file_size +syn keyword ngxDirectiveThirdParty contained upload_limit_rate +syn keyword ngxDirectiveThirdParty contained upload_max_output_body_len +syn keyword ngxDirectiveThirdParty contained upload_tame_arrays +syn keyword ngxDirectiveThirdParty contained upload_pass_args + +" Upstream Fair Module +" The fair load balancer module for nginx http://nginx.localdomain.pl +syn keyword ngxDirectiveThirdParty contained fair +syn keyword ngxDirectiveThirdParty contained upstream_fair_shm_size + +" Upstream Hash Module (DEPRECATED) " Provides simple upstream load distribution by hashing a configurable variable. -syn keyword ngxDirectiveThirdParty hash -syn keyword ngxDirectiveThirdParty hash_again +" syn keyword ngxDirectiveDeprecated contained hash +syn keyword ngxDirectiveDeprecated contained hash_again -" XSS Module +" Upstream Domain Resolve Module +" A load-balancer that resolves an upstream domain name asynchronously. +syn keyword ngxDirectiveThirdParty contained jdomain + +" Upsync Module +" Sync upstreams from consul or others, dynamiclly modify backend-servers attribute(weight, max_fails,...), needn't reload nginx +syn keyword ngxDirectiveThirdParty contained upsync +syn keyword ngxDirectiveThirdParty contained upsync_dump_path +syn keyword ngxDirectiveThirdParty contained upsync_lb +syn keyword ngxDirectiveThirdParty contained upstream_show + +" URL Module +" Nginx url encoding converting module +syn keyword ngxDirectiveThirdParty contained url_encoding_convert +syn keyword ngxDirectiveThirdParty contained url_encoding_convert_from +syn keyword ngxDirectiveThirdParty contained url_encoding_convert_to + +" User Agent Module +" Match browsers and crawlers +syn keyword ngxDirectiveThirdParty contained user_agent + +" Upstrema Ketama Chash Module +" Nginx load-balancer module implementing ketama consistent hashing. +syn keyword ngxDirectiveThirdParty contained ketama_chash + +" Video Thumbextractor Module +" Extract thumbs from a video file +syn keyword ngxDirectiveThirdParty contained video_thumbextractor +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_video_filename +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_video_second +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_image_width +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_image_height +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_only_keyframe +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_next_time +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_tile_rows +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_tile_cols +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_tile_max_rows +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_tile_max_cols +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_tile_sample_interval +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_tile_color +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_tile_margin +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_tile_padding +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_threads +syn keyword ngxDirectiveThirdParty contained video_thumbextractor_processes_per_worker + +" Eval Module +" Module for nginx web server evaluates response of proxy or memcached module into variables. +syn keyword ngxDirectiveThirdParty contained eval +syn keyword ngxDirectiveThirdParty contained eval_escalate +syn keyword ngxDirectiveThirdParty contained eval_override_content_type + +" VTS Module +" Nginx virtual host traffic status module +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_zone +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_display +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_display_format +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_display_jsonp +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_filter +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_filter_by_host +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_filter_by_set_key +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_filter_check_duplicate +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_limit +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_limit_traffic +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_limit_traffic_by_set_key +syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_limit_check_duplicate + +" XSS Module " Native support for cross-site scripting (XSS) in an nginx. -syn keyword ngxDirectiveThirdParty xss_callback_arg -syn keyword ngxDirectiveThirdParty xss_get -syn keyword ngxDirectiveThirdParty xss_input_types -syn keyword ngxDirectiveThirdParty xss_output_type +syn keyword ngxDirectiveThirdParty contained xss_get +syn keyword ngxDirectiveThirdParty contained xss_callback_arg +syn keyword ngxDirectiveThirdParty contained xss_override_status +syn keyword ngxDirectiveThirdParty contained xss_check_status +syn keyword ngxDirectiveThirdParty contained xss_input_types + +" ZIP Module +" ZIP archiver for nginx + " highlight hi link ngxComment Comment +hi link ngxParamComment Comment +hi link ngxListenComment Comment hi link ngxVariable Identifier -hi link ngxVariableBlock Identifier hi link ngxVariableString PreProc -hi link ngxBlock Normal hi link ngxString String +hi link ngxListenString String hi link ngxBoolean Boolean hi link ngxDirectiveBlock Statement hi link ngxDirectiveImportant Type +hi link ngxDirectiveListen Type hi link ngxDirectiveControl Keyword hi link ngxDirectiveError Constant hi link ngxDirectiveDeprecated Error hi link ngxDirective Identifier hi link ngxDirectiveThirdParty Special +hi link ngxListenOptions Keyword + let b:current_syntax = "nginx" diff --git a/src/core/nginx.c b/src/core/nginx.c index c5f09a5..abaa50d 100644 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -124,6 +124,13 @@ static ngx_command_t ngx_core_commands[] = { offsetof(ngx_core_conf_t, rlimit_core), NULL }, + { ngx_string("worker_shutdown_timeout"), + NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, + ngx_conf_set_msec_slot, + 0, + offsetof(ngx_core_conf_t, shutdown_timeout), + NULL }, + { ngx_string("working_directory"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -1014,6 +1021,7 @@ ngx_core_module_create_conf(ngx_cycle_t *cycle) ccf->daemon = NGX_CONF_UNSET; ccf->master = NGX_CONF_UNSET; ccf->timer_resolution = NGX_CONF_UNSET_MSEC; + ccf->shutdown_timeout = NGX_CONF_UNSET_MSEC; ccf->worker_processes = NGX_CONF_UNSET; ccf->debug_points = NGX_CONF_UNSET; @@ -1042,6 +1050,7 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf) ngx_conf_init_value(ccf->daemon, 1); ngx_conf_init_value(ccf->master, 1); ngx_conf_init_msec_value(ccf->timer_resolution, 0); + ngx_conf_init_msec_value(ccf->shutdown_timeout, 0); ngx_conf_init_value(ccf->worker_processes, 1); ngx_conf_init_value(ccf->debug_points, 0); diff --git a/src/core/nginx.h b/src/core/nginx.h index 3c06864..8cc2d80 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1011009 -#define NGINX_VERSION "1.11.9" +#define nginx_version 1013001 +#define NGINX_VERSION "1.13.1" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c index 2af2876..ec4692b 100644 --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -1345,6 +1345,49 @@ ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s, } +ngx_int_t +ngx_tcp_nodelay(ngx_connection_t *c) +{ + int tcp_nodelay; + + if (c->tcp_nodelay != NGX_TCP_NODELAY_UNSET) { + return NGX_OK; + } + + ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0, "tcp_nodelay"); + + tcp_nodelay = 1; + + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) + == -1) + { +#if (NGX_SOLARIS) + if (c->log_error == NGX_ERROR_INFO) { + + /* Solaris returns EINVAL if a socket has been shut down */ + c->log_error = NGX_ERROR_IGNORE_EINVAL; + + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + + c->log_error = NGX_ERROR_INFO; + + return NGX_ERROR; + } +#endif + + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + return NGX_ERROR; + } + + c->tcp_nodelay = NGX_TCP_NODELAY_SET; + + return NGX_OK; +} + + ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text) { diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index 1d3e3a3..e4dfe58 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -214,6 +214,7 @@ void ngx_close_connection(ngx_connection_t *c); void ngx_close_idle_connections(ngx_cycle_t *cycle); ngx_int_t ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s, ngx_uint_t port); +ngx_int_t ngx_tcp_nodelay(ngx_connection_t *c); ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text); ngx_connection_t *ngx_get_connection(ngx_socket_t s, ngx_log_t *log); diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c index 5e95628..aee7a58 100644 --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -15,6 +15,7 @@ static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *shm_zone); static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log); static void ngx_clean_old_cycles(ngx_event_t *ev); +static void ngx_shutdown_timer_handler(ngx_event_t *ev); volatile ngx_cycle_t *ngx_cycle; @@ -22,6 +23,7 @@ ngx_array_t ngx_old_cycles; static ngx_pool_t *ngx_temp_pool; static ngx_event_t ngx_cleaner_event; +static ngx_event_t ngx_shutdown_event; ngx_uint_t ngx_test_config; ngx_uint_t ngx_dump_config; @@ -113,16 +115,14 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10; - cycle->paths.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *)); - if (cycle->paths.elts == NULL) { + if (ngx_array_init(&cycle->paths, pool, n, sizeof(ngx_path_t *)) + != NGX_OK) + { ngx_destroy_pool(pool); return NULL; } - cycle->paths.nelts = 0; - cycle->paths.size = sizeof(ngx_path_t *); - cycle->paths.nalloc = n; - cycle->paths.pool = pool; + ngx_memzero(cycle->paths.elts, n * sizeof(ngx_path_t *)); if (ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t)) @@ -173,16 +173,14 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10; - cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t)); - if (cycle->listening.elts == NULL) { + if (ngx_array_init(&cycle->listening, pool, n, sizeof(ngx_listening_t)) + != NGX_OK) + { ngx_destroy_pool(pool); return NULL; } - cycle->listening.nelts = 0; - cycle->listening.size = sizeof(ngx_listening_t); - cycle->listening.nalloc = n; - cycle->listening.pool = pool; + ngx_memzero(cycle->listening.elts, n * sizeof(ngx_listening_t)); ngx_queue_init(&cycle->reusable_connections_queue); @@ -766,15 +764,15 @@ old_shm_zone_done: } n = 10; - ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool, - n * sizeof(ngx_cycle_t *)); - if (ngx_old_cycles.elts == NULL) { + + if (ngx_array_init(&ngx_old_cycles, ngx_temp_pool, n, + sizeof(ngx_cycle_t *)) + != NGX_OK) + { exit(1); } - ngx_old_cycles.nelts = 0; - ngx_old_cycles.size = sizeof(ngx_cycle_t *); - ngx_old_cycles.nalloc = n; - ngx_old_cycles.pool = ngx_temp_pool; + + ngx_memzero(ngx_old_cycles.elts, n * sizeof(ngx_cycle_t *)); ngx_cleaner_event.handler = ngx_clean_old_cycles; ngx_cleaner_event.log = cycle->log; @@ -1333,3 +1331,54 @@ ngx_clean_old_cycles(ngx_event_t *ev) ngx_old_cycles.nelts = 0; } } + + +void +ngx_set_shutdown_timer(ngx_cycle_t *cycle) +{ + ngx_core_conf_t *ccf; + + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); + + if (ccf->shutdown_timeout) { + ngx_shutdown_event.handler = ngx_shutdown_timer_handler; + ngx_shutdown_event.data = cycle; + ngx_shutdown_event.log = cycle->log; + ngx_shutdown_event.cancelable = 1; + + ngx_add_timer(&ngx_shutdown_event, ccf->shutdown_timeout); + } +} + + +static void +ngx_shutdown_timer_handler(ngx_event_t *ev) +{ + ngx_uint_t i; + ngx_cycle_t *cycle; + ngx_connection_t *c; + + cycle = ev->data; + + c = cycle->connections; + + for (i = 0; i < cycle->connection_n; i++) { + + if (c[i].fd == (ngx_socket_t) -1 + || c[i].read == NULL + || c[i].read->accept + || c[i].read->channel + || c[i].read->resolver) + { + continue; + } + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, + "*%uA shutdown timeout", c[i].number); + + c[i].close = 1; + c[i].error = 1; + + c[i].read->handler(c[i].read); + } +} diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h index d804eb4..2b48ccb 100644 --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -88,6 +88,7 @@ typedef struct { ngx_flag_t master; ngx_msec_t timer_resolution; + ngx_msec_t shutdown_timeout; ngx_int_t worker_processes; ngx_int_t debug_points; @@ -129,6 +130,7 @@ ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv); ngx_cpuset_t *ngx_get_cpu_affinity(ngx_uint_t n); ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag); +void ngx_set_shutdown_timer(ngx_cycle_t *cycle); extern volatile ngx_cycle_t *ngx_cycle; diff --git a/src/core/ngx_murmurhash.c b/src/core/ngx_murmurhash.c index c31e0e0..5ade658 100644 --- a/src/core/ngx_murmurhash.c +++ b/src/core/ngx_murmurhash.c @@ -35,8 +35,10 @@ ngx_murmur_hash2(u_char *data, size_t len) switch (len) { case 3: h ^= data[2] << 16; + /* fall through */ case 2: h ^= data[1] << 8; + /* fall through */ case 1: h ^= data[0]; h *= 0x5bd1e995; diff --git a/src/core/ngx_palloc.h b/src/core/ngx_palloc.h index d652829..376e012 100644 --- a/src/core/ngx_palloc.h +++ b/src/core/ngx_palloc.h @@ -72,9 +72,6 @@ typedef struct { } ngx_pool_cleanup_file_t; -void *ngx_alloc(size_t size, ngx_log_t *log); -void *ngx_calloc(size_t size, ngx_log_t *log); - ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log); void ngx_destroy_pool(ngx_pool_t *pool); void ngx_reset_pool(ngx_pool_t *pool); diff --git a/src/core/ngx_parse.c b/src/core/ngx_parse.c index 7b60c5f..d35e60f 100644 --- a/src/core/ngx_parse.c +++ b/src/core/ngx_parse.c @@ -17,6 +17,11 @@ ngx_parse_size(ngx_str_t *line) ssize_t size, scale, max; len = line->len; + + if (len == 0) { + return NGX_ERROR; + } + unit = line->data[len - 1]; switch (unit) { @@ -58,6 +63,11 @@ ngx_parse_offset(ngx_str_t *line) size_t len; len = line->len; + + if (len == 0) { + return NGX_ERROR; + } + unit = line->data[len - 1]; switch (unit) { diff --git a/src/core/ngx_rbtree.c b/src/core/ngx_rbtree.c index 6c66f40..969d549 100644 --- a/src/core/ngx_rbtree.c +++ b/src/core/ngx_rbtree.c @@ -28,7 +28,7 @@ ngx_rbtree_insert(ngx_rbtree_t *tree, ngx_rbtree_node_t *node) /* a binary tree insert */ - root = (ngx_rbtree_node_t **) &tree->root; + root = &tree->root; sentinel = tree->sentinel; if (*root == sentinel) { @@ -161,7 +161,7 @@ ngx_rbtree_delete(ngx_rbtree_t *tree, ngx_rbtree_node_t *node) /* a binary tree delete */ - root = (ngx_rbtree_node_t **) &tree->root; + root = &tree->root; sentinel = tree->sentinel; if (node->left == sentinel) { @@ -378,3 +378,32 @@ ngx_rbtree_right_rotate(ngx_rbtree_node_t **root, ngx_rbtree_node_t *sentinel, temp->right = node; node->parent = temp; } + + +ngx_rbtree_node_t * +ngx_rbtree_next(ngx_rbtree_t *tree, ngx_rbtree_node_t *node) +{ + ngx_rbtree_node_t *root, *sentinel, *parent; + + sentinel = tree->sentinel; + + if (node->right != sentinel) { + return ngx_rbtree_min(node->right, sentinel); + } + + root = tree->root; + + for ( ;; ) { + parent = node->parent; + + if (node == root) { + return NULL; + } + + if (node == parent->left) { + return parent; + } + + node = parent; + } +} diff --git a/src/core/ngx_rbtree.h b/src/core/ngx_rbtree.h index 1d33e3f..97f0e3e 100644 --- a/src/core/ngx_rbtree.h +++ b/src/core/ngx_rbtree.h @@ -54,6 +54,8 @@ void ngx_rbtree_insert_value(ngx_rbtree_node_t *root, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); void ngx_rbtree_insert_timer_value(ngx_rbtree_node_t *root, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); +ngx_rbtree_node_t *ngx_rbtree_next(ngx_rbtree_t *tree, + ngx_rbtree_node_t *node); #define ngx_rbt_red(node) ((node)->color = 1) diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c index 2065f75..e140ab6 100644 --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -56,8 +56,8 @@ typedef struct { ((u_char *) (n) - offsetof(ngx_resolver_node_t, node)) -ngx_int_t ngx_udp_connect(ngx_resolver_connection_t *rec); -ngx_int_t ngx_tcp_connect(ngx_resolver_connection_t *rec); +static ngx_int_t ngx_udp_connect(ngx_resolver_connection_t *rec); +static ngx_int_t ngx_tcp_connect(ngx_resolver_connection_t *rec); static void ngx_resolver_cleanup(void *data); @@ -4379,7 +4379,7 @@ ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len) } -ngx_int_t +static ngx_int_t ngx_udp_connect(ngx_resolver_connection_t *rec) { int rc; @@ -4463,7 +4463,7 @@ failed: } -ngx_int_t +static ngx_int_t ngx_tcp_connect(ngx_resolver_connection_t *rec) { int rc; diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c index 7a73ef5..7526f60 100644 --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -1808,7 +1808,19 @@ ngx_escape_json(u_char *dst, u_char *src, size_t size) len++; } else if (ch <= 0x1f) { - len += sizeof("\\u001F") - 2; + + switch (ch) { + case '\n': + case '\r': + case '\t': + case '\b': + case '\f': + len++; + break; + + default: + len += sizeof("\\u001F") - 2; + } } size--; @@ -1829,12 +1841,37 @@ ngx_escape_json(u_char *dst, u_char *src, size_t size) *dst++ = ch; } else { - *dst++ = '\\'; *dst++ = 'u'; *dst++ = '0'; *dst++ = '0'; - *dst++ = '0' + (ch >> 4); + *dst++ = '\\'; - ch &= 0xf; + switch (ch) { + case '\n': + *dst++ = 'n'; + break; - *dst++ = (ch < 10) ? ('0' + ch) : ('A' + ch - 10); + case '\r': + *dst++ = 'r'; + break; + + case '\t': + *dst++ = 't'; + break; + + case '\b': + *dst++ = 'b'; + break; + + case '\f': + *dst++ = 'f'; + break; + + default: + *dst++ = 'u'; *dst++ = '0'; *dst++ = '0'; + *dst++ = '0' + (ch >> 4); + + ch &= 0xf; + + *dst++ = (ch < 10) ? ('0' + ch) : ('A' + ch - 10); + } } size--; diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c index 39e480e..ee9f854 100644 --- a/src/event/modules/ngx_devpoll_module.c +++ b/src/event/modules/ngx_devpoll_module.c @@ -78,7 +78,7 @@ static ngx_command_t ngx_devpoll_commands[] = { }; -ngx_event_module_t ngx_devpoll_module_ctx = { +static ngx_event_module_t ngx_devpoll_module_ctx = { &devpoll_name, ngx_devpoll_create_conf, /* create configuration */ ngx_devpoll_init_conf, /* init configuration */ @@ -336,7 +336,7 @@ ngx_devpoll_set_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) } -ngx_int_t +static ngx_int_t ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags) { diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c index 760c69b..76aee08 100644 --- a/src/event/modules/ngx_epoll_module.c +++ b/src/event/modules/ngx_epoll_module.c @@ -176,7 +176,7 @@ static ngx_command_t ngx_epoll_commands[] = { }; -ngx_event_module_t ngx_epoll_module_ctx = { +static ngx_event_module_t ngx_epoll_module_ctx = { &epoll_name, ngx_epoll_create_conf, /* create configuration */ ngx_epoll_init_conf, /* init configuration */ diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c index 0413599..e723f92 100644 --- a/src/event/modules/ngx_eventport_module.c +++ b/src/event/modules/ngx_eventport_module.c @@ -169,7 +169,7 @@ static ngx_command_t ngx_eventport_commands[] = { }; -ngx_event_module_t ngx_eventport_module_ctx = { +static ngx_event_module_t ngx_eventport_module_ctx = { &eventport_name, ngx_eventport_create_conf, /* create configuration */ ngx_eventport_init_conf, /* init configuration */ @@ -432,7 +432,7 @@ ngx_eventport_notify(ngx_event_handler_pt handler) } -ngx_int_t +static ngx_int_t ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags) { diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c index ca3bfe4..9c7244c 100644 --- a/src/event/modules/ngx_kqueue_module.c +++ b/src/event/modules/ngx_kqueue_module.c @@ -73,7 +73,7 @@ static ngx_command_t ngx_kqueue_commands[] = { }; -ngx_event_module_t ngx_kqueue_module_ctx = { +static ngx_event_module_t ngx_kqueue_module_ctx = { &kqueue_name, ngx_kqueue_create_conf, /* create configuration */ ngx_kqueue_init_conf, /* init configuration */ diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c index a2a7079..4e03dab 100644 --- a/src/event/modules/ngx_poll_module.c +++ b/src/event/modules/ngx_poll_module.c @@ -25,9 +25,9 @@ static struct pollfd *event_list; static ngx_uint_t nevents; -static ngx_str_t poll_name = ngx_string("poll"); +static ngx_str_t poll_name = ngx_string("poll"); -ngx_event_module_t ngx_poll_module_ctx = { +static ngx_event_module_t ngx_poll_module_ctx = { &poll_name, NULL, /* create configuration */ ngx_poll_init_conf, /* init configuration */ diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c index 5a976bd..0644621 100644 --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -33,9 +33,9 @@ static ngx_uint_t nevents; static ngx_event_t **event_index; -static ngx_str_t select_name = ngx_string("select"); +static ngx_str_t select_name = ngx_string("select"); -ngx_event_module_t ngx_select_module_ctx = { +static ngx_event_module_t ngx_select_module_ctx = { &select_name, NULL, /* create configuration */ ngx_select_init_conf, /* init configuration */ diff --git a/src/event/modules/ngx_win32_select_module.c b/src/event/modules/ngx_win32_select_module.c index c671f83..a98a83f 100644 --- a/src/event/modules/ngx_win32_select_module.c +++ b/src/event/modules/ngx_win32_select_module.c @@ -34,9 +34,9 @@ static ngx_uint_t nevents; static ngx_event_t **event_index; -static ngx_str_t select_name = ngx_string("select"); +static ngx_str_t select_name = ngx_string("select"); -ngx_event_module_t ngx_select_module_ctx = { +static ngx_event_module_t ngx_select_module_ctx = { &select_name, NULL, /* create configuration */ ngx_select_init_conf, /* init configuration */ diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index 9d6c4c9..57af813 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -59,20 +59,20 @@ ngx_int_t ngx_accept_disabled; #if (NGX_STAT_STUB) -ngx_atomic_t ngx_stat_accepted0; -ngx_atomic_t *ngx_stat_accepted = &ngx_stat_accepted0; -ngx_atomic_t ngx_stat_handled0; -ngx_atomic_t *ngx_stat_handled = &ngx_stat_handled0; -ngx_atomic_t ngx_stat_requests0; -ngx_atomic_t *ngx_stat_requests = &ngx_stat_requests0; -ngx_atomic_t ngx_stat_active0; -ngx_atomic_t *ngx_stat_active = &ngx_stat_active0; -ngx_atomic_t ngx_stat_reading0; -ngx_atomic_t *ngx_stat_reading = &ngx_stat_reading0; -ngx_atomic_t ngx_stat_writing0; -ngx_atomic_t *ngx_stat_writing = &ngx_stat_writing0; -ngx_atomic_t ngx_stat_waiting0; -ngx_atomic_t *ngx_stat_waiting = &ngx_stat_waiting0; +static ngx_atomic_t ngx_stat_accepted0; +ngx_atomic_t *ngx_stat_accepted = &ngx_stat_accepted0; +static ngx_atomic_t ngx_stat_handled0; +ngx_atomic_t *ngx_stat_handled = &ngx_stat_handled0; +static ngx_atomic_t ngx_stat_requests0; +ngx_atomic_t *ngx_stat_requests = &ngx_stat_requests0; +static ngx_atomic_t ngx_stat_active0; +ngx_atomic_t *ngx_stat_active = &ngx_stat_active0; +static ngx_atomic_t ngx_stat_reading0; +ngx_atomic_t *ngx_stat_reading = &ngx_stat_reading0; +static ngx_atomic_t ngx_stat_writing0; +ngx_atomic_t *ngx_stat_writing = &ngx_stat_writing0; +static ngx_atomic_t ngx_stat_waiting0; +ngx_atomic_t *ngx_stat_waiting = &ngx_stat_waiting0; #endif @@ -165,7 +165,7 @@ static ngx_command_t ngx_event_core_commands[] = { }; -ngx_event_module_t ngx_event_core_module_ctx = { +static ngx_event_module_t ngx_event_core_module_ctx = { &event_core_name, ngx_event_core_create_conf, /* create configuration */ ngx_event_core_init_conf, /* init configuration */ @@ -500,8 +500,7 @@ ngx_event_module_init(ngx_cycle_t *cycle) #endif shm.size = size; - shm.name.len = sizeof("nginx_shared_zone") - 1; - shm.name.data = (u_char *) "nginx_shared_zone"; + ngx_str_set(&shm.name, "nginx_shared_zone"); shm.log = cycle->log; if (ngx_shm_alloc(&shm) != NGX_OK) { diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index 1fce2e8..87447d0 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -238,7 +238,7 @@ ngx_event_accept(ngx_event_t *ev) if (ev->deferred_accept) { rev->ready = 1; -#if (NGX_HAVE_KQUEUE) +#if (NGX_HAVE_KQUEUE || NGX_HAVE_EPOLLRDHUP) rev->available = 1; #endif } diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 3c74b7b..2c4e114 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -121,7 +121,17 @@ ngx_ssl_init(ngx_log_t *log) { #if OPENSSL_VERSION_NUMBER >= 0x10100003L - OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); + if (OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL) == 0) { + ngx_ssl_error(NGX_LOG_ALERT, log, 0, "OPENSSL_init_ssl() failed"); + return NGX_ERROR; + } + + /* + * OPENSSL_init_ssl() may leave errors in the error queue + * while returning success + */ + + ERR_clear_error(); #else @@ -313,6 +323,12 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data) SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_2); } #endif +#ifdef SSL_OP_NO_TLSv1_3 + SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TLSv1_3); + if (!(protocols & NGX_SSL_TLSv1_3)) { + SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_3); + } +#endif #ifdef SSL_OP_NO_COMPRESSION SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION); @@ -821,7 +837,9 @@ ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret) BIO *rbio, *wbio; ngx_connection_t *c; - if (where & SSL_CB_HANDSHAKE_START) { + if ((where & SSL_CB_HANDSHAKE_START) + && SSL_is_server((ngx_ssl_conn_t *) ssl_conn)) + { c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); if (c->ssl->handshaked) { @@ -1072,7 +1090,7 @@ ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name) * maximum interoperability. */ -#ifdef SSL_CTRL_SET_CURVES_LIST +#if (defined SSL_CTX_set1_curves_list || defined SSL_CTRL_SET_CURVES_LIST) /* * OpenSSL 1.0.2+ allows configuring a curve list instead of a single @@ -1282,7 +1300,7 @@ ngx_ssl_handshake(ngx_connection_t *c) #ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS /* initial handshake done, disable renegotiation (CVE-2009-3555) */ - if (c->ssl->connection->s3) { + if (c->ssl->connection->s3 && SSL_is_server(c->ssl->connection)) { c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; } diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index e093e10..2a14980 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -54,6 +54,11 @@ #define ngx_ssl_conn_t SSL +#if (OPENSSL_VERSION_NUMBER < 0x10002000L) +#define SSL_is_server(s) (s)->server +#endif + + struct ngx_ssl_s { SSL_CTX *ctx; ngx_log_t *log; @@ -131,6 +136,7 @@ typedef struct { #define NGX_SSL_TLSv1 0x0008 #define NGX_SSL_TLSv1_1 0x0010 #define NGX_SSL_TLSv1_2 0x0020 +#define NGX_SSL_TLSv1_3 0x0040 #define NGX_SSL_BUFFER 1 diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c index 8f547b2..698b88f 100644 --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -67,7 +67,7 @@ ngx_event_expire_timers(void) node = ngx_rbtree_min(root, sentinel); - /* node->key > ngx_current_time */ + /* node->key > ngx_current_msec */ if ((ngx_msec_int_t) (node->key - ngx_current_msec) > 0) { return; @@ -96,43 +96,31 @@ ngx_event_expire_timers(void) } -void -ngx_event_cancel_timers(void) +ngx_int_t +ngx_event_no_timers_left(void) { ngx_event_t *ev; ngx_rbtree_node_t *node, *root, *sentinel; sentinel = ngx_event_timer_rbtree.sentinel; + root = ngx_event_timer_rbtree.root; - for ( ;; ) { - root = ngx_event_timer_rbtree.root; - - if (root == sentinel) { - return; - } - - node = ngx_rbtree_min(root, sentinel); + if (root == sentinel) { + return NGX_OK; + } + for (node = ngx_rbtree_min(root, sentinel); + node; + node = ngx_rbtree_next(&ngx_event_timer_rbtree, node)) + { ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); if (!ev->cancelable) { - return; + return NGX_AGAIN; } - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, - "event timer cancel: %d: %M", - ngx_event_ident(ev->data), ev->timer.key); - - ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); - -#if (NGX_DEBUG) - ev->timer.left = NULL; - ev->timer.right = NULL; - ev->timer.parent = NULL; -#endif - - ev->timer_set = 0; - - ev->handler(ev); } + + /* only cancelable timers left */ + + return NGX_OK; } diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h index 99f8a48..be81b15 100644 --- a/src/event/ngx_event_timer.h +++ b/src/event/ngx_event_timer.h @@ -22,7 +22,7 @@ ngx_int_t ngx_event_timer_init(ngx_log_t *log); ngx_msec_t ngx_event_find_timer(void); void ngx_event_expire_timers(void); -void ngx_event_cancel_timers(void); +ngx_int_t ngx_event_no_timers_left(void); extern ngx_rbtree_t ngx_event_timer_rbtree; diff --git a/src/http/modules/ngx_http_access_module.c b/src/http/modules/ngx_http_access_module.c index c553e46..7355de9 100644 --- a/src/http/modules/ngx_http_access_module.c +++ b/src/http/modules/ngx_http_access_module.c @@ -309,28 +309,22 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_http_access_rule_un_t *rule_un; #endif + all = 0; ngx_memzero(&cidr, sizeof(ngx_cidr_t)); value = cf->args->elts; - all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0); - - if (!all) { + if (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0) { + all = 1; #if (NGX_HAVE_UNIX_DOMAIN) - - if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) { - cidr.family = AF_UNIX; - rc = NGX_OK; - - } else { - rc = ngx_ptocidr(&value[1], &cidr); - } - -#else - rc = ngx_ptocidr(&value[1], &cidr); + } else if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) { + cidr.family = AF_UNIX; #endif + } else { + rc = ngx_ptocidr(&value[1], &cidr); + if (rc == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[1]); diff --git a/src/http/modules/ngx_http_auth_basic_module.c b/src/http/modules/ngx_http_auth_basic_module.c index 1e7a0c2..4aa684f 100644 --- a/src/http/modules/ngx_http_auth_basic_module.c +++ b/src/http/modules/ngx_http_auth_basic_module.c @@ -361,6 +361,8 @@ ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm) basic = ngx_pnalloc(r->pool, len); if (basic == NULL) { + r->headers_out.www_authenticate->hash = 0; + r->headers_out.www_authenticate = NULL; return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c index 4ea9818..e52b96e 100644 --- a/src/http/modules/ngx_http_charset_filter_module.c +++ b/src/http/modules/ngx_http_charset_filter_module.c @@ -123,7 +123,7 @@ static char *ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, static ngx_int_t ngx_http_charset_postconfiguration(ngx_conf_t *cf); -ngx_str_t ngx_http_charset_default_types[] = { +static ngx_str_t ngx_http_charset_default_types[] = { ngx_string("text/html"), ngx_string("text/xml"), ngx_string("text/plain"), diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c index 895a52d..566b08b 100644 --- a/src/http/modules/ngx_http_dav_module.c +++ b/src/http/modules/ngx_http_dav_module.c @@ -1080,6 +1080,7 @@ ngx_http_dav_location(ngx_http_request_t *r, u_char *path) } else { location = ngx_pnalloc(r->pool, r->uri.len); if (location == NULL) { + ngx_http_clear_location(r); return NGX_ERROR; } diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c index c7c417b..741e577 100644 --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -211,6 +211,7 @@ static ngx_conf_bitmask_t ngx_http_fastcgi_next_upstream_masks[] = { { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, + { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 }, { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, { ngx_null_string, 0 } @@ -469,6 +470,13 @@ static ngx_command_t ngx_http_fastcgi_commands[] = { offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_revalidate), NULL }, + { ngx_string("fastcgi_cache_background_update"), + 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_fastcgi_loc_conf_t, upstream.cache_background_update), + NULL }, + #endif { ngx_string("fastcgi_temp_path"), @@ -1870,6 +1878,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r) p = ngx_pnalloc(r->pool, size); if (p == NULL) { + h->hash = 0; return NGX_ERROR; } @@ -1892,6 +1901,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r) ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "invalid header after joining " "FastCGI records"); + h->hash = 0; return NGX_ERROR; } @@ -1917,6 +1927,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r) h->key.len + 1 + h->value.len + 1 + h->key.len); if (h->key.data == NULL) { + h->hash = 0; return NGX_ERROR; } @@ -2769,6 +2780,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf) conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC; conf->upstream.cache_revalidate = NGX_CONF_UNSET; + conf->upstream.cache_background_update = NGX_CONF_UNSET; #endif conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; @@ -3061,6 +3073,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_value(conf->upstream.cache_revalidate, prev->upstream.cache_revalidate, 0); + ngx_conf_merge_value(conf->upstream.cache_background_update, + prev->upstream.cache_background_update, 0); + #endif ngx_conf_merge_value(conf->upstream.pass_request_headers, diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c index cc25320..7b72fae 100644 --- a/src/http/modules/ngx_http_flv_module.c +++ b/src/http/modules/ngx_http_flv_module.c @@ -203,7 +203,7 @@ ngx_http_flv_handler(ngx_http_request_t *r) } if (i == 0) { - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -217,7 +217,7 @@ ngx_http_flv_handler(ngx_http_request_t *r) } - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c index 536fdf8..287fd36 100644 --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -644,7 +644,7 @@ ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) static u_char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 }; - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_ERROR; } @@ -671,6 +671,8 @@ ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) static ngx_int_t ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) { + ngx_chain_t *cl; + if (ctx->zstream.avail_in || ctx->flush != Z_NO_FLUSH || ctx->redo) { return NGX_OK; } @@ -694,13 +696,16 @@ ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) ctx->copy_buf = NULL; } - ctx->in_buf = ctx->in->buf; + cl = ctx->in; + ctx->in_buf = cl->buf; + ctx->in = cl->next; if (ctx->in_buf->tag == (ngx_buf_tag_t) &ngx_http_gzip_filter_module) { - ctx->copy_buf = ctx->in; - } + ctx->copy_buf = cl; - ctx->in = ctx->in->next; + } else { + ngx_free_chain(r->pool, cl); + } ctx->zstream.next_in = ctx->in_buf->pos; ctx->zstream.avail_in = ctx->in_buf->last - ctx->in_buf->pos; @@ -733,6 +738,7 @@ ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) static ngx_int_t ngx_http_gzip_filter_get_buf(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) { + ngx_chain_t *cl; ngx_http_gzip_conf_t *conf; if (ctx->zstream.avail_out) { @@ -742,8 +748,12 @@ ngx_http_gzip_filter_get_buf(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module); if (ctx->free) { - ctx->out_buf = ctx->free->buf; - ctx->free = ctx->free->next; + + cl = ctx->free; + ctx->out_buf = cl->buf; + ctx->free = cl->next; + + ngx_free_chain(r->pool, cl); } else if (ctx->bufs < conf->bufs.num) { diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c index 4d54090..7652a9a 100644 --- a/src/http/modules/ngx_http_gzip_static_module.c +++ b/src/http/modules/ngx_http_gzip_static_module.c @@ -48,7 +48,7 @@ static ngx_command_t ngx_http_gzip_static_commands[] = { }; -ngx_http_module_t ngx_http_gzip_static_module_ctx = { +static ngx_http_module_t ngx_http_gzip_static_module_ctx = { NULL, /* preconfiguration */ ngx_http_gzip_static_init, /* postconfiguration */ @@ -238,7 +238,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r) h = ngx_list_push(&r->headers_out.headers); if (h == NULL) { - return NGX_ERROR; + return NGX_HTTP_INTERNAL_SERVER_ERROR; } h->hash = 1; @@ -248,7 +248,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r) /* we need to allocate all before the header would be sent */ - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c index 6738afe..94dc51e 100644 --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -173,6 +173,7 @@ ngx_http_headers_filter(ngx_http_request_t *r) case NGX_HTTP_SEE_OTHER: case NGX_HTTP_NOT_MODIFIED: case NGX_HTTP_TEMPORARY_REDIRECT: + case NGX_HTTP_PERMANENT_REDIRECT: safe_status = 1; break; @@ -270,11 +271,6 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) return NGX_ERROR; } - ccp = ngx_array_push(&r->headers_out.cache_control); - if (ccp == NULL) { - return NGX_ERROR; - } - cc = ngx_list_push(&r->headers_out.headers); if (cc == NULL) { return NGX_ERROR; @@ -282,6 +278,12 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) cc->hash = 1; ngx_str_set(&cc->key, "Cache-Control"); + + ccp = ngx_array_push(&r->headers_out.cache_control); + if (ccp == NULL) { + return NGX_ERROR; + } + *ccp = cc; } else { @@ -469,11 +471,6 @@ ngx_http_add_cache_control(ngx_http_request_t *r, ngx_http_header_val_t *hv, } } - ccp = ngx_array_push(&r->headers_out.cache_control); - if (ccp == NULL) { - return NGX_ERROR; - } - cc = ngx_list_push(&r->headers_out.headers); if (cc == NULL) { return NGX_ERROR; @@ -483,6 +480,11 @@ ngx_http_add_cache_control(ngx_http_request_t *r, ngx_http_header_val_t *hv, ngx_str_set(&cc->key, "Cache-Control"); cc->value = *value; + ccp = ngx_array_push(&r->headers_out.cache_control); + if (ccp == NULL) { + return NGX_ERROR; + } + *ccp = cc; return NGX_OK; diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c index dbec5d8..6c03e8a 100644 --- a/src/http/modules/ngx_http_image_filter_module.c +++ b/src/http/modules/ngx_http_image_filter_module.c @@ -581,7 +581,7 @@ ngx_http_image_json(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) size_t len; ngx_buf_t *b; - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { return NULL; } @@ -633,7 +633,7 @@ ngx_http_image_asis(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) { ngx_buf_t *b; - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { return NULL; } @@ -1067,7 +1067,7 @@ transparent: return NULL; } - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { gdFree(out); return NULL; diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c index d3544db..c144b31 100644 --- a/src/http/modules/ngx_http_index_module.c +++ b/src/http/modules/ngx_http_index_module.c @@ -217,13 +217,13 @@ ngx_http_index_handler(ngx_http_request_t *r) if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) != NGX_OK) { - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err, - "%s \"%s\" failed", of.failed, path.data); - if (of.err == 0) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err, + "%s \"%s\" failed", of.failed, path.data); + #if (NGX_HAVE_OPENAT) if (of.err == NGX_EMLINK || of.err == NGX_ELOOP) diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c index 2f695f2..579b13c 100644 --- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -276,6 +276,8 @@ ngx_http_limit_req_handler(ngx_http_request_t *r) r->read_event_handler = ngx_http_test_reading; r->write_event_handler = ngx_http_limit_req_delay; + + r->connection->write->delayed = 1; ngx_add_timer(r->connection->write, delay); return NGX_AGAIN; @@ -292,7 +294,7 @@ ngx_http_limit_req_delay(ngx_http_request_t *r) wev = r->connection->write; - if (!wev->timedout) { + if (wev->delayed) { if (ngx_handle_write_event(wev, 0) != NGX_OK) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); @@ -301,8 +303,6 @@ ngx_http_limit_req_delay(ngx_http_request_t *r) return; } - wev->timedout = 0; - if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c index ff8572b..917ed55 100644 --- a/src/http/modules/ngx_http_log_module.c +++ b/src/http/modules/ngx_http_log_module.c @@ -552,6 +552,11 @@ ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script, if (ngx_open_cached_file(llcf->open_file_cache, &log, &of, r->pool) != NGX_OK) { + if (of.err == 0) { + /* simulate successful logging */ + return len; + } + ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, "%s \"%s\" failed", of.failed, log.data); /* simulate successful logging */ @@ -748,23 +753,10 @@ ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log) static void ngx_http_log_flush_handler(ngx_event_t *ev) { - ngx_open_file_t *file; - ngx_http_log_buf_t *buffer; - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "http log buffer flush handler"); - if (ev->timedout) { - ngx_http_log_flush(ev->data, ev->log); - return; - } - - /* cancel the flush timer for graceful shutdown */ - - file = ev->data; - buffer = file->data; - - buffer->event = NULL; + ngx_http_log_flush(ev->data, ev->log); } diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c index f3c0fdd..08a68d0 100644 --- a/src/http/modules/ngx_http_mp4_module.c +++ b/src/http/modules/ngx_http_mp4_module.c @@ -636,7 +636,7 @@ ngx_http_mp4_handler(ngx_http_request_t *r) } if (mp4 == NULL) { - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index 42b6afc..839d479 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -220,6 +220,7 @@ static ngx_conf_bitmask_t ngx_http_proxy_next_upstream_masks[] = { { ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 }, { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, + { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 }, { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, { ngx_null_string, 0 } @@ -234,6 +235,7 @@ static ngx_conf_bitmask_t ngx_http_proxy_ssl_protocols[] = { { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, + { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 }, { ngx_null_string, 0 } }; @@ -548,6 +550,13 @@ static ngx_command_t ngx_http_proxy_commands[] = { offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_convert_head), NULL }, + { ngx_string("proxy_cache_background_update"), + 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.cache_background_update), + NULL }, + #endif { ngx_string("proxy_temp_path"), @@ -1789,6 +1798,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r) h->key.data = ngx_pnalloc(r->pool, h->key.len + 1 + h->value.len + 1 + h->key.len); if (h->key.data == NULL) { + h->hash = 0; return NGX_ERROR; } @@ -2863,6 +2873,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC; conf->upstream.cache_revalidate = NGX_CONF_UNSET; conf->upstream.cache_convert_head = NGX_CONF_UNSET; + conf->upstream.cache_background_update = NGX_CONF_UNSET; #endif conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; @@ -3168,6 +3179,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_value(conf->upstream.cache_convert_head, prev->upstream.cache_convert_head, 1); + ngx_conf_merge_value(conf->upstream.cache_background_update, + prev->upstream.cache_background_update, 0); + #endif if (conf->method == NULL) { diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c index 951a00d..8ffca82 100644 --- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -425,6 +425,8 @@ ngx_http_range_singlepart_header(ngx_http_request_t *r, content_range->value.data = ngx_pnalloc(r->pool, sizeof("bytes -/") - 1 + 3 * NGX_OFF_T_LEN); if (content_range->value.data == NULL) { + content_range->hash = 0; + r->headers_out.content_range = NULL; return NGX_ERROR; } @@ -594,6 +596,8 @@ ngx_http_range_not_satisfiable(ngx_http_request_t *r) content_range->value.data = ngx_pnalloc(r->pool, sizeof("bytes */") - 1 + NGX_OFF_T_LEN); if (content_range->value.data == NULL) { + content_range->hash = 0; + r->headers_out.content_range = NULL; return NGX_ERROR; } diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c index 5e3355c..e1839e6 100644 --- a/src/http/modules/ngx_http_realip_module.c +++ b/src/http/modules/ngx_http_realip_module.c @@ -317,9 +317,15 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_realip_loc_conf_t *rlcf = conf; - ngx_int_t rc; - ngx_str_t *value; - ngx_cidr_t *cidr; + ngx_int_t rc; + ngx_str_t *value; + ngx_url_t u; + ngx_cidr_t c, *cidr; + ngx_uint_t i; + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif value = cf->args->elts; @@ -331,31 +337,78 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } } - cidr = ngx_array_push(rlcf->from); - if (cidr == NULL) { - return NGX_CONF_ERROR; - } - #if (NGX_HAVE_UNIX_DOMAIN) if (ngx_strcmp(value[1].data, "unix:") == 0) { + cidr = ngx_array_push(rlcf->from); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + cidr->family = AF_UNIX; return NGX_CONF_OK; } #endif - rc = ngx_ptocidr(&value[1], cidr); + rc = ngx_ptocidr(&value[1], &c); + + if (rc != NGX_ERROR) { + if (rc == NGX_DONE) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "low address bits of %V are meaningless", + &value[1]); + } + + cidr = ngx_array_push(rlcf->from); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + + *cidr = c; + + return NGX_CONF_OK; + } + + ngx_memzero(&u, sizeof(ngx_url_t)); + u.host = value[1]; + + if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { + if (u.err) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "%s in set_real_ip_from \"%V\"", + u.err, &u.host); + } - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", - &value[1]); return NGX_CONF_ERROR; } - if (rc == NGX_DONE) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "low address bits of %V are meaningless", &value[1]); + cidr = ngx_array_push_n(rlcf->from, u.naddrs); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t)); + + for (i = 0; i < u.naddrs; i++) { + cidr[i].family = u.addrs[i].sockaddr->sa_family; + + switch (cidr[i].family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr; + cidr[i].u.in6.addr = sin6->sin6_addr; + ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16); + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) u.addrs[i].sockaddr; + cidr[i].u.in.addr = sin->sin_addr.s_addr; + cidr[i].u.in.mask = 0xffffffff; + break; + } } return NGX_CONF_OK; diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c index 6b2444c..a6f1fc8 100644 --- a/src/http/modules/ngx_http_rewrite_module.c +++ b/src/http/modules/ngx_http_rewrite_module.c @@ -917,7 +917,8 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) value[1].len--; value[1].data++; - v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE); + v = ngx_http_add_variable(cf, &value[1], + NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_WEAK); if (v == NULL) { return NGX_CONF_ERROR; } @@ -927,15 +928,7 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - if (v->get_handler == NULL - && ngx_strncasecmp(value[1].data, (u_char *) "http_", 5) != 0 - && ngx_strncasecmp(value[1].data, (u_char *) "sent_http_", 10) != 0 - && ngx_strncasecmp(value[1].data, (u_char *) "upstream_http_", 14) != 0 - && ngx_strncasecmp(value[1].data, (u_char *) "cookie_", 7) != 0 - && ngx_strncasecmp(value[1].data, (u_char *) "upstream_cookie_", 16) - != 0 - && ngx_strncasecmp(value[1].data, (u_char *) "arg_", 4) != 0) - { + if (v->get_handler == NULL) { v->get_handler = ngx_http_rewrite_var; v->data = index; } diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c index aa84a3d..9204af4 100644 --- a/src/http/modules/ngx_http_scgi_module.c +++ b/src/http/modules/ngx_http_scgi_module.c @@ -82,6 +82,7 @@ static ngx_conf_bitmask_t ngx_http_scgi_next_upstream_masks[] = { { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, + { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 }, { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, { ngx_null_string, 0 } @@ -319,6 +320,13 @@ static ngx_command_t ngx_http_scgi_commands[] = { offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_revalidate), NULL }, + { ngx_string("scgi_cache_background_update"), + 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_scgi_loc_conf_t, upstream.cache_background_update), + NULL }, + #endif { ngx_string("scgi_temp_path"), @@ -1032,6 +1040,7 @@ ngx_http_scgi_process_header(ngx_http_request_t *r) h->key.len + 1 + h->value.len + 1 + h->key.len); if (h->key.data == NULL) { + h->hash = 0; return NGX_ERROR; } @@ -1219,6 +1228,7 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t *cf) conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC; conf->upstream.cache_revalidate = NGX_CONF_UNSET; + conf->upstream.cache_background_update = NGX_CONF_UNSET; #endif conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; @@ -1506,6 +1516,9 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_value(conf->upstream.cache_revalidate, prev->upstream.cache_revalidate, 0); + ngx_conf_merge_value(conf->upstream.cache_background_update, + prev->upstream.cache_background_update, 0); + #endif ngx_conf_merge_value(conf->upstream.pass_request_headers, diff --git a/src/http/modules/ngx_http_slice_filter_module.c b/src/http/modules/ngx_http_slice_filter_module.c index 5e149b4..7758342 100644 --- a/src/http/modules/ngx_http_slice_filter_module.c +++ b/src/http/modules/ngx_http_slice_filter_module.c @@ -11,23 +11,25 @@ typedef struct { - size_t size; + size_t size; } ngx_http_slice_loc_conf_t; typedef struct { - off_t start; - off_t end; - ngx_str_t range; - ngx_str_t etag; - ngx_uint_t last; /* unsigned last:1; */ + off_t start; + off_t end; + ngx_str_t range; + ngx_str_t etag; + unsigned last:1; + unsigned active:1; + ngx_http_request_t *sr; } ngx_http_slice_ctx_t; typedef struct { - off_t start; - off_t end; - off_t complete_length; + off_t start; + off_t end; + off_t complete_length; } ngx_http_slice_content_range_t; @@ -169,6 +171,7 @@ ngx_http_slice_header_filter(ngx_http_request_t *r) } ctx->start = end; + ctx->active = 1; r->headers_out.status = NGX_HTTP_OK; r->headers_out.status_line.len = 0; @@ -209,7 +212,6 @@ ngx_http_slice_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { ngx_int_t rc; ngx_chain_t *cl; - ngx_http_request_t *sr; ngx_http_slice_ctx_t *ctx; ngx_http_slice_loc_conf_t *slcf; @@ -234,6 +236,16 @@ ngx_http_slice_body_filter(ngx_http_request_t *r, ngx_chain_t *in) return rc; } + if (ctx->sr && !ctx->sr->done) { + return rc; + } + + if (!ctx->active) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "missing slice response"); + return NGX_ERROR; + } + if (ctx->start >= ctx->end) { ngx_http_set_ctx(r, NULL, ngx_http_slice_filter_module); ngx_http_send_special(r, NGX_HTTP_LAST); @@ -244,11 +256,14 @@ ngx_http_slice_body_filter(ngx_http_request_t *r, ngx_chain_t *in) return rc; } - if (ngx_http_subrequest(r, &r->uri, &r->args, &sr, NULL, 0) != NGX_OK) { + if (ngx_http_subrequest(r, &r->uri, &r->args, &ctx->sr, NULL, + NGX_HTTP_SUBREQUEST_CLONE) + != NGX_OK) + { return NGX_ERROR; } - ngx_http_set_ctx(sr, ctx, ngx_http_slice_filter_module); + ngx_http_set_ctx(ctx->sr, ctx, ngx_http_slice_filter_module); slcf = ngx_http_get_module_loc_conf(r, ngx_http_slice_filter_module); @@ -256,6 +271,8 @@ ngx_http_slice_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ctx->start + (off_t) slcf->size - 1) - ctx->range.data; + ctx->active = 0; + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http slice subrequest: \"%V\"", &ctx->range); diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index 2771ac1..b466e5d 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -57,6 +57,7 @@ static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = { { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, + { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 }, { ngx_null_string, 0 } }; diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c index 07b9580..0e16c05 100644 --- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_static_module.c @@ -14,7 +14,7 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r); static ngx_int_t ngx_http_static_init(ngx_conf_t *cf); -ngx_http_module_t ngx_http_static_module_ctx = { +static ngx_http_module_t ngx_http_static_module_ctx = { NULL, /* preconfiguration */ ngx_http_static_init, /* postconfiguration */ @@ -169,6 +169,7 @@ ngx_http_static_handler(ngx_http_request_t *r) location = ngx_pnalloc(r->pool, len); if (location == NULL) { + ngx_http_clear_location(r); return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -233,7 +234,7 @@ ngx_http_static_handler(ngx_http_request_t *r) /* we need to allocate all before the header would be sent */ - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c index de58c6f..6d3de59 100644 --- a/src/http/modules/ngx_http_sub_filter_module.c +++ b/src/http/modules/ngx_http_sub_filter_module.c @@ -248,8 +248,6 @@ ngx_http_sub_header_filter(ngx_http_request_t *r) ctx->matches->nelts); } - ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module); - ctx->saved.data = ngx_pnalloc(r->pool, ctx->tables->max_match_len - 1); if (ctx->saved.data == NULL) { return NGX_ERROR; @@ -260,6 +258,8 @@ ngx_http_sub_header_filter(ngx_http_request_t *r) return NGX_ERROR; } + ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module); + ctx->offset = ctx->tables->min_match_len - 1; ctx->last_out = &ctx->out; diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c index b9c8dba..a2bec4c 100644 --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -114,6 +114,7 @@ static ngx_conf_bitmask_t ngx_http_uwsgi_next_upstream_masks[] = { { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, + { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 }, { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, { ngx_null_string, 0 } @@ -128,6 +129,7 @@ static ngx_conf_bitmask_t ngx_http_uwsgi_ssl_protocols[] = { { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, + { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 }, { ngx_null_string, 0 } }; @@ -379,6 +381,13 @@ static ngx_command_t ngx_http_uwsgi_commands[] = { offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_revalidate), NULL }, + { ngx_string("uwsgi_cache_background_update"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_background_update), + NULL }, + #endif { ngx_string("uwsgi_temp_path"), @@ -1235,6 +1244,7 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r) h->key.len + 1 + h->value.len + 1 + h->key.len); if (h->key.data == NULL) { + h->hash = 0; return NGX_ERROR; } @@ -1425,6 +1435,7 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf) conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC; conf->upstream.cache_revalidate = NGX_CONF_UNSET; + conf->upstream.cache_background_update = NGX_CONF_UNSET; #endif conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; @@ -1720,6 +1731,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_value(conf->upstream.cache_revalidate, prev->upstream.cache_revalidate, 0); + ngx_conf_merge_value(conf->upstream.cache_background_update, + prev->upstream.cache_background_update, 0); + #endif ngx_conf_merge_value(conf->upstream.pass_request_headers, diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c index 315081e..fae5895 100644 --- a/src/http/modules/ngx_http_xslt_filter_module.c +++ b/src/http/modules/ngx_http_xslt_filter_module.c @@ -109,7 +109,7 @@ static ngx_int_t ngx_http_xslt_filter_init(ngx_conf_t *cf); static void ngx_http_xslt_filter_exit(ngx_cycle_t *cycle); -ngx_str_t ngx_http_xslt_default_types[] = { +static ngx_str_t ngx_http_xslt_default_types[] = { ngx_string("text/xml"), ngx_null_string }; @@ -584,7 +584,7 @@ ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r, return NULL; } - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { ngx_free(buf); return NULL; diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm index e3f7361..d4663dc 100644 --- a/src/http/modules/perl/nginx.pm +++ b/src/http/modules/perl/nginx.pm @@ -24,6 +24,7 @@ our @EXPORT = qw( HTTP_SEE_OTHER HTTP_NOT_MODIFIED HTTP_TEMPORARY_REDIRECT + HTTP_PERMANENT_REDIRECT HTTP_BAD_REQUEST HTTP_UNAUTHORIZED @@ -72,6 +73,7 @@ use constant HTTP_REDIRECT => 302; use constant HTTP_SEE_OTHER => 303; use constant HTTP_NOT_MODIFIED => 304; use constant HTTP_TEMPORARY_REDIRECT => 307; +use constant HTTP_PERMANENT_REDIRECT => 308; use constant HTTP_BAD_REQUEST => 400; use constant HTTP_UNAUTHORIZED => 401; diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs index 6716620..ad12632 100644 --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -510,10 +510,12 @@ header_out(r, key, value) header->hash = 1; if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) { + header->hash = 0; XSRETURN_EMPTY; } if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) { + header->hash = 0; XSRETURN_EMPTY; } @@ -1001,6 +1003,7 @@ sleep(r, sleep, next) ctx->next = SvRV(ST(2)); + r->connection->write->delayed = 1; ngx_add_timer(r->connection->write, sleep); r->write_event_handler = ngx_http_perl_sleep_handler; diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c index 2796319..6d3be91 100644 --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -278,15 +278,16 @@ ngx_http_perl_sleep_handler(ngx_http_request_t *r) wev = r->connection->write; - if (wev->timedout) { - wev->timedout = 0; - ngx_http_perl_handle_request(r); + if (wev->delayed) { + + if (ngx_handle_write_event(wev, 0) != NGX_OK) { + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + } + return; } - if (ngx_handle_write_event(wev, 0) != NGX_OK) { - ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - } + ngx_http_perl_handle_request(r); } diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h index 4075f3d..f9e9664 100644 --- a/src/http/ngx_http_cache.h +++ b/src/http/ngx_http_cache.h @@ -24,10 +24,10 @@ #define NGX_HTTP_CACHE_SCARCE 8 #define NGX_HTTP_CACHE_KEY_LEN 16 -#define NGX_HTTP_CACHE_ETAG_LEN 42 -#define NGX_HTTP_CACHE_VARY_LEN 42 +#define NGX_HTTP_CACHE_ETAG_LEN 128 +#define NGX_HTTP_CACHE_VARY_LEN 128 -#define NGX_HTTP_CACHE_VERSION 3 +#define NGX_HTTP_CACHE_VERSION 5 typedef struct { @@ -71,6 +71,8 @@ struct ngx_http_cache_s { ngx_file_uniq_t uniq; time_t valid_sec; + time_t updating_sec; + time_t error_sec; time_t last_modified; time_t date; @@ -114,12 +116,18 @@ struct ngx_http_cache_s { unsigned purged:1; unsigned reading:1; unsigned secondary:1; + unsigned background:1; + + unsigned stale_updating:1; + unsigned stale_error:1; }; typedef struct { ngx_uint_t version; time_t valid_sec; + time_t updating_sec; + time_t error_sec; time_t last_modified; time_t date; uint32_t crc32; diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c index c696fb6..c8ad5da 100644 --- a/src/http/ngx_http_copy_filter_module.c +++ b/src/http/ngx_http_copy_filter_module.c @@ -187,15 +187,24 @@ static void ngx_http_copy_aio_event_handler(ngx_event_t *ev) { ngx_event_aio_t *aio; + ngx_connection_t *c; ngx_http_request_t *r; aio = ev->data; r = aio->data; + c = r->connection; + + ngx_http_set_log_request(c->log, r); + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http aio: \"%V?%V\"", &r->uri, &r->args); r->main->blocked--; r->aio = 0; - r->connection->write->handler(r->connection->write); + r->write_event_handler(r); + + ngx_http_run_posted_requests(c); } @@ -300,14 +309,33 @@ ngx_http_copy_thread_handler(ngx_thread_task_t *task, ngx_file_t *file) static void ngx_http_copy_thread_event_handler(ngx_event_t *ev) { + ngx_connection_t *c; ngx_http_request_t *r; r = ev->data; + c = r->connection; + + ngx_http_set_log_request(c->log, r); + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http thread: \"%V?%V\"", &r->uri, &r->args); r->main->blocked--; r->aio = 0; - r->connection->write->handler(r->connection->write); + if (r->done) { + /* + * trigger connection event handler if the subrequest was + * already finalized; this can happen if the handler is used + * for sendfile() in threads + */ + + c->write->handler(c->write); + + } else { + r->write_event_handler(r); + ngx_http_run_posted_requests(c); + } } #endif diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 666d96f..7e40e78 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -120,6 +120,14 @@ static ngx_conf_enum_t ngx_http_core_lingering_close[] = { }; +static ngx_conf_enum_t ngx_http_core_server_tokens[] = { + { ngx_string("off"), NGX_HTTP_SERVER_TOKENS_OFF }, + { ngx_string("on"), NGX_HTTP_SERVER_TOKENS_ON }, + { ngx_string("build"), NGX_HTTP_SERVER_TOKENS_BUILD }, + { ngx_null_string, 0 } +}; + + static ngx_conf_enum_t ngx_http_core_if_modified_since[] = { { ngx_string("off"), NGX_HTTP_IMS_OFF }, { ngx_string("exact"), NGX_HTTP_IMS_EXACT }, @@ -599,11 +607,11 @@ static ngx_command_t ngx_http_core_commands[] = { NULL }, { ngx_string("server_tokens"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_enum_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, server_tokens), - NULL }, + &ngx_http_core_server_tokens }, { ngx_string("if_modified_since"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, @@ -994,6 +1002,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r, p = ngx_pnalloc(r->pool, len); if (p == NULL) { + ngx_http_clear_location(r); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_OK; } @@ -1306,6 +1315,11 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r, if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) != NGX_OK) { + if (of.err == 0) { + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_OK; + } + if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR && of.err != NGX_ENAMETOOLONG) @@ -1881,7 +1895,8 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status, if (status == NGX_HTTP_MOVED_PERMANENTLY || status == NGX_HTTP_MOVED_TEMPORARILY || status == NGX_HTTP_SEE_OTHER - || status == NGX_HTTP_TEMPORARY_REDIRECT) + || status == NGX_HTTP_TEMPORARY_REDIRECT + || status == NGX_HTTP_PERMANENT_REDIRECT) { ngx_http_clear_location(r); @@ -1913,7 +1928,7 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status, return ngx_http_send_header(r); } - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -2503,6 +2518,7 @@ ngx_http_subrequest(ngx_http_request_t *r, sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0; sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0; + sr->background = (flags & NGX_HTTP_SUBREQUEST_BACKGROUND) != 0; sr->unparsed_uri = r->unparsed_uri; sr->method_name = ngx_http_core_get_method; @@ -2516,29 +2532,31 @@ ngx_http_subrequest(ngx_http_request_t *r, sr->read_event_handler = ngx_http_request_empty_handler; sr->write_event_handler = ngx_http_handler; - if (c->data == r && r->postponed == NULL) { - c->data = sr; - } - sr->variables = r->variables; sr->log_handler = r->log_handler; - pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t)); - if (pr == NULL) { - return NGX_ERROR; - } + if (!sr->background) { + if (c->data == r && r->postponed == NULL) { + c->data = sr; + } - pr->request = sr; - pr->out = NULL; - pr->next = NULL; + pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t)); + if (pr == NULL) { + return NGX_ERROR; + } - if (r->postponed) { - for (p = r->postponed; p->next; p = p->next) { /* void */ } - p->next = pr; + pr->request = sr; + pr->out = NULL; + pr->next = NULL; - } else { - r->postponed = pr; + if (r->postponed) { + for (p = r->postponed; p->next; p = p->next) { /* void */ } + p->next = pr; + + } else { + r->postponed = pr; + } } sr->internal = 1; @@ -2558,6 +2576,18 @@ ngx_http_subrequest(ngx_http_request_t *r, *psr = sr; + if (flags & NGX_HTTP_SUBREQUEST_CLONE) { + sr->method = r->method; + sr->method_name = r->method_name; + sr->loc_conf = r->loc_conf; + sr->valid_location = r->valid_location; + sr->content_handler = r->content_handler; + sr->phase_handler = r->phase_handler; + sr->write_event_handler = ngx_http_core_run_phases; + + ngx_http_update_location_config(sr); + } + return ngx_http_post_request(sr, NULL); } @@ -3576,9 +3606,9 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf) clcf->log_not_found = NGX_CONF_UNSET; clcf->log_subrequest = NGX_CONF_UNSET; clcf->recursive_error_pages = NGX_CONF_UNSET; - clcf->server_tokens = NGX_CONF_UNSET; clcf->chunked_transfer_encoding = NGX_CONF_UNSET; clcf->etag = NGX_CONF_UNSET; + clcf->server_tokens = NGX_CONF_UNSET_UINT; clcf->types_hash_max_size = NGX_CONF_UNSET_UINT; clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT; @@ -3842,11 +3872,13 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0); ngx_conf_merge_value(conf->recursive_error_pages, prev->recursive_error_pages, 0); - ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1); ngx_conf_merge_value(conf->chunked_transfer_encoding, prev->chunked_transfer_encoding, 1); ngx_conf_merge_value(conf->etag, prev->etag, 1); + ngx_conf_merge_uint_value(conf->server_tokens, prev->server_tokens, + NGX_HTTP_SERVER_TOKENS_ON); + ngx_conf_merge_ptr_value(conf->open_file_cache, prev->open_file_cache, NULL); @@ -4383,16 +4415,14 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (clcf->root.data) { if ((clcf->alias != 0) == alias) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"%V\" directive is duplicate", - &cmd->name); - } else { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"%V\" directive is duplicate, " - "\"%s\" directive was specified earlier", - &cmd->name, clcf->alias ? "alias" : "root"); + return "is duplicate"; } + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"%V\" directive is duplicate, " + "\"%s\" directive was specified earlier", + &cmd->name, clcf->alias ? "alias" : "root"); + return NGX_CONF_ERROR; } @@ -4507,7 +4537,7 @@ ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_http_core_loc_conf_t *clcf; if (pclcf->limit_except) { - return "duplicate"; + return "is duplicate"; } pclcf->limit_except = 0xffffffff; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index 237cc5c..5018da0 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -55,6 +55,11 @@ typedef struct ngx_thread_pool_s ngx_thread_pool_t; #define NGX_HTTP_KEEPALIVE_DISABLE_SAFARI 0x0008 +#define NGX_HTTP_SERVER_TOKENS_OFF 0 +#define NGX_HTTP_SERVER_TOKENS_ON 1 +#define NGX_HTTP_SERVER_TOKENS_BUILD 2 + + typedef struct ngx_http_location_tree_node_s ngx_http_location_tree_node_t; typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t; @@ -153,7 +158,8 @@ typedef struct { ngx_hash_t variables_hash; - ngx_array_t variables; /* ngx_http_variable_t */ + ngx_array_t variables; /* ngx_http_variable_t */ + ngx_array_t prefix_variables; /* ngx_http_variable_t */ ngx_uint_t ncaptures; ngx_uint_t server_names_hash_max_size; @@ -393,7 +399,7 @@ struct ngx_http_core_loc_conf_s { ngx_flag_t log_not_found; /* log_not_found */ ngx_flag_t log_subrequest; /* log_subrequest */ ngx_flag_t recursive_error_pages; /* recursive_error_pages */ - ngx_flag_t server_tokens; /* server_tokens */ + ngx_uint_t server_tokens; /* server_tokens */ ngx_flag_t chunked_transfer_encoding; /* chunked_transfer_encoding */ ngx_flag_t etag; /* etag */ diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c index a5a9300..a823c51 100644 --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -601,6 +601,8 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c) c->buf->last += n; c->valid_sec = h->valid_sec; + c->updating_sec = h->updating_sec; + c->error_sec = h->error_sec; c->last_modified = h->last_modified; c->date = h->date; c->valid_msec = h->valid_msec; @@ -632,6 +634,8 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c) now = ngx_time(); if (c->valid_sec < now) { + c->stale_updating = c->valid_sec + c->updating_sec >= now; + c->stale_error = c->valid_sec + c->error_sec >= now; ngx_shmtx_lock(&cache->shpool->mutex); @@ -1252,6 +1256,8 @@ ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf) h->version = NGX_HTTP_CACHE_VERSION; h->valid_sec = c->valid_sec; + h->updating_sec = c->updating_sec; + h->error_sec = c->error_sec; h->last_modified = c->last_modified; h->date = c->date; h->crc32 = c->crc32; @@ -1513,6 +1519,8 @@ ngx_http_file_cache_update_header(ngx_http_request_t *r) h.version = NGX_HTTP_CACHE_VERSION; h.valid_sec = c->valid_sec; + h.updating_sec = c->updating_sec; + h.error_sec = c->error_sec; h.last_modified = c->last_modified; h.date = c->date; h.crc32 = c->crc32; @@ -1569,7 +1577,7 @@ ngx_http_cache_send(ngx_http_request_t *r) /* we need to allocate all before the header would be sent */ - b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -1680,7 +1688,7 @@ ngx_http_file_cache_cleanup(void *data) ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->file.log, 0, "http file cache cleanup"); - if (c->updating) { + if (c->updating && !c->background) { ngx_log_error(NGX_LOG_ALERT, c->file.log, 0, "stalled cache updating, error:%ui", c->error); } @@ -1692,13 +1700,14 @@ ngx_http_file_cache_cleanup(void *data) static time_t ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache) { - u_char *name; + u_char *name, *p; size_t len; time_t wait; ngx_uint_t tries; ngx_path_t *path; - ngx_queue_t *q; + ngx_queue_t *q, *sentinel; ngx_http_file_cache_node_t *fcn; + u_char key[2 * NGX_HTTP_CACHE_KEY_LEN]; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "http file cache forced expire"); @@ -1715,13 +1724,21 @@ ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache) wait = 10; tries = 20; + sentinel = NULL; ngx_shmtx_lock(&cache->shpool->mutex); - for (q = ngx_queue_last(&cache->sh->queue); - q != ngx_queue_sentinel(&cache->sh->queue); - q = ngx_queue_prev(q)) - { + for ( ;; ) { + if (ngx_queue_empty(&cache->sh->queue)) { + break; + } + + q = ngx_queue_last(&cache->sh->queue); + + if (q == sentinel) { + break; + } + fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, @@ -1732,15 +1749,37 @@ ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache) if (fcn->count == 0) { ngx_http_file_cache_delete(cache, q, name); wait = 0; - - } else { - if (--tries) { - continue; - } - - wait = 1; + break; } + p = ngx_hex_dump(key, (u_char *) &fcn->node.key, + sizeof(ngx_rbtree_key_t)); + len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); + (void) ngx_hex_dump(p, fcn->key, len); + + /* + * abnormally exited workers may leave locked cache entries, + * and although it may be safe to remove them completely, + * we prefer to just move them to the top of the inactive queue + */ + + ngx_queue_remove(q); + fcn->expire = ngx_time() + cache->inactive; + ngx_queue_insert_head(&cache->sh->queue, &fcn->queue); + + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, + "ignore long locked inactive cache entry %*s, count:%d", + (size_t) 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count); + + if (sentinel == NULL) { + sentinel = q; + } + + if (--tries) { + continue; + } + + wait = 1; break; } diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c index 88c8a61..9b89405 100644 --- a/src/http/ngx_http_header_filter_module.c +++ b/src/http/ngx_http_header_filter_module.c @@ -46,8 +46,9 @@ ngx_module_t ngx_http_header_filter_module = { }; -static char ngx_http_server_string[] = "Server: nginx" CRLF; -static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF; +static u_char ngx_http_server_string[] = "Server: nginx" 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; static ngx_str_t ngx_http_status_lines[] = { @@ -74,8 +75,9 @@ static ngx_str_t ngx_http_status_lines[] = { ngx_null_string, /* "305 Use Proxy" */ ngx_null_string, /* "306 unused" */ ngx_string("307 Temporary Redirect"), + ngx_string("308 Permanent Redirect"), -#define NGX_HTTP_LAST_3XX 308 +#define NGX_HTTP_LAST_3XX 309 #define NGX_HTTP_OFF_4XX (NGX_HTTP_LAST_3XX - 301 + NGX_HTTP_OFF_3XX) ngx_string("400 Bad Request"), @@ -100,12 +102,16 @@ static ngx_str_t ngx_http_status_lines[] = { ngx_null_string, /* "419 unused" */ ngx_null_string, /* "420 unused" */ ngx_string("421 Misdirected Request"), + ngx_null_string, /* "422 Unprocessable Entity" */ + ngx_null_string, /* "423 Locked" */ + ngx_null_string, /* "424 Failed Dependency" */ + ngx_null_string, /* "425 unused" */ + ngx_null_string, /* "426 Upgrade Required" */ + ngx_null_string, /* "427 unused" */ + ngx_null_string, /* "428 Precondition Required" */ + ngx_string("429 Too Many Requests"), - /* ngx_null_string, */ /* "422 Unprocessable Entity" */ - /* ngx_null_string, */ /* "423 Locked" */ - /* ngx_null_string, */ /* "424 Failed Dependency" */ - -#define NGX_HTTP_LAST_4XX 422 +#define NGX_HTTP_LAST_4XX 430 #define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX) ngx_string("500 Internal Server Error"), @@ -113,7 +119,7 @@ static ngx_str_t ngx_http_status_lines[] = { ngx_string("502 Bad Gateway"), ngx_string("503 Service Temporarily Unavailable"), ngx_string("504 Gateway Time-out"), - ngx_null_string, /* "505 HTTP Version Not Supported" */ + ngx_string("505 HTTP Version Not Supported"), ngx_null_string, /* "506 Variant Also Negotiates" */ ngx_string("507 Insufficient Storage"), @@ -274,8 +280,15 @@ ngx_http_header_filter(ngx_http_request_t *r) clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->headers_out.server == NULL) { - len += clcf->server_tokens ? sizeof(ngx_http_server_full_string) - 1: - sizeof(ngx_http_server_string) - 1; + if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { + len += sizeof(ngx_http_server_full_string) - 1; + + } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { + len += sizeof(ngx_http_server_build_string) - 1; + + } else { + len += sizeof(ngx_http_server_string) - 1; + } } if (r->headers_out.date == NULL) { @@ -436,12 +449,16 @@ ngx_http_header_filter(ngx_http_request_t *r) *b->last++ = CR; *b->last++ = LF; if (r->headers_out.server == NULL) { - if (clcf->server_tokens) { - p = (u_char *) ngx_http_server_full_string; + if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { + p = ngx_http_server_full_string; len = sizeof(ngx_http_server_full_string) - 1; + } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { + p = ngx_http_server_build_string; + len = sizeof(ngx_http_server_build_string) - 1; + } else { - p = (u_char *) ngx_http_server_string; + p = ngx_http_server_string; len = sizeof(ngx_http_server_string) - 1; } diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c index 9f99473..e8e5156 100644 --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -723,6 +723,11 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b) } r->http_major = ch - '0'; + + if (r->http_major > 1) { + return NGX_HTTP_PARSE_INVALID_VERSION; + } + state = sw_major_digit; break; @@ -737,11 +742,12 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b) return NGX_HTTP_PARSE_INVALID_REQUEST; } - if (r->http_major > 99) { - return NGX_HTTP_PARSE_INVALID_REQUEST; + r->http_major = r->http_major * 10 + ch - '0'; + + if (r->http_major > 1) { + return NGX_HTTP_PARSE_INVALID_VERSION; } - r->http_major = r->http_major * 10 + ch - '0'; break; /* first digit of minor HTTP version */ @@ -1390,6 +1396,7 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes) goto done; case '+': r->plus_in_uri = 1; + /* fall through */ default: state = sw_usual; *u++ = ch; @@ -1431,6 +1438,7 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes) goto done; case '+': r->plus_in_uri = 1; + /* fall through */ default: state = sw_usual; *u++ = ch; @@ -1478,6 +1486,7 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes) goto done; case '+': r->plus_in_uri = 1; + /* fall through */ default: state = sw_usual; *u++ = ch; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 6ff7903..cc3722f 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -72,6 +72,9 @@ static char *ngx_http_client_errors[] = { /* NGX_HTTP_PARSE_INVALID_REQUEST */ "client sent invalid request", + /* NGX_HTTP_PARSE_INVALID_VERSION */ + "client sent invalid version", + /* NGX_HTTP_PARSE_INVALID_09_METHOD */ "client sent invalid method in HTTP/0.9 request" }; @@ -549,7 +552,7 @@ ngx_http_create_request(ngx_connection_t *c) ngx_set_connection_log(r->connection, clcf->error_log); - r->header_in = hc->nbusy ? hc->busy[0] : c->buffer; + r->header_in = hc->busy ? hc->busy->buf : c->buffer; if (ngx_list_init(&r->headers_out.headers, r->pool, 20, sizeof(ngx_table_elt_t)) @@ -620,14 +623,15 @@ ngx_http_create_request(ngx_connection_t *c) static void ngx_http_ssl_handshake(ngx_event_t *rev) { - u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1]; - size_t size; - ssize_t n; - ngx_err_t err; - ngx_int_t rc; - ngx_connection_t *c; - ngx_http_connection_t *hc; - ngx_http_ssl_srv_conf_t *sscf; + u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1]; + size_t size; + ssize_t n; + ngx_err_t err; + ngx_int_t rc; + ngx_connection_t *c; + ngx_http_connection_t *hc; + ngx_http_ssl_srv_conf_t *sscf; + ngx_http_core_loc_conf_t *clcf; c = rev->data; hc = c->data; @@ -709,6 +713,14 @@ ngx_http_ssl_handshake(ngx_event_t *rev) ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "https ssl handshake: 0x%02Xd", buf[0]); + clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, + ngx_http_core_module); + + if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + ngx_http_close_connection(c); + return; + } + sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); @@ -884,6 +896,8 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); + c->ssl->buffer_size = sscf->buffer_size; + if (sscf->ssl.ctx) { SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx); @@ -1034,7 +1048,14 @@ ngx_http_process_request_line(ngx_event_t *rev) ngx_log_error(NGX_LOG_INFO, c->log, 0, ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]); - ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + + if (rc == NGX_HTTP_PARSE_INVALID_VERSION) { + ngx_http_finalize_request(r, NGX_HTTP_VERSION_NOT_SUPPORTED); + + } else { + ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + } + return; } @@ -1429,6 +1450,7 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, { u_char *old, *new; ngx_buf_t *b; + ngx_chain_t *cl; ngx_http_connection_t *hc; ngx_http_core_srv_conf_t *cscf; @@ -1458,8 +1480,11 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, hc = r->http_connection; - if (hc->nfree) { - b = hc->free[--hc->nfree]; + if (hc->free) { + cl = hc->free; + hc->free = cl->next; + + b = cl->buf; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http large header free: %p %uz", @@ -1467,20 +1492,19 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, } else if (hc->nbusy < cscf->large_client_header_buffers.num) { - if (hc->busy == NULL) { - hc->busy = ngx_palloc(r->connection->pool, - cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *)); - if (hc->busy == NULL) { - return NGX_ERROR; - } - } - b = ngx_create_temp_buf(r->connection->pool, cscf->large_client_header_buffers.size); if (b == NULL) { return NGX_ERROR; } + cl = ngx_alloc_chain_link(r->connection->pool); + if (cl == NULL) { + return NGX_ERROR; + } + + cl->buf = b; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http large header alloc: %p %uz", b->pos, b->end - b->last); @@ -1489,7 +1513,9 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, return NGX_DECLINED; } - hc->busy[hc->nbusy++] = b; + cl->next = hc->busy; + hc->busy = cl; + hc->nbusy++; if (r->state == 0) { /* @@ -2191,6 +2217,11 @@ ngx_http_request_handler(ngx_event_t *ev) ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "http run request: \"%V?%V\"", &r->uri, &r->args); + if (ev->delayed && ev->timedout) { + ev->delayed = 0; + ev->timedout = 0; + } + if (ev->write) { r->write_event_handler(r); @@ -2300,10 +2331,6 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) return; } - if (r->main->blocked) { - r->write_event_handler = ngx_http_request_finalizer; - } - ngx_http_terminate_request(r, rc); return; } @@ -2335,6 +2362,26 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) } if (r != r->main) { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (r->background) { + if (!r->logged) { + if (clcf->log_subrequest) { + ngx_http_log_request(r); + } + + r->logged = 1; + + } else { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "subrequest: \"%V?%V\" logged again", + &r->uri, &r->args); + } + + r->done = 1; + ngx_http_finalize_connection(r); + return; + } if (r->buffered || r->postponed) { @@ -2352,9 +2399,6 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) r->main->count--; if (!r->logged) { - - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if (clcf->log_subrequest) { ngx_http_log_request(r); } @@ -2401,7 +2445,7 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) return; } - if (r->buffered || c->buffered || r->postponed || r->blocked) { + if (r->buffered || c->buffered || r->postponed) { if (ngx_http_set_write_handler(r) != NGX_OK) { ngx_http_terminate_request(r, 0); @@ -2418,6 +2462,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc) } r->done = 1; + + r->read_event_handler = ngx_http_block_reading; r->write_event_handler = ngx_http_request_empty_handler; if (!r->post_action) { @@ -2480,6 +2526,8 @@ ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc) if (mr->write_event_handler) { if (mr->blocked) { + r->connection->error = 1; + r->write_event_handler = ngx_http_request_finalizer; return; } @@ -2536,6 +2584,8 @@ ngx_http_finalize_connection(ngx_http_request_t *r) return; } + r = r->main; + if (r->reading_body) { r->keepalive = 0; r->lingering_close = 1; @@ -2600,7 +2650,7 @@ ngx_http_set_write_handler(ngx_http_request_t *r) static void ngx_http_writer(ngx_http_request_t *r) { - int rc; + ngx_int_t rc; ngx_event_t *wev; ngx_connection_t *c; ngx_http_core_loc_conf_t *clcf; @@ -2614,34 +2664,22 @@ ngx_http_writer(ngx_http_request_t *r) clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module); if (wev->timedout) { - if (!wev->delayed) { - ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, - "client timed out"); - c->timedout = 1; - - ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); - return; - } - - wev->timedout = 0; - wev->delayed = 0; - - if (!wev->ready) { - ngx_add_timer(wev, clcf->send_timeout); - - if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) { - ngx_http_close_request(r, 0); - } - - return; - } + ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, + "client timed out"); + c->timedout = 1; + ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); + return; } if (wev->delayed || r->aio) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http writer delayed"); + if (!wev->delayed) { + ngx_add_timer(wev, clcf->send_timeout); + } + if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) { ngx_http_close_request(r, 0); } @@ -2652,7 +2690,7 @@ ngx_http_writer(ngx_http_request_t *r) rc = ngx_http_output_filter(r, NULL); ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http writer output filter: %d, \"%V?%V\"", + "http writer output filter: %i, \"%V?%V\"", rc, &r->uri, &r->args); if (rc == NGX_ERROR) { @@ -2833,12 +2871,11 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) { int tcp_nodelay; - ngx_int_t i; ngx_buf_t *b, *f; + ngx_chain_t *cl, *ln; ngx_event_t *rev, *wev; ngx_connection_t *c; ngx_http_connection_t *hc; - ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf; c = r->connection; @@ -2874,26 +2911,33 @@ ngx_http_set_keepalive(ngx_http_request_t *r) * Now we would move the large header buffers to the free list. */ - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); + for (cl = hc->busy; cl; /* void */) { + ln = cl; + cl = cl->next; - if (hc->free == NULL) { - hc->free = ngx_palloc(c->pool, - cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *)); - - if (hc->free == NULL) { - ngx_http_close_request(r, 0); - return; + if (ln->buf == b) { + ngx_free_chain(c->pool, ln); + continue; } - } - for (i = 0; i < hc->nbusy - 1; i++) { - f = hc->busy[i]; - hc->free[hc->nfree++] = f; + f = ln->buf; f->pos = f->start; f->last = f->start; + + ln->next = hc->free; + hc->free = ln; } - hc->busy[0] = b; + cl = ngx_alloc_chain_link(c->pool); + if (cl == NULL) { + ngx_http_close_request(r, 0); + return; + } + + cl->buf = b; + cl->next = NULL; + + hc->busy = cl; hc->nbusy = 1; } } @@ -2964,27 +3008,32 @@ ngx_http_set_keepalive(ngx_http_request_t *r) b->last = b->start; } - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p %i", - hc->free, hc->nfree); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p", + hc->free); if (hc->free) { - for (i = 0; i < hc->nfree; i++) { - ngx_pfree(c->pool, hc->free[i]->start); - hc->free[i] = NULL; + for (cl = hc->free; cl; /* void */) { + ln = cl; + cl = cl->next; + ngx_pfree(c->pool, ln->buf->start); + ngx_free_chain(c->pool, ln); } - hc->nfree = 0; + hc->free = NULL; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %i", hc->busy, hc->nbusy); if (hc->busy) { - for (i = 0; i < hc->nbusy; i++) { - ngx_pfree(c->pool, hc->busy[i]->start); - hc->busy[i] = NULL; + for (cl = hc->busy; cl; /* void */) { + ln = cl; + cl = cl->next; + ngx_pfree(c->pool, ln->buf->start); + ngx_free_chain(c->pool, ln); } + hc->busy = NULL; hc->nbusy = 0; } @@ -3019,30 +3068,9 @@ ngx_http_set_keepalive(ngx_http_request_t *r) tcp_nodelay = 1; } - if (tcp_nodelay - && clcf->tcp_nodelay - && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) - { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) - == -1) - { -#if (NGX_SOLARIS) - /* Solaris returns EINVAL if a socket has been shut down */ - c->log_error = NGX_ERROR_IGNORE_EINVAL; -#endif - - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - - c->log_error = NGX_ERROR_INFO; - ngx_http_close_connection(c); - return; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + ngx_http_close_connection(c); + return; } #if 0 diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index cf9ee3c..283c582 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -54,15 +54,19 @@ #define NGX_HTTP_CLIENT_ERROR 10 #define NGX_HTTP_PARSE_INVALID_METHOD 10 #define NGX_HTTP_PARSE_INVALID_REQUEST 11 -#define NGX_HTTP_PARSE_INVALID_09_METHOD 12 +#define NGX_HTTP_PARSE_INVALID_VERSION 12 +#define NGX_HTTP_PARSE_INVALID_09_METHOD 13 -#define NGX_HTTP_PARSE_INVALID_HEADER 13 +#define NGX_HTTP_PARSE_INVALID_HEADER 14 /* unused 1 */ #define NGX_HTTP_SUBREQUEST_IN_MEMORY 2 #define NGX_HTTP_SUBREQUEST_WAITED 4 -#define NGX_HTTP_LOG_UNSAFE 8 +#define NGX_HTTP_SUBREQUEST_CLONE 8 +#define NGX_HTTP_SUBREQUEST_BACKGROUND 16 + +#define NGX_HTTP_LOG_UNSAFE 1 #define NGX_HTTP_CONTINUE 100 @@ -81,6 +85,7 @@ #define NGX_HTTP_SEE_OTHER 303 #define NGX_HTTP_NOT_MODIFIED 304 #define NGX_HTTP_TEMPORARY_REDIRECT 307 +#define NGX_HTTP_PERMANENT_REDIRECT 308 #define NGX_HTTP_BAD_REQUEST 400 #define NGX_HTTP_UNAUTHORIZED 401 @@ -96,6 +101,7 @@ #define NGX_HTTP_UNSUPPORTED_MEDIA_TYPE 415 #define NGX_HTTP_RANGE_NOT_SATISFIABLE 416 #define NGX_HTTP_MISDIRECTED_REQUEST 421 +#define NGX_HTTP_TOO_MANY_REQUESTS 429 /* Our own HTTP codes */ @@ -132,6 +138,7 @@ #define NGX_HTTP_BAD_GATEWAY 502 #define NGX_HTTP_SERVICE_UNAVAILABLE 503 #define NGX_HTTP_GATEWAY_TIME_OUT 504 +#define NGX_HTTP_VERSION_NOT_SUPPORTED 505 #define NGX_HTTP_INSUFFICIENT_STORAGE 507 @@ -307,11 +314,10 @@ typedef struct { #endif #endif - ngx_buf_t **busy; + ngx_chain_t *busy; ngx_int_t nbusy; - ngx_buf_t **free; - ngx_int_t nfree; + ngx_chain_t *free; unsigned ssl:1; unsigned proxy_protocol:1; @@ -537,6 +543,7 @@ struct ngx_http_request_s { unsigned stat_writing:1; unsigned stat_processing:1; + unsigned background:1; unsigned health_check:1; /* used to parse HTTP headers */ diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c index 0641329..c4f092e 100644 --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -46,13 +46,6 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, return NGX_OK; } -#if (NGX_HTTP_V2) - if (r->stream) { - rc = ngx_http_v2_read_request_body(r, post_handler); - goto done; - } -#endif - if (ngx_http_test_expect(r) != NGX_OK) { rc = NGX_HTTP_INTERNAL_SERVER_ERROR; goto done; @@ -85,6 +78,13 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, return NGX_OK; } +#if (NGX_HTTP_V2) + if (r->stream) { + rc = ngx_http_v2_read_request_body(r); + goto done; + } +#endif + preread = r->header_in->last - r->header_in->pos; if (preread) { @@ -805,7 +805,11 @@ ngx_http_test_expect(ngx_http_request_t *r) if (r->expect_tested || r->headers_in.expect == NULL - || r->http_version < NGX_HTTP_VERSION_11) + || r->http_version < NGX_HTTP_VERSION_11 +#if (NGX_HTTP_V2) + || r->stream != NULL +#endif + ) { return NGX_OK; } @@ -835,6 +839,8 @@ ngx_http_test_expect(ngx_http_request_t *r) /* we assume that such small packet should be send successfully */ + r->connection->error = 1; + return NGX_ERROR; } @@ -1085,6 +1091,7 @@ ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in) #if (NGX_DEBUG) +#if 0 for (cl = rb->bufs; cl; cl = cl->next) { ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, "http body old buf t:%d f:%d %p, pos %p, size: %z " @@ -1095,6 +1102,7 @@ ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in) cl->buf->file_pos, cl->buf->file_last - cl->buf->file_pos); } +#endif for (cl = in; cl; cl = cl->next) { ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c index c1a0b4c..96f3ec6 100644 --- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -220,7 +220,7 @@ ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) cv = (ngx_http_complex_value_t **) (p + cmd->offset); if (*cv != NULL) { - return "duplicate"; + return "is duplicate"; } *cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); @@ -1513,6 +1513,12 @@ ngx_http_script_file_code(ngx_http_script_engine_t *e) if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) != NGX_OK) { + if (of.err == 0) { + e->ip = ngx_http_script_exit; + e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; + return; + } + if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR && of.err != NGX_ENAMETOOLONG) diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c index d4c39ff..2c1ff17 100644 --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -25,6 +25,13 @@ static u_char ngx_http_error_full_tail[] = ; +static u_char ngx_http_error_build_tail[] = +"
" NGINX_VER_BUILD "
" CRLF +"" CRLF +"" CRLF +; + + static u_char ngx_http_error_tail[] = "
nginx
" CRLF "" CRLF @@ -82,6 +89,14 @@ static char ngx_http_error_307_page[] = ; +static char ngx_http_error_308_page[] = +"" CRLF +"308 Permanent Redirect" CRLF +"" CRLF +"

308 Permanent Redirect

" CRLF +; + + static char ngx_http_error_400_page[] = "" CRLF "400 Bad Request" CRLF @@ -218,6 +233,14 @@ static char ngx_http_error_421_page[] = ; +static char ngx_http_error_429_page[] = +"" CRLF +"429 Too Many Requests" CRLF +"" CRLF +"

429 Too Many Requests

" CRLF +; + + static char ngx_http_error_494_page[] = "" CRLF "400 Request Header Or Cookie Too Large" @@ -298,6 +321,14 @@ static char ngx_http_error_504_page[] = ; +static char ngx_http_error_505_page[] = +"" CRLF +"505 HTTP Version Not Supported" CRLF +"" CRLF +"

505 HTTP Version Not Supported

" CRLF +; + + static char ngx_http_error_507_page[] = "" CRLF "507 Insufficient Storage" CRLF @@ -321,8 +352,9 @@ static ngx_str_t ngx_http_error_pages[] = { ngx_null_string, /* 305 */ ngx_null_string, /* 306 */ ngx_string(ngx_http_error_307_page), + ngx_string(ngx_http_error_308_page), -#define NGX_HTTP_LAST_3XX 308 +#define NGX_HTTP_LAST_3XX 309 #define NGX_HTTP_OFF_4XX (NGX_HTTP_LAST_3XX - 301 + NGX_HTTP_OFF_3XX) ngx_string(ngx_http_error_400_page), @@ -347,8 +379,16 @@ static ngx_str_t ngx_http_error_pages[] = { ngx_null_string, /* 419 */ ngx_null_string, /* 420 */ ngx_string(ngx_http_error_421_page), + ngx_null_string, /* 422 */ + ngx_null_string, /* 423 */ + ngx_null_string, /* 424 */ + ngx_null_string, /* 425 */ + ngx_null_string, /* 426 */ + ngx_null_string, /* 427 */ + ngx_null_string, /* 428 */ + ngx_string(ngx_http_error_429_page), -#define NGX_HTTP_LAST_4XX 422 +#define NGX_HTTP_LAST_4XX 430 #define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX) ngx_string(ngx_http_error_494_page), /* 494, request header too large */ @@ -363,7 +403,7 @@ static ngx_str_t ngx_http_error_pages[] = { ngx_string(ngx_http_error_502_page), ngx_string(ngx_http_error_503_page), ngx_string(ngx_http_error_504_page), - ngx_null_string, /* 505 */ + ngx_string(ngx_http_error_505_page), ngx_null_string, /* 506 */ ngx_string(ngx_http_error_507_page) @@ -592,7 +632,8 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page) if (overwrite != NGX_HTTP_MOVED_PERMANENTLY && overwrite != NGX_HTTP_MOVED_TEMPORARILY && overwrite != NGX_HTTP_SEE_OTHER - && overwrite != NGX_HTTP_TEMPORARY_REDIRECT) + && overwrite != NGX_HTTP_TEMPORARY_REDIRECT + && overwrite != NGX_HTTP_PERMANENT_REDIRECT) { r->err_status = NGX_HTTP_MOVED_TEMPORARILY; } @@ -628,10 +669,14 @@ ngx_http_send_special_response(ngx_http_request_t *r, ngx_uint_t msie_padding; ngx_chain_t out[3]; - if (clcf->server_tokens) { + if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { len = sizeof(ngx_http_error_full_tail) - 1; tail = ngx_http_error_full_tail; + } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { + len = sizeof(ngx_http_error_build_tail) - 1; + tail = ngx_http_error_build_tail; + } else { len = sizeof(ngx_http_error_tail) - 1; tail = ngx_http_error_tail; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 74a7c64..0fc5ab5 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -17,6 +17,8 @@ static ngx_int_t ngx_http_upstream_cache_get(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_http_file_cache_t **cache); static ngx_int_t ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u); +static ngx_int_t ngx_http_upstream_cache_background_update( + ngx_http_request_t *r, ngx_http_upstream_t *u); static ngx_int_t ngx_http_upstream_cache_check_range(ngx_http_request_t *r, ngx_http_upstream_t *u); static ngx_int_t ngx_http_upstream_cache_status(ngx_http_request_t *r, @@ -162,6 +164,10 @@ 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_header_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); static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, @@ -182,7 +188,7 @@ static ngx_int_t ngx_http_upstream_ssl_name(ngx_http_request_t *r, #endif -ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { +static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { { ngx_string("Status"), ngx_http_upstream_process_header_line, @@ -413,6 +419,12 @@ static ngx_http_variable_t ngx_http_upstream_vars[] = { #endif + { ngx_string("upstream_http_"), NULL, ngx_http_upstream_header_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 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; @@ -424,6 +436,7 @@ static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = { { 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 }, { 403, NGX_HTTP_UPSTREAM_FT_HTTP_403 }, { 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 }, + { 429, NGX_HTTP_UPSTREAM_FT_HTTP_429 }, { 0, 0 } }; @@ -568,6 +581,10 @@ ngx_http_upstream_init_request(ngx_http_request_t *r) rc = NGX_DECLINED; r->cached = 0; } + + if (ngx_http_upstream_cache_background_update(r, u) != NGX_OK) { + rc = NGX_ERROR; + } } if (rc != NGX_DECLINED) { @@ -859,9 +876,24 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u) switch (rc) { + case NGX_HTTP_CACHE_STALE: + + if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) + || c->stale_updating) && !r->background + && u->conf->cache_background_update) + { + r->cache->background = 1; + u->cache_status = rc; + rc = NGX_OK; + } + + break; + case NGX_HTTP_CACHE_UPDATING: - if (u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) { + if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) + || c->stale_updating) && !r->background) + { u->cache_status = rc; rc = NGX_OK; @@ -884,6 +916,9 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u) case NGX_HTTP_CACHE_STALE: c->valid_sec = 0; + c->updating_sec = 0; + c->error_sec = 0; + u->buffer.start = NULL; u->cache_status = NGX_HTTP_CACHE_EXPIRED; @@ -1030,6 +1065,30 @@ ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u) } +static ngx_int_t +ngx_http_upstream_cache_background_update(ngx_http_request_t *r, + ngx_http_upstream_t *u) +{ + ngx_http_request_t *sr; + + if (!r->cached || !r->cache->background) { + return NGX_OK; + } + + if (ngx_http_subrequest(r, &r->uri, &r->args, &sr, NULL, + NGX_HTTP_SUBREQUEST_CLONE + |NGX_HTTP_SUBREQUEST_BACKGROUND) + != NGX_OK) + { + return NGX_ERROR; + } + + sr->header_only = 1; + + return NGX_OK; +} + + static ngx_int_t ngx_http_upstream_cache_check_range(ngx_http_request_t *r, ngx_http_upstream_t *u) @@ -1174,6 +1233,11 @@ ngx_http_upstream_handler(ngx_event_t *ev) ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "http upstream request: \"%V?%V\"", &r->uri, &r->args); + if (ev->delayed && ev->timedout) { + ev->delayed = 0; + ev->timedout = 0; + } + if (ev->write) { u->write_event_handler(r, u); @@ -1542,7 +1606,6 @@ static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_connection_t *c) { - int tcp_nodelay; ngx_int_t rc; ngx_http_core_loc_conf_t *clcf; @@ -1582,22 +1645,10 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, + if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); - return; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + return; } } @@ -1950,7 +2001,6 @@ static ngx_int_t ngx_http_upstream_send_request_body(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_uint_t do_write) { - int tcp_nodelay; ngx_int_t rc; ngx_chain_t *out, *cl, *ln; ngx_connection_t *c; @@ -1987,20 +2037,8 @@ ngx_http_upstream_send_request_body(ngx_http_request_t *r, c = u->peer.connection; clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - return NGX_ERROR; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + return NGX_ERROR; } r->read_event_handler = ngx_http_upstream_read_request_handler; @@ -2330,7 +2368,7 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u) #if (NGX_HTTP_CACHE) if (u->cache_status == NGX_HTTP_CACHE_EXPIRED - && (u->conf->cache_use_stale & un->mask)) + && ((u->conf->cache_use_stale & un->mask) || r->cache->stale_error)) { ngx_int_t rc; @@ -2354,14 +2392,17 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u) && u->cache_status == NGX_HTTP_CACHE_EXPIRED && u->conf->cache_revalidate) { - time_t now, valid; + time_t now, valid, updating, error; ngx_int_t rc; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http upstream not modified"); now = ngx_time(); + valid = r->cache->valid_sec; + updating = r->cache->updating_sec; + error = r->cache->error_sec; rc = u->reinit_request(r); @@ -2375,6 +2416,8 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u) if (valid == 0) { valid = r->cache->valid_sec; + updating = r->cache->updating_sec; + error = r->cache->error_sec; } if (valid == 0) { @@ -2387,6 +2430,9 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u) if (valid) { r->cache->valid_sec = valid; + r->cache->updating_sec = updating; + r->cache->error_sec = error; + r->cache->date = now; ngx_http_file_cache_update_header(r); @@ -2750,7 +2796,6 @@ ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r, static void ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) { - int tcp_nodelay; ssize_t n; ngx_int_t rc; ngx_event_pipe_t *p; @@ -2831,21 +2876,9 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) return; } - if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, NGX_ERROR); - return; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; } n = u->buffer.last - u->buffer.pos; @@ -3104,7 +3137,6 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) static void ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u) { - int tcp_nodelay; ngx_connection_t *c; ngx_http_core_loc_conf_t *clcf; @@ -3122,37 +3154,15 @@ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u) r->write_event_handler = ngx_http_upstream_upgraded_write_downstream; if (clcf->tcp_nodelay) { - tcp_nodelay = 1; - if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, NGX_ERROR); - return; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + if (ngx_tcp_nodelay(c) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; } - if (u->peer.connection->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, u->peer.connection->log, 0, - "tcp_nodelay"); - - if (setsockopt(u->peer.connection->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(u->peer.connection, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_http_upstream_finalize_request(r, u, NGX_ERROR); - return; - } - - u->peer.connection->tcp_nodelay = NGX_TCP_NODELAY_SET; + if (ngx_tcp_nodelay(u->peer.connection) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, NGX_ERROR); + return; } } @@ -3670,9 +3680,19 @@ ngx_http_upstream_thread_event_handler(ngx_event_t *ev) r->main->blocked--; r->aio = 0; - r->write_event_handler(r); + if (r->done) { + /* + * trigger connection event handler if the subrequest was + * already finalized; this can happen if the handler is used + * for sendfile() in threads + */ - ngx_http_run_posted_requests(c); + c->write->handler(c->write); + + } else { + r->write_event_handler(r); + ngx_http_run_posted_requests(c); + } } #endif @@ -3720,31 +3740,9 @@ ngx_http_upstream_process_downstream(ngx_http_request_t *r) if (wev->timedout) { - if (wev->delayed) { - - wev->timedout = 0; - wev->delayed = 0; - - if (!wev->ready) { - ngx_add_timer(wev, p->send_timeout); - - if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, NGX_ERROR); - } - - return; - } - - if (ngx_event_pipe(p, wev->write) == NGX_ABORT) { - ngx_http_upstream_finalize_request(r, u, NGX_ERROR); - return; - } - - } else { - p->downstream_error = 1; - c->timedout = 1; - ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out"); - } + p->downstream_error = 1; + c->timedout = 1; + ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out"); } else { @@ -3789,30 +3787,8 @@ ngx_http_upstream_process_upstream(ngx_http_request_t *r, if (rev->timedout) { - if (rev->delayed) { - - rev->timedout = 0; - rev->delayed = 0; - - if (!rev->ready) { - ngx_add_timer(rev, p->read_timeout); - - if (ngx_handle_read_event(rev, 0) != NGX_OK) { - ngx_http_upstream_finalize_request(r, u, NGX_ERROR); - } - - return; - } - - if (ngx_event_pipe(p, 0) == NGX_ABORT) { - ngx_http_upstream_finalize_request(r, u, NGX_ERROR); - return; - } - - } else { - p->upstream_error = 1; - ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); - } + p->upstream_error = 1; + ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); } else { @@ -4089,6 +4065,10 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u, status = NGX_HTTP_NOT_FOUND; break; + case NGX_HTTP_UPSTREAM_FT_HTTP_429: + status = NGX_HTTP_TOO_MANY_REQUESTS; + break; + /* * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING * never reach here @@ -4122,7 +4102,7 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u, #if (NGX_HTTP_CACHE) if (u->cache_status == NGX_HTTP_CACHE_EXPIRED - && (u->conf->cache_use_stale & ft_type)) + && ((u->conf->cache_use_stale & ft_type) || r->cache->stale_error)) { ngx_int_t rc; @@ -4300,6 +4280,8 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r, u->buffer.last = u->buffer.pos; } + r->read_event_handler = ngx_http_block_reading; + if (rc == NGX_DECLINED) { return; } @@ -4497,32 +4479,76 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r, offset = 8; } - if (p == NULL) { - return NGX_OK; - } + if (p) { + n = 0; - n = 0; + for (p += offset; p < last; p++) { + if (*p == ',' || *p == ';' || *p == ' ') { + break; + } - for (p += offset; p < last; p++) { - if (*p == ',' || *p == ';' || *p == ' ') { - break; + if (*p >= '0' && *p <= '9') { + n = n * 10 + *p - '0'; + continue; + } + + u->cacheable = 0; + return NGX_OK; } - if (*p >= '0' && *p <= '9') { - n = n * 10 + *p - '0'; - continue; + if (n == 0) { + u->cacheable = 0; + return NGX_OK; } - u->cacheable = 0; - return NGX_OK; + r->cache->valid_sec = ngx_time() + n; } - if (n == 0) { - u->cacheable = 0; - return NGX_OK; + p = ngx_strlcasestrn(start, last, (u_char *) "stale-while-revalidate=", + 23 - 1); + + if (p) { + n = 0; + + for (p += 23; p < last; p++) { + if (*p == ',' || *p == ';' || *p == ' ') { + break; + } + + if (*p >= '0' && *p <= '9') { + n = n * 10 + *p - '0'; + continue; + } + + u->cacheable = 0; + return NGX_OK; + } + + r->cache->updating_sec = n; + r->cache->error_sec = n; } - r->cache->valid_sec = ngx_time() + n; + p = ngx_strlcasestrn(start, last, (u_char *) "stale-if-error=", 15 - 1); + + if (p) { + n = 0; + + for (p += 15; p < last; p++) { + if (*p == ',' || *p == ';' || *p == ' ') { + break; + } + + if (*p >= '0' && *p <= '9') { + n = n * 10 + *p - '0'; + continue; + } + + u->cacheable = 0; + return NGX_OK; + } + + r->cache->error_sec = n; + } } #endif @@ -4809,17 +4835,18 @@ ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r, } } - ph = ngx_array_push(pa); - if (ph == NULL) { - return NGX_ERROR; - } - ho = ngx_list_push(&r->headers_out.headers); if (ho == NULL) { return NGX_ERROR; } *ho = *h; + + ph = ngx_array_push(pa); + if (ph == NULL) { + return NGX_ERROR; + } + *ph = ho; return NGX_OK; @@ -5391,7 +5418,7 @@ ngx_http_upstream_response_length_variable(ngx_http_request_t *r, } -ngx_int_t +static ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { @@ -5406,7 +5433,7 @@ ngx_http_upstream_header_variable(ngx_http_request_t *r, } -ngx_int_t +static ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { @@ -5442,7 +5469,7 @@ ngx_http_upstream_cookie_variable(ngx_http_request_t *r, #if (NGX_HTTP_CACHE) -ngx_int_t +static ngx_int_t ngx_http_upstream_cache_status(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 7390f2e..c552ac0 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -26,10 +26,11 @@ #define NGX_HTTP_UPSTREAM_FT_HTTP_504 0x00000080 #define NGX_HTTP_UPSTREAM_FT_HTTP_403 0x00000100 #define NGX_HTTP_UPSTREAM_FT_HTTP_404 0x00000200 -#define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000400 -#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00000800 -#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00001000 -#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT 0x00002000 +#define NGX_HTTP_UPSTREAM_FT_HTTP_429 0x00000400 +#define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000800 +#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00001000 +#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00002000 +#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT 0x00004000 #define NGX_HTTP_UPSTREAM_FT_NOLIVE 0x40000000 #define NGX_HTTP_UPSTREAM_FT_OFF 0x80000000 @@ -38,7 +39,8 @@ |NGX_HTTP_UPSTREAM_FT_HTTP_503 \ |NGX_HTTP_UPSTREAM_FT_HTTP_504 \ |NGX_HTTP_UPSTREAM_FT_HTTP_403 \ - |NGX_HTTP_UPSTREAM_FT_HTTP_404) + |NGX_HTTP_UPSTREAM_FT_HTTP_404 \ + |NGX_HTTP_UPSTREAM_FT_HTTP_429) #define NGX_HTTP_UPSTREAM_INVALID_HEADER 40 @@ -55,9 +57,6 @@ typedef struct { - ngx_msec_t bl_time; - ngx_uint_t bl_state; - ngx_uint_t status; ngx_msec_t response_time; ngx_msec_t connect_time; @@ -151,7 +150,6 @@ typedef struct { ngx_msec_t connect_timeout; ngx_msec_t send_timeout; ngx_msec_t read_timeout; - ngx_msec_t timeout; ngx_msec_t next_upstream_timeout; size_t send_lowat; @@ -206,6 +204,7 @@ typedef struct { ngx_flag_t cache_revalidate; ngx_flag_t cache_convert_head; + ngx_flag_t cache_background_update; ngx_array_t *cache_valid; ngx_array_t *cache_bypass; @@ -390,9 +389,6 @@ struct ngx_http_upstream_s { unsigned request_sent:1; unsigned request_body_sent:1; unsigned header_sent:1; - - NGX_COMPAT_BEGIN(1) - NGX_COMPAT_END }; @@ -409,11 +405,6 @@ typedef struct { } ngx_http_upstream_param_t; -ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r, - ngx_http_variable_value_t *v, uintptr_t data); -ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r, - ngx_http_variable_value_t *v, uintptr_t data); - ngx_int_t ngx_http_upstream_create(ngx_http_request_t *r); void ngx_http_upstream_init(ngx_http_request_t *r); ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf, diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index 62006ba..6138819 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -11,6 +11,9 @@ #include +static ngx_http_variable_t *ngx_http_add_prefix_variable(ngx_conf_t *cf, + ngx_str_t *name, ngx_uint_t flags); + static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); #if 0 @@ -356,6 +359,18 @@ static ngx_http_variable_t ngx_http_core_variables[] = { 3, NGX_HTTP_VAR_NOCACHEABLE, 0 }, #endif + { ngx_string("http_"), NULL, ngx_http_variable_unknown_header_in, + 0, NGX_HTTP_VAR_PREFIX, 0 }, + + { ngx_string("sent_http_"), NULL, ngx_http_variable_unknown_header_out, + 0, NGX_HTTP_VAR_PREFIX, 0 }, + + { ngx_string("cookie_"), NULL, ngx_http_variable_cookie, + 0, NGX_HTTP_VAR_PREFIX, 0 }, + + { ngx_string("arg_"), NULL, ngx_http_variable_argument, + 0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; @@ -384,6 +399,10 @@ ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) return NULL; } + if (flags & NGX_HTTP_VAR_PREFIX) { + return ngx_http_add_prefix_variable(cf, name, flags); + } + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); key = cmcf->variables_keys->keys.elts; @@ -402,6 +421,8 @@ ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) return NULL; } + v->flags &= flags | ~NGX_HTTP_VAR_WEAK; + return v; } @@ -440,6 +461,59 @@ ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) } +static ngx_http_variable_t * +ngx_http_add_prefix_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) +{ + ngx_uint_t i; + ngx_http_variable_t *v; + ngx_http_core_main_conf_t *cmcf; + + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); + + v = cmcf->prefix_variables.elts; + for (i = 0; i < cmcf->prefix_variables.nelts; i++) { + if (name->len != v[i].name.len + || ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0) + { + continue; + } + + v = &v[i]; + + if (!(v->flags & NGX_HTTP_VAR_CHANGEABLE)) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the duplicate \"%V\" variable", name); + return NULL; + } + + v->flags &= flags | ~NGX_HTTP_VAR_WEAK; + + return v; + } + + v = ngx_array_push(&cmcf->prefix_variables); + if (v == NULL) { + return NULL; + } + + v->name.len = name->len; + v->name.data = ngx_pnalloc(cf->pool, name->len); + if (v->name.data == NULL) { + return NULL; + } + + ngx_strlow(v->name.data, name->data, name->len); + + v->set_handler = NULL; + v->get_handler = NULL; + v->data = 0; + v->flags = flags; + v->index = 0; + + return v; +} + + ngx_int_t ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name) { @@ -573,6 +647,8 @@ ngx_http_get_flushed_variable(ngx_http_request_t *r, ngx_uint_t index) ngx_http_variable_value_t * ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key) { + size_t len; + ngx_uint_t i, n; ngx_http_variable_t *v; ngx_http_variable_value_t *vv; ngx_http_core_main_conf_t *cmcf; @@ -610,64 +686,22 @@ ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key) return NULL; } - if (name->len >= 5 && ngx_strncmp(name->data, "http_", 5) == 0) { + len = 0; - if (ngx_http_variable_unknown_header_in(r, vv, (uintptr_t) name) - == NGX_OK) + v = cmcf->prefix_variables.elts; + n = cmcf->prefix_variables.nelts; + + for (i = 0; i < cmcf->prefix_variables.nelts; i++) { + if (name->len >= v[i].name.len && name->len > len + && ngx_strncmp(name->data, v[i].name.data, v[i].name.len) == 0) { - return vv; + len = v[i].name.len; + n = i; } - - return NULL; } - if (name->len >= 10 && ngx_strncmp(name->data, "sent_http_", 10) == 0) { - - if (ngx_http_variable_unknown_header_out(r, vv, (uintptr_t) name) - == NGX_OK) - { - return vv; - } - - return NULL; - } - - if (name->len >= 14 && ngx_strncmp(name->data, "upstream_http_", 14) == 0) { - - if (ngx_http_upstream_header_variable(r, vv, (uintptr_t) name) - == NGX_OK) - { - return vv; - } - - return NULL; - } - - if (name->len >= 7 && ngx_strncmp(name->data, "cookie_", 7) == 0) { - - if (ngx_http_variable_cookie(r, vv, (uintptr_t) name) == NGX_OK) { - return vv; - } - - return NULL; - } - - if (name->len >= 16 - && ngx_strncmp(name->data, "upstream_cookie_", 16) == 0) - { - - if (ngx_http_upstream_cookie_variable(r, vv, (uintptr_t) name) - == NGX_OK) - { - return vv; - } - - return NULL; - } - - if (name->len >= 4 && ngx_strncmp(name->data, "arg_", 4) == 0) { - - if (ngx_http_variable_argument(r, vv, (uintptr_t) name) == NGX_OK) { + if (n != cmcf->prefix_variables.nelts) { + if (v[n].get_handler(r, vv, (uintptr_t) name) == NGX_OK) { return vv; } @@ -2502,7 +2536,6 @@ ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re, ngx_str_t *s) ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf) { - ngx_int_t rc; ngx_http_variable_t *cv, *v; ngx_http_core_main_conf_t *cmcf; @@ -2523,27 +2556,20 @@ ngx_http_variables_add_core_vars(ngx_conf_t *cf) return NGX_ERROR; } + if (ngx_array_init(&cmcf->prefix_variables, cf->pool, 8, + sizeof(ngx_http_variable_t)) + != NGX_OK) + { + return NGX_ERROR; + } + for (cv = ngx_http_core_variables; cv->name.len; cv++) { - v = ngx_palloc(cf->pool, sizeof(ngx_http_variable_t)); + v = ngx_http_add_variable(cf, &cv->name, cv->flags); if (v == NULL) { return NGX_ERROR; } *v = *cv; - - rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, - NGX_HASH_READONLY_KEY); - - if (rc == NGX_OK) { - continue; - } - - if (rc == NGX_BUSY) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "conflicting variable name \"%V\"", &v->name); - } - - return NGX_ERROR; } return NGX_OK; @@ -2553,10 +2579,11 @@ ngx_http_variables_add_core_vars(ngx_conf_t *cf) ngx_int_t ngx_http_variables_init_vars(ngx_conf_t *cf) { + size_t len; ngx_uint_t i, n; ngx_hash_key_t *key; ngx_hash_init_t hash; - ngx_http_variable_t *v, *av; + ngx_http_variable_t *v, *av, *pv; ngx_http_core_main_conf_t *cmcf; /* set the handlers for the indexed http variables */ @@ -2564,6 +2591,7 @@ ngx_http_variables_init_vars(ngx_conf_t *cf) cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); v = cmcf->variables.elts; + pv = cmcf->prefix_variables.elts; key = cmcf->variables_keys->keys.elts; for (i = 0; i < cmcf->variables.nelts; i++) { @@ -2584,7 +2612,9 @@ ngx_http_variables_init_vars(ngx_conf_t *cf) av->index = i; - if (av->get_handler == NULL) { + if (av->get_handler == NULL + || (av->flags & NGX_HTTP_VAR_WEAK)) + { break; } @@ -2592,68 +2622,34 @@ ngx_http_variables_init_vars(ngx_conf_t *cf) } } - if (v[i].name.len >= 5 - && ngx_strncmp(v[i].name.data, "http_", 5) == 0) - { - v[i].get_handler = ngx_http_variable_unknown_header_in; - v[i].data = (uintptr_t) &v[i].name; + len = 0; + av = NULL; - continue; + for (n = 0; n < cmcf->prefix_variables.nelts; n++) { + if (v[i].name.len >= pv[n].name.len && v[i].name.len > len + && ngx_strncmp(v[i].name.data, pv[n].name.data, pv[n].name.len) + == 0) + { + av = &pv[n]; + len = pv[n].name.len; + } } - if (v[i].name.len >= 10 - && ngx_strncmp(v[i].name.data, "sent_http_", 10) == 0) - { - v[i].get_handler = ngx_http_variable_unknown_header_out; + if (av) { + v[i].get_handler = av->get_handler; v[i].data = (uintptr_t) &v[i].name; + v[i].flags = av->flags; - continue; + goto next; } - if (v[i].name.len >= 14 - && ngx_strncmp(v[i].name.data, "upstream_http_", 14) == 0) - { - v[i].get_handler = ngx_http_upstream_header_variable; - v[i].data = (uintptr_t) &v[i].name; - v[i].flags = NGX_HTTP_VAR_NOCACHEABLE; + if (v[i].get_handler == NULL) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "unknown \"%V\" variable", &v[i].name); - continue; + return NGX_ERROR; } - if (v[i].name.len >= 7 - && ngx_strncmp(v[i].name.data, "cookie_", 7) == 0) - { - v[i].get_handler = ngx_http_variable_cookie; - v[i].data = (uintptr_t) &v[i].name; - - continue; - } - - if (v[i].name.len >= 16 - && ngx_strncmp(v[i].name.data, "upstream_cookie_", 16) == 0) - { - v[i].get_handler = ngx_http_upstream_cookie_variable; - v[i].data = (uintptr_t) &v[i].name; - v[i].flags = NGX_HTTP_VAR_NOCACHEABLE; - - continue; - } - - if (v[i].name.len >= 4 - && ngx_strncmp(v[i].name.data, "arg_", 4) == 0) - { - v[i].get_handler = ngx_http_variable_argument; - v[i].data = (uintptr_t) &v[i].name; - v[i].flags = NGX_HTTP_VAR_NOCACHEABLE; - - continue; - } - - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "unknown \"%V\" variable", &v[i].name); - - return NGX_ERROR; - next: continue; } diff --git a/src/http/ngx_http_variables.h b/src/http/ngx_http_variables.h index 829fab3..df337de 100644 --- a/src/http/ngx_http_variables.h +++ b/src/http/ngx_http_variables.h @@ -30,6 +30,8 @@ typedef ngx_int_t (*ngx_http_get_variable_pt) (ngx_http_request_t *r, #define NGX_HTTP_VAR_NOCACHEABLE 2 #define NGX_HTTP_VAR_INDEXED 4 #define NGX_HTTP_VAR_NOHASH 8 +#define NGX_HTTP_VAR_WEAK 16 +#define NGX_HTTP_VAR_PREFIX 32 struct ngx_http_variable_s { diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c index f3050f1..ed78638 100644 --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -529,29 +529,8 @@ ngx_http_v2_send_output_queue(ngx_http_v2_connection_t *h2c) tcp_nodelay = 1; } - if (tcp_nodelay - && clcf->tcp_nodelay - && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) - { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) - == -1) - { -#if (NGX_SOLARIS) - /* Solaris returns EINVAL if a socket has been shut down */ - c->log_error = NGX_ERROR_IGNORE_EINVAL; -#endif - - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - - c->log_error = NGX_ERROR_INFO; - goto error; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + goto error; } for ( /* void */ ; out; out = fn) { @@ -783,9 +762,12 @@ ngx_http_v2_state_head(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) static u_char * ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) { + size_t size; ngx_http_v2_node_t *node; ngx_http_v2_stream_t *stream; + size = h2c->state.length; + if (h2c->state.flags & NGX_HTTP_V2_PADDED_FLAG) { if (h2c->state.length == 0) { @@ -802,33 +784,33 @@ ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) } h2c->state.padding = *pos++; - h2c->state.length--; - if (h2c->state.padding > h2c->state.length) { + if (h2c->state.padding >= size) { ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, "client sent padded DATA frame " "with incorrect length: %uz, padding: %uz", - h2c->state.length, h2c->state.padding); + size, h2c->state.padding); - return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_PROTOCOL_ERROR); } - h2c->state.length -= h2c->state.padding; + h2c->state.length -= 1 + h2c->state.padding; } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, "http2 DATA frame"); - if (h2c->state.length > h2c->recv_window) { + if (size > h2c->recv_window) { ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, "client violated connection flow control: " "received DATA frame length %uz, available window %uz", - h2c->state.length, h2c->recv_window); + size, h2c->recv_window); return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_FLOW_CTRL_ERROR); } - h2c->recv_window -= h2c->state.length; + h2c->recv_window -= size; if (h2c->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) { @@ -854,11 +836,11 @@ ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) stream = node->stream; - if (h2c->state.length > stream->recv_window) { + if (size > stream->recv_window) { ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, "client violated flow control for stream %ui: " "received DATA frame length %uz, available window %uz", - node->id, h2c->state.length, stream->recv_window); + node->id, size, stream->recv_window); if (ngx_http_v2_terminate_stream(h2c, stream, NGX_HTTP_V2_FLOW_CTRL_ERROR) @@ -871,7 +853,7 @@ ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) return ngx_http_v2_state_skip_padded(h2c, pos, end); } - stream->recv_window -= h2c->state.length; + stream->recv_window -= size; if (stream->no_flow_control && stream->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) @@ -938,7 +920,7 @@ ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos, if (size >= h2c->state.length) { size = h2c->state.length; - stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG; + stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG; } r = stream->request; @@ -1053,7 +1035,8 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos, "with incorrect length: %uz, padding: %uz", h2c->state.length, h2c->state.padding); - return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_PROTOCOL_ERROR); } h2c->state.length -= h2c->state.padding; @@ -1901,7 +1884,7 @@ ngx_http_v2_state_rst_stream(ngx_http_v2_connection_t *h2c, u_char *pos, if (node == NULL || node->stream == NULL) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, - "unknown http2 stream"); + "unknown http2 stream"); return ngx_http_v2_state_complete(h2c, pos, end); } @@ -2015,6 +1998,7 @@ ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos, break; case NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING: + if (value > NGX_HTTP_V2_MAX_FRAME_SIZE || value < NGX_HTTP_V2_DEFAULT_FRAME_SIZE) { @@ -2161,6 +2145,44 @@ ngx_http_v2_state_window_update(ngx_http_v2_connection_t *h2c, u_char *pos, "http2 WINDOW_UPDATE frame sid:%ui window:%uz", h2c->state.sid, window); + if (window == 0) { + if (h2c->state.sid == 0) { + ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, + "client sent WINDOW_UPDATE frame " + "with incorrect window increment 0"); + + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_PROTOCOL_ERROR); + } + + ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, + "client sent WINDOW_UPDATE frame for stream %ui " + "with incorrect window increment 0", h2c->state.sid); + + node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0); + + if (node && node->stream) { + if (ngx_http_v2_terminate_stream(h2c, node->stream, + NGX_HTTP_V2_PROTOCOL_ERROR) + == NGX_ERROR) + { + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_INTERNAL_ERROR); + } + + } else { + if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, + NGX_HTTP_V2_PROTOCOL_ERROR) + == NGX_ERROR) + { + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_INTERNAL_ERROR); + } + } + + return ngx_http_v2_state_complete(h2c, pos, end); + } + if (h2c->state.sid) { node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0); @@ -3072,7 +3094,7 @@ ngx_http_v2_pseudo_header(ngx_http_request_t *r, ngx_http_v2_header_t *header) } ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent unknown pseudo header \"%V\"", + "client sent unknown pseudo-header \":%V\"", &header->name); return NGX_DECLINED; @@ -3219,14 +3241,14 @@ ngx_http_v2_parse_scheme(ngx_http_request_t *r, ngx_http_v2_header_t *header) { if (r->schema_start) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent duplicate :schema header"); + "client sent duplicate :scheme header"); return NGX_DECLINED; } if (header->value.len == 0) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent empty :schema header"); + "client sent empty :scheme header"); return NGX_DECLINED; } @@ -3479,8 +3501,7 @@ ngx_http_v2_run_request(ngx_http_request_t *r) ngx_int_t -ngx_http_v2_read_request_body(ngx_http_request_t *r, - ngx_http_client_body_handler_pt post_handler) +ngx_http_v2_read_request_body(ngx_http_request_t *r) { off_t len; size_t size; @@ -3493,33 +3514,14 @@ ngx_http_v2_read_request_body(ngx_http_request_t *r, ngx_http_v2_connection_t *h2c; stream = r->stream; + rb = r->request_body; if (stream->skip_data) { r->request_body_no_buffering = 0; - post_handler(r); + rb->post_handler(r); return NGX_OK; } - rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); - if (rb == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - /* - * set by ngx_pcalloc(): - * - * rb->bufs = NULL; - * rb->buf = NULL; - * rb->received = 0; - * rb->free = NULL; - * rb->busy = NULL; - */ - - rb->rest = 1; - rb->post_handler = post_handler; - - r->request_body = rb; - h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); @@ -3569,6 +3571,8 @@ ngx_http_v2_read_request_body(ngx_http_request_t *r, return NGX_HTTP_INTERNAL_SERVER_ERROR; } + rb->rest = 1; + buf = stream->preread; if (stream->in_closed) { @@ -4130,6 +4134,14 @@ ngx_http_v2_handle_connection_handler(ngx_event_t *rev) ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http2 handle connection handler"); + c = rev->data; + h2c = c->data; + + if (c->error) { + ngx_http_v2_finalize_connection(h2c, 0); + return; + } + rev->handler = ngx_http_v2_read_handler; if (rev->ready) { @@ -4137,9 +4149,6 @@ ngx_http_v2_handle_connection_handler(ngx_event_t *rev) return; } - c = rev->data; - h2c = c->data; - if (h2c->last_out && ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) { ngx_http_v2_finalize_connection(h2c, 0); return; @@ -4262,7 +4271,10 @@ ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c, if (stream->queued) { stream->queued = 0; + ev = fc->write; + ev->active = 0; + ev->ready = 1; } else { ev = fc->read; diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h index cddfccd..be34a09 100644 --- a/src/http/v2/ngx_http_v2.h +++ b/src/http/v2/ngx_http_v2.h @@ -249,8 +249,8 @@ ngx_http_v2_queue_blocked_frame(ngx_http_v2_connection_t *h2c, { ngx_http_v2_out_frame_t **out; - for (out = &h2c->last_out; *out; out = &(*out)->next) - { + for (out = &h2c->last_out; *out; out = &(*out)->next) { + if ((*out)->blocked || (*out)->stream == NULL) { break; } @@ -264,8 +264,7 @@ ngx_http_v2_queue_blocked_frame(ngx_http_v2_connection_t *h2c, void ngx_http_v2_init(ngx_event_t *rev); void ngx_http_v2_request_headers_init(void); -ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r, - ngx_http_client_body_handler_pt post_handler); +ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r); ngx_int_t ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r); void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc); diff --git a/src/http/v2/ngx_http_v2_filter_module.c b/src/http/v2/ngx_http_v2_filter_module.c index f2f0d1e..7276531 100644 --- a/src/http/v2/ngx_http_v2_filter_module.c +++ b/src/http/v2/ngx_http_v2_filter_module.c @@ -148,6 +148,10 @@ ngx_http_v2_header_filter(ngx_http_request_t *r) 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)]; + static size_t nginx_ver_build_len = + ngx_http_v2_literal_size(NGINX_VER_BUILD); + static u_char nginx_ver_build[ngx_http_v2_literal_size(NGINX_VER_BUILD)]; + if (!r->stream) { return ngx_http_next_header_filter(r); } @@ -232,7 +236,16 @@ ngx_http_v2_header_filter(ngx_http_request_t *r) clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->headers_out.server == NULL) { - len += 1 + (clcf->server_tokens ? nginx_ver_len : sizeof(nginx)); + + if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { + len += 1 + nginx_ver_len; + + } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { + len += 1 + nginx_ver_build_len; + + } else { + len += 1 + sizeof(nginx); + } } if (r->headers_out.date == NULL) { @@ -420,13 +433,25 @@ ngx_http_v2_header_filter(ngx_http_request_t *r) } if (r->headers_out.server == NULL) { - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, - "http2 output header: \"server: %s\"", - clcf->server_tokens ? NGINX_VER : "nginx"); + + if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \"server: %s\"", + NGINX_VER); + + } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \"server: %s\"", + NGINX_VER_BUILD); + + } else { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 output header: \"server: nginx\""); + } *pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_SERVER_INDEX); - if (clcf->server_tokens) { + if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { if (nginx_ver[0] == '\0') { p = ngx_http_v2_write_value(nginx_ver, (u_char *) NGINX_VER, sizeof(NGINX_VER) - 1, tmp); @@ -435,6 +460,16 @@ ngx_http_v2_header_filter(ngx_http_request_t *r) pos = ngx_cpymem(pos, nginx_ver, nginx_ver_len); + } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { + if (nginx_ver_build[0] == '\0') { + p = ngx_http_v2_write_value(nginx_ver_build, + (u_char *) NGINX_VER_BUILD, + sizeof(NGINX_VER_BUILD) - 1, tmp); + nginx_ver_build_len = p - nginx_ver_build; + } + + pos = ngx_cpymem(pos, nginx_ver_build, nginx_ver_build_len); + } else { pos = ngx_cpymem(pos, nginx, sizeof(nginx)); } @@ -584,6 +619,8 @@ ngx_http_v2_header_filter(ngx_http_request_t *r) 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; @@ -592,8 +629,6 @@ ngx_http_v2_header_filter(ngx_http_request_t *r) cln->handler = ngx_http_v2_filter_cleanup; cln->data = r->stream; - r->stream->queued = 1; - fc->send_chain = ngx_http_v2_send_chain; fc->need_last_buf = 1; @@ -734,6 +769,8 @@ ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos, rest -= frame_size; if (rest) { + frame->length += NGX_HTTP_V2_FRAME_HEADER_SIZE; + type = NGX_HTTP_V2_CONTINUATION_FRAME; flags = NGX_HTTP_V2_NO_FLAG; continue; @@ -1174,6 +1211,9 @@ ngx_http_v2_headers_frame_handler(ngx_http_v2_connection_t *h2c, "http2:%ui HEADERS frame %p was sent", stream->node->id, frame); + stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE + + frame->length; + ngx_http_v2_handle_frame(stream, frame); ngx_http_v2_handle_stream(h2c, stream); diff --git a/src/mail/ngx_mail.c b/src/mail/ngx_mail.c index 9e560bb..5fd5fa0 100644 --- a/src/mail/ngx_mail.c +++ b/src/mail/ngx_mail.c @@ -333,6 +333,8 @@ ngx_mail_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) ls->log.handler = ngx_accept_log_error; ls->backlog = addr[i].opt.backlog; + ls->rcvbuf = addr[i].opt.rcvbuf; + ls->sndbuf = addr[i].opt.sndbuf; ls->keepalive = addr[i].opt.so_keepalive; #if (NGX_HAVE_KEEPALIVE_TUNABLE) diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h index 6002508..6ecfefc 100644 --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -46,6 +46,8 @@ typedef struct { int tcp_keepcnt; #endif int backlog; + int rcvbuf; + int sndbuf; } ngx_mail_listen_t; diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c index b974d90..276b8ee 100644 --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_core_module.c @@ -295,7 +295,7 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_mail_core_srv_conf_t *cscf = conf; - ngx_str_t *value; + ngx_str_t *value, size; ngx_url_t u; ngx_uint_t i, m; ngx_mail_listen_t *ls; @@ -350,6 +350,8 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ls->socklen = u.socklen; ls->backlog = NGX_LISTEN_BACKLOG; + ls->rcvbuf = -1; + ls->sndbuf = -1; ls->wildcard = u.wildcard; ls->ctx = cf->ctx; @@ -398,6 +400,38 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) continue; } + if (ngx_strncmp(value[i].data, "rcvbuf=", 7) == 0) { + size.len = value[i].len - 7; + size.data = value[i].data + 7; + + ls->rcvbuf = ngx_parse_size(&size); + ls->bind = 1; + + if (ls->rcvbuf == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid rcvbuf \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + + if (ngx_strncmp(value[i].data, "sndbuf=", 7) == 0) { + size.len = value[i].len - 7; + size.data = value[i].data + 7; + + ls->sndbuf = ngx_parse_size(&size); + ls->bind = 1; + + if (ls->sndbuf == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid sndbuf \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) size_t len; diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c index 9d4ef56..f6b26ed 100644 --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -222,7 +222,7 @@ ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c) ngx_mail_session_t *s; ngx_mail_core_srv_conf_t *cscf; - if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { + if (ngx_ssl_create_connection(ssl, c, 0) != NGX_OK) { ngx_mail_close_connection(c); return; } diff --git a/src/mail/ngx_mail_pop3_module.c b/src/mail/ngx_mail_pop3_module.c index bd60e0a..a673070 100644 --- a/src/mail/ngx_mail_pop3_module.c +++ b/src/mail/ngx_mail_pop3_module.c @@ -185,6 +185,10 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { + if (ngx_mail_pop3_auth_methods_names[i].len == 0) { + continue; + } + if (m & conf->auth_methods) { size += 1 + ngx_mail_pop3_auth_methods_names[i].len; } @@ -212,6 +216,10 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { + if (ngx_mail_pop3_auth_methods_names[i].len == 0) { + continue; + } + if (m & conf->auth_methods) { *p++ = ' '; p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data, @@ -248,6 +256,10 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { + if (ngx_mail_pop3_auth_methods_names[i].len == 0) { + continue; + } + if (m & conf->auth_methods) { size += ngx_mail_pop3_auth_methods_names[i].len + sizeof(CRLF) - 1; @@ -269,6 +281,10 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED; m <<= 1, i++) { + if (ngx_mail_pop3_auth_methods_names[i].len == 0) { + continue; + } + if (m & conf->auth_methods) { p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data, ngx_mail_pop3_auth_methods_names[i].len); diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c index fbc9bc7..aebd179 100644 --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -42,6 +42,7 @@ static ngx_conf_bitmask_t ngx_mail_ssl_protocols[] = { { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, + { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 }, { ngx_null_string, 0 } }; diff --git a/src/os/unix/ngx_darwin_config.h b/src/os/unix/ngx_darwin_config.h index cfe3ce2..0dfe633 100644 --- a/src/os/unix/ngx_darwin_config.h +++ b/src/os/unix/ngx_darwin_config.h @@ -9,6 +9,9 @@ #define _NGX_DARWIN_CONFIG_H_INCLUDED_ +#define __APPLE_USE_RFC_3542 /* IPV6_PKTINFO */ + + #include #include #include diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c index 3c0696a..b44724c 100644 --- a/src/os/unix/ngx_linux_sendfile_chain.c +++ b/src/os/unix/ngx_linux_sendfile_chain.c @@ -20,8 +20,8 @@ static ssize_t ngx_linux_sendfile(ngx_connection_t *c, ngx_buf_t *file, #error sendfile64() is required! #endif -static ngx_int_t ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, - size_t size, size_t *sent); +static ssize_t ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, + size_t size); static void ngx_linux_sendfile_thread_handler(void *data, ngx_log_t *log); #endif @@ -56,10 +56,6 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) ngx_chain_t *cl; ngx_iovec_t header; struct iovec headers[NGX_IOVS_PREALLOCATE]; -#if (NGX_THREADS) - ngx_int_t rc; - ngx_uint_t thread_handled, thread_complete; -#endif wev = c->write; @@ -82,10 +78,6 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) for ( ;; ) { prev_send = send; -#if (NGX_THREADS) - thread_handled = 0; - thread_complete = 0; -#endif /* create the iovec and coalesce the neighbouring bufs */ @@ -179,38 +171,19 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) } #endif -#if (NGX_THREADS) - if (file->file->thread_handler) { - rc = ngx_linux_sendfile_thread(c, file, file_size, &sent); + n = ngx_linux_sendfile(c, file, file_size); - switch (rc) { - case NGX_OK: - thread_handled = 1; - break; - - case NGX_DONE: - thread_complete = 1; - break; - - case NGX_AGAIN: - break; - - default: /* NGX_ERROR */ - return NGX_CHAIN_ERROR; - } - - } else -#endif - { - n = ngx_linux_sendfile(c, file, file_size); - - if (n == NGX_ERROR) { - return NGX_CHAIN_ERROR; - } - - sent = (n == NGX_AGAIN) ? 0 : n; + if (n == NGX_ERROR) { + return NGX_CHAIN_ERROR; } + if (n == NGX_DONE) { + /* thread task posted */ + return in; + } + + sent = (n == NGX_AGAIN) ? 0 : n; + } else { n = ngx_writev(c, &header); @@ -225,21 +198,27 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) in = ngx_chain_update_sent(in, sent); - if ((size_t) (send - prev_send) != sent) { -#if (NGX_THREADS) - if (thread_handled) { - return in; - } - - if (thread_complete) { - send = prev_send + sent; - continue; - } -#endif + if (n == NGX_AGAIN) { wev->ready = 0; return in; } + if ((size_t) (send - prev_send) != sent) { + + /* + * sendfile() on Linux 4.3+ might be interrupted at any time, + * and provides no indication if it was interrupted or not, + * so we have to retry till an explicit EAGAIN + * + * sendfile() in threads can also report less bytes written + * than we are prepared to send now, since it was started in + * some point in the past, so we again have to retry + */ + + send = prev_send + sent; + continue; + } + if (send >= limit || in == NULL) { return in; } @@ -258,6 +237,14 @@ ngx_linux_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size) ssize_t n; ngx_err_t err; +#if (NGX_THREADS) + + if (file->file->thread_handler) { + return ngx_linux_sendfile_thread(c, file, size); + } + +#endif + #if (NGX_HAVE_SENDFILE64) offset = file->file_pos; #else @@ -324,9 +311,8 @@ typedef struct { } ngx_linux_sendfile_ctx_t; -static ngx_int_t -ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size, - size_t *sent) +static ssize_t +ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size) { ngx_event_t *wev; ngx_thread_task_t *task; @@ -356,10 +342,14 @@ ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size, task->event.complete = 0; if (ctx->err == NGX_EAGAIN) { - *sent = 0; + /* + * if wev->complete is set, this means that a write event + * happened while we were waiting for the thread task, so + * we have to retry sending even on EAGAIN + */ if (wev->complete) { - return NGX_DONE; + return 0; } return NGX_AGAIN; @@ -384,13 +374,7 @@ ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size, return NGX_ERROR; } - *sent = ctx->sent; - - if (ctx->sent == ctx->size || wev->complete) { - return NGX_DONE; - } - - return NGX_AGAIN; + return ctx->sent; } if (task->event.active && ctx->file == file) { @@ -399,9 +383,7 @@ ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size, * or multiple calls of the next body filter from a filter */ - *sent = 0; - - return NGX_OK; + return NGX_DONE; } ctx->file = file; @@ -414,9 +396,7 @@ ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size, return NGX_ERROR; } - *sent = 0; - - return NGX_OK; + return NGX_DONE; } diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c index 24a63fb..993c032 100644 --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c @@ -15,13 +15,13 @@ typedef struct { int signo; char *signame; char *name; - void (*handler)(int signo); + void (*handler)(int signo, siginfo_t *siginfo, void *ucontext); } ngx_signal_t; static void ngx_execute_proc(ngx_cycle_t *cycle, void *data); -static void ngx_signal_handler(int signo); +static void ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext); static void ngx_process_get_status(void); static void ngx_unlock_mutexes(ngx_pid_t pid); @@ -75,9 +75,9 @@ ngx_signal_t signals[] = { { SIGCHLD, "SIGCHLD", "", ngx_signal_handler }, - { SIGSYS, "SIGSYS, SIG_IGN", "", SIG_IGN }, + { SIGSYS, "SIGSYS, SIG_IGN", "", NULL }, - { SIGPIPE, "SIGPIPE, SIG_IGN", "", SIG_IGN }, + { SIGPIPE, "SIGPIPE, SIG_IGN", "", NULL }, { 0, NULL, "", NULL } }; @@ -288,7 +288,15 @@ ngx_init_signals(ngx_log_t *log) for (sig = signals; sig->signo != 0; sig++) { ngx_memzero(&sa, sizeof(struct sigaction)); - sa.sa_handler = sig->handler; + + if (sig->handler) { + sa.sa_sigaction = sig->handler; + sa.sa_flags = SA_SIGINFO; + + } else { + sa.sa_handler = SIG_IGN; + } + sigemptyset(&sa.sa_mask); if (sigaction(sig->signo, &sa, NULL) == -1) { #if (NGX_VALGRIND) @@ -306,8 +314,8 @@ ngx_init_signals(ngx_log_t *log) } -void -ngx_signal_handler(int signo) +static void +ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext) { char *action; ngx_int_t ignore; @@ -405,6 +413,7 @@ ngx_signal_handler(int signo) break; } ngx_debug_quit = 1; + /* fall through */ case ngx_signal_value(NGX_SHUTDOWN_SIGNAL): ngx_quit = 1; action = ", shutting down"; @@ -431,8 +440,16 @@ ngx_signal_handler(int signo) break; } - ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, - "signal %d (%s) received%s", signo, sig->signame, action); + if (siginfo && siginfo->si_pid) { + ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, + "signal %d (%s) received from %P%s", + signo, sig->signame, siginfo->si_pid, action); + + } else { + ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, + "signal %d (%s) received%s", + signo, sig->signame, action); + } if (ignore) { ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, 0, diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index 5c4e21d..1710ea8 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -738,12 +738,8 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) for ( ;; ) { if (ngx_exiting) { - ngx_event_cancel_timers(); - - if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel) - { + if (ngx_event_no_timers_left() == NGX_OK) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); - ngx_worker_process_exit(cycle); } } @@ -754,7 +750,6 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) if (ngx_terminate) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); - ngx_worker_process_exit(cycle); } @@ -766,6 +761,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) if (!ngx_exiting) { ngx_exiting = 1; + ngx_set_shutdown_timer(cycle); ngx_close_listening_sockets(cycle); ngx_close_idle_connections(cycle); } diff --git a/src/os/unix/ngx_udp_sendmsg_chain.c b/src/os/unix/ngx_udp_sendmsg_chain.c index 65bde6f..5f1cfa5 100644 --- a/src/os/unix/ngx_udp_sendmsg_chain.c +++ b/src/os/unix/ngx_udp_sendmsg_chain.c @@ -203,6 +203,20 @@ ngx_sendmsg(ngx_connection_t *c, ngx_iovec_t *vec) ngx_err_t err; struct msghdr msg; +#if (NGX_HAVE_MSGHDR_MSG_CONTROL) + +#if (NGX_HAVE_IP_SENDSRCADDR) + u_char msg_control[CMSG_SPACE(sizeof(struct in_addr))]; +#elif (NGX_HAVE_IP_PKTINFO) + u_char msg_control[CMSG_SPACE(sizeof(struct in_pktinfo))]; +#endif + +#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) + u_char msg_control6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; +#endif + +#endif + ngx_memzero(&msg, sizeof(struct msghdr)); if (c->socklen) { @@ -213,6 +227,82 @@ ngx_sendmsg(ngx_connection_t *c, ngx_iovec_t *vec) msg.msg_iov = vec->iovs; msg.msg_iovlen = vec->count; +#if (NGX_HAVE_MSGHDR_MSG_CONTROL) + + if (c->listening && c->listening->wildcard && c->local_sockaddr) { + +#if (NGX_HAVE_IP_SENDSRCADDR) + + if (c->local_sockaddr->sa_family == AF_INET) { + struct cmsghdr *cmsg; + struct in_addr *addr; + struct sockaddr_in *sin; + + msg.msg_control = &msg_control; + msg.msg_controllen = sizeof(msg_control); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_SENDSRCADDR; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); + + sin = (struct sockaddr_in *) c->local_sockaddr; + + addr = (struct in_addr *) CMSG_DATA(cmsg); + *addr = sin->sin_addr; + } + +#elif (NGX_HAVE_IP_PKTINFO) + + if (c->local_sockaddr->sa_family == AF_INET) { + struct cmsghdr *cmsg; + struct in_pktinfo *pkt; + struct sockaddr_in *sin; + + msg.msg_control = &msg_control; + msg.msg_controllen = sizeof(msg_control); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_PKTINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); + + sin = (struct sockaddr_in *) c->local_sockaddr; + + pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); + ngx_memzero(pkt, sizeof(struct in_pktinfo)); + pkt->ipi_spec_dst = sin->sin_addr; + } + +#endif + +#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO) + + if (c->local_sockaddr->sa_family == AF_INET6) { + struct cmsghdr *cmsg; + struct in6_pktinfo *pkt6; + struct sockaddr_in6 *sin6; + + msg.msg_control = &msg_control6; + msg.msg_controllen = sizeof(msg_control6); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = IPPROTO_IPV6; + cmsg->cmsg_type = IPV6_PKTINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); + + sin6 = (struct sockaddr_in6 *) c->local_sockaddr; + + pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); + ngx_memzero(pkt6, sizeof(struct in6_pktinfo)); + pkt6->ipi6_addr = sin6->sin6_addr; + } + +#endif + } + +#endif + eintr: n = sendmsg(c->fd, &msg, 0); diff --git a/src/stream/ngx_stream.c b/src/stream/ngx_stream.c index 4a394d7..0efbda8 100644 --- a/src/stream/ngx_stream.c +++ b/src/stream/ngx_stream.c @@ -494,6 +494,8 @@ ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) ls->log.handler = ngx_accept_log_error; ls->backlog = addr[i].opt.backlog; + ls->rcvbuf = addr[i].opt.rcvbuf; + ls->sndbuf = addr[i].opt.sndbuf; ls->wildcard = addr[i].opt.wildcard; diff --git a/src/stream/ngx_stream.h b/src/stream/ngx_stream.h index 9e4169c..09d2459 100644 --- a/src/stream/ngx_stream.h +++ b/src/stream/ngx_stream.h @@ -62,6 +62,8 @@ typedef struct { int tcp_keepcnt; #endif int backlog; + int rcvbuf; + int sndbuf; int type; } ngx_stream_listen_t; @@ -153,7 +155,8 @@ typedef struct { ngx_hash_t variables_hash; - ngx_array_t variables; /* ngx_stream_variable_t */ + ngx_array_t variables; /* ngx_stream_variable_t */ + ngx_array_t prefix_variables; /* ngx_stream_variable_t */ ngx_uint_t ncaptures; ngx_uint_t variables_hash_max_size; diff --git a/src/stream/ngx_stream_access_module.c b/src/stream/ngx_stream_access_module.c index 1745cdf..a3020d4 100644 --- a/src/stream/ngx_stream_access_module.c +++ b/src/stream/ngx_stream_access_module.c @@ -299,28 +299,22 @@ ngx_stream_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_stream_access_rule_un_t *rule_un; #endif + all = 0; ngx_memzero(&cidr, sizeof(ngx_cidr_t)); value = cf->args->elts; - all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0); - - if (!all) { + if (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0) { + all = 1; #if (NGX_HAVE_UNIX_DOMAIN) - - if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) { - cidr.family = AF_UNIX; - rc = NGX_OK; - - } else { - rc = ngx_ptocidr(&value[1], &cidr); - } - -#else - rc = ngx_ptocidr(&value[1], &cidr); + } else if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) { + cidr.family = AF_UNIX; #endif + } else { + rc = ngx_ptocidr(&value[1], &cidr); + if (rc == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[1]); diff --git a/src/stream/ngx_stream_core_module.c b/src/stream/ngx_stream_core_module.c index f7870ee..272708d 100644 --- a/src/stream/ngx_stream_core_module.c +++ b/src/stream/ngx_stream_core_module.c @@ -309,7 +309,6 @@ ngx_int_t ngx_stream_core_content_phase(ngx_stream_session_t *s, ngx_stream_phase_handler_t *ph) { - int tcp_nodelay; ngx_connection_t *c; ngx_stream_core_srv_conf_t *cscf; @@ -321,22 +320,10 @@ ngx_stream_core_content_phase(ngx_stream_session_t *s, if (c->type == SOCK_STREAM && cscf->tcp_nodelay - && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) + && ngx_tcp_nodelay(c) != NGX_OK) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(c, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return NGX_OK; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; + ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return NGX_OK; } cscf->handler(s); @@ -582,7 +569,7 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_stream_core_srv_conf_t *cscf = conf; - ngx_str_t *value; + ngx_str_t *value, size; ngx_url_t u; ngx_uint_t i, backlog; ngx_stream_listen_t *ls, *als; @@ -620,6 +607,8 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ls->socklen = u.socklen; ls->backlog = NGX_LISTEN_BACKLOG; + ls->rcvbuf = -1; + ls->sndbuf = -1; ls->type = SOCK_STREAM; ls->wildcard = u.wildcard; ls->ctx = cf->ctx; @@ -659,6 +648,38 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) continue; } + if (ngx_strncmp(value[i].data, "rcvbuf=", 7) == 0) { + size.len = value[i].len - 7; + size.data = value[i].data + 7; + + ls->rcvbuf = ngx_parse_size(&size); + ls->bind = 1; + + if (ls->rcvbuf == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid rcvbuf \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + + if (ngx_strncmp(value[i].data, "sndbuf=", 7) == 0) { + size.len = value[i].len - 7; + size.data = value[i].data + 7; + + ls->sndbuf = ngx_parse_size(&size); + ls->bind = 1; + + if (ls->sndbuf == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid sndbuf \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) size_t len; diff --git a/src/stream/ngx_stream_log_module.c b/src/stream/ngx_stream_log_module.c index a4b67d0..466bdda 100644 --- a/src/stream/ngx_stream_log_module.c +++ b/src/stream/ngx_stream_log_module.c @@ -443,6 +443,11 @@ ngx_stream_log_script_write(ngx_stream_session_t *s, s->connection->pool) != NGX_OK) { + if (of.err == 0) { + /* simulate successful logging */ + return len; + } + ngx_log_error(NGX_LOG_CRIT, s->connection->log, ngx_errno, "%s \"%s\" failed", of.failed, log.data); /* simulate successful logging */ @@ -641,23 +646,10 @@ ngx_stream_log_flush(ngx_open_file_t *file, ngx_log_t *log) static void ngx_stream_log_flush_handler(ngx_event_t *ev) { - ngx_open_file_t *file; - ngx_stream_log_buf_t *buffer; - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "stream log buffer flush handler"); - if (ev->timedout) { - ngx_stream_log_flush(ev->data, ev->log); - return; - } - - /* cancel the flush timer for graceful shutdown */ - - file = ev->data; - buffer = file->data; - - buffer->event = NULL; + ngx_stream_log_flush(ev->data, ev->log); } diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c index 81a0891..0afde1c 100644 --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -103,6 +103,7 @@ static ngx_conf_bitmask_t ngx_stream_proxy_ssl_protocols[] = { { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, + { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 }, { ngx_null_string, 0 } }; @@ -728,7 +729,6 @@ ngx_stream_proxy_connect(ngx_stream_session_t *s) static void ngx_stream_proxy_init_upstream(ngx_stream_session_t *s) { - int tcp_nodelay; u_char *p; ngx_chain_t *cl; ngx_connection_t *c, *pc; @@ -744,22 +744,10 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s) if (pc->type == SOCK_STREAM && cscf->tcp_nodelay - && pc->tcp_nodelay == NGX_TCP_NODELAY_UNSET) + && ngx_tcp_nodelay(pc) != NGX_OK) { - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "tcp_nodelay"); - - tcp_nodelay = 1; - - if (setsockopt(pc->fd, IPPROTO_TCP, TCP_NODELAY, - (const void *) &tcp_nodelay, sizeof(int)) == -1) - { - ngx_connection_error(pc, ngx_socket_errno, - "setsockopt(TCP_NODELAY) failed"); - ngx_stream_proxy_next_upstream(s); - return; - } - - pc->tcp_nodelay = NGX_TCP_NODELAY_SET; + ngx_stream_proxy_next_upstream(s); + return; } pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); diff --git a/src/stream/ngx_stream_realip_module.c b/src/stream/ngx_stream_realip_module.c index 0740431..1266605 100644 --- a/src/stream/ngx_stream_realip_module.c +++ b/src/stream/ngx_stream_realip_module.c @@ -178,9 +178,15 @@ ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_stream_realip_srv_conf_t *rscf = conf; - ngx_int_t rc; - ngx_str_t *value; - ngx_cidr_t *cidr; + ngx_int_t rc; + ngx_str_t *value; + ngx_url_t u; + ngx_cidr_t c, *cidr; + ngx_uint_t i; + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif value = cf->args->elts; @@ -192,31 +198,78 @@ ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } } - cidr = ngx_array_push(rscf->from); - if (cidr == NULL) { - return NGX_CONF_ERROR; - } - #if (NGX_HAVE_UNIX_DOMAIN) if (ngx_strcmp(value[1].data, "unix:") == 0) { + cidr = ngx_array_push(rscf->from); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + cidr->family = AF_UNIX; return NGX_CONF_OK; } #endif - rc = ngx_ptocidr(&value[1], cidr); + rc = ngx_ptocidr(&value[1], &c); + + if (rc != NGX_ERROR) { + if (rc == NGX_DONE) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "low address bits of %V are meaningless", + &value[1]); + } + + cidr = ngx_array_push(rscf->from); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + + *cidr = c; + + return NGX_CONF_OK; + } + + ngx_memzero(&u, sizeof(ngx_url_t)); + u.host = value[1]; + + if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { + if (u.err) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "%s in set_real_ip_from \"%V\"", + u.err, &u.host); + } - if (rc == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", - &value[1]); return NGX_CONF_ERROR; } - if (rc == NGX_DONE) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "low address bits of %V are meaningless", &value[1]); + cidr = ngx_array_push_n(rscf->from, u.naddrs); + if (cidr == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t)); + + for (i = 0; i < u.naddrs; i++) { + cidr[i].family = u.addrs[i].sockaddr->sa_family; + + switch (cidr[i].family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr; + cidr[i].u.in6.addr = sin6->sin6_addr; + ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16); + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) u.addrs[i].sockaddr; + cidr[i].u.in.addr = sin->sin_addr.s_addr; + cidr[i].u.in.mask = 0xffffffff; + break; + } } return NGX_CONF_OK; diff --git a/src/stream/ngx_stream_script.c b/src/stream/ngx_stream_script.c index ff8e655..aa555ca 100644 --- a/src/stream/ngx_stream_script.c +++ b/src/stream/ngx_stream_script.c @@ -222,7 +222,7 @@ ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, cv = (ngx_stream_complex_value_t **) (p + cmd->offset); if (*cv != NULL) { - return "duplicate"; + return "is duplicate"; } *cv = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t)); diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c index 2f242b6..da26a41 100644 --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -45,6 +45,7 @@ static ngx_conf_bitmask_t ngx_stream_ssl_protocols[] = { { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, + { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 }, { ngx_null_string, 0 } }; @@ -351,13 +352,20 @@ ngx_stream_ssl_handler(ngx_stream_session_t *s) static ngx_int_t ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c) { - ngx_int_t rc; - ngx_stream_session_t *s; - ngx_stream_ssl_conf_t *sslcf; + ngx_int_t rc; + ngx_stream_session_t *s; + ngx_stream_ssl_conf_t *sslcf; + ngx_stream_core_srv_conf_t *cscf; s = c->data; - if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { + cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); + + if (cscf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) { + return NGX_ERROR; + } + + if (ngx_ssl_create_connection(ssl, c, 0) != NGX_OK) { return NGX_ERROR; } diff --git a/src/stream/ngx_stream_variables.c b/src/stream/ngx_stream_variables.c index 9dc93ee..5d15f3a 100644 --- a/src/stream/ngx_stream_variables.c +++ b/src/stream/ngx_stream_variables.c @@ -10,6 +10,8 @@ #include #include +static ngx_stream_variable_t *ngx_stream_add_prefix_variable(ngx_conf_t *cf, + ngx_str_t *name, ngx_uint_t flags); static ngx_int_t ngx_stream_variable_binary_remote_addr( ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); @@ -137,6 +139,10 @@ ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) return NULL; } + if (flags & NGX_STREAM_VAR_PREFIX) { + return ngx_stream_add_prefix_variable(cf, name, flags); + } + cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); key = cmcf->variables_keys->keys.elts; @@ -155,6 +161,8 @@ ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) return NULL; } + v->flags &= flags | ~NGX_STREAM_VAR_WEAK; + return v; } @@ -193,6 +201,60 @@ ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) } +static ngx_stream_variable_t * +ngx_stream_add_prefix_variable(ngx_conf_t *cf, ngx_str_t *name, + ngx_uint_t flags) +{ + ngx_uint_t i; + ngx_stream_variable_t *v; + ngx_stream_core_main_conf_t *cmcf; + + cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); + + v = cmcf->prefix_variables.elts; + for (i = 0; i < cmcf->prefix_variables.nelts; i++) { + if (name->len != v[i].name.len + || ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0) + { + continue; + } + + v = &v[i]; + + if (!(v->flags & NGX_STREAM_VAR_CHANGEABLE)) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the duplicate \"%V\" variable", name); + return NULL; + } + + v->flags &= flags | ~NGX_STREAM_VAR_WEAK; + + return v; + } + + v = ngx_array_push(&cmcf->prefix_variables); + if (v == NULL) { + return NULL; + } + + v->name.len = name->len; + v->name.data = ngx_pnalloc(cf->pool, name->len); + if (v->name.data == NULL) { + return NULL; + } + + ngx_strlow(v->name.data, name->data, name->len); + + v->set_handler = NULL; + v->get_handler = NULL; + v->data = 0; + v->flags = flags; + v->index = 0; + + return v; +} + + ngx_int_t ngx_stream_get_variable_index(ngx_conf_t *cf, ngx_str_t *name) { @@ -327,6 +389,8 @@ ngx_stream_variable_value_t * ngx_stream_get_variable(ngx_stream_session_t *s, ngx_str_t *name, ngx_uint_t key) { + size_t len; + ngx_uint_t i, n; ngx_stream_variable_t *v; ngx_stream_variable_value_t *vv; ngx_stream_core_main_conf_t *cmcf; @@ -365,6 +429,28 @@ ngx_stream_get_variable(ngx_stream_session_t *s, ngx_str_t *name, return NULL; } + len = 0; + + v = cmcf->prefix_variables.elts; + n = cmcf->prefix_variables.nelts; + + for (i = 0; i < cmcf->prefix_variables.nelts; i++) { + if (name->len >= v[i].name.len && name->len > len + && ngx_strncmp(name->data, v[i].name.data, v[i].name.len) == 0) + { + len = v[i].name.len; + n = i; + } + } + + if (n != cmcf->prefix_variables.nelts) { + if (v[n].get_handler(s, vv, (uintptr_t) name) == NGX_OK) { + return vv; + } + + return NULL; + } + vv->not_found = 1; return vv; @@ -1000,7 +1086,6 @@ ngx_stream_regex_exec(ngx_stream_session_t *s, ngx_stream_regex_t *re, ngx_int_t ngx_stream_variables_add_core_vars(ngx_conf_t *cf) { - ngx_int_t rc; ngx_stream_variable_t *cv, *v; ngx_stream_core_main_conf_t *cmcf; @@ -1021,27 +1106,20 @@ ngx_stream_variables_add_core_vars(ngx_conf_t *cf) return NGX_ERROR; } + if (ngx_array_init(&cmcf->prefix_variables, cf->pool, 8, + sizeof(ngx_stream_variable_t)) + != NGX_OK) + { + return NGX_ERROR; + } + for (cv = ngx_stream_core_variables; cv->name.len; cv++) { - v = ngx_palloc(cf->pool, sizeof(ngx_stream_variable_t)); + v = ngx_stream_add_variable(cf, &cv->name, cv->flags); if (v == NULL) { return NGX_ERROR; } *v = *cv; - - rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, - NGX_HASH_READONLY_KEY); - - if (rc == NGX_OK) { - continue; - } - - if (rc == NGX_BUSY) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "conflicting variable name \"%V\"", &v->name); - } - - return NGX_ERROR; } return NGX_OK; @@ -1051,10 +1129,11 @@ ngx_stream_variables_add_core_vars(ngx_conf_t *cf) ngx_int_t ngx_stream_variables_init_vars(ngx_conf_t *cf) { + size_t len; ngx_uint_t i, n; ngx_hash_key_t *key; ngx_hash_init_t hash; - ngx_stream_variable_t *v, *av; + ngx_stream_variable_t *v, *av, *pv; ngx_stream_core_main_conf_t *cmcf; /* set the handlers for the indexed stream variables */ @@ -1062,6 +1141,7 @@ ngx_stream_variables_init_vars(ngx_conf_t *cf) cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); v = cmcf->variables.elts; + pv = cmcf->prefix_variables.elts; key = cmcf->variables_keys->keys.elts; for (i = 0; i < cmcf->variables.nelts; i++) { @@ -1082,7 +1162,9 @@ ngx_stream_variables_init_vars(ngx_conf_t *cf) av->index = i; - if (av->get_handler == NULL) { + if (av->get_handler == NULL + || (av->flags & NGX_STREAM_VAR_WEAK)) + { break; } @@ -1090,10 +1172,32 @@ ngx_stream_variables_init_vars(ngx_conf_t *cf) } } - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "unknown \"%V\" variable", &v[i].name); + len = 0; + av = NULL; - return NGX_ERROR; + for (n = 0; n < cmcf->prefix_variables.nelts; n++) { + if (v[i].name.len >= pv[n].name.len && v[i].name.len > len + && ngx_strncmp(v[i].name.data, pv[n].name.data, pv[n].name.len) + == 0) + { + av = &pv[n]; + len = pv[n].name.len; + } + } + + if (av) { + v[i].get_handler = av->get_handler; + v[i].data = (uintptr_t) &v[i].name; + v[i].flags = av->flags; + + goto next; + } + + if (v[i].get_handler == NULL) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "unknown \"%V\" variable", &v[i].name); + return NGX_ERROR; + } next: continue; diff --git a/src/stream/ngx_stream_variables.h b/src/stream/ngx_stream_variables.h index e4151e2..8155111 100644 --- a/src/stream/ngx_stream_variables.h +++ b/src/stream/ngx_stream_variables.h @@ -30,6 +30,8 @@ typedef ngx_int_t (*ngx_stream_get_variable_pt) (ngx_stream_session_t *s, #define NGX_STREAM_VAR_NOCACHEABLE 2 #define NGX_STREAM_VAR_INDEXED 4 #define NGX_STREAM_VAR_NOHASH 8 +#define NGX_STREAM_VAR_WEAK 16 +#define NGX_STREAM_VAR_PREFIX 32 struct ngx_stream_variable_s {