Merged with the default branch.

This commit is contained in:
Sergey Kandaurov 2021-07-15 16:28:21 +03:00
commit 161759443c
25 changed files with 383 additions and 211 deletions

View File

@ -461,3 +461,4 @@ f618488eb769e0ed74ef0d93cd118d2ad79ef94d release-1.19.6
da571b8eaf8f30f36c43b3c9b25e01e31f47149c release-1.19.9 da571b8eaf8f30f36c43b3c9b25e01e31f47149c release-1.19.9
ffcbb9980ee2bad27b4d7b1cd680b14ff47b29aa release-1.19.10 ffcbb9980ee2bad27b4d7b1cd680b14ff47b29aa release-1.19.10
df34dcc9ac072ffd0945e5a1f3eb7987e8275375 release-1.21.0 df34dcc9ac072ffd0945e5a1f3eb7987e8275375 release-1.21.0
a68ac0677f8553b1f84d357bc9da114731ab5f47 release-1.21.1

View File

@ -152,6 +152,7 @@ syn keyword ngxDirective contained auth_jwt_header_set
syn keyword ngxDirective contained auth_jwt_key_file syn keyword ngxDirective contained auth_jwt_key_file
syn keyword ngxDirective contained auth_jwt_key_request syn keyword ngxDirective contained auth_jwt_key_request
syn keyword ngxDirective contained auth_jwt_leeway syn keyword ngxDirective contained auth_jwt_leeway
syn keyword ngxDirective contained auth_jwt_type
syn keyword ngxDirective contained auth_request syn keyword ngxDirective contained auth_request
syn keyword ngxDirective contained auth_request_set syn keyword ngxDirective contained auth_request_set
syn keyword ngxDirective contained autoindex syn keyword ngxDirective contained autoindex
@ -332,16 +333,20 @@ syn keyword ngxDirective contained index
syn keyword ngxDirective contained iocp_threads syn keyword ngxDirective contained iocp_threads
syn keyword ngxDirective contained ip_hash syn keyword ngxDirective contained ip_hash
syn keyword ngxDirective contained js_access syn keyword ngxDirective contained js_access
syn keyword ngxDirective contained js_body_filter
syn keyword ngxDirective contained js_content syn keyword ngxDirective contained js_content
syn keyword ngxDirective contained js_filter syn keyword ngxDirective contained js_filter
syn keyword ngxDirective contained js_header_filter
syn keyword ngxDirective contained js_import syn keyword ngxDirective contained js_import
syn keyword ngxDirective contained js_include syn keyword ngxDirective contained js_include
syn keyword ngxDirective contained js_path syn keyword ngxDirective contained js_path
syn keyword ngxDirective contained js_preread syn keyword ngxDirective contained js_preread
syn keyword ngxDirective contained js_set syn keyword ngxDirective contained js_set
syn keyword ngxDirective contained js_var
syn keyword ngxDirective contained keepalive syn keyword ngxDirective contained keepalive
syn keyword ngxDirective contained keepalive_disable syn keyword ngxDirective contained keepalive_disable
syn keyword ngxDirective contained keepalive_requests syn keyword ngxDirective contained keepalive_requests
syn keyword ngxDirective contained keepalive_time
syn keyword ngxDirective contained keepalive_timeout syn keyword ngxDirective contained keepalive_timeout
syn keyword ngxDirective contained keyval syn keyword ngxDirective contained keyval
syn keyword ngxDirective contained keyval_zone syn keyword ngxDirective contained keyval_zone
@ -373,6 +378,7 @@ syn keyword ngxDirective contained log_subrequest
syn keyword ngxDirective contained map_hash_bucket_size syn keyword ngxDirective contained map_hash_bucket_size
syn keyword ngxDirective contained map_hash_max_size syn keyword ngxDirective contained map_hash_max_size
syn keyword ngxDirective contained master_process syn keyword ngxDirective contained master_process
syn keyword ngxDirective contained max_errors
syn keyword ngxDirective contained max_ranges syn keyword ngxDirective contained max_ranges
syn keyword ngxDirective contained memcached_bind syn keyword ngxDirective contained memcached_bind
syn keyword ngxDirective contained memcached_buffer_size syn keyword ngxDirective contained memcached_buffer_size
@ -1080,6 +1086,8 @@ syn keyword ngxDirectiveThirdParty contained nchan_subscriber_compound_etag_mess
syn keyword ngxDirectiveThirdParty contained nchan_subscribe_request syn keyword ngxDirectiveThirdParty contained nchan_subscribe_request
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_first_message syn keyword ngxDirectiveThirdParty contained nchan_subscriber_first_message
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_http_raw_stream_separator syn keyword ngxDirectiveThirdParty contained nchan_subscriber_http_raw_stream_separator
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_info
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_info_string
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_last_message_id syn keyword ngxDirectiveThirdParty contained nchan_subscriber_last_message_id
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_location syn keyword ngxDirectiveThirdParty contained nchan_subscriber_location
syn keyword ngxDirectiveThirdParty contained nchan_subscriber_message_id_custom_etag_header syn keyword ngxDirectiveThirdParty contained nchan_subscriber_message_id_custom_etag_header
@ -2368,9 +2376,9 @@ syn keyword ngxDirectiveThirdParty contained websockify_send_timeout
" IP2Location Nginx " IP2Location Nginx
" https://github.com/ip2location/ip2location-nginx " https://github.com/ip2location/ip2location-nginx
syn keyword ngxDirectiveThirdParty contained ip2location_proxy syn keyword ngxDirectiveThirdParty contained ip2location_addresstype
syn keyword ngxDirectiveThirdParty contained ip2location_proxy_recursive
syn keyword ngxDirectiveThirdParty contained ip2location_areacode syn keyword ngxDirectiveThirdParty contained ip2location_areacode
syn keyword ngxDirectiveThirdParty contained ip2location_category
syn keyword ngxDirectiveThirdParty contained ip2location_city syn keyword ngxDirectiveThirdParty contained ip2location_city
syn keyword ngxDirectiveThirdParty contained ip2location_country_long syn keyword ngxDirectiveThirdParty contained ip2location_country_long
syn keyword ngxDirectiveThirdParty contained ip2location_country_short syn keyword ngxDirectiveThirdParty contained ip2location_country_short
@ -2384,6 +2392,8 @@ syn keyword ngxDirectiveThirdParty contained ip2location_mcc
syn keyword ngxDirectiveThirdParty contained ip2location_mnc syn keyword ngxDirectiveThirdParty contained ip2location_mnc
syn keyword ngxDirectiveThirdParty contained ip2location_mobilebrand syn keyword ngxDirectiveThirdParty contained ip2location_mobilebrand
syn keyword ngxDirectiveThirdParty contained ip2location_netspeed syn keyword ngxDirectiveThirdParty contained ip2location_netspeed
syn keyword ngxDirectiveThirdParty contained ip2location_proxy
syn keyword ngxDirectiveThirdParty contained ip2location_proxy_recursive
syn keyword ngxDirectiveThirdParty contained ip2location_region syn keyword ngxDirectiveThirdParty contained ip2location_region
syn keyword ngxDirectiveThirdParty contained ip2location_timezone syn keyword ngxDirectiveThirdParty contained ip2location_timezone
syn keyword ngxDirectiveThirdParty contained ip2location_usagetype syn keyword ngxDirectiveThirdParty contained ip2location_usagetype
@ -2403,6 +2413,7 @@ syn keyword ngxDirectiveThirdParty contained ip2proxy_domain
syn keyword ngxDirectiveThirdParty contained ip2proxy_isp syn keyword ngxDirectiveThirdParty contained ip2proxy_isp
syn keyword ngxDirectiveThirdParty contained ip2proxy_is_proxy syn keyword ngxDirectiveThirdParty contained ip2proxy_is_proxy
syn keyword ngxDirectiveThirdParty contained ip2proxy_last_seen syn keyword ngxDirectiveThirdParty contained ip2proxy_last_seen
syn keyword ngxDirectiveThirdParty contained ip2proxy_provider
syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy
syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy_recursive syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy_recursive
syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy_type syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy_type

View File

@ -5,6 +5,125 @@
<change_log title="nginx"> <change_log title="nginx">
<changes ver="1.21.1" date="2021-07-06">
<change type="change">
<para lang="ru">
теперь nginx для метода CONNECT всегда возвращает ошибку.
</para>
<para lang="en">
now nginx always returns an error for the CONNECT method.
</para>
</change>
<change type="change">
<para lang="ru">
теперь nginx всегда возвращает ошибку,
если в запросе одновременно присутствуют строки заголовка "Content-Length"
и "Transfer-Encoding".
</para>
<para lang="en">
now nginx always returns an error
if both "Content-Length" and "Transfer-Encoding" header lines
are present in the request.
</para>
</change>
<change type="change">
<para lang="ru">
теперь nginx всегда возвращает ошибку,
если в строке запроса используются пробелы или управляющие символы.
</para>
<para lang="en">
now nginx always returns an error
if spaces or control characters are used in the request line.
</para>
</change>
<change type="change">
<para lang="ru">
теперь nginx всегда возвращает ошибку,
если в имени заголовка используются пробелы или управляющие символы.
</para>
<para lang="en">
now nginx always returns an error
if spaces or control characters are used in a header name.
</para>
</change>
<change type="change">
<para lang="ru">
теперь nginx всегда возвращает ошибку,
если в строке "Host" заголовка запроса
используются пробелы или управляющие символы.
</para>
<para lang="en">
now nginx always returns an error
if spaces or control characters
are used in the "Host" request header line.
</para>
</change>
<change type="change">
<para lang="ru">
оптимизация тестирования конфигурации
при использовании большого количества listen-сокетов.
</para>
<para lang="en">
optimization of configuration testing
when using many listening sockets.
</para>
</change>
<change type="bugfix">
<para lang="ru">
nginx не экранировал
символы """, "&lt;", ">", "\", "^", "`", "{", "|", и "}"
при проксировании с изменением URI запроса.
</para>
<para lang="en">
nginx did not escape
""", "&lt;", ">", "\", "^", "`", "{", "|", and "}" characters
when proxying with changed URI.
</para>
</change>
<change type="bugfix">
<para lang="ru">
SSL-переменные могли быть пустыми при записи в лог;
ошибка появилась в 1.19.5.
</para>
<para lang="en">
SSL variables might be empty when used in logs;
the bug had appeared in 1.19.5.
</para>
</change>
<change type="bugfix">
<para lang="ru">
keepalive-соединения с gRPC-бэкендами могли не закрываться
после получения GOAWAY-фрейма.
</para>
<para lang="en">
keepalive connections with gRPC backends might not be closed
after receiving a GOAWAY frame.
</para>
</change>
<change type="bugfix">
<para lang="ru">
уменьшено потребление памяти для долгоживущих запросов
при проксировании с использованием более 64 буферов.
</para>
<para lang="en">
reduced memory consumption for long-lived requests
when proxying with more than 64 buffers.
</para>
</change>
</changes>
<changes ver="1.21.0" date="2021-05-25"> <changes ver="1.21.0" date="2021-05-25">
<change type="security"> <change type="security">

View File

@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_ #define _NGINX_H_INCLUDED_
#define nginx_version 1021000 #define nginx_version 1021001
#define NGINX_VERSION "1.21.0" #define NGINX_VERSION "1.21.1"
#define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VER "nginx/" NGINX_VERSION
#ifdef NGX_BUILD #ifdef NGX_BUILD

View File

@ -495,21 +495,24 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
return NGX_ERROR; return NGX_ERROR;
} }
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, if (ls[i].type != SOCK_DGRAM || !ngx_test_config) {
(const void *) &reuseaddr, sizeof(int))
== -1)
{
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
"setsockopt(SO_REUSEADDR) %V failed",
&ls[i].addr_text);
if (ngx_close_socket(s) == -1) { if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(const void *) &reuseaddr, sizeof(int))
== -1)
{
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_close_socket_n " %V failed", "setsockopt(SO_REUSEADDR) %V failed",
&ls[i].addr_text); &ls[i].addr_text);
}
return NGX_ERROR; if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_close_socket_n " %V failed",
&ls[i].addr_text);
}
return NGX_ERROR;
}
} }
#if (NGX_HAVE_REUSEPORT) #if (NGX_HAVE_REUSEPORT)

View File

@ -47,6 +47,9 @@ struct ngx_rbtree_s {
(tree)->sentinel = s; \ (tree)->sentinel = s; \
(tree)->insert = i (tree)->insert = i
#define ngx_rbtree_data(node, type, link) \
(type *) ((u_char *) (node) - offsetof(type, link))
void ngx_rbtree_insert(ngx_rbtree_t *tree, ngx_rbtree_node_t *node); void ngx_rbtree_insert(ngx_rbtree_t *tree, ngx_rbtree_node_t *node);
void ngx_rbtree_delete(ngx_rbtree_t *tree, ngx_rbtree_node_t *node); void ngx_rbtree_delete(ngx_rbtree_t *tree, ngx_rbtree_node_t *node);

View File

@ -51,9 +51,7 @@ typedef struct {
} ngx_resolver_an_t; } ngx_resolver_an_t;
#define ngx_resolver_node(n) \ #define ngx_resolver_node(n) ngx_rbtree_data(n, ngx_resolver_node_t, node)
(ngx_resolver_node_t *) \
((u_char *) (n) - offsetof(ngx_resolver_node_t, node))
static ngx_int_t ngx_udp_connect(ngx_resolver_connection_t *rec); static ngx_int_t ngx_udp_connect(ngx_resolver_connection_t *rec);

View File

@ -1493,19 +1493,32 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
uint32_t *escape; uint32_t *escape;
static u_char hex[] = "0123456789ABCDEF"; static u_char hex[] = "0123456789ABCDEF";
/* " ", "#", "%", "?", %00-%1F, %7F-%FF */ /*
* Per RFC 3986 only the following chars are allowed in URIs unescaped:
*
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
* gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
* / "*" / "+" / "," / ";" / "="
*
* And "%" can appear as a part of escaping itself. The following
* characters are not allowed and need to be escaped: %00-%1F, %7F-%FF,
* " ", """, "<", ">", "\", "^", "`", "{", "|", "}".
*/
/* " ", "#", "%", "?", not allowed */
static uint32_t uri[] = { static uint32_t uri[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
0x80000029, /* 1000 0000 0000 0000 0000 0000 0010 1001 */ 0xd000002d, /* 1101 0000 0000 0000 0000 0000 0010 1101 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ 0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */
/* ~}| {zyx wvut srqp onml kjih gfed cba` */ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */ 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
@ -1513,19 +1526,19 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
}; };
/* " ", "#", "%", "&", "+", "?", %00-%1F, %7F-%FF */ /* " ", "#", "%", "&", "+", ";", "?", not allowed */
static uint32_t args[] = { static uint32_t args[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
0x88000869, /* 1000 1000 0000 0000 0000 1000 0110 1001 */ 0xd800086d, /* 1101 1000 0000 0000 0000 1000 0110 1101 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ 0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */
/* ~}| {zyx wvut srqp onml kjih gfed cba` */ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */ 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
@ -1553,19 +1566,19 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
}; };
/* " ", "#", """, "%", "'", %00-%1F, %7F-%FF */ /* " ", "#", """, "%", "'", not allowed */
static uint32_t html[] = { static uint32_t html[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
0x000000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */ 0x500000ad, /* 0101 0000 0000 0000 0000 0000 1010 1101 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ 0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */
/* ~}| {zyx wvut srqp onml kjih gfed cba` */ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */ 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
@ -1573,19 +1586,19 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
}; };
/* " ", """, "'", %00-%1F, %7F-%FF */ /* " ", """, "'", not allowed */
static uint32_t refresh[] = { static uint32_t refresh[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
0x00000085, /* 0000 0000 0000 0000 0000 0000 1000 0101 */ 0x50000085, /* 0101 0000 0000 0000 0000 0000 1000 0101 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ 0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */
/* ~}| {zyx wvut srqp onml kjih gfed cba` */ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */ 0xd8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */

View File

@ -477,20 +477,23 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
#if (NGX_HAVE_REUSEPORT) #if (NGX_HAVE_REUSEPORT)
ls = cycle->listening.elts; if (!ngx_test_config) {
for (i = 0; i < cycle->listening.nelts; i++) {
if (!ls[i].reuseport || ls[i].worker != 0) {
continue;
}
if (ngx_clone_listening(cycle, &ls[i]) != NGX_OK) {
return NGX_CONF_ERROR;
}
/* cloning may change cycle->listening.elts */
ls = cycle->listening.elts; ls = cycle->listening.elts;
for (i = 0; i < cycle->listening.nelts; i++) {
if (!ls[i].reuseport || ls[i].worker != 0) {
continue;
}
if (ngx_clone_listening(cycle, &ls[i]) != NGX_OK) {
return NGX_CONF_ERROR;
}
/* cloning may change cycle->listening.elts */
ls = cycle->listening.elts;
}
} }
#endif #endif

View File

@ -2896,6 +2896,7 @@ ngx_int_t
ngx_ssl_shutdown(ngx_connection_t *c) ngx_ssl_shutdown(ngx_connection_t *c)
{ {
int n, sslerr, mode; int n, sslerr, mode;
ngx_int_t rc;
ngx_err_t err; ngx_err_t err;
ngx_uint_t tries; ngx_uint_t tries;
@ -2906,6 +2907,8 @@ ngx_ssl_shutdown(ngx_connection_t *c)
} }
#endif #endif
rc = NGX_OK;
ngx_ssl_ocsp_cleanup(c); ngx_ssl_ocsp_cleanup(c);
if (SSL_in_init(c->ssl->connection)) { if (SSL_in_init(c->ssl->connection)) {
@ -2915,11 +2918,7 @@ ngx_ssl_shutdown(ngx_connection_t *c)
* Avoid calling SSL_shutdown() if handshake wasn't completed. * Avoid calling SSL_shutdown() if handshake wasn't completed.
*/ */
SSL_free(c->ssl->connection); goto done;
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_OK;
} }
if (c->timedout || c->error || c->buffered) { if (c->timedout || c->error || c->buffered) {
@ -2961,11 +2960,7 @@ ngx_ssl_shutdown(ngx_connection_t *c)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
if (n == 1) { if (n == 1) {
SSL_free(c->ssl->connection); goto done;
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_OK;
} }
if (n == 0 && tries-- > 1) { if (n == 0 && tries-- > 1) {
@ -2991,11 +2986,11 @@ ngx_ssl_shutdown(ngx_connection_t *c)
} }
if (ngx_handle_read_event(c->read, 0) != NGX_OK) { if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
return NGX_ERROR; goto failed;
} }
if (ngx_handle_write_event(c->write, 0) != NGX_OK) { if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
return NGX_ERROR; goto failed;
} }
ngx_add_timer(c->read, 3000); ngx_add_timer(c->read, 3000);
@ -3004,23 +2999,33 @@ ngx_ssl_shutdown(ngx_connection_t *c)
} }
if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
SSL_free(c->ssl->connection); goto done;
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_OK;
} }
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed"); ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
SSL_free(c->ssl->connection); break;
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_ERROR;
} }
failed:
rc = NGX_ERROR;
done:
if (c->ssl->shutdown_without_free) {
c->ssl->shutdown_without_free = 0;
c->recv = ngx_recv;
return rc;
}
SSL_free(c->ssl->connection);
c->ssl = NULL;
c->recv = ngx_recv;
return rc;
} }

View File

@ -108,6 +108,7 @@ struct ngx_ssl_connection_s {
unsigned buffer:1; unsigned buffer:1;
unsigned no_wait_shutdown:1; unsigned no_wait_shutdown:1;
unsigned no_send_shutdown:1; unsigned no_send_shutdown:1;
unsigned shutdown_without_free:1;
unsigned handshake_buffer_set:1; unsigned handshake_buffer_set:1;
unsigned try_early_data:1; unsigned try_early_data:1;
unsigned in_early:1; unsigned in_early:1;

View File

@ -73,7 +73,7 @@ ngx_event_expire_timers(void)
return; return;
} }
ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); ev = ngx_rbtree_data(node, ngx_event_t, timer);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"event timer del: %d: %M", "event timer del: %d: %M",
@ -113,7 +113,7 @@ ngx_event_no_timers_left(void)
node; node;
node = ngx_rbtree_next(&ngx_event_timer_rbtree, node)) node = ngx_rbtree_next(&ngx_event_timer_rbtree, node))
{ {
ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); ev = ngx_rbtree_data(node, ngx_event_t, timer);
if (!ev->cancelable) { if (!ev->cancelable) {
return NGX_AGAIN; return NGX_AGAIN;

View File

@ -2019,10 +2019,12 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
break; break;
} }
/* there was error while a header line parsing */ /* rc == NGX_HTTP_PARSE_INVALID_HEADER */
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"upstream sent invalid header"); "upstream sent invalid header: \"%*s\\x%02xd...\"",
r->header_end - r->header_name_start,
r->header_name_start, *r->header_end);
return NGX_HTTP_UPSTREAM_INVALID_HEADER; return NGX_HTTP_UPSTREAM_INVALID_HEADER;
} }

View File

@ -121,6 +121,7 @@ typedef struct {
unsigned done:1; unsigned done:1;
unsigned status:1; unsigned status:1;
unsigned rst:1; unsigned rst:1;
unsigned goaway:1;
ngx_http_request_t *request; ngx_http_request_t *request;
@ -1210,6 +1211,7 @@ ngx_http_grpc_reinit_request(ngx_http_request_t *r)
ctx->done = 0; ctx->done = 0;
ctx->status = 0; ctx->status = 0;
ctx->rst = 0; ctx->rst = 0;
ctx->goaway = 0;
ctx->connection = NULL; ctx->connection = NULL;
return NGX_OK; return NGX_OK;
@ -1565,6 +1567,7 @@ ngx_http_grpc_body_output_filter(void *data, ngx_chain_t *in)
&& ctx->out == NULL && ctx->out == NULL
&& ctx->output_closed && ctx->output_closed
&& !ctx->output_blocked && !ctx->output_blocked
&& !ctx->goaway
&& ctx->state == ngx_http_grpc_st_start) && ctx->state == ngx_http_grpc_st_start)
{ {
u->keepalive = 1; u->keepalive = 1;
@ -1714,6 +1717,8 @@ ngx_http_grpc_process_header(ngx_http_request_t *r)
return NGX_HTTP_UPSTREAM_INVALID_HEADER; return NGX_HTTP_UPSTREAM_INVALID_HEADER;
} }
ctx->goaway = 1;
continue; continue;
} }
@ -1907,6 +1912,7 @@ ngx_http_grpc_process_header(ngx_http_request_t *r)
&& ctx->out == NULL && ctx->out == NULL
&& ctx->output_closed && ctx->output_closed
&& !ctx->output_blocked && !ctx->output_blocked
&& !ctx->goaway
&& b->last == b->pos) && b->last == b->pos)
{ {
u->keepalive = 1; u->keepalive = 1;
@ -2035,6 +2041,7 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
if (ctx->in == NULL if (ctx->in == NULL
&& ctx->output_closed && ctx->output_closed
&& !ctx->output_blocked && !ctx->output_blocked
&& !ctx->goaway
&& ctx->state == ngx_http_grpc_st_start) && ctx->state == ngx_http_grpc_st_start)
{ {
u->keepalive = 1; u->keepalive = 1;
@ -2170,6 +2177,8 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
} }
ctx->rst = 1; ctx->rst = 1;
continue;
} }
if (ctx->type == NGX_HTTP_V2_GOAWAY_FRAME) { if (ctx->type == NGX_HTTP_V2_GOAWAY_FRAME) {
@ -2204,6 +2213,8 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
return NGX_ERROR; return NGX_ERROR;
} }
ctx->goaway = 1;
continue; continue;
} }
@ -3373,7 +3384,7 @@ ngx_http_grpc_validate_header_name(ngx_http_request_t *r, ngx_str_t *s)
return NGX_ERROR; return NGX_ERROR;
} }
if (ch == '\0' || ch == CR || ch == LF) { if (ch <= 0x20 || ch == 0x7f) {
return NGX_ERROR; return NGX_ERROR;
} }
} }
@ -3475,6 +3486,8 @@ ngx_http_grpc_parse_rst_stream(ngx_http_request_t *r, ngx_http_grpc_ctx_t *ctx,
return NGX_AGAIN; return NGX_AGAIN;
} }
ctx->state = ngx_http_grpc_st_start;
return NGX_OK; return NGX_OK;
} }

View File

@ -1186,7 +1186,7 @@ ngx_http_proxy_create_key(ngx_http_request_t *r)
loc_len = (r->valid_location && ctx->vars.uri.len) ? plcf->location.len : 0; loc_len = (r->valid_location && ctx->vars.uri.len) ? plcf->location.len : 0;
if (r->quoted_uri || r->space_in_uri || r->internal) { if (r->quoted_uri || r->internal) {
escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len, escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
r->uri.len - loc_len, NGX_ESCAPE_URI); r->uri.len - loc_len, NGX_ESCAPE_URI);
} else { } else {
@ -1299,7 +1299,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
loc_len = (r->valid_location && ctx->vars.uri.len) ? loc_len = (r->valid_location && ctx->vars.uri.len) ?
plcf->location.len : 0; plcf->location.len : 0;
if (r->quoted_uri || r->space_in_uri || r->internal) { if (r->quoted_uri || r->internal) {
escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len, escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
r->uri.len - loc_len, NGX_ESCAPE_URI); r->uri.len - loc_len, NGX_ESCAPE_URI);
} }
@ -2019,10 +2019,12 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
return NGX_AGAIN; return NGX_AGAIN;
} }
/* there was error while a header line parsing */ /* rc == NGX_HTTP_PARSE_INVALID_HEADER */
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"upstream sent invalid header"); "upstream sent invalid header: \"%*s\\x%02xd...\"",
r->header_end - r->header_name_start,
r->header_name_start, *r->header_end);
return NGX_HTTP_UPSTREAM_INVALID_HEADER; return NGX_HTTP_UPSTREAM_INVALID_HEADER;
} }

View File

@ -1140,10 +1140,12 @@ ngx_http_scgi_process_header(ngx_http_request_t *r)
return NGX_AGAIN; return NGX_AGAIN;
} }
/* there was error while a header line parsing */ /* rc == NGX_HTTP_PARSE_INVALID_HEADER */
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"upstream sent invalid header"); "upstream sent invalid header: \"%*s\\x%02xd...\"",
r->header_end - r->header_name_start,
r->header_name_start, *r->header_end);
return NGX_HTTP_UPSTREAM_INVALID_HEADER; return NGX_HTTP_UPSTREAM_INVALID_HEADER;
} }

View File

@ -1361,10 +1361,12 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
return NGX_AGAIN; return NGX_AGAIN;
} }
/* there was error while a header line parsing */ /* rc == NGX_HTTP_PARSE_INVALID_HEADER */
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"upstream sent invalid header"); "upstream sent invalid header: \"%*s\\x%02xd...\"",
r->header_end - r->header_name_start,
r->header_name_start, *r->header_end);
return NGX_HTTP_UPSTREAM_INVALID_HEADER; return NGX_HTTP_UPSTREAM_INVALID_HEADER;
} }

View File

@ -11,7 +11,7 @@
static uint32_t usual[] = { static uint32_t usual[] = {
0xffffdbfe, /* 1111 1111 1111 1111 1101 1011 1111 1110 */ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
0x7fff37d6, /* 0111 1111 1111 1111 0011 0111 1101 0110 */ 0x7fff37d6, /* 0111 1111 1111 1111 0011 0111 1101 0110 */
@ -24,7 +24,7 @@ static uint32_t usual[] = {
#endif #endif
/* ~}| {zyx wvut srqp onml kjih gfed cba` */ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0x7fffffff, /* 0111 1111 1111 1111 1111 1111 1111 1111 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
@ -116,10 +116,8 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
sw_host_end, sw_host_end,
sw_host_ip_literal, sw_host_ip_literal,
sw_port, sw_port,
sw_host_http_09,
sw_after_slash_in_uri, sw_after_slash_in_uri,
sw_check_uri, sw_check_uri,
sw_check_uri_http_09,
sw_uri, sw_uri,
sw_http_09, sw_http_09,
sw_http_H, sw_http_H,
@ -246,6 +244,11 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
r->method = NGX_HTTP_OPTIONS; r->method = NGX_HTTP_OPTIONS;
} }
if (ngx_str7_cmp(m, 'C', 'O', 'N', 'N', 'E', 'C', 'T', ' '))
{
r->method = NGX_HTTP_CONNECT;
}
break; break;
case 8: case 8:
@ -393,7 +396,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
*/ */
r->uri_start = r->schema_end + 1; r->uri_start = r->schema_end + 1;
r->uri_end = r->schema_end + 2; r->uri_end = r->schema_end + 2;
state = sw_host_http_09; state = sw_http_09;
break; break;
default: default:
return NGX_HTTP_PARSE_INVALID_REQUEST; return NGX_HTTP_PARSE_INVALID_REQUEST;
@ -467,35 +470,13 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
*/ */
r->uri_start = r->schema_end + 1; r->uri_start = r->schema_end + 1;
r->uri_end = r->schema_end + 2; r->uri_end = r->schema_end + 2;
state = sw_host_http_09; state = sw_http_09;
break; break;
default: default:
return NGX_HTTP_PARSE_INVALID_REQUEST; return NGX_HTTP_PARSE_INVALID_REQUEST;
} }
break; break;
/* space+ after "http://host[:port] " */
case sw_host_http_09:
switch (ch) {
case ' ':
break;
case CR:
r->http_minor = 9;
state = sw_almost_done;
break;
case LF:
r->http_minor = 9;
goto done;
case 'H':
r->http_protocol.data = p;
state = sw_http_H;
break;
default:
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
/* check "/.", "//", "%", and "\" (Win32) in URI */ /* check "/.", "//", "%", and "\" (Win32) in URI */
case sw_after_slash_in_uri: case sw_after_slash_in_uri:
@ -507,7 +488,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
switch (ch) { switch (ch) {
case ' ': case ' ':
r->uri_end = p; r->uri_end = p;
state = sw_check_uri_http_09; state = sw_http_09;
break; break;
case CR: case CR:
r->uri_end = p; r->uri_end = p;
@ -547,9 +528,10 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
case '+': case '+':
r->plus_in_uri = 1; r->plus_in_uri = 1;
break; break;
case '\0':
return NGX_HTTP_PARSE_INVALID_REQUEST;
default: default:
if (ch < 0x20 || ch == 0x7f) {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
state = sw_check_uri; state = sw_check_uri;
break; break;
} }
@ -579,7 +561,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
break; break;
case ' ': case ' ':
r->uri_end = p; r->uri_end = p;
state = sw_check_uri_http_09; state = sw_http_09;
break; break;
case CR: case CR:
r->uri_end = p; r->uri_end = p;
@ -611,36 +593,14 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
case '+': case '+':
r->plus_in_uri = 1; r->plus_in_uri = 1;
break; break;
case '\0':
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
/* space+ after URI */
case sw_check_uri_http_09:
switch (ch) {
case ' ':
break;
case CR:
r->http_minor = 9;
state = sw_almost_done;
break;
case LF:
r->http_minor = 9;
goto done;
case 'H':
r->http_protocol.data = p;
state = sw_http_H;
break;
default: default:
r->space_in_uri = 1; if (ch < 0x20 || ch == 0x7f) {
state = sw_check_uri; return NGX_HTTP_PARSE_INVALID_REQUEST;
p--; }
break; break;
} }
break; break;
/* URI */ /* URI */
case sw_uri: case sw_uri:
@ -665,8 +625,11 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
case '#': case '#':
r->complex_uri = 1; r->complex_uri = 1;
break; break;
case '\0': default:
return NGX_HTTP_PARSE_INVALID_REQUEST; if (ch < 0x20 || ch == 0x7f) {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
} }
break; break;
@ -687,10 +650,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
state = sw_http_H; state = sw_http_H;
break; break;
default: default:
r->space_in_uri = 1; return NGX_HTTP_PARSE_INVALID_REQUEST;
state = sw_uri;
p--;
break;
} }
break; break;
@ -933,7 +893,8 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
break; break;
} }
if (ch == '\0') { if (ch <= 0x20 || ch == 0x7f || ch == ':') {
r->header_end = p;
return NGX_HTTP_PARSE_INVALID_HEADER; return NGX_HTTP_PARSE_INVALID_HEADER;
} }
@ -1001,7 +962,8 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
break; break;
} }
if (ch == '\0') { if (ch <= 0x20 || ch == 0x7f) {
r->header_end = p;
return NGX_HTTP_PARSE_INVALID_HEADER; return NGX_HTTP_PARSE_INVALID_HEADER;
} }
@ -1024,6 +986,7 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
r->header_end = p; r->header_end = p;
goto done; goto done;
case '\0': case '\0':
r->header_end = p;
return NGX_HTTP_PARSE_INVALID_HEADER; return NGX_HTTP_PARSE_INVALID_HEADER;
default: default:
r->header_start = p; r->header_start = p;
@ -1047,6 +1010,7 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
r->header_end = p; r->header_end = p;
goto done; goto done;
case '\0': case '\0':
r->header_end = p;
return NGX_HTTP_PARSE_INVALID_HEADER; return NGX_HTTP_PARSE_INVALID_HEADER;
} }
break; break;
@ -1062,6 +1026,7 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
case LF: case LF:
goto done; goto done;
case '\0': case '\0':
r->header_end = p;
return NGX_HTTP_PARSE_INVALID_HEADER; return NGX_HTTP_PARSE_INVALID_HEADER;
default: default:
state = sw_value; state = sw_value;
@ -1165,10 +1130,6 @@ ngx_http_parse_uri(ngx_http_request_t *r)
} }
switch (ch) { switch (ch) {
case ' ':
r->space_in_uri = 1;
state = sw_check_uri;
break;
case '.': case '.':
r->complex_uri = 1; r->complex_uri = 1;
state = sw_uri; state = sw_uri;
@ -1199,6 +1160,9 @@ ngx_http_parse_uri(ngx_http_request_t *r)
r->plus_in_uri = 1; r->plus_in_uri = 1;
break; break;
default: default:
if (ch <= 0x20 || ch == 0x7f) {
return NGX_ERROR;
}
state = sw_check_uri; state = sw_check_uri;
break; break;
} }
@ -1226,9 +1190,6 @@ ngx_http_parse_uri(ngx_http_request_t *r)
case '.': case '.':
r->uri_ext = p + 1; r->uri_ext = p + 1;
break; break;
case ' ':
r->space_in_uri = 1;
break;
#if (NGX_WIN32) #if (NGX_WIN32)
case '\\': case '\\':
r->complex_uri = 1; r->complex_uri = 1;
@ -1250,6 +1211,11 @@ ngx_http_parse_uri(ngx_http_request_t *r)
case '+': case '+':
r->plus_in_uri = 1; r->plus_in_uri = 1;
break; break;
default:
if (ch <= 0x20 || ch == 0x7f) {
return NGX_ERROR;
}
break;
} }
break; break;
@ -1261,12 +1227,14 @@ ngx_http_parse_uri(ngx_http_request_t *r)
} }
switch (ch) { switch (ch) {
case ' ':
r->space_in_uri = 1;
break;
case '#': case '#':
r->complex_uri = 1; r->complex_uri = 1;
break; break;
default:
if (ch <= 0x20 || ch == 0x7f) {
return NGX_ERROR;
}
break;
} }
break; break;
} }

View File

@ -1273,7 +1273,7 @@ ngx_http_process_request_uri(ngx_http_request_t *r)
r->unparsed_uri.len = r->uri_end - r->uri_start; r->unparsed_uri.len = r->uri_end - r->uri_start;
r->unparsed_uri.data = r->uri_start; r->unparsed_uri.data = r->uri_start;
r->valid_unparsed_uri = (r->space_in_uri || r->empty_path_in_uri) ? 0 : 1; r->valid_unparsed_uri = r->empty_path_in_uri ? 0 : 1;
if (r->uri_ext) { if (r->uri_ext) {
if (r->args_start) { if (r->args_start) {
@ -1531,7 +1531,9 @@ ngx_http_process_request_headers(ngx_event_t *rev)
/* rc == NGX_HTTP_PARSE_INVALID_HEADER */ /* rc == NGX_HTTP_PARSE_INVALID_HEADER */
ngx_log_error(NGX_LOG_INFO, c->log, 0, ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent invalid header line"); "client sent invalid header line: \"%*s\\x%02xd...\"",
r->header_end - r->header_name_start,
r->header_name_start, *r->header_end);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
break; break;
@ -1989,20 +1991,20 @@ ngx_http_process_request_header(ngx_http_request_t *r)
} }
} }
if (r->method == NGX_HTTP_TRACE) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent TRACE method");
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
return NGX_ERROR;
}
if (r->headers_in.transfer_encoding) { if (r->headers_in.transfer_encoding) {
if (r->headers_in.transfer_encoding->value.len == 7 if (r->headers_in.transfer_encoding->value.len == 7
&& ngx_strncasecmp(r->headers_in.transfer_encoding->value.data, && ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
(u_char *) "chunked", 7) == 0) (u_char *) "chunked", 7) == 0)
{ {
r->headers_in.content_length = NULL; if (r->headers_in.content_length) {
r->headers_in.content_length_n = -1; ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent \"Content-Length\" and "
"\"Transfer-Encoding\" headers "
"at the same time");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return NGX_ERROR;
}
r->headers_in.chunked = 1; r->headers_in.chunked = 1;
} else { } else {
@ -2022,6 +2024,20 @@ ngx_http_process_request_header(ngx_http_request_t *r)
} }
} }
if (r->method == NGX_HTTP_CONNECT) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent CONNECT method");
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
return NGX_ERROR;
}
if (r->method == NGX_HTTP_TRACE) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent TRACE method");
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
return NGX_ERROR;
}
return NGX_OK; return NGX_OK;
} }
@ -2169,15 +2185,16 @@ ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc)
} }
break; break;
case '\0':
return NGX_DECLINED;
default: default:
if (ngx_path_separator(ch)) { if (ngx_path_separator(ch)) {
return NGX_DECLINED; return NGX_DECLINED;
} }
if (ch <= 0x20 || ch == 0x7f) {
return NGX_DECLINED;
}
if (ch >= 'A' && ch <= 'Z') { if (ch >= 'A' && ch <= 'Z') {
alloc = 1; alloc = 1;
} }
@ -3429,6 +3446,8 @@ ngx_http_set_lingering_close(ngx_connection_t *c)
if (c->ssl) { if (c->ssl) {
ngx_int_t rc; ngx_int_t rc;
c->ssl->shutdown_without_free = 1;
rc = ngx_ssl_shutdown(c); rc = ngx_ssl_shutdown(c);
if (rc == NGX_ERROR) { if (rc == NGX_ERROR) {

View File

@ -26,22 +26,23 @@
#define NGX_HTTP_VERSION_20 2000 #define NGX_HTTP_VERSION_20 2000
#define NGX_HTTP_VERSION_30 3000 #define NGX_HTTP_VERSION_30 3000
#define NGX_HTTP_UNKNOWN 0x0001 #define NGX_HTTP_UNKNOWN 0x00000001
#define NGX_HTTP_GET 0x0002 #define NGX_HTTP_GET 0x00000002
#define NGX_HTTP_HEAD 0x0004 #define NGX_HTTP_HEAD 0x00000004
#define NGX_HTTP_POST 0x0008 #define NGX_HTTP_POST 0x00000008
#define NGX_HTTP_PUT 0x0010 #define NGX_HTTP_PUT 0x00000010
#define NGX_HTTP_DELETE 0x0020 #define NGX_HTTP_DELETE 0x00000020
#define NGX_HTTP_MKCOL 0x0040 #define NGX_HTTP_MKCOL 0x00000040
#define NGX_HTTP_COPY 0x0080 #define NGX_HTTP_COPY 0x00000080
#define NGX_HTTP_MOVE 0x0100 #define NGX_HTTP_MOVE 0x00000100
#define NGX_HTTP_OPTIONS 0x0200 #define NGX_HTTP_OPTIONS 0x00000200
#define NGX_HTTP_PROPFIND 0x0400 #define NGX_HTTP_PROPFIND 0x00000400
#define NGX_HTTP_PROPPATCH 0x0800 #define NGX_HTTP_PROPPATCH 0x00000800
#define NGX_HTTP_LOCK 0x1000 #define NGX_HTTP_LOCK 0x00001000
#define NGX_HTTP_UNLOCK 0x2000 #define NGX_HTTP_UNLOCK 0x00002000
#define NGX_HTTP_PATCH 0x4000 #define NGX_HTTP_PATCH 0x00004000
#define NGX_HTTP_TRACE 0x8000 #define NGX_HTTP_TRACE 0x00008000
#define NGX_HTTP_CONNECT 0x00010000
#define NGX_HTTP_CONNECTION_CLOSE 1 #define NGX_HTTP_CONNECTION_CLOSE 1
#define NGX_HTTP_CONNECTION_KEEP_ALIVE 2 #define NGX_HTTP_CONNECTION_KEEP_ALIVE 2
@ -473,9 +474,6 @@ struct ngx_http_request_s {
/* URI with "+" */ /* URI with "+" */
unsigned plus_in_uri:1; unsigned plus_in_uri:1;
/* URI with " " */
unsigned space_in_uri:1;
/* URI with empty path */ /* URI with empty path */
unsigned empty_path_in_uri:1; unsigned empty_path_in_uri:1;

View File

@ -3457,7 +3457,7 @@ ngx_http_v2_validate_header(ngx_http_request_t *r, ngx_http_v2_header_t *header)
continue; continue;
} }
if (ch == '\0' || ch == LF || ch == CR || ch == ':' if (ch <= 0x20 || ch == 0x7f || ch == ':'
|| (ch >= 'A' && ch <= 'Z')) || (ch >= 'A' && ch <= 'Z'))
{ {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
@ -3606,7 +3606,8 @@ ngx_http_v2_parse_method(ngx_http_request_t *r, ngx_str_t *value)
{ 4, "LOCK", NGX_HTTP_LOCK }, { 4, "LOCK", NGX_HTTP_LOCK },
{ 6, "UNLOCK", NGX_HTTP_UNLOCK }, { 6, "UNLOCK", NGX_HTTP_UNLOCK },
{ 5, "PATCH", NGX_HTTP_PATCH }, { 5, "PATCH", NGX_HTTP_PATCH },
{ 5, "TRACE", NGX_HTTP_TRACE } { 5, "TRACE", NGX_HTTP_TRACE },
{ 7, "CONNECT", NGX_HTTP_CONNECT }
}, *test; }, *test;
if (r->method_name.len) { if (r->method_name.len) {

View File

@ -96,7 +96,7 @@ ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain, off_t limit)
iov->iov_len += n; iov->iov_len += n;
} else { } else {
if (vec.nelts >= IOV_MAX) { if (vec.nelts == vec.nalloc) {
break; break;
} }

View File

@ -295,7 +295,7 @@ ngx_os_status(ngx_log_t *log)
osviex_stub = (ngx_osviex_stub_t *) &osvi.wServicePackMinor; osviex_stub = (ngx_osviex_stub_t *) &osvi.wServicePackMinor;
ngx_log_error(NGX_LOG_INFO, log, 0, ngx_log_error(NGX_LOG_INFO, log, 0,
"OS: %ud build:%ud, \"%s\", suite:%Xd, type:%ud", "OS: %ui build:%ud, \"%s\", suite:%Xd, type:%ud",
ngx_win32_version, osvi.dwBuildNumber, osvi.szCSDVersion, ngx_win32_version, osvi.dwBuildNumber, osvi.szCSDVersion,
osviex_stub->wSuiteMask, osviex_stub->wProductType); osviex_stub->wSuiteMask, osviex_stub->wProductType);
@ -305,7 +305,7 @@ ngx_os_status(ngx_log_t *log)
/* Win9x build */ /* Win9x build */
ngx_log_error(NGX_LOG_INFO, log, 0, ngx_log_error(NGX_LOG_INFO, log, 0,
"OS: %u build:%ud.%ud.%ud, \"%s\"", "OS: %ui build:%ud.%ud.%ud, \"%s\"",
ngx_win32_version, ngx_win32_version,
osvi.dwBuildNumber >> 24, osvi.dwBuildNumber >> 24,
(osvi.dwBuildNumber >> 16) & 0xff, (osvi.dwBuildNumber >> 16) & 0xff,
@ -321,7 +321,7 @@ ngx_os_status(ngx_log_t *log)
* and we do not support VER_PLATFORM_WIN32s at all * and we do not support VER_PLATFORM_WIN32s at all
*/ */
ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %ud build:%ud, \"%s\"", ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %ui build:%ud, \"%s\"",
ngx_win32_version, osvi.dwBuildNumber, ngx_win32_version, osvi.dwBuildNumber,
osvi.szCSDVersion); osvi.szCSDVersion);
} }

View File

@ -10,7 +10,7 @@
#include <ngx_event.h> #include <ngx_event.h>
#define NGX_WSABUFS 8 #define NGX_WSABUFS 64
ssize_t ssize_t
@ -57,6 +57,10 @@ ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain, off_t limit)
wsabuf->len += n; wsabuf->len += n;
} else { } else {
if (vec.nelts == vec.nalloc) {
break;
}
wsabuf = ngx_array_push(&vec); wsabuf = ngx_array_push(&vec);
if (wsabuf == NULL) { if (wsabuf == NULL) {
return NGX_ERROR; return NGX_ERROR;

View File

@ -10,7 +10,7 @@
#include <ngx_event.h> #include <ngx_event.h>
#define NGX_WSABUFS 8 #define NGX_WSABUFS 64
ngx_chain_t * ngx_chain_t *
@ -47,7 +47,7 @@ ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
vec.elts = wsabufs; vec.elts = wsabufs;
vec.size = sizeof(WSABUF); vec.size = sizeof(WSABUF);
vec.nalloc = NGX_WSABUFS; vec.nalloc = ngx_min(NGX_WSABUFS, ngx_max_wsabufs);
vec.pool = c->pool; vec.pool = c->pool;
for ( ;; ) { for ( ;; ) {
@ -59,10 +59,8 @@ ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
/* create the WSABUF and coalesce the neighbouring bufs */ /* create the WSABUF and coalesce the neighbouring bufs */
for (cl = in; for (cl = in; cl && send < limit; cl = cl->next) {
cl && vec.nelts < ngx_max_wsabufs && send < limit;
cl = cl->next)
{
if (ngx_buf_special(cl->buf)) { if (ngx_buf_special(cl->buf)) {
continue; continue;
} }
@ -77,6 +75,10 @@ ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
wsabuf->len += cl->buf->last - cl->buf->pos; wsabuf->len += cl->buf->last - cl->buf->pos;
} else { } else {
if (vec.nelts == vec.nalloc) {
break;
}
wsabuf = ngx_array_push(&vec); wsabuf = ngx_array_push(&vec);
if (wsabuf == NULL) { if (wsabuf == NULL) {
return NGX_CHAIN_ERROR; return NGX_CHAIN_ERROR;
@ -169,7 +171,7 @@ ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
vec.elts = wsabufs; vec.elts = wsabufs;
vec.nelts = 0; vec.nelts = 0;
vec.size = sizeof(WSABUF); vec.size = sizeof(WSABUF);
vec.nalloc = NGX_WSABUFS; vec.nalloc = ngx_min(NGX_WSABUFS, ngx_max_wsabufs);
vec.pool = c->pool; vec.pool = c->pool;
send = 0; send = 0;
@ -178,10 +180,8 @@ ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
/* create the WSABUF and coalesce the neighbouring bufs */ /* create the WSABUF and coalesce the neighbouring bufs */
for (cl = in; for (cl = in; cl && send < limit; cl = cl->next) {
cl && vec.nelts < ngx_max_wsabufs && send < limit;
cl = cl->next)
{
if (ngx_buf_special(cl->buf)) { if (ngx_buf_special(cl->buf)) {
continue; continue;
} }
@ -196,6 +196,10 @@ ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
wsabuf->len += cl->buf->last - cl->buf->pos; wsabuf->len += cl->buf->last - cl->buf->pos;
} else { } else {
if (vec.nelts == vec.nalloc) {
break;
}
wsabuf = ngx_array_push(&vec); wsabuf = ngx_array_push(&vec);
if (wsabuf == NULL) { if (wsabuf == NULL) {
return NGX_CHAIN_ERROR; return NGX_CHAIN_ERROR;