From 2cb5bdf665c74d09f619add61228e4c3cb626469 Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Fri, 29 Apr 2022 17:38:01 +0400 Subject: [PATCH 01/37] Configure: recognize arm64 machine name as a synonym for aarch64. In particular, this sets a reasonable cacheline size on FreeBSD and macOS, which prefer to use this name and both lack _SC_LEVEL1_DCACHE_LINESIZE. --- auto/os/conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auto/os/conf b/auto/os/conf index 7c6cb691a..d7f6e0382 100644 --- a/auto/os/conf +++ b/auto/os/conf @@ -110,7 +110,7 @@ case "$NGX_MACHINE" in NGX_MACH_CACHE_LINE=64 ;; - aarch64 ) + aarch64 | arm64) have=NGX_ALIGNMENT value=16 . auto/define NGX_MACH_CACHE_LINE=64 ;; From f7e68dba8ca579a3a2357840e827fd598f165ec3 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 24 May 2022 02:51:49 +0300 Subject: [PATCH 02/37] Updated OpenSSL and zlib used for win32 builds. --- misc/GNUmakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/GNUmakefile b/misc/GNUmakefile index 58e9f7f00..8f839b477 100644 --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -6,8 +6,8 @@ TEMP = tmp CC = cl OBJS = objs.msvc8 -OPENSSL = openssl-1.1.1m -ZLIB = zlib-1.2.11 +OPENSSL = openssl-1.1.1o +ZLIB = zlib-1.2.12 PCRE = pcre2-10.39 From 0c1d3268a6e4f138d2ebf1f859a4a9b1f2777513 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 02:37:59 +0300 Subject: [PATCH 03/37] Version bump. --- src/core/nginx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/nginx.h b/src/core/nginx.h index 43e658259..57e7b2023 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1021007 -#define NGINX_VERSION "1.21.7" +#define nginx_version 1023000 +#define NGINX_VERSION "1.23.0" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From a4eddea7112cf5db86bea5ab9c8dcc597f2a1344 Mon Sep 17 00:00:00 2001 From: Marcus Ball Date: Mon, 30 May 2022 02:38:07 +0300 Subject: [PATCH 04/37] Fixed runtime handling of systems without EPOLLRDHUP support. In 7583:efd71d49bde0 (nginx 1.17.5) along with introduction of the ioctl(FIONREAD) support proper handling of systems without EPOLLRDHUP support in the kernel (but with EPOLLRDHUP in headers) was broken. Before the change, rev->available was never set to 0 unless ngx_use_epoll_rdhup was also set (that is, runtime test for EPOLLRDHUP introduced in 6536:f7849bfb6d21 succeeded). After the change, rev->available might reach 0 on systems without runtime EPOLLRDHUP support, stopping further reading in ngx_readv_chain() and ngx_unix_recv(). And, if EOF happened to be already reported along with the last event, it is not reported again by epoll_wait(), leading to connection hangs and timeouts on such systems. This affects Linux kernels before 2.6.17 if nginx was compiled with newer headers, and, more importantly, emulation layers, such as DigitalOcean's App Platform's / gVisor's epoll emulation layer. Fix is to explicitly check ngx_use_epoll_rdhup before the corresponding rev->pending_eof tests in ngx_readv_chain() and ngx_unix_recv(). --- src/os/unix/ngx_readv_chain.c | 4 +++- src/os/unix/ngx_recv.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/os/unix/ngx_readv_chain.c b/src/os/unix/ngx_readv_chain.c index b1ae4b51d..370a4011f 100644 --- a/src/os/unix/ngx_readv_chain.c +++ b/src/os/unix/ngx_readv_chain.c @@ -55,7 +55,9 @@ ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain, off_t limit) #if (NGX_HAVE_EPOLLRDHUP) - if (ngx_event_flags & NGX_USE_EPOLL_EVENT) { + if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) + && ngx_use_epoll_rdhup) + { ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, "readv: eof:%d, avail:%d", rev->pending_eof, rev->available); diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c index ddfae4dbe..cc04a5fbb 100644 --- a/src/os/unix/ngx_recv.c +++ b/src/os/unix/ngx_recv.c @@ -52,7 +52,9 @@ ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size) #if (NGX_HAVE_EPOLLRDHUP) - if (ngx_event_flags & NGX_USE_EPOLL_EVENT) { + if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) + && ngx_use_epoll_rdhup) + { ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, "recv: eof:%d, avail:%d", rev->pending_eof, rev->available); From 8ad0f62863aaa7ed64b4514c4c1d3ba924410c16 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:25 +0300 Subject: [PATCH 05/37] Perl: fixed $r->header_in("Connection"). Previously, the r->header_in->connection pointer was never set despite being present in ngx_http_headers_in, resulting in incorrect value returned by $r->header_in("Connection") in embedded perl. --- src/http/ngx_http_request.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 013b7158e..44e4d89de 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1827,6 +1827,10 @@ static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { + if (ngx_http_process_header_line(r, h, offset) != NGX_OK) { + return NGX_ERROR; + } + if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) { r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE; From d8a7c653e4b8e842c947c0a550a7bc5a7812058a Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:27 +0300 Subject: [PATCH 06/37] FastCGI: combining headers with identical names (ticket #1724). FastCGI responder is expected to receive CGI/1.1 environment variables in the parameters (see section "6.2 Responder" of the FastCGI specification). Obviously enough, there cannot be multiple environment variables with the same name. Further, CGI specification (RFC 3875, section "4.1.18. Protocol-Specific Meta-Variables") explicitly requires to combine headers: "If multiple header fields with the same field-name are received then the server MUST rewrite them as a single value having the same semantics". --- src/core/ngx_hash.h | 7 +- src/http/modules/ngx_http_fastcgi_module.c | 70 ++++++++++++++++---- src/http/ngx_http_core_module.c | 74 ++++++++++++++++++++++ src/http/ngx_http_core_module.h | 2 + src/http/ngx_http_request.h | 2 + 5 files changed, 140 insertions(+), 15 deletions(-) diff --git a/src/core/ngx_hash.h b/src/core/ngx_hash.h index abc3cbe5d..3b5709928 100644 --- a/src/core/ngx_hash.h +++ b/src/core/ngx_hash.h @@ -89,12 +89,15 @@ typedef struct { } ngx_hash_keys_arrays_t; -typedef struct { +typedef struct ngx_table_elt_s ngx_table_elt_t; + +struct ngx_table_elt_s { ngx_uint_t hash; ngx_str_t key; ngx_str_t value; u_char *lowcase_key; -} ngx_table_elt_t; + ngx_table_elt_t *next; +}; void *ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, u_char *name, size_t len); diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c index 4a8dc338e..17b7e83a3 100644 --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -835,14 +835,14 @@ static ngx_int_t ngx_http_fastcgi_create_request(ngx_http_request_t *r) { off_t file_pos; - u_char ch, *pos, *lowcase_key; + u_char ch, sep, *pos, *lowcase_key; size_t size, len, key_len, val_len, padding, allocated; ngx_uint_t i, n, next, hash, skip_empty, header_params; ngx_buf_t *b; ngx_chain_t *cl, *body; ngx_list_part_t *part; - ngx_table_elt_t *header, **ignored; + ngx_table_elt_t *header, *hn, **ignored; ngx_http_upstream_t *u; ngx_http_script_code_pt code; ngx_http_script_engine_t e, le; @@ -900,7 +900,11 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) allocated = 0; lowcase_key = NULL; - if (params->number) { + if (ngx_http_link_multi_headers(r) != NGX_OK) { + return NGX_ERROR; + } + + if (params->number || r->headers_in.multi) { n = 0; part = &r->headers_in.headers.part; @@ -930,6 +934,12 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) i = 0; } + for (n = 0; n < header_params; n++) { + if (&header[i] == ignored[n]) { + goto next_length; + } + } + if (params->number) { if (allocated < header[i].key.len) { allocated = header[i].key.len + 16; @@ -959,15 +969,23 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) ignored[header_params++] = &header[i]; continue; } - - n += sizeof("HTTP_") - 1; - - } else { - n = sizeof("HTTP_") - 1 + header[i].key.len; } - len += ((n > 127) ? 4 : 1) + ((header[i].value.len > 127) ? 4 : 1) - + n + header[i].value.len; + key_len = sizeof("HTTP_") - 1 + header[i].key.len; + + val_len = header[i].value.len; + + for (hn = header[i].next; hn; hn = hn->next) { + val_len += hn->value.len + 2; + ignored[header_params++] = hn; + } + + len += ((key_len > 127) ? 4 : 1) + key_len + + ((val_len > 127) ? 4 : 1) + val_len; + + next_length: + + continue; } } @@ -1109,7 +1127,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) for (n = 0; n < header_params; n++) { if (&header[i] == ignored[n]) { - goto next; + goto next_value; } } @@ -1125,6 +1143,11 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) } val_len = header[i].value.len; + + for (hn = header[i].next; hn; hn = hn->next) { + val_len += hn->value.len + 2; + } + if (val_len > 127) { *b->last++ = (u_char) (((val_len >> 24) & 0x7f) | 0x80); *b->last++ = (u_char) ((val_len >> 16) & 0xff); @@ -1150,13 +1173,34 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) *b->last++ = ch; } - b->last = ngx_copy(b->last, header[i].value.data, val_len); + b->last = ngx_copy(b->last, header[i].value.data, + header[i].value.len); + + if (header[i].next) { + + if (header[i].key.len == sizeof("Cookie") - 1 + && ngx_strncasecmp(header[i].key.data, (u_char *) "Cookie", + sizeof("Cookie") - 1) + == 0) + { + sep = ';'; + + } else { + sep = ','; + } + + for (hn = header[i].next; hn; hn = hn->next) { + *b->last++ = sep; + *b->last++ = ' '; + b->last = ngx_copy(b->last, hn->value.data, hn->value.len); + } + } ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "fastcgi param: \"%*s: %*s\"", key_len, b->last - (key_len + val_len), val_len, b->last - val_len); - next: + next_value: continue; } diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index c7463dcdc..ad8caad19 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -2802,6 +2802,80 @@ ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr, } +ngx_int_t +ngx_http_link_multi_headers(ngx_http_request_t *r) +{ + ngx_uint_t i, j; + ngx_list_part_t *part, *ppart; + ngx_table_elt_t *header, *pheader, **ph; + + if (r->headers_in.multi_linked) { + return NGX_OK; + } + + r->headers_in.multi_linked = 1; + + part = &r->headers_in.headers.part; + header = part->elts; + + for (i = 0; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + header = part->elts; + i = 0; + } + + header[i].next = NULL; + + /* + * search for previous headers with the same name; + * if there are any, link to them + */ + + ppart = &r->headers_in.headers.part; + pheader = ppart->elts; + + for (j = 0; /* void */; j++) { + + if (j >= ppart->nelts) { + if (ppart->next == NULL) { + break; + } + + ppart = ppart->next; + pheader = ppart->elts; + j = 0; + } + + if (part == ppart && i == j) { + break; + } + + if (header[i].key.len == pheader[j].key.len + && ngx_strncasecmp(header[i].key.data, pheader[j].key.data, + header[i].key.len) + == 0) + { + ph = &pheader[j].next; + while (*ph) { ph = &(*ph)->next; } + *ph = &header[i]; + + r->headers_in.multi = 1; + + break; + } + } + } + + return NGX_OK; +} + + static char * ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) { diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index 004a98eef..7ba64947b 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -532,6 +532,8 @@ ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr, ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies, int recursive); +ngx_int_t ngx_http_link_multi_headers(ngx_http_request_t *r); + extern ngx_module_t ngx_http_core_module; diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index b1269d22d..52165793a 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -242,6 +242,8 @@ typedef struct { unsigned connection_type:2; unsigned chunked:1; + unsigned multi:1; + unsigned multi_linked:1; unsigned msie:1; unsigned msie6:1; unsigned opera:1; From 54ce38187cf4061c68d3955558d325d1c688e0bd Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:28 +0300 Subject: [PATCH 07/37] SCGI: combining headers with identical names (ticket #1724). SCGI specification explicitly forbids headers with duplicate names (section "3. Request Format"): "Duplicate names are not allowed in the headers". Further, provided headers are expected to follow CGI specification, which also requires to combine headers (RFC 3875, section "4.1.18. Protocol-Specific Meta-Variables"): "If multiple header fields with the same field-name are received then the server MUST rewrite them as a single value having the same semantics". --- src/http/modules/ngx_http_scgi_module.c | 50 ++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c index e5d31ae91..cc865fdc1 100644 --- a/src/http/modules/ngx_http_scgi_module.c +++ b/src/http/modules/ngx_http_scgi_module.c @@ -633,14 +633,14 @@ static ngx_int_t ngx_http_scgi_create_request(ngx_http_request_t *r) { off_t content_length_n; - u_char ch, *key, *val, *lowcase_key; + u_char ch, sep, *key, *val, *lowcase_key; size_t len, key_len, val_len, allocated; ngx_buf_t *b; ngx_str_t content_length; ngx_uint_t i, n, hash, skip_empty, header_params; ngx_chain_t *cl, *body; ngx_list_part_t *part; - ngx_table_elt_t *header, **ignored; + ngx_table_elt_t *header, *hn, **ignored; ngx_http_scgi_params_t *params; ngx_http_script_code_pt code; ngx_http_script_engine_t e, le; @@ -707,7 +707,11 @@ ngx_http_scgi_create_request(ngx_http_request_t *r) allocated = 0; lowcase_key = NULL; - if (params->number) { + if (ngx_http_link_multi_headers(r) != NGX_OK) { + return NGX_ERROR; + } + + if (params->number || r->headers_in.multi) { n = 0; part = &r->headers_in.headers.part; @@ -737,6 +741,12 @@ ngx_http_scgi_create_request(ngx_http_request_t *r) i = 0; } + for (n = 0; n < header_params; n++) { + if (&header[i] == ignored[n]) { + goto next_length; + } + } + if (params->number) { if (allocated < header[i].key.len) { allocated = header[i].key.len + 16; @@ -770,6 +780,15 @@ ngx_http_scgi_create_request(ngx_http_request_t *r) len += sizeof("HTTP_") - 1 + header[i].key.len + 1 + header[i].value.len + 1; + + for (hn = header[i].next; hn; hn = hn->next) { + len += hn->value.len + 2; + ignored[header_params++] = hn; + } + + next_length: + + continue; } } @@ -869,7 +888,7 @@ ngx_http_scgi_create_request(ngx_http_request_t *r) for (n = 0; n < header_params; n++) { if (&header[i] == ignored[n]) { - goto next; + goto next_value; } } @@ -893,12 +912,33 @@ ngx_http_scgi_create_request(ngx_http_request_t *r) val = b->last; b->last = ngx_copy(val, header[i].value.data, header[i].value.len); + + if (header[i].next) { + + if (header[i].key.len == sizeof("Cookie") - 1 + && ngx_strncasecmp(header[i].key.data, (u_char *) "Cookie", + sizeof("Cookie") - 1) + == 0) + { + sep = ';'; + + } else { + sep = ','; + } + + for (hn = header[i].next; hn; hn = hn->next) { + *b->last++ = sep; + *b->last++ = ' '; + b->last = ngx_copy(b->last, hn->value.data, hn->value.len); + } + } + *b->last++ = (u_char) 0; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "scgi param: \"%s: %s\"", key, val); - next: + next_value: continue; } From 321ff71a6c3d3bd9cbc7a348a0cac26158590f10 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:30 +0300 Subject: [PATCH 08/37] Uwsgi: combining headers with identical names (ticket #1724). The uwsgi specification states that "The uwsgi block vars represent a dictionary/hash". This implies that no duplicate headers are expected. Further, provided headers are expected to follow CGI specification, which also requires to combine headers (RFC 3875, section "4.1.18. Protocol-Specific Meta-Variables"): "If multiple header fields with the same field-name are received then the server MUST rewrite them as a single value having the same semantics". --- src/http/modules/ngx_http_uwsgi_module.c | 57 +++++++++++++++++++++--- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c index d46741a00..a1a76f623 100644 --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -845,13 +845,13 @@ ngx_http_uwsgi_create_key(ngx_http_request_t *r) static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r) { - u_char ch, *lowcase_key; + u_char ch, sep, *lowcase_key; size_t key_len, val_len, len, allocated; ngx_uint_t i, n, hash, skip_empty, header_params; ngx_buf_t *b; ngx_chain_t *cl, *body; ngx_list_part_t *part; - ngx_table_elt_t *header, **ignored; + ngx_table_elt_t *header, *hn, **ignored; ngx_http_uwsgi_params_t *params; ngx_http_script_code_pt code; ngx_http_script_engine_t e, le; @@ -905,7 +905,11 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r) allocated = 0; lowcase_key = NULL; - if (params->number) { + if (ngx_http_link_multi_headers(r) != NGX_OK) { + return NGX_ERROR; + } + + if (params->number || r->headers_in.multi) { n = 0; part = &r->headers_in.headers.part; @@ -935,6 +939,12 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r) i = 0; } + for (n = 0; n < header_params; n++) { + if (&header[i] == ignored[n]) { + goto next_length; + } + } + if (params->number) { if (allocated < header[i].key.len) { allocated = header[i].key.len + 16; @@ -968,6 +978,15 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r) len += 2 + sizeof("HTTP_") - 1 + header[i].key.len + 2 + header[i].value.len; + + for (hn = header[i].next; hn; hn = hn->next) { + len += hn->value.len + 2; + ignored[header_params++] = hn; + } + + next_length: + + continue; } } @@ -1086,7 +1105,7 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r) for (n = 0; n < header_params; n++) { if (&header[i] == ignored[n]) { - goto next; + goto next_value; } } @@ -1109,15 +1128,41 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r) } val_len = header[i].value.len; + + for (hn = header[i].next; hn; hn = hn->next) { + val_len += hn->value.len + 2; + } + *b->last++ = (u_char) (val_len & 0xff); *b->last++ = (u_char) ((val_len >> 8) & 0xff); - b->last = ngx_copy(b->last, header[i].value.data, val_len); + b->last = ngx_copy(b->last, header[i].value.data, + header[i].value.len); + + if (header[i].next) { + + if (header[i].key.len == sizeof("Cookie") - 1 + && ngx_strncasecmp(header[i].key.data, (u_char *) "Cookie", + sizeof("Cookie") - 1) + == 0) + { + sep = ';'; + + } else { + sep = ','; + } + + for (hn = header[i].next; hn; hn = hn->next) { + *b->last++ = sep; + *b->last++ = ' '; + b->last = ngx_copy(b->last, hn->value.data, hn->value.len); + } + } ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "uwsgi param: \"%*s: %*s\"", key_len, b->last - (key_len + 2 + val_len), val_len, b->last - val_len); - next: + next_value: continue; } From 7dc6f4e25d21588249691aab8c6013c126eae258 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:32 +0300 Subject: [PATCH 09/37] Combining unknown headers during variables lookup (ticket #1316). Previously, $http_*, $sent_http_*, $sent_trailer_*, $upstream_http_*, and $upstream_trailer_* variables returned only the first header (with a few specially handled exceptions: $http_cookie, $http_x_forwarded_for, $sent_http_cache_control, $sent_http_link). With this change, all headers are returned, combined together. For example, $http_foo variable will be "a, b" if there are "Foo: a" and "Foo: b" headers in the request. Note that $upstream_http_set_cookie will also return all "Set-Cookie" headers (ticket #1843), though this might not be what one want, since the "Set-Cookie" header does not follow the list syntax (see RFC 7230, section 3.2.2). --- src/http/ngx_http_upstream.c | 4 +- src/http/ngx_http_variables.c | 86 ++++++++++++++++++++++++++++------- src/http/ngx_http_variables.h | 5 +- 3 files changed, 74 insertions(+), 21 deletions(-) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index ded833c41..46fde8396 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -5703,7 +5703,7 @@ ngx_http_upstream_header_variable(ngx_http_request_t *r, return NGX_OK; } - return ngx_http_variable_unknown_header(v, (ngx_str_t *) data, + return ngx_http_variable_unknown_header(r, v, (ngx_str_t *) data, &r->upstream->headers_in.headers.part, sizeof("upstream_http_") - 1); } @@ -5718,7 +5718,7 @@ ngx_http_upstream_trailer_variable(ngx_http_request_t *r, return NGX_OK; } - return ngx_http_variable_unknown_header(v, (ngx_str_t *) data, + return ngx_http_variable_unknown_header(r, v, (ngx_str_t *) data, &r->upstream->headers_in.trailers.part, sizeof("upstream_trailer_") - 1); } diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index 942dacd70..b0f06ac7c 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -919,7 +919,7 @@ static ngx_int_t ngx_http_variable_unknown_header_in(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - return ngx_http_variable_unknown_header(v, (ngx_str_t *) data, + return ngx_http_variable_unknown_header(r, v, (ngx_str_t *) data, &r->headers_in.headers.part, sizeof("http_") - 1); } @@ -929,7 +929,7 @@ static ngx_int_t ngx_http_variable_unknown_header_out(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - return ngx_http_variable_unknown_header(v, (ngx_str_t *) data, + return ngx_http_variable_unknown_header(r, v, (ngx_str_t *) data, &r->headers_out.headers.part, sizeof("sent_http_") - 1); } @@ -939,19 +939,26 @@ static ngx_int_t ngx_http_variable_unknown_trailer_out(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - return ngx_http_variable_unknown_header(v, (ngx_str_t *) data, + return ngx_http_variable_unknown_header(r, v, (ngx_str_t *) data, &r->headers_out.trailers.part, sizeof("sent_trailer_") - 1); } ngx_int_t -ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var, +ngx_http_variable_unknown_header(ngx_http_request_t *r, + ngx_http_variable_value_t *v, ngx_str_t *var, ngx_list_part_t *part, size_t prefix) { - u_char ch; + u_char *p, ch; + size_t len; ngx_uint_t i, n; - ngx_table_elt_t *header; + ngx_table_elt_t *header, *h, **ph; + + ph = &h; +#if (NGX_SUPPRESS_WARN) + len = 0; +#endif header = part->elts; @@ -971,7 +978,11 @@ ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var, continue; } - for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) { + if (header[i].key.len != var->len - prefix) { + continue; + } + + for (n = 0; n < var->len - prefix; n++) { ch = header[i].key.data[n]; if (ch >= 'A' && ch <= 'Z') { @@ -986,18 +997,59 @@ ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var, } } - if (n + prefix == var->len && n == header[i].key.len) { - v->len = header[i].value.len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = header[i].value.data; - - return NGX_OK; + if (n != var->len - prefix) { + continue; } + + len += header[i].value.len + 2; + + *ph = &header[i]; + ph = &header[i].next; } - v->not_found = 1; + *ph = NULL; + + if (h == NULL) { + v->not_found = 1; + return NGX_OK; + } + + len -= 2; + + if (h->next == NULL) { + + v->len = h->value.len; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = h->value.data; + + return NGX_OK; + } + + p = ngx_pnalloc(r->pool, len); + if (p == NULL) { + return NGX_ERROR; + } + + v->len = len; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = p; + + for ( ;; ) { + + p = ngx_copy(p, h->value.data, h->value.len); + + if (h->next == NULL) { + break; + } + + *p++ = ','; *p++ = ' '; + + h = h->next; + } return NGX_OK; } @@ -1879,7 +1931,7 @@ ngx_http_variable_sent_location(ngx_http_request_t *r, ngx_str_set(&name, "sent_http_location"); - return ngx_http_variable_unknown_header(v, &name, + return ngx_http_variable_unknown_header(r, v, &name, &r->headers_out.headers.part, sizeof("sent_http_") - 1); } diff --git a/src/http/ngx_http_variables.h b/src/http/ngx_http_variables.h index f3f7f3c1c..6a661a256 100644 --- a/src/http/ngx_http_variables.h +++ b/src/http/ngx_http_variables.h @@ -57,8 +57,9 @@ ngx_http_variable_value_t *ngx_http_get_flushed_variable(ngx_http_request_t *r, ngx_http_variable_value_t *ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key); -ngx_int_t ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, - ngx_str_t *var, ngx_list_part_t *part, size_t prefix); +ngx_int_t ngx_http_variable_unknown_header(ngx_http_request_t *r, + ngx_http_variable_value_t *v, ngx_str_t *var, ngx_list_part_t *part, + size_t prefix); #if (NGX_PCRE) From 3aef1d693f3cc431563a7e6a6aba6a34e5290f03 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:33 +0300 Subject: [PATCH 10/37] Reworked multi headers to use linked lists. Multi headers are now using linked lists instead of arrays. Notably, the following fields were changed: r->headers_in.cookies (renamed to r->headers_in.cookie), r->headers_in.x_forwarded_for, r->headers_out.cache_control, r->headers_out.link, u->headers_in.cache_control u->headers_in.cookies (renamed to u->headers_in.set_cookie). The r->headers_in.cookies and u->headers_in.cookies fields were renamed to r->headers_in.cookie and u->headers_in.set_cookie to match header names. The ngx_http_parse_multi_header_lines() and ngx_http_parse_set_cookie_lines() functions were changed accordingly. With this change, multi headers are now essentially equivalent to normal headers, and following changes will further make them equivalent. --- src/http/modules/ngx_http_geo_module.c | 6 +- src/http/modules/ngx_http_geoip_module.c | 12 ++-- .../modules/ngx_http_headers_filter_module.c | 49 +++++---------- src/http/modules/ngx_http_proxy_module.c | 18 +++--- src/http/modules/ngx_http_realip_module.c | 7 +-- .../modules/ngx_http_userid_filter_module.c | 19 +++--- src/http/modules/perl/nginx.xs | 22 +++---- src/http/ngx_http.h | 8 +-- src/http/ngx_http_core_module.c | 52 ++++++++++------ src/http/ngx_http_core_module.h | 2 +- src/http/ngx_http_parse.c | 60 +++++++++---------- src/http/ngx_http_request.c | 26 +++----- src/http/ngx_http_request.h | 12 ++-- src/http/ngx_http_upstream.c | 56 ++++------------- src/http/ngx_http_upstream.h | 4 +- src/http/ngx_http_variables.c | 41 ++++++------- src/http/v2/ngx_http_v2_filter_module.c | 26 ++++---- 17 files changed, 175 insertions(+), 245 deletions(-) diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c index 153b6aaf3..ef4e9b84a 100644 --- a/src/http/modules/ngx_http_geo_module.c +++ b/src/http/modules/ngx_http_geo_module.c @@ -327,15 +327,15 @@ static ngx_int_t ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr) { - ngx_array_t *xfwd; + ngx_table_elt_t *xfwd; if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) { return NGX_ERROR; } - xfwd = &r->headers_in.x_forwarded_for; + xfwd = r->headers_in.x_forwarded_for; - if (xfwd->nelts > 0 && ctx->proxies != NULL) { + if (xfwd != NULL && ctx->proxies != NULL) { (void) ngx_http_get_forwarded_addr(r, addr, xfwd, NULL, ctx->proxies, ctx->proxy_recursive); } diff --git a/src/http/modules/ngx_http_geoip_module.c b/src/http/modules/ngx_http_geoip_module.c index 5ea4f5fb0..eaf98764f 100644 --- a/src/http/modules/ngx_http_geoip_module.c +++ b/src/http/modules/ngx_http_geoip_module.c @@ -240,16 +240,16 @@ static u_long ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf) { ngx_addr_t addr; - ngx_array_t *xfwd; + ngx_table_elt_t *xfwd; struct sockaddr_in *sin; addr.sockaddr = r->connection->sockaddr; addr.socklen = r->connection->socklen; /* addr.name = r->connection->addr_text; */ - xfwd = &r->headers_in.x_forwarded_for; + xfwd = r->headers_in.x_forwarded_for; - if (xfwd->nelts > 0 && gcf->proxies != NULL) { + if (xfwd != NULL && gcf->proxies != NULL) { (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL, gcf->proxies, gcf->proxy_recursive); } @@ -292,7 +292,7 @@ static geoipv6_t ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf) { ngx_addr_t addr; - ngx_array_t *xfwd; + ngx_table_elt_t *xfwd; in_addr_t addr4; struct in6_addr addr6; struct sockaddr_in *sin; @@ -302,9 +302,9 @@ ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf) addr.socklen = r->connection->socklen; /* addr.name = r->connection->addr_text; */ - xfwd = &r->headers_in.x_forwarded_for; + xfwd = r->headers_in.x_forwarded_for; - if (xfwd->nelts > 0 && gcf->proxies != NULL) { + if (xfwd != NULL && gcf->proxies != NULL) { (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL, gcf->proxies, gcf->proxy_recursive); } diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c index a4c8cc264..995beb41b 100644 --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -329,8 +329,7 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) time_t now, expires_time, max_age; ngx_str_t value; ngx_int_t rc; - ngx_uint_t i; - ngx_table_elt_t *e, *cc, **ccp; + ngx_table_elt_t *e, *cc; ngx_http_expires_t expires; expires = conf->expires; @@ -371,38 +370,28 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT"); e->value.len = len - 1; - ccp = r->headers_out.cache_control.elts; + cc = r->headers_out.cache_control; - if (ccp == NULL) { - - if (ngx_array_init(&r->headers_out.cache_control, r->pool, - 1, sizeof(ngx_table_elt_t *)) - != NGX_OK) - { - return NGX_ERROR; - } + if (cc == NULL) { cc = ngx_list_push(&r->headers_out.headers); if (cc == NULL) { return NGX_ERROR; } + r->headers_out.cache_control = cc; + cc->next = NULL; + cc->hash = 1; ngx_str_set(&cc->key, "Cache-Control"); - ccp = ngx_array_push(&r->headers_out.cache_control); - if (ccp == NULL) { - return NGX_ERROR; - } - - *ccp = cc; - } else { - for (i = 1; i < r->headers_out.cache_control.nelts; i++) { - ccp[i]->hash = 0; + for (cc = cc->next; cc; cc = cc->next) { + cc->hash = 0; } - cc = ccp[0]; + cc = r->headers_out.cache_control; + cc->next = NULL; } if (expires == NGX_HTTP_EXPIRES_EPOCH) { @@ -564,22 +553,12 @@ static ngx_int_t ngx_http_add_multi_header_lines(ngx_http_request_t *r, ngx_http_header_val_t *hv, ngx_str_t *value) { - ngx_array_t *pa; ngx_table_elt_t *h, **ph; if (value->len == 0) { return NGX_OK; } - pa = (ngx_array_t *) ((char *) &r->headers_out + hv->offset); - - if (pa->elts == NULL) { - if (ngx_array_init(pa, r->pool, 1, sizeof(ngx_table_elt_t *)) != NGX_OK) - { - return NGX_ERROR; - } - } - h = ngx_list_push(&r->headers_out.headers); if (h == NULL) { return NGX_ERROR; @@ -589,12 +568,12 @@ ngx_http_add_multi_header_lines(ngx_http_request_t *r, h->key = hv->key; h->value = *value; - ph = ngx_array_push(pa); - if (ph == NULL) { - return NGX_ERROR; - } + ph = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset); + + while (*ph) { ph = &(*ph)->next; } *ph = h; + h->next = NULL; return NGX_OK; } diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index 7c4061c02..644dacd51 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -2559,22 +2559,20 @@ static ngx_int_t ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - size_t len; - u_char *p; - ngx_uint_t i, n; - ngx_table_elt_t **h; + size_t len; + u_char *p; + ngx_table_elt_t *h, *xfwd; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; - n = r->headers_in.x_forwarded_for.nelts; - h = r->headers_in.x_forwarded_for.elts; + xfwd = r->headers_in.x_forwarded_for; len = 0; - for (i = 0; i < n; i++) { - len += h[i]->value.len + sizeof(", ") - 1; + for (h = xfwd; h; h = h->next) { + len += h->value.len + sizeof(", ") - 1; } if (len == 0) { @@ -2593,8 +2591,8 @@ ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r, v->len = len; v->data = p; - for (i = 0; i < n; i++) { - p = ngx_copy(p, h[i]->value.data, h[i]->value.len); + for (h = xfwd; h; h = h->next) { + p = ngx_copy(p, h->value.data, h->value.len); *p++ = ','; *p++ = ' '; } diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c index 9586ebe07..f6731e780 100644 --- a/src/http/modules/ngx_http_realip_module.c +++ b/src/http/modules/ngx_http_realip_module.c @@ -134,9 +134,8 @@ ngx_http_realip_handler(ngx_http_request_t *r) ngx_str_t *value; ngx_uint_t i, hash; ngx_addr_t addr; - ngx_array_t *xfwd; ngx_list_part_t *part; - ngx_table_elt_t *header; + ngx_table_elt_t *header, *xfwd; ngx_connection_t *c; ngx_http_realip_ctx_t *ctx; ngx_http_realip_loc_conf_t *rlcf; @@ -168,9 +167,9 @@ ngx_http_realip_handler(ngx_http_request_t *r) case NGX_HTTP_REALIP_XFWD: - xfwd = &r->headers_in.x_forwarded_for; + xfwd = r->headers_in.x_forwarded_for; - if (xfwd->elts == NULL) { + if (xfwd == NULL) { return NGX_DECLINED; } diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c index 1e33c5c96..e52844446 100644 --- a/src/http/modules/ngx_http_userid_filter_module.c +++ b/src/http/modules/ngx_http_userid_filter_module.c @@ -319,10 +319,9 @@ ngx_http_userid_set_variable(ngx_http_request_t *r, static ngx_http_userid_ctx_t * ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf) { - ngx_int_t n; - ngx_str_t src, dst; - ngx_table_elt_t **cookies; - ngx_http_userid_ctx_t *ctx; + ngx_str_t src, dst; + ngx_table_elt_t *cookie; + ngx_http_userid_ctx_t *ctx; ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module); @@ -339,9 +338,9 @@ ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf) ngx_http_set_ctx(r, ctx, ngx_http_userid_filter_module); } - n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &conf->name, - &ctx->cookie); - if (n == NGX_DECLINED) { + cookie = ngx_http_parse_multi_header_lines(r, r->headers_in.cookie, + &conf->name, &ctx->cookie); + if (cookie == NULL) { return ctx; } @@ -349,10 +348,9 @@ ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf) "uid cookie: \"%V\"", &ctx->cookie); if (ctx->cookie.len < 22) { - cookies = r->headers_in.cookies.elts; ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "client sent too short userid cookie \"%V\"", - &cookies[n]->value); + &cookie->value); return ctx; } @@ -370,10 +368,9 @@ ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf) dst.data = (u_char *) ctx->uid_got; if (ngx_decode_base64(&dst, &src) == NGX_ERROR) { - cookies = r->headers_in.cookies.elts; ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "client sent invalid userid cookie \"%V\"", - &cookies[n]->value); + &cookie->value); return ctx; } diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs index caf7c084a..e2180e6cf 100644 --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -302,7 +302,7 @@ header_in(r, key) if (hh) { - if (hh->offset == offsetof(ngx_http_headers_in_t, cookies)) { + if (hh->offset == offsetof(ngx_http_headers_in_t, cookie)) { sep = ';'; goto multi; } @@ -327,17 +327,13 @@ header_in(r, key) /* Cookie, X-Forwarded-For */ - a = (ngx_array_t *) ((char *) &r->headers_in + hh->offset); + ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); - n = a->nelts; - - if (n == 0) { + if (*ph == NULL) { XSRETURN_UNDEF; } - ph = a->elts; - - if (n == 1) { + if ((*ph)->next == NULL) { ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); goto done; @@ -345,8 +341,8 @@ header_in(r, key) size = - (ssize_t) (sizeof("; ") - 1); - for (i = 0; i < n; i++) { - size += ph[i]->value.len + sizeof("; ") - 1; + for (h = *ph; h; h = h->next) { + size += h->value.len + sizeof("; ") - 1; } value = ngx_pnalloc(r->pool, size); @@ -357,10 +353,10 @@ header_in(r, key) p = value; - for (i = 0; /* void */ ; i++) { - p = ngx_copy(p, ph[i]->value.data, ph[i]->value.len); + for (h = *ph; h; h = h->next) { + p = ngx_copy(p, h->value.data, h->value.len); - if (i == n - 1) { + if (h->next == NULL) { break; } diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h index be8b7cd71..a7f312f41 100644 --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -103,10 +103,10 @@ ngx_int_t ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args, ngx_uint_t *flags); ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b, ngx_uint_t allow_underscores); -ngx_int_t ngx_http_parse_multi_header_lines(ngx_array_t *headers, - ngx_str_t *name, ngx_str_t *value); -ngx_int_t ngx_http_parse_set_cookie_lines(ngx_array_t *headers, - ngx_str_t *name, ngx_str_t *value); +ngx_table_elt_t *ngx_http_parse_multi_header_lines(ngx_http_request_t *r, + ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value); +ngx_table_elt_t *ngx_http_parse_set_cookie_lines(ngx_http_request_t *r, + ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value); ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len, ngx_str_t *value); void ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri, diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index ad8caad19..afb086284 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -2024,8 +2024,7 @@ ngx_http_gzip_ok(ngx_http_request_t *r) { time_t date, expires; ngx_uint_t p; - ngx_array_t *cc; - ngx_table_elt_t *e, *d, *ae; + ngx_table_elt_t *e, *d, *ae, *cc; ngx_http_core_loc_conf_t *clcf; r->gzip_tested = 1; @@ -2118,30 +2117,30 @@ ngx_http_gzip_ok(ngx_http_request_t *r) return NGX_DECLINED; } - cc = &r->headers_out.cache_control; + cc = r->headers_out.cache_control; - if (cc->elts) { + if (cc) { if ((p & NGX_HTTP_GZIP_PROXIED_NO_CACHE) - && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_cache, + && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_no_cache, NULL) - >= 0) + != NULL) { goto ok; } if ((p & NGX_HTTP_GZIP_PROXIED_NO_STORE) - && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_store, + && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_no_store, NULL) - >= 0) + != NULL) { goto ok; } if ((p & NGX_HTTP_GZIP_PROXIED_PRIVATE) - && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_private, + && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_private, NULL) - >= 0) + != NULL) { goto ok; } @@ -2712,12 +2711,12 @@ ngx_http_set_disable_symlinks(ngx_http_request_t *r, ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr, - ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies, + ngx_table_elt_t *headers, ngx_str_t *value, ngx_array_t *proxies, int recursive) { - ngx_int_t rc; - ngx_uint_t i, found; - ngx_table_elt_t **h; + ngx_int_t rc; + ngx_uint_t found; + ngx_table_elt_t *h, *next; if (headers == NULL) { return ngx_http_get_forwarded_addr_internal(r, addr, value->data, @@ -2725,16 +2724,23 @@ ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr, recursive); } - i = headers->nelts; - h = headers->elts; + /* revert headers order */ + + for (h = headers, headers = NULL; h; h = next) { + next = h->next; + h->next = headers; + headers = h; + } + + /* iterate over all headers in reverse order */ rc = NGX_DECLINED; found = 0; - while (i-- > 0) { - rc = ngx_http_get_forwarded_addr_internal(r, addr, h[i]->value.data, - h[i]->value.len, proxies, + for (h = headers; h; h = h->next) { + rc = ngx_http_get_forwarded_addr_internal(r, addr, h->value.data, + h->value.len, proxies, recursive); if (!recursive) { @@ -2753,6 +2759,14 @@ ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr, found = 1; } + /* restore headers order */ + + for (h = headers, headers = NULL; h; h = next) { + next = h->next; + h->next = headers; + headers = h; + } + return rc; } diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index 7ba64947b..49bbd4aa9 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -529,7 +529,7 @@ ngx_int_t ngx_http_set_disable_symlinks(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of); ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr, - ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies, + ngx_table_elt_t *headers, ngx_str_t *value, ngx_array_t *proxies, int recursive); ngx_int_t ngx_http_link_multi_headers(ngx_http_request_t *r); diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c index 6460da293..d4f2dae87 100644 --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -1960,27 +1960,24 @@ unsafe: } -ngx_int_t -ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name, - ngx_str_t *value) +ngx_table_elt_t * +ngx_http_parse_multi_header_lines(ngx_http_request_t *r, + ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value) { - ngx_uint_t i; - u_char *start, *last, *end, ch; - ngx_table_elt_t **h; + u_char *start, *last, *end, ch; + ngx_table_elt_t *h; - h = headers->elts; + for (h = headers; h; h = h->next) { - for (i = 0; i < headers->nelts; i++) { + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "parse header: \"%V: %V\"", &h->key, &h->value); - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, headers->pool->log, 0, - "parse header: \"%V: %V\"", &h[i]->key, &h[i]->value); - - if (name->len > h[i]->value.len) { + if (name->len > h->value.len) { continue; } - start = h[i]->value.data; - end = h[i]->value.data + h[i]->value.len; + start = h->value.data; + end = h->value.data + h->value.len; while (start < end) { @@ -1994,7 +1991,7 @@ ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name, if (value == NULL) { if (start == end || *start == ',') { - return i; + return h; } goto skip; @@ -2014,7 +2011,7 @@ ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name, value->len = last - start; value->data = start; - return i; + return h; skip: @@ -2029,31 +2026,28 @@ ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name, } } - return NGX_DECLINED; + return NULL; } -ngx_int_t -ngx_http_parse_set_cookie_lines(ngx_array_t *headers, ngx_str_t *name, - ngx_str_t *value) +ngx_table_elt_t * +ngx_http_parse_set_cookie_lines(ngx_http_request_t *r, + ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value) { - ngx_uint_t i; - u_char *start, *last, *end; - ngx_table_elt_t **h; + u_char *start, *last, *end; + ngx_table_elt_t *h; - h = headers->elts; + for (h = headers; h; h = h->next) { - for (i = 0; i < headers->nelts; i++) { + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "parse header: \"%V: %V\"", &h->key, &h->value); - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, headers->pool->log, 0, - "parse header: \"%V: %V\"", &h[i]->key, &h[i]->value); - - if (name->len >= h[i]->value.len) { + if (name->len >= h->value.len) { continue; } - start = h[i]->value.data; - end = h[i]->value.data + h[i]->value.len; + start = h->value.data; + end = h->value.data + h->value.len; if (ngx_strncasecmp(start, name->data, name->len) != 0) { continue; @@ -2077,10 +2071,10 @@ ngx_http_parse_set_cookie_lines(ngx_array_t *headers, ngx_str_t *name, value->len = last - start; value->data = start; - return i; + return h; } - return NGX_DECLINED; + return NULL; } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 44e4d89de..57fdd2f66 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -196,7 +196,7 @@ ngx_http_header_t ngx_http_headers_in[] = { ngx_http_process_header_line }, #endif - { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookies), + { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookie), ngx_http_process_multi_header_lines }, { ngx_null_string, 0, NULL } @@ -1744,6 +1744,7 @@ ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, if (*ph == NULL) { *ph = h; + h->next = NULL; } return NGX_OK; @@ -1760,6 +1761,7 @@ ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, if (*ph == NULL) { *ph = h; + h->next = NULL; return NGX_OK; } @@ -1792,6 +1794,7 @@ ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, } r->headers_in.host = h; + h->next = NULL; host = h->value; @@ -1853,6 +1856,7 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h, } r->headers_in.user_agent = h; + h->next = NULL; /* check some widespread browsers while the header is in CPU cache */ @@ -1919,27 +1923,15 @@ static ngx_int_t ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - ngx_array_t *headers; ngx_table_elt_t **ph; - headers = (ngx_array_t *) ((char *) &r->headers_in + offset); + ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset); - if (headers->elts == NULL) { - if (ngx_array_init(headers, r->pool, 1, sizeof(ngx_table_elt_t *)) - != NGX_OK) - { - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - return NGX_ERROR; - } - } - - ph = ngx_array_push(headers); - if (ph == NULL) { - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - return NGX_ERROR; - } + while (*ph) { ph = &(*ph)->next; } *ph = h; + h->next = NULL; + return NGX_OK; } diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index 52165793a..8c9eed249 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -212,7 +212,7 @@ typedef struct { ngx_table_elt_t *keep_alive; #if (NGX_HTTP_X_FORWARDED_FOR) - ngx_array_t x_forwarded_for; + ngx_table_elt_t *x_forwarded_for; #endif #if (NGX_HTTP_REALIP) @@ -231,11 +231,11 @@ typedef struct { ngx_table_elt_t *date; #endif + ngx_table_elt_t *cookie; + ngx_str_t user; ngx_str_t passwd; - ngx_array_t cookies; - ngx_str_t server; off_t content_length_n; time_t keep_alive_n; @@ -274,6 +274,9 @@ typedef struct { ngx_table_elt_t *expires; ngx_table_elt_t *etag; + ngx_table_elt_t *cache_control; + ngx_table_elt_t *link; + ngx_str_t *override_charset; size_t content_type_len; @@ -282,9 +285,6 @@ typedef struct { u_char *content_type_lowcase; ngx_uint_t content_type_hash; - ngx_array_t cache_control; - ngx_array_t link; - off_t content_length_n; off_t content_offset; time_t date_time; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 46fde8396..99d72be07 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -246,7 +246,7 @@ static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { { ngx_string("Set-Cookie"), ngx_http_upstream_process_set_cookie, - offsetof(ngx_http_upstream_headers_in_t, cookies), + offsetof(ngx_http_upstream_headers_in_t, set_cookie), ngx_http_upstream_rewrite_set_cookie, 0, 1 }, { ngx_string("Content-Disposition"), @@ -4666,26 +4666,16 @@ static ngx_int_t ngx_http_upstream_process_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - ngx_array_t *pa; ngx_table_elt_t **ph; ngx_http_upstream_t *u; u = r->upstream; - pa = &u->headers_in.cookies; + ph = &u->headers_in.set_cookie; - if (pa->elts == NULL) { - if (ngx_array_init(pa, r->pool, 1, sizeof(ngx_table_elt_t *)) != NGX_OK) - { - return NGX_ERROR; - } - } - - ph = ngx_array_push(pa); - if (ph == NULL) { - return NGX_ERROR; - } + while (*ph) { ph = &(*ph)->next; } *ph = h; + h->next = NULL; #if (NGX_HTTP_CACHE) if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE)) { @@ -4701,26 +4691,16 @@ static ngx_int_t ngx_http_upstream_process_cache_control(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - ngx_array_t *pa; ngx_table_elt_t **ph; ngx_http_upstream_t *u; u = r->upstream; - pa = &u->headers_in.cache_control; + ph = &u->headers_in.cache_control; - if (pa->elts == NULL) { - if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK) - { - return NGX_ERROR; - } - } - - ph = ngx_array_push(pa); - if (ph == NULL) { - return NGX_ERROR; - } + while (*ph) { ph = &(*ph)->next; } *ph = h; + h->next = NULL; #if (NGX_HTTP_CACHE) { @@ -5103,18 +5083,8 @@ static ngx_int_t ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - ngx_array_t *pa; ngx_table_elt_t *ho, **ph; - pa = (ngx_array_t *) ((char *) &r->headers_out + offset); - - if (pa->elts == NULL) { - if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK) - { - return NGX_ERROR; - } - } - ho = ngx_list_push(&r->headers_out.headers); if (ho == NULL) { return NGX_ERROR; @@ -5122,12 +5092,12 @@ ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r, *ho = *h; - ph = ngx_array_push(pa); - if (ph == NULL) { - return NGX_ERROR; - } + ph = (ngx_table_elt_t **) ((char *) &r->headers_out + offset); + + while (*ph) { ph = &(*ph)->next; } *ph = ho; + ho->next = NULL; return NGX_OK; } @@ -5740,9 +5710,9 @@ ngx_http_upstream_cookie_variable(ngx_http_request_t *r, s.len = name->len - (sizeof("upstream_cookie_") - 1); s.data = name->data + sizeof("upstream_cookie_") - 1; - if (ngx_http_parse_set_cookie_lines(&r->upstream->headers_in.cookies, + if (ngx_http_parse_set_cookie_lines(r, r->upstream->headers_in.set_cookie, &s, &cookie) - == NGX_DECLINED) + == NULL) { v->not_found = 1; return NGX_OK; diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index 3db7b0643..18a9c570b 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -289,8 +289,8 @@ typedef struct { ngx_table_elt_t *content_encoding; #endif - ngx_array_t cache_control; - ngx_array_t cookies; + ngx_table_elt_t *cache_control; + ngx_table_elt_t *set_cookie; off_t content_length_n; time_t last_modified_time; diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index b0f06ac7c..69462f10c 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -183,7 +183,7 @@ static ngx_http_variable_t ngx_http_core_variables[] = { #endif { ngx_string("http_cookie"), NULL, ngx_http_variable_cookies, - offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 }, + offsetof(ngx_http_request_t, headers_in.cookie), 0, 0 }, { ngx_string("content_length"), NULL, ngx_http_variable_content_length, 0, 0, 0 }, @@ -846,26 +846,21 @@ static ngx_int_t ngx_http_variable_headers_internal(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data, u_char sep) { - size_t len; - u_char *p, *end; - ngx_uint_t i, n; - ngx_array_t *a; - ngx_table_elt_t **h; + size_t len; + u_char *p; + ngx_table_elt_t *h, *th; - a = (ngx_array_t *) ((char *) r + data); - - n = a->nelts; - h = a->elts; + h = *(ngx_table_elt_t **) ((char *) r + data); len = 0; - for (i = 0; i < n; i++) { + for (th = h; th; th = th->next) { - if (h[i]->hash == 0) { + if (th->hash == 0) { continue; } - len += h[i]->value.len + 2; + len += th->value.len + 2; } if (len == 0) { @@ -879,9 +874,9 @@ ngx_http_variable_headers_internal(ngx_http_request_t *r, v->no_cacheable = 0; v->not_found = 0; - if (n == 1) { - v->len = (*h)->value.len; - v->data = (*h)->value.data; + if (h->next == NULL) { + v->len = h->value.len; + v->data = h->value.data; return NGX_OK; } @@ -894,17 +889,15 @@ ngx_http_variable_headers_internal(ngx_http_request_t *r, v->len = len; v->data = p; - end = p + len; + for (th = h; th; th = th->next) { - for (i = 0; /* void */ ; i++) { - - if (h[i]->hash == 0) { + if (th->hash == 0) { continue; } - p = ngx_copy(p, h[i]->value.data, h[i]->value.len); + p = ngx_copy(p, th->value.data, th->value.len); - if (p == end) { + if (th->next == NULL) { break; } @@ -1102,8 +1095,8 @@ ngx_http_variable_cookie(ngx_http_request_t *r, ngx_http_variable_value_t *v, s.len = name->len - (sizeof("cookie_") - 1); s.data = name->data + sizeof("cookie_") - 1; - if (ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &s, &cookie) - == NGX_DECLINED) + if (ngx_http_parse_multi_header_lines(r, r->headers_in.cookie, &s, &cookie) + == NULL) { v->not_found = 1; return NGX_OK; diff --git a/src/http/v2/ngx_http_v2_filter_module.c b/src/http/v2/ngx_http_v2_filter_module.c index 62b6a047c..5f8626a40 100644 --- a/src/http/v2/ngx_http_v2_filter_module.c +++ b/src/http/v2/ngx_http_v2_filter_module.c @@ -674,14 +674,14 @@ ngx_http_v2_header_filter(ngx_http_request_t *r) static ngx_int_t ngx_http_v2_push_resources(ngx_http_request_t *r) { - u_char *start, *end, *last; - ngx_int_t rc; - ngx_str_t path; - ngx_uint_t i, push; - ngx_table_elt_t **h; - ngx_http_v2_loc_conf_t *h2lcf; - ngx_http_complex_value_t *pushes; - ngx_str_t binary[NGX_HTTP_V2_PUSH_HEADERS]; + u_char *start, *end, *last; + ngx_int_t rc; + ngx_str_t path; + ngx_uint_t i, push; + ngx_table_elt_t *h; + ngx_http_v2_loc_conf_t *h2lcf; + ngx_http_complex_value_t *pushes; + ngx_str_t binary[NGX_HTTP_V2_PUSH_HEADERS]; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http2 push resources"); @@ -725,15 +725,13 @@ ngx_http_v2_push_resources(ngx_http_request_t *r) return NGX_OK; } - h = r->headers_out.link.elts; - - for (i = 0; i < r->headers_out.link.nelts; i++) { + for (h = r->headers_out.link; h; h = h->next) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http2 parse link: \"%V\"", &h[i]->value); + "http2 parse link: \"%V\"", &h->value); - start = h[i]->value.data; - end = h[i]->value.data + h[i]->value.len; + start = h->value.data; + end = h->value.data + h->value.len; next_link: From fcf4331a0fdaf620a75fc62ce9d31b1295db3b3c Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:35 +0300 Subject: [PATCH 11/37] All non-unique input headers are now linked lists. The ngx_http_process_multi_header_lines() function is removed, as it is exactly equivalent to ngx_http_process_header_line(). Similarly, ngx_http_variable_header() is used instead of ngx_http_variable_headers(). --- src/http/ngx_http_request.c | 38 ++++++++--------------------------- src/http/ngx_http_variables.c | 33 ++++-------------------------- 2 files changed, 12 insertions(+), 59 deletions(-) diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 57fdd2f66..131a2c83c 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -22,8 +22,6 @@ static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); -static ngx_int_t ngx_http_process_multi_header_lines(ngx_http_request_t *r, - ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r, @@ -164,7 +162,7 @@ ngx_http_header_t ngx_http_headers_in[] = { #if (NGX_HTTP_X_FORWARDED_FOR) { ngx_string("X-Forwarded-For"), offsetof(ngx_http_headers_in_t, x_forwarded_for), - ngx_http_process_multi_header_lines }, + ngx_http_process_header_line }, #endif #if (NGX_HTTP_REALIP) @@ -197,7 +195,7 @@ ngx_http_header_t ngx_http_headers_in[] = { #endif { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookie), - ngx_http_process_multi_header_lines }, + ngx_http_process_header_line }, { ngx_null_string, 0, NULL } }; @@ -1742,10 +1740,10 @@ ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset); - if (*ph == NULL) { - *ph = h; - h->next = NULL; - } + while (*ph) { ph = &(*ph)->next; } + + *ph = h; + h->next = NULL; return NGX_OK; } @@ -1851,13 +1849,10 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h, { u_char *user_agent, *msie; - if (r->headers_in.user_agent) { - return NGX_OK; + if (ngx_http_process_header_line(r, h, offset) != NGX_OK) { + return NGX_ERROR; } - r->headers_in.user_agent = h; - h->next = NULL; - /* check some widespread browsers while the header is in CPU cache */ user_agent = h->value.data; @@ -1919,23 +1914,6 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h, } -static ngx_int_t -ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h, - ngx_uint_t offset) -{ - ngx_table_elt_t **ph; - - ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset); - - while (*ph) { ph = &(*ph)->next; } - - *ph = h; - h->next = NULL; - - return NGX_OK; -} - - ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) { diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index 69462f10c..f17e90803 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -27,8 +27,6 @@ static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r, static ngx_int_t ngx_http_variable_cookies(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r, - ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_headers_internal(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data, u_char sep); @@ -178,7 +176,7 @@ static ngx_http_variable_t ngx_http_core_variables[] = { #endif #if (NGX_HTTP_X_FORWARDED_FOR) - { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_headers, + { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_header, offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 }, #endif @@ -327,10 +325,10 @@ static ngx_http_variable_t ngx_http_core_variables[] = { { ngx_string("sent_http_transfer_encoding"), NULL, ngx_http_variable_sent_transfer_encoding, 0, 0, 0 }, - { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_headers, + { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_header, offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 }, - { ngx_string("sent_http_link"), NULL, ngx_http_variable_headers, + { ngx_string("sent_http_link"), NULL, ngx_http_variable_header, offsetof(ngx_http_request_t, headers_out.link), 0, 0 }, { ngx_string("limit_rate"), ngx_http_variable_set_limit_rate, @@ -807,22 +805,7 @@ static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - ngx_table_elt_t *h; - - h = *(ngx_table_elt_t **) ((char *) r + data); - - if (h) { - v->len = h->value.len; - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - v->data = h->value.data; - - } else { - v->not_found = 1; - } - - return NGX_OK; + return ngx_http_variable_headers_internal(r, v, data, ','); } @@ -834,14 +817,6 @@ ngx_http_variable_cookies(ngx_http_request_t *r, } -static ngx_int_t -ngx_http_variable_headers(ngx_http_request_t *r, - ngx_http_variable_value_t *v, uintptr_t data) -{ - return ngx_http_variable_headers_internal(r, v, data, ','); -} - - static ngx_int_t ngx_http_variable_headers_internal(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data, u_char sep) From dab1b086ef6702811196f317b39623ad81eac505 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:36 +0300 Subject: [PATCH 12/37] Perl: all known input headers are handled identically. As all known input headers are now linked lists, these are now handled identically. In particular, this makes it possible to access properly combined values of headers not specifically handled previously, such as "Via" or "Connection". --- src/http/modules/perl/nginx.xs | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs index e2180e6cf..9e8a6a5ce 100644 --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -304,28 +304,10 @@ header_in(r, key) if (hh->offset == offsetof(ngx_http_headers_in_t, cookie)) { sep = ';'; - goto multi; - } -#if (NGX_HTTP_X_FORWARDED_FOR) - if (hh->offset == offsetof(ngx_http_headers_in_t, x_forwarded_for)) { + + } else { sep = ','; - goto multi; } -#endif - - ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); - - if (*ph) { - ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); - - goto done; - } - - XSRETURN_UNDEF; - - multi: - - /* Cookie, X-Forwarded-For */ ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); From 1d22d0f56bd1ff7ab49ce92e197056ea7f2e6523 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:38 +0300 Subject: [PATCH 13/37] Perl: combining unknown headers during $r->header_in() lookup. --- src/http/modules/perl/nginx.xs | 84 ++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs index 9e8a6a5ce..c398e77d7 100644 --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -272,7 +272,7 @@ header_in(r, key) ngx_uint_t i, n, hash; ngx_array_t *a; ngx_list_part_t *part; - ngx_table_elt_t *h, **ph; + ngx_table_elt_t *h, *header, **ph; ngx_http_header_t *hh; ngx_http_core_main_conf_t *cmcf; @@ -311,47 +311,14 @@ header_in(r, key) ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); - if (*ph == NULL) { - XSRETURN_UNDEF; - } - - if ((*ph)->next == NULL) { - ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); - - goto done; - } - - size = - (ssize_t) (sizeof("; ") - 1); - - for (h = *ph; h; h = h->next) { - size += h->value.len + sizeof("; ") - 1; - } - - value = ngx_pnalloc(r->pool, size); - if (value == NULL) { - ctx->error = 1; - croak("ngx_pnalloc() failed"); - } - - p = value; - - for (h = *ph; h; h = h->next) { - p = ngx_copy(p, h->value.data, h->value.len); - - if (h->next == NULL) { - break; - } - - *p++ = sep; *p++ = ' '; - } - - ngx_http_perl_set_targ(value, size); - - goto done; + goto found; } /* iterate over all headers */ + sep = ','; + ph = &header; + part = &r->headers_in.headers.part; h = part->elts; @@ -373,12 +340,49 @@ header_in(r, key) continue; } - ngx_http_perl_set_targ(h[i].value.data, h[i].value.len); + *ph = &h[i]; + ph = &h[i].next; + } + *ph = NULL; + ph = &header; + + found: + + if (*ph == NULL) { + XSRETURN_UNDEF; + } + + if ((*ph)->next == NULL) { + ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); goto done; } - XSRETURN_UNDEF; + size = - (ssize_t) (sizeof("; ") - 1); + + for (h = *ph; h; h = h->next) { + size += h->value.len + sizeof("; ") - 1; + } + + value = ngx_pnalloc(r->pool, size); + if (value == NULL) { + ctx->error = 1; + croak("ngx_pnalloc() failed"); + } + + p = value; + + for (h = *ph; h; h = h->next) { + p = ngx_copy(p, h->value.data, h->value.len); + + if (h->next == NULL) { + break; + } + + *p++ = sep; *p++ = ' '; + } + + ngx_http_perl_set_targ(value, size); done: From 6bf6ef394761c1ba1f06af1b515a5ad1efda99c6 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:40 +0300 Subject: [PATCH 14/37] Upstream: style. --- src/http/ngx_http_upstream.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 99d72be07..c9cfcf835 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -4691,8 +4691,8 @@ static ngx_int_t ngx_http_upstream_process_cache_control(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - ngx_table_elt_t **ph; - ngx_http_upstream_t *u; + ngx_table_elt_t **ph; + ngx_http_upstream_t *u; u = r->upstream; ph = &u->headers_in.cache_control; @@ -4980,7 +4980,11 @@ static ngx_int_t ngx_http_upstream_process_charset(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - if (r->upstream->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_CHARSET) { + ngx_http_upstream_t *u; + + u = r->upstream; + + if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_CHARSET) { return NGX_OK; } @@ -4994,13 +4998,16 @@ static ngx_int_t ngx_http_upstream_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - r->upstream->headers_in.connection = h; + ngx_http_upstream_t *u; + + u = r->upstream; + u->headers_in.connection = h; if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len, (u_char *) "close", 5 - 1) != NULL) { - r->upstream->headers_in.connection_close = 1; + u->headers_in.connection_close = 1; } return NGX_OK; @@ -5011,13 +5018,16 @@ static ngx_int_t ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - r->upstream->headers_in.transfer_encoding = h; + ngx_http_upstream_t *u; + + u = r->upstream; + u->headers_in.transfer_encoding = h; if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len, (u_char *) "chunked", 7 - 1) != NULL) { - r->upstream->headers_in.chunked = 1; + u->headers_in.chunked = 1; } return NGX_OK; From 25093473051cae249963ace3156900dcc7ef5fae Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:42 +0300 Subject: [PATCH 15/37] Upstream: simplified Content-Encoding handling. Since introduction of offset handling in ngx_http_upstream_copy_header_line() in revision 573:58475592100c, the ngx_http_upstream_copy_content_encoding() function is no longer needed, as its behaviour is exactly equivalent to ngx_http_upstream_copy_header_line() with appropriate offset. As such, the ngx_http_upstream_copy_content_encoding() function was removed. Further, the u->headers_in.content_encoding field is not used anywhere, so it was removed as well. Further, Content-Encoding handling no longer depends on NGX_HTTP_GZIP, as it can be used even without any gzip handling compiled in (for example, in the charset filter). --- src/http/ngx_http_upstream.c | 36 +++--------------------------------- src/http/ngx_http_upstream.h | 4 ---- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index c9cfcf835..4bf207ba1 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -147,11 +147,6 @@ static ngx_int_t ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r, static ngx_int_t ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); -#if (NGX_HTTP_GZIP) -static ngx_int_t ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r, - ngx_table_elt_t *h, ngx_uint_t offset); -#endif - static ngx_int_t ngx_http_upstream_add_variables(ngx_conf_t *cf); static ngx_int_t ngx_http_upstream_addr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); @@ -316,12 +311,10 @@ static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { ngx_http_upstream_process_transfer_encoding, 0, ngx_http_upstream_ignore_header_line, 0, 0 }, -#if (NGX_HTTP_GZIP) { ngx_string("Content-Encoding"), - ngx_http_upstream_process_header_line, - offsetof(ngx_http_upstream_headers_in_t, content_encoding), - ngx_http_upstream_copy_content_encoding, 0, 0 }, -#endif + ngx_http_upstream_ignore_header_line, 0, + ngx_http_upstream_copy_header_line, + offsetof(ngx_http_headers_out_t, content_encoding), 0 }, { ngx_null_string, NULL, 0, NULL, 0, 0 } }; @@ -5349,29 +5342,6 @@ ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r, } -#if (NGX_HTTP_GZIP) - -static ngx_int_t -ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r, - ngx_table_elt_t *h, ngx_uint_t offset) -{ - ngx_table_elt_t *ho; - - ho = ngx_list_push(&r->headers_out.headers); - if (ho == NULL) { - return NGX_ERROR; - } - - *ho = *h; - - r->headers_out.content_encoding = ho; - - return NGX_OK; -} - -#endif - - static ngx_int_t ngx_http_upstream_add_variables(ngx_conf_t *cf) { diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index 18a9c570b..c402d8334 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -285,10 +285,6 @@ typedef struct { ngx_table_elt_t *transfer_encoding; ngx_table_elt_t *vary; -#if (NGX_HTTP_GZIP) - ngx_table_elt_t *content_encoding; -#endif - ngx_table_elt_t *cache_control; ngx_table_elt_t *set_cookie; From bbf8ed48c455dbb95accf886d25be95d15abde1f Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:43 +0300 Subject: [PATCH 16/37] Upstream: simplified Accept-Ranges handling. The u->headers_in.accept_ranges field is not used anywhere and hence removed. --- src/http/ngx_http_upstream.c | 3 +-- src/http/ngx_http_upstream.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 4bf207ba1..b480f5559 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -259,8 +259,7 @@ static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { offsetof(ngx_http_headers_out_t, expires), 1 }, { ngx_string("Accept-Ranges"), - ngx_http_upstream_process_header_line, - offsetof(ngx_http_upstream_headers_in_t, accept_ranges), + ngx_http_upstream_ignore_header_line, 0, ngx_http_upstream_copy_allow_ranges, offsetof(ngx_http_headers_out_t, accept_ranges), 1 }, diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index c402d8334..1ccfb8f92 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -280,7 +280,6 @@ typedef struct { ngx_table_elt_t *last_modified; ngx_table_elt_t *location; - ngx_table_elt_t *accept_ranges; ngx_table_elt_t *www_authenticate; ngx_table_elt_t *transfer_encoding; ngx_table_elt_t *vary; From e59c2096ae9d561997ad2d64d61094503e6be4c3 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:45 +0300 Subject: [PATCH 17/37] All known output headers can be linked lists now. The h->next pointer properly provided as NULL in all cases where known output headers are added. Note that there are 3rd party modules which might not do this, and it might be risky to rely on this for arbitrary headers. --- src/http/modules/ngx_http_auth_basic_module.c | 1 + src/http/modules/ngx_http_auth_request_module.c | 1 + src/http/modules/ngx_http_dav_module.c | 1 + src/http/modules/ngx_http_gzip_filter_module.c | 1 + src/http/modules/ngx_http_gzip_static_module.c | 1 + src/http/modules/ngx_http_headers_filter_module.c | 2 ++ src/http/modules/ngx_http_memcached_module.c | 1 + src/http/modules/ngx_http_range_filter_module.c | 3 +++ src/http/modules/ngx_http_static_module.c | 1 + src/http/modules/perl/nginx.xs | 1 + src/http/ngx_http_core_module.c | 3 +++ src/http/ngx_http_script.c | 1 + src/http/ngx_http_special_response.c | 1 + src/http/ngx_http_upstream.c | 7 +++++++ 14 files changed, 25 insertions(+) diff --git a/src/http/modules/ngx_http_auth_basic_module.c b/src/http/modules/ngx_http_auth_basic_module.c index 069331982..02d41e88a 100644 --- a/src/http/modules/ngx_http_auth_basic_module.c +++ b/src/http/modules/ngx_http_auth_basic_module.c @@ -339,6 +339,7 @@ ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm) *p = '"'; r->headers_out.www_authenticate->hash = 1; + r->headers_out.www_authenticate->next = NULL; ngx_str_set(&r->headers_out.www_authenticate->key, "WWW-Authenticate"); r->headers_out.www_authenticate->value.data = basic; r->headers_out.www_authenticate->value.len = len; diff --git a/src/http/modules/ngx_http_auth_request_module.c b/src/http/modules/ngx_http_auth_request_module.c index bab79e496..f64ab09aa 100644 --- a/src/http/modules/ngx_http_auth_request_module.c +++ b/src/http/modules/ngx_http_auth_request_module.c @@ -154,6 +154,7 @@ ngx_http_auth_request_handler(ngx_http_request_t *r) } *ho = *h; + ho->next = NULL; r->headers_out.www_authenticate = ho; } diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c index 0cc9ae18b..cfb98929e 100644 --- a/src/http/modules/ngx_http_dav_module.c +++ b/src/http/modules/ngx_http_dav_module.c @@ -1082,6 +1082,7 @@ ngx_http_dav_location(ngx_http_request_t *r) } r->headers_out.location->hash = 1; + r->headers_out.location->next = NULL; ngx_str_set(&r->headers_out.location->key, "Location"); escape = 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, NGX_ESCAPE_URI); diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c index b8c5ccc5c..b7758690f 100644 --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -280,6 +280,7 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r) } h->hash = 1; + h->next = NULL; ngx_str_set(&h->key, "Content-Encoding"); ngx_str_set(&h->value, "gzip"); r->headers_out.content_encoding = h; diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c index 7652a9af3..66fcc5d1b 100644 --- a/src/http/modules/ngx_http_gzip_static_module.c +++ b/src/http/modules/ngx_http_gzip_static_module.c @@ -242,6 +242,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r) } h->hash = 1; + h->next = NULL; ngx_str_set(&h->key, "Content-Encoding"); ngx_str_set(&h->value, "gzip"); r->headers_out.content_encoding = h; diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c index 995beb41b..50295f452 100644 --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -362,6 +362,7 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) } r->headers_out.expires = e; + e->next = NULL; e->hash = 1; ngx_str_set(&e->key, "Expires"); @@ -621,6 +622,7 @@ ngx_http_set_response_header(ngx_http_request_t *r, ngx_http_header_val_t *hv, } *old = h; + h->next = NULL; } h->hash = 1; diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c index c82df6e33..11bbd9165 100644 --- a/src/http/modules/ngx_http_memcached_module.c +++ b/src/http/modules/ngx_http_memcached_module.c @@ -401,6 +401,7 @@ found: } h->hash = 1; + h->next = NULL; ngx_str_set(&h->key, "Content-Encoding"); ngx_str_set(&h->value, "gzip"); r->headers_out.content_encoding = h; diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c index ae08ebbc5..fa408b792 100644 --- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -258,6 +258,7 @@ next_filter: } r->headers_out.accept_ranges->hash = 1; + r->headers_out.accept_ranges->next = NULL; ngx_str_set(&r->headers_out.accept_ranges->key, "Accept-Ranges"); ngx_str_set(&r->headers_out.accept_ranges->value, "bytes"); @@ -427,6 +428,7 @@ ngx_http_range_singlepart_header(ngx_http_request_t *r, r->headers_out.content_range = content_range; content_range->hash = 1; + content_range->next = NULL; ngx_str_set(&content_range->key, "Content-Range"); content_range->value.data = ngx_pnalloc(r->pool, @@ -599,6 +601,7 @@ ngx_http_range_not_satisfiable(ngx_http_request_t *r) r->headers_out.content_range = content_range; content_range->hash = 1; + content_range->next = NULL; ngx_str_set(&content_range->key, "Content-Range"); content_range->value.data = ngx_pnalloc(r->pool, diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c index cf29d5a6d..e30565d4e 100644 --- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_static_module.c @@ -195,6 +195,7 @@ ngx_http_static_handler(ngx_http_request_t *r) } r->headers_out.location->hash = 1; + r->headers_out.location->next = NULL; ngx_str_set(&r->headers_out.location->key, "Location"); r->headers_out.location->value.len = len; r->headers_out.location->value.data = location; diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs index c398e77d7..da1227952 100644 --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -573,6 +573,7 @@ header_out(r, key, value) } header->hash = 1; + header->next = NULL; if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) { header->hash = 0; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index afb086284..0c7dd3f99 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1007,6 +1007,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r, } r->headers_out.location->hash = 1; + r->headers_out.location->next = NULL; ngx_str_set(&r->headers_out.location->key, "Location"); if (r->args.len == 0) { @@ -1687,6 +1688,7 @@ ngx_http_set_etag(ngx_http_request_t *r) } etag->hash = 1; + etag->next = NULL; ngx_str_set(&etag->key, "ETag"); etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3); @@ -1781,6 +1783,7 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status, } r->headers_out.location->hash = 1; + r->headers_out.location->next = NULL; ngx_str_set(&r->headers_out.location->key, "Location"); r->headers_out.location->value = val; diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c index bebdbd92b..a2b9f1b7b 100644 --- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -1243,6 +1243,7 @@ ngx_http_script_regex_end_code(ngx_http_script_engine_t *e) } r->headers_out.location->hash = 1; + r->headers_out.location->next = NULL; ngx_str_set(&r->headers_out.location->key, "Location"); r->headers_out.location->value = e->buf; diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c index 72f56fd9a..eaf42e399 100644 --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -649,6 +649,7 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page) } location->hash = 1; + location->next = NULL; ngx_str_set(&location->key, "Location"); location->value = uri; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index b480f5559..73936f714 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -2681,6 +2681,7 @@ ngx_http_upstream_intercept_errors(ngx_http_request_t *r, } *h = *u->headers_in.www_authenticate; + h->next = NULL; r->headers_out.www_authenticate = h; } @@ -5075,6 +5076,7 @@ ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, if (offset) { ph = (ngx_table_elt_t **) ((char *) &r->headers_out + offset); *ph = ho; + ho->next = NULL; } return NGX_OK; @@ -5169,6 +5171,7 @@ ngx_http_upstream_copy_last_modified(ngx_http_request_t *r, ngx_table_elt_t *h, } *ho = *h; + ho->next = NULL; r->headers_out.last_modified = ho; r->headers_out.last_modified_time = @@ -5191,6 +5194,7 @@ ngx_http_upstream_rewrite_location(ngx_http_request_t *r, ngx_table_elt_t *h, } *ho = *h; + ho->next = NULL; if (r->upstream->rewrite_redirect) { rc = r->upstream->rewrite_redirect(r, ho, 0); @@ -5236,6 +5240,7 @@ ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, ngx_table_elt_t *h, } *ho = *h; + ho->next = NULL; if (r->upstream->rewrite_redirect) { @@ -5281,6 +5286,7 @@ ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, } *ho = *h; + ho->next = NULL; if (r->upstream->rewrite_cookie) { rc = r->upstream->rewrite_cookie(r, ho); @@ -5334,6 +5340,7 @@ ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r, } *ho = *h; + ho->next = NULL; r->headers_out.accept_ranges = ho; From 268f0cba8887ba77b6a2c97a8732df2784fe6001 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:46 +0300 Subject: [PATCH 18/37] Upstream: all known headers in u->headers_in are linked lists now. --- src/http/modules/ngx_http_proxy_module.c | 2 ++ src/http/ngx_http_upstream.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index 644dacd51..20b11097d 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -1965,6 +1965,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r) ngx_str_set(&h->key, "Server"); ngx_str_null(&h->value); h->lowcase_key = (u_char *) "server"; + h->next = NULL; } if (r->upstream->headers_in.date == NULL) { @@ -1978,6 +1979,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r) ngx_str_set(&h->key, "Date"); ngx_str_null(&h->value); h->lowcase_key = (u_char *) "date"; + h->next = NULL; } /* clear content length if response is chunked */ diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 73936f714..a111de826 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -4610,6 +4610,7 @@ ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, if (*ph == NULL) { *ph = h; + h->next = NULL; } return NGX_OK; @@ -4632,6 +4633,7 @@ ngx_http_upstream_process_content_length(ngx_http_request_t *r, u = r->upstream; + h->next = NULL; u->headers_in.content_length = h; u->headers_in.content_length_n = ngx_atoof(h->value.data, h->value.len); @@ -4647,6 +4649,7 @@ ngx_http_upstream_process_last_modified(ngx_http_request_t *r, u = r->upstream; + h->next = NULL; u->headers_in.last_modified = h; u->headers_in.last_modified_time = ngx_parse_http_time(h->value.data, h->value.len); @@ -4816,6 +4819,7 @@ ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h, u = r->upstream; u->headers_in.expires = h; + h->next = NULL; #if (NGX_HTTP_CACHE) { @@ -4856,6 +4860,7 @@ ngx_http_upstream_process_accel_expires(ngx_http_request_t *r, u = r->upstream; u->headers_in.x_accel_expires = h; + h->next = NULL; #if (NGX_HTTP_CACHE) { @@ -4915,6 +4920,7 @@ ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h, u = r->upstream; u->headers_in.x_accel_limit_rate = h; + h->next = NULL; if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE) { return NGX_OK; @@ -4995,6 +5001,7 @@ ngx_http_upstream_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h, u = r->upstream; u->headers_in.connection = h; + h->next = NULL; if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len, (u_char *) "close", 5 - 1) @@ -5015,6 +5022,7 @@ ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r, u = r->upstream; u->headers_in.transfer_encoding = h; + h->next = NULL; if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len, (u_char *) "chunked", 7 - 1) @@ -5035,6 +5043,7 @@ ngx_http_upstream_process_vary(ngx_http_request_t *r, u = r->upstream; u->headers_in.vary = h; + h->next = NULL; #if (NGX_HTTP_CACHE) From d22157fade0c3dc05b860be8d7e3eff4a56cb7d3 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:48 +0300 Subject: [PATCH 19/37] Upstream: header handlers can now return parsing errors. With this change, duplicate Content-Length and Transfer-Encoding headers are now rejected. Further, responses with invalid Content-Length or Transfer-Encoding headers are now rejected, as well as responses with both Content-Length and Transfer-Encoding. --- src/http/modules/ngx_http_fastcgi_module.c | 8 +++- src/http/modules/ngx_http_grpc_module.c | 8 +++- src/http/modules/ngx_http_proxy_module.c | 8 +++- src/http/modules/ngx_http_scgi_module.c | 8 +++- src/http/modules/ngx_http_uwsgi_module.c | 8 +++- src/http/ngx_http_upstream.c | 53 ++++++++++++++++++++-- 6 files changed, 80 insertions(+), 13 deletions(-) diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c index 17b7e83a3..2d9a18f90 100644 --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -2007,8 +2007,12 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r) hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, h->lowcase_key, h->key.len); - if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { - return NGX_ERROR; + if (hh) { + rc = hh->handler(r, h, hh->offset); + + if (rc != NGX_OK) { + return rc; + } } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c index 864fc4fda..a64658f72 100644 --- a/src/http/modules/ngx_http_grpc_module.c +++ b/src/http/modules/ngx_http_grpc_module.c @@ -1891,8 +1891,12 @@ ngx_http_grpc_process_header(ngx_http_request_t *r) hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, h->lowcase_key, h->key.len); - if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { - return NGX_ERROR; + if (hh) { + rc = hh->handler(r, h, hh->offset); + + if (rc != NGX_OK) { + return rc; + } } continue; diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index 20b11097d..e8df555b9 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -1930,8 +1930,12 @@ ngx_http_proxy_process_header(ngx_http_request_t *r) hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, h->lowcase_key, h->key.len); - if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { - return NGX_ERROR; + if (hh) { + rc = hh->handler(r, h, hh->offset); + + if (rc != NGX_OK) { + return rc; + } } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c index cc865fdc1..9fc18dcd3 100644 --- a/src/http/modules/ngx_http_scgi_module.c +++ b/src/http/modules/ngx_http_scgi_module.c @@ -1114,8 +1114,12 @@ ngx_http_scgi_process_header(ngx_http_request_t *r) hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, h->lowcase_key, h->key.len); - if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { - return NGX_ERROR; + if (hh) { + rc = hh->handler(r, h, hh->offset); + + if (rc != NGX_OK) { + return rc; + } } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c index a1a76f623..5078ef773 100644 --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -1340,8 +1340,12 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r) hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, h->lowcase_key, h->key.len); - if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { - return NGX_ERROR; + if (hh) { + rc = hh->handler(r, h, hh->offset); + + if (rc != NGX_OK) { + return rc; + } } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index a111de826..8cc4ea5ad 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -4633,10 +4633,34 @@ ngx_http_upstream_process_content_length(ngx_http_request_t *r, u = r->upstream; + if (u->headers_in.content_length) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent duplicate header line: \"%V: %V\", " + "previous value: \"%V: %V\"", + &h->key, &h->value, + &u->headers_in.content_length->key, + &u->headers_in.content_length->value); + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + } + + if (u->headers_in.transfer_encoding) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent \"Content-Length\" and " + "\"Transfer-Encoding\" headers at the same time"); + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + } + h->next = NULL; u->headers_in.content_length = h; u->headers_in.content_length_n = ngx_atoof(h->value.data, h->value.len); + if (u->headers_in.content_length_n == NGX_ERROR) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent invalid \"Content-Length\" header: " + "\"%V: %V\"", &h->key, &h->value); + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + } + return NGX_OK; } @@ -5021,14 +5045,37 @@ ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r, ngx_http_upstream_t *u; u = r->upstream; + + if (u->headers_in.transfer_encoding) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent duplicate header line: \"%V: %V\", " + "previous value: \"%V: %V\"", + &h->key, &h->value, + &u->headers_in.transfer_encoding->key, + &u->headers_in.transfer_encoding->value); + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + } + + if (u->headers_in.content_length) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent \"Content-Length\" and " + "\"Transfer-Encoding\" headers at the same time"); + return NGX_HTTP_UPSTREAM_INVALID_HEADER; + } + u->headers_in.transfer_encoding = h; h->next = NULL; - if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len, - (u_char *) "chunked", 7 - 1) - != NULL) + if (h->value.len == 7 + && ngx_strncasecmp(h->value.data, (u_char *) "chunked", 7) == 0) { u->headers_in.chunked = 1; + + } else { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent unknown \"Transfer-Encoding\": \"%V\"", + &h->value); + return NGX_HTTP_UPSTREAM_INVALID_HEADER; } return NGX_OK; From b8815c797a3e33ae1249886f9fa80b2188eadd0b Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:49 +0300 Subject: [PATCH 20/37] Upstream: duplicate headers ignored or properly linked. Most of the known duplicate upstream response headers are now ignored with a warning. If syntax permits multiple headers, these are now properly linked to the lists, notably Vary and WWW-Authenticate. This makes it possible to further handle such lists where it makes sense. --- src/http/ngx_http_upstream.c | 112 ++++++++++++++++++++++++++++++++--- src/http/ngx_http_upstream.h | 1 + 2 files changed, 104 insertions(+), 9 deletions(-) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 8cc4ea5ad..7482bc9bd 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -101,6 +101,9 @@ static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); +static ngx_int_t + ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r, + ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_upstream_process_content_length(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_upstream_process_last_modified(ngx_http_request_t *r, @@ -226,7 +229,7 @@ static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { offsetof(ngx_http_headers_out_t, server), 0 }, { ngx_string("WWW-Authenticate"), - ngx_http_upstream_process_header_line, + ngx_http_upstream_process_multi_header_lines, offsetof(ngx_http_upstream_headers_in_t, www_authenticate), ngx_http_upstream_copy_header_line, 0, 0 }, @@ -236,7 +239,8 @@ static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { ngx_http_upstream_rewrite_location, 0, 0 }, { ngx_string("Refresh"), - ngx_http_upstream_ignore_header_line, 0, + ngx_http_upstream_process_header_line, + offsetof(ngx_http_upstream_headers_in_t, refresh), ngx_http_upstream_rewrite_refresh, 0, 0 }, { ngx_string("Set-Cookie"), @@ -2804,6 +2808,10 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u) i = 0; } + if (h[i].hash == 0) { + continue; + } + hh = ngx_hash_find(&umcf->headers_in_hash, h[i].hash, h[i].lowcase_key, h[i].key.len); @@ -2857,6 +2865,10 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u) i = 0; } + if (h[i].hash == 0) { + continue; + } + if (ngx_hash_find(&u->conf->hide_headers_hash, h[i].hash, h[i].lowcase_key, h[i].key.len)) { @@ -4608,11 +4620,36 @@ ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ph = (ngx_table_elt_t **) ((char *) &r->upstream->headers_in + offset); - if (*ph == NULL) { - *ph = h; - h->next = NULL; + if (*ph) { + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, + "upstream sent duplicate header line: \"%V: %V\", " + "previous value: \"%V: %V\", ignored", + &h->key, &h->value, + &(*ph)->key, &(*ph)->value); + h->hash = 0; + return NGX_OK; } + *ph = h; + h->next = NULL; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r, + ngx_table_elt_t *h, ngx_uint_t offset) +{ + ngx_table_elt_t **ph; + + ph = (ngx_table_elt_t **) ((char *) &r->upstream->headers_in + offset); + + while (*ph) { ph = &(*ph)->next; } + + *ph = h; + h->next = NULL; + return NGX_OK; } @@ -4673,6 +4710,17 @@ ngx_http_upstream_process_last_modified(ngx_http_request_t *r, u = r->upstream; + if (u->headers_in.last_modified) { + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, + "upstream sent duplicate header line: \"%V: %V\", " + "previous value: \"%V: %V\", ignored", + &h->key, &h->value, + &u->headers_in.last_modified->key, + &u->headers_in.last_modified->value); + h->hash = 0; + return NGX_OK; + } + h->next = NULL; u->headers_in.last_modified = h; u->headers_in.last_modified_time = ngx_parse_http_time(h->value.data, @@ -4842,6 +4890,18 @@ ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_http_upstream_t *u; u = r->upstream; + + if (u->headers_in.expires) { + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, + "upstream sent duplicate header line: \"%V: %V\", " + "previous value: \"%V: %V\", ignored", + &h->key, &h->value, + &u->headers_in.expires->key, + &u->headers_in.expires->value); + h->hash = 0; + return NGX_OK; + } + u->headers_in.expires = h; h->next = NULL; @@ -4883,6 +4943,18 @@ ngx_http_upstream_process_accel_expires(ngx_http_request_t *r, ngx_http_upstream_t *u; u = r->upstream; + + if (u->headers_in.x_accel_expires) { + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, + "upstream sent duplicate header line: \"%V: %V\", " + "previous value: \"%V: %V\", ignored", + &h->key, &h->value, + &u->headers_in.x_accel_expires->key, + &u->headers_in.x_accel_expires->value); + h->hash = 0; + return NGX_OK; + } + u->headers_in.x_accel_expires = h; h->next = NULL; @@ -4943,6 +5015,18 @@ ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_http_upstream_t *u; u = r->upstream; + + if (u->headers_in.x_accel_limit_rate) { + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, + "upstream sent duplicate header line: \"%V: %V\", " + "previous value: \"%V: %V\", ignored", + &h->key, &h->value, + &u->headers_in.x_accel_limit_rate->key, + &u->headers_in.x_accel_limit_rate->value); + h->hash = 0; + return NGX_OK; + } + u->headers_in.x_accel_limit_rate = h; h->next = NULL; @@ -5021,10 +5105,15 @@ static ngx_int_t ngx_http_upstream_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - ngx_http_upstream_t *u; + ngx_table_elt_t **ph; + ngx_http_upstream_t *u; u = r->upstream; - u->headers_in.connection = h; + ph = &u->headers_in.connection; + + while (*ph) { ph = &(*ph)->next; } + + *ph = h; h->next = NULL; if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len, @@ -5086,10 +5175,15 @@ static ngx_int_t ngx_http_upstream_process_vary(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - ngx_http_upstream_t *u; + ngx_table_elt_t **ph; + ngx_http_upstream_t *u; u = r->upstream; - u->headers_in.vary = h; + ph = &u->headers_in.vary; + + while (*ph) { ph = &(*ph)->next; } + + *ph = h; h->next = NULL; #if (NGX_HTTP_CACHE) diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index 1ccfb8f92..28d1cfbed 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -280,6 +280,7 @@ typedef struct { ngx_table_elt_t *last_modified; ngx_table_elt_t *location; + ngx_table_elt_t *refresh; ngx_table_elt_t *www_authenticate; ngx_table_elt_t *transfer_encoding; ngx_table_elt_t *vary; From 260f48816e06cc1641b0961547bedd1e088a97eb Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:51 +0300 Subject: [PATCH 21/37] Upstream: handling of multiple Vary headers (ticket #1423). Previously, only the last header value was used when caching. --- src/http/ngx_http_upstream.c | 48 ++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 7482bc9bd..e68d7aab0 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -5175,6 +5175,9 @@ static ngx_int_t ngx_http_upstream_process_vary(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { + u_char *p; + size_t len; + ngx_str_t vary; ngx_table_elt_t **ph; ngx_http_upstream_t *u; @@ -5192,17 +5195,52 @@ ngx_http_upstream_process_vary(ngx_http_request_t *r, return NGX_OK; } - if (r->cache == NULL) { + if (r->cache == NULL || !u->cacheable) { return NGX_OK; } - if (h->value.len > NGX_HTTP_CACHE_VARY_LEN - || (h->value.len == 1 && h->value.data[0] == '*')) - { + if (h->value.len == 1 && h->value.data[0] == '*') { + u->cacheable = 0; + return NGX_OK; + } + + if (u->headers_in.vary->next) { + + len = 0; + + for (h = u->headers_in.vary; h; h = h->next) { + len += h->value.len + 2; + } + + len -= 2; + + p = ngx_pnalloc(r->pool, len); + if (p == NULL) { + return NGX_ERROR; + } + + vary.len = len; + vary.data = p; + + for (h = u->headers_in.vary; h; h = h->next) { + p = ngx_copy(p, h->value.data, h->value.len); + + if (h->next == NULL) { + break; + } + + *p++ = ','; *p++ = ' '; + } + + } else { + vary = h->value; + } + + if (vary.len > NGX_HTTP_CACHE_VARY_LEN) { u->cacheable = 0; } - r->cache->vary = h->value; + r->cache->vary = vary; #endif From 87465e089b169f58a6bdd99ab0e7e9fcc79edda1 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:53 +0300 Subject: [PATCH 22/37] Upstream: multiple WWW-Authenticate headers (ticket #485). When using proxy_intercept_errors and an error page for error 401 (Unauthorized), multiple WWW-Authenticate headers from the upstream server response are now properly copied to the response. --- src/http/ngx_http_upstream.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index e68d7aab0..80b4a37be 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -2647,7 +2647,7 @@ ngx_http_upstream_intercept_errors(ngx_http_request_t *r, { ngx_int_t status; ngx_uint_t i; - ngx_table_elt_t *h; + ngx_table_elt_t *h, *ho, **ph; ngx_http_err_page_t *err_page; ngx_http_core_loc_conf_t *clcf; @@ -2676,18 +2676,26 @@ ngx_http_upstream_intercept_errors(ngx_http_request_t *r, if (status == NGX_HTTP_UNAUTHORIZED && u->headers_in.www_authenticate) { - h = ngx_list_push(&r->headers_out.headers); + h = u->headers_in.www_authenticate; + ph = &r->headers_out.www_authenticate; - if (h == NULL) { - ngx_http_upstream_finalize_request(r, u, + while (h) { + ho = ngx_list_push(&r->headers_out.headers); + + if (ho == NULL) { + ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); - return NGX_OK; + return NGX_OK; + } + + *ho = *h; + ho->next = NULL; + + *ph = ho; + ph = &ho->next; + + h = h->next; } - - *h = *u->headers_in.www_authenticate; - h->next = NULL; - - r->headers_out.www_authenticate = h; } #if (NGX_HTTP_CACHE) From 911c95bfd3a17632c6f3d8c2f261055520278cc7 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:54 +0300 Subject: [PATCH 23/37] Auth request: multiple WWW-Authenticate headers (ticket #485). When using auth_request with an upstream server which returns 401 (Unauthorized), multiple WWW-Authenticate headers from the upstream server response are now properly copied to the response. --- src/http/modules/ngx_http_auth_request_module.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/http/modules/ngx_http_auth_request_module.c b/src/http/modules/ngx_http_auth_request_module.c index f64ab09aa..8bc98aae6 100644 --- a/src/http/modules/ngx_http_auth_request_module.c +++ b/src/http/modules/ngx_http_auth_request_module.c @@ -101,7 +101,7 @@ ngx_module_t ngx_http_auth_request_module = { static ngx_int_t ngx_http_auth_request_handler(ngx_http_request_t *r) { - ngx_table_elt_t *h, *ho; + ngx_table_elt_t *h, *ho, **ph; ngx_http_request_t *sr; ngx_http_post_subrequest_t *ps; ngx_http_auth_request_ctx_t *ctx; @@ -147,7 +147,9 @@ ngx_http_auth_request_handler(ngx_http_request_t *r) h = sr->upstream->headers_in.www_authenticate; } - if (h) { + ph = &r->headers_out.www_authenticate; + + while (h) { ho = ngx_list_push(&r->headers_out.headers); if (ho == NULL) { return NGX_ERROR; @@ -156,7 +158,10 @@ ngx_http_auth_request_handler(ngx_http_request_t *r) *ho = *h; ho->next = NULL; - r->headers_out.www_authenticate = ho; + *ph = ho; + ph = &ho->next; + + h = h->next; } return ctx->status; From f74e1ea9959f714dd8c284a7811b97815171adc3 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:56 +0300 Subject: [PATCH 24/37] Multiple WWW-Authenticate headers with "satisfy any;". If a module adds multiple WWW-Authenticate headers (ticket #485) to the response, linked in r->headers_out.www_authenticate, all headers are now cleared if another module later allows access. This change is a nop for standard modules, since the only access module which can add multiple WWW-Authenticate headers is the auth request module, and it is checked after other standard access modules. Though this might affect some third party access modules. Note that if a 3rd party module adds a single WWW-Authenticate header and not yet modified to set the header's next pointer to NULL, attempt to clear such a header with this change will result in a segmentation fault. --- src/http/ngx_http_core_module.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 0c7dd3f99..28f7d99b4 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1088,6 +1088,7 @@ ngx_int_t ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph) { ngx_int_t rc; + ngx_table_elt_t *h; ngx_http_core_loc_conf_t *clcf; if (r != r->main) { @@ -1122,8 +1123,8 @@ ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph) if (rc == NGX_OK) { r->access_code = 0; - if (r->headers_out.www_authenticate) { - r->headers_out.www_authenticate->hash = 0; + for (h = r->headers_out.www_authenticate; h; h = h->next) { + h->hash = 0; } r->phase_handler = ph->next; From 887d51938ff8ce853e76f746e6a080a18005f6d3 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:57 +0300 Subject: [PATCH 25/37] Headers filter: improved memory allocation error handling. --- src/http/modules/ngx_http_headers_filter_module.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c index 50295f452..90e6da8b3 100644 --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -377,6 +377,7 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) cc = ngx_list_push(&r->headers_out.headers); if (cc == NULL) { + e->hash = 0; return NGX_ERROR; } @@ -410,6 +411,8 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) e->value.data = ngx_pnalloc(r->pool, len); if (e->value.data == NULL) { + e->hash = 0; + cc->hash = 0; return NGX_ERROR; } @@ -447,6 +450,7 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf) cc->value.data = ngx_pnalloc(r->pool, sizeof("max-age=") + NGX_TIME_T_LEN + 1); if (cc->value.data == NULL) { + cc->hash = 0; return NGX_ERROR; } From bfc5b35827903a3c543b58e4562db8b62021c164 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 31 May 2022 00:14:11 +0300 Subject: [PATCH 26/37] Upstream: fixed build without http cache (broken by cd73509f21e2). --- src/http/ngx_http_upstream.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 80b4a37be..fa71949a5 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -5183,9 +5183,6 @@ static ngx_int_t ngx_http_upstream_process_vary(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - u_char *p; - size_t len; - ngx_str_t vary; ngx_table_elt_t **ph; ngx_http_upstream_t *u; @@ -5198,6 +5195,10 @@ ngx_http_upstream_process_vary(ngx_http_request_t *r, h->next = NULL; #if (NGX_HTTP_CACHE) + { + u_char *p; + size_t len; + ngx_str_t vary; if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_VARY) { return NGX_OK; @@ -5249,7 +5250,7 @@ ngx_http_upstream_process_vary(ngx_http_request_t *r, } r->cache->vary = vary; - + } #endif return NGX_OK; From 8df3ad13c5bb10360221f25ca45ae03dd09e1c3b Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 7 Jun 2022 00:07:12 +0300 Subject: [PATCH 27/37] Upstream: fixed X-Accel-Expires/Cache-Control/Expires handling. Previously, if caching was disabled due to Expires in the past, nginx failed to cache the response even if it was cacheable as per subsequently parsed Cache-Control header (ticket #964). Similarly, if caching was disabled due to Expires in the past, "Cache-Control: no-cache" or "Cache-Control: max-age=0", caching was not used if it was cacheable as per subsequently parsed X-Accel-Expires header. Fix is to avoid disabling caching immediately after parsing Expires in the past or Cache-Control, but rather set flags which are later checked by ngx_http_upstream_process_headers() (and cleared by "Cache-Control: max-age" and X-Accel-Expires). Additionally, now X-Accel-Expires does not prevent parsing of cache control extensions, notably stale-while-revalidate and stale-if-error. This ensures that order of the X-Accel-Expires and Cache-Control headers is not important. Prodded by Vadim Fedorenko and Yugo Horie. --- src/http/ngx_http_upstream.c | 29 ++++++++++++++++++++++------- src/http/ngx_http_upstream.h | 2 ++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index fa71949a5..ead371556 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -2702,6 +2702,10 @@ ngx_http_upstream_intercept_errors(ngx_http_request_t *r, if (r->cache) { + if (u->headers_in.no_cache || u->headers_in.expired) { + u->cacheable = 0; + } + if (u->cacheable) { time_t valid; @@ -2796,6 +2800,10 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u) umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); + if (u->headers_in.no_cache || u->headers_in.expired) { + u->cacheable = 0; + } + if (u->headers_in.x_accel_redirect && !(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT)) { @@ -4791,18 +4799,18 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r, return NGX_OK; } - if (r->cache->valid_sec != 0 && u->headers_in.x_accel_expires != NULL) { - return NGX_OK; - } - start = h->value.data; last = start + h->value.len; + if (r->cache->valid_sec != 0 && u->headers_in.x_accel_expires != NULL) { + goto extensions; + } + if (ngx_strlcasestrn(start, last, (u_char *) "no-cache", 8 - 1) != NULL || ngx_strlcasestrn(start, last, (u_char *) "no-store", 8 - 1) != NULL || ngx_strlcasestrn(start, last, (u_char *) "private", 7 - 1) != NULL) { - u->cacheable = 0; + u->headers_in.no_cache = 1; return NGX_OK; } @@ -4832,13 +4840,16 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r, } if (n == 0) { - u->cacheable = 0; + u->headers_in.no_cache = 1; return NGX_OK; } r->cache->valid_sec = ngx_time() + n; + u->headers_in.expired = 0; } +extensions: + p = ngx_strlcasestrn(start, last, (u_char *) "stale-while-revalidate=", 23 - 1); @@ -4932,7 +4943,7 @@ ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h, expires = ngx_parse_http_time(h->value.data, h->value.len); if (expires == NGX_ERROR || expires < ngx_time()) { - u->cacheable = 0; + u->headers_in.expired = 1; return NGX_OK; } @@ -4996,6 +5007,8 @@ ngx_http_upstream_process_accel_expires(ngx_http_request_t *r, default: r->cache->valid_sec = ngx_time() + n; + u->headers_in.no_cache = 0; + u->headers_in.expired = 0; return NGX_OK; } } @@ -5007,6 +5020,8 @@ ngx_http_upstream_process_accel_expires(ngx_http_request_t *r, if (n != NGX_ERROR) { r->cache->valid_sec = n; + u->headers_in.no_cache = 0; + u->headers_in.expired = 0; } } #endif diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h index 28d1cfbed..9a17a03a8 100644 --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -293,6 +293,8 @@ typedef struct { unsigned connection_close:1; unsigned chunked:1; + unsigned no_cache:1; + unsigned expired:1; } ngx_http_upstream_headers_in_t; From f08dbefadf083b8546423e35d8d12ba27e46efa8 Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Tue, 7 Jun 2022 20:08:57 +0400 Subject: [PATCH 28/37] Upstream: handling of certificates specified as an empty string. Now, if the directive is given an empty string, such configuration cancels loading of certificates, in particular, if they would be otherwise inherited from the previous level. This restores previous behaviour, before variables support in certificates was introduced (3ab8e1e2f0f7). --- src/http/modules/ngx_http_grpc_module.c | 5 +++-- src/http/modules/ngx_http_proxy_module.c | 5 +++-- src/http/modules/ngx_http_uwsgi_module.c | 5 +++-- src/http/ngx_http_upstream.c | 6 ++++-- src/stream/ngx_stream_proxy_module.c | 11 +++++++---- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c index a64658f72..617814ec9 100644 --- a/src/http/modules/ngx_http_grpc_module.c +++ b/src/http/modules/ngx_http_grpc_module.c @@ -4906,8 +4906,9 @@ ngx_http_grpc_set_ssl(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *glcf) return NGX_ERROR; } - if (glcf->upstream.ssl_certificate) { - + if (glcf->upstream.ssl_certificate + && glcf->upstream.ssl_certificate->value.len) + { if (glcf->upstream.ssl_certificate_key == NULL) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"grpc_ssl_certificate_key\" is defined " diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index e8df555b9..bb930305d 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -4955,8 +4955,9 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf) return NGX_ERROR; } - if (plcf->upstream.ssl_certificate) { - + if (plcf->upstream.ssl_certificate + && plcf->upstream.ssl_certificate->value.len) + { if (plcf->upstream.ssl_certificate_key == NULL) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"proxy_ssl_certificate_key\" is defined " diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c index 5078ef773..1dcee1e6c 100644 --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -2487,8 +2487,9 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf) return NGX_ERROR; } - if (uwcf->upstream.ssl_certificate) { - + if (uwcf->upstream.ssl_certificate + && uwcf->upstream.ssl_certificate->value.len) + { if (uwcf->upstream.ssl_certificate_key == NULL) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"uwsgi_ssl_certificate_key\" is defined " diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index ead371556..3ae822bb8 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -1690,8 +1690,10 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, } } - if (u->conf->ssl_certificate && (u->conf->ssl_certificate->lengths - || u->conf->ssl_certificate_key->lengths)) + if (u->conf->ssl_certificate + && u->conf->ssl_certificate->value.len + && (u->conf->ssl_certificate->lengths + || u->conf->ssl_certificate_key->lengths)) { if (ngx_http_upstream_ssl_certificate(r, u, c) != NGX_OK) { ngx_http_upstream_finalize_request(r, u, diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c index 934e7d8f2..683f7d7a4 100644 --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -1069,8 +1069,10 @@ ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s) } } - if (pscf->ssl_certificate && (pscf->ssl_certificate->lengths - || pscf->ssl_certificate_key->lengths)) + if (pscf->ssl_certificate + && pscf->ssl_certificate->value.len + && (pscf->ssl_certificate->lengths + || pscf->ssl_certificate_key->lengths)) { if (ngx_stream_proxy_ssl_certificate(s) != NGX_OK) { ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); @@ -2225,8 +2227,9 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf) return NGX_ERROR; } - if (pscf->ssl_certificate) { - + if (pscf->ssl_certificate + && pscf->ssl_certificate->value.len) + { if (pscf->ssl_certificate_key == NULL) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"proxy_ssl_certificate_key\" is defined " From 80fc2ddf57558ec43b94220ce2d3d88e2e470c75 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 7 Jun 2022 21:58:52 +0300 Subject: [PATCH 29/37] Mp4: fixed potential overflow in ngx_http_mp4_crop_stts_data(). Both "count" and "duration" variables are 32-bit, so their product might potentially overflow. It is used to reduce 64-bit start_time variable, and with very large start_time this can result in incorrect seeking. Found by Coverity (CID 1499904). --- src/http/modules/ngx_http_mp4_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c index 9c3f627fe..5721efbe6 100644 --- a/src/http/modules/ngx_http_mp4_module.c +++ b/src/http/modules/ngx_http_mp4_module.c @@ -2331,7 +2331,7 @@ ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4, } start_sample += count; - start_time -= count * duration; + start_time -= (uint64_t) count * duration; entries--; entry++; } From d7994be44592f0ce9c240406b13020cdc377a9f0 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Mon, 23 May 2022 11:29:44 -0700 Subject: [PATCH 30/37] Stream: don't flush empty buffers created for read errors. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we generate the last_buf buffer for an UDP upstream recv error, it does not contain any data from the wire. ngx_stream_write_filter attempts to forward it anyways, which is incorrect (e.g., UDP upstream ECONNREFUSED will be translated to an empty packet). This happens because we mark the buffer as both 'flush' and 'last_buf', and ngx_stream_write_filter has special handling for flush with certain types of connections (see d127837c714f, 32b0ba4855a6). The flags are meant to be mutually exclusive, so the fix is to ensure that flush and last_buf are not set at the same time. Reproduction: stream { upstream unreachable { server 127.0.0.1:8880; } server { listen 127.0.0.1:8998 udp; proxy_pass unreachable; } } 1 0.000000000 127.0.0.1 → 127.0.0.1 UDP 47 45588 → 8998 Len=5 2 0.000166300 127.0.0.1 → 127.0.0.1 UDP 47 51149 → 8880 Len=5 3 0.000172600 127.0.0.1 → 127.0.0.1 ICMP 75 Destination unreachable (Port unreachable) 4 0.000202400 127.0.0.1 → 127.0.0.1 UDP 42 8998 → 45588 Len=0 Fixes d127837c714f. --- src/stream/ngx_stream_proxy_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c index 683f7d7a4..bd462ff01 100644 --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -1737,7 +1737,7 @@ ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream, cl->buf->temporary = (n ? 1 : 0); cl->buf->last_buf = src->read->eof; - cl->buf->flush = 1; + cl->buf->flush = !src->read->eof; (*packets)++; *received += n; From f2fcc03d3aa6f0e0a457a994dbc743b5b63ad035 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Wed, 1 Jun 2022 20:17:23 -0700 Subject: [PATCH 31/37] Resolver: make TCP write timer event cancelable. Similar to 70e65bf8dfd7, the change is made to ensure that the ability to cancel resolver tasks is fully controlled by the caller. As mentioned in the referenced commit, it is safe to make this timer cancelable because resolve tasks can have their own timeouts that are not cancelable. The scenario where this may become a problem is a periodic background resolve task (not tied to a specific request or a client connection), which receives a response with short TTL, large enough to warrant fallback to a TCP query. With each event loop wakeup, we either have a previously set write timer instance or schedule a new one. The non-cancelable write timer can delay or block graceful shutdown of a worker even if the ngx_resolver_ctx_t->cancelable flag is set by the API user, and there are no other tasks or connections. We use the resolver API in this way to maintain the list of upstream server addresses specified with the 'resolve' parameter, and there could be third-party modules implementing similar logic. --- src/core/ngx_resolver.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c index 6d129e56a..b3947f5fd 100644 --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -1389,6 +1389,7 @@ ngx_resolver_send_tcp_query(ngx_resolver_t *r, ngx_resolver_connection_t *rec, rec->tcp->data = rec; rec->tcp->write->handler = ngx_resolver_tcp_write; + rec->tcp->write->cancelable = 1; rec->tcp->read->handler = ngx_resolver_tcp_read; rec->tcp->read->resolver = 1; From 21506a2f851c9dbff4bee67fe5b6d199c83c799a Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Tue, 14 Jun 2022 10:39:58 +0400 Subject: [PATCH 32/37] Perl: removed unused variables, forgotten in ef6a3a99a81a. --- src/http/modules/perl/nginx.xs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs index da1227952..fd59e29ea 100644 --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -269,8 +269,7 @@ header_in(r, key) u_char *p, *lowcase_key, *value, sep; STRLEN len; ssize_t size; - ngx_uint_t i, n, hash; - ngx_array_t *a; + ngx_uint_t i, hash; ngx_list_part_t *part; ngx_table_elt_t *h, *header, **ph; ngx_http_header_t *hh; From ecdbd066174262710a28acce5ee9cb54d5a5741b Mon Sep 17 00:00:00 2001 From: Gena Makhomed Date: Sat, 18 Jun 2022 15:54:40 +0300 Subject: [PATCH 33/37] Contrib: vim syntax, update core and 3rd party module directives. List of 3rd party modules github repositories are obtained from https://github.com/freebsd/freebsd-ports/blob/main/www/nginx-devel/Makefile.extmod --- contrib/vim/syntax/nginx.vim | 1004 +++++++++------------------------- 1 file changed, 260 insertions(+), 744 deletions(-) diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim index 6828cd3e5..7d587fc48 100644 --- a/contrib/vim/syntax/nginx.vim +++ b/contrib/vim/syntax/nginx.vim @@ -111,19 +111,14 @@ syn keyword ngxDirectiveControl contained set syn keyword ngxDirectiveError contained error_page syn keyword ngxDirectiveError contained post_action -syn keyword ngxDirectiveDeprecated contained limit_zone syn keyword ngxDirectiveDeprecated contained proxy_downstream_buffer syn keyword ngxDirectiveDeprecated contained proxy_upstream_buffer -syn keyword ngxDirectiveDeprecated contained spdy_chunk_size -syn keyword ngxDirectiveDeprecated contained spdy_headers_comp -syn keyword ngxDirectiveDeprecated contained spdy_keepalive_timeout -syn keyword ngxDirectiveDeprecated contained spdy_max_concurrent_streams -syn keyword ngxDirectiveDeprecated contained spdy_pool_size -syn keyword ngxDirectiveDeprecated contained spdy_recv_buffer_size -syn keyword ngxDirectiveDeprecated contained spdy_recv_timeout -syn keyword ngxDirectiveDeprecated contained spdy_streams_index_size syn keyword ngxDirectiveDeprecated contained ssl -syn keyword ngxDirectiveDeprecated contained upstream_conf +syn keyword ngxDirectiveDeprecated contained http2_idle_timeout +syn keyword ngxDirectiveDeprecated contained http2_max_field_size +syn keyword ngxDirectiveDeprecated contained http2_max_header_size +syn keyword ngxDirectiveDeprecated contained http2_max_requests +syn keyword ngxDirectiveDeprecated contained http2_recv_timeout syn keyword ngxDirective contained absolute_redirect syn keyword ngxDirective contained accept_mutex @@ -152,6 +147,7 @@ syn keyword ngxDirective contained auth_http_timeout syn keyword ngxDirective contained auth_jwt syn keyword ngxDirective contained auth_jwt_claim_set syn keyword ngxDirective contained auth_jwt_header_set +syn keyword ngxDirective contained auth_jwt_key_cache syn keyword ngxDirective contained auth_jwt_key_file syn keyword ngxDirective contained auth_jwt_key_request syn keyword ngxDirective contained auth_jwt_leeway @@ -309,17 +305,12 @@ syn keyword ngxDirective contained hls_mp4_buffer_size syn keyword ngxDirective contained hls_mp4_max_buffer_size syn keyword ngxDirective contained http2_body_preread_size syn keyword ngxDirective contained http2_chunk_size -syn keyword ngxDirective contained http2_idle_timeout syn keyword ngxDirective contained http2_max_concurrent_pushes syn keyword ngxDirective contained http2_max_concurrent_streams -syn keyword ngxDirective contained http2_max_field_size -syn keyword ngxDirective contained http2_max_header_size -syn keyword ngxDirective contained http2_max_requests syn keyword ngxDirective contained http2_pool_size syn keyword ngxDirective contained http2_push syn keyword ngxDirective contained http2_push_preload syn keyword ngxDirective contained http2_recv_buffer_size -syn keyword ngxDirective contained http2_recv_timeout syn keyword ngxDirective contained http2_streams_index_size syn keyword ngxDirective contained if_modified_since syn keyword ngxDirective contained ignore_invalid_headers @@ -339,14 +330,17 @@ syn keyword ngxDirective contained ip_hash syn keyword ngxDirective contained js_access syn keyword ngxDirective contained js_body_filter syn keyword ngxDirective contained js_content +syn keyword ngxDirective contained js_fetch_buffer_size syn keyword ngxDirective contained js_fetch_ciphers +syn keyword ngxDirective contained js_fetch_max_response_buffer_size syn keyword ngxDirective contained js_fetch_protocols +syn keyword ngxDirective contained js_fetch_timeout syn keyword ngxDirective contained js_fetch_trusted_certificate +syn keyword ngxDirective contained js_fetch_verify syn keyword ngxDirective contained js_fetch_verify_depth syn keyword ngxDirective contained js_filter syn keyword ngxDirective contained js_header_filter syn keyword ngxDirective contained js_import -syn keyword ngxDirective contained js_include syn keyword ngxDirective contained js_path syn keyword ngxDirective contained js_preread syn keyword ngxDirective contained js_set @@ -391,7 +385,6 @@ syn keyword ngxDirective contained max_ranges syn keyword ngxDirective contained memcached_bind syn keyword ngxDirective contained memcached_buffer_size syn keyword ngxDirective contained memcached_connect_timeout -syn keyword ngxDirective contained memcached_force_ranges syn keyword ngxDirective contained memcached_gzip_flag syn keyword ngxDirective contained memcached_next_upstream syn keyword ngxDirective contained memcached_next_upstream_timeout @@ -645,7 +638,6 @@ syn keyword ngxDirective contained status syn keyword ngxDirective contained status_format syn keyword ngxDirective contained status_zone syn keyword ngxDirective contained sticky -syn keyword ngxDirective contained sticky_cookie_insert syn keyword ngxDirective contained stub_status syn keyword ngxDirective contained sub_filter syn keyword ngxDirective contained sub_filter_last_modified @@ -774,62 +766,14 @@ syn keyword ngxDirective contained zone_sync_ssl_verify syn keyword ngxDirective contained zone_sync_ssl_verify_depth syn keyword ngxDirective contained zone_sync_timeout + " 3rd party modules list taken from -" https://github.com/freebsd/freebsd-ports/blob/master/www/nginx-devel/Makefile -" ----------------------------------------------------------------------------- +" https://github.com/freebsd/freebsd-ports/blob/main/www/nginx-devel/Makefile.extmod +" ---------------------------------------------------------------------------------- -" Accept Language -" https://github.com/giom/nginx_accept_language_module -syn keyword ngxDirectiveThirdParty contained set_from_accept_language - -" Digest Authentication -" https://github.com/atomx/nginx-http-auth-digest -syn keyword ngxDirectiveThirdParty contained auth_digest -syn keyword ngxDirectiveThirdParty contained auth_digest_drop_time -syn keyword ngxDirectiveThirdParty contained auth_digest_evasion_time -syn keyword ngxDirectiveThirdParty contained auth_digest_expires -syn keyword ngxDirectiveThirdParty contained auth_digest_maxtries -syn keyword ngxDirectiveThirdParty contained auth_digest_replays -syn keyword ngxDirectiveThirdParty contained auth_digest_shm_size -syn keyword ngxDirectiveThirdParty contained auth_digest_timeout -syn keyword ngxDirectiveThirdParty contained auth_digest_user_file - -" SPNEGO Authentication -" https://github.com/stnoonan/spnego-http-auth-nginx-module -syn keyword ngxDirectiveThirdParty contained auth_gss -syn keyword ngxDirectiveThirdParty contained auth_gss_allow_basic_fallback -syn keyword ngxDirectiveThirdParty contained auth_gss_authorized_principal -syn keyword ngxDirectiveThirdParty contained auth_gss_authorized_principal_regex -syn keyword ngxDirectiveThirdParty contained auth_gss_constrained_delegation -syn keyword ngxDirectiveThirdParty contained auth_gss_delegate_credentials -syn keyword ngxDirectiveThirdParty contained auth_gss_force_realm -syn keyword ngxDirectiveThirdParty contained auth_gss_format_full -syn keyword ngxDirectiveThirdParty contained auth_gss_keytab -syn keyword ngxDirectiveThirdParty contained auth_gss_map_to_local -syn keyword ngxDirectiveThirdParty contained auth_gss_realm -syn keyword ngxDirectiveThirdParty contained auth_gss_service_ccache -syn keyword ngxDirectiveThirdParty contained auth_gss_service_name - -" LDAP Authentication -" https://github.com/kvspb/nginx-auth-ldap -syn keyword ngxDirectiveThirdParty contained auth_ldap -syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_enabled -syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_expiration_time -syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_size -syn keyword ngxDirectiveThirdParty contained auth_ldap_servers -syn keyword ngxDirectiveThirdParty contained auth_ldap_servers_size -syn keyword ngxDirectiveThirdParty contained ldap_server - -" PAM Authentication -" https://github.com/sto/ngx_http_auth_pam_module -syn keyword ngxDirectiveThirdParty contained auth_pam -syn keyword ngxDirectiveThirdParty contained auth_pam_service_name -syn keyword ngxDirectiveThirdParty contained auth_pam_set_pam_env - -" AJP protocol proxy -" https://github.com/yaoweibin/nginx_ajp_module -syn keyword ngxDirectiveThirdParty contained ajp_buffers +" https://github.com/msva/nginx_ajp_module syn keyword ngxDirectiveThirdParty contained ajp_buffer_size +syn keyword ngxDirectiveThirdParty contained ajp_buffers syn keyword ngxDirectiveThirdParty contained ajp_busy_buffers_size syn keyword ngxDirectiveThirdParty contained ajp_cache syn keyword ngxDirectiveThirdParty contained ajp_cache_key @@ -850,11 +794,13 @@ syn keyword ngxDirectiveThirdParty contained ajp_keep_conn syn keyword ngxDirectiveThirdParty contained ajp_max_data_packet_size syn keyword ngxDirectiveThirdParty contained ajp_max_temp_file_size syn keyword ngxDirectiveThirdParty contained ajp_next_upstream +syn keyword ngxDirectiveThirdParty contained ajp_param syn keyword ngxDirectiveThirdParty contained ajp_pass syn keyword ngxDirectiveThirdParty contained ajp_pass_header syn keyword ngxDirectiveThirdParty contained ajp_pass_request_body syn keyword ngxDirectiveThirdParty contained ajp_pass_request_headers syn keyword ngxDirectiveThirdParty contained ajp_read_timeout +syn keyword ngxDirectiveThirdParty contained ajp_script_url syn keyword ngxDirectiveThirdParty contained ajp_secret syn keyword ngxDirectiveThirdParty contained ajp_send_lowat syn keyword ngxDirectiveThirdParty contained ajp_send_timeout @@ -865,7 +811,12 @@ syn keyword ngxDirectiveThirdParty contained ajp_temp_path syn keyword ngxDirectiveThirdParty contained ajp_upstream_fail_timeout syn keyword ngxDirectiveThirdParty contained ajp_upstream_max_fails -" AWS proxy +" https://github.com/openresty/array-var-nginx-module +syn keyword ngxDirectiveThirdParty contained array_join +syn keyword ngxDirectiveThirdParty contained array_map +syn keyword ngxDirectiveThirdParty contained array_map_op +syn keyword ngxDirectiveThirdParty contained array_split + " https://github.com/anomalizer/ngx_aws_auth syn keyword ngxDirectiveThirdParty contained aws_access_key syn keyword ngxDirectiveThirdParty contained aws_endpoint @@ -874,7 +825,18 @@ syn keyword ngxDirectiveThirdParty contained aws_s3_bucket syn keyword ngxDirectiveThirdParty contained aws_sign syn keyword ngxDirectiveThirdParty contained aws_signing_key -" embedding Clojure or Java or Groovy programs +" https://github.com/google/ngx_brotli +syn keyword ngxDirectiveThirdParty contained brotli +syn keyword ngxDirectiveThirdParty contained brotli_buffers +syn keyword ngxDirectiveThirdParty contained brotli_comp_level +syn keyword ngxDirectiveThirdParty contained brotli_min_length +syn keyword ngxDirectiveThirdParty contained brotli_static +syn keyword ngxDirectiveThirdParty contained brotli_types +syn keyword ngxDirectiveThirdParty contained brotli_window + +" https://github.com/torden/ngx_cache_purge +syn keyword ngxDirectiveThirdParty contained cache_purge_response_type + " https://github.com/nginx-clojure/nginx-clojure syn keyword ngxDirectiveThirdParty contained access_handler_code syn keyword ngxDirectiveThirdParty contained access_handler_name @@ -892,8 +854,8 @@ syn keyword ngxDirectiveThirdParty contained content_handler_property syn keyword ngxDirectiveThirdParty contained content_handler_type syn keyword ngxDirectiveThirdParty contained handler_code syn keyword ngxDirectiveThirdParty contained handler_name -syn keyword ngxDirectiveThirdParty contained handlers_lazy_init syn keyword ngxDirectiveThirdParty contained handler_type +syn keyword ngxDirectiveThirdParty contained handlers_lazy_init syn keyword ngxDirectiveThirdParty contained header_filter_code syn keyword ngxDirectiveThirdParty contained header_filter_name syn keyword ngxDirectiveThirdParty contained header_filter_property @@ -921,18 +883,20 @@ syn keyword ngxDirectiveThirdParty contained rewrite_handler_type syn keyword ngxDirectiveThirdParty contained shared_map syn keyword ngxDirectiveThirdParty contained write_page_size +" https://github.com/AirisX/nginx_cookie_flag_module +syn keyword ngxDirectiveThirdParty contained set_cookie_flag -" Certificate Transparency " https://github.com/grahamedgecombe/nginx-ct syn keyword ngxDirectiveThirdParty contained ssl_ct syn keyword ngxDirectiveThirdParty contained ssl_ct_static_scts -" ngx_echo " https://github.com/openresty/echo-nginx-module +syn keyword ngxDirectiveThirdParty contained echo syn keyword ngxDirectiveThirdParty contained echo_abort_parent syn keyword ngxDirectiveThirdParty contained echo_after_body syn keyword ngxDirectiveThirdParty contained echo_before_body syn keyword ngxDirectiveThirdParty contained echo_blocking_sleep +syn keyword ngxDirectiveThirdParty contained echo_duplicate syn keyword ngxDirectiveThirdParty contained echo_end syn keyword ngxDirectiveThirdParty contained echo_exec syn keyword ngxDirectiveThirdParty contained echo_flush @@ -942,28 +906,124 @@ syn keyword ngxDirectiveThirdParty contained echo_location_async syn keyword ngxDirectiveThirdParty contained echo_read_request_body syn keyword ngxDirectiveThirdParty contained echo_request_body syn keyword ngxDirectiveThirdParty contained echo_reset_timer +syn keyword ngxDirectiveThirdParty contained echo_sleep syn keyword ngxDirectiveThirdParty contained echo_status syn keyword ngxDirectiveThirdParty contained echo_subrequest syn keyword ngxDirectiveThirdParty contained echo_subrequest_async -" FastDFS -" https://github.com/happyfish100/fastdfs-nginx-module -syn keyword ngxDirectiveThirdParty contained ngx_fastdfs_module +" https://github.com/openresty/drizzle-nginx-module +syn keyword ngxDirectiveThirdParty contained drizzle_buffer_size +syn keyword ngxDirectiveThirdParty contained drizzle_connect_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_dbname +syn keyword ngxDirectiveThirdParty contained drizzle_keepalive +syn keyword ngxDirectiveThirdParty contained drizzle_module_header +syn keyword ngxDirectiveThirdParty contained drizzle_pass +syn keyword ngxDirectiveThirdParty contained drizzle_query +syn keyword ngxDirectiveThirdParty contained drizzle_recv_cols_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_recv_rows_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_send_query_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_server +syn keyword ngxDirectiveThirdParty contained drizzle_status + +" https://github.com/ZigzagAK/ngx_dynamic_upstream +syn keyword ngxDirectiveThirdParty contained dns_add_down +syn keyword ngxDirectiveThirdParty contained dns_ipv6 +syn keyword ngxDirectiveThirdParty contained dns_update +syn keyword ngxDirectiveThirdParty contained dynamic_state_file +syn keyword ngxDirectiveThirdParty contained dynamic_upstream + +" https://github.com/ZigzagAK/ngx_dynamic_healthcheck +syn keyword ngxDirectiveThirdParty contained check +syn keyword ngxDirectiveThirdParty contained check_disable_host +syn keyword ngxDirectiveThirdParty contained check_exclude_host +syn keyword ngxDirectiveThirdParty contained check_persistent +syn keyword ngxDirectiveThirdParty contained check_request_body +syn keyword ngxDirectiveThirdParty contained check_request_headers +syn keyword ngxDirectiveThirdParty contained check_request_uri +syn keyword ngxDirectiveThirdParty contained check_response_body +syn keyword ngxDirectiveThirdParty contained check_response_codes +syn keyword ngxDirectiveThirdParty contained healthcheck +syn keyword ngxDirectiveThirdParty contained healthcheck_buffer_size +syn keyword ngxDirectiveThirdParty contained healthcheck_disable_host +syn keyword ngxDirectiveThirdParty contained healthcheck_get +syn keyword ngxDirectiveThirdParty contained healthcheck_persistent +syn keyword ngxDirectiveThirdParty contained healthcheck_request_body +syn keyword ngxDirectiveThirdParty contained healthcheck_request_headers +syn keyword ngxDirectiveThirdParty contained healthcheck_request_uri +syn keyword ngxDirectiveThirdParty contained healthcheck_response_body +syn keyword ngxDirectiveThirdParty contained healthcheck_response_codes +syn keyword ngxDirectiveThirdParty contained healthcheck_status +syn keyword ngxDirectiveThirdParty contained healthcheck_update + +" https://github.com/openresty/encrypted-session-nginx-module +syn keyword ngxDirectiveThirdParty contained encrypted_session_expires +syn keyword ngxDirectiveThirdParty contained encrypted_session_iv +syn keyword ngxDirectiveThirdParty contained encrypted_session_key +syn keyword ngxDirectiveThirdParty contained set_decrypt_session +syn keyword ngxDirectiveThirdParty contained set_encrypt_session + +" https://github.com/calio/form-input-nginx-module +syn keyword ngxDirectiveThirdParty contained set_form_input +syn keyword ngxDirectiveThirdParty contained set_form_input_multi + +" https://github.com/nieoding/nginx-gridfs +syn keyword ngxDirectiveThirdParty contained gridfs +syn keyword ngxDirectiveThirdParty contained mongo -" ngx_headers_more " https://github.com/openresty/headers-more-nginx-module syn keyword ngxDirectiveThirdParty contained more_clear_headers syn keyword ngxDirectiveThirdParty contained more_clear_input_headers syn keyword ngxDirectiveThirdParty contained more_set_headers syn keyword ngxDirectiveThirdParty contained more_set_input_headers -" NGINX WebDAV missing commands support (PROPFIND & OPTIONS) +" https://github.com/dvershinin/nginx_accept_language_module +syn keyword ngxDirectiveThirdParty contained set_from_accept_language + +" https://github.com/atomx/nginx-http-auth-digest +syn keyword ngxDirectiveThirdParty contained auth_digest +syn keyword ngxDirectiveThirdParty contained auth_digest_drop_time +syn keyword ngxDirectiveThirdParty contained auth_digest_evasion_time +syn keyword ngxDirectiveThirdParty contained auth_digest_expires +syn keyword ngxDirectiveThirdParty contained auth_digest_maxtries +syn keyword ngxDirectiveThirdParty contained auth_digest_replays +syn keyword ngxDirectiveThirdParty contained auth_digest_shm_size +syn keyword ngxDirectiveThirdParty contained auth_digest_timeout +syn keyword ngxDirectiveThirdParty contained auth_digest_user_file + +" https://github.com/stnoonan/spnego-http-auth-nginx-module +syn keyword ngxDirectiveThirdParty contained auth_gss +syn keyword ngxDirectiveThirdParty contained auth_gss_allow_basic_fallback +syn keyword ngxDirectiveThirdParty contained auth_gss_authorized_principal +syn keyword ngxDirectiveThirdParty contained auth_gss_authorized_principal_regex +syn keyword ngxDirectiveThirdParty contained auth_gss_constrained_delegation +syn keyword ngxDirectiveThirdParty contained auth_gss_delegate_credentials +syn keyword ngxDirectiveThirdParty contained auth_gss_force_realm +syn keyword ngxDirectiveThirdParty contained auth_gss_format_full +syn keyword ngxDirectiveThirdParty contained auth_gss_keytab +syn keyword ngxDirectiveThirdParty contained auth_gss_map_to_local +syn keyword ngxDirectiveThirdParty contained auth_gss_realm +syn keyword ngxDirectiveThirdParty contained auth_gss_service_ccache +syn keyword ngxDirectiveThirdParty contained auth_gss_service_name + +" https://github.com/kvspb/nginx-auth-ldap +syn keyword ngxDirectiveThirdParty contained auth_ldap +syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_enabled +syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_expiration_time +syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_size +syn keyword ngxDirectiveThirdParty contained auth_ldap_servers +syn keyword ngxDirectiveThirdParty contained auth_ldap_servers_size +syn keyword ngxDirectiveThirdParty contained ldap_server + +" https://github.com/sto/ngx_http_auth_pam_module +syn keyword ngxDirectiveThirdParty contained auth_pam +syn keyword ngxDirectiveThirdParty contained auth_pam_service_name +syn keyword ngxDirectiveThirdParty contained auth_pam_set_pam_env + " https://github.com/arut/nginx-dav-ext-module syn keyword ngxDirectiveThirdParty contained dav_ext_lock syn keyword ngxDirectiveThirdParty contained dav_ext_lock_zone syn keyword ngxDirectiveThirdParty contained dav_ext_methods -" ngx_eval " https://github.com/openresty/nginx-eval-module syn keyword ngxDirectiveThirdParty contained eval syn keyword ngxDirectiveThirdParty contained eval_buffer_size @@ -971,7 +1031,6 @@ syn keyword ngxDirectiveThirdParty contained eval_escalate syn keyword ngxDirectiveThirdParty contained eval_override_content_type syn keyword ngxDirectiveThirdParty contained eval_subrequest_in_memory -" Fancy Index " https://github.com/aperezdc/ngx-fancyindex syn keyword ngxDirectiveThirdParty contained fancyindex syn keyword ngxDirectiveThirdParty contained fancyindex_css_href @@ -988,40 +1047,29 @@ syn keyword ngxDirectiveThirdParty contained fancyindex_show_dotfiles syn keyword ngxDirectiveThirdParty contained fancyindex_show_path syn keyword ngxDirectiveThirdParty contained fancyindex_time_format -" Footer filter " https://github.com/alibaba/nginx-http-footer-filter syn keyword ngxDirectiveThirdParty contained footer syn keyword ngxDirectiveThirdParty contained footer_types -" ngx_http_geoip2_module " https://github.com/leev/ngx_http_geoip2_module syn keyword ngxDirectiveThirdParty contained geoip2 syn keyword ngxDirectiveThirdParty contained geoip2_proxy syn keyword ngxDirectiveThirdParty contained geoip2_proxy_recursive -" A version of the Nginx HTTP stub status module that outputs in JSON format -" https://github.com/nginx-modules/nginx-json-status-module -syn keyword ngxDirectiveThirdParty contained json_status -syn keyword ngxDirectiveThirdParty contained json_status_type +" https://github.com/ip2location/ip2location-nginx +syn keyword ngxDirectiveThirdParty contained ip2location_database +syn keyword ngxDirectiveThirdParty contained ip2location_proxy +syn keyword ngxDirectiveThirdParty contained ip2location_proxy_recursive -" MogileFS client for nginx -" https://github.com/vkholodkov/nginx-mogilefs-module -syn keyword ngxDirectiveThirdParty contained mogilefs_class -syn keyword ngxDirectiveThirdParty contained mogilefs_connect_timeout -syn keyword ngxDirectiveThirdParty contained mogilefs_domain -syn keyword ngxDirectiveThirdParty contained mogilefs_methods -syn keyword ngxDirectiveThirdParty contained mogilefs_noverify -syn keyword ngxDirectiveThirdParty contained mogilefs_pass -syn keyword ngxDirectiveThirdParty contained mogilefs_read_timeout -syn keyword ngxDirectiveThirdParty contained mogilefs_send_timeout -syn keyword ngxDirectiveThirdParty contained mogilefs_tracker +" https://github.com/ip2location/ip2proxy-nginx +syn keyword ngxDirectiveThirdParty contained ip2proxy_database +syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy +syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy_recursive -" Ancient nginx plugin; probably not useful to anyone " https://github.com/kr/nginx-notice syn keyword ngxDirectiveThirdParty contained notice syn keyword ngxDirectiveThirdParty contained notice_type -" nchan " https://github.com/slact/nchan syn keyword ngxDirectiveThirdParty contained nchan_access_control_allow_credentials syn keyword ngxDirectiveThirdParty contained nchan_access_control_allow_origin @@ -1034,8 +1082,8 @@ syn keyword ngxDirectiveThirdParty contained nchan_benchmark_publisher_distribut syn keyword ngxDirectiveThirdParty contained nchan_benchmark_subscriber_distribution syn keyword ngxDirectiveThirdParty contained nchan_benchmark_subscribers_per_channel syn keyword ngxDirectiveThirdParty contained nchan_benchmark_time -syn keyword ngxDirectiveThirdParty contained nchan_channel_events_channel_id syn keyword ngxDirectiveThirdParty contained nchan_channel_event_string +syn keyword ngxDirectiveThirdParty contained nchan_channel_events_channel_id syn keyword ngxDirectiveThirdParty contained nchan_channel_group syn keyword ngxDirectiveThirdParty contained nchan_channel_group_accounting syn keyword ngxDirectiveThirdParty contained nchan_channel_id @@ -1074,11 +1122,25 @@ syn keyword ngxDirectiveThirdParty contained nchan_pubsub syn keyword ngxDirectiveThirdParty contained nchan_pubsub_channel_id syn keyword ngxDirectiveThirdParty contained nchan_pubsub_location syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_check_interval +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_check_interval_backoff +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_check_interval_jitter +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_check_interval_max +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_check_interval_min +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_connect_timeout +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_max_failing_time +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_recovery_delay +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_recovery_delay_backoff +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_recovery_delay_jitter +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_recovery_delay_max +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_recovery_delay_min +syn keyword ngxDirectiveThirdParty contained nchan_redis_command_timeout syn keyword ngxDirectiveThirdParty contained nchan_redis_connect_timeout syn keyword ngxDirectiveThirdParty contained nchan_redis_discovered_ip_range_blacklist syn keyword ngxDirectiveThirdParty contained nchan_redis_fakesub_timer_interval syn keyword ngxDirectiveThirdParty contained nchan_redis_idle_channel_cache_timeout +syn keyword ngxDirectiveThirdParty contained nchan_redis_load_scripts_unconditionally syn keyword ngxDirectiveThirdParty contained nchan_redis_namespace +syn keyword ngxDirectiveThirdParty contained nchan_redis_node_connect_timeout syn keyword ngxDirectiveThirdParty contained nchan_redis_nostore_fastpublish syn keyword ngxDirectiveThirdParty contained nchan_redis_optimize_target syn keyword ngxDirectiveThirdParty contained nchan_redis_pass @@ -1086,6 +1148,13 @@ syn keyword ngxDirectiveThirdParty contained nchan_redis_pass_inheritable syn keyword ngxDirectiveThirdParty contained nchan_redis_password syn keyword ngxDirectiveThirdParty contained nchan_redis_ping_interval syn keyword ngxDirectiveThirdParty contained nchan_redis_publish_msgpacked_max_size +syn keyword ngxDirectiveThirdParty contained nchan_redis_reconnect_delay +syn keyword ngxDirectiveThirdParty contained nchan_redis_reconnect_delay_backoff +syn keyword ngxDirectiveThirdParty contained nchan_redis_reconnect_delay_jitter +syn keyword ngxDirectiveThirdParty contained nchan_redis_reconnect_delay_max +syn keyword ngxDirectiveThirdParty contained nchan_redis_reconnect_delay_min +syn keyword ngxDirectiveThirdParty contained nchan_redis_retry_commands +syn keyword ngxDirectiveThirdParty contained nchan_redis_retry_commands_max_wait syn keyword ngxDirectiveThirdParty contained nchan_redis_server syn keyword ngxDirectiveThirdParty contained nchan_redis_ssl syn keyword ngxDirectiveThirdParty contained nchan_redis_ssl_ciphers @@ -1113,10 +1182,10 @@ syn keyword ngxDirectiveThirdParty contained nchan_store_messages syn keyword ngxDirectiveThirdParty contained nchan_stub_status syn keyword ngxDirectiveThirdParty contained nchan_sub_channel_id syn keyword ngxDirectiveThirdParty contained nchan_subscribe_existing_channels_only +syn keyword ngxDirectiveThirdParty contained nchan_subscribe_request syn keyword ngxDirectiveThirdParty contained nchan_subscriber syn keyword ngxDirectiveThirdParty contained nchan_subscriber_channel_id syn keyword ngxDirectiveThirdParty contained nchan_subscriber_compound_etag_message_id -syn keyword ngxDirectiveThirdParty contained nchan_subscribe_request syn keyword ngxDirectiveThirdParty contained nchan_subscriber_first_message syn keyword ngxDirectiveThirdParty contained nchan_subscriber_http_raw_stream_separator syn keyword ngxDirectiveThirdParty contained nchan_subscriber_info @@ -1145,7 +1214,6 @@ syn keyword ngxDirectiveThirdParty contained push_subscriber syn keyword ngxDirectiveThirdParty contained push_subscriber_concurrency syn keyword ngxDirectiveThirdParty contained push_subscriber_timeout -" Push Stream " https://github.com/wandenberg/nginx-push-stream-module syn keyword ngxDirectiveThirdParty contained push_stream_allow_connections_to_events_channel syn keyword ngxDirectiveThirdParty contained push_stream_allowed_origins @@ -1184,23 +1252,6 @@ syn keyword ngxDirectiveThirdParty contained push_stream_websocket_allow_publish syn keyword ngxDirectiveThirdParty contained push_stream_wildcard_channel_max_qtd syn keyword ngxDirectiveThirdParty contained push_stream_wildcard_channel_prefix -" redis module -" https://www.nginx.com/resources/wiki/modules/redis/ -syn keyword ngxDirectiveThirdParty contained redis_bind -syn keyword ngxDirectiveThirdParty contained redis_buffer_size -syn keyword ngxDirectiveThirdParty contained redis_connect_timeout -syn keyword ngxDirectiveThirdParty contained redis_gzip_flag -syn keyword ngxDirectiveThirdParty contained redis_next_upstream -syn keyword ngxDirectiveThirdParty contained redis_pass -syn keyword ngxDirectiveThirdParty contained redis_read_timeout -syn keyword ngxDirectiveThirdParty contained redis_send_timeout - -" ngx_http_response -" http://catap.ru/downloads/nginx/ -syn keyword ngxDirectiveThirdParty contained response -syn keyword ngxDirectiveThirdParty contained response_type - -" nginx_substitutions_filter " https://github.com/yaoweibin/ngx_http_substitutions_filter_module syn keyword ngxDirectiveThirdParty contained subs_buffers syn keyword ngxDirectiveThirdParty contained subs_filter @@ -1208,7 +1259,6 @@ syn keyword ngxDirectiveThirdParty contained subs_filter_bypass syn keyword ngxDirectiveThirdParty contained subs_filter_types syn keyword ngxDirectiveThirdParty contained subs_line_buffer_size -" Tarantool nginx upstream module " https://github.com/tarantool/nginx_upstream_module syn keyword ngxDirectiveThirdParty contained tnt_allowed_indexes syn keyword ngxDirectiveThirdParty contained tnt_allowed_spaces @@ -1238,44 +1288,28 @@ syn keyword ngxDirectiveThirdParty contained tnt_set_header syn keyword ngxDirectiveThirdParty contained tnt_update syn keyword ngxDirectiveThirdParty contained tnt_upsert -" A module for nginx web server for handling file uploads using multipart/form-data encoding (RFC 1867) -" https://github.com/Austinb/nginx-upload-module +" https://github.com/fdintino/nginx-upload-module +syn keyword ngxDirectiveThirdParty contained upload_add_header syn keyword ngxDirectiveThirdParty contained upload_aggregate_form_field -syn keyword ngxDirectiveThirdParty contained upload_archive_elm -syn keyword ngxDirectiveThirdParty contained upload_archive_elm_separator -syn keyword ngxDirectiveThirdParty contained upload_archive_path -syn keyword ngxDirectiveThirdParty contained upload_archive_path_separator syn keyword ngxDirectiveThirdParty contained upload_buffer_size syn keyword ngxDirectiveThirdParty contained upload_cleanup -syn keyword ngxDirectiveThirdParty contained upload_content_type -syn keyword ngxDirectiveThirdParty contained upload_discard -syn keyword ngxDirectiveThirdParty contained upload_field_name -syn keyword ngxDirectiveThirdParty contained upload_file_crc32 -syn keyword ngxDirectiveThirdParty contained upload_file_md5 -syn keyword ngxDirectiveThirdParty contained upload_file_md5_uc -syn keyword ngxDirectiveThirdParty contained upload_file_name -syn keyword ngxDirectiveThirdParty contained upload_file_sha1 -syn keyword ngxDirectiveThirdParty contained upload_file_sha1_uc -syn keyword ngxDirectiveThirdParty contained upload_file_size -syn keyword ngxDirectiveThirdParty contained upload_filter +syn keyword ngxDirectiveThirdParty contained upload_empty_fiels_names +syn keyword ngxDirectiveThirdParty contained upload_limit_rate syn keyword ngxDirectiveThirdParty contained upload_max_file_size syn keyword ngxDirectiveThirdParty contained upload_max_output_body_len syn keyword ngxDirectiveThirdParty contained upload_max_part_header_len +syn keyword ngxDirectiveThirdParty contained upload_merge_buffer_size syn keyword ngxDirectiveThirdParty contained upload_pass syn keyword ngxDirectiveThirdParty contained upload_pass_args syn keyword ngxDirectiveThirdParty contained upload_pass_form_field +syn keyword ngxDirectiveThirdParty contained upload_range_header_buffer_size +syn keyword ngxDirectiveThirdParty contained upload_resumable syn keyword ngxDirectiveThirdParty contained upload_set_form_field +syn keyword ngxDirectiveThirdParty contained upload_state_store syn keyword ngxDirectiveThirdParty contained upload_store syn keyword ngxDirectiveThirdParty contained upload_store_access -syn keyword ngxDirectiveThirdParty contained upload_tmp_path -syn keyword ngxDirectiveThirdParty contained upload_unzip -syn keyword ngxDirectiveThirdParty contained upload_unzip_buffers -syn keyword ngxDirectiveThirdParty contained upload_unzip_hash -syn keyword ngxDirectiveThirdParty contained upload_unzip_max_file_name_len -syn keyword ngxDirectiveThirdParty contained upload_unzip_window -syn keyword ngxDirectiveThirdParty contained upload_void_content_type +syn keyword ngxDirectiveThirdParty contained upload_tame_arrays -" nginx-upload-progress-module " https://github.com/masterzen/nginx-upload-progress-module syn keyword ngxDirectiveThirdParty contained report_uploads syn keyword ngxDirectiveThirdParty contained track_uploads @@ -1288,9 +1322,7 @@ syn keyword ngxDirectiveThirdParty contained upload_progress_jsonp_output syn keyword ngxDirectiveThirdParty contained upload_progress_jsonp_parameter syn keyword ngxDirectiveThirdParty contained upload_progress_template -" Health checks upstreams for nginx " https://github.com/yaoweibin/nginx_upstream_check_module -syn keyword ngxDirectiveThirdParty contained check syn keyword ngxDirectiveThirdParty contained check_fastcgi_param syn keyword ngxDirectiveThirdParty contained check_http_expect_alive syn keyword ngxDirectiveThirdParty contained check_http_send @@ -1298,13 +1330,14 @@ syn keyword ngxDirectiveThirdParty contained check_keepalive_requests syn keyword ngxDirectiveThirdParty contained check_shm_size syn keyword ngxDirectiveThirdParty contained check_status -" The fair load balancer module for nginx -" https://github.com/cryptofuture/nginx-upstream-fair +" https://github.com/jaygooby/nginx-upstream-fair syn keyword ngxDirectiveThirdParty contained fair syn keyword ngxDirectiveThirdParty contained upstream_fair_shm_size -" Nginx Video Thumb Extractor Module -" https://github.com/wandenberg/nginx-video-thumbextractor-module +" https://github.com/ayty-adrianomartins/nginx-sticky-module-ng +syn keyword ngxDirectiveThirdParty contained sticky_no_fallback + +" https://github.com/Novetta/nginx-video-thumbextractor-module syn keyword ngxDirectiveThirdParty contained video_thumbextractor syn keyword ngxDirectiveThirdParty contained video_thumbextractor_image_height syn keyword ngxDirectiveThirdParty contained video_thumbextractor_image_width @@ -1329,43 +1362,14 @@ syn keyword ngxDirectiveThirdParty contained video_thumbextractor_tile_sample_in syn keyword ngxDirectiveThirdParty contained video_thumbextractor_video_filename syn keyword ngxDirectiveThirdParty contained video_thumbextractor_video_second -" drizzle-nginx-module - Upstream module for talking to MySQL and Drizzle directly -" https://github.com/openresty/drizzle-nginx-module -syn keyword ngxDirectiveThirdParty contained drizzle_buffer_size -syn keyword ngxDirectiveThirdParty contained drizzle_connect_timeout -syn keyword ngxDirectiveThirdParty contained drizzle_dbname -syn keyword ngxDirectiveThirdParty contained drizzle_keepalive -syn keyword ngxDirectiveThirdParty contained drizzle_module_header -syn keyword ngxDirectiveThirdParty contained drizzle_pass -syn keyword ngxDirectiveThirdParty contained drizzle_query -syn keyword ngxDirectiveThirdParty contained drizzle_recv_cols_timeout -syn keyword ngxDirectiveThirdParty contained drizzle_recv_rows_timeout -syn keyword ngxDirectiveThirdParty contained drizzle_send_query_timeout -syn keyword ngxDirectiveThirdParty contained drizzle_server -syn keyword ngxDirectiveThirdParty contained drizzle_status +" https://github.com/calio/iconv-nginx-module +syn keyword ngxDirectiveThirdParty contained iconv_buffer_size +syn keyword ngxDirectiveThirdParty contained iconv_filter +syn keyword ngxDirectiveThirdParty contained set_iconv -" ngx_dynamic_upstream -" https://github.com/cubicdaiya/ngx_dynamic_upstream -syn keyword ngxDirectiveThirdParty contained dynamic_upstream - -" encrypt and decrypt nginx variable values -" https://github.com/openresty/encrypted-session-nginx-module -syn keyword ngxDirectiveThirdParty contained encrypted_session_expires -syn keyword ngxDirectiveThirdParty contained encrypted_session_iv -syn keyword ngxDirectiveThirdParty contained encrypted_session_key -syn keyword ngxDirectiveThirdParty contained set_decrypt_session -syn keyword ngxDirectiveThirdParty contained set_encrypt_session - -" serve content directly from MongoDB's GridFS -" https://github.com/mdirolf/nginx-gridfs -syn keyword ngxDirectiveThirdParty contained gridfs -syn keyword ngxDirectiveThirdParty contained mongo - -" Adds support for arithmetic operations to NGINX config -" https://github.com/arut/nginx-let-module +" https://github.com/baysao/nginx-let-module syn keyword ngxDirectiveThirdParty contained let -" ngx_http_lua_module - Embed the power of Lua into Nginx HTTP Servers " https://github.com/openresty/lua-nginx-module syn keyword ngxDirectiveThirdParty contained access_by_lua syn keyword ngxDirectiveThirdParty contained access_by_lua_block @@ -1431,6 +1435,8 @@ syn keyword ngxDirectiveThirdParty contained rewrite_by_lua syn keyword ngxDirectiveThirdParty contained rewrite_by_lua_block syn keyword ngxDirectiveThirdParty contained rewrite_by_lua_file syn keyword ngxDirectiveThirdParty contained rewrite_by_lua_no_postpone +syn keyword ngxDirectiveThirdParty contained server_rewrite_by_lua_block +syn keyword ngxDirectiveThirdParty contained server_rewrite_by_lua_file syn keyword ngxDirectiveThirdParty contained set_by_lua syn keyword ngxDirectiveThirdParty contained set_by_lua_block syn keyword ngxDirectiveThirdParty contained set_by_lua_file @@ -1443,7 +1449,16 @@ syn keyword ngxDirectiveThirdParty contained ssl_session_fetch_by_lua_file syn keyword ngxDirectiveThirdParty contained ssl_session_store_by_lua_block syn keyword ngxDirectiveThirdParty contained ssl_session_store_by_lua_file -" ngx_memc - An extended version of the standard memcached module +" https://github.com/Taymindis/nginx-link-function +syn keyword ngxDirectiveThirdParty contained ngx_link_func_add_prop +syn keyword ngxDirectiveThirdParty contained ngx_link_func_add_req_header +syn keyword ngxDirectiveThirdParty contained ngx_link_func_ca_cert +syn keyword ngxDirectiveThirdParty contained ngx_link_func_call +syn keyword ngxDirectiveThirdParty contained ngx_link_func_download_link_lib +syn keyword ngxDirectiveThirdParty contained ngx_link_func_lib +syn keyword ngxDirectiveThirdParty contained ngx_link_func_shm_size +syn keyword ngxDirectiveThirdParty contained ngx_link_func_subrequest + " https://github.com/openresty/memc-nginx-module syn keyword ngxDirectiveThirdParty contained memc_buffer_size syn keyword ngxDirectiveThirdParty contained memc_cmds_allowed @@ -1457,21 +1472,24 @@ syn keyword ngxDirectiveThirdParty contained memc_send_timeout syn keyword ngxDirectiveThirdParty contained memc_upstream_fail_timeout syn keyword ngxDirectiveThirdParty contained memc_upstream_max_fails -" ModSecurity web application firewall -" https://github.com/SpiderLabs/ModSecurity/tree/master -syn keyword ngxDirectiveThirdParty contained ModSecurityConfig -syn keyword ngxDirectiveThirdParty contained ModSecurityEnabled -syn keyword ngxDirectiveThirdParty contained pool_context_hash_size +" https://github.com/SpiderLabs/ModSecurity-nginx +syn keyword ngxDirectiveThirdParty contained modsecurity +syn keyword ngxDirectiveThirdParty contained modsecurity_rules +syn keyword ngxDirectiveThirdParty contained modsecurity_rules_file +syn keyword ngxDirectiveThirdParty contained modsecurity_rules_remote +syn keyword ngxDirectiveThirdParty contained modsecurity_transaction_id -" NAXSI is an open-source, high performance, low rules maintenance WAF for NGINX " https://github.com/nbs-system/naxsi syn keyword ngxDirectiveThirdParty contained BasicRule syn keyword ngxDirectiveThirdParty contained CheckRule syn keyword ngxDirectiveThirdParty contained DeniedUrl +syn keyword ngxDirectiveThirdParty contained IgnoreCIDR +syn keyword ngxDirectiveThirdParty contained IgnoreIP syn keyword ngxDirectiveThirdParty contained LearningMode syn keyword ngxDirectiveThirdParty contained LibInjectionSql syn keyword ngxDirectiveThirdParty contained LibInjectionXss syn keyword ngxDirectiveThirdParty contained MainRule +syn keyword ngxDirectiveThirdParty contained NaxsiLogFile syn keyword ngxDirectiveThirdParty contained SecRulesDisabled syn keyword ngxDirectiveThirdParty contained SecRulesEnabled syn keyword ngxDirectiveThirdParty contained basic_rule @@ -1481,17 +1499,31 @@ syn keyword ngxDirectiveThirdParty contained learning_mode syn keyword ngxDirectiveThirdParty contained libinjection_sql syn keyword ngxDirectiveThirdParty contained libinjection_xss syn keyword ngxDirectiveThirdParty contained main_rule +syn keyword ngxDirectiveThirdParty contained naxsi_log syn keyword ngxDirectiveThirdParty contained rules_disabled syn keyword ngxDirectiveThirdParty contained rules_enabled -" Phusion Passenger -" https://www.phusionpassenger.com/library/config/nginx/reference/ +" https://github.com/opentracing-contrib/nginx-opentracing +syn keyword ngxDirectiveThirdParty contained opentracing +syn keyword ngxDirectiveThirdParty contained opentracing_fastcgi_propagate_context +syn keyword ngxDirectiveThirdParty contained opentracing_grpc_propagate_context +syn keyword ngxDirectiveThirdParty contained opentracing_load_tracer +syn keyword ngxDirectiveThirdParty contained opentracing_location_operation_name +syn keyword ngxDirectiveThirdParty contained opentracing_operation_name +syn keyword ngxDirectiveThirdParty contained opentracing_propagate_context +syn keyword ngxDirectiveThirdParty contained opentracing_tag +syn keyword ngxDirectiveThirdParty contained opentracing_trace_locations +syn keyword ngxDirectiveThirdParty contained opentracing_trust_incoming_span + +" https://github.com/phusion/passenger syn keyword ngxDirectiveThirdParty contained passenger_abort_on_startup_error syn keyword ngxDirectiveThirdParty contained passenger_abort_websockets_on_process_shutdown syn keyword ngxDirectiveThirdParty contained passenger_admin_panel_auth_type syn keyword ngxDirectiveThirdParty contained passenger_admin_panel_password syn keyword ngxDirectiveThirdParty contained passenger_admin_panel_url syn keyword ngxDirectiveThirdParty contained passenger_admin_panel_username +syn keyword ngxDirectiveThirdParty contained passenger_analytics_log_group +syn keyword ngxDirectiveThirdParty contained passenger_analytics_log_user syn keyword ngxDirectiveThirdParty contained passenger_anonymous_telemetry_proxy syn keyword ngxDirectiveThirdParty contained passenger_app_env syn keyword ngxDirectiveThirdParty contained passenger_app_file_descriptor_ulimit @@ -1499,20 +1531,25 @@ syn keyword ngxDirectiveThirdParty contained passenger_app_group_name syn keyword ngxDirectiveThirdParty contained passenger_app_log_file syn keyword ngxDirectiveThirdParty contained passenger_app_rights syn keyword ngxDirectiveThirdParty contained passenger_app_root +syn keyword ngxDirectiveThirdParty contained passenger_app_start_command syn keyword ngxDirectiveThirdParty contained passenger_app_type syn keyword ngxDirectiveThirdParty contained passenger_base_uri syn keyword ngxDirectiveThirdParty contained passenger_buffer_response syn keyword ngxDirectiveThirdParty contained passenger_buffer_size +syn keyword ngxDirectiveThirdParty contained passenger_buffer_upload syn keyword ngxDirectiveThirdParty contained passenger_buffers syn keyword ngxDirectiveThirdParty contained passenger_busy_buffers_size syn keyword ngxDirectiveThirdParty contained passenger_concurrency_model syn keyword ngxDirectiveThirdParty contained passenger_core_file_descriptor_ulimit syn keyword ngxDirectiveThirdParty contained passenger_ctl syn keyword ngxDirectiveThirdParty contained passenger_data_buffer_dir +syn keyword ngxDirectiveThirdParty contained passenger_debug_log_file syn keyword ngxDirectiveThirdParty contained passenger_debugger syn keyword ngxDirectiveThirdParty contained passenger_default_group syn keyword ngxDirectiveThirdParty contained passenger_default_user +syn keyword ngxDirectiveThirdParty contained passenger_direct_instance_request_address syn keyword ngxDirectiveThirdParty contained passenger_disable_anonymous_telemetry +syn keyword ngxDirectiveThirdParty contained passenger_disable_log_prefix syn keyword ngxDirectiveThirdParty contained passenger_disable_security_update_check syn keyword ngxDirectiveThirdParty contained passenger_document_root syn keyword ngxDirectiveThirdParty contained passenger_dump_config_manifest @@ -1548,8 +1585,10 @@ syn keyword ngxDirectiveThirdParty contained passenger_nodejs syn keyword ngxDirectiveThirdParty contained passenger_pass_header syn keyword ngxDirectiveThirdParty contained passenger_pool_idle_time syn keyword ngxDirectiveThirdParty contained passenger_pre_start +syn keyword ngxDirectiveThirdParty contained passenger_preload_bundler syn keyword ngxDirectiveThirdParty contained passenger_python syn keyword ngxDirectiveThirdParty contained passenger_read_timeout +syn keyword ngxDirectiveThirdParty contained passenger_request_buffering syn keyword ngxDirectiveThirdParty contained passenger_request_queue_overflow_status_code syn keyword ngxDirectiveThirdParty contained passenger_resist_deployment_errors syn keyword ngxDirectiveThirdParty contained passenger_response_buffer_high_watermark @@ -1561,36 +1600,36 @@ syn keyword ngxDirectiveThirdParty contained passenger_security_update_check_pro syn keyword ngxDirectiveThirdParty contained passenger_set_header syn keyword ngxDirectiveThirdParty contained passenger_show_version_in_header syn keyword ngxDirectiveThirdParty contained passenger_socket_backlog +syn keyword ngxDirectiveThirdParty contained passenger_spawn_dir +syn keyword ngxDirectiveThirdParty contained passenger_spawn_exception_status_code syn keyword ngxDirectiveThirdParty contained passenger_spawn_method syn keyword ngxDirectiveThirdParty contained passenger_start_timeout syn keyword ngxDirectiveThirdParty contained passenger_startup_file syn keyword ngxDirectiveThirdParty contained passenger_stat_throttle_rate syn keyword ngxDirectiveThirdParty contained passenger_sticky_sessions +syn keyword ngxDirectiveThirdParty contained passenger_sticky_sessions_cookie_attributes syn keyword ngxDirectiveThirdParty contained passenger_sticky_sessions_cookie_name +syn keyword ngxDirectiveThirdParty contained passenger_temp_path syn keyword ngxDirectiveThirdParty contained passenger_thread_count syn keyword ngxDirectiveThirdParty contained passenger_turbocaching +syn keyword ngxDirectiveThirdParty contained passenger_use_global_queue syn keyword ngxDirectiveThirdParty contained passenger_user syn keyword ngxDirectiveThirdParty contained passenger_user_switching syn keyword ngxDirectiveThirdParty contained passenger_vary_turbocache_by_cookie -syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_analytics_log_group -syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_analytics_log_user -syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_debug_log_file -syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_use_global_queue -syn keyword ngxDirectiveThirdPartyDeprecated contained rack_env -syn keyword ngxDirectiveThirdPartyDeprecated contained rails_app_spawner_idle_time -syn keyword ngxDirectiveThirdPartyDeprecated contained rails_env -syn keyword ngxDirectiveThirdPartyDeprecated contained rails_framework_spawner_idle_time -syn keyword ngxDirectiveThirdPartyDeprecated contained rails_spawn_method -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_filter -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_gateway_address -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_gateway_cert -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_gateway_port -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_key -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_proxy_address -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_support +syn keyword ngxDirectiveThirdParty contained rack_env +syn keyword ngxDirectiveThirdParty contained rails_app_spawner_idle_time +syn keyword ngxDirectiveThirdParty contained rails_env +syn keyword ngxDirectiveThirdParty contained rails_framework_spawner_idle_time +syn keyword ngxDirectiveThirdParty contained rails_spawn_method +syn keyword ngxDirectiveThirdParty contained union_station_filter +syn keyword ngxDirectiveThirdParty contained union_station_gateway_address +syn keyword ngxDirectiveThirdParty contained union_station_gateway_cert +syn keyword ngxDirectiveThirdParty contained union_station_gateway_port +syn keyword ngxDirectiveThirdParty contained union_station_key +syn keyword ngxDirectiveThirdParty contained union_station_proxy_address +syn keyword ngxDirectiveThirdParty contained union_station_support -" ngx_postgres is an upstream module that allows nginx to communicate directly with PostgreSQL database -" https://github.com/FRiCKLE/ngx_postgres +" https://github.com/konstruxi/ngx_postgres syn keyword ngxDirectiveThirdParty contained postgres_connect_timeout syn keyword ngxDirectiveThirdParty contained postgres_escape syn keyword ngxDirectiveThirdParty contained postgres_keepalive @@ -1602,7 +1641,6 @@ syn keyword ngxDirectiveThirdParty contained postgres_rewrite syn keyword ngxDirectiveThirdParty contained postgres_server syn keyword ngxDirectiveThirdParty contained postgres_set -" ngx_rds_csv - Nginx output filter module to convert Resty-DBD-Streams (RDS) to Comma-Separated Values (CSV) " https://github.com/openresty/rds-csv-nginx-module syn keyword ngxDirectiveThirdParty contained rds_csv syn keyword ngxDirectiveThirdParty contained rds_csv_buffer_size @@ -1611,7 +1649,6 @@ syn keyword ngxDirectiveThirdParty contained rds_csv_field_name_header syn keyword ngxDirectiveThirdParty contained rds_csv_field_separator syn keyword ngxDirectiveThirdParty contained rds_csv_row_terminator -" ngx_rds_json - an output filter that formats Resty DBD Streams generated by ngx_drizzle and others to JSON " https://github.com/openresty/rds-json-nginx-module syn keyword ngxDirectiveThirdParty contained rds_json syn keyword ngxDirectiveThirdParty contained rds_json_buffer_size @@ -1624,7 +1661,6 @@ syn keyword ngxDirectiveThirdParty contained rds_json_root syn keyword ngxDirectiveThirdParty contained rds_json_success_property syn keyword ngxDirectiveThirdParty contained rds_json_user_property -" ngx_redis2 - Nginx upstream module for the Redis 2.0 protocol " https://github.com/openresty/redis2-nginx-module syn keyword ngxDirectiveThirdParty contained redis2_bind syn keyword ngxDirectiveThirdParty contained redis2_buffer_size @@ -1638,7 +1674,6 @@ syn keyword ngxDirectiveThirdParty contained redis2_raw_query syn keyword ngxDirectiveThirdParty contained redis2_read_timeout syn keyword ngxDirectiveThirdParty contained redis2_send_timeout -" NGINX-based Media Streaming Server " https://github.com/arut/nginx-rtmp-module syn keyword ngxDirectiveThirdParty contained ack_window syn keyword ngxDirectiveThirdParty contained application @@ -1750,7 +1785,6 @@ syn keyword ngxDirectiveThirdParty contained sync syn keyword ngxDirectiveThirdParty contained wait_key syn keyword ngxDirectiveThirdParty contained wait_video -" ngx_set_misc - Various set_xxx directives added to nginx's rewrite module (md5/sha1, sql/json quoting, and many more) " https://github.com/openresty/set-misc-nginx-module syn keyword ngxDirectiveThirdParty contained set_base32_alphabet syn keyword ngxDirectiveThirdParty contained set_base32_padding @@ -1770,6 +1804,7 @@ syn keyword ngxDirectiveThirdParty contained set_hmac_sha1 syn keyword ngxDirectiveThirdParty contained set_hmac_sha256 syn keyword ngxDirectiveThirdParty contained set_if_empty syn keyword ngxDirectiveThirdParty contained set_local_today +syn keyword ngxDirectiveThirdParty contained set_md5 syn keyword ngxDirectiveThirdParty contained set_misc_base32_padding syn keyword ngxDirectiveThirdParty contained set_quote_json_str syn keyword ngxDirectiveThirdParty contained set_quote_pgsql_str @@ -1778,20 +1813,18 @@ syn keyword ngxDirectiveThirdParty contained set_random syn keyword ngxDirectiveThirdParty contained set_rotate syn keyword ngxDirectiveThirdParty contained set_secure_random_alphanum syn keyword ngxDirectiveThirdParty contained set_secure_random_lcalpha +syn keyword ngxDirectiveThirdParty contained set_sha1 syn keyword ngxDirectiveThirdParty contained set_unescape_uri -" nginx-sflow-module " https://github.com/sflow/nginx-sflow-module syn keyword ngxDirectiveThirdParty contained sflow -" Shibboleth auth request module for Nginx " https://github.com/nginx-shib/nginx-http-shibboleth syn keyword ngxDirectiveThirdParty contained shib_request syn keyword ngxDirectiveThirdParty contained shib_request_set syn keyword ngxDirectiveThirdParty contained shib_request_use_headers -" nginx module which adds ability to cache static files -" https://github.com/FRiCKLE/ngx_slowfs_cache +" https://github.com/baysao/ngx_slowfs_cache syn keyword ngxDirectiveThirdParty contained slowfs_big_file_size syn keyword ngxDirectiveThirdParty contained slowfs_cache syn keyword ngxDirectiveThirdParty contained slowfs_cache_key @@ -1801,8 +1834,7 @@ syn keyword ngxDirectiveThirdParty contained slowfs_cache_purge syn keyword ngxDirectiveThirdParty contained slowfs_cache_valid syn keyword ngxDirectiveThirdParty contained slowfs_temp_path -" Dynamic Image Transformation Module For nginx -" https://github.com/cubicdaiya/ngx_small_light +" https://github.com/kawakibi/ngx_small_light syn keyword ngxDirectiveThirdParty contained small_light syn keyword ngxDirectiveThirdParty contained small_light_buffer syn keyword ngxDirectiveThirdParty contained small_light_getparam_mode @@ -1812,7 +1844,6 @@ syn keyword ngxDirectiveThirdParty contained small_light_pattern_define syn keyword ngxDirectiveThirdParty contained small_light_radius_max syn keyword ngxDirectiveThirdParty contained small_light_sigma_max -" ngx_srcache - Transparent subrequest-based caching layout for arbitrary nginx locations " https://github.com/openresty/srcache-nginx-module syn keyword ngxDirectiveThirdParty contained srcache_buffer syn keyword ngxDirectiveThirdParty contained srcache_default_expire @@ -1835,7 +1866,6 @@ syn keyword ngxDirectiveThirdParty contained srcache_store_ranges syn keyword ngxDirectiveThirdParty contained srcache_store_skip syn keyword ngxDirectiveThirdParty contained srcache_store_statuses -" NGINX-based VOD Packager " https://github.com/kaltura/nginx-vod-module syn keyword ngxDirectiveThirdParty contained vod syn keyword ngxDirectiveThirdParty contained vod_align_segments_to_key_frames @@ -1875,6 +1905,7 @@ syn keyword ngxDirectiveThirdParty contained vod_live_window_duration syn keyword ngxDirectiveThirdParty contained vod_manifest_duration_policy syn keyword ngxDirectiveThirdParty contained vod_manifest_segment_durations_mode syn keyword ngxDirectiveThirdParty contained vod_mapping_cache +syn keyword ngxDirectiveThirdParty contained vod_max_frame_count syn keyword ngxDirectiveThirdParty contained vod_max_frames_size syn keyword ngxDirectiveThirdParty contained vod_max_mapping_response_size syn keyword ngxDirectiveThirdParty contained vod_max_metadata_size @@ -1901,6 +1932,7 @@ syn keyword ngxDirectiveThirdParty contained vod_response_cache syn keyword ngxDirectiveThirdParty contained vod_secret_key syn keyword ngxDirectiveThirdParty contained vod_segment_count_policy syn keyword ngxDirectiveThirdParty contained vod_segment_duration +syn keyword ngxDirectiveThirdParty contained vod_segment_max_frame_count syn keyword ngxDirectiveThirdParty contained vod_segments_base_url syn keyword ngxDirectiveThirdParty contained vod_source_clip_map_uri syn keyword ngxDirectiveThirdParty contained vod_speed_param_name @@ -1910,7 +1942,6 @@ syn keyword ngxDirectiveThirdParty contained vod_tracks_param_name syn keyword ngxDirectiveThirdParty contained vod_upstream_extra_args syn keyword ngxDirectiveThirdParty contained vod_upstream_location -" Nginx virtual host traffic status module " https://github.com/vozlt/nginx-module-vts syn keyword ngxDirectiveThirdParty contained vhost_traffic_status syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_average_method @@ -1934,7 +1965,6 @@ syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_limit_traffic_ syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_set_by_filter syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_zone -" xss-nginx-module - Native cross-site scripting support in nginx " https://github.com/openresty/xss-nginx-module syn keyword ngxDirectiveThirdParty contained xss_callback_arg syn keyword ngxDirectiveThirdParty contained xss_check_status @@ -1943,471 +1973,6 @@ syn keyword ngxDirectiveThirdParty contained xss_input_types syn keyword ngxDirectiveThirdParty contained xss_output_type syn keyword ngxDirectiveThirdParty contained xss_override_status -" Add support for array-typed variables to nginx config files -" https://github.com/openresty/array-var-nginx-module -syn keyword ngxDirectiveThirdParty contained array_join -syn keyword ngxDirectiveThirdParty contained array_map -syn keyword ngxDirectiveThirdParty contained array_map_op -syn keyword ngxDirectiveThirdParty contained array_split - -" NGINX module for Brotli compression -" https://github.com/eustas/ngx_brotli -syn keyword ngxDirectiveThirdParty contained brotli -syn keyword ngxDirectiveThirdParty contained brotli_buffers -syn keyword ngxDirectiveThirdParty contained brotli_comp_level -syn keyword ngxDirectiveThirdParty contained brotli_min_length -syn keyword ngxDirectiveThirdParty contained brotli_static -syn keyword ngxDirectiveThirdParty contained brotli_types -syn keyword ngxDirectiveThirdParty contained brotli_window - -" form-input-nginx-module -" https://github.com/calio/form-input-nginx-module -syn keyword ngxDirectiveThirdParty contained set_form_input -syn keyword ngxDirectiveThirdParty contained set_form_input_multi - -" character conversion nginx module using libiconv -" https://github.com/calio/iconv-nginx-module -syn keyword ngxDirectiveThirdParty contained iconv_buffer_size -syn keyword ngxDirectiveThirdParty contained iconv_filter -syn keyword ngxDirectiveThirdParty contained set_iconv - -" 3rd party modules list taken from -" https://www.nginx.com/resources/wiki/modules/ -" --------------------------------------------- - -" Nginx Module for Authenticating Akamai G2O requests -" https://github.com/kaltura/nginx_mod_akamai_g2o -syn keyword ngxDirectiveThirdParty contained g2o -syn keyword ngxDirectiveThirdParty contained g2o_data_header -syn keyword ngxDirectiveThirdParty contained g2o_hash_function -syn keyword ngxDirectiveThirdParty contained g2o_key -syn keyword ngxDirectiveThirdParty contained g2o_log_level -syn keyword ngxDirectiveThirdParty contained g2o_nonce -syn keyword ngxDirectiveThirdParty contained g2o_sign_header -syn keyword ngxDirectiveThirdParty contained g2o_time_window -syn keyword ngxDirectiveThirdParty contained g2o_version - -" nginx_lua_module -" https://github.com/alacner/nginx_lua_module -syn keyword ngxDirectiveThirdParty contained lua_file - -" Nginx Audio Track for HTTP Live Streaming -" https://github.com/flavioribeiro/nginx-audio-track-for-hls-module -syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track -syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track_output_format -syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track_output_header -syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track_rootpath - -" A Nginx module to dump backtrace when a worker process exits abnormally -" https://github.com/alibaba/nginx-backtrace -syn keyword ngxDirectiveThirdParty contained backtrace_log -syn keyword ngxDirectiveThirdParty contained backtrace_max_stack_size - -" circle_gif module -" https://github.com/evanmiller/nginx_circle_gif -syn keyword ngxDirectiveThirdParty contained circle_gif -syn keyword ngxDirectiveThirdParty contained circle_gif_max_radius -syn keyword ngxDirectiveThirdParty contained circle_gif_min_radius -syn keyword ngxDirectiveThirdParty contained circle_gif_step_radius - -" Upstream Consistent Hash -" https://github.com/replay/ngx_http_consistent_hash -syn keyword ngxDirectiveThirdParty contained consistent_hash - -" Nginx module for etags on dynamic content -" https://github.com/kali/nginx-dynamic-etags -syn keyword ngxDirectiveThirdParty contained dynamic_etags - -" Enhanced Nginx Memcached Module -" https://github.com/bpaquet/ngx_http_enhanced_memcached_module -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_allow_delete -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_allow_put -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_bind -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_buffer_size -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_connect_timeout -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_flush -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_flush_namespace -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_hash_keys_with_md5 -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_pass -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_read_timeout -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_send_timeout -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_stats - -" nginx max connections queue -" https://github.com/ezmobius/nginx-ey-balancer -syn keyword ngxDirectiveThirdParty contained max_connections_max_queue_length -syn keyword ngxDirectiveThirdParty contained max_connections_queue_timeout - -" Nginx module for POST authentication and authorization -" https://github.com/veruu/ngx_form_auth -syn keyword ngxDirectiveThirdParty contained form_auth -syn keyword ngxDirectiveThirdParty contained form_auth_login -syn keyword ngxDirectiveThirdParty contained form_auth_pam_service -syn keyword ngxDirectiveThirdParty contained form_auth_password -syn keyword ngxDirectiveThirdParty contained form_auth_remote_user - -" ngx_http_accounting_module -" https://github.com/Lax/ngx_http_accounting_module -syn keyword ngxDirectiveThirdParty contained accounting -syn keyword ngxDirectiveThirdParty contained accounting_id -syn keyword ngxDirectiveThirdParty contained accounting_interval -syn keyword ngxDirectiveThirdParty contained accounting_log -syn keyword ngxDirectiveThirdParty contained accounting_perturb - -" concatenating files in a given context: CSS and JS files usually -" https://github.com/alibaba/nginx-http-concat -syn keyword ngxDirectiveThirdParty contained concat -syn keyword ngxDirectiveThirdParty contained concat_delimiter -syn keyword ngxDirectiveThirdParty contained concat_ignore_file_error -syn keyword ngxDirectiveThirdParty contained concat_max_files -syn keyword ngxDirectiveThirdParty contained concat_types -syn keyword ngxDirectiveThirdParty contained concat_unique - -" update upstreams' config by restful interface -" https://github.com/yzprofile/ngx_http_dyups_module -syn keyword ngxDirectiveThirdParty contained dyups_interface -syn keyword ngxDirectiveThirdParty contained dyups_shm_zone_size - -" add given content to the end of the response according to the condition specified -" https://github.com/flygoast/ngx_http_footer_if_filter -syn keyword ngxDirectiveThirdParty contained footer_if - -" NGINX HTTP Internal Redirect Module -" https://github.com/flygoast/ngx_http_internal_redirect -syn keyword ngxDirectiveThirdParty contained internal_redirect_if -syn keyword ngxDirectiveThirdParty contained internal_redirect_if_no_postpone - -" nginx-ip-blocker -" https://github.com/tmthrgd/nginx-ip-blocker -syn keyword ngxDirectiveThirdParty contained ip_blocker - -" IP2Location Nginx -" https://github.com/chrislim2888/ip2location-nginx -syn keyword ngxDirectiveThirdParty contained ip2location_database - -" Limit upload rate -" https://github.com/cfsego/limit_upload_rate -syn keyword ngxDirectiveThirdParty contained limit_upload_rate -syn keyword ngxDirectiveThirdParty contained limit_upload_rate_after -syn keyword ngxDirectiveThirdParty contained limit_upload_rate_log_level - -" limit the number of connections to upstream -" https://github.com/cfsego/nginx-limit-upstream -syn keyword ngxDirectiveThirdParty contained limit_upstream_conn -syn keyword ngxDirectiveThirdParty contained limit_upstream_log_level -syn keyword ngxDirectiveThirdParty contained limit_upstream_zone - -" conditional accesslog for nginx -" https://github.com/cfsego/ngx_log_if -syn keyword ngxDirectiveThirdParty contained access_log_bypass_if - -" log messages over ZeroMQ -" https://github.com/alticelabs/nginx-log-zmq -syn keyword ngxDirectiveThirdParty contained log_zmq_endpoint -syn keyword ngxDirectiveThirdParty contained log_zmq_format -syn keyword ngxDirectiveThirdParty contained log_zmq_off -syn keyword ngxDirectiveThirdParty contained log_zmq_server - -" simple module to uppercase/lowercase strings in the nginx config -" https://github.com/replay/ngx_http_lower_upper_case -syn keyword ngxDirectiveThirdParty contained lower -syn keyword ngxDirectiveThirdParty contained upper - -" content filter for nginx, which returns the md5 hash of the content otherwise returned -" https://github.com/kainswor/nginx_md5_filter -syn keyword ngxDirectiveThirdParty contained md5_filter - -" Non-blocking upstream module for Nginx to connect to MongoDB -" https://github.com/simpl/ngx_mongo -syn keyword ngxDirectiveThirdParty contained mongo_auth -syn keyword ngxDirectiveThirdParty contained mongo_bind -syn keyword ngxDirectiveThirdParty contained mongo_buffer_size -syn keyword ngxDirectiveThirdParty contained mongo_buffering -syn keyword ngxDirectiveThirdParty contained mongo_buffers -syn keyword ngxDirectiveThirdParty contained mongo_busy_buffers_size -syn keyword ngxDirectiveThirdParty contained mongo_connect_timeout -syn keyword ngxDirectiveThirdParty contained mongo_json -syn keyword ngxDirectiveThirdParty contained mongo_next_upstream -syn keyword ngxDirectiveThirdParty contained mongo_pass -syn keyword ngxDirectiveThirdParty contained mongo_query -syn keyword ngxDirectiveThirdParty contained mongo_read_timeout -syn keyword ngxDirectiveThirdParty contained mongo_send_timeout - -" Nginx OCSP processing module designed for response caching -" https://github.com/kyprizel/nginx_ocsp_proxy-module -syn keyword ngxDirectiveThirdParty contained ocsp_cache_timeout -syn keyword ngxDirectiveThirdParty contained ocsp_proxy - -" Nginx OpenSSL version check at startup -" https://github.com/apcera/nginx-openssl-version -syn keyword ngxDirectiveThirdParty contained openssl_builddate_minimum -syn keyword ngxDirectiveThirdParty contained openssl_version_minimum - -" Automatic PageSpeed optimization module for Nginx -" https://github.com/pagespeed/ngx_pagespeed -syn keyword ngxDirectiveThirdParty contained pagespeed - -" PECL Memcache standard hashing compatible loadbalancer for Nginx -" https://github.com/replay/ngx_http_php_memcache_standard_balancer -syn keyword ngxDirectiveThirdParty contained hash_key - -" nginx module to parse php sessions -" https://github.com/replay/ngx_http_php_session -syn keyword ngxDirectiveThirdParty contained php_session_parse -syn keyword ngxDirectiveThirdParty contained php_session_strip_formatting - -" Nginx HTTP rDNS module -" https://github.com/flant/nginx-http-rdns -syn keyword ngxDirectiveThirdParty contained rdns -syn keyword ngxDirectiveThirdParty contained rdns_allow -syn keyword ngxDirectiveThirdParty contained rdns_deny - -" Streaming regular expression replacement in response bodies -" https://github.com/openresty/replace-filter-nginx-module -syn keyword ngxDirectiveThirdParty contained replace_filter -syn keyword ngxDirectiveThirdParty contained replace_filter_last_modified -syn keyword ngxDirectiveThirdParty contained replace_filter_max_buffered_size -syn keyword ngxDirectiveThirdParty contained replace_filter_skip -syn keyword ngxDirectiveThirdParty contained replace_filter_types - -" Link RRDtool's graphing facilities directly into nginx -" https://github.com/evanmiller/mod_rrd_graph -syn keyword ngxDirectiveThirdParty contained rrd_graph -syn keyword ngxDirectiveThirdParty contained rrd_graph_root - -" Module for nginx to proxy rtmp using http protocol -" https://github.com/kwojtek/nginx-rtmpt-proxy-module -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_http_timeout -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_rtmp_timeout -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_stat -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_stylesheet -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_target - -" Syntactically Awesome NGINX Module -" https://github.com/mneudert/sass-nginx-module -syn keyword ngxDirectiveThirdParty contained sass_compile -syn keyword ngxDirectiveThirdParty contained sass_error_log -syn keyword ngxDirectiveThirdParty contained sass_include_path -syn keyword ngxDirectiveThirdParty contained sass_indent -syn keyword ngxDirectiveThirdParty contained sass_is_indented_syntax -syn keyword ngxDirectiveThirdParty contained sass_linefeed -syn keyword ngxDirectiveThirdParty contained sass_output_style -syn keyword ngxDirectiveThirdParty contained sass_precision -syn keyword ngxDirectiveThirdParty contained sass_source_comments -syn keyword ngxDirectiveThirdParty contained sass_source_map_embed - -" Nginx Selective Cache Purge Module -" https://github.com/wandenberg/nginx-selective-cache-purge-module -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_query -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_database -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_host -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_password -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_port -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_unix_socket - -" cconv nginx module -" https://github.com/liseen/set-cconv-nginx-module -syn keyword ngxDirectiveThirdParty contained set_cconv_to_simp -syn keyword ngxDirectiveThirdParty contained set_cconv_to_trad -syn keyword ngxDirectiveThirdParty contained set_pinyin_to_normal - -" Nginx module that allows the setting of variables to the value of a variety of hashes -" https://github.com/simpl/ngx_http_set_hash -syn keyword ngxDirectiveThirdParty contained set_md5 -syn keyword ngxDirectiveThirdParty contained set_md5_upper -syn keyword ngxDirectiveThirdParty contained set_murmur2 -syn keyword ngxDirectiveThirdParty contained set_murmur2_upper -syn keyword ngxDirectiveThirdParty contained set_sha1 -syn keyword ngxDirectiveThirdParty contained set_sha1_upper - -" Nginx module to set the language of a request based on a number of options -" https://github.com/simpl/ngx_http_set_lang -syn keyword ngxDirectiveThirdParty contained lang_cookie -syn keyword ngxDirectiveThirdParty contained lang_get_var -syn keyword ngxDirectiveThirdParty contained lang_host -syn keyword ngxDirectiveThirdParty contained lang_list -syn keyword ngxDirectiveThirdParty contained lang_post_var -syn keyword ngxDirectiveThirdParty contained lang_referer -syn keyword ngxDirectiveThirdParty contained set_lang -syn keyword ngxDirectiveThirdParty contained set_lang_method - -" Nginx Sorted Querystring Module -" https://github.com/wandenberg/nginx-sorted-querystring-module -syn keyword ngxDirectiveThirdParty contained sorted_querysting_filter_parameter - -" Nginx upstream module for Sphinx 2.x search daemon -" https://github.com/reeteshranjan/sphinx2-nginx-module -syn keyword ngxDirectiveThirdParty contained sphinx2_bind -syn keyword ngxDirectiveThirdParty contained sphinx2_buffer_size -syn keyword ngxDirectiveThirdParty contained sphinx2_connect_timeout -syn keyword ngxDirectiveThirdParty contained sphinx2_next_upstream -syn keyword ngxDirectiveThirdParty contained sphinx2_pass -syn keyword ngxDirectiveThirdParty contained sphinx2_read_timeout -syn keyword ngxDirectiveThirdParty contained sphinx2_send_timeout - -" Nginx module for retrieving user attributes and groups from SSSD -" https://github.com/veruu/ngx_sssd_info -syn keyword ngxDirectiveThirdParty contained sssd_info -syn keyword ngxDirectiveThirdParty contained sssd_info_attribute -syn keyword ngxDirectiveThirdParty contained sssd_info_attribute_separator -syn keyword ngxDirectiveThirdParty contained sssd_info_attributes -syn keyword ngxDirectiveThirdParty contained sssd_info_group -syn keyword ngxDirectiveThirdParty contained sssd_info_group_separator -syn keyword ngxDirectiveThirdParty contained sssd_info_groups -syn keyword ngxDirectiveThirdParty contained sssd_info_output_to - -" An nginx module for sending statistics to statsd -" https://github.com/zebrafishlabs/nginx-statsd -syn keyword ngxDirectiveThirdParty contained statsd_count -syn keyword ngxDirectiveThirdParty contained statsd_sample_rate -syn keyword ngxDirectiveThirdParty contained statsd_server -syn keyword ngxDirectiveThirdParty contained statsd_timing - -" ngx_stream_echo - TCP/stream echo module for NGINX (a port of the ngx_http_echo module) -" https://github.com/openresty/stream-echo-nginx-module -syn keyword ngxDirectiveThirdParty contained echo -syn keyword ngxDirectiveThirdParty contained echo_client_error_log_level -syn keyword ngxDirectiveThirdParty contained echo_discard_request -syn keyword ngxDirectiveThirdParty contained echo_duplicate -syn keyword ngxDirectiveThirdParty contained echo_flush_wait -syn keyword ngxDirectiveThirdParty contained echo_lingering_close -syn keyword ngxDirectiveThirdParty contained echo_lingering_time -syn keyword ngxDirectiveThirdParty contained echo_lingering_timeout -syn keyword ngxDirectiveThirdParty contained echo_read_buffer_size -syn keyword ngxDirectiveThirdParty contained echo_read_bytes -syn keyword ngxDirectiveThirdParty contained echo_read_line -syn keyword ngxDirectiveThirdParty contained echo_read_timeout -syn keyword ngxDirectiveThirdParty contained echo_request_data -syn keyword ngxDirectiveThirdParty contained echo_send_timeout -syn keyword ngxDirectiveThirdParty contained echo_sleep - -" Embed the power of Lua into NGINX TCP/UDP servers -" https://github.com/openresty/stream-lua-nginx-module -syn keyword ngxDirectiveThirdParty contained lua_add_variable -syn keyword ngxDirectiveThirdParty contained preread_by_lua_block -syn keyword ngxDirectiveThirdParty contained preread_by_lua_file -syn keyword ngxDirectiveThirdParty contained preread_by_lua_no_postpone - -" nginx-upsync-module -" https://github.com/weibocom/nginx-upsync-module -syn keyword ngxDirectiveThirdParty contained upstream_show -syn keyword ngxDirectiveThirdParty contained upsync -syn keyword ngxDirectiveThirdParty contained upsync_dump_path -syn keyword ngxDirectiveThirdParty contained upsync_lb - -" Whitespace stripper for nginx -" https://github.com/evanmiller/mod_strip -syn keyword ngxDirectiveThirdParty contained strip - -" Split one big HTTP/Range request to multiple subrange requesets -" https://github.com/Qihoo360/ngx_http_subrange_module -syn keyword ngxDirectiveThirdParty contained subrange - -" summarizer-nginx-module -" https://github.com/reeteshranjan/summarizer-nginx-module -syn keyword ngxDirectiveThirdParty contained summarizer_bind -syn keyword ngxDirectiveThirdParty contained summarizer_buffer_size -syn keyword ngxDirectiveThirdParty contained summarizer_connect_timeout -syn keyword ngxDirectiveThirdParty contained summarizer_next_upstream -syn keyword ngxDirectiveThirdParty contained summarizer_pass -syn keyword ngxDirectiveThirdParty contained summarizer_read_timeout -syn keyword ngxDirectiveThirdParty contained summarizer_send_timeout - -" nginx module providing API to communicate with supervisord and manage (start/stop) backends on-demand -" https://github.com/FRiCKLE/ngx_supervisord -syn keyword ngxDirectiveThirdParty contained supervisord -syn keyword ngxDirectiveThirdParty contained supervisord_inherit_backend_status -syn keyword ngxDirectiveThirdParty contained supervisord_name -syn keyword ngxDirectiveThirdParty contained supervisord_start -syn keyword ngxDirectiveThirdParty contained supervisord_stop - -" simple robot mitigation module using cookie based challenge/response technique. Not supported any more. -" https://github.com/kyprizel/testcookie-nginx-module -syn keyword ngxDirectiveThirdParty contained testcookie -syn keyword ngxDirectiveThirdParty contained testcookie_arg -syn keyword ngxDirectiveThirdParty contained testcookie_deny_keepalive -syn keyword ngxDirectiveThirdParty contained testcookie_domain -syn keyword ngxDirectiveThirdParty contained testcookie_expires -syn keyword ngxDirectiveThirdParty contained testcookie_fallback -syn keyword ngxDirectiveThirdParty contained testcookie_get_only -syn keyword ngxDirectiveThirdParty contained testcookie_httponly_flag -syn keyword ngxDirectiveThirdParty contained testcookie_https_location -syn keyword ngxDirectiveThirdParty contained testcookie_internal -syn keyword ngxDirectiveThirdParty contained testcookie_max_attempts -syn keyword ngxDirectiveThirdParty contained testcookie_name -syn keyword ngxDirectiveThirdParty contained testcookie_p3p -syn keyword ngxDirectiveThirdParty contained testcookie_pass -syn keyword ngxDirectiveThirdParty contained testcookie_path -syn keyword ngxDirectiveThirdParty contained testcookie_port_in_redirect -syn keyword ngxDirectiveThirdParty contained testcookie_redirect_via_refresh -syn keyword ngxDirectiveThirdParty contained testcookie_refresh_encrypt_cookie -syn keyword ngxDirectiveThirdParty contained testcookie_refresh_encrypt_cookie_iv -syn keyword ngxDirectiveThirdParty contained testcookie_refresh_encrypt_cookie_key -syn keyword ngxDirectiveThirdParty contained testcookie_refresh_status -syn keyword ngxDirectiveThirdParty contained testcookie_refresh_template -syn keyword ngxDirectiveThirdParty contained testcookie_samesite -syn keyword ngxDirectiveThirdParty contained testcookie_secret -syn keyword ngxDirectiveThirdParty contained testcookie_secure_flag -syn keyword ngxDirectiveThirdParty contained testcookie_session -syn keyword ngxDirectiveThirdParty contained testcookie_whitelist - -" ngx_http_types_filter_module -" https://github.com/flygoast/ngx_http_types_filter -syn keyword ngxDirectiveThirdParty contained types_filter -syn keyword ngxDirectiveThirdParty contained types_filter_use_default - -" A module allowing the nginx to use files embedded in a zip file -" https://github.com/youzee/nginx-unzip-module -syn keyword ngxDirectiveThirdParty contained file_in_unzip -syn keyword ngxDirectiveThirdParty contained file_in_unzip_archivefile -syn keyword ngxDirectiveThirdParty contained file_in_unzip_extract - -" An asynchronous domain name resolve module for nginx upstream -" https://github.com/wdaike/ngx_upstream_jdomain -syn keyword ngxDirectiveThirdParty contained jdomain - -" Nginx url encoding converting module -" https://github.com/vozlt/nginx-module-url -syn keyword ngxDirectiveThirdParty contained url_encoding_convert -syn keyword ngxDirectiveThirdParty contained url_encoding_convert_alloc_size -syn keyword ngxDirectiveThirdParty contained url_encoding_convert_alloc_size_x -syn keyword ngxDirectiveThirdParty contained url_encoding_convert_from -syn keyword ngxDirectiveThirdParty contained url_encoding_convert_phase -syn keyword ngxDirectiveThirdParty contained url_encoding_convert_to - -" A nginx module to match browsers and crawlers -" https://github.com/alibaba/nginx-http-user-agent -syn keyword ngxDirectiveThirdParty contained user_agent - -" nginx load-balancer module implementing ketama consistent hashing -" https://github.com/flygoast/ngx_http_upstream_ketama_chash -syn keyword ngxDirectiveThirdParty contained ketama_chash - -" nginx-sticky-module-ng -" https://github.com/ayty-adrianomartins/nginx-sticky-module-ng -syn keyword ngxDirectiveThirdParty contained sticky_no_fallback - -" dynamic linking and call the function of your application -" https://github.com/Taymindis/nginx-link-function -syn keyword ngxDirectiveThirdParty contained ngx_link_func_add_prop -syn keyword ngxDirectiveThirdParty contained ngx_link_func_add_req_header -syn keyword ngxDirectiveThirdParty contained ngx_link_func_ca_cert -syn keyword ngxDirectiveThirdParty contained ngx_link_func_call -syn keyword ngxDirectiveThirdParty contained ngx_link_func_download_link_lib -syn keyword ngxDirectiveThirdParty contained ngx_link_func_lib -syn keyword ngxDirectiveThirdParty contained ngx_link_func_shm_size -syn keyword ngxDirectiveThirdParty contained ngx_link_func_subrequest - -" purge content from FastCGI, proxy, SCGI and uWSGI caches -" https://github.com/torden/ngx_cache_purge -syn keyword ngxDirectiveThirdParty contained cache_purge_response_type - -" set the flags "HttpOnly", "secure" and "SameSite" for cookies -" https://github.com/AirisX/nginx_cookie_flag_module -syn keyword ngxDirectiveThirdParty contained set_cookie_flag - -" Embed websockify into Nginx (convert any tcp connection into websocket) " https://github.com/tg123/websockify-nginx-module syn keyword ngxDirectiveThirdParty contained websockify_buffer_size syn keyword ngxDirectiveThirdParty contained websockify_connect_timeout @@ -2415,55 +1980,6 @@ syn keyword ngxDirectiveThirdParty contained websockify_pass syn keyword ngxDirectiveThirdParty contained websockify_read_timeout syn keyword ngxDirectiveThirdParty contained websockify_send_timeout -" IP2Location Nginx -" https://github.com/ip2location/ip2location-nginx -syn keyword ngxDirectiveThirdParty contained ip2location_addresstype -syn keyword ngxDirectiveThirdParty contained ip2location_areacode -syn keyword ngxDirectiveThirdParty contained ip2location_category -syn keyword ngxDirectiveThirdParty contained ip2location_city -syn keyword ngxDirectiveThirdParty contained ip2location_country_long -syn keyword ngxDirectiveThirdParty contained ip2location_country_short -syn keyword ngxDirectiveThirdParty contained ip2location_domain -syn keyword ngxDirectiveThirdParty contained ip2location_elevation -syn keyword ngxDirectiveThirdParty contained ip2location_iddcode -syn keyword ngxDirectiveThirdParty contained ip2location_isp -syn keyword ngxDirectiveThirdParty contained ip2location_latitude -syn keyword ngxDirectiveThirdParty contained ip2location_longitude -syn keyword ngxDirectiveThirdParty contained ip2location_mcc -syn keyword ngxDirectiveThirdParty contained ip2location_mnc -syn keyword ngxDirectiveThirdParty contained ip2location_mobilebrand -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_timezone -syn keyword ngxDirectiveThirdParty contained ip2location_usagetype -syn keyword ngxDirectiveThirdParty contained ip2location_weatherstationcode -syn keyword ngxDirectiveThirdParty contained ip2location_weatherstationname -syn keyword ngxDirectiveThirdParty contained ip2location_zipcode - -" IP2Proxy module for Nginx -" https://github.com/ip2location/ip2proxy-nginx -syn keyword ngxDirectiveThirdParty contained ip2proxy_as -syn keyword ngxDirectiveThirdParty contained ip2proxy_asn -syn keyword ngxDirectiveThirdParty contained ip2proxy_city -syn keyword ngxDirectiveThirdParty contained ip2proxy_country_long -syn keyword ngxDirectiveThirdParty contained ip2proxy_country_short -syn keyword ngxDirectiveThirdParty contained ip2proxy_database -syn keyword ngxDirectiveThirdParty contained ip2proxy_domain -syn keyword ngxDirectiveThirdParty contained ip2proxy_isp -syn keyword ngxDirectiveThirdParty contained ip2proxy_is_proxy -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_recursive -syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy_type -syn keyword ngxDirectiveThirdParty contained ip2proxy_region -syn keyword ngxDirectiveThirdParty contained ip2proxy_threat -syn keyword ngxDirectiveThirdParty contained ip2proxy_usage_type - - - " highlight hi def link ngxComment Comment From 295f5b28aefdb97e94ddd51b0773c6d7a2a91e9b Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 20 Jun 2022 19:30:50 +0300 Subject: [PATCH 34/37] Misc: win32 sources now preserved in release tarballs. This makes it possible to build nginx under Windows from release tarballs instead of using source code repository. --- misc/GNUmakefile | 6 ------ 1 file changed, 6 deletions(-) diff --git a/misc/GNUmakefile b/misc/GNUmakefile index 8f839b477..6895317c8 100644 --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -15,12 +15,6 @@ release: export mv $(TEMP)/$(NGINX)/auto/configure $(TEMP)/$(NGINX) - # delete incomplete sources - rm $(TEMP)/$(NGINX)/src/event/ngx_event_acceptex.c - rm $(TEMP)/$(NGINX)/src/event/ngx_event_connectex.c - rm $(TEMP)/$(NGINX)/src/event/modules/ngx_iocp_module.* - rm -r $(TEMP)/$(NGINX)/src/os/win32 - mv $(TEMP)/$(NGINX)/docs/text/LICENSE $(TEMP)/$(NGINX) mv $(TEMP)/$(NGINX)/docs/text/README $(TEMP)/$(NGINX) mv $(TEMP)/$(NGINX)/docs/html $(TEMP)/$(NGINX) From 35c2d7a75e4c845251901b69cb4363fd61ddb1cd Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 21 Jun 2022 17:09:34 +0300 Subject: [PATCH 35/37] Updated OpenSSL used for win32 builds. --- misc/GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/GNUmakefile b/misc/GNUmakefile index 6895317c8..dfb5b9b62 100644 --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -6,7 +6,7 @@ TEMP = tmp CC = cl OBJS = objs.msvc8 -OPENSSL = openssl-1.1.1o +OPENSSL = openssl-1.1.1p ZLIB = zlib-1.2.12 PCRE = pcre2-10.39 From 2d2d0829a992c786a53c3bea6e804653ad2f5ba9 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 21 Jun 2022 17:25:36 +0300 Subject: [PATCH 36/37] nginx-1.23.0-RELEASE --- docs/xml/nginx/changes.xml | 101 +++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml index 2f9c350e1..b084f6f82 100644 --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,107 @@ + + + + +Изменение во внутреннем API: +теперь строки заголовков представлены связными списками. + + +Change in internal API: +now header lines are represented as linked lists. + + + + + +теперь nginx объединяет произвольные строки заголовков с одинаковыми именами +при отправке на FastCGI-, SCGI- и uwsgi-бэкенды, +в методе $r->header_in() модуля ngx_http_perl_module, +и при доступе через переменные "$http_...", "$sent_http_...", +"$sent_trailer_...", "$upstream_http_..." и "$upstream_trailer_...". + + +now nginx combines arbitrary header lines with identical names +when sending to FastCGI, SCGI, and uwsgi backends, +in the $r->header_in() method of the ngx_http_perl_module, +and during lookup of the "$http_...", "$sent_http_...", +"$sent_trailer_...", "$upstream_http_...", and "$upstream_trailer_..." +variables. + + + + + +если в заголовке ответа бэкенда было несколько строк "Vary", +при кэшировании nginx учитывал только последнюю из них. + + +if there were multiple "Vary" header lines in the backend response, +nginx only used the last of them when caching. + + + + + +если в заголовке ответа бэкенда было несколько строк "WWW-Authenticate" +и использовался перехват ошибок с кодом 401 от бэкенда +или директива auth_request, +nginx пересылал клиенту только первую из этих строк. + + +if there were multiple "WWW-Authenticate" header lines in the backend response +and errors with code 401 were intercepted +or the "auth_request" directive was used, +nginx only sent the first of the header lines to the client. + + + + + +уровень логгирования ошибок SSL "application data after close notify" +понижен с уровня crit до info. + + +the logging level of the "application data after close notify" SSL errors +has been lowered from "crit" to "info". + + + + + +соединения могли зависать, если nginx был собран на Linux 2.6.17 и новее, +а использовался на системах без поддержки EPOLLRDHUP, в частности, на +системах с эмуляцией epoll; +ошибка появилась в 1.17.5.
+Спасибо Marcus Ball. +
+ +connections might hang if nginx was built on Linux 2.6.17 or newer, +but was used on systems without EPOLLRDHUP support, notably with epoll +emulation layers; +the bug had appeared in 1.17.5.
+Thanks to Marcus Ball. +
+
+ + + +nginx не кэшировал ответ, +если строка заголовка ответа "Expires" запрещала кэширование, +а последующая строка заголовка "Cache-Control" разрешала кэширование. + + +nginx did not cache the response +if the "Expires" response header line disabled caching, +but following "Cache-Control" header line enabled caching. + + + +
+ + From 1009f5586ccf07375595675227d296815d91b2f2 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 21 Jun 2022 17:25:37 +0300 Subject: [PATCH 37/37] release-1.23.0 tag --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 40a72593c..ef9cbf79f 100644 --- a/.hgtags +++ b/.hgtags @@ -467,3 +467,4 @@ bfbc52374adcbf2f9060afd62de940f6fab3bba5 release-1.21.2 39be8a682c58308d9399cddd57e37f9fdb7bdf3e release-1.21.4 d986378168fd4d70e0121cabac274c560cca9bdf release-1.21.5 714eb4b2c09e712fb2572a2164ce2bf67638ccac release-1.21.6 +5da2c0902e8e2aa4534008a582a60c61c135960e release-1.23.0