# HG changeset patch # User Sergey Kandaurov # Date 1586882120 -10800 # Node ID 5b7ec588de4835539bc590e2db19f34cf9cebca3 # Parent 7bd334b8d91a6f32c2fd39f520fe92ea24069e8b# Parent 3a860f22c8791e66397213611b4f2192fce19df8 Merged with the default branch. diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -447,3 +447,5 @@ 9af0dddbddb2c368bfedd2801bc100ffad01e19b de68d0d94320cbf033599c6f3ca37e5335c67fd7 release-1.17.6 e56295fe0ea76bf53b06bffa77a2d3a9a335cb8c release-1.17.7 fdacd273711ddf20f778c1fb91529ab53979a454 release-1.17.8 +5e8d52bca714d4b85284ddb649d1ba4a3ca978a8 release-1.17.9 +c44970de01474f6f3e01b0adea85ec1d03e3a5f2 release-1.17.10 diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,96 @@ + + + + +директива auth_delay. + + +the "auth_delay" directive. + + + + + + + + + + +теперь nginx не разрешает +несколько строк "Host" в заголовке запроса. + + +now nginx does not allow +several "Host" request header lines. + + + + + +nginx игнорировал дополнительные +строки "Transfer-Encoding" в заголовке запроса. + + +nginx ignored additional +"Transfer-Encoding" request header lines. + + + + + +утечки сокетов при использовании HTTP/2. + + +socket leak when using HTTP/2. + + + + + +в рабочем процессе мог произойти segmentation fault, +если использовался OCSP stapling. + + +a segmentation fault might occur in a worker process +if OCSP stapling was used. + + + + + +в модуле ngx_http_mp4_module. + + +in the ngx_http_mp4_module. + + + + + +при перенаправлении ошибок с кодом 494 с помощью директивы error_page +nginx возвращал ответ с кодом 494 вместо 400. + + +nginx used status code 494 instead of 400 +if errors with code 494 were redirected with the "error_page" directive. + + + + + +утечки сокетов при использовании подзапросов в модуле njs и директивы aio. + + +socket leak when using subrequests in the njs module and the "aio" directive. + + + + + + diff --git a/misc/GNUmakefile b/misc/GNUmakefile --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -6,9 +6,9 @@ TEMP = tmp CC = cl OBJS = objs.msvc8 -OPENSSL = openssl-1.1.1d +OPENSSL = openssl-1.1.1f ZLIB = zlib-1.2.11 -PCRE = pcre-8.43 +PCRE = pcre-8.44 release: export diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1017009 -#define NGINX_VERSION "1.17.9" +#define nginx_version 1017010 +#define NGINX_VERSION "1.17.10" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD diff --git a/src/http/modules/ngx_http_auth_basic_module.c b/src/http/modules/ngx_http_auth_basic_module.c --- a/src/http/modules/ngx_http_auth_basic_module.c +++ b/src/http/modules/ngx_http_auth_basic_module.c @@ -25,7 +25,6 @@ static ngx_int_t ngx_http_auth_basic_cry ngx_str_t *passwd, ngx_str_t *realm); static ngx_int_t ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm); -static void ngx_http_auth_basic_close(ngx_file_t *file); static void *ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); @@ -177,8 +176,8 @@ ngx_http_auth_basic_handler(ngx_http_req offset); if (n == NGX_ERROR) { - ngx_http_auth_basic_close(&file); - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + goto cleanup; } if (n == 0) { @@ -219,12 +218,11 @@ ngx_http_auth_basic_handler(ngx_http_req if (buf[i] == LF || buf[i] == CR || buf[i] == ':') { buf[i] = '\0'; - ngx_http_auth_basic_close(&file); - pwd.len = i - passwd; pwd.data = &buf[passwd]; - return ngx_http_auth_basic_crypt_handler(r, &pwd, &realm); + rc = ngx_http_auth_basic_crypt_handler(r, &pwd, &realm); + goto cleanup; } break; @@ -251,8 +249,6 @@ ngx_http_auth_basic_handler(ngx_http_req offset += n; } - ngx_http_auth_basic_close(&file); - if (state == sw_passwd) { pwd.len = i - passwd; pwd.data = ngx_pnalloc(r->pool, pwd.len + 1); @@ -262,14 +258,26 @@ ngx_http_auth_basic_handler(ngx_http_req ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1); - return ngx_http_auth_basic_crypt_handler(r, &pwd, &realm); + rc = ngx_http_auth_basic_crypt_handler(r, &pwd, &realm); + goto cleanup; } ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "user \"%V\" was not found in \"%s\"", &r->headers_in.user, user_file.data); - return ngx_http_auth_basic_set_realm(r, &realm); + rc = ngx_http_auth_basic_set_realm(r, &realm); + +cleanup: + + if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, + ngx_close_file_n " \"%s\" failed", user_file.data); + } + + ngx_explicit_memzero(buf, NGX_HTTP_AUTH_BUF_SIZE); + + return rc; } @@ -338,15 +346,6 @@ ngx_http_auth_basic_set_realm(ngx_http_r return NGX_HTTP_UNAUTHORIZED; } -static void -ngx_http_auth_basic_close(ngx_file_t *file) -{ - if (ngx_close_file(file->fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, file->log, ngx_errno, - ngx_close_file_n " \"%s\" failed", file->name.data); - } -} - static void * ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf) diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -21,6 +21,9 @@ typedef struct { #define NGX_HTTP_REQUEST_BODY_FILE_CLEAN 2 +static ngx_int_t ngx_http_core_auth_delay(ngx_http_request_t *r); +static void ngx_http_core_auth_delay_handler(ngx_http_request_t *r); + static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r); static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r, ngx_http_location_tree_node_t *node); @@ -520,6 +523,13 @@ static ngx_command_t ngx_http_core_comm offsetof(ngx_http_core_loc_conf_t, satisfy), &ngx_http_core_satisfy }, + { ngx_string("auth_delay"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_msec_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_core_loc_conf_t, auth_delay), + NULL }, + { ngx_string("internal"), NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, ngx_http_core_internal, @@ -1124,6 +1134,10 @@ ngx_http_core_access_phase(ngx_http_requ /* rc == NGX_ERROR || rc == NGX_HTTP_... */ + if (rc == NGX_HTTP_UNAUTHORIZED) { + return ngx_http_core_auth_delay(r); + } + ngx_http_finalize_request(r, rc); return NGX_OK; } @@ -1141,12 +1155,17 @@ ngx_http_core_post_access_phase(ngx_http access_code = r->access_code; if (access_code) { + r->access_code = 0; + if (access_code == NGX_HTTP_FORBIDDEN) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "access forbidden by rule"); } - r->access_code = 0; + if (access_code == NGX_HTTP_UNAUTHORIZED) { + return ngx_http_core_auth_delay(r); + } + ngx_http_finalize_request(r, access_code); return NGX_OK; } @@ -1156,6 +1175,65 @@ ngx_http_core_post_access_phase(ngx_http } +static ngx_int_t +ngx_http_core_auth_delay(ngx_http_request_t *r) +{ + ngx_http_core_loc_conf_t *clcf; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->auth_delay == 0) { + ngx_http_finalize_request(r, NGX_HTTP_UNAUTHORIZED); + return NGX_OK; + } + + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "delaying unauthorized request"); + + if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + r->read_event_handler = ngx_http_test_reading; + r->write_event_handler = ngx_http_core_auth_delay_handler; + + r->connection->write->delayed = 1; + ngx_add_timer(r->connection->write, clcf->auth_delay); + + /* + * trigger an additional event loop iteration + * to ensure constant-time processing + */ + + ngx_post_event(r->connection->write, &ngx_posted_next_events); + + return NGX_OK; +} + + +static void +ngx_http_core_auth_delay_handler(ngx_http_request_t *r) +{ + ngx_event_t *wev; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "auth delay handler"); + + wev = r->connection->write; + + if (wev->delayed) { + + if (ngx_handle_write_event(wev, 0) != NGX_OK) { + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + } + + return; + } + + ngx_http_finalize_request(r, NGX_HTTP_UNAUTHORIZED); +} + + ngx_int_t ngx_http_core_content_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph) @@ -3394,6 +3472,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE; clcf->client_body_timeout = NGX_CONF_UNSET_MSEC; clcf->satisfy = NGX_CONF_UNSET_UINT; + clcf->auth_delay = NGX_CONF_UNSET_MSEC; clcf->if_modified_since = NGX_CONF_UNSET_UINT; clcf->max_ranges = NGX_CONF_UNSET_UINT; clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT; @@ -3609,6 +3688,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t |NGX_HTTP_KEEPALIVE_DISABLE_MSIE6)); ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy, NGX_HTTP_SATISFY_ALL); + ngx_conf_merge_msec_value(conf->auth_delay, prev->auth_delay, 0); ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since, NGX_HTTP_IMS_EXACT); ngx_conf_merge_uint_value(conf->max_ranges, prev->max_ranges, diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -367,6 +367,7 @@ struct ngx_http_core_loc_conf_s { ngx_msec_t lingering_time; /* lingering_time */ ngx_msec_t lingering_timeout; /* lingering_timeout */ ngx_msec_t resolver_timeout; /* resolver_timeout */ + ngx_msec_t auth_delay; /* auth_delay */ ngx_resolver_t *resolver; /* resolver */ diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -2630,10 +2630,24 @@ ngx_http_finalize_request(ngx_http_reque } if (r != r->main) { - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - if (r->background) { + + if (r->buffered || r->postponed) { + + if (ngx_http_set_write_handler(r) != NGX_OK) { + ngx_http_terminate_request(r, 0); + } + + return; + } + + pr = r->parent; + + if (r == c->data || r->background) { + if (!r->logged) { + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + if (clcf->log_subrequest) { ngx_http_log_request(r); } @@ -2647,40 +2661,14 @@ ngx_http_finalize_request(ngx_http_reque } r->done = 1; - ngx_http_finalize_connection(r); - return; - } - - if (r->buffered || r->postponed) { - - if (ngx_http_set_write_handler(r) != NGX_OK) { - ngx_http_terminate_request(r, 0); + + if (r->background) { + ngx_http_finalize_connection(r); + return; } - return; - } - - pr = r->parent; - - if (r == c->data) { - r->main->count--; - if (!r->logged) { - if (clcf->log_subrequest) { - ngx_http_log_request(r); - } - - r->logged = 1; - - } else { - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "subrequest: \"%V?%V\" logged again", - &r->uri, &r->args); - } - - r->done = 1; - if (pr->postponed && pr->postponed->request == r) { pr->postponed = pr->postponed->next; }