summaryrefslogtreecommitdiffhomepage
path: root/src/http/ngx_http_core_module.c
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2022-05-30 21:25:27 +0300
committerMaxim Dounin <mdounin@mdounin.ru>2022-05-30 21:25:27 +0300
commitd8a7c653e4b8e842c947c0a550a7bc5a7812058a (patch)
treecf35530032c5eea4e7cd15fb893fe9ddd0e46730 /src/http/ngx_http_core_module.c
parent8ad0f62863aaa7ed64b4514c4c1d3ba924410c16 (diff)
downloadnginx-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.c74
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)
{