Changes of Revision 199
[-] | Changed | nginx.changes |
1
2 ------------------------------------------------------------------- 3 +Wed Oct 12 21:29:31 UTC 2016 - cs@linux-administrator.com 4 + 5 +- update to nginx 1.11.5 6 + 7 +------------------------------------------------------------------- 8 Wed Sep 28 18:04:31 UTC 2016 - cs@linux-administrator.com 9 10 - update to nginx 1.11.4 11 |
||
[-] | Changed | nginx.spec ^ |
10 1
2 3 4 Name: nginx 5 -Version: 1.11.4 6 +Version: 1.11.5 7 Release: 1 8 Summary: Robust, small and high performance http and reverse proxy server 9 Group: System Environment/Daemons 10 |
||
[+] | Changed | _service ^ |
@@ -2,6 +2,6 @@ <service name="download_url"> <param name="host">nginx.org</param> <param name="protocol">http</param> - <param name="path">/download/nginx-1.11.4.tar.gz</param> + <param name="path">/download/nginx-1.11.5.tar.gz</param> </service> </services> | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/CHANGES ^ |
@@ -1,4 +1,43 @@ +Changes with nginx 1.11.5 11 Oct 2016 + + *) Change: the --with-ipv6 configure option was removed, now IPv6 + support is configured automatically. + + *) Change: now if there are no available servers in an upstream, nginx + will not reset number of failures of all servers as it previously + did, but will wait for fail_timeout to expire. + + *) Feature: the ngx_stream_ssl_preread_module. + + *) Feature: the "server" directive in the "upstream" context supports + the "max_conns" parameter. + + *) Feature: the --with-compat configure option. + + *) Feature: "manager_files", "manager_threshold", and "manager_sleep" + parameters of the "proxy_cache_path", "fastcgi_cache_path", + "scgi_cache_path", and "uwsgi_cache_path" directives. + + *) Bugfix: flags passed by the --with-ld-opt configure option were not + used while building perl module. + + *) Bugfix: in the "add_after_body" directive when used with the + "sub_filter" directive. + + *) Bugfix: in the $realip_remote_addr variable. + + *) Bugfix: the "dav_access", "proxy_store_access", + "fastcgi_store_access", "scgi_store_access", and "uwsgi_store_access" + directives ignored permissions specified for user. + + *) Bugfix: unix domain listen sockets might not be inherited during + binary upgrade on Linux. + + *) Bugfix: nginx returned the 400 response on requests with the "-" + character in the HTTP method. + + Changes with nginx 1.11.4 13 Sep 2016 *) Feature: the $upstream_bytes_received variable. | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/CHANGES.ru ^ |
@@ -1,4 +1,43 @@ +Изменения в nginx 1.11.5 11.10.2016 + + *) Изменение: параметр configure --with-ipv6 упразднён, поддержка IPv6 + теперь собирается автоматически. + + *) Изменение: теперь, если в блоке upstream не оказалось доступных + серверов, nginx не сбрасывает статистику ошибок всех серверов, как + делал ранее, а ожидает истечения fail_timeout. + + *) Добавление: модуль ngx_stream_ssl_preread_module. + + *) Добавление: директива server в блоке upstream поддерживает параметр + max_conns. + + *) Добавление: параметр configure --with-compat. + + *) Добавление: параметры manager_files, manager_threshold и + manager_sleep директив proxy_cache_path, fastcgi_cache_path, + scgi_cache_path и uwsgi_cache_path. + + *) Исправление: при сборке perl-модуля не использовались флаги, заданные + с помощью параметра configure --with-ld-opt. + + *) Исправление: в директиве add_after_body при использовании совместно с + директивой sub_filter. + + *) Исправление: в переменной $realip_remote_addr. + + *) Исправление: директивы dav_access, proxy_store_access, + fastcgi_store_access, scgi_store_access и uwsgi_store_access + игнорировали права, заданные для пользователя. + + *) Исправление: unix domain listen-сокеты могли не наследоваться при + обновлении исполняемого файла на Linux. + + *) Исправление: nginx возвращал ошибку 400 на запросы с символом "-" в + HTTP-методе. + + Изменения в nginx 1.11.4 13.09.2016 *) Добавление: переменная $upstream_bytes_received. | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/auto/lib/geoip/conf ^ |
@@ -74,17 +74,15 @@ NGX_LIB_GEOIP=$ngx_feature_libs - if [ $NGX_IPV6 = YES ]; then - ngx_feature="GeoIP IPv6 support" - ngx_feature_name="NGX_HAVE_GEOIP_V6" - ngx_feature_run=no - ngx_feature_incs="#include <stdio.h> - #include <GeoIP.h>" - #ngx_feature_path= - #ngx_feature_libs= - ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);" - . auto/feature - fi + ngx_feature="GeoIP IPv6 support" + ngx_feature_name="NGX_HAVE_GEOIP_V6" + ngx_feature_run=no + ngx_feature_incs="#include <stdio.h> + #include <GeoIP.h>" + #ngx_feature_path= + #ngx_feature_libs= + ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);" + . auto/feature else | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/auto/lib/perl/conf ^ |
@@ -28,8 +28,10 @@ exit 1; fi - NGX_PERL_CFLAGS="$CFLAGS `$NGX_PERL -MExtUtils::Embed -e ccopts`" NGX_PM_CFLAGS=`$NGX_PERL -MExtUtils::Embed -e ccopts` + NGX_PM_LDFLAGS=`$NGX_PERL -MConfig -e 'print $Config{lddlflags}'` + + NGX_PERL_CFLAGS="$CFLAGS `$NGX_PERL -MExtUtils::Embed -e ccopts`" # gcc 4.1/4.2 warn about unused values in pTHX_ NGX_PERL_CFLAGS=`echo $NGX_PERL_CFLAGS \ | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/auto/lib/perl/make ^ |
@@ -35,6 +35,7 @@ cd $NGX_OBJS/src/http/modules/perl \\ && NGX_PM_CFLAGS="\$(NGX_PM_CFLAGS) -g $NGX_CC_OPT" \\ + NGX_PM_LDFLAGS="$NGX_LD_OPT \$(NGX_PM_LDFLAGS)" \\ NGX_INCS="$CORE_INCS $NGX_OBJS $HTTP_INCS" \\ NGX_DEPS="\$(CORE_DEPS) \$(HTTP_DEPS)" \\ $NGX_PERL Makefile.PL \\ | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/auto/make ^ |
@@ -31,6 +31,7 @@ if test -n "$NGX_PERL_CFLAGS"; then echo NGX_PERL_CFLAGS = $NGX_PERL_CFLAGS >> $NGX_MAKEFILE echo NGX_PM_CFLAGS = $NGX_PM_CFLAGS >> $NGX_MAKEFILE + echo NGX_PM_LDFLAGS = $NGX_PM_LDFLAGS >> $NGX_MAKEFILE fi | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/auto/modules ^ |
@@ -973,7 +973,8 @@ ngx_stream_core_module \ ngx_stream_log_module \ ngx_stream_proxy_module \ - ngx_stream_upstream_module" + ngx_stream_upstream_module \ + ngx_stream_write_filter_module" ngx_module_incs="src/stream" ngx_module_deps="src/stream/ngx_stream.h \ src/stream/ngx_stream_variables.h \ @@ -988,7 +989,8 @@ src/stream/ngx_stream_log_module.c \ src/stream/ngx_stream_proxy_module.c \ src/stream/ngx_stream_upstream.c \ - src/stream/ngx_stream_upstream_round_robin.c" + src/stream/ngx_stream_upstream_round_robin.c \ + src/stream/ngx_stream_write_filter_module.c" . auto/module @@ -1118,6 +1120,16 @@ . auto/module fi + + if [ $STREAM_SSL_PREREAD = YES ]; then + ngx_module_name=ngx_stream_ssl_preread_module + ngx_module_deps= + ngx_module_srcs=src/stream/ngx_stream_ssl_preread_module.c + ngx_module_libs= + ngx_module_link=$STREAM_SSL_PREREAD + + . auto/module + fi fi @@ -1300,6 +1312,18 @@ modules="$modules $MISC_MODULES" +if [ $NGX_COMPAT = YES ]; then + have=NGX_COMPAT . auto/have + have=NGX_HTTP_GZIP . auto/have + have=NGX_HTTP_DAV . auto/have + have=NGX_HTTP_REALIP . auto/have + have=NGX_HTTP_X_FORWARDED_FOR . auto/have + have=NGX_HTTP_HEADERS . auto/have + have=NGX_HTTP_UPSTREAM_ZONE . auto/have + have=NGX_STREAM_UPSTREAM_ZONE . auto/have +fi + + cat << END > $NGX_MODULES_C #include <ngx_config.h> | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/auto/options ^ |
@@ -44,7 +44,6 @@ USE_THREADS=NO NGX_FILE_AIO=NO -NGX_IPV6=NO HTTP=YES @@ -126,6 +125,7 @@ STREAM_UPSTREAM_HASH=YES STREAM_UPSTREAM_LEAST_CONN=YES STREAM_UPSTREAM_ZONE=YES +STREAM_SSL_PREREAD=NO DYNAMIC_MODULES= @@ -133,6 +133,8 @@ NGX_ADDON_DEPS= DYNAMIC_ADDONS= +NGX_COMPAT=NO + USE_PCRE=NO PCRE=NONE PCRE_OPT= @@ -201,7 +203,11 @@ --with-threads) USE_THREADS=YES ;; --with-file-aio) NGX_FILE_AIO=YES ;; - --with-ipv6) NGX_IPV6=YES ;; + + --with-ipv6) + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-ipv6\" option is deprecated" + ;; --without-http) HTTP=NO ;; --without-http-cache) HTTP_CACHE=NO ;; @@ -301,6 +307,8 @@ --with-stream_geoip_module) STREAM_GEOIP=YES ;; --with-stream_geoip_module=dynamic) STREAM_GEOIP=DYNAMIC ;; + --with-stream_ssl_preread_module) + STREAM_SSL_PREREAD=YES ;; --without-stream_limit_conn_module) STREAM_LIMIT_CONN=NO ;; --without-stream_access_module) STREAM_ACCESS=NO ;; @@ -322,6 +330,8 @@ --add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;; --add-dynamic-module=*) DYNAMIC_ADDONS="$DYNAMIC_ADDONS $value" ;; + --with-compat) NGX_COMPAT=YES ;; + --with-cc=*) CC="$value" ;; --with-cpp=*) CPP="$value" ;; --with-cc-opt=*) NGX_CC_OPT="$value" ;; @@ -417,7 +427,6 @@ --with-threads enable thread pool support --with-file-aio enable file AIO support - --with-ipv6 enable IPv6 support --with-http_ssl_module enable ngx_http_ssl_module --with-http_v2_module enable ngx_http_v2_module @@ -508,6 +517,7 @@ --with-stream_realip_module enable ngx_stream_realip_module --with-stream_geoip_module enable ngx_stream_geoip_module --with-stream_geoip_module=dynamic enable dynamic ngx_stream_geoip_module + --with-stream_ssl_preread_module enable ngx_stream_ssl_preread_module --without-stream_limit_conn_module disable ngx_stream_limit_conn_module --without-stream_access_module disable ngx_stream_access_module --without-stream_geo_module disable ngx_stream_geo_module @@ -528,6 +538,8 @@ --add-module=PATH enable external module --add-dynamic-module=PATH enable dynamic external module + --with-compat dynamic modules compatibility + --with-cc=PATH set C compiler pathname --with-cpp=PATH set C preprocessor pathname --with-cc-opt=OPTIONS set additional C compiler options | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/auto/os/win32 ^ |
@@ -37,8 +37,6 @@ EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE" fi -if [ $NGX_IPV6 = YES ]; then - have=NGX_HAVE_INET6 . auto/have -fi +have=NGX_HAVE_INET6 . auto/have have=NGX_HAVE_IOCP . auto/have | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/auto/sources ^ |
@@ -167,6 +167,7 @@ src/os/unix/ngx_send.c \ src/os/unix/ngx_writev_chain.c \ src/os/unix/ngx_udp_send.c \ + src/os/unix/ngx_udp_sendmsg_chain.c \ src/os/unix/ngx_channel.c \ src/os/unix/ngx_shmem.c \ src/os/unix/ngx_process.c \ | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/auto/unix ^ |
@@ -637,20 +637,18 @@ # syscalls, libc calls and some features -if [ $NGX_IPV6 = YES ]; then - ngx_feature="AF_INET6" - ngx_feature_name="NGX_HAVE_INET6" - ngx_feature_run=no - ngx_feature_incs="#include <sys/socket.h> - #include <netinet/in.h> - #include <arpa/inet.h>" - ngx_feature_path= - ngx_feature_libs= - ngx_feature_test="struct sockaddr_in6 sin6; - sin6.sin6_family = AF_INET6; - (void) sin6" - . auto/feature -fi +ngx_feature="AF_INET6" +ngx_feature_name="NGX_HAVE_INET6" +ngx_feature_run=no +ngx_feature_incs="#include <sys/socket.h> + #include <netinet/in.h> + #include <arpa/inet.h>" +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="struct sockaddr_in6 sin6; + sin6.sin6_family = AF_INET6; + (void) sin6" +. auto/feature ngx_feature="setproctitle()" | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/nginx.h ^ |
@@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1011004 -#define NGINX_VERSION "1.11.4" +#define nginx_version 1011005 +#define NGINX_VERSION "1.11.5" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_buf.h ^ |
@@ -72,10 +72,8 @@ typedef ngx_int_t (*ngx_output_chain_filter_pt)(void *ctx, ngx_chain_t *in); -#if (NGX_HAVE_FILE_AIO) typedef void (*ngx_output_chain_aio_pt)(ngx_output_chain_ctx_t *ctx, ngx_file_t *file); -#endif struct ngx_output_chain_ctx_s { ngx_buf_t *buf; @@ -85,23 +83,19 @@ unsigned sendfile:1; unsigned directio:1; -#if (NGX_HAVE_ALIGNED_DIRECTIO) unsigned unaligned:1; -#endif unsigned need_in_memory:1; unsigned need_in_temp:1; -#if (NGX_HAVE_FILE_AIO || NGX_THREADS) unsigned aio:1; -#endif -#if (NGX_HAVE_FILE_AIO) +#if (NGX_HAVE_FILE_AIO || NGX_COMPAT) ngx_output_chain_aio_pt aio_handler; -#if (NGX_HAVE_AIO_SENDFILE) +#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) ssize_t (*aio_preload)(ngx_buf_t *file); #endif #endif -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_int_t (*thread_handler)(ngx_thread_task_t *task, ngx_file_t *file); ngx_thread_task_t *thread_task; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_conf_file.c ^ |
@@ -1336,7 +1336,7 @@ return NGX_CONF_OK; } - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid value \"%s\"", value[1].data); return NGX_CONF_ERROR; @@ -1378,7 +1378,7 @@ } if (mask[m].name.len == 0) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid value \"%s\"", value[i].data); return NGX_CONF_ERROR; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_config.h ^ |
@@ -129,4 +129,17 @@ #define NGX_MAX_INT32_VALUE (uint32_t) 0x7fffffff +#if (NGX_COMPAT) + +#define NGX_COMPAT_BEGIN(slots) uint64_t spare[slots]; +#define NGX_COMPAT_END + +#else + +#define NGX_COMPAT_BEGIN(slots) +#define NGX_COMPAT_END + +#endif + + #endif /* _NGX_CONFIG_H_INCLUDED_ */ | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_connection.c ^ |
@@ -1191,10 +1191,7 @@ level = NGX_LOG_CRIT; } - /* we use ngx_cycle->log because c->log was in c->pool */ - - ngx_log_error(level, ngx_cycle->log, err, - ngx_close_socket_n " %d failed", fd); + ngx_log_error(level, c->log, err, ngx_close_socket_n " %d failed", fd); } } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_connection.h ^ |
@@ -66,23 +66,19 @@ unsigned addr_ntop:1; unsigned wildcard:1; -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif -#if (NGX_HAVE_REUSEPORT) unsigned reuseport:1; unsigned add_reuseport:1; -#endif unsigned keepalive:2; -#if (NGX_HAVE_DEFERRED_ACCEPT) unsigned deferred_accept:1; unsigned delete_deferred:1; unsigned add_deferred:1; -#ifdef SO_ACCEPTFILTER +#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) char *accept_filter; #endif -#endif #if (NGX_HAVE_SETFIB) int setfib; #endif @@ -151,7 +147,7 @@ ngx_str_t proxy_protocol_addr; in_port_t proxy_protocol_port; -#if (NGX_SSL) +#if (NGX_SSL || NGX_COMPAT) ngx_ssl_connection_t *ssl; #endif @@ -186,11 +182,11 @@ unsigned need_last_buf:1; -#if (NGX_HAVE_AIO_SENDFILE) +#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) unsigned busy_count:2; #endif -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_thread_task_t *sendfile_task; #endif }; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_core.h ^ |
@@ -12,22 +12,21 @@ #include <ngx_config.h> -typedef struct ngx_module_s ngx_module_t; -typedef struct ngx_conf_s ngx_conf_t; -typedef struct ngx_cycle_s ngx_cycle_t; -typedef struct ngx_pool_s ngx_pool_t; -typedef struct ngx_chain_s ngx_chain_t; -typedef struct ngx_log_s ngx_log_t; -typedef struct ngx_open_file_s ngx_open_file_t; -typedef struct ngx_command_s ngx_command_t; -typedef struct ngx_file_s ngx_file_t; -typedef struct ngx_event_s ngx_event_t; -typedef struct ngx_event_aio_s ngx_event_aio_t; -typedef struct ngx_connection_s ngx_connection_t; - -#if (NGX_THREADS) -typedef struct ngx_thread_task_s ngx_thread_task_t; -#endif +typedef struct ngx_module_s ngx_module_t; +typedef struct ngx_conf_s ngx_conf_t; +typedef struct ngx_cycle_s ngx_cycle_t; +typedef struct ngx_pool_s ngx_pool_t; +typedef struct ngx_chain_s ngx_chain_t; +typedef struct ngx_log_s ngx_log_t; +typedef struct ngx_open_file_s ngx_open_file_t; +typedef struct ngx_command_s ngx_command_t; +typedef struct ngx_file_s ngx_file_t; +typedef struct ngx_event_s ngx_event_t; +typedef struct ngx_event_aio_s ngx_event_aio_t; +typedef struct ngx_connection_s ngx_connection_t; +typedef struct ngx_thread_task_s ngx_thread_task_t; +typedef struct ngx_ssl_s ngx_ssl_t; +typedef struct ngx_ssl_connection_s ngx_ssl_connection_t; typedef void (*ngx_event_handler_pt)(ngx_event_t *ev); typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_file.c ^ |
@@ -441,7 +441,7 @@ u_char *p; ngx_str_t *value; - ngx_uint_t i, right, shift, *access; + ngx_uint_t i, right, shift, *access, user; access = (ngx_uint_t *) (confp + cmd->offset); @@ -451,7 +451,8 @@ value = cf->args->elts; - *access = 0600; + *access = 0; + user = 0600; for (i = 1; i < cf->args->nelts; i++) { @@ -460,6 +461,7 @@ if (ngx_strncmp(p, "user:", sizeof("user:") - 1) == 0) { shift = 6; p += sizeof("user:") - 1; + user = 0; } else if (ngx_strncmp(p, "group:", sizeof("group:") - 1) == 0) { shift = 3; @@ -486,6 +488,8 @@ *access |= right << shift; } + *access |= user; + return NGX_CONF_OK; invalid: | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_file.h ^ |
@@ -23,14 +23,14 @@ ngx_log_t *log; -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_int_t (*thread_handler)(ngx_thread_task_t *task, ngx_file_t *file); void *thread_ctx; ngx_thread_task_t *thread_task; #endif -#if (NGX_HAVE_FILE_AIO) +#if (NGX_HAVE_FILE_AIO || NGX_COMPAT) ngx_event_aio_t *aio; #endif @@ -42,7 +42,8 @@ #define NGX_MAX_PATH_LEVEL 3 -typedef time_t (*ngx_path_manager_pt) (void *data); +typedef ngx_msec_t (*ngx_path_manager_pt) (void *data); +typedef ngx_msec_t (*ngx_path_purger_pt) (void *data); typedef void (*ngx_path_loader_pt) (void *data); @@ -52,6 +53,7 @@ size_t level[NGX_MAX_PATH_LEVEL]; ngx_path_manager_pt manager; + ngx_path_purger_pt purger; ngx_path_loader_pt loader; void *data; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_inet.c ^ |
@@ -1364,6 +1364,7 @@ struct sockaddr_in6 *sin61, *sin62; #endif #if (NGX_HAVE_UNIX_DOMAIN) + size_t len; struct sockaddr_un *saun1, *saun2; #endif @@ -1393,15 +1394,21 @@ #if (NGX_HAVE_UNIX_DOMAIN) case AF_UNIX: - /* TODO length */ - saun1 = (struct sockaddr_un *) sa1; saun2 = (struct sockaddr_un *) sa2; - if (ngx_memcmp(&saun1->sun_path, &saun2->sun_path, - sizeof(saun1->sun_path)) - != 0) - { + if (slen1 < slen2) { + len = slen1 - offsetof(struct sockaddr_un, sun_path); + + } else { + len = slen2 - offsetof(struct sockaddr_un, sun_path); + } + + if (len > sizeof(saun1->sun_path)) { + len = sizeof(saun1->sun_path); + } + + if (ngx_memcmp(&saun1->sun_path, &saun2->sun_path, len) != 0) { return NGX_DECLINED; } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_module.h ^ |
@@ -35,13 +35,13 @@ #define NGX_MODULE_SIGNATURE_2 "0" #endif -#if (NGX_HAVE_FILE_AIO) +#if (NGX_HAVE_FILE_AIO || NGX_COMPAT) #define NGX_MODULE_SIGNATURE_3 "1" #else #define NGX_MODULE_SIGNATURE_3 "0" #endif -#if (NGX_HAVE_AIO_SENDFILE) +#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) #define NGX_MODULE_SIGNATURE_4 "1" #else #define NGX_MODULE_SIGNATURE_4 "0" @@ -71,17 +71,8 @@ #define NGX_MODULE_SIGNATURE_8 "0" #endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) #define NGX_MODULE_SIGNATURE_9 "1" -#else -#define NGX_MODULE_SIGNATURE_9 "0" -#endif - -#if (NGX_HAVE_REUSEPORT) #define NGX_MODULE_SIGNATURE_10 "1" -#else -#define NGX_MODULE_SIGNATURE_10 "0" -#endif #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) #define NGX_MODULE_SIGNATURE_11 "1" @@ -89,11 +80,7 @@ #define NGX_MODULE_SIGNATURE_11 "0" #endif -#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) #define NGX_MODULE_SIGNATURE_12 "1" -#else -#define NGX_MODULE_SIGNATURE_12 "0" -#endif #if (NGX_HAVE_SETFIB) #define NGX_MODULE_SIGNATURE_13 "1" @@ -140,7 +127,7 @@ #define NGX_MODULE_SIGNATURE_21 "0" #endif -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) #define NGX_MODULE_SIGNATURE_22 "1" #else #define NGX_MODULE_SIGNATURE_22 "0" @@ -152,17 +139,13 @@ #define NGX_MODULE_SIGNATURE_23 "0" #endif -#if (NGX_HTTP_SSL) +#if (NGX_HTTP_SSL || NGX_COMPAT) #define NGX_MODULE_SIGNATURE_24 "1" #else #define NGX_MODULE_SIGNATURE_24 "0" #endif -#if (NGX_HTTP_V2) #define NGX_MODULE_SIGNATURE_25 "1" -#else -#define NGX_MODULE_SIGNATURE_25 "0" -#endif #if (NGX_HTTP_GZIP) #define NGX_MODULE_SIGNATURE_26 "1" @@ -170,11 +153,7 @@ #define NGX_MODULE_SIGNATURE_26 "0" #endif -#if (NGX_HTTP_DEGRADATION) #define NGX_MODULE_SIGNATURE_27 "1" -#else -#define NGX_MODULE_SIGNATURE_27 "0" -#endif #if (NGX_HTTP_X_FORWARDED_FOR) #define NGX_MODULE_SIGNATURE_28 "1" @@ -212,6 +191,12 @@ #define NGX_MODULE_SIGNATURE_33 "0" #endif +#if (NGX_COMPAT) +#define NGX_MODULE_SIGNATURE_34 "1" +#else +#define NGX_MODULE_SIGNATURE_34 "0" +#endif + #define NGX_MODULE_SIGNATURE \ NGX_MODULE_SIGNATURE_0 NGX_MODULE_SIGNATURE_1 NGX_MODULE_SIGNATURE_2 \ NGX_MODULE_SIGNATURE_3 NGX_MODULE_SIGNATURE_4 NGX_MODULE_SIGNATURE_5 \ @@ -224,7 +209,7 @@ NGX_MODULE_SIGNATURE_24 NGX_MODULE_SIGNATURE_25 NGX_MODULE_SIGNATURE_26 \ NGX_MODULE_SIGNATURE_27 NGX_MODULE_SIGNATURE_28 NGX_MODULE_SIGNATURE_29 \ NGX_MODULE_SIGNATURE_30 NGX_MODULE_SIGNATURE_31 NGX_MODULE_SIGNATURE_32 \ - NGX_MODULE_SIGNATURE_33 + NGX_MODULE_SIGNATURE_33 NGX_MODULE_SIGNATURE_34 #define NGX_MODULE_V1 \ | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_resolver.c ^ |
@@ -3006,6 +3006,7 @@ ctx->count--; srv->ctx = NULL; + srv->state = cctx->state; if (cctx->naddrs) { | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/core/ngx_resolver.h ^ |
@@ -82,6 +82,7 @@ u_short port; ngx_resolver_ctx_t *ctx; + ngx_int_t state; ngx_uint_t naddrs; ngx_addr_t *addrs; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/event/ngx_event.h ^ |
@@ -152,7 +152,7 @@ ngx_event_handler_pt handler; ngx_file_t *file; -#if (NGX_HAVE_AIO_SENDFILE) +#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) ssize_t (*preload_handler)(ngx_buf_t *file); #endif @@ -430,6 +430,7 @@ #define ngx_send ngx_io.send #define ngx_send_chain ngx_io.send_chain #define ngx_udp_send ngx_io.udp_send +#define ngx_udp_send_chain ngx_io.udp_send_chain #define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */ | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/event/ngx_event_accept.c ^ |
@@ -467,6 +467,7 @@ *log = ls->log; c->send = ngx_udp_send; + c->send_chain = ngx_udp_send_chain; c->log = log; c->pool->log = log; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/event/ngx_event_connect.c ^ |
@@ -166,6 +166,7 @@ } else { /* type == SOCK_DGRAM */ c->recv = ngx_udp_recv; c->send = ngx_send; + c->send_chain = ngx_udp_send_chain; } c->log_error = pc->log_error; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/event/ngx_event_connect.h ^ |
@@ -25,13 +25,12 @@ void *data); typedef void (*ngx_event_free_peer_pt)(ngx_peer_connection_t *pc, void *data, ngx_uint_t state); -#if (NGX_SSL) - +typedef void (*ngx_event_notify_peer_pt)(ngx_peer_connection_t *pc, + void *data, ngx_uint_t type); typedef ngx_int_t (*ngx_event_set_peer_session_pt)(ngx_peer_connection_t *pc, void *data); typedef void (*ngx_event_save_peer_session_pt)(ngx_peer_connection_t *pc, void *data); -#endif struct ngx_peer_connection_s { @@ -46,9 +45,10 @@ ngx_event_get_peer_pt get; ngx_event_free_peer_pt free; + ngx_event_notify_peer_pt notify; void *data; -#if (NGX_SSL) +#if (NGX_SSL || NGX_COMPAT) ngx_event_set_peer_session_pt set_session; ngx_event_save_peer_session_pt save_session; #endif @@ -61,12 +61,13 @@ ngx_log_t *log; unsigned cached:1; -#if (NGX_HAVE_TRANSPARENT_PROXY) unsigned transparent:1; -#endif /* ngx_connection_log_error_e */ unsigned log_error:2; + + NGX_COMPAT_BEGIN(2) + NGX_COMPAT_END }; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/event/ngx_event_openssl.c ^ |
@@ -55,7 +55,7 @@ HMAC_CTX *hctx, int enc); #endif -#if OPENSSL_VERSION_NUMBER < 0x10002002L +#ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str); #endif @@ -3092,7 +3092,7 @@ return NGX_ERROR; } -#if OPENSSL_VERSION_NUMBER >= 0x10002002L +#ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT /* X509_check_host() is only available in OpenSSL 1.0.2+ */ @@ -3209,7 +3209,7 @@ } -#if OPENSSL_VERSION_NUMBER < 0x10002002L +#ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern) @@ -3656,13 +3656,13 @@ engine = ENGINE_by_id((char *) value[1].data); if (engine == NULL) { - ngx_ssl_error(NGX_LOG_WARN, cf->log, 0, + ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, "ENGINE_by_id(\"%V\") failed", &value[1]); return NGX_CONF_ERROR; } if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) { - ngx_ssl_error(NGX_LOG_WARN, cf->log, 0, + ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, "ENGINE_set_default(\"%V\", ENGINE_METHOD_ALL) failed", &value[1]); | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/event/ngx_event_openssl.h ^ |
@@ -54,14 +54,14 @@ #define ngx_ssl_conn_t SSL -typedef struct { +struct ngx_ssl_s { SSL_CTX *ctx; ngx_log_t *log; size_t buffer_size; -} ngx_ssl_t; +}; -typedef struct { +struct ngx_ssl_connection_s { ngx_ssl_conn_t *connection; SSL_CTX *session_ctx; @@ -80,7 +80,7 @@ unsigned no_wait_shutdown:1; unsigned no_send_shutdown:1; unsigned handshake_buffer_set:1; -} ngx_ssl_connection_t; +}; #define NGX_SSL_NO_SCACHE -2 | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/event/ngx_event_pipe.h ^ |
@@ -47,7 +47,7 @@ ngx_event_pipe_output_filter_pt output_filter; void *output_ctx; -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_int_t (*thread_handler)(ngx_thread_task_t *task, ngx_file_t *file); void *thread_ctx; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/modules/ngx_http_addition_filter_module.c ^ |
@@ -171,6 +171,7 @@ for (cl = in; cl; cl = cl->next) { if (cl->buf->last_buf) { cl->buf->last_buf = 0; + cl->buf->last_in_chain = 1; cl->buf->sync = 1; last = 1; } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/modules/ngx_http_mp4_module.c ^ |
@@ -1144,7 +1144,7 @@ data = &mp4->mdat_data_buf; data->file = &mp4->file; data->in_file = 1; - data->last_buf = 1; + data->last_buf = (mp4->request == mp4->request->main) ? 1 : 0; data->last_in_chain = 1; data->file_last = mp4->offset + atom_data_size; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/modules/ngx_http_range_filter_module.c ^ |
@@ -750,7 +750,8 @@ buf->last -= (size_t) (last - range->end); } - buf->last_buf = 1; + buf->last_buf = (r == r->main) ? 1 : 0; + buf->last_in_chain = 1; *ll = cl; cl->next = NULL; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/modules/ngx_http_realip_module.c ^ |
@@ -141,15 +141,15 @@ ngx_http_realip_ctx_t *ctx; ngx_http_realip_loc_conf_t *rlcf; - ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); + rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); - if (ctx) { + if (rlcf->from == NULL) { return NGX_DECLINED; } - rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); + ctx = ngx_http_realip_get_module_ctx(r); - if (rlcf->from == NULL) { + if (ctx) { return NGX_DECLINED; } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/modules/ngx_http_upstream_hash_module.c ^ |
@@ -242,6 +242,10 @@ goto next; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + goto next; + } + break; next: @@ -523,7 +527,6 @@ peer; peer = peer->next, i++) { - n = i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); @@ -549,6 +552,10 @@ continue; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + continue; + } + peer->current_weight += peer->effective_weight; total += peer->effective_weight; @@ -571,6 +578,7 @@ hp->tries++; if (hp->tries >= points->number) { + pc->name = hp->rrp.peers->name; ngx_http_upstream_rr_peers_unlock(hp->rrp.peers); return NGX_BUSY; } @@ -647,6 +655,7 @@ uscf->flags = NGX_HTTP_UPSTREAM_CREATE |NGX_HTTP_UPSTREAM_WEIGHT + |NGX_HTTP_UPSTREAM_MAX_CONNS |NGX_HTTP_UPSTREAM_MAX_FAILS |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT |NGX_HTTP_UPSTREAM_DOWN; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/modules/ngx_http_upstream_ip_hash_module.c ^ |
@@ -212,6 +212,10 @@ goto next; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + goto next; + } + break; next: @@ -259,6 +263,7 @@ uscf->flags = NGX_HTTP_UPSTREAM_CREATE |NGX_HTTP_UPSTREAM_WEIGHT + |NGX_HTTP_UPSTREAM_MAX_CONNS |NGX_HTTP_UPSTREAM_MAX_FAILS |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT |NGX_HTTP_UPSTREAM_DOWN; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/modules/ngx_http_upstream_least_conn_module.c ^ |
@@ -136,7 +136,6 @@ peer; peer = peer->next, i++) { - n = i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); @@ -155,6 +154,10 @@ continue; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + continue; + } + /* * select peer with least number of connections; if there are * multiple peers with the same number of connections, select @@ -210,6 +213,10 @@ continue; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + continue; + } + peer->current_weight += peer->effective_weight; total += peer->effective_weight; @@ -273,12 +280,6 @@ ngx_http_upstream_rr_peers_wlock(peers); } - /* all peers failed, mark them as live for quick recovery */ - - for (peer = peers->peer; peer; peer = peer->next) { - peer->fails = 0; - } - ngx_http_upstream_rr_peers_unlock(peers); pc->name = peers->name; @@ -303,6 +304,7 @@ uscf->flags = NGX_HTTP_UPSTREAM_CREATE |NGX_HTTP_UPSTREAM_WEIGHT + |NGX_HTTP_UPSTREAM_MAX_CONNS |NGX_HTTP_UPSTREAM_MAX_FAILS |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT |NGX_HTTP_UPSTREAM_DOWN | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/modules/perl/Makefile.PL ^ |
@@ -16,6 +16,8 @@ CCFLAGS => "$ENV{NGX_PM_CFLAGS}", OPTIMIZE => '-O', + LDDLFLAGS => "$ENV{NGX_PM_LDFLAGS}", + INC => join(" ", map { m#^/# ? "-I $_" : "-I ../../../../../$_" } (split /\s+/, $ENV{NGX_INCS})), | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http.c ^ |
@@ -1756,7 +1756,7 @@ ls->deferred_accept = addr->opt.deferred_accept; #endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) ls->ipv6only = addr->opt.ipv6only; #endif | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http.h ^ |
@@ -19,10 +19,7 @@ typedef struct ngx_http_file_cache_s ngx_http_file_cache_t; typedef struct ngx_http_log_ctx_s ngx_http_log_ctx_t; typedef struct ngx_http_chunked_s ngx_http_chunked_t; - -#if (NGX_HTTP_V2) typedef struct ngx_http_v2_stream_s ngx_http_v2_stream_t; -#endif typedef ngx_int_t (*ngx_http_header_handler_pt)(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http_cache.h ^ |
@@ -50,7 +50,8 @@ unsigned exists:1; unsigned updating:1; unsigned deleting:1; - /* 11 unused bits */ + unsigned purged:1; + /* 10 unused bits */ ngx_file_uniq_t uniq; time_t expire; @@ -85,13 +86,14 @@ ngx_uint_t min_uses; ngx_uint_t error; ngx_uint_t valid_msec; + ngx_uint_t vary_tag; ngx_buf_t *buf; ngx_http_file_cache_t *file_cache; ngx_http_file_cache_node_t *node; -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_thread_task_t *thread_task; #endif @@ -109,6 +111,7 @@ unsigned updating:1; unsigned exists:1; unsigned temp_file:1; + unsigned purged:1; unsigned reading:1; unsigned secondary:1; }; @@ -163,6 +166,10 @@ ngx_msec_t loader_sleep; ngx_msec_t loader_threshold; + ngx_uint_t manager_files; + ngx_msec_t manager_sleep; + ngx_msec_t manager_threshold; + ngx_shm_zone_t *shm_zone; }; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http_core_module.c ^ |
@@ -3760,10 +3760,8 @@ ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0); ngx_conf_merge_size_value(conf->sendfile_max_chunk, prev->sendfile_max_chunk, 0); -#if (NGX_HAVE_FILE_AIO || NGX_THREADS) ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF); ngx_conf_merge_value(conf->aio_write, prev->aio_write, 0); -#endif #if (NGX_THREADS) ngx_conf_merge_ptr_value(conf->thread_pool, prev->thread_pool, NULL); ngx_conf_merge_ptr_value(conf->thread_pool_value, prev->thread_pool_value, @@ -3939,7 +3937,7 @@ lsopt.fastopen = -1; #endif lsopt.wildcard = u.wildcard; -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) lsopt.ipv6only = 1; #endif | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http_core_module.h ^ |
@@ -15,6 +15,8 @@ #if (NGX_THREADS) #include <ngx_thread_pool.h> +#elif (NGX_COMPAT) +typedef struct ngx_thread_pool_s ngx_thread_pool_t; #endif @@ -65,18 +67,13 @@ unsigned default_server:1; unsigned bind:1; unsigned wildcard:1; -#if (NGX_HTTP_SSL) unsigned ssl:1; -#endif -#if (NGX_HTTP_V2) unsigned http2:1; -#endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif -#if (NGX_HAVE_REUSEPORT) + unsigned deferred_accept:1; unsigned reuseport:1; -#endif unsigned so_keepalive:2; unsigned proxy_protocol:1; @@ -98,9 +95,6 @@ #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) char *accept_filter; #endif -#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) - ngx_uint_t deferred_accept; -#endif u_char addr[NGX_SOCKADDR_STRLEN + 1]; } ngx_http_listen_opt_t; @@ -234,12 +228,8 @@ ngx_http_virtual_names_t *virtual_names; -#if (NGX_HTTP_SSL) unsigned ssl:1; -#endif -#if (NGX_HTTP_V2) unsigned http2:1; -#endif unsigned proxy_protocol:1; }; @@ -327,10 +317,8 @@ unsigned auto_redirect:1; #if (NGX_HTTP_GZIP) unsigned gzip_disable_msie6:2; -#if (NGX_HTTP_DEGRADATION) unsigned gzip_disable_degradation:2; #endif -#endif ngx_http_location_tree_node_t *static_locations; #if (NGX_PCRE) @@ -419,7 +407,7 @@ #endif #endif -#if (NGX_THREADS) +#if (NGX_THREADS || NGX_COMPAT) ngx_thread_pool_t *thread_pool; ngx_http_complex_value_t *thread_pool_value; #endif | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http_file_cache.c ^ |
@@ -1759,6 +1759,7 @@ size_t len; time_t now, wait; ngx_path_t *path; + ngx_msec_t elapsed; ngx_queue_t *q; ngx_http_file_cache_node_t *fcn; u_char key[2 * NGX_HTTP_CACHE_KEY_LEN]; @@ -1810,7 +1811,7 @@ if (fcn->count == 0) { ngx_http_file_cache_delete(cache, q, name); - continue; + goto next; } if (fcn->deleting) { @@ -1836,6 +1837,22 @@ 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); + +next: + + if (++cache->files >= cache->manager_files) { + wait = 0; + break; + } + + ngx_time_update(); + + elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last)); + + if (elapsed >= cache->manager_threshold) { + wait = 0; + break; + } } ngx_shmtx_unlock(&cache->shpool->mutex); @@ -1897,20 +1914,25 @@ } -static time_t +static ngx_msec_t ngx_http_file_cache_manager(void *data) { ngx_http_file_cache_t *cache = data; off_t size; time_t next, wait; + ngx_msec_t elapsed; ngx_uint_t count, watermark; - next = ngx_http_file_cache_expire(cache); - cache->last = ngx_current_msec; cache->files = 0; + next = ngx_http_file_cache_expire(cache); + + if (next == 0) { + return cache->manager_sleep; + } + for ( ;; ) { ngx_shmtx_lock(&cache->shpool->mutex); @@ -1925,17 +1947,29 @@ size, count, (ngx_int_t) watermark); if (size < cache->max_size && count < watermark) { - return next; + return (ngx_msec_t) next * 1000; } wait = ngx_http_file_cache_forced_expire(cache); if (wait > 0) { - return wait; + return (ngx_msec_t) wait * 1000; } if (ngx_quit || ngx_terminate) { - return next; + return (ngx_msec_t) next * 1000; + } + + if (++cache->files >= cache->manager_files) { + return cache->manager_sleep; + } + + ngx_time_update(); + + elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last)); + + if (elapsed >= cache->manager_threshold) { + return cache->manager_sleep; } } } @@ -2211,8 +2245,9 @@ size_t len; ssize_t size; ngx_str_t s, name, *value; - ngx_int_t loader_files; - ngx_msec_t loader_sleep, loader_threshold; + ngx_int_t loader_files, manager_files; + ngx_msec_t loader_sleep, manager_sleep, loader_threshold, + manager_threshold; ngx_uint_t i, n, use_temp_path; ngx_array_t *caches; ngx_http_file_cache_t *cache, **ce; @@ -2230,10 +2265,15 @@ use_temp_path = 1; inactive = 600; + loader_files = 100; loader_sleep = 50; loader_threshold = 200; + manager_files = 100; + manager_sleep = 50; + manager_threshold = 200; + name.len = 0; size = 0; max_size = NGX_MAX_OFF_T_VALUE; @@ -2405,6 +2445,48 @@ continue; } + if (ngx_strncmp(value[i].data, "manager_files=", 14) == 0) { + + manager_files = ngx_atoi(value[i].data + 14, value[i].len - 14); + if (manager_files == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid manager_files value \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + + if (ngx_strncmp(value[i].data, "manager_sleep=", 14) == 0) { + + s.len = value[i].len - 14; + s.data = value[i].data + 14; + + manager_sleep = ngx_parse_time(&s, 0); + if (manager_sleep == (ngx_msec_t) NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid manager_sleep value \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + + if (ngx_strncmp(value[i].data, "manager_threshold=", 18) == 0) { + + s.len = value[i].len - 18; + s.data = value[i].data + 18; + + manager_threshold = ngx_parse_time(&s, 0); + if (manager_threshold == (ngx_msec_t) NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid manager_threshold value \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; @@ -2425,6 +2507,9 @@ cache->loader_files = loader_files; cache->loader_sleep = loader_sleep; cache->loader_threshold = loader_threshold; + cache->manager_files = manager_files; + cache->manager_sleep = manager_sleep; + cache->manager_threshold = manager_threshold; if (ngx_add_path(cf, &cache->path) != NGX_OK) { return NGX_CONF_ERROR; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http_parse.c ^ |
@@ -149,7 +149,7 @@ break; } - if ((ch < 'A' || ch > 'Z') && ch != '_') { + if ((ch < 'A' || ch > 'Z') && ch != '_' && ch != '-') { return NGX_HTTP_PARSE_INVALID_METHOD; } @@ -270,7 +270,7 @@ break; } - if ((ch < 'A' || ch > 'Z') && ch != '_') { + if ((ch < 'A' || ch > 'Z') && ch != '_' && ch != '-') { return NGX_HTTP_PARSE_INVALID_METHOD; } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http_request.h ^ |
@@ -286,9 +286,7 @@ ngx_chain_t *bufs; ngx_buf_t *buf; off_t rest; -#if (NGX_HTTP_V2) off_t received; -#endif ngx_chain_t *free; ngx_chain_t *busy; ngx_http_chunked_t *chunked; @@ -302,7 +300,7 @@ ngx_http_addr_conf_t *addr_conf; ngx_http_conf_ctx_t *conf_ctx; -#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME) +#if (NGX_HTTP_SSL || NGX_COMPAT) ngx_str_t *ssl_servername; #if (NGX_PCRE) ngx_http_regex_t *ssl_servername_regex; @@ -315,9 +313,7 @@ ngx_buf_t **free; ngx_int_t nfree; -#if (NGX_HTTP_SSL) unsigned ssl:1; -#endif unsigned proxy_protocol:1; } ngx_http_connection_t; @@ -438,9 +434,7 @@ ngx_uint_t err_status; ngx_http_connection_t *http_connection; -#if (NGX_HTTP_V2) ngx_http_v2_stream_t *stream; -#endif ngx_http_log_handler_pt log_handler; @@ -539,11 +533,11 @@ unsigned subrequest_ranges:1; unsigned single_range:1; unsigned disable_not_modified:1; - -#if (NGX_STAT_STUB) unsigned stat_reading:1; unsigned stat_writing:1; -#endif + unsigned stat_processing:1; + + unsigned health_check:1; /* used to parse HTTP headers */ | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http_special_response.c ^ |
@@ -792,7 +792,7 @@ b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail, sizeof(ngx_http_msie_refresh_tail) - 1); - b->last_buf = 1; + b->last_buf = (r == r->main) ? 1 : 0; b->last_in_chain = 1; out.buf = b; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http_upstream.c ^ |
@@ -748,6 +748,8 @@ return; } + u->upstream = uscf; + #if (NGX_HTTP_SSL) u->ssl_name = uscf->host; #endif @@ -5442,6 +5444,7 @@ uscf = ngx_http_upstream_add(cf, &u, NGX_HTTP_UPSTREAM_CREATE |NGX_HTTP_UPSTREAM_WEIGHT + |NGX_HTTP_UPSTREAM_MAX_CONNS |NGX_HTTP_UPSTREAM_MAX_FAILS |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT |NGX_HTTP_UPSTREAM_DOWN @@ -5543,7 +5546,7 @@ time_t fail_timeout; ngx_str_t *value, s; ngx_url_t u; - ngx_int_t weight, max_fails; + ngx_int_t weight, max_conns, max_fails; ngx_uint_t i; ngx_http_upstream_server_t *us; @@ -5557,6 +5560,7 @@ value = cf->args->elts; weight = 1; + max_conns = 0; max_fails = 1; fail_timeout = 10; @@ -5577,6 +5581,21 @@ continue; } + if (ngx_strncmp(value[i].data, "max_conns=", 10) == 0) { + + if (!(uscf->flags & NGX_HTTP_UPSTREAM_MAX_CONNS)) { + goto not_supported; + } + + max_conns = ngx_atoi(&value[i].data[10], value[i].len - 10); + + if (max_conns == NGX_ERROR) { + goto invalid; + } + + continue; + } + if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) { if (!(uscf->flags & NGX_HTTP_UPSTREAM_MAX_FAILS)) { @@ -5653,6 +5672,7 @@ us->addrs = u.addrs; us->naddrs = u.naddrs; us->weight = weight; + us->max_conns = max_conns; us->max_fails = max_fails; us->fail_timeout = fail_timeout; @@ -5717,14 +5737,14 @@ } if ((uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE) && !u->no_port) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "upstream \"%V\" may not have port %d", &u->host, u->port); return NULL; } if ((flags & NGX_HTTP_UPSTREAM_CREATE) && !uscfp[i]->no_port) { - ngx_log_error(NGX_LOG_WARN, cf->log, 0, + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "upstream \"%V\" may not have port %d in %s:%ui", &u->host, uscfp[i]->port, uscfp[i]->file_name, uscfp[i]->line); | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http_upstream.h ^ |
@@ -95,11 +95,16 @@ ngx_addr_t *addrs; ngx_uint_t naddrs; ngx_uint_t weight; + ngx_uint_t max_conns; ngx_uint_t max_fails; time_t fail_timeout; + ngx_msec_t slow_start; unsigned down:1; unsigned backup:1; + + NGX_COMPAT_BEGIN(6) + NGX_COMPAT_END } ngx_http_upstream_server_t; @@ -109,6 +114,7 @@ #define NGX_HTTP_UPSTREAM_FAIL_TIMEOUT 0x0008 #define NGX_HTTP_UPSTREAM_DOWN 0x0010 #define NGX_HTTP_UPSTREAM_BACKUP 0x0020 +#define NGX_HTTP_UPSTREAM_MAX_CONNS 0x0100 struct ngx_http_upstream_srv_conf_s { @@ -202,6 +208,7 @@ ngx_array_t *cache_valid; ngx_array_t *cache_bypass; + ngx_array_t *cache_purge; ngx_array_t *no_cache; #endif @@ -215,7 +222,7 @@ unsigned intercept_404:1; unsigned change_buffering:1; -#if (NGX_HTTP_SSL) +#if (NGX_HTTP_SSL || NGX_COMPAT) ngx_ssl_t *ssl; ngx_flag_t ssl_session_reuse; @@ -225,6 +232,9 @@ #endif ngx_str_t module; + + NGX_COMPAT_BEGIN(2) + NGX_COMPAT_END } ngx_http_upstream_conf_t; @@ -313,6 +323,7 @@ ngx_chain_writer_ctx_t writer; ngx_http_upstream_conf_t *conf; + ngx_http_upstream_srv_conf_t *upstream; #if (NGX_HTTP_CACHE) ngx_array_t *caches; #endif @@ -356,7 +367,7 @@ ngx_str_t schema; ngx_str_t uri; -#if (NGX_HTTP_SSL) +#if (NGX_HTTP_SSL || NGX_COMPAT) ngx_str_t ssl_name; #endif @@ -377,6 +388,9 @@ unsigned request_sent:1; unsigned request_body_sent:1; unsigned header_sent:1; + + NGX_COMPAT_BEGIN(1) + NGX_COMPAT_END }; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http_upstream_round_robin.c ^ |
@@ -92,6 +92,7 @@ peer[n].weight = server[i].weight; peer[n].effective_weight = server[i].weight; peer[n].current_weight = 0; + peer[n].max_conns = server[i].max_conns; peer[n].max_fails = server[i].max_fails; peer[n].fail_timeout = server[i].fail_timeout; peer[n].down = server[i].down; @@ -155,6 +156,7 @@ peer[n].weight = server[i].weight; peer[n].effective_weight = server[i].weight; peer[n].current_weight = 0; + peer[n].max_conns = server[i].max_conns; peer[n].max_fails = server[i].max_fails; peer[n].fail_timeout = server[i].fail_timeout; peer[n].down = server[i].down; @@ -223,6 +225,7 @@ peer[i].weight = 1; peer[i].effective_weight = 1; peer[i].current_weight = 0; + peer[i].max_conns = 0; peer[i].max_fails = 1; peer[i].fail_timeout = 10; *peerp = &peer[i]; @@ -257,6 +260,7 @@ rrp->peers = us->peer.data; rrp->current = NULL; + rrp->config = 0; n = rrp->peers->number; @@ -337,6 +341,7 @@ peer[0].weight = 1; peer[0].effective_weight = 1; peer[0].current_weight = 0; + peer[0].max_conns = 0; peer[0].max_fails = 1; peer[0].fail_timeout = 10; peers->peer = peer; @@ -370,6 +375,7 @@ peer[i].weight = 1; peer[i].effective_weight = 1; peer[i].current_weight = 0; + peer[i].max_conns = 0; peer[i].max_fails = 1; peer[i].fail_timeout = 10; *peerp = &peer[i]; @@ -379,6 +385,7 @@ rrp->peers = peers; rrp->current = NULL; + rrp->config = 0; if (rrp->peers->number <= 8 * sizeof(uintptr_t)) { rrp->tried = &rrp->data; @@ -432,6 +439,10 @@ goto failed; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + goto failed; + } + rrp->current = peer; } else { @@ -485,12 +496,6 @@ ngx_http_upstream_rr_peers_wlock(peers); } - /* all peers failed, mark them as live for quick recovery */ - - for (peer = peers->peer; peer; peer = peer->next) { - peer->fails = 0; - } - ngx_http_upstream_rr_peers_unlock(peers); pc->name = peers->name; @@ -521,7 +526,6 @@ peer; peer = peer->next, i++) { - n = i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); @@ -540,6 +544,10 @@ continue; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + continue; + } + peer->current_weight += peer->effective_weight; total += peer->effective_weight; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/ngx_http_upstream_round_robin.h ^ |
@@ -27,6 +27,7 @@ ngx_int_t weight; ngx_uint_t conns; + ngx_uint_t max_conns; ngx_uint_t fails; time_t accessed; @@ -34,19 +35,24 @@ ngx_uint_t max_fails; time_t fail_timeout; + ngx_msec_t slow_start; + ngx_msec_t start_time; - ngx_uint_t down; /* unsigned down:1; */ + ngx_uint_t down; -#if (NGX_HTTP_SSL) +#if (NGX_HTTP_SSL || NGX_COMPAT) void *ssl_session; int ssl_session_len; #endif - ngx_http_upstream_rr_peer_t *next; - #if (NGX_HTTP_UPSTREAM_ZONE) ngx_atomic_t lock; #endif + + ngx_http_upstream_rr_peer_t *next; + + NGX_COMPAT_BEGIN(32) + NGX_COMPAT_END }; @@ -119,6 +125,7 @@ typedef struct { + ngx_uint_t config; ngx_http_upstream_rr_peers_t *peers; ngx_http_upstream_rr_peer_t *current; uintptr_t *tried; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/http/v2/ngx_http_v2.c ^ |
@@ -3178,7 +3178,7 @@ p = r->method_name.data; do { - if ((*p < 'A' || *p > 'Z') && *p != '_') { + if ((*p < 'A' || *p > 'Z') && *p != '_' && *p != '-') { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent invalid method: \"%V\"", &r->method_name); | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/mail/ngx_mail.c ^ |
@@ -341,7 +341,7 @@ ls->keepcnt = addr[i].opt.tcp_keepcnt; #endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) ls->ipv6only = addr[i].opt.ipv6only; #endif | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/mail/ngx_mail.h ^ |
@@ -35,10 +35,8 @@ unsigned bind:1; unsigned wildcard:1; -#if (NGX_MAIL_SSL) unsigned ssl:1; -#endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif unsigned so_keepalive:2; @@ -54,9 +52,7 @@ typedef struct { ngx_mail_conf_ctx_t *ctx; ngx_str_t addr_text; -#if (NGX_MAIL_SSL) ngx_uint_t ssl; /* unsigned ssl:1; */ -#endif } ngx_mail_addr_conf_t; typedef struct { | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/mail/ngx_mail_core_module.c ^ |
@@ -353,7 +353,7 @@ ls->wildcard = u.wildcard; ls->ctx = cf->ctx; -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) ls->ipv6only = 1; #endif | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/mail/ngx_mail_ssl_module.c ^ |
@@ -488,7 +488,7 @@ } if (scf->enable && (ngx_int_t) scf->starttls > NGX_MAIL_STARTTLS_OFF) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"starttls\" directive conflicts with \"ssl on\""); return NGX_CONF_ERROR; } @@ -514,7 +514,7 @@ } if (scf->enable == 1 && (ngx_int_t) scf->starttls > NGX_MAIL_STARTTLS_OFF) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"ssl\" directive conflicts with \"starttls\""); return NGX_CONF_ERROR; } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/os/unix/ngx_darwin_init.c ^ |
@@ -24,6 +24,7 @@ ngx_udp_unix_recv, ngx_unix_send, ngx_udp_unix_send, + ngx_udp_unix_sendmsg_chain, #if (NGX_HAVE_SENDFILE) ngx_darwin_sendfile_chain, NGX_IO_SENDFILE | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/os/unix/ngx_freebsd_init.c ^ |
@@ -33,6 +33,7 @@ ngx_udp_unix_recv, ngx_unix_send, ngx_udp_unix_send, + ngx_udp_unix_sendmsg_chain, #if (NGX_HAVE_SENDFILE) ngx_freebsd_sendfile_chain, NGX_IO_SENDFILE | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/os/unix/ngx_linux_init.c ^ |
@@ -19,6 +19,7 @@ ngx_udp_unix_recv, ngx_unix_send, ngx_udp_unix_send, + ngx_udp_unix_sendmsg_chain, #if (NGX_HAVE_SENDFILE) ngx_linux_sendfile_chain, NGX_IO_SENDFILE | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/os/unix/ngx_os.h ^ |
@@ -29,6 +29,7 @@ ngx_recv_pt udp_recv; ngx_send_pt send; ngx_send_pt udp_send; + ngx_send_chain_pt udp_send_chain; ngx_send_chain_pt send_chain; ngx_uint_t flags; } ngx_os_io_t; @@ -49,6 +50,8 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); ssize_t ngx_udp_unix_send(ngx_connection_t *c, u_char *buf, size_t size); +ngx_chain_t *ngx_udp_unix_sendmsg_chain(ngx_connection_t *c, ngx_chain_t *in, + off_t limit); #if (IOV_MAX > 64) | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/os/unix/ngx_posix_init.c ^ |
@@ -25,6 +25,7 @@ ngx_udp_unix_recv, ngx_unix_send, ngx_udp_unix_send, + ngx_udp_unix_sendmsg_chain, ngx_writev_chain, 0 }; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/os/unix/ngx_process_cycle.c ^ |
@@ -1148,11 +1148,11 @@ static void ngx_cache_manager_process_handler(ngx_event_t *ev) { - time_t next, n; ngx_uint_t i; + ngx_msec_t next, n; ngx_path_t **path; - next = 60 * 60; + next = 60 * 60 * 1000; path = ngx_cycle->paths.elts; for (i = 0; i < ngx_cycle->paths.nelts; i++) { @@ -1170,7 +1170,7 @@ next = 1; } - ngx_add_timer(ev, next * 1000); + ngx_add_timer(ev, next); } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/os/unix/ngx_solaris_init.c ^ |
@@ -20,6 +20,7 @@ ngx_udp_unix_recv, ngx_unix_send, ngx_udp_unix_send, + ngx_udp_unix_sendmsg_chain, #if (NGX_HAVE_SENDFILE) ngx_solaris_sendfilev_chain, NGX_IO_SENDFILE | ||
[+] | Added | _service:download_url:nginx-1.11.5.tar.gz/src/os/unix/ngx_udp_sendmsg_chain.c ^ |
@@ -0,0 +1,245 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Nginx, Inc. + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_event.h> + + +static ngx_chain_t *ngx_udp_output_chain_to_iovec(ngx_iovec_t *vec, + ngx_chain_t *in, ngx_log_t *log); +static ssize_t ngx_sendmsg(ngx_connection_t *c, ngx_iovec_t *vec); + + +ngx_chain_t * +ngx_udp_unix_sendmsg_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) +{ + ssize_t n; + off_t send; + ngx_chain_t *cl; + ngx_event_t *wev; + ngx_iovec_t vec; + struct iovec iovs[NGX_IOVS_PREALLOCATE]; + + wev = c->write; + + if (!wev->ready) { + return in; + } + +#if (NGX_HAVE_KQUEUE) + + if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) && wev->pending_eof) { + (void) ngx_connection_error(c, wev->kq_errno, + "kevent() reported about an closed connection"); + wev->error = 1; + return NGX_CHAIN_ERROR; + } + +#endif + + /* the maximum limit size is the maximum size_t value - the page size */ + + if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) { + limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize; + } + + send = 0; + + vec.iovs = iovs; + vec.nalloc = NGX_IOVS_PREALLOCATE; + + for ( ;; ) { + + /* create the iovec and coalesce the neighbouring bufs */ + + cl = ngx_udp_output_chain_to_iovec(&vec, in, c->log); + + if (cl == NGX_CHAIN_ERROR) { + return NGX_CHAIN_ERROR; + } + + if (cl && cl->buf->in_file) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "file buf in sendmsg " + "t:%d r:%d f:%d %p %p-%p %p %O-%O", + cl->buf->temporary, + cl->buf->recycled, + cl->buf->in_file, + cl->buf->start, + cl->buf->pos, + cl->buf->last, + cl->buf->file, + cl->buf->file_pos, + cl->buf->file_last); + + ngx_debug_point(); + + return NGX_CHAIN_ERROR; + } + + if (cl == in) { + return in; + } + + send += vec.size; + + n = ngx_sendmsg(c, &vec); + + if (n == NGX_ERROR) { + return NGX_CHAIN_ERROR; + } + + if (n == NGX_AGAIN) { + wev->ready = 0; + return in; + } + + c->sent += n; + + in = ngx_chain_update_sent(in, n); + + if (send >= limit || in == NULL) { + return in; + } + } +} + + +static ngx_chain_t * +ngx_udp_output_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *in, ngx_log_t *log) +{ + size_t total, size; + u_char *prev; + ngx_uint_t n, flush; + ngx_chain_t *cl; + struct iovec *iov; + + cl = in; + iov = NULL; + prev = NULL; + total = 0; + n = 0; + flush = 0; + + for ( /* void */ ; in && !flush; in = in->next) { + + if (in->buf->flush || in->buf->last_buf) { + flush = 1; + } + + if (ngx_buf_special(in->buf)) { + continue; + } + + if (in->buf->in_file) { + break; + } + + if (!ngx_buf_in_memory(in->buf)) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "bad buf in output chain " + "t:%d r:%d f:%d %p %p-%p %p %O-%O", + in->buf->temporary, + in->buf->recycled, + in->buf->in_file, + in->buf->start, + in->buf->pos, + in->buf->last, + in->buf->file, + in->buf->file_pos, + in->buf->file_last); + + ngx_debug_point(); + + return NGX_CHAIN_ERROR; + } + + size = in->buf->last - in->buf->pos; + + if (prev == in->buf->pos) { + iov->iov_len += size; + + } else { + if (n == vec->nalloc) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "too many parts in a datagram"); + return NGX_CHAIN_ERROR; + } + + iov = &vec->iovs[n++]; + + iov->iov_base = (void *) in->buf->pos; + iov->iov_len = size; + } + + prev = in->buf->pos + size; + total += size; + } + + if (!flush) { +#if (NGX_SUPPRESS_WARN) + vec->size = 0; + vec->count = 0; +#endif + return cl; + } + + vec->count = n; + vec->size = total; + + return in; +} + + +static ssize_t +ngx_sendmsg(ngx_connection_t *c, ngx_iovec_t *vec) +{ + ssize_t n; + ngx_err_t err; + struct msghdr msg; + + ngx_memzero(&msg, sizeof(struct msghdr)); + + if (c->socklen) { + msg.msg_name = c->sockaddr; + msg.msg_namelen = c->socklen; + } + + msg.msg_iov = vec->iovs; + msg.msg_iovlen = vec->count; + +eintr: + + n = sendmsg(c->fd, &msg, 0); + + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, + "sendmsg: %z of %uz", n, vec->size); + + if (n == -1) { + err = ngx_errno; + + switch (err) { + case NGX_EAGAIN: + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, + "sendmsg() not ready"); + return NGX_AGAIN; + + case NGX_EINTR: + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, + "sendmsg() was interrupted"); + goto eintr; + + default: + c->write->error = 1; + ngx_connection_error(c, err, "sendmsg() failed"); + return NGX_ERROR; + } + } + + return n; +} | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream.c ^ |
@@ -12,6 +12,10 @@ static char *ngx_stream_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static ngx_int_t ngx_stream_init_phases(ngx_conf_t *cf, + ngx_stream_core_main_conf_t *cmcf); +static ngx_int_t ngx_stream_init_phase_handlers(ngx_conf_t *cf, + ngx_stream_core_main_conf_t *cmcf); static ngx_int_t ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports, ngx_stream_listen_t *listen); static char *ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports); @@ -27,6 +31,9 @@ ngx_uint_t ngx_stream_max_module; +ngx_stream_filter_pt ngx_stream_top_filter; + + static ngx_command_t ngx_stream_commands[] = { { ngx_string("stream"), @@ -216,6 +223,10 @@ } } + if (ngx_stream_init_phases(cf, cmcf) != NGX_OK) { + return NGX_CONF_ERROR; + } + for (m = 0; cf->cycle->modules[m]; m++) { if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { continue; @@ -236,6 +247,9 @@ *cf = pcf; + if (ngx_stream_init_phase_handlers(cf, cmcf) != NGX_OK) { + return NGX_CONF_ERROR; + } if (ngx_array_init(&ports, cf->temp_pool, 4, sizeof(ngx_stream_conf_port_t)) != NGX_OK) @@ -256,6 +270,114 @@ static ngx_int_t +ngx_stream_init_phases(ngx_conf_t *cf, ngx_stream_core_main_conf_t *cmcf) +{ + if (ngx_array_init(&cmcf->phases[NGX_STREAM_POST_ACCEPT_PHASE].handlers, + cf->pool, 1, sizeof(ngx_stream_handler_pt)) + != NGX_OK) + { + return NGX_ERROR; + } + + if (ngx_array_init(&cmcf->phases[NGX_STREAM_PREACCESS_PHASE].handlers, + cf->pool, 1, sizeof(ngx_stream_handler_pt)) + != NGX_OK) + { + return NGX_ERROR; + } + + if (ngx_array_init(&cmcf->phases[NGX_STREAM_ACCESS_PHASE].handlers, + cf->pool, 1, sizeof(ngx_stream_handler_pt)) + != NGX_OK) + { + return NGX_ERROR; + } + + if (ngx_array_init(&cmcf->phases[NGX_STREAM_SSL_PHASE].handlers, + cf->pool, 1, sizeof(ngx_stream_handler_pt)) + != NGX_OK) + { + return NGX_ERROR; + } + + if (ngx_array_init(&cmcf->phases[NGX_STREAM_PREREAD_PHASE].handlers, + cf->pool, 1, sizeof(ngx_stream_handler_pt)) + != NGX_OK) + { + return NGX_ERROR; + } + + if (ngx_array_init(&cmcf->phases[NGX_STREAM_LOG_PHASE].handlers, + cf->pool, 1, sizeof(ngx_stream_handler_pt)) + != NGX_OK) + { + return NGX_ERROR; + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_stream_init_phase_handlers(ngx_conf_t *cf, + ngx_stream_core_main_conf_t *cmcf) +{ + ngx_int_t j; + ngx_uint_t i, n; + ngx_stream_handler_pt *h; + ngx_stream_phase_handler_t *ph; + ngx_stream_phase_handler_pt checker; + + n = 1 /* content phase */; + + for (i = 0; i < NGX_STREAM_LOG_PHASE; i++) { + n += cmcf->phases[i].handlers.nelts; + } + + ph = ngx_pcalloc(cf->pool, + n * sizeof(ngx_stream_phase_handler_t) + sizeof(void *)); + if (ph == NULL) { + return NGX_ERROR; + } + + cmcf->phase_engine.handlers = ph; + n = 0; + + for (i = 0; i < NGX_STREAM_LOG_PHASE; i++) { + h = cmcf->phases[i].handlers.elts; + + switch (i) { + + case NGX_STREAM_PREREAD_PHASE: + checker = ngx_stream_core_preread_phase; + break; + + case NGX_STREAM_CONTENT_PHASE: + ph->checker = ngx_stream_core_content_phase; + n++; + ph++; + + continue; + + default: + checker = ngx_stream_core_generic_phase; + } + + n += cmcf->phases[i].handlers.nelts; + + for (j = cmcf->phases[i].handlers.nelts - 1; j >= 0; j--) { + ph->checker = checker; + ph->handler = h[j]; + ph->next = n; + ph++; + } + } + + return NGX_OK; +} + + +static ngx_int_t ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports, ngx_stream_listen_t *listen) { @@ -382,7 +504,7 @@ ls->keepcnt = addr[i].opt.tcp_keepcnt; #endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) ls->ipv6only = addr[i].opt.ipv6only; #endif | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream.h ^ |
@@ -49,15 +49,11 @@ unsigned bind:1; unsigned wildcard:1; -#if (NGX_STREAM_SSL) unsigned ssl:1; -#endif -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) unsigned ipv6only:1; #endif -#if (NGX_HAVE_REUSEPORT) unsigned reuseport:1; -#endif unsigned so_keepalive:2; unsigned proxy_protocol:1; #if (NGX_HAVE_KEEPALIVE_TUNABLE) @@ -73,9 +69,7 @@ typedef struct { ngx_stream_conf_ctx_t *ctx; ngx_str_t addr_text; -#if (NGX_STREAM_SSL) unsigned ssl:1; -#endif unsigned proxy_protocol:1; } ngx_stream_addr_conf_t; @@ -115,17 +109,47 @@ } ngx_stream_conf_addr_t; -typedef ngx_int_t (*ngx_stream_access_pt)(ngx_stream_session_t *s); +typedef enum { + NGX_STREAM_POST_ACCEPT_PHASE = 0, + NGX_STREAM_PREACCESS_PHASE, + NGX_STREAM_ACCESS_PHASE, + NGX_STREAM_SSL_PHASE, + NGX_STREAM_PREREAD_PHASE, + NGX_STREAM_CONTENT_PHASE, + NGX_STREAM_LOG_PHASE +} ngx_stream_phases; + + +typedef struct ngx_stream_phase_handler_s ngx_stream_phase_handler_t; + +typedef ngx_int_t (*ngx_stream_phase_handler_pt)(ngx_stream_session_t *s, + ngx_stream_phase_handler_t *ph); +typedef ngx_int_t (*ngx_stream_handler_pt)(ngx_stream_session_t *s); +typedef void (*ngx_stream_content_handler_pt)(ngx_stream_session_t *s); + + +struct ngx_stream_phase_handler_s { + ngx_stream_phase_handler_pt checker; + ngx_stream_handler_pt handler; + ngx_uint_t next; +}; + + +typedef struct { + ngx_stream_phase_handler_t *handlers; +} ngx_stream_phase_engine_t; + + +typedef struct { + ngx_array_t handlers; +} ngx_stream_phase_t; typedef struct { ngx_array_t servers; /* ngx_stream_core_srv_conf_t */ ngx_array_t listen; /* ngx_stream_listen_t */ - ngx_stream_access_pt realip_handler; - ngx_stream_access_pt limit_conn_handler; - ngx_stream_access_pt access_handler; - ngx_stream_access_pt access_log_handler; + ngx_stream_phase_engine_t phase_engine; ngx_hash_t variables_hash; @@ -136,14 +160,13 @@ ngx_uint_t variables_hash_bucket_size; ngx_hash_keys_arrays_t *variables_keys; -} ngx_stream_core_main_conf_t; - -typedef void (*ngx_stream_handler_pt)(ngx_stream_session_t *s); + ngx_stream_phase_t phases[NGX_STREAM_LOG_PHASE + 1]; +} ngx_stream_core_main_conf_t; typedef struct { - ngx_stream_handler_pt handler; + ngx_stream_content_handler_pt handler; ngx_stream_conf_ctx_t *ctx; @@ -151,6 +174,8 @@ ngx_uint_t line; ngx_flag_t tcp_nodelay; + size_t preread_buffer_size; + ngx_msec_t preread_timeout; ngx_log_t *error_log; @@ -189,11 +214,14 @@ u_char *captures_data; #endif + ngx_int_t phase_handler; ngx_uint_t status; -#if (NGX_STREAM_SSL) - ngx_uint_t ssl; /* unsigned ssl:1; */ -#endif + unsigned ssl:1; + + unsigned stat_processing:1; + + unsigned health_check:1; }; @@ -243,7 +271,20 @@ NULL) +#define NGX_STREAM_WRITE_BUFFERED 0x10 + + +void ngx_stream_core_run_phases(ngx_stream_session_t *s); +ngx_int_t ngx_stream_core_generic_phase(ngx_stream_session_t *s, + ngx_stream_phase_handler_t *ph); +ngx_int_t ngx_stream_core_preread_phase(ngx_stream_session_t *s, + ngx_stream_phase_handler_t *ph); +ngx_int_t ngx_stream_core_content_phase(ngx_stream_session_t *s, + ngx_stream_phase_handler_t *ph); + + void ngx_stream_init_connection(ngx_connection_t *c); +void ngx_stream_session_handler(ngx_event_t *rev); void ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc); @@ -252,4 +293,11 @@ extern ngx_module_t ngx_stream_core_module; +typedef ngx_int_t (*ngx_stream_filter_pt)(ngx_stream_session_t *s, + ngx_chain_t *chain, ngx_uint_t from_upstream); + + +extern ngx_stream_filter_pt ngx_stream_top_filter; + + #endif /* _NGX_STREAM_H_INCLUDED_ */ | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_access_module.c ^ |
@@ -275,7 +275,7 @@ if (deny) { ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "access forbidden by rule"); - return NGX_ABORT; + return NGX_STREAM_FORBIDDEN; } return NGX_OK; @@ -443,10 +443,17 @@ static ngx_int_t ngx_stream_access_init(ngx_conf_t *cf) { + ngx_stream_handler_pt *h; ngx_stream_core_main_conf_t *cmcf; cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - cmcf->access_handler = ngx_stream_access_handler; + + h = ngx_array_push(&cmcf->phases[NGX_STREAM_ACCESS_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_stream_access_handler; return NGX_OK; } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_core_module.c ^ |
@@ -91,6 +91,20 @@ offsetof(ngx_stream_core_srv_conf_t, tcp_nodelay), NULL }, + { ngx_string("preread_buffer_size"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_core_srv_conf_t, preread_buffer_size), + NULL }, + + { ngx_string("preread_timeout"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_msec_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_core_srv_conf_t, preread_timeout), + NULL }, + ngx_null_command }; @@ -123,6 +137,214 @@ }; +void +ngx_stream_core_run_phases(ngx_stream_session_t *s) +{ + ngx_int_t rc; + ngx_stream_phase_handler_t *ph; + ngx_stream_core_main_conf_t *cmcf; + + cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); + + ph = cmcf->phase_engine.handlers; + + while (ph[s->phase_handler].checker) { + + rc = ph[s->phase_handler].checker(s, &ph[s->phase_handler]); + + if (rc == NGX_OK) { + return; + } + } +} + + +ngx_int_t +ngx_stream_core_generic_phase(ngx_stream_session_t *s, + ngx_stream_phase_handler_t *ph) +{ + ngx_int_t rc; + + /* + * generic phase checker, + * used by all phases, except for preread and content + */ + + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "generic phase: %ui", s->phase_handler); + + rc = ph->handler(s); + + if (rc == NGX_OK) { + s->phase_handler = ph->next; + return NGX_AGAIN; + } + + if (rc == NGX_DECLINED) { + s->phase_handler++; + return NGX_AGAIN; + } + + if (rc == NGX_AGAIN || rc == NGX_DONE) { + return NGX_OK; + } + + if (rc == NGX_ERROR) { + rc = NGX_STREAM_INTERNAL_SERVER_ERROR; + } + + ngx_stream_finalize_session(s, rc); + + return NGX_OK; +} + + +ngx_int_t +ngx_stream_core_preread_phase(ngx_stream_session_t *s, + ngx_stream_phase_handler_t *ph) +{ + size_t size; + ssize_t n; + ngx_int_t rc; + ngx_connection_t *c; + ngx_stream_core_srv_conf_t *cscf; + + c = s->connection; + + c->log->action = "prereading client data"; + + cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); + + if (c->read->timedout) { + rc = NGX_STREAM_OK; + + } else if (c->read->timer_set) { + rc = NGX_AGAIN; + + } else { + rc = ph->handler(s); + } + + while (rc == NGX_AGAIN) { + + if (c->buffer == NULL) { + c->buffer = ngx_create_temp_buf(c->pool, cscf->preread_buffer_size); + if (c->buffer == NULL) { + rc = NGX_ERROR; + break; + } + } + + size = c->buffer->end - c->buffer->last; + + if (size == 0) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, "preread buffer full"); + rc = NGX_STREAM_BAD_REQUEST; + break; + } + + if (c->read->eof) { + rc = NGX_STREAM_OK; + break; + } + + if (!c->read->ready) { + if (ngx_handle_read_event(c->read, 0) != NGX_OK) { + rc = NGX_ERROR; + break; + } + + if (!c->read->timer_set) { + ngx_add_timer(c->read, cscf->preread_timeout); + } + + c->read->handler = ngx_stream_session_handler; + + return NGX_OK; + } + + n = c->recv(c, c->buffer->last, size); + + if (n == NGX_ERROR) { + rc = NGX_STREAM_OK; + break; + } + + if (n > 0) { + c->buffer->last += n; + } + + rc = ph->handler(s); + } + + if (c->read->timer_set) { + ngx_del_timer(c->read); + } + + if (rc == NGX_OK) { + s->phase_handler = ph->next; + return NGX_AGAIN; + } + + if (rc == NGX_DECLINED) { + s->phase_handler++; + return NGX_AGAIN; + } + + if (rc == NGX_DONE) { + return NGX_OK; + } + + if (rc == NGX_ERROR) { + rc = NGX_STREAM_INTERNAL_SERVER_ERROR; + } + + ngx_stream_finalize_session(s, rc); + + return NGX_OK; +} + + +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; + + c = s->connection; + + c->log->action = NULL; + + cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); + + if (c->type == SOCK_STREAM + && cscf->tcp_nodelay + && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) + { + 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; + } + + cscf->handler(s); + + return NGX_OK; +} + + static ngx_int_t ngx_stream_core_preconfiguration(ngx_conf_t *cf) { @@ -201,6 +423,8 @@ cscf->resolver_timeout = NGX_CONF_UNSET_MSEC; cscf->proxy_protocol_timeout = NGX_CONF_UNSET_MSEC; cscf->tcp_nodelay = NGX_CONF_UNSET; + cscf->preread_buffer_size = NGX_CONF_UNSET_SIZE; + cscf->preread_timeout = NGX_CONF_UNSET_MSEC; return cscf; } @@ -253,6 +477,12 @@ ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1); + ngx_conf_merge_size_value(conf->preread_buffer_size, + prev->preread_buffer_size, 16384); + + ngx_conf_merge_msec_value(conf->preread_timeout, + prev->preread_timeout, 30000); + return NGX_CONF_OK; } @@ -394,7 +624,7 @@ ls->wildcard = u.wildcard; ls->ctx = cf->ctx; -#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) +#if (NGX_HAVE_INET6) ls->ipv6only = 1; #endif | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_handler.c ^ |
@@ -11,15 +11,10 @@ #include <ngx_stream.h> +static void ngx_stream_log_session(ngx_stream_session_t *s); static void ngx_stream_close_connection(ngx_connection_t *c); static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len); static void ngx_stream_proxy_protocol_handler(ngx_event_t *rev); -static void ngx_stream_init_session_handler(ngx_event_t *rev); - -#if (NGX_STREAM_SSL) -static void ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); -static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c); -#endif void @@ -134,6 +129,10 @@ s->ssl = addr_conf->ssl; #endif + if (c->buffer) { + s->received += c->buffer->last - c->buffer->pos; + } + s->connection = c; c->data = s; @@ -150,7 +149,7 @@ c->log->connection = c->number; c->log->handler = ngx_stream_log_error; c->log->data = s; - c->log->action = "initializing connection"; + c->log->action = "initializing session"; c->log_error = NGX_ERROR_INFO; s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_stream_max_module); @@ -175,7 +174,7 @@ s->start_msec = tp->msec; rev = c->read; - rev->handler = ngx_stream_init_session_handler; + rev->handler = ngx_stream_session_handler; if (addr_conf->proxy_protocol) { c->log->action = "reading PROXY protocol"; @@ -275,189 +274,54 @@ return; } - ngx_stream_init_session_handler(rev); -} - - -static void -ngx_stream_init_session_handler(ngx_event_t *rev) -{ - int tcp_nodelay; - ngx_int_t rc; - ngx_connection_t *c; - ngx_stream_session_t *s; - ngx_stream_core_srv_conf_t *cscf; - ngx_stream_core_main_conf_t *cmcf; - - c = rev->data; - s = c->data; - c->log->action = "initializing session"; - cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); - - if (cmcf->realip_handler) { - rc = cmcf->realip_handler(s); - - if (rc == NGX_ERROR) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - } - - if (cmcf->limit_conn_handler) { - rc = cmcf->limit_conn_handler(s); - - if (rc == NGX_ERROR) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (rc == NGX_ABORT) { - ngx_stream_finalize_session(s, NGX_STREAM_SERVICE_UNAVAILABLE); - return; - } - } - - if (cmcf->access_handler) { - rc = cmcf->access_handler(s); - - if (rc == NGX_ERROR) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (rc == NGX_ABORT) { - ngx_stream_finalize_session(s, NGX_STREAM_FORBIDDEN); - return; - } - } - - cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); - - if (c->type == SOCK_STREAM - && cscf->tcp_nodelay - && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) - { - 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; - } - - c->tcp_nodelay = NGX_TCP_NODELAY_SET; - } - - -#if (NGX_STREAM_SSL) - { - ngx_stream_ssl_conf_t *sslcf; - - sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); - - if (s->ssl) { - c->log->action = "SSL handshaking"; - - if (sslcf->ssl.ctx == NULL) { - ngx_log_error(NGX_LOG_ERR, c->log, 0, - "no \"ssl_certificate\" is defined " - "in server listening on SSL port"); - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - ngx_stream_ssl_init_connection(&sslcf->ssl, c); - return; - } - } -#endif - - c->log->action = "handling client connection"; - - cscf->handler(s); + ngx_stream_session_handler(rev); } -#if (NGX_STREAM_SSL) - -static void -ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c) +void +ngx_stream_session_handler(ngx_event_t *rev) { - ngx_stream_session_t *s; - ngx_stream_ssl_conf_t *sslcf; + ngx_connection_t *c; + ngx_stream_session_t *s; + c = rev->data; s = c->data; - if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { - ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (ngx_ssl_handshake(c) == NGX_AGAIN) { - sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); - - ngx_add_timer(c->read, sslcf->handshake_timeout); - - c->ssl->handler = ngx_stream_ssl_handshake_handler; - - return; - } - - ngx_stream_ssl_handshake_handler(c); + ngx_stream_core_run_phases(s); } -static void -ngx_stream_ssl_handshake_handler(ngx_connection_t *c) +void +ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc) { - ngx_stream_session_t *s; - ngx_stream_core_srv_conf_t *cscf; - - if (!c->ssl->handshaked) { - ngx_stream_finalize_session(c->data, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - if (c->read->timer_set) { - ngx_del_timer(c->read); - } - - c->log->action = "handling client connection"; + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, + "finalize stream session: %i", rc); - s = c->data; + s->status = rc; - cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); + ngx_stream_log_session(s); - cscf->handler(s); + ngx_stream_close_connection(s->connection); } -#endif - -void -ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc) +static void +ngx_stream_log_session(ngx_stream_session_t *s) { + ngx_uint_t i, n; + ngx_stream_handler_pt *log_handler; ngx_stream_core_main_conf_t *cmcf; - ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, - "finalize stream session: %i", rc); - - s->status = rc; - cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); - if (cmcf->access_log_handler) { - (void) cmcf->access_log_handler(s); - } + log_handler = cmcf->phases[NGX_STREAM_LOG_PHASE].handlers.elts; + n = cmcf->phases[NGX_STREAM_LOG_PHASE].handlers.nelts; - ngx_stream_close_connection(s->connection); + for (i = 0; i < n; i++) { + log_handler[i](s); + } } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_limit_conn_module.c ^ |
@@ -178,7 +178,7 @@ if (node == NULL) { ngx_shmtx_unlock(&shpool->mutex); ngx_stream_limit_conn_cleanup_all(s->connection->pool); - return NGX_ABORT; + return NGX_STREAM_SERVICE_UNAVAILABLE; } lc = (ngx_stream_limit_conn_node_t *) &node->color; @@ -203,7 +203,7 @@ &limits[i].shm_zone->shm.name); ngx_stream_limit_conn_cleanup_all(s->connection->pool); - return NGX_ABORT; + return NGX_STREAM_SERVICE_UNAVAILABLE; } lc->conn++; @@ -630,11 +630,17 @@ static ngx_int_t ngx_stream_limit_conn_init(ngx_conf_t *cf) { + ngx_stream_handler_pt *h; ngx_stream_core_main_conf_t *cmcf; cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - cmcf->limit_conn_handler = ngx_stream_limit_conn_handler; + h = ngx_array_push(&cmcf->phases[NGX_STREAM_PREACCESS_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_stream_limit_conn_handler; return NGX_OK; } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_log_module.c ^ |
@@ -1464,11 +1464,17 @@ static ngx_int_t ngx_stream_log_init(ngx_conf_t *cf) { + ngx_stream_handler_pt *h; ngx_stream_core_main_conf_t *cmcf; cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - cmcf->access_log_handler = ngx_stream_log_handler; + h = ngx_array_push(&cmcf->phases[NGX_STREAM_LOG_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_stream_log_handler; return NGX_OK; } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_proxy_module.c ^ |
@@ -84,10 +84,10 @@ void *conf); static char *ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s); #if (NGX_STREAM_SSL) +static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s); static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static void ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s); @@ -385,8 +385,6 @@ } u->peer.type = c->type; - - u->proxy_protocol = pscf->proxy_protocol; u->start_sec = ngx_time(); c->write->handler = ngx_stream_proxy_downstream_handler; @@ -411,28 +409,6 @@ u->downstream_buf.pos = p; u->downstream_buf.last = p; - if (u->proxy_protocol -#if (NGX_STREAM_SSL) - && pscf->ssl == NULL -#endif - && pscf->buffer_size >= NGX_PROXY_PROTOCOL_MAX_HEADER) - { - /* optimization for a typical case */ - - ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, - "stream proxy send PROXY protocol header"); - - p = ngx_proxy_protocol_write(c, u->downstream_buf.last, - u->downstream_buf.end); - if (p == NULL) { - ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); - return; - } - - u->downstream_buf.last = p; - u->proxy_protocol = 0; - } - if (c->read->ready) { ngx_post_event(c->read, &ngx_posted_events); } @@ -545,6 +521,8 @@ return; } + u->upstream = uscf; + #if (NGX_STREAM_SSL) u->ssl_name = uscf->host; #endif @@ -682,8 +660,13 @@ c->log->action = "connecting to upstream"; + pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); + u = s->upstream; + u->connected = 0; + u->proxy_protocol = pscf->proxy_protocol; + if (u->state) { u->state->response_time = ngx_current_msec - u->state->response_time; } @@ -740,8 +723,6 @@ pc->read->handler = ngx_stream_proxy_connect_handler; pc->write->handler = ngx_stream_proxy_connect_handler; - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); - ngx_add_timer(pc->write, pscf->connect_timeout); } @@ -751,6 +732,7 @@ { int tcp_nodelay; u_char *p; + ngx_chain_t *cl; ngx_connection_t *c, *pc; ngx_log_handler_pt handler; ngx_stream_upstream_t *u; @@ -782,21 +764,26 @@ pc->tcp_nodelay = NGX_TCP_NODELAY_SET; } - if (u->proxy_protocol) { - if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) { - return; - } - - u->proxy_protocol = 0; - } - pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); #if (NGX_STREAM_SSL) - if (pc->type == SOCK_STREAM && pscf->ssl && pc->ssl == NULL) { - ngx_stream_proxy_ssl_init_connection(s); - return; + + if (pc->type == SOCK_STREAM && pscf->ssl) { + + if (u->proxy_protocol) { + if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) { + return; + } + + u->proxy_protocol = 0; + } + + if (pc->ssl == NULL) { + ngx_stream_proxy_ssl_init_connection(s); + return; + } } + #endif c = s->connection; @@ -838,14 +825,66 @@ u->upstream_buf.last = p; } - if (c->type == SOCK_DGRAM) { - s->received = c->buffer->last - c->buffer->pos; - u->downstream_buf = *c->buffer; - - if (pscf->responses == 0) { - pc->read->ready = 0; - pc->read->eof = 1; + if (c->buffer && c->buffer->pos < c->buffer->last) { + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, + "stream proxy add preread buffer: %uz", + c->buffer->last - c->buffer->pos); + + cl = ngx_chain_get_free_buf(c->pool, &u->free); + if (cl == NULL) { + ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return; } + + *cl->buf = *c->buffer; + + cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module; + cl->buf->flush = 1; + cl->buf->last_buf = (c->type == SOCK_DGRAM); + + cl->next = u->upstream_out; + u->upstream_out = cl; + } + + if (u->proxy_protocol) { + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, + "stream proxy add PROXY protocol header"); + + cl = ngx_chain_get_free_buf(c->pool, &u->free); + if (cl == NULL) { + ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return; + } + + p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_MAX_HEADER); + if (p == NULL) { + ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return; + } + + cl->buf->pos = p; + + p = ngx_proxy_protocol_write(c, p, p + NGX_PROXY_PROTOCOL_MAX_HEADER); + if (p == NULL) { + ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return; + } + + cl->buf->last = p; + cl->buf->temporary = 1; + cl->buf->flush = 0; + cl->buf->last_buf = 0; + cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module; + + cl->next = u->upstream_out; + u->upstream_out = cl; + + u->proxy_protocol = 0; + } + + if (c->type == SOCK_DGRAM && pscf->responses == 0) { + pc->read->ready = 0; + pc->read->eof = 1; } u->connected = 1; @@ -861,6 +900,8 @@ } +#if (NGX_STREAM_SSL) + static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s) { @@ -931,8 +972,6 @@ } -#if (NGX_STREAM_SSL) - static char * ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) @@ -1412,8 +1451,10 @@ size_t size, limit_rate; ssize_t n; ngx_buf_t *b; + ngx_int_t rc; ngx_uint_t flags; ngx_msec_t delay; + ngx_chain_t *cl, **ll, **out, **busy; ngx_connection_t *c, *pc, *src, *dst; ngx_log_handler_pt handler; ngx_stream_upstream_t *u; @@ -1447,6 +1488,8 @@ b = &u->upstream_buf; limit_rate = pscf->download_rate; received = &u->received; + out = &u->downstream_out; + busy = &u->downstream_busy; } else { src = c; @@ -1454,24 +1497,18 @@ b = &u->downstream_buf; limit_rate = pscf->upload_rate; received = &s->received; + out = &u->upstream_out; + busy = &u->upstream_busy; } for ( ;; ) { - if (do_write) { - - size = b->last - b->pos; - - if (size && dst && dst->write->ready) { - - n = dst->send(dst, b->pos, size); + if (do_write && dst) { - if (n == NGX_AGAIN && dst->shared) { - /* cannot wait on a shared socket */ - n = NGX_ERROR; - } + if (*out || *busy || dst->buffered) { + rc = ngx_stream_top_filter(s, *out, from_upstream); - if (n == NGX_ERROR) { + if (rc == NGX_ERROR) { if (c->type == SOCK_DGRAM && !from_upstream) { ngx_stream_proxy_next_upstream(s); return; @@ -1481,13 +1518,12 @@ return; } - if (n > 0) { - b->pos += n; + ngx_chain_update_chains(c->pool, &u->free, busy, out, + (ngx_buf_tag_t) &ngx_stream_proxy_module); - if (b->pos == b->last) { - b->pos = b->start; - b->last = b->start; - } + if (*busy == NULL) { + b->pos = b->start; + b->last = b->start; } } } @@ -1514,11 +1550,21 @@ n = src->recv(src, b->last, size); - if (n == NGX_AGAIN || n == 0) { + if (n == NGX_AGAIN) { break; } - if (n > 0) { + if (n == NGX_ERROR) { + if (c->type == SOCK_DGRAM && u->received == 0) { + ngx_stream_proxy_next_upstream(s); + return; + } + + src->read->eof = 1; + n = 0; + } + + if (n >= 0) { if (limit_rate) { delay = (ngx_msec_t) (n * 1000 / limit_rate); @@ -1541,27 +1587,37 @@ src->read->eof = 1; } + for (ll = out; *ll; ll = &(*ll)->next) { /* void */ } + + cl = ngx_chain_get_free_buf(c->pool, &u->free); + if (cl == NULL) { + ngx_stream_proxy_finalize(s, + NGX_STREAM_INTERNAL_SERVER_ERROR); + return; + } + + *ll = cl; + + cl->buf->pos = b->last; + cl->buf->last = b->last + n; + cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module; + + cl->buf->temporary = (n ? 1 : 0); + cl->buf->last_buf = src->read->eof; + cl->buf->flush = 1; + *received += n; b->last += n; do_write = 1; continue; } - - if (n == NGX_ERROR) { - if (c->type == SOCK_DGRAM && u->received == 0) { - ngx_stream_proxy_next_upstream(s); - return; - } - - src->read->eof = 1; - } } break; } - if (src->read->eof && (b->pos == b->last || (dst && dst->read->eof))) { + if (src->read->eof && dst && (dst->read->eof || !dst->buffered)) { handler = c->log->handler; c->log->handler = NULL; @@ -1614,6 +1670,14 @@ "stream proxy next upstream"); u = s->upstream; + pc = u->peer.connection; + + if (u->upstream_out || u->upstream_busy || (pc && pc->buffered)) { + ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, + "pending buffers on next upstream"); + ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return; + } if (u->peer.sockaddr) { u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED); @@ -1632,8 +1696,6 @@ return; } - pc = u->peer.connection; - if (pc) { ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, "close proxy upstream connection: %d", pc->fd); | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_realip_module.c ^ |
@@ -279,11 +279,17 @@ static ngx_int_t ngx_stream_realip_init(ngx_conf_t *cf) { + ngx_stream_handler_pt *h; ngx_stream_core_main_conf_t *cmcf; cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - cmcf->realip_handler = ngx_stream_realip_handler; + h = ngx_array_push(&cmcf->phases[NGX_STREAM_POST_ACCEPT_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_stream_realip_handler; return NGX_OK; } | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_return_module.c ^ |
@@ -11,12 +11,12 @@ typedef struct { - ngx_stream_complex_value_t text; + ngx_stream_complex_value_t text; } ngx_stream_return_srv_conf_t; typedef struct { - ngx_buf_t buf; + ngx_chain_t *out; } ngx_stream_return_ctx_t; @@ -72,6 +72,7 @@ ngx_stream_return_handler(ngx_stream_session_t *s) { ngx_str_t text; + ngx_buf_t *b; ngx_connection_t *c; ngx_stream_return_ctx_t *ctx; ngx_stream_return_srv_conf_t *rscf; @@ -103,8 +104,25 @@ ngx_stream_set_ctx(s, ctx, ngx_stream_return_module); - ctx->buf.pos = text.data; - ctx->buf.last = text.data + text.len; + b = ngx_calloc_buf(c->pool); + if (b == NULL) { + ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return; + } + + b->memory = 1; + b->pos = text.data; + b->last = text.data + text.len; + b->last_buf = 1; + + ctx->out = ngx_alloc_chain_link(c->pool); + if (ctx->out == NULL) { + ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return; + } + + ctx->out->buf = b; + ctx->out->next = NULL; c->write->handler = ngx_stream_return_write_handler; @@ -115,8 +133,6 @@ static void ngx_stream_return_write_handler(ngx_event_t *ev) { - ssize_t n; - ngx_buf_t *b; ngx_connection_t *c; ngx_stream_session_t *s; ngx_stream_return_ctx_t *ctx; @@ -130,25 +146,20 @@ return; } - if (ev->ready) { - ctx = ngx_stream_get_module_ctx(s, ngx_stream_return_module); + ctx = ngx_stream_get_module_ctx(s, ngx_stream_return_module); - b = &ctx->buf; + if (ngx_stream_top_filter(s, ctx->out, 1) == NGX_ERROR) { + ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return; + } - n = c->send(c, b->pos, b->last - b->pos); - if (n == NGX_ERROR) { - ngx_stream_finalize_session(s, NGX_STREAM_OK); - return; - } - - if (n > 0) { - b->pos += n; - - if (b->pos == b->last) { - ngx_stream_finalize_session(s, NGX_STREAM_OK); - return; - } - } + ctx->out = NULL; + + if (!c->buffered) { + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, + "stream return done sending"); + ngx_stream_finalize_session(s, NGX_STREAM_OK); + return; } if (ngx_handle_write_event(ev, 0) != NGX_OK) { | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_ssl_module.c ^ |
@@ -18,6 +18,10 @@ #define NGX_DEFAULT_ECDH_CURVE "auto" +static ngx_int_t 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); +static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c); static ngx_int_t ngx_stream_ssl_static_variable(ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_stream_ssl_variable(ngx_stream_session_t *s, @@ -32,6 +36,7 @@ void *conf); static char *ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static ngx_int_t ngx_stream_ssl_init(ngx_conf_t *cf); static ngx_conf_bitmask_t ngx_stream_ssl_protocols[] = { @@ -143,7 +148,7 @@ static ngx_stream_module_t ngx_stream_ssl_module_ctx = { ngx_stream_ssl_add_variables, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_stream_ssl_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -194,6 +199,88 @@ static ngx_int_t +ngx_stream_ssl_handler(ngx_stream_session_t *s) +{ + ngx_connection_t *c; + ngx_stream_ssl_conf_t *sslcf; + + c = s->connection; + + sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); + + if (s->ssl && c->ssl == NULL) { + c->log->action = "SSL handshaking"; + + if (sslcf->ssl.ctx == NULL) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "no \"ssl_certificate\" is defined " + "in server listening on SSL port"); + return NGX_ERROR; + } + + return ngx_stream_ssl_init_connection(&sslcf->ssl, c); + } + + return NGX_OK; +} + + +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; + + s = c->data; + + if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { + return NGX_ERROR; + } + + rc = ngx_ssl_handshake(c); + + if (rc == NGX_ERROR) { + return NGX_ERROR; + } + + if (rc == NGX_AGAIN) { + sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); + + ngx_add_timer(c->read, sslcf->handshake_timeout); + + c->ssl->handler = ngx_stream_ssl_handshake_handler; + + return NGX_AGAIN; + } + + /* rc == NGX_OK */ + + return NGX_OK; +} + + +static void +ngx_stream_ssl_handshake_handler(ngx_connection_t *c) +{ + ngx_stream_session_t *s; + + s = c->data; + + if (!c->ssl->handshaked) { + ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); + return; + } + + if (c->read->timer_set) { + ngx_del_timer(c->read); + } + + ngx_stream_core_run_phases(s); +} + + +static ngx_int_t ngx_stream_ssl_static_variable(ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data) { @@ -565,3 +652,22 @@ return NGX_CONF_ERROR; } + + +static ngx_int_t +ngx_stream_ssl_init(ngx_conf_t *cf) +{ + ngx_stream_handler_pt *h; + ngx_stream_core_main_conf_t *cmcf; + + cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); + + h = ngx_array_push(&cmcf->phases[NGX_STREAM_SSL_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_stream_ssl_handler; + + return NGX_OK; +} | ||
[+] | Added | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_ssl_preread_module.c ^ |
@@ -0,0 +1,449 @@ + +/* + * Copyright (C) Nginx, Inc. + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_stream.h> + + +typedef struct { + ngx_flag_t enabled; +} ngx_stream_ssl_preread_srv_conf_t; + + +typedef struct { + size_t left; + size_t size; + u_char *pos; + u_char *dst; + u_char buf[4]; + ngx_str_t host; + ngx_log_t *log; + ngx_pool_t *pool; + ngx_uint_t state; +} ngx_stream_ssl_preread_ctx_t; + + +static ngx_int_t ngx_stream_ssl_preread_handler(ngx_stream_session_t *s); +static ngx_int_t ngx_stream_ssl_preread_parse_record( + ngx_stream_ssl_preread_ctx_t *ctx, u_char *pos, u_char *last); +static ngx_int_t ngx_stream_ssl_preread_server_name_variable( + ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_stream_ssl_preread_add_variables(ngx_conf_t *cf); +static void *ngx_stream_ssl_preread_create_srv_conf(ngx_conf_t *cf); +static char *ngx_stream_ssl_preread_merge_srv_conf(ngx_conf_t *cf, void *parent, + void *child); +static ngx_int_t ngx_stream_ssl_preread_init(ngx_conf_t *cf); + + +static ngx_command_t ngx_stream_ssl_preread_commands[] = { + + { ngx_string("ssl_preread"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_ssl_preread_srv_conf_t, enabled), + NULL }, + + ngx_null_command +}; + + +static ngx_stream_module_t ngx_stream_ssl_preread_module_ctx = { + ngx_stream_ssl_preread_add_variables, /* preconfiguration */ + ngx_stream_ssl_preread_init, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + ngx_stream_ssl_preread_create_srv_conf, /* create server configuration */ + ngx_stream_ssl_preread_merge_srv_conf /* merge server configuration */ +}; + + +ngx_module_t ngx_stream_ssl_preread_module = { + NGX_MODULE_V1, + &ngx_stream_ssl_preread_module_ctx, /* module context */ + ngx_stream_ssl_preread_commands, /* module directives */ + NGX_STREAM_MODULE, /* module type */ + NULL, /* init master */ + NULL, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ + NGX_MODULE_V1_PADDING +}; + + +static ngx_stream_variable_t ngx_stream_ssl_preread_vars[] = { + + { ngx_string("ssl_preread_server_name"), NULL, + ngx_stream_ssl_preread_server_name_variable, 0, 0, 0 }, + + { ngx_null_string, NULL, NULL, 0, 0, 0 } +}; + + +static ngx_int_t +ngx_stream_ssl_preread_handler(ngx_stream_session_t *s) +{ + u_char *last, *p; + size_t len; + ngx_int_t rc; + ngx_connection_t *c; + ngx_stream_ssl_preread_ctx_t *ctx; + ngx_stream_ssl_preread_srv_conf_t *sscf; + + c = s->connection; + + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "ssl preread handler"); + + sscf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_preread_module); + + if (!sscf->enabled) { + return NGX_DECLINED; + } + + if (c->type != SOCK_STREAM) { + return NGX_DECLINED; + } + + if (c->buffer == NULL) { + return NGX_AGAIN; + } + + ctx = ngx_stream_get_module_ctx(s, ngx_stream_ssl_preread_module); + if (ctx == NULL) { + ctx = ngx_pcalloc(c->pool, sizeof(ngx_stream_ssl_preread_ctx_t)); + if (ctx == NULL) { + return NGX_ERROR; + } + + ngx_stream_set_ctx(s, ctx, ngx_stream_ssl_preread_module); + + ctx->pool = c->pool; + ctx->log = c->log; + ctx->pos = c->buffer->pos; + } + + p = ctx->pos; + last = c->buffer->last; + + while (last - p >= 5) { + + if (p[0] != 0x16) { + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, + "ssl preread: not a handshake"); + return NGX_DECLINED; + } + + if (p[1] != 3 || p[2] == 0) { + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, + "ssl preread: unsupported SSL version"); + return NGX_DECLINED; + } + + len = (p[3] << 8) + p[4]; + + /* read the whole record before parsing */ + if ((size_t) (last - p) < len + 5) { + break; + } + + p += 5; + + rc = ngx_stream_ssl_preread_parse_record(ctx, p, p + len); + if (rc != NGX_AGAIN) { + return rc; + } + + p += len; + } + + ctx->pos = p; + + return NGX_AGAIN; +} + + +static ngx_int_t +ngx_stream_ssl_preread_parse_record(ngx_stream_ssl_preread_ctx_t *ctx, + u_char *pos, u_char *last) +{ + size_t left, n, size; + u_char *dst, *p; + + enum { + sw_start = 0, + sw_header, /* handshake msg_type, length */ + sw_head_tail, /* version, random */ + sw_sid_len, /* session_id length */ + sw_sid, /* session_id */ + sw_cs_len, /* cipher_suites length */ + sw_cs, /* cipher_suites */ + sw_cm_len, /* compression_methods length */ + sw_cm, /* compression_methods */ + sw_ext, /* extension */ + sw_ext_header, /* extension_type, extension_data length */ + sw_sni_len, /* SNI length */ + sw_sni_host_head, /* SNI name_type, host_name length */ + sw_sni_host /* SNI host_name */ + } state; + + ngx_log_debug2(NGX_LOG_DEBUG_STREAM, ctx->log, 0, + "ssl preread: state %ui left %z", ctx->state, ctx->left); + + state = ctx->state; + size = ctx->size; + left = ctx->left; + dst = ctx->dst; + p = ctx->buf; + + for ( ;; ) { + n = ngx_min((size_t) (last - pos), size); + + if (dst) { + dst = ngx_cpymem(dst, pos, n); + } + + pos += n; + size -= n; + left -= n; + + if (size != 0) { + break; + } + + switch (state) { + + case sw_start: + state = sw_header; + dst = p; + size = 4; + left = size; + break; + + case sw_header: + if (p[0] != 1) { + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, + "ssl preread: not a client hello"); + return NGX_DECLINED; + } + + state = sw_head_tail; + dst = NULL; + size = 34; + left = (p[1] << 16) + (p[2] << 8) + p[3]; + break; + + case sw_head_tail: + state = sw_sid_len; + dst = p; + size = 1; + break; + + case sw_sid_len: + state = sw_sid; + dst = NULL; + size = p[0]; + break; + + case sw_sid: + state = sw_cs_len; + dst = p; + size = 2; + break; + + case sw_cs_len: + state = sw_cs; + dst = NULL; + size = (p[0] << 8) + p[1]; + break; + + case sw_cs: + state = sw_cm_len; + dst = p; + size = 1; + break; + + case sw_cm_len: + state = sw_cm; + dst = NULL; + size = p[0]; + break; + + case sw_cm: + if (left == 0) { + /* no extensions */ + return NGX_OK; + } + + state = sw_ext; + dst = p; + size = 2; + break; + + case sw_ext: + if (left == 0) { + return NGX_OK; + } + + state = sw_ext_header; + dst = p; + size = 4; + break; + + case sw_ext_header: + if (p[0] == 0 && p[1] == 0) { + /* SNI extension */ + state = sw_sni_len; + dst = NULL; + size = 2; + break; + } + + state = sw_ext; + dst = NULL; + size = (p[2] << 8) + p[3]; + break; + + case sw_sni_len: + state = sw_sni_host_head; + dst = p; + size = 3; + break; + + case sw_sni_host_head: + if (p[0] != 0) { + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, + "ssl preread: SNI hostname type is not DNS"); + return NGX_DECLINED; + } + + state = sw_sni_host; + size = (p[1] << 8) + p[2]; + + ctx->host.data = ngx_pnalloc(ctx->pool, size); + if (ctx->host.data == NULL) { + return NGX_ERROR; + } + + dst = ctx->host.data; + break; + + case sw_sni_host: + ctx->host.len = (p[1] << 8) + p[2]; + + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ctx->log, 0, + "ssl preread: SNI hostname \"%V\"", &ctx->host); + return NGX_OK; + } + + if (left < size) { + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0, + "ssl preread: failed to parse handshake"); + return NGX_DECLINED; + } + } + + ctx->state = state; + ctx->size = size; + ctx->left = left; + ctx->dst = dst; + + return NGX_AGAIN; +} + + +static ngx_int_t +ngx_stream_ssl_preread_server_name_variable(ngx_stream_session_t *s, + ngx_variable_value_t *v, uintptr_t data) +{ + ngx_stream_ssl_preread_ctx_t *ctx; + + ctx = ngx_stream_get_module_ctx(s, ngx_stream_ssl_preread_module); + + if (ctx == NULL) { + v->not_found = 1; + return NGX_OK; + } + + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->len = ctx->host.len; + v->data = ctx->host.data; + + return NGX_OK; +} + + +static ngx_int_t +ngx_stream_ssl_preread_add_variables(ngx_conf_t *cf) +{ + ngx_stream_variable_t *var, *v; + + for (v = ngx_stream_ssl_preread_vars; v->name.len; v++) { + var = ngx_stream_add_variable(cf, &v->name, v->flags); + if (var == NULL) { + return NGX_ERROR; + } + + var->get_handler = v->get_handler; + var->data = v->data; + } + + return NGX_OK; +} + + +static void * +ngx_stream_ssl_preread_create_srv_conf(ngx_conf_t *cf) +{ + ngx_stream_ssl_preread_srv_conf_t *conf; + + conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_ssl_preread_srv_conf_t)); + if (conf == NULL) { + return NULL; + } + + conf->enabled = NGX_CONF_UNSET; + + return conf; +} + + +static char * +ngx_stream_ssl_preread_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) +{ + ngx_stream_ssl_preread_srv_conf_t *prev = parent; + ngx_stream_ssl_preread_srv_conf_t *conf = child; + + ngx_conf_merge_value(conf->enabled, prev->enabled, 0); + + return NGX_CONF_OK; +} + + +static ngx_int_t +ngx_stream_ssl_preread_init(ngx_conf_t *cf) +{ + ngx_stream_handler_pt *h; + ngx_stream_core_main_conf_t *cmcf; + + cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); + + h = ngx_array_push(&cmcf->phases[NGX_STREAM_PREREAD_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_stream_ssl_preread_handler; + + return NGX_OK; +} | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_upstream.c ^ |
@@ -322,6 +322,7 @@ uscf = ngx_stream_upstream_add(cf, &u, NGX_STREAM_UPSTREAM_CREATE |NGX_STREAM_UPSTREAM_WEIGHT + |NGX_STREAM_UPSTREAM_MAX_CONNS |NGX_STREAM_UPSTREAM_MAX_FAILS |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT |NGX_STREAM_UPSTREAM_DOWN @@ -407,7 +408,7 @@ time_t fail_timeout; ngx_str_t *value, s; ngx_url_t u; - ngx_int_t weight, max_fails; + ngx_int_t weight, max_conns, max_fails; ngx_uint_t i; ngx_stream_upstream_server_t *us; @@ -421,6 +422,7 @@ value = cf->args->elts; weight = 1; + max_conns = 0; max_fails = 1; fail_timeout = 10; @@ -441,6 +443,21 @@ continue; } + if (ngx_strncmp(value[i].data, "max_conns=", 10) == 0) { + + if (!(uscf->flags & NGX_STREAM_UPSTREAM_MAX_CONNS)) { + goto not_supported; + } + + max_conns = ngx_atoi(&value[i].data[10], value[i].len - 10); + + if (max_conns == NGX_ERROR) { + goto invalid; + } + + continue; + } + if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) { if (!(uscf->flags & NGX_STREAM_UPSTREAM_MAX_FAILS)) { @@ -522,6 +539,7 @@ us->addrs = u.addrs; us->naddrs = u.naddrs; us->weight = weight; + us->max_conns = max_conns; us->max_fails = max_fails; us->fail_timeout = fail_timeout; @@ -586,14 +604,14 @@ } if ((uscfp[i]->flags & NGX_STREAM_UPSTREAM_CREATE) && !u->no_port) { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "upstream \"%V\" may not have port %d", &u->host, u->port); return NULL; } if ((flags & NGX_STREAM_UPSTREAM_CREATE) && !uscfp[i]->no_port) { - ngx_log_error(NGX_LOG_WARN, cf->log, 0, + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "upstream \"%V\" may not have port %d in %s:%ui", &u->host, uscfp[i]->port, uscfp[i]->file_name, uscfp[i]->line); | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_upstream.h ^ |
@@ -21,6 +21,7 @@ #define NGX_STREAM_UPSTREAM_FAIL_TIMEOUT 0x0008 #define NGX_STREAM_UPSTREAM_DOWN 0x0010 #define NGX_STREAM_UPSTREAM_BACKUP 0x0020 +#define NGX_STREAM_UPSTREAM_MAX_CONNS 0x0100 typedef struct { @@ -50,11 +51,16 @@ ngx_addr_t *addrs; ngx_uint_t naddrs; ngx_uint_t weight; + ngx_uint_t max_conns; ngx_uint_t max_fails; time_t fail_timeout; + ngx_msec_t slow_start; unsigned down:1; unsigned backup:1; + + NGX_COMPAT_BEGIN(4) + NGX_COMPAT_END } ngx_stream_upstream_server_t; @@ -106,14 +112,23 @@ typedef struct { ngx_peer_connection_t peer; + ngx_buf_t downstream_buf; ngx_buf_t upstream_buf; + + ngx_chain_t *free; + ngx_chain_t *upstream_out; + ngx_chain_t *upstream_busy; + ngx_chain_t *downstream_out; + ngx_chain_t *downstream_busy; + off_t received; time_t start_sec; ngx_uint_t responses; -#if (NGX_STREAM_SSL) + ngx_str_t ssl_name; -#endif + + ngx_stream_upstream_srv_conf_t *upstream; ngx_stream_upstream_resolved_t *resolved; ngx_stream_upstream_state_t *state; unsigned connected:1; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_upstream_hash_module.c ^ |
@@ -241,6 +241,10 @@ goto next; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + goto next; + } + break; next: @@ -524,7 +528,6 @@ peer; peer = peer->next, i++) { - n = i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); @@ -550,6 +553,10 @@ continue; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + continue; + } + peer->current_weight += peer->effective_weight; total += peer->effective_weight; @@ -572,6 +579,7 @@ hp->tries++; if (hp->tries >= points->number) { + pc->name = hp->rrp.peers->name; ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers); return NGX_BUSY; } @@ -646,6 +654,7 @@ uscf->flags = NGX_STREAM_UPSTREAM_CREATE |NGX_STREAM_UPSTREAM_WEIGHT + |NGX_STREAM_UPSTREAM_MAX_CONNS |NGX_STREAM_UPSTREAM_MAX_FAILS |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT |NGX_STREAM_UPSTREAM_DOWN; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_upstream_least_conn_module.c ^ |
@@ -132,7 +132,6 @@ peer; peer = peer->next, i++) { - n = i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); @@ -151,6 +150,10 @@ continue; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + continue; + } + /* * select peer with least number of connections; if there are * multiple peers with the same number of connections, select @@ -206,6 +209,10 @@ continue; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + continue; + } + peer->current_weight += peer->effective_weight; total += peer->effective_weight; @@ -269,12 +276,6 @@ ngx_stream_upstream_rr_peers_wlock(peers); } - /* all peers failed, mark them as live for quick recovery */ - - for (peer = peers->peer; peer; peer = peer->next) { - peer->fails = 0; - } - ngx_stream_upstream_rr_peers_unlock(peers); pc->name = peers->name; @@ -299,6 +300,7 @@ uscf->flags = NGX_STREAM_UPSTREAM_CREATE |NGX_STREAM_UPSTREAM_WEIGHT + |NGX_STREAM_UPSTREAM_MAX_CONNS |NGX_STREAM_UPSTREAM_MAX_FAILS |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT |NGX_STREAM_UPSTREAM_DOWN | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_upstream_round_robin.c ^ |
@@ -96,6 +96,7 @@ peer[n].weight = server[i].weight; peer[n].effective_weight = server[i].weight; peer[n].current_weight = 0; + peer[n].max_conns = server[i].max_conns; peer[n].max_fails = server[i].max_fails; peer[n].fail_timeout = server[i].fail_timeout; peer[n].down = server[i].down; @@ -159,6 +160,7 @@ peer[n].weight = server[i].weight; peer[n].effective_weight = server[i].weight; peer[n].current_weight = 0; + peer[n].max_conns = server[i].max_conns; peer[n].max_fails = server[i].max_fails; peer[n].fail_timeout = server[i].fail_timeout; peer[n].down = server[i].down; @@ -227,6 +229,7 @@ peer[i].weight = 1; peer[i].effective_weight = 1; peer[i].current_weight = 0; + peer[i].max_conns = 0; peer[i].max_fails = 1; peer[i].fail_timeout = 10; *peerp = &peer[i]; @@ -262,6 +265,7 @@ rrp->peers = us->peer.data; rrp->current = NULL; + rrp->config = 0; n = rrp->peers->number; @@ -344,6 +348,7 @@ peer[0].weight = 1; peer[0].effective_weight = 1; peer[0].current_weight = 0; + peer[0].max_conns = 0; peer[0].max_fails = 1; peer[0].fail_timeout = 10; peers->peer = peer; @@ -377,6 +382,7 @@ peer[i].weight = 1; peer[i].effective_weight = 1; peer[i].current_weight = 0; + peer[i].max_conns = 0; peer[i].max_fails = 1; peer[i].fail_timeout = 10; *peerp = &peer[i]; @@ -386,6 +392,7 @@ rrp->peers = peers; rrp->current = NULL; + rrp->config = 0; if (rrp->peers->number <= 8 * sizeof(uintptr_t)) { rrp->tried = &rrp->data; @@ -438,6 +445,10 @@ goto failed; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + goto failed; + } + rrp->current = peer; } else { @@ -491,12 +502,6 @@ ngx_stream_upstream_rr_peers_wlock(peers); } - /* all peers failed, mark them as live for quick recovery */ - - for (peer = peers->peer; peer; peer = peer->next) { - peer->fails = 0; - } - ngx_stream_upstream_rr_peers_unlock(peers); pc->name = peers->name; @@ -527,7 +532,6 @@ peer; peer = peer->next, i++) { - n = i / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); @@ -546,6 +550,10 @@ continue; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + continue; + } + peer->current_weight += peer->effective_weight; total += peer->effective_weight; | ||
[+] | Changed | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_upstream_round_robin.h ^ |
@@ -27,6 +27,7 @@ ngx_int_t weight; ngx_uint_t conns; + ngx_uint_t max_conns; ngx_uint_t fails; time_t accessed; @@ -34,19 +35,22 @@ ngx_uint_t max_fails; time_t fail_timeout; + ngx_msec_t slow_start; + ngx_msec_t start_time; - ngx_uint_t down; /* unsigned down:1; */ + ngx_uint_t down; -#if (NGX_STREAM_SSL) void *ssl_session; int ssl_session_len; -#endif - - ngx_stream_upstream_rr_peer_t *next; #if (NGX_STREAM_UPSTREAM_ZONE) ngx_atomic_t lock; #endif + + ngx_stream_upstream_rr_peer_t *next; + + NGX_COMPAT_BEGIN(25) + NGX_COMPAT_END }; @@ -119,6 +123,7 @@ typedef struct { + ngx_uint_t config; ngx_stream_upstream_rr_peers_t *peers; ngx_stream_upstream_rr_peer_t *current; uintptr_t *tried; | ||
[+] | Added | _service:download_url:nginx-1.11.5.tar.gz/src/stream/ngx_stream_write_filter_module.c ^ |
@@ -0,0 +1,273 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Nginx, Inc. + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_stream.h> + + +typedef struct { + ngx_chain_t *from_upstream; + ngx_chain_t *from_downstream; +} ngx_stream_write_filter_ctx_t; + + +static ngx_int_t ngx_stream_write_filter(ngx_stream_session_t *s, + ngx_chain_t *in, ngx_uint_t from_upstream); +static ngx_int_t ngx_stream_write_filter_init(ngx_conf_t *cf); + + +static ngx_stream_module_t ngx_stream_write_filter_module_ctx = { + NULL, /* preconfiguration */ + ngx_stream_write_filter_init, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL /* merge server configuration */ +}; + + +ngx_module_t ngx_stream_write_filter_module = { + NGX_MODULE_V1, + &ngx_stream_write_filter_module_ctx, /* module context */ + NULL, /* module directives */ + NGX_STREAM_MODULE, /* module type */ + NULL, /* init master */ + NULL, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ + NGX_MODULE_V1_PADDING +}; + + +static ngx_int_t +ngx_stream_write_filter(ngx_stream_session_t *s, ngx_chain_t *in, + ngx_uint_t from_upstream) +{ + off_t size; + ngx_uint_t last, flush, sync; + ngx_chain_t *cl, *ln, **ll, **out, *chain; + ngx_connection_t *c; + ngx_stream_write_filter_ctx_t *ctx; + + ctx = ngx_stream_get_module_ctx(s, ngx_stream_write_filter_module); + + if (ctx == NULL) { + ctx = ngx_pcalloc(s->connection->pool, + sizeof(ngx_stream_write_filter_ctx_t)); + if (ctx == NULL) { + return NGX_ERROR; + } + + ngx_stream_set_ctx(s, ctx, ngx_stream_write_filter_module); + } + + if (from_upstream) { + c = s->connection; + out = &ctx->from_upstream; + + } else { + c = s->upstream->peer.connection; + out = &ctx->from_downstream; + } + + if (c->error) { + return NGX_ERROR; + } + + size = 0; + flush = 0; + sync = 0; + last = 0; + ll = out; + + /* find the size, the flush point and the last link of the saved chain */ + + for (cl = *out; cl; cl = cl->next) { + ll = &cl->next; + + ngx_log_debug7(NGX_LOG_DEBUG_EVENT, c->log, 0, + "write old buf t:%d f:%d %p, pos %p, size: %z " + "file: %O, size: %O", + cl->buf->temporary, cl->buf->in_file, + cl->buf->start, cl->buf->pos, + cl->buf->last - cl->buf->pos, + cl->buf->file_pos, + cl->buf->file_last - cl->buf->file_pos); + +#if 1 + if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "zero size buf in writer " + "t:%d r:%d f:%d %p %p-%p %p %O-%O", + cl->buf->temporary, + cl->buf->recycled, + cl->buf->in_file, + cl->buf->start, + cl->buf->pos, + cl->buf->last, + cl->buf->file, + cl->buf->file_pos, + cl->buf->file_last); + + ngx_debug_point(); + return NGX_ERROR; + } +#endif + + size += ngx_buf_size(cl->buf); + + if (cl->buf->flush || cl->buf->recycled) { + flush = 1; + } + + if (cl->buf->sync) { + sync = 1; + } + + if (cl->buf->last_buf) { + last = 1; + } + } + + /* add the new chain to the existent one */ + + for (ln = in; ln; ln = ln->next) { + cl = ngx_alloc_chain_link(c->pool); + if (cl == NULL) { + return NGX_ERROR; + } + + cl->buf = ln->buf; + *ll = cl; + ll = &cl->next; + + ngx_log_debug7(NGX_LOG_DEBUG_EVENT, c->log, 0, + "write new buf t:%d f:%d %p, pos %p, size: %z " + "file: %O, size: %O", + cl->buf->temporary, cl->buf->in_file, + cl->buf->start, cl->buf->pos, + cl->buf->last - cl->buf->pos, + cl->buf->file_pos, + cl->buf->file_last - cl->buf->file_pos); + +#if 1 + if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "zero size buf in writer " + "t:%d r:%d f:%d %p %p-%p %p %O-%O", + cl->buf->temporary, + cl->buf->recycled, + cl->buf->in_file, + cl->buf->start, + cl->buf->pos, + cl->buf->last, + cl->buf->file, + cl->buf->file_pos, + cl->buf->file_last); + + ngx_debug_point(); + return NGX_ERROR; + } +#endif + + size += ngx_buf_size(cl->buf); + + if (cl->buf->flush || cl->buf->recycled) { + flush = 1; + } + + if (cl->buf->sync) { + sync = 1; + } + + if (cl->buf->last_buf) { + last = 1; + } + } + + *ll = NULL; + + ngx_log_debug3(NGX_LOG_DEBUG_STREAM, c->log, 0, + "stream write filter: l:%ui f:%ui s:%O", last, flush, size); + + if (size == 0 + && !(c->buffered & NGX_LOWLEVEL_BUFFERED) + && !(last && c->need_last_buf)) + { + if (last || flush || sync) { + for (cl = *out; cl; /* void */) { + ln = cl; + cl = cl->next; + ngx_free_chain(c->pool, ln); + } + + *out = NULL; + c->buffered &= ~NGX_STREAM_WRITE_BUFFERED; + + return NGX_OK; + } + + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "the stream output chain is empty"); + + ngx_debug_point(); + + return NGX_ERROR; + } + + chain = c->send_chain(c, *out, 0); + + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, + "stream write filter %p", chain); + + if (chain == NGX_CHAIN_ERROR) { + c->error = 1; + return NGX_ERROR; + } + + for (cl = *out; cl && cl != chain; /* void */) { + ln = cl; + cl = cl->next; + ngx_free_chain(c->pool, ln); + } + + *out = chain; + + if (chain) { + if (c->shared) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "shared connection is busy"); + return NGX_ERROR; + } + + c->buffered |= NGX_STREAM_WRITE_BUFFERED; + return NGX_AGAIN; + } + + c->buffered &= ~NGX_STREAM_WRITE_BUFFERED; + + if (c->buffered & NGX_LOWLEVEL_BUFFERED) { + return NGX_AGAIN; + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_stream_write_filter_init(ngx_conf_t *cf) +{ + ngx_stream_top_filter = ngx_stream_write_filter; + + return NGX_OK; +} |