From 1d1103eacbfdb53f7debf003b51a8a15cacd2a44 Mon Sep 17 00:00:00 2001 From: Hakase Date: Wed, 25 Dec 2019 00:35:18 +0900 Subject: [PATCH] Release - v1.17.7 --- .hgtags | 1 + docs/man/nginx.8 | 15 ++-- docs/xml/nginx/changes.xml | 84 ++++++++++++++++++++++ src/event/ngx_event.c | 3 +- src/event/ngx_event_openssl.c | 31 -------- src/event/ngx_event_openssl.h | 1 - src/event/ngx_event_posted.c | 26 +++++++ src/event/ngx_event_posted.h | 1 + src/http/modules/ngx_http_dav_module.c | 38 +++------- src/http/modules/ngx_http_index_module.c | 2 +- src/http/modules/ngx_http_rewrite_module.c | 5 ++ src/http/modules/ngx_http_static_module.c | 4 +- src/http/ngx_http_core_module.c | 3 +- src/http/ngx_http_script.c | 9 ++- src/http/ngx_http_special_response.c | 6 ++ src/http/v2/ngx_http_v2.c | 22 +++++- 16 files changed, 175 insertions(+), 76 deletions(-) diff --git a/.hgtags b/.hgtags index 2dcc1b3..d8c1590 100644 --- a/.hgtags +++ b/.hgtags @@ -445,3 +445,4 @@ ed4303aa1b31a9aad5440640c0840d9d0af45fed release-1.17.3 ce2ced3856909f36f8130c99eaa4dbdbae636ddc release-1.17.4 9af0dddbddb2c368bfedd2801bc100ffad01e19b release-1.17.5 de68d0d94320cbf033599c6f3ca37e5335c67fd7 release-1.17.6 +e56295fe0ea76bf53b06bffa77a2d3a9a335cb8c release-1.17.7 diff --git a/docs/man/nginx.8 b/docs/man/nginx.8 index 1f4dc89..573d935 100644 --- a/docs/man/nginx.8 +++ b/docs/man/nginx.8 @@ -1,5 +1,5 @@ .\" -.\" Copyright (C) 2010 Sergey A. Osokin +.\" Copyright (C) 2010, 2019 Sergey A. Osokin .\" Copyright (C) Nginx, Inc. .\" All rights reserved. .\" @@ -25,7 +25,7 @@ .\" SUCH DAMAGE. .\" .\" -.Dd June 16, 2015 +.Dd December 5, 2019 .Dt NGINX 8 .Os .Sh NAME @@ -42,7 +42,8 @@ .Nm (pronounced .Dq engine x ) -is an HTTP and reverse proxy server, as well as a mail proxy server. +is an HTTP and reverse proxy server, a mail proxy server, and a generic +TCP/UDP proxy server. It is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption. .Pp @@ -82,15 +83,15 @@ The following table shows the corresponding system signals: .It Cm reload .Dv SIGHUP .El +.It Fl T +Same as +.Fl t , +but additionally dump configuration files to standard output. .It Fl t Do not run, just test the configuration file. .Nm checks the configuration file syntax and then tries to open files referenced in the configuration file. -.It Fl T -Same as -.Fl t , -but additionally dump configuration files to standard output. .It Fl V Print the .Nm diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml index e0cb545..359c25e 100644 --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,90 @@ + + + + +на старте или во время переконфигурации мог произойти segmentation fault, +если в конфигурации использовалась +директива rewrite с пустой строкой замены. + + +a segmentation fault might occur on start or during reconfiguration +if the "rewrite" directive with an empty replacement string +was used in the configuration. + + + + + +в рабочем процессе мог произойти segmentation fault, +если директива break использовалась совместно с директивой alias +или директивой proxy_pass с URI. + + +a segmentation fault might occur in a worker process +if the "break" directive was used with the "alias" directive +or with the "proxy_pass" directive with a URI. + + + + + +строка Location заголовка ответа могла содержать мусор, +если URI запроса был изменён на URI, содержащий нулевой символ. + + +the "Location" response header line might contain garbage +if the request URI was rewritten to the one containing a null character. + + + + + +при возврате перенаправлений с помощью директивы error_page +запросы с телом обрабатывались некорректно; +ошибка появилась в 0.7.12. + + +requests with bodies were handled incorrectly +when returning redirections with the "error_page" directive; +the bug had appeared in 0.7.12. + + + + + +утечки сокетов при использовании HTTP/2. + + +socket leak when using HTTP/2. + + + + + +при обработке pipelined-запросов по SSL-соединению мог произойти таймаут; +ошибка появилась в 1.17.5. + + +a timeout might occur while handling pipelined requests in an SSL connection; +the bug had appeared in 1.17.5. + + + + + +в модуле ngx_http_dav_module. + + +in the ngx_http_dav_module. + + + + + + diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index 8c49c06..c7575bd 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -238,8 +238,6 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle) } if (!ngx_queue_empty(&ngx_posted_next_events)) { - ngx_queue_add(&ngx_posted_events, &ngx_posted_next_events); - ngx_queue_init(&ngx_posted_next_events); timer = 0; } @@ -263,6 +261,7 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle) } ngx_event_process_posted(cycle, &ngx_posted_events); + ngx_event_process_posted_next(cycle, &ngx_posted_next_events); } diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 3bf5bf1..e0715d6 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -43,7 +43,6 @@ static ssize_t ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf, #endif static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); static void ngx_ssl_write_handler(ngx_event_t *wev); -static void ngx_ssl_next_read_handler(ngx_event_t *rev); #ifdef SSL_READ_EARLY_DATA_SUCCESS static ssize_t ngx_ssl_write_early(ngx_connection_t *c, u_char *data, size_t size); @@ -2027,11 +2026,6 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) c->read->available = 0; c->read->ready = 0; - if (c->ssl->next_read_handler == NULL) { - c->ssl->next_read_handler = c->read->handler; - c->read->handler = ngx_ssl_next_read_handler; - } - ngx_post_event(c->read, &ngx_posted_next_events); } @@ -2337,31 +2331,6 @@ ngx_ssl_write_handler(ngx_event_t *wev) } -static void -ngx_ssl_next_read_handler(ngx_event_t *rev) -{ - ngx_connection_t *c; - - c = rev->data; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL next read handler"); - - rev->handler = c->ssl->next_read_handler; - c->ssl->next_read_handler = NULL; - - if (!rev->ready) { - rev->ready = 1; - rev->available = -1; - } - - if (rev->posted) { - ngx_delete_posted_event(rev); - } - - rev->handler(rev); -} - - /* * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer * before the SSL_write() call to decrease a SSL overhead. diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index 1b438a3..0ef823b 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -95,7 +95,6 @@ struct ngx_ssl_connection_s { ngx_event_handler_pt saved_read_handler; ngx_event_handler_pt saved_write_handler; - ngx_event_handler_pt next_read_handler; u_char early_buf; diff --git a/src/event/ngx_event_posted.c b/src/event/ngx_event_posted.c index fd0b411..125bf4c 100644 --- a/src/event/ngx_event_posted.c +++ b/src/event/ngx_event_posted.c @@ -34,3 +34,29 @@ ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted) ev->handler(ev); } } + + +void +ngx_event_process_posted_next(ngx_cycle_t *cycle, ngx_queue_t *posted) +{ + ngx_queue_t *q; + ngx_event_t *ev; + + while (!ngx_queue_empty(posted)) { + + q = ngx_queue_head(posted); + ev = ngx_queue_data(q, ngx_event_t, queue); + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "posted next event %p", ev); + + ngx_delete_posted_event(ev); + + if (!ev->ready) { + ev->ready = 1; + ev->available = -1; + } + + ev->handler(ev); + } +} diff --git a/src/event/ngx_event_posted.h b/src/event/ngx_event_posted.h index bac5b35..de0a804 100644 --- a/src/event/ngx_event_posted.h +++ b/src/event/ngx_event_posted.h @@ -39,6 +39,7 @@ void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted); +void ngx_event_process_posted_next(ngx_cycle_t *cycle, ngx_queue_t *posted); extern ngx_queue_t ngx_posted_accept_events; diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c index 95c7b32..8b69e6f 100644 --- a/src/http/modules/ngx_http_dav_module.c +++ b/src/http/modules/ngx_http_dav_module.c @@ -56,7 +56,7 @@ static ngx_int_t ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, static ngx_int_t ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt); static ngx_int_t ngx_http_dav_error(ngx_log_t *log, ngx_err_t err, ngx_int_t not_found, char *failed, u_char *path); -static ngx_int_t ngx_http_dav_location(ngx_http_request_t *r, u_char *path); +static ngx_int_t ngx_http_dav_location(ngx_http_request_t *r); static void *ngx_http_dav_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_dav_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); @@ -285,7 +285,7 @@ ngx_http_dav_put_handler(ngx_http_request_t *r) } if (status == NGX_HTTP_CREATED) { - if (ngx_http_dav_location(r, path.data) != NGX_OK) { + if (ngx_http_dav_location(r) != NGX_OK) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } @@ -312,7 +312,7 @@ ngx_http_dav_delete_handler(ngx_http_request_t *r) ngx_file_info_t fi; ngx_http_dav_loc_conf_t *dlcf; - if (r->headers_in.content_length_n > 0) { + if (r->headers_in.content_length_n > 0 || r->headers_in.chunked) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "DELETE with body is unsupported"); return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE; @@ -495,7 +495,7 @@ ngx_http_dav_mkcol_handler(ngx_http_request_t *r, ngx_http_dav_loc_conf_t *dlcf) size_t root; ngx_str_t path; - if (r->headers_in.content_length_n > 0) { + if (r->headers_in.content_length_n > 0 || r->headers_in.chunked) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "MKCOL with body is unsupported"); return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE; @@ -513,7 +513,6 @@ ngx_http_dav_mkcol_handler(ngx_http_request_t *r, ngx_http_dav_loc_conf_t *dlcf) } *(p - 1) = '\0'; - r->uri.len--; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http mkcol path: \"%s\"", path.data); @@ -521,7 +520,7 @@ ngx_http_dav_mkcol_handler(ngx_http_request_t *r, ngx_http_dav_loc_conf_t *dlcf) if (ngx_create_dir(path.data, ngx_dir_access(dlcf->access)) != NGX_FILE_ERROR) { - if (ngx_http_dav_location(r, path.data) != NGX_OK) { + if (ngx_http_dav_location(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -550,7 +549,9 @@ ngx_http_dav_copy_move_handler(ngx_http_request_t *r) ngx_http_dav_copy_ctx_t copy; ngx_http_dav_loc_conf_t *dlcf; - if (r->headers_in.content_length_n > 0) { + if (r->headers_in.content_length_n > 0 || r->headers_in.chunked) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "COPY and MOVE with body are unsupported"); return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE; } @@ -1069,35 +1070,16 @@ ngx_http_dav_error(ngx_log_t *log, ngx_err_t err, ngx_int_t not_found, static ngx_int_t -ngx_http_dav_location(ngx_http_request_t *r, u_char *path) +ngx_http_dav_location(ngx_http_request_t *r) { - u_char *location; - ngx_http_core_loc_conf_t *clcf; - r->headers_out.location = ngx_list_push(&r->headers_out.headers); if (r->headers_out.location == NULL) { return NGX_ERROR; } - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - if (!clcf->alias && clcf->root_lengths == NULL) { - location = path + clcf->root.len; - - } else { - location = ngx_pnalloc(r->pool, r->uri.len); - if (location == NULL) { - ngx_http_clear_location(r); - return NGX_ERROR; - } - - ngx_memcpy(location, r->uri.data, r->uri.len); - } - r->headers_out.location->hash = 1; ngx_str_set(&r->headers_out.location->key, "Location"); - r->headers_out.location->value.len = r->uri.len; - r->headers_out.location->value.data = location; + r->headers_out.location->value = r->uri; return NGX_OK; } diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c index c144b31..2ee1dd5 100644 --- a/src/http/modules/ngx_http_index_module.c +++ b/src/http/modules/ngx_http_index_module.c @@ -163,7 +163,7 @@ ngx_http_index_handler(ngx_http_request_t *r) name = ngx_http_map_uri_to_path(r, &path, &root, reserve); if (name == NULL) { - return NGX_ERROR; + return NGX_HTTP_INTERNAL_SERVER_ERROR; } allocated = path.data + path.len - name; diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c index 3b49c45..0e6d4df 100644 --- a/src/http/modules/ngx_http_rewrite_module.c +++ b/src/http/modules/ngx_http_rewrite_module.c @@ -318,6 +318,11 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) value = cf->args->elts; + if (value[2].len == 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty replacement"); + return NGX_CONF_ERROR; + } + ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); rc.pattern = value[1]; diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c index 0e16c05..282d6ee 100644 --- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_static_module.c @@ -157,8 +157,8 @@ ngx_http_static_handler(ngx_http_request_t *r) len = r->uri.len + 1; - if (!clcf->alias && clcf->root_lengths == NULL && r->args.len == 0) { - location = path.data + clcf->root.len; + if (!clcf->alias && r->args.len == 0) { + location = path.data + root; *last = '/'; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 89f1bca..acca57d 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1857,7 +1857,8 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path, } } - last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1); + last = ngx_copy(last, r->uri.data + alias, r->uri.len - alias); + *last = '\0'; return last; } diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c index f2f5a1c..13c57d6 100644 --- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -1470,7 +1470,14 @@ ngx_http_script_return_code(ngx_http_script_engine_t *e) void ngx_http_script_break_code(ngx_http_script_engine_t *e) { - e->request->uri_changed = 0; + ngx_http_request_t *r; + + r = e->request; + + if (r->uri_changed) { + r->valid_location = 0; + r->uri_changed = 0; + } e->ip = ngx_http_script_exit; } diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c index 31aff60..f25d1e2 100644 --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -622,6 +622,12 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page) return ngx_http_named_location(r, &uri); } + r->expect_tested = 1; + + if (ngx_http_discard_request_body(r) != NGX_OK) { + r->keepalive = 0; + } + location = ngx_list_push(&r->headers_out.headers); if (location == NULL) { diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c index 55406fc..004277a 100644 --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -178,6 +178,7 @@ static void ngx_http_v2_read_client_request_body_handler(ngx_http_request_t *r); static ngx_int_t ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream, ngx_uint_t status); static void ngx_http_v2_close_stream_handler(ngx_event_t *ev); +static void ngx_http_v2_retry_close_stream_handler(ngx_event_t *ev); static void ngx_http_v2_handle_connection_handler(ngx_event_t *rev); static void ngx_http_v2_idle_handler(ngx_event_t *rev); static void ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c, @@ -4298,8 +4299,9 @@ ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc) fc = stream->request->connection; if (stream->queued) { - fc->write->handler = ngx_http_v2_close_stream_handler; - fc->read->handler = ngx_http_empty_handler; + fc->error = 1; + fc->write->handler = ngx_http_v2_retry_close_stream_handler; + fc->read->handler = ngx_http_v2_retry_close_stream_handler; return; } @@ -4421,6 +4423,22 @@ ngx_http_v2_close_stream_handler(ngx_event_t *ev) } +static void +ngx_http_v2_retry_close_stream_handler(ngx_event_t *ev) +{ + ngx_connection_t *fc; + ngx_http_request_t *r; + + fc = ev->data; + r = fc->data; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 retry close stream handler"); + + ngx_http_v2_close_stream(r->stream, 0); +} + + static void ngx_http_v2_handle_connection_handler(ngx_event_t *rev) {