From e59c2096ae9d561997ad2d64d61094503e6be4c3 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:45 +0300 Subject: [PATCH] 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 @@ ngx_http_memcached_process_header(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_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 @@ ngx_http_range_header_filter(ngx_http_request_t *r) } 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;