@@ -2105,17 +2105,47 @@ TEST_F(HttpFilterTest, DeniedResponseWithBodyNotTruncatedWhenLimitIsZero) {
21052105 EXPECT_EQ (1U , config_->stats ().denied_ .value ());
21062106}
21072107
2108- // Verifies that the downstream request fails when the ext_authz response
2109- // would cause the request headers to exceed their limit.
2110- TEST_F (HttpFilterTest, DownstreamRequestFailsOnHeaderLimit) {
2111- InSequence s;
2108+ class RequestHeaderLimitTest : public HttpFilterTest {
2109+ public:
2110+ RequestHeaderLimitTest () = default ;
21122111
2113- initialize (R"EOF(
2114- grpc_service:
2115- envoy_grpc:
2116- cluster_name: "ext_authz_server"
2117- )EOF" );
2112+ void runTest (Http::RequestHeaderMap& request_headers,
2113+ Filters::Common::ExtAuthz::Response response) {
2114+ InSequence s;
2115+
2116+ initialize (R"EOF(
2117+ grpc_service:
2118+ envoy_grpc:
2119+ cluster_name: "ext_authz_server"
2120+ )EOF" );
2121+
2122+ prepareCheck ();
2123+
2124+ EXPECT_CALL (*client_, check (_, _, _, _))
2125+ .WillOnce (Invoke (
2126+ [&](Filters::Common::ExtAuthz::RequestCallbacks& callbacks,
2127+ const envoy::service::auth::v3::CheckRequest&, Tracing::Span&,
2128+ const StreamInfo::StreamInfo&) -> void { request_callbacks_ = &callbacks; }));
2129+
2130+ EXPECT_EQ (Http::FilterHeadersStatus::StopAllIterationAndWatermark,
2131+ filter_->decodeHeaders (request_headers, false ));
2132+
2133+ // Now the test should fail, since we expect the downstream request to fail.
2134+ EXPECT_CALL (decoder_filter_callbacks_.stream_info_ ,
2135+ setResponseFlag (Envoy::StreamInfo::CoreResponseFlag::UnauthorizedExternalService));
2136+ EXPECT_CALL (decoder_filter_callbacks_, encodeHeaders_ (_, _))
2137+ .WillOnce (Invoke ([&](const Http::ResponseHeaderMap& headers, bool ) -> void {
2138+ EXPECT_EQ (headers.getStatusValue (),
2139+ std::to_string (enumToInt (Http::Code::InternalServerError)));
2140+ }));
2141+ EXPECT_CALL (decoder_filter_callbacks_, continueDecoding ()).Times (0 );
21182142
2143+ request_callbacks_->onComplete (std::make_unique<Filters::Common::ExtAuthz::Response>(response));
2144+ EXPECT_EQ (1U , config_->stats ().request_header_limits_reached_ .value ());
2145+ }
2146+ };
2147+
2148+ TEST_F (RequestHeaderLimitTest, HeadersToSetCount) {
21192149 // The total number of headers in the request header map is not allowed to
21202150 // exceed the limit.
21212151 Http::TestRequestHeaderMapImpl request_headers ({}, /* max_headers_kb=*/ 99999 ,
@@ -2124,32 +2154,77 @@ TEST_F(HttpFilterTest, DownstreamRequestFailsOnHeaderLimit) {
21242154 request_headers.addCopy (Http::Headers::get ().Path , " /" );
21252155 request_headers.addCopy (Http::Headers::get ().Method , " GET" );
21262156
2127- prepareCheck ();
2157+ Filters::Common::ExtAuthz::Response response{};
2158+ response.status = Filters::Common::ExtAuthz::CheckStatus::OK;
2159+ response.headers_to_set = {{" foo" , " bar" }, {" foo2" , " bar2" }};
21282160
2129- EXPECT_CALL (*client_, check (_, _, _, _))
2130- .WillOnce (
2131- Invoke ([&](Filters::Common::ExtAuthz::RequestCallbacks& callbacks,
2132- const envoy::service::auth::v3::CheckRequest&, Tracing::Span&,
2133- const StreamInfo::StreamInfo&) -> void { request_callbacks_ = &callbacks; }));
2161+ runTest (request_headers, response);
2162+ }
21342163
2135- EXPECT_EQ (Http::FilterHeadersStatus::StopAllIterationAndWatermark,
2136- filter_->decodeHeaders (request_headers, false ));
2164+ TEST_F (RequestHeaderLimitTest, HeadersToSetSize) {
2165+ // The total number of headers in the request header map is not allowed to
2166+ // exceed the limit.
2167+ Http::TestRequestHeaderMapImpl request_headers ({}, /* max_headers_kb=*/ 1 ,
2168+ /* max_headers_count=*/ 9999 );
2169+ request_headers.addCopy (Http::Headers::get ().Host , " host" );
2170+ request_headers.addCopy (Http::Headers::get ().Path , " /" );
2171+ request_headers.addCopy (Http::Headers::get ().Method , " GET" );
21372172
21382173 Filters::Common::ExtAuthz::Response response{};
21392174 response.status = Filters::Common::ExtAuthz::CheckStatus::OK;
2140- response.headers_to_set = {{" foo" , " bar" }, {" foo2" , " bar2 " }};
2175+ response.headers_to_set = {{" foo" , " bar" }, {" foo2" , std::string ( 9999 , ' a ' ) }};
21412176
2142- // Now the test should fail, since we expect the downstream request to fail.
2143- EXPECT_CALL (decoder_filter_callbacks_.stream_info_ ,
2144- setResponseFlag (Envoy::StreamInfo::CoreResponseFlag::UnauthorizedExternalService));
2145- EXPECT_CALL (decoder_filter_callbacks_, encodeHeaders_ (_, _))
2146- .WillOnce (Invoke ([&](const Http::ResponseHeaderMap& headers, bool ) -> void {
2147- EXPECT_EQ (headers.getStatusValue (),
2148- std::to_string (enumToInt (Http::Code::InternalServerError)));
2149- }));
2150- EXPECT_CALL (decoder_filter_callbacks_, continueDecoding ()).Times (0 );
2177+ runTest (request_headers, response);
2178+ }
21512179
2152- request_callbacks_->onComplete (std::make_unique<Filters::Common::ExtAuthz::Response>(response));
2180+ // (headers to append can't add new headers, so it won't ever violate the count limit)
2181+ TEST_F (RequestHeaderLimitTest, HeadersToAppendSize) {
2182+ // The total number of headers in the request header map is not allowed to
2183+ // exceed the limit.
2184+ Http::TestRequestHeaderMapImpl request_headers ({}, /* max_headers_kb=*/ 1 ,
2185+ /* max_headers_count=*/ 9999 );
2186+ request_headers.addCopy (Http::Headers::get ().Host , " host" );
2187+ request_headers.addCopy (Http::Headers::get ().Path , " /" );
2188+ request_headers.addCopy (Http::Headers::get ().Method , " GET" );
2189+ request_headers.addCopy (" foo" , " original value" );
2190+
2191+ Filters::Common::ExtAuthz::Response response{};
2192+ response.status = Filters::Common::ExtAuthz::CheckStatus::OK;
2193+ response.headers_to_append = {{" foo" , std::string (9999 , ' a' )}};
2194+
2195+ runTest (request_headers, response);
2196+ }
2197+
2198+ TEST_F (RequestHeaderLimitTest, HeadersToAddCount) {
2199+ // The total number of headers in the request header map is not allowed to
2200+ // exceed the limit.
2201+ Http::TestRequestHeaderMapImpl request_headers ({}, /* max_headers_kb=*/ 99999 ,
2202+ /* max_headers_count=*/ 4 );
2203+ request_headers.addCopy (Http::Headers::get ().Host , " host" );
2204+ request_headers.addCopy (Http::Headers::get ().Path , " /" );
2205+ request_headers.addCopy (Http::Headers::get ().Method , " GET" );
2206+
2207+ Filters::Common::ExtAuthz::Response response{};
2208+ response.status = Filters::Common::ExtAuthz::CheckStatus::OK;
2209+ response.headers_to_add = {{" foo" , " bar" }, {" foo2" , " bar2" }};
2210+
2211+ runTest (request_headers, response);
2212+ }
2213+
2214+ TEST_F (RequestHeaderLimitTest, HeadersToAddSize) {
2215+ // The total number of headers in the request header map is not allowed to
2216+ // exceed the limit.
2217+ Http::TestRequestHeaderMapImpl request_headers ({}, /* max_headers_kb=*/ 1 ,
2218+ /* max_headers_count=*/ 9999 );
2219+ request_headers.addCopy (Http::Headers::get ().Host , " host" );
2220+ request_headers.addCopy (Http::Headers::get ().Path , " /" );
2221+ request_headers.addCopy (Http::Headers::get ().Method , " GET" );
2222+
2223+ Filters::Common::ExtAuthz::Response response{};
2224+ response.status = Filters::Common::ExtAuthz::CheckStatus::OK;
2225+ response.headers_to_add = {{" foo2" , std::string (9999 , ' a' )}};
2226+
2227+ runTest (request_headers, response);
21532228}
21542229
21552230// Verifies that the downstream request fails when the ext_authz response
0 commit comments