diff --git a/proxy/hdrs/HTTP.cc b/proxy/hdrs/HTTP.cc index 7f0dc82a241..c557172858e 100644 --- a/proxy/hdrs/HTTP.cc +++ b/proxy/hdrs/HTTP.cc @@ -959,8 +959,8 @@ http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const return PARSE_RESULT_ERROR; } - ParseResult ret = - mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof, max_hdr_field_size); + ParseResult ret = mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof, + false, max_hdr_field_size); // If we're done with the main parse do some validation if (ret == PARSE_RESULT_DONE) { ret = validate_hdr_host(hh); // check HOST header @@ -1116,8 +1116,8 @@ http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const parser->m_parsing_http = false; } - ParseResult ret = - mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof, max_hdr_field_size); + ParseResult ret = mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof, false, + max_hdr_field_size); // If we're done with the main parse do some validation if (ret == PARSE_RESULT_DONE) { ret = validate_hdr_host(hh); // check HOST header @@ -1287,7 +1287,7 @@ http_parser_parse_resp(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const end = real_end; parser->m_parsing_http = false; - return mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof); + return mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof, true); } #endif @@ -1403,7 +1403,7 @@ http_parser_parse_resp(HTTPParser *parser, HdrHeap *heap, HTTPHdrImpl *hh, const parser->m_parsing_http = false; } - return mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof); + return mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof, true); } /*------------------------------------------------------------------------- diff --git a/proxy/hdrs/MIME.cc b/proxy/hdrs/MIME.cc index d5b0a3ff197..29ff5995dbf 100644 --- a/proxy/hdrs/MIME.cc +++ b/proxy/hdrs/MIME.cc @@ -2510,7 +2510,7 @@ mime_parser_clear(MIMEParser *parser) ParseResult mime_parser_parse(MIMEParser *parser, HdrHeap *heap, MIMEHdrImpl *mh, const char **real_s, const char *real_e, - bool must_copy_strings, bool eof, size_t max_hdr_field_size) + bool must_copy_strings, bool eof, bool remove_ws_from_field_name, size_t max_hdr_field_size) { ParseResult err; bool line_is_real; @@ -2570,8 +2570,13 @@ mime_parser_parse(MIMEParser *parser, HdrHeap *heap, MIMEHdrImpl *mh, const char // server MUST reject any received request message that contains // whitespace between a header field-name and colon with a response code // of 400 (Bad Request). + // A proxy MUST remove any such whitespace from a response message before + // fowarding the message downstream. if (is_ws(field_name.back())) { - return PARSE_RESULT_ERROR; + if (!remove_ws_from_field_name) { + return PARSE_RESULT_ERROR; + } + field_name.rtrim_if(&ParseRules::is_ws); } // find value first diff --git a/proxy/hdrs/MIME.h b/proxy/hdrs/MIME.h index a1e9dbc2c88..b15d665092d 100644 --- a/proxy/hdrs/MIME.h +++ b/proxy/hdrs/MIME.h @@ -761,7 +761,7 @@ void mime_field_value_append(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, c void mime_parser_init(MIMEParser *parser); void mime_parser_clear(MIMEParser *parser); ParseResult mime_parser_parse(MIMEParser *parser, HdrHeap *heap, MIMEHdrImpl *mh, const char **real_s, const char *real_e, - bool must_copy_strings, bool eof, size_t max_hdr_field_size = 131070); + bool must_copy_strings, bool eof, bool remove_ws_from_field_name, size_t max_hdr_field_size = 131070); void mime_hdr_describe(HdrHeapObjImpl *raw, bool recurse); void mime_field_block_describe(HdrHeapObjImpl *raw, bool recurse); @@ -1017,7 +1017,7 @@ class MIMEHdr : public HdrHeapSDKHandle int print(char *buf, int bufsize, int *bufindex, int *chars_to_skip); - int parse(MIMEParser *parser, const char **start, const char *end, bool must_copy_strs, bool eof, + int parse(MIMEParser *parser, const char **start, const char *end, bool must_copy_strs, bool eof, bool remove_ws_from_field_name, size_t max_hdr_field_size = UINT16_MAX); int value_get_index(const char *name, int name_length, const char *value, int value_length) const; @@ -1299,7 +1299,8 @@ MIMEHdr::print(char *buf, int bufsize, int *bufindex, int *chars_to_skip) -------------------------------------------------------------------------*/ inline int -MIMEHdr::parse(MIMEParser *parser, const char **start, const char *end, bool must_copy_strs, bool eof, size_t max_hdr_field_size) +MIMEHdr::parse(MIMEParser *parser, const char **start, const char *end, bool must_copy_strs, bool eof, + bool remove_ws_from_field_name, size_t max_hdr_field_size) { if (!m_heap) m_heap = new_HdrHeap(); @@ -1307,7 +1308,7 @@ MIMEHdr::parse(MIMEParser *parser, const char **start, const char *end, bool mus if (!m_mime) m_mime = mime_hdr_create(m_heap); - return mime_parser_parse(parser, m_heap, m_mime, start, end, must_copy_strs, eof, max_hdr_field_size); + return mime_parser_parse(parser, m_heap, m_mime, start, end, must_copy_strs, eof, remove_ws_from_field_name, max_hdr_field_size); } /*------------------------------------------------------------------------- diff --git a/proxy/hdrs/unit_tests/test_HdrUtils.cc b/proxy/hdrs/unit_tests/test_HdrUtils.cc index 9c41ae216a7..3a164c8b62f 100644 --- a/proxy/hdrs/unit_tests/test_HdrUtils.cc +++ b/proxy/hdrs/unit_tests/test_HdrUtils.cc @@ -56,7 +56,7 @@ TEST_CASE("HdrUtils", "[proxy][hdrutils]") mime.create(heap); mime_parser_init(&parser); - auto result = mime_parser_parse(&parser, heap, mime.m_mime, &real_s, real_e, false, true); + auto result = mime_parser_parse(&parser, heap, mime.m_mime, &real_s, real_e, false, true, false); REQUIRE(PARSE_RESULT_DONE == result); HdrCsvIter iter; @@ -144,7 +144,7 @@ TEST_CASE("HdrUtils 2", "[proxy][hdrutils]") mime.create(heap); mime_parser_init(&parser); - auto result = mime_parser_parse(&parser, heap, mime.m_mime, &real_s, real_e, false, true); + auto result = mime_parser_parse(&parser, heap, mime.m_mime, &real_s, real_e, false, true, false); REQUIRE(PARSE_RESULT_DONE == result); MIMEField *field{mime.field_find(connection_tag.data(), int(connection_tag.size()))}; @@ -187,7 +187,7 @@ TEST_CASE("HdrUtils 3", "[proxy][hdrutils]") mime.create(heap); mime_parser_init(&parser); - auto result = mime_parser_parse(&parser, heap, mime.m_mime, &real_s, real_e, false, true); + auto result = mime_parser_parse(&parser, heap, mime.m_mime, &real_s, real_e, false, true, false); REQUIRE(PARSE_RESULT_DONE == result); MIMEField *field{mime.field_find(connection_tag.data(), int(connection_tag.size()))}; diff --git a/proxy/hdrs/unit_tests/test_Hdrs.cc b/proxy/hdrs/unit_tests/test_Hdrs.cc index dcbbd8318af..20ecfa829d3 100644 --- a/proxy/hdrs/unit_tests/test_Hdrs.cc +++ b/proxy/hdrs/unit_tests/test_Hdrs.cc @@ -861,7 +861,7 @@ TEST_CASE("HdrTest", "[proxy][hdrtest]") bool must_copy_strs = false; hdr.create(nullptr); - err = hdr.parse(&parser, &start, end, must_copy_strs, false); + err = hdr.parse(&parser, &start, end, must_copy_strs, false, false); REQUIRE(err >= 0); diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index 41fddf8001a..16bba4a618a 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -2739,7 +2739,8 @@ TSMimeHdrParse(TSMimeParser parser, TSMBuffer bufp, TSMLoc obj, const char **sta MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(obj); - return (TSParseResult)mime_parser_parse((MIMEParser *)parser, ((HdrHeapSDKHandle *)bufp)->m_heap, mh, start, end, false, false); + return (TSParseResult)mime_parser_parse((MIMEParser *)parser, ((HdrHeapSDKHandle *)bufp)->m_heap, mh, start, end, false, false, + false); } int