From f0b27b3b3793eee2295017860545e01905ba2ffe Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Wed, 17 Aug 2022 19:11:20 +0200 Subject: [PATCH] Fix revproxy and fastcgi http header field merging --- src/lib/fastcgi.c | 2 +- src/lib/http.c | 6 +++--- src/lib/http.h | 4 +++- src/lib/rev_proxy.c | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/lib/fastcgi.c b/src/lib/fastcgi.c index a9e6945..a9a7707 100644 --- a/src/lib/fastcgi.c +++ b/src/lib/fastcgi.c @@ -386,7 +386,7 @@ int fastcgi_header(fastcgi_conn *conn, http_res *res, char *err_msg) { return 1; } - ret = http_parse_header_field(&res->hdr, ptr, pos0); + ret = http_parse_header_field(&res->hdr, ptr, pos0, 0); if (ret != 0) return (int) ret; if (pos0[2] == '\r' && pos0[3] == '\n') { return 0; diff --git a/src/lib/http.c b/src/lib/http.c index 0048bb8..99dfe2b 100644 --- a/src/lib/http.c +++ b/src/lib/http.c @@ -83,7 +83,7 @@ void http_free_res(http_res *res) { http_free_hdr(&res->hdr); } -int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr) { +int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr, int flags) { if (hdr->last_field_num > hdr->field_num) { print(ERR_STR "Unable to parse header: Invalid state" CLR_STR); return 3; @@ -116,7 +116,7 @@ int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr) char field_num = hdr->field_num; int found = http_get_header_field_num_len(hdr, buf, len1); - if (found == -1) { + if (!(flags & HTTP_MERGE_FIELDS) || found == -1) { if (http_add_header_field_len(hdr, buf, len1, pos1, len2 < 0 ? 0 : len2) != 0) { print(ERR_STR "Unable to parse header: Too many header fields" CLR_STR); return 3; @@ -204,7 +204,7 @@ int http_receive_request(sock *client, http_req *req) { sprintf(req->uri, "%.*s", (int) len, pos1); sprintf(req->version, "%.3s", pos2 + 5); } else { - int ret = http_parse_header_field(&req->hdr, ptr, pos0); + int ret = http_parse_header_field(&req->hdr, ptr, pos0, HTTP_MERGE_FIELDS); if (ret != 0) return ret; } ptr = pos0 + 2; diff --git a/src/lib/http.h b/src/lib/http.h index 4ce1ff7..6d76246 100644 --- a/src/lib/http.h +++ b/src/lib/http.h @@ -22,6 +22,8 @@ #define HTTP_FIELD_EX_VALUE 1 #define HTTP_FIELD_EX_NAME 2 +#define HTTP_MERGE_FIELDS 1 + #define HTTP_1XX_STR "\x1B[1;32m" #define HTTP_2XX_STR "\x1B[1;32m" #define HTTP_3XX_STR "\x1B[1;33m" @@ -140,7 +142,7 @@ void http_free_res(http_res *res); int http_receive_request(sock *client, http_req *req); -int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr) ; +int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr, int flags); const char *http_get_header_field(const http_hdr *hdr, const char *field_name); diff --git a/src/lib/rev_proxy.c b/src/lib/rev_proxy.c index f8841ba..141d995 100644 --- a/src/lib/rev_proxy.c +++ b/src/lib/rev_proxy.c @@ -422,7 +422,7 @@ int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_conf goto proxy_err; } } else { - ret = http_parse_header_field(&res->hdr, ptr, pos0); + ret = http_parse_header_field(&res->hdr, ptr, pos0, 0); if (ret != 0) { res->status = http_get_status(502); ctx->origin = SERVER_RES;