diff --git a/.hgtags b/.hgtags index da0a246d2..4dffd1a73 100644 --- a/.hgtags +++ b/.hgtags @@ -454,3 +454,5 @@ cbe6ba650211541310618849168631ce0b788f35 release-1.19.0 a7b46539f507e6c64efa0efda69ad60b6f4ffbce release-1.19.2 3cbc2602325f0ac08917a4397d76f5155c34b7b1 release-1.19.3 dc0cc425fa63a80315f6efb68697cadb6626cdf2 release-1.19.4 +8e5b068f761cd512d10c9671fbde0b568c1fd08b release-1.19.5 +f618488eb769e0ed74ef0d93cd118d2ad79ef94d release-1.19.6 diff --git a/auto/configure b/auto/configure index 7e6e33a7c..474d69e84 100755 --- a/auto/configure +++ b/auto/configure @@ -87,6 +87,10 @@ have=NGX_PID_PATH value="\"$NGX_PID_PATH\"" . auto/define have=NGX_LOCK_PATH value="\"$NGX_LOCK_PATH\"" . auto/define have=NGX_ERROR_LOG_PATH value="\"$NGX_ERROR_LOG_PATH\"" . auto/define +if [ ".$NGX_ERROR_LOG_PATH" = "." ]; then + have=NGX_ERROR_LOG_STDERR . auto/have +fi + have=NGX_HTTP_LOG_PATH value="\"$NGX_HTTP_LOG_PATH\"" . auto/define have=NGX_HTTP_CLIENT_TEMP_PATH value="\"$NGX_HTTP_CLIENT_TEMP_PATH\"" . auto/define diff --git a/auto/make b/auto/make index 136c0a64e..5d5848149 100644 --- a/auto/make +++ b/auto/make @@ -314,7 +314,7 @@ $ngx_obj: \$(CORE_DEPS) \$(HTTP_DEPS)$ngx_cont$ngx_src END fi - done + done fi @@ -344,7 +344,7 @@ $ngx_obj: \$(CORE_DEPS) \$(MAIL_DEPS)$ngx_cont$ngx_src $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX END - done + done fi @@ -374,7 +374,7 @@ $ngx_obj: \$(CORE_DEPS) \$(STREAM_DEPS)$ngx_cont$ngx_src $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX END - done + done fi @@ -400,7 +400,7 @@ $ngx_obj: \$(CORE_DEPS) $ngx_cont$ngx_src $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX END - done + done fi @@ -432,7 +432,7 @@ $ngx_obj: \$(ADDON_DEPS)$ngx_cont$ngx_src $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX END - done + done fi @@ -503,6 +503,7 @@ fi for ngx_module in $DYNAMIC_MODULES do eval ngx_module_srcs="\$${ngx_module}_SRCS" + eval ngx_module_shrd="\$${ngx_module}_SHRD" eval eval ngx_module_libs="\\\"\$${ngx_module}_LIBS\\\"" eval ngx_module_modules="\$${ngx_module}_MODULES" @@ -568,7 +569,7 @@ END | sed -e "s/\(.*\.\)c/\1$ngx_objext/"` ngx_module_objs= - for ngx_src in $ngx_module_srcs + for ngx_src in $ngx_module_srcs $ngx_module_shrd do case "$ngx_src" in src/*) diff --git a/auto/module b/auto/module index a2b578db2..3857d04ca 100644 --- a/auto/module +++ b/auto/module @@ -17,7 +17,6 @@ if [ "$ngx_module_link" = DYNAMIC ]; then done DYNAMIC_MODULES="$DYNAMIC_MODULES $ngx_module" - eval ${ngx_module}_SRCS=\"$ngx_module_srcs\" eval ${ngx_module}_MODULES=\"$ngx_module_name\" @@ -31,6 +30,30 @@ if [ "$ngx_module_link" = DYNAMIC ]; then eval ${ngx_module}_ORDER=\"$ngx_module_order\" fi + srcs= + shrd= + for src in $ngx_module_srcs + do + found=no + for old in $DYNAMIC_MODULES_SRCS + do + if [ $src = $old ]; then + found=yes + break + fi + done + + if [ $found = no ]; then + srcs="$srcs $src" + else + shrd="$shrd $src" + fi + done + eval ${ngx_module}_SRCS=\"$srcs\" + eval ${ngx_module}_SHRD=\"$shrd\" + + DYNAMIC_MODULES_SRCS="$DYNAMIC_MODULES_SRCS $srcs" + if test -n "$ngx_module_incs"; then CORE_INCS="$CORE_INCS $ngx_module_incs" fi @@ -107,7 +130,24 @@ elif [ "$ngx_module_link" = ADDON ]; then eval ${ngx_module_type}_MODULES=\"\$${ngx_module_type}_MODULES \ $ngx_module_name\" - NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_module_srcs" + srcs= + for src in $ngx_module_srcs + do + found=no + for old in $NGX_ADDON_SRCS + do + if [ $src = $old ]; then + found=yes + break + fi + done + + if [ $found = no ]; then + srcs="$srcs $src" + fi + done + + NGX_ADDON_SRCS="$NGX_ADDON_SRCS $srcs" if test -n "$ngx_module_incs"; then eval ${ngx_var}_INCS=\"\$${ngx_var}_INCS $ngx_module_incs\" diff --git a/auto/options b/auto/options index 08bf13924..14745abf2 100644 --- a/auto/options +++ b/auto/options @@ -134,8 +134,10 @@ STREAM_UPSTREAM_ZONE=YES STREAM_SSL_PREREAD=NO DYNAMIC_MODULES= +DYNAMIC_MODULES_SRCS= NGX_ADDONS= +NGX_ADDON_SRCS= NGX_ADDON_DEPS= DYNAMIC_ADDONS= diff --git a/docs/man/nginx.8 b/docs/man/nginx.8 index 573d935e6..10db3e6cb 100644 --- a/docs/man/nginx.8 +++ b/docs/man/nginx.8 @@ -25,7 +25,7 @@ .\" SUCH DAMAGE. .\" .\" -.Dd December 5, 2019 +.Dd November 5, 2020 .Dt NGINX 8 .Os .Sh NAME @@ -35,6 +35,7 @@ .Nm .Op Fl ?hqTtVv .Op Fl c Ar file +.Op Fl e Ar file .Op Fl g Ar directives .Op Fl p Ar prefix .Op Fl s Ar signal @@ -54,6 +55,12 @@ Print help. .It Fl c Ar file Use an alternative configuration .Ar file . +.It Fl e Ar file +Use an alternative error log +.Ar file . +Special value +.Cm stderr +indicates that the standard error output should be used. .It Fl g Ar directives Set global configuration directives. See @@ -198,10 +205,10 @@ Development of started in 2002, with the first public release on October 4, 2004. .Sh AUTHORS .An -nosplit -.An Igor Sysoev Aq igor@sysoev.ru . +.An Igor Sysoev Aq Mt igor@sysoev.ru . .Pp This manual page was originally written by -.An Sergey A. Osokin Aq osa@FreeBSD.org.ru +.An Sergey A. Osokin Aq Mt osa@FreeBSD.org.ru as a result of compiling many .Nm documents from all over the world. diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml index a7417f59c..3d5666711 100644 --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,111 @@ + + + + +ошибки "no live upstreams", +если server в блоке upstream был помечен как down. + + +"no live upstreams" errors +if a "server" inside "upstream" block was marked as "down". + + + + + +при использовании HTTPS в рабочем процессе мог произойти segmentation fault; +ошибка появилась в 1.19.5. + + +a segmentation fault might occur in a worker process if HTTPS was used; +the bug had appeared in 1.19.5. + + + + + +nginx возвращал ошибку 400 на запросы вида +"GET http://example.com?args HTTP/1.0". + + +nginx returned the 400 response on requests like +"GET http://example.com?args HTTP/1.0". + + + + + +в модулях ngx_http_flv_module и ngx_http_mp4_module.
+Спасибо Chris Newton. +
+ +in the ngx_http_flv_module and ngx_http_mp4_module.
+Thanks to Chris Newton. +
+
+ +
+ + + + + + +ключ -e. + + +the -e switch. + + + + + +при сборке дополнительных модулей +теперь можно указывать одни и те же исходные файлы в разных модулях. + + +the same source files can now be specified in different modules +while building addon modules. + + + + + +SSL shutdown не работал +при закрытии соединений с ожиданием дополнительных данных (lingering close). + + +SSL shutdown did not work +when lingering close was used. + + + + + +при работе с gRPC-бэкендами +могли возникать ошибки "upstream sent frame for closed stream". + + +"upstream sent frame for closed stream" errors might occur +when working with gRPC backends. + + + + + +во внутреннем API для обработки тела запроса. + + +in request body filters internal API. + + + + + + diff --git a/misc/GNUmakefile b/misc/GNUmakefile index 80eb9b929..5c7550558 100644 --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -6,7 +6,7 @@ TEMP = tmp CC = cl OBJS = objs.msvc8 -OPENSSL = openssl-1.1.1h +OPENSSL = openssl-1.1.1i ZLIB = zlib-1.2.11 PCRE = pcre-8.44 diff --git a/src/core/nginx.c b/src/core/nginx.c index f73e5598e..48a20e9fd 100644 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -183,6 +183,7 @@ static ngx_uint_t ngx_show_help; static ngx_uint_t ngx_show_version; static ngx_uint_t ngx_show_configure; static u_char *ngx_prefix; +static u_char *ngx_error_log; static u_char *ngx_conf_file; static u_char *ngx_conf_params; static char *ngx_signal; @@ -230,7 +231,7 @@ main(int argc, char *const *argv) ngx_pid = ngx_getpid(); ngx_parent = ngx_getppid(); - log = ngx_log_init(ngx_prefix); + log = ngx_log_init(ngx_prefix, ngx_error_log); if (log == NULL) { return 1; } @@ -393,9 +394,9 @@ ngx_show_version_info(void) if (ngx_show_help) { ngx_write_stderr( - "Usage: nginx [-?hvVtTq] [-s signal] [-c filename] " - "[-p prefix] [-g directives]" NGX_LINEFEED - NGX_LINEFEED + "Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]" NGX_LINEFEED + " [-e filename] [-c filename] [-g directives]" + NGX_LINEFEED NGX_LINEFEED "Options:" NGX_LINEFEED " -?,-h : this help" NGX_LINEFEED " -v : show version and exit" NGX_LINEFEED @@ -413,6 +414,12 @@ ngx_show_version_info(void) NGX_LINEFEED #else " -p prefix : set prefix path (default: NONE)" NGX_LINEFEED +#endif + " -e filename : set error log file (default: " +#ifdef NGX_ERROR_LOG_STDERR + "stderr)" NGX_LINEFEED +#else + NGX_ERROR_LOG_PATH ")" NGX_LINEFEED #endif " -c filename : set configuration file (default: " NGX_CONF_PATH ")" NGX_LINEFEED @@ -800,6 +807,24 @@ ngx_get_options(int argc, char *const *argv) ngx_log_stderr(0, "option \"-p\" requires directory name"); return NGX_ERROR; + case 'e': + if (*p) { + ngx_error_log = p; + + } else if (argv[++i]) { + ngx_error_log = (u_char *) argv[i]; + + } else { + ngx_log_stderr(0, "option \"-e\" requires file name"); + return NGX_ERROR; + } + + if (ngx_strcmp(ngx_error_log, "stderr") == 0) { + ngx_error_log = (u_char *) ""; + } + + goto next; + case 'c': if (*p) { ngx_conf_file = p; @@ -992,6 +1017,14 @@ ngx_process_options(ngx_cycle_t *cycle) } } + if (ngx_error_log) { + cycle->error_log.len = ngx_strlen(ngx_error_log); + cycle->error_log.data = ngx_error_log; + + } else { + ngx_str_set(&cycle->error_log, NGX_ERROR_LOG_PATH); + } + if (ngx_conf_params) { cycle->conf_param.len = ngx_strlen(ngx_conf_params); cycle->conf_param.data = ngx_conf_params; diff --git a/src/core/nginx.h b/src/core/nginx.h index f92742eff..e915be3e7 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1019004 -#define NGINX_VERSION "1.19.4" +#define nginx_version 1019006 +#define NGINX_VERSION "1.19.6" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c index d7479fa41..6978c3e43 100644 --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -96,6 +96,15 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) return NULL; } + cycle->error_log.len = old_cycle->error_log.len; + cycle->error_log.data = ngx_pnalloc(pool, old_cycle->error_log.len + 1); + if (cycle->error_log.data == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + ngx_cpystrn(cycle->error_log.data, old_cycle->error_log.data, + old_cycle->error_log.len + 1); + cycle->conf_file.len = old_cycle->conf_file.len; cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1); if (cycle->conf_file.data == NULL) { diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h index 0f7d9bc74..0c47f25fe 100644 --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -80,6 +80,7 @@ struct ngx_cycle_s { ngx_str_t conf_param; ngx_str_t conf_prefix; ngx_str_t prefix; + ngx_str_t error_log; ngx_str_t lock_file; ngx_str_t hostname; }; diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c index 8e9408df0..0c094265e 100644 --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -315,7 +315,7 @@ ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err) ngx_log_t * -ngx_log_init(u_char *prefix) +ngx_log_init(u_char *prefix, u_char *error_log) { u_char *p, *name; size_t nlen, plen; @@ -323,13 +323,11 @@ ngx_log_init(u_char *prefix) ngx_log.file = &ngx_log_file; ngx_log.log_level = NGX_LOG_NOTICE; - name = (u_char *) NGX_ERROR_LOG_PATH; - - /* - * we use ngx_strlen() here since BCC warns about - * condition is always false and unreachable code - */ + if (error_log == NULL) { + error_log = (u_char *) NGX_ERROR_LOG_PATH; + } + name = error_log; nlen = ngx_strlen(name); if (nlen == 0) { @@ -369,7 +367,7 @@ ngx_log_init(u_char *prefix) *p++ = '/'; } - ngx_cpystrn(p, (u_char *) NGX_ERROR_LOG_PATH, nlen + 1); + ngx_cpystrn(p, error_log, nlen + 1); p = name; } @@ -403,8 +401,7 @@ ngx_log_init(u_char *prefix) ngx_int_t ngx_log_open_default(ngx_cycle_t *cycle) { - ngx_log_t *log; - static ngx_str_t error_log = ngx_string(NGX_ERROR_LOG_PATH); + ngx_log_t *log; if (ngx_log_get_file_log(&cycle->new_log) != NULL) { return NGX_OK; @@ -425,7 +422,7 @@ ngx_log_open_default(ngx_cycle_t *cycle) log->log_level = NGX_LOG_ERR; - log->file = ngx_conf_open_file(cycle, &error_log); + log->file = ngx_conf_open_file(cycle, &cycle->error_log); if (log->file == NULL) { return NGX_ERROR; } diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h index afb73bf71..ab64a5ad0 100644 --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -228,7 +228,7 @@ void ngx_cdecl ngx_log_debug_core(ngx_log_t *log, ngx_err_t err, /*********************************/ -ngx_log_t *ngx_log_init(u_char *prefix); +ngx_log_t *ngx_log_init(u_char *prefix, u_char *error_log); void ngx_cdecl ngx_log_abort(ngx_err_t err, const char *fmt, ...); void ngx_cdecl ngx_log_stderr(ngx_err_t err, const char *fmt, ...); u_char *ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err); diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c index 468e9600c..93f32ea0c 100644 --- a/src/core/ngx_string.c +++ b/src/core/ngx_string.c @@ -11,6 +11,8 @@ static u_char *ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64, u_char zero, ngx_uint_t hexadecimal, ngx_uint_t width); +static u_char *ngx_sprintf_str(u_char *buf, u_char *last, u_char *src, + size_t len, ngx_uint_t hexadecimal); static void ngx_encode_base64_internal(ngx_str_t *dst, ngx_str_t *src, const u_char *basis, ngx_uint_t padding); static ngx_int_t ngx_decode_base64_internal(ngx_str_t *dst, ngx_str_t *src, @@ -101,10 +103,10 @@ ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src) * %M ngx_msec_t * %r rlim_t * %p void * - * %V ngx_str_t * - * %v ngx_variable_value_t * - * %s null-terminated string - * %*s length and string + * %[x|X]V ngx_str_t * + * %[x|X]v ngx_variable_value_t * + * %[x|X]s null-terminated string + * %*[x|X]s length and string * %Z '\0' * %N '\n' * %c char @@ -165,7 +167,7 @@ ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args) u_char *p, zero; int d; double f; - size_t len, slen; + size_t slen; int64_t i64; uint64_t ui64, frac; ngx_msec_t ms; @@ -250,8 +252,7 @@ ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args) case 'V': v = va_arg(args, ngx_str_t *); - len = ngx_min(((size_t) (last - buf)), v->len); - buf = ngx_cpymem(buf, v->data, len); + buf = ngx_sprintf_str(buf, last, v->data, v->len, hex); fmt++; continue; @@ -259,8 +260,7 @@ ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args) case 'v': vv = va_arg(args, ngx_variable_value_t *); - len = ngx_min(((size_t) (last - buf)), vv->len); - buf = ngx_cpymem(buf, vv->data, len); + buf = ngx_sprintf_str(buf, last, vv->data, vv->len, hex); fmt++; continue; @@ -268,16 +268,7 @@ ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args) case 's': p = va_arg(args, u_char *); - if (slen == (size_t) -1) { - while (*p && buf < last) { - *buf++ = *p++; - } - - } else { - len = ngx_min(((size_t) (last - buf)), slen); - buf = ngx_cpymem(buf, p, len); - } - + buf = ngx_sprintf_str(buf, last, p, slen, hex); fmt++; continue; @@ -576,6 +567,64 @@ ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64, u_char zero, } +static u_char * +ngx_sprintf_str(u_char *buf, u_char *last, u_char *src, size_t len, + ngx_uint_t hexadecimal) +{ + static u_char hex[] = "0123456789abcdef"; + static u_char HEX[] = "0123456789ABCDEF"; + + if (hexadecimal == 0) { + + if (len == (size_t) -1) { + while (*src && buf < last) { + *buf++ = *src++; + } + + } else { + len = ngx_min((size_t) (last - buf), len); + buf = ngx_cpymem(buf, src, len); + } + + } else if (hexadecimal == 1) { + + if (len == (size_t) -1) { + + while (*src && buf < last - 1) { + *buf++ = hex[*src >> 4]; + *buf++ = hex[*src++ & 0xf]; + } + + } else { + + while (len-- && buf < last - 1) { + *buf++ = hex[*src >> 4]; + *buf++ = hex[*src++ & 0xf]; + } + } + + } else { /* hexadecimal == 2 */ + + if (len == (size_t) -1) { + + while (*src && buf < last - 1) { + *buf++ = HEX[*src >> 4]; + *buf++ = HEX[*src++ & 0xf]; + } + + } else { + + while (len-- && buf < last - 1) { + *buf++ = HEX[*src >> 4]; + *buf++ = HEX[*src++ & 0xf]; + } + } + } + + return buf; +} + + /* * We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII strings only, * and implement our own ngx_strcasecmp()/ngx_strncasecmp() diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 0fc7ec54e..3cd31cfda 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -2921,6 +2921,7 @@ ngx_ssl_shutdown(ngx_connection_t *c) SSL_free(c->ssl->connection); c->ssl = NULL; + c->recv = ngx_recv; return NGX_OK; } @@ -2966,6 +2967,7 @@ ngx_ssl_shutdown(ngx_connection_t *c) if (n == 1) { SSL_free(c->ssl->connection); c->ssl = NULL; + c->recv = ngx_recv; return NGX_OK; } @@ -3008,6 +3010,7 @@ ngx_ssl_shutdown(ngx_connection_t *c) if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { SSL_free(c->ssl->connection); c->ssl = NULL; + c->recv = ngx_recv; return NGX_OK; } @@ -3018,6 +3021,7 @@ ngx_ssl_shutdown(ngx_connection_t *c) SSL_free(c->ssl->connection); c->ssl = NULL; + c->recv = ngx_recv; return NGX_ERROR; } @@ -4098,9 +4102,6 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_ticket_key_t *key; const EVP_MD *digest; const EVP_CIPHER *cipher; -#if (NGX_DEBUG) - u_char buf[32]; -#endif c = ngx_ssl_get_connection(ssl_conn); ssl_ctx = c->ssl->session_ctx; @@ -4122,8 +4123,8 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, /* encrypt session ticket */ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "ssl session ticket encrypt, key: \"%*s\" (%s session)", - ngx_hex_dump(buf, key[0].name, 16) - buf, buf, + "ssl session ticket encrypt, key: \"%*xs\" (%s session)", + (size_t) 16, key[0].name, SSL_session_reused(ssl_conn) ? "reused" : "new"); if (key[0].size == 48) { @@ -4169,17 +4170,16 @@ ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "ssl session ticket decrypt, key: \"%*s\" not found", - ngx_hex_dump(buf, name, 16) - buf, buf); + "ssl session ticket decrypt, key: \"%*xs\" not found", + (size_t) 16, name); return 0; found: ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "ssl session ticket decrypt, key: \"%*s\"%s", - ngx_hex_dump(buf, key[i].name, 16) - buf, buf, - (i == 0) ? " (default)" : ""); + "ssl session ticket decrypt, key: \"%*xs\"%s", + (size_t) 16, key[i].name, (i == 0) ? " (default)" : ""); if (key[i].size == 48) { cipher = EVP_aes_128_cbc(); diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c index fee27ea89..8740ce3c0 100644 --- a/src/event/ngx_event_openssl_stapling.c +++ b/src/event/ngx_event_openssl_stapling.c @@ -2662,16 +2662,8 @@ ngx_ssl_ocsp_create_key(ngx_ssl_ocsp_ctx_t *ctx) p = ngx_cpymem(p, serial->data, serial->length); ngx_memzero(p, 20 - serial->length); -#if (NGX_DEBUG) - { - u_char buf[120]; - - ngx_hex_dump(buf, ctx->key.data, ctx->key.len); - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0, - "ssl ocsp key %*s", sizeof(buf), buf); - } -#endif + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ctx->log, 0, + "ssl ocsp key %xV", &ctx->key); return NGX_OK; } diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c index 7b72fae03..cc06d538a 100644 --- a/src/http/modules/ngx_http_flv_module.c +++ b/src/http/modules/ngx_http_flv_module.c @@ -156,12 +156,6 @@ ngx_http_flv_handler(ngx_http_request_t *r) } if (!of.is_file) { - - if (ngx_close_file(of.fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - ngx_close_file_n " \"%s\" failed", path.data); - } - return NGX_DECLINED; } diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c index 7e14af8d9..aa7576561 100644 --- a/src/http/modules/ngx_http_grpc_module.c +++ b/src/http/modules/ngx_http_grpc_module.c @@ -1141,20 +1141,11 @@ ngx_http_grpc_create_request(ngx_http_request_t *r) f->flags |= NGX_HTTP_V2_END_HEADERS_FLAG; -#if (NGX_DEBUG) - if (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP) { - u_char buf[512]; - size_t n, m; - - n = ngx_min(b->last - b->pos, 256); - m = ngx_hex_dump(buf, b->pos, n) - buf; - - ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "grpc header: %*s%s, len: %uz", - m, buf, b->last - b->pos > 256 ? "..." : "", - b->last - b->pos); - } -#endif + ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "grpc header: %*xs%s, len: %uz", + (size_t) ngx_min(b->last - b->pos, 256), b->pos, + b->last - b->pos > 256 ? "..." : "", + b->last - b->pos); if (r->request_body_no_buffering) { @@ -1604,20 +1595,11 @@ ngx_http_grpc_process_header(ngx_http_request_t *r) u = r->upstream; b = &u->buffer; -#if (NGX_DEBUG) - if (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP) { - u_char buf[512]; - size_t n, m; - - n = ngx_min(b->last - b->pos, 256); - m = ngx_hex_dump(buf, b->pos, n) - buf; - - ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "grpc response: %*s%s, len: %uz", - m, buf, b->last - b->pos > 256 ? "..." : "", - b->last - b->pos); - } -#endif + ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "grpc response: %*xs%s, len: %uz", + (size_t) ngx_min(b->last - b->pos, 256), + b->pos, b->last - b->pos > 256 ? "..." : "", + b->last - b->pos); ctx = ngx_http_grpc_get_ctx(r); @@ -1987,6 +1969,7 @@ ngx_http_grpc_filter_init(void *data) } u->length = 0; + ctx->done = 1; } else { u->length = 1; diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c index c1006abbb..0e93fbd09 100644 --- a/src/http/modules/ngx_http_mp4_module.c +++ b/src/http/modules/ngx_http_mp4_module.c @@ -521,12 +521,6 @@ ngx_http_mp4_handler(ngx_http_request_t *r) } if (!of.is_file) { - - if (ngx_close_file(of.fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - ngx_close_file_n " \"%s\" failed", path.data); - } - return NGX_DECLINED; } diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c index cfc42f9dd..20ad89a77 100644 --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -380,6 +380,12 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b) r->uri_start = p; state = sw_after_slash_in_uri; break; + case '?': + r->uri_start = p; + r->args_start = p + 1; + r->empty_path_in_uri = 1; + state = sw_uri; + break; case ' ': /* * use single "/" from request line to preserve pointers, @@ -446,6 +452,13 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b) r->uri_start = p; state = sw_after_slash_in_uri; break; + case '?': + r->port_end = p; + r->uri_start = p; + r->args_start = p + 1; + r->empty_path_in_uri = 1; + state = sw_uri; + break; case ' ': r->port_end = p; /* @@ -1287,6 +1300,10 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes) r->uri_ext = NULL; r->args_start = NULL; + if (r->empty_path_in_uri) { + *u++ = '/'; + } + ch = *p++; while (p <= r->uri_end) { diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 12982460b..348a8a21b 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -49,7 +49,7 @@ static void ngx_http_request_finalizer(ngx_http_request_t *r); static void ngx_http_set_keepalive(ngx_http_request_t *r); static void ngx_http_keepalive_handler(ngx_event_t *ev); -static void ngx_http_set_lingering_close(ngx_http_request_t *r); +static void ngx_http_set_lingering_close(ngx_connection_t *c); static void ngx_http_lingering_close_handler(ngx_event_t *ev); static ngx_int_t ngx_http_post_action(ngx_http_request_t *r); static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error); @@ -1328,9 +1328,13 @@ ngx_http_process_request_uri(ngx_http_request_t *r) r->uri.len = r->uri_end - r->uri_start; } - if (r->complex_uri || r->quoted_uri) { + if (r->complex_uri || r->quoted_uri || r->empty_path_in_uri) { - r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1); + if (r->empty_path_in_uri) { + r->uri.len++; + } + + r->uri.data = ngx_pnalloc(r->pool, r->uri.len); if (r->uri.data == NULL) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_ERROR; @@ -1354,7 +1358,7 @@ ngx_http_process_request_uri(ngx_http_request_t *r) r->unparsed_uri.len = r->uri_end - r->uri_start; r->unparsed_uri.data = r->uri_start; - r->valid_unparsed_uri = r->space_in_uri ? 0 : 1; + r->valid_unparsed_uri = (r->space_in_uri || r->empty_path_in_uri) ? 0 : 1; if (r->uri_ext) { if (r->args_start) { @@ -2865,7 +2869,7 @@ ngx_http_finalize_connection(ngx_http_request_t *r) || r->header_in->pos < r->header_in->last || r->connection->read->ready))) { - ngx_http_set_lingering_close(r); + ngx_http_set_lingering_close(r->connection); return; } @@ -3163,13 +3167,6 @@ ngx_http_set_keepalive(ngx_http_request_t *r) ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler"); - if (r->discard_body) { - r->write_event_handler = ngx_http_request_empty_handler; - r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000); - ngx_add_timer(rev, clcf->lingering_timeout); - return; - } - c->log->action = "closing request"; hc = r->http_connection; @@ -3499,22 +3496,41 @@ ngx_http_keepalive_handler(ngx_event_t *rev) static void -ngx_http_set_lingering_close(ngx_http_request_t *r) +ngx_http_set_lingering_close(ngx_connection_t *c) { ngx_event_t *rev, *wev; - ngx_connection_t *c; + ngx_http_request_t *r; ngx_http_core_loc_conf_t *clcf; - c = r->connection; + r = c->data; clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + if (r->lingering_time == 0) { + r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000); + } + +#if (NGX_HTTP_SSL) + if (c->ssl) { + ngx_int_t rc; + + rc = ngx_ssl_shutdown(c); + + if (rc == NGX_ERROR) { + ngx_http_close_request(r, 0); + return; + } + + if (rc == NGX_AGAIN) { + c->ssl->handler = ngx_http_set_lingering_close; + return; + } + } +#endif + rev = c->read; rev->handler = ngx_http_lingering_close_handler; - r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000); - ngx_add_timer(rev, clcf->lingering_timeout); - if (ngx_handle_read_event(rev, 0) != NGX_OK) { ngx_http_close_request(r, 0); return; @@ -3537,6 +3553,8 @@ ngx_http_set_lingering_close(ngx_http_request_t *r) return; } + ngx_add_timer(rev, clcf->lingering_timeout); + if (rev->ready) { ngx_http_lingering_close_handler(rev); } diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index e44daa061..52b274a62 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -473,6 +473,9 @@ struct ngx_http_request_s { /* URI with " " */ unsigned space_in_uri:1; + /* URI with empty path */ + unsigned empty_path_in_uri:1; + unsigned invalid_header:1; unsigned add_uri_to_alias:1; diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c index f1cfedfd3..c6f03aa74 100644 --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -144,8 +144,9 @@ ngx_http_read_client_request_body(ngx_http_request_t *r, } else { /* set rb->rest */ - if (ngx_http_request_body_filter(r, NULL) != NGX_OK) { - rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = ngx_http_request_body_filter(r, NULL); + + if (rc != NGX_OK) { goto done; } } @@ -324,6 +325,9 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r) return NGX_AGAIN; } + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "busy buffers after request body flush"); + return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -700,6 +704,7 @@ ngx_http_discarded_request_body_handler(ngx_http_request_t *r) if (rc == NGX_OK) { r->discard_body = 0; r->lingering_close = 0; + r->lingering_time = 0; ngx_http_finalize_request(r, NGX_DONE); return; } diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c index 8e7b4ea8b..1f15fae50 100644 --- a/src/http/ngx_http_upstream_round_robin.c +++ b/src/http/ngx_http_upstream_round_robin.c @@ -10,8 +10,8 @@ #include -#define ngx_http_upstream_tries(p) ((p)->number \ - + ((p)->next ? (p)->next->number : 0)) +#define ngx_http_upstream_tries(p) ((p)->tries \ + + ((p)->next ? (p)->next->tries : 0)) static ngx_http_upstream_rr_peer_t *ngx_http_upstream_get_peer( @@ -32,7 +32,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) { ngx_url_t u; - ngx_uint_t i, j, n, w; + ngx_uint_t i, j, n, w, t; ngx_http_upstream_server_t *server; ngx_http_upstream_rr_peer_t *peer, **peerp; ngx_http_upstream_rr_peers_t *peers, *backup; @@ -44,6 +44,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, n = 0; w = 0; + t = 0; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { @@ -52,6 +53,10 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, n += server[i].naddrs; w += server[i].naddrs * server[i].weight; + + if (!server[i].down) { + t += server[i].naddrs; + } } if (n == 0) { @@ -75,6 +80,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, peers->number = n; peers->weighted = (w != n); peers->total_weight = w; + peers->tries = t; peers->name = &us->host; n = 0; @@ -110,6 +116,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, n = 0; w = 0; + t = 0; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { @@ -118,6 +125,10 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, n += server[i].naddrs; w += server[i].naddrs * server[i].weight; + + if (!server[i].down) { + t += server[i].naddrs; + } } if (n == 0) { @@ -139,6 +150,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, backup->number = n; backup->weighted = (w != n); backup->total_weight = w; + backup->tries = t; backup->name = &us->host; n = 0; @@ -214,6 +226,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, peers->number = n; peers->weighted = 0; peers->total_weight = n; + peers->tries = n; peers->name = &us->host; peerp = &peers->peer; @@ -332,6 +345,7 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r, peers->single = (ur->naddrs == 1); peers->number = ur->naddrs; + peers->tries = ur->naddrs; peers->name = &ur->host; if (ur->sockaddr) { diff --git a/src/http/ngx_http_upstream_round_robin.h b/src/http/ngx_http_upstream_round_robin.h index 45f258d28..922ceaa04 100644 --- a/src/http/ngx_http_upstream_round_robin.h +++ b/src/http/ngx_http_upstream_round_robin.h @@ -68,6 +68,7 @@ struct ngx_http_upstream_rr_peers_s { #endif ngx_uint_t total_weight; + ngx_uint_t tries; unsigned single:1; unsigned weighted:1; diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c index 5fdbe3832..49085a554 100644 --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -60,7 +60,7 @@ typedef struct { static void ngx_http_v2_read_handler(ngx_event_t *rev); static void ngx_http_v2_write_handler(ngx_event_t *wev); static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c); -static void ngx_http_v2_lingering_close(ngx_http_v2_connection_t *h2c); +static void ngx_http_v2_lingering_close(ngx_connection_t *c); static void ngx_http_v2_lingering_close_handler(ngx_event_t *rev); static u_char *ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c, @@ -666,7 +666,7 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c) } if (h2c->goaway) { - ngx_http_v2_lingering_close(h2c); + ngx_http_v2_lingering_close(c); return; } @@ -705,13 +705,13 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c) static void -ngx_http_v2_lingering_close(ngx_http_v2_connection_t *h2c) +ngx_http_v2_lingering_close(ngx_connection_t *c) { ngx_event_t *rev, *wev; - ngx_connection_t *c; + ngx_http_v2_connection_t *h2c; ngx_http_core_loc_conf_t *clcf; - c = h2c->connection; + h2c = c->data; clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx, ngx_http_core_module); @@ -721,12 +721,32 @@ ngx_http_v2_lingering_close(ngx_http_v2_connection_t *h2c) return; } + if (h2c->lingering_time == 0) { + h2c->lingering_time = ngx_time() + + (time_t) (clcf->lingering_time / 1000); + } + +#if (NGX_HTTP_SSL) + if (c->ssl) { + ngx_int_t rc; + + rc = ngx_ssl_shutdown(c); + + if (rc == NGX_ERROR) { + ngx_http_close_connection(c); + return; + } + + if (rc == NGX_AGAIN) { + c->ssl->handler = ngx_http_v2_lingering_close; + return; + } + } +#endif + rev = c->read; rev->handler = ngx_http_v2_lingering_close_handler; - h2c->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000); - ngx_add_timer(rev, clcf->lingering_timeout); - if (ngx_handle_read_event(rev, 0) != NGX_OK) { ngx_http_close_connection(c); return; @@ -749,6 +769,8 @@ ngx_http_v2_lingering_close(ngx_http_v2_connection_t *h2c) return; } + ngx_add_timer(rev, clcf->lingering_timeout); + if (rev->ready) { ngx_http_v2_lingering_close_handler(rev); } @@ -4767,7 +4789,7 @@ ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c, return; } - ngx_http_v2_lingering_close(h2c); + ngx_http_v2_lingering_close(c); } diff --git a/src/stream/ngx_stream_upstream_round_robin.c b/src/stream/ngx_stream_upstream_round_robin.c index c2076673a..ae3bf37a6 100644 --- a/src/stream/ngx_stream_upstream_round_robin.c +++ b/src/stream/ngx_stream_upstream_round_robin.c @@ -10,8 +10,8 @@ #include -#define ngx_stream_upstream_tries(p) ((p)->number \ - + ((p)->next ? (p)->next->number : 0)) +#define ngx_stream_upstream_tries(p) ((p)->tries \ + + ((p)->next ? (p)->next->tries : 0)) static ngx_stream_upstream_rr_peer_t *ngx_stream_upstream_get_peer( @@ -38,7 +38,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, ngx_stream_upstream_srv_conf_t *us) { ngx_url_t u; - ngx_uint_t i, j, n, w; + ngx_uint_t i, j, n, w, t; ngx_stream_upstream_server_t *server; ngx_stream_upstream_rr_peer_t *peer, **peerp; ngx_stream_upstream_rr_peers_t *peers, *backup; @@ -50,6 +50,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, n = 0; w = 0; + t = 0; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { @@ -58,6 +59,10 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, n += server[i].naddrs; w += server[i].naddrs * server[i].weight; + + if (!server[i].down) { + t += server[i].naddrs; + } } if (n == 0) { @@ -81,6 +86,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, peers->number = n; peers->weighted = (w != n); peers->total_weight = w; + peers->tries = t; peers->name = &us->host; n = 0; @@ -116,6 +122,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, n = 0; w = 0; + t = 0; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { @@ -124,6 +131,10 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, n += server[i].naddrs; w += server[i].naddrs * server[i].weight; + + if (!server[i].down) { + t += server[i].naddrs; + } } if (n == 0) { @@ -145,6 +156,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, backup->number = n; backup->weighted = (w != n); backup->total_weight = w; + backup->tries = t; backup->name = &us->host; n = 0; @@ -220,6 +232,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, peers->number = n; peers->weighted = 0; peers->total_weight = n; + peers->tries = n; peers->name = &us->host; peerp = &peers->peer; @@ -342,6 +355,7 @@ ngx_stream_upstream_create_round_robin_peer(ngx_stream_session_t *s, peers->single = (ur->naddrs == 1); peers->number = ur->naddrs; + peers->tries = ur->naddrs; peers->name = &ur->host; if (ur->sockaddr) { diff --git a/src/stream/ngx_stream_upstream_round_robin.h b/src/stream/ngx_stream_upstream_round_robin.h index 35d9fce6c..bd96667ba 100644 --- a/src/stream/ngx_stream_upstream_round_robin.h +++ b/src/stream/ngx_stream_upstream_round_robin.h @@ -66,6 +66,7 @@ struct ngx_stream_upstream_rr_peers_s { #endif ngx_uint_t total_weight; + ngx_uint_t tries; unsigned single:1; unsigned weighted:1;