From 3aef1d693f3cc431563a7e6a6aba6a34e5290f03 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:33 +0300 Subject: 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/perl/nginx.xs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'src/http/modules/perl/nginx.xs') 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); - - n = a->nelts; + ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); - 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; } -- cgit From dab1b086ef6702811196f317b39623ad81eac505 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:36 +0300 Subject: 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(-) (limited to 'src/http/modules/perl/nginx.xs') 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,29 +304,11 @@ 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)) { - 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; + } else { + sep = ','; } - XSRETURN_UNDEF; - - multi: - - /* Cookie, X-Forwarded-For */ - ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); if (*ph == NULL) { -- cgit From 1d22d0f56bd1ff7ab49ce92e197056ea7f2e6523 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:38 +0300 Subject: Perl: combining unknown headers during $r->header_in() lookup. --- src/http/modules/perl/nginx.xs | 84 ++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 40 deletions(-) (limited to 'src/http/modules/perl/nginx.xs') 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: -- cgit From e59c2096ae9d561997ad2d64d61094503e6be4c3 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 30 May 2022 21:25:45 +0300 Subject: 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/perl/nginx.xs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/http/modules/perl/nginx.xs') 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; -- cgit From 21506a2f851c9dbff4bee67fe5b6d199c83c799a Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Tue, 14 Jun 2022 10:39:58 +0400 Subject: Perl: removed unused variables, forgotten in ef6a3a99a81a. --- src/http/modules/perl/nginx.xs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/http/modules/perl/nginx.xs') 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; -- cgit