diff --git a/bazel/external/http_parser/BUILD b/bazel/external/http_parser/BUILD index 5fefacde47dc..bb50c4adeb9d 100644 --- a/bazel/external/http_parser/BUILD +++ b/bazel/external/http_parser/BUILD @@ -12,7 +12,10 @@ cc_library( # This compiler flag is set to an arbtitrarily high number so # as to effectively disables the http_parser header limit, as # we do our own checks in the conn manager and codec. - copts = ["-DHTTP_MAX_HEADER_SIZE=0x2000000"], + copts = ["-DHTTP_MAX_HEADER_SIZE=0x2000000"] + select({ + "@envoy//bazel:uhv_enabled": ["-DHTTP_PARSER_STRICT=0"], + "//conditions:default": [], + }), includes = ["."], visibility = ["//visibility:public"], ) diff --git a/test/common/http/http1/codec_impl_test.cc b/test/common/http/http1/codec_impl_test.cc index 59ced124d59c..a267c529a8c0 100644 --- a/test/common/http/http1/codec_impl_test.cc +++ b/test/common/http/http1/codec_impl_test.cc @@ -3149,6 +3149,34 @@ TEST_F(Http1ServerConnectionImplTest, PipedRequestWithMutipleEvent) { connection_.dispatcher_.clearDeferredDeleteList(); } +TEST_F(Http1ServerConnectionImplTest, Utf8Path) { + initialize(); + + MockRequestDecoder decoder; + Buffer::OwnedImpl buffer("GET /δ¶/δt/pope?q=1#narf HXXP/1.1\r\n\r\n"); +#ifdef ENVOY_ENABLE_UHV + // permissive + EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); + + TestRequestHeaderMapImpl expected_headers{ + {":path", "/δ¶/δt/pope?q=1#narf"}, + {":method", "GET"}, + }; + EXPECT_CALL(decoder, decodeHeaders_(HeaderMapEqual(&expected_headers), true)); + + auto status = codec_->dispatch(buffer); + EXPECT_TRUE(status.ok()); + EXPECT_EQ(0U, buffer.length()); +#else + // strict + EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); + + EXPECT_CALL(decoder, sendLocalReply(_, _, _, _, _)); + auto status = codec_->dispatch(buffer); + EXPECT_TRUE(isCodecProtocolError(status)); +#endif +} + // Tests that incomplete response headers of 80 kB header value fails. TEST_F(Http1ClientConnectionImplTest, ResponseHeadersWithLargeValueRejected) { initialize(); diff --git a/test/extensions/filters/listener/http_inspector/http_inspector_test.cc b/test/extensions/filters/listener/http_inspector/http_inspector_test.cc index 5eb8a912b9c5..de3dc09ed292 100644 --- a/test/extensions/filters/listener/http_inspector/http_inspector_test.cc +++ b/test/extensions/filters/listener/http_inspector/http_inspector_test.cc @@ -482,6 +482,11 @@ TEST_F(HttpInspectorTest, MultipleReadsHttp1IncompleteBadHeader) { } TEST_F(HttpInspectorTest, MultipleReadsHttp1BadProtocol) { +#ifdef ENVOY_ENABLE_UHV + // permissive parsing + return; +#endif + const std::string valid_header = "GET /index HTTP/1.1\r"; // offset: 0 10 const std::string truncate_header = valid_header.substr(0, 14).append("\r"); diff --git a/test/integration/protocol_integration_test.cc b/test/integration/protocol_integration_test.cc index 89bf7268ba51..d3ae35134d1f 100644 --- a/test/integration/protocol_integration_test.cc +++ b/test/integration/protocol_integration_test.cc @@ -3468,6 +3468,11 @@ TEST_P(ProtocolIntegrationTest, UpstreamDisconnectBeforeResponseCompleteWireByte TEST_P(DownstreamProtocolIntegrationTest, BadRequest) { config_helper_.disableDelayClose(); // we only care about upstream protocol. +#ifdef ENVOY_ENABLE_UHV + // permissive parsing is enabled + return; +#endif + if (downstreamProtocol() != Http::CodecType::HTTP1) { return; } diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt index 3fe1262e1458..f2368366d784 100644 --- a/tools/spelling/spelling_dictionary.txt +++ b/tools/spelling/spelling_dictionary.txt @@ -373,6 +373,7 @@ UA UBSAN UDP UDS +UHV UNC URI URL