diff options
| author | Maxim Dounin <mdounin@mdounin.ru> | 2022-05-30 21:25:27 +0300 |
|---|---|---|
| committer | Maxim Dounin <mdounin@mdounin.ru> | 2022-05-30 21:25:27 +0300 |
| commit | d8a7c653e4b8e842c947c0a550a7bc5a7812058a (patch) | |
| tree | cf35530032c5eea4e7cd15fb893fe9ddd0e46730 /src/http/ngx_http_core_module.c | |
| parent | 8ad0f62863aaa7ed64b4514c4c1d3ba924410c16 (diff) | |
| download | nginx-d8a7c653e4b8e842c947c0a550a7bc5a7812058a.tar.gz nginx-d8a7c653e4b8e842c947c0a550a7bc5a7812058a.tar.bz2 | |
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".
Diffstat (limited to 'src/http/ngx_http_core_module.c')
| -rw-r--r-- | src/http/ngx_http_core_module.c | 74 |
1 files changed, 74 insertions, 0 deletions
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) { |
