diff --git a/test/integration/integration_test.cc b/test/integration/integration_test.cc index a1ace5f25b9bf..1f8cc7cec89af 100644 --- a/test/integration/integration_test.cc +++ b/test/integration/integration_test.cc @@ -1399,40 +1399,6 @@ TEST_P(IntegrationTest, TestDelayedConnectionTeardownConfig) { EXPECT_EQ(codec_client_->lastConnectionEvent(), Network::ConnectionEvent::RemoteClose); } -// Test that delay closed connections are eventually force closed when the timeout triggers. -TEST_P(IntegrationTest, TestDelayedConnectionTeardownTimeoutTrigger) { - config_helper_.addFilter("{ name: encoder-decoder-buffer-filter, typed_config: { \"@type\": " - "type.googleapis.com/google.protobuf.Empty } }"); - config_helper_.setBufferLimits(1024, 1024); - config_helper_.addConfigModifier( - [](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& - hcm) { - // 200ms. - hcm.mutable_delayed_close_timeout()->set_nanos(200000000); - }); - - initialize(); - - codec_client_ = makeHttpConnection(lookupPort("http")); - - auto encoder_decoder = - codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); - request_encoder_ = &encoder_decoder.first; - auto response = std::move(encoder_decoder.second); - - codec_client_->sendData(*request_encoder_, 1024 * 65, false); - - ASSERT_TRUE(response->waitForEndStream()); - // The delayed close timeout should trigger since client is not closing the connection. - EXPECT_TRUE(codec_client_->waitForDisconnect(std::chrono::milliseconds(2000))); - EXPECT_EQ(codec_client_->lastConnectionEvent(), Network::ConnectionEvent::RemoteClose); - EXPECT_EQ(test_server_->counter("http.config_test.downstream_cx_delayed_close_timeout")->value(), - 1); -} - // Test that if the route cache is cleared, it doesn't cause problems. TEST_P(IntegrationTest, TestClearingRouteCacheFilter) { config_helper_.addFilter("{ name: clear-route-cache, typed_config: { \"@type\": " diff --git a/test/integration/protocol_integration_test.cc b/test/integration/protocol_integration_test.cc index 1a000a70b9bd8..b70e4b9fb4bfc 100644 --- a/test/integration/protocol_integration_test.cc +++ b/test/integration/protocol_integration_test.cc @@ -2020,15 +2020,22 @@ name: encode-headers-return-stop-all-filter // Per https://github.com/envoyproxy/envoy/issues/7488 make sure we don't // combine set-cookie headers -TEST_P(ProtocolIntegrationTest, MultipleSetCookies) { +TEST_P(ProtocolIntegrationTest, MultipleCookiesAndSetCookies) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, {":path", "/dynamo/url"}, + {":scheme", "http"}, {":authority", "host"}, + {"cookie", "a=b"}, {"cookie", "c=d"}}; Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"set-cookie", "foo"}, {"set-cookie", "bar"}}; - auto response = sendRequestAndWaitForResponse(default_request_headers_, 0, response_headers, 0); + auto response = sendRequestAndWaitForResponse(request_headers, 0, response_headers, 0); + if (downstreamProtocol() == Http::CodecClient::Type::HTTP3) { + EXPECT_EQ(upstream_request_->headers().get(Http::Headers::get().Cookie)[0]->value(), + "a=b; c=d"); + } ASSERT_TRUE(response->complete()); EXPECT_EQ("200", response->headers().getStatusValue()); @@ -2039,6 +2046,42 @@ TEST_P(ProtocolIntegrationTest, MultipleSetCookies) { ASSERT_EQ(out[1]->value().getStringView(), "bar"); } +// Test that delay closed connections are eventually force closed when the timeout triggers. +TEST_P(DownstreamProtocolIntegrationTest, TestDelayedConnectionTeardownTimeoutTrigger) { + config_helper_.addFilter("{ name: encoder-decoder-buffer-filter, typed_config: { \"@type\": " + "type.googleapis.com/google.protobuf.Empty } }"); + config_helper_.setBufferLimits(1024, 1024); + config_helper_.addConfigModifier( + [](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& + hcm) { + // 200ms. + hcm.mutable_delayed_close_timeout()->set_nanos(200000000); + hcm.mutable_drain_timeout()->set_seconds(1); + hcm.mutable_common_http_protocol_options()->mutable_idle_timeout()->set_seconds(1); + }); + + initialize(); + + codec_client_ = makeHttpConnection(lookupPort("http")); + + auto encoder_decoder = + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); + request_encoder_ = &encoder_decoder.first; + auto response = std::move(encoder_decoder.second); + + codec_client_->sendData(*request_encoder_, 1024 * 65, false); + + ASSERT_TRUE(response->waitForEndStream()); + // The delayed close timeout should trigger since client is not closing the connection. + EXPECT_TRUE(codec_client_->waitForDisconnect(std::chrono::milliseconds(5000))); + EXPECT_EQ(codec_client_->lastConnectionEvent(), Network::ConnectionEvent::RemoteClose); + EXPECT_EQ(test_server_->counter("http.config_test.downstream_cx_delayed_close_timeout")->value(), + 1); +} + // Resets the downstream stream immediately and verifies that we clean up everything. TEST_P(ProtocolIntegrationTest, TestDownstreamResetIdleTimeout) { useAccessLog("%RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS%"); diff --git a/test/integration/quic_http_integration_test.cc b/test/integration/quic_http_integration_test.cc index edcbeda8fa8eb..0384dae2fea1c 100644 --- a/test/integration/quic_http_integration_test.cc +++ b/test/integration/quic_http_integration_test.cc @@ -315,107 +315,6 @@ TEST_P(QuicHttpIntegrationTest, ZeroRtt) { codec_client_->close(); } -TEST_P(QuicHttpIntegrationTest, GetRequestAndResponseWithBody) { - initialize(); - sendRequestAndVerifyResponse(default_request_headers_, /*request_size=*/0, - default_response_headers_, /*response_size=*/1024, - /*backend_index*/ 0); -} - -TEST_P(QuicHttpIntegrationTest, PostRequestAndResponseWithBody) { - testRouterRequestAndResponseWithBody(1024, 512, false); -} - -TEST_P(QuicHttpIntegrationTest, PostRequestWithBigHeadersAndResponseWithBody) { - testRouterRequestAndResponseWithBody(1024, 512, true); -} - -TEST_P(QuicHttpIntegrationTest, RouterUpstreamDisconnectBeforeRequestcomplete) { - testRouterUpstreamDisconnectBeforeRequestComplete(); -} - -TEST_P(QuicHttpIntegrationTest, RouterUpstreamDisconnectBeforeResponseComplete) { - testRouterUpstreamDisconnectBeforeResponseComplete(); - EXPECT_EQ(Http::StreamResetReason::RemoteReset, client_codec_callback_.last_stream_reset_reason_); -} - -TEST_P(QuicHttpIntegrationTest, RouterDownstreamDisconnectBeforeRequestComplete) { - testRouterDownstreamDisconnectBeforeRequestComplete(); -} - -TEST_P(QuicHttpIntegrationTest, RouterDownstreamDisconnectBeforeResponseComplete) { - testRouterDownstreamDisconnectBeforeResponseComplete(); -} - -TEST_P(QuicHttpIntegrationTest, RouterUpstreamResponseBeforeRequestComplete) { - testRouterUpstreamResponseBeforeRequestComplete(); -} - -TEST_P(QuicHttpIntegrationTest, Retry) { testRetry(); } - -TEST_P(QuicHttpIntegrationTest, UpstreamReadDisabledOnGiantResponseBody) { - DISABLE_UNDER_COVERAGE; - config_helper_.addConfigModifier(ConfigHelper::adjustUpstreamTimeoutForTsan); - config_helper_.setBufferLimits(/*upstream_buffer_limit=*/1024, /*downstream_buffer_limit=*/1024); - testRouterRequestAndResponseWithBody(/*request_size=*/512, /*response_size=*/10 * 1024 * 1024, - false, false, nullptr, - TSAN_TIMEOUT_FACTOR * TestUtility::DefaultTimeout); -} - -TEST_P(QuicHttpIntegrationTest, DownstreamReadDisabledOnGiantPost) { - DISABLE_UNDER_COVERAGE; - config_helper_.addConfigModifier(ConfigHelper::adjustUpstreamTimeoutForTsan); - config_helper_.setBufferLimits(/*upstream_buffer_limit=*/1024, /*downstream_buffer_limit=*/1024); - testRouterRequestAndResponseWithBody(/*request_size=*/10 * 1024 * 1024, /*response_size=*/1024, - false); -} - -TEST_P(QuicHttpIntegrationTest, LargeFlowControlOnAndGiantBody) { - DISABLE_UNDER_COVERAGE; - config_helper_.addConfigModifier(ConfigHelper::adjustUpstreamTimeoutForTsan); - config_helper_.setBufferLimits(/*upstream_buffer_limit=*/128 * 1024, - /*downstream_buffer_limit=*/128 * 1024); - testRouterRequestAndResponseWithBody(/*request_size=*/10 * 1024 * 1024, - /*response_size=*/10 * 1024 * 1024, false, false, nullptr, - TSAN_TIMEOUT_FACTOR * TestUtility::DefaultTimeout); -} - -// Tests that a connection idle times out after 1s and starts delayed close. -TEST_P(QuicHttpIntegrationTest, TestDelayedConnectionTeardownTimeoutTrigger) { - config_helper_.addFilter("{ name: encoder-decoder-buffer-filter, typed_config: { \"@type\": " - "type.googleapis.com/google.protobuf.Empty } }"); - config_helper_.setBufferLimits(1024, 1024); - config_helper_.addConfigModifier( - [](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& - hcm) { - // 200ms. - hcm.mutable_delayed_close_timeout()->set_nanos(200000000); - hcm.mutable_drain_timeout()->set_seconds(1); - hcm.mutable_common_http_protocol_options()->mutable_idle_timeout()->set_seconds(1); - }); - - initialize(); - - codec_client_ = makeHttpConnection(lookupPort("http")); - - auto encoder_decoder = - codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); - request_encoder_ = &encoder_decoder.first; - auto response = std::move(encoder_decoder.second); - - codec_client_->sendData(*request_encoder_, 1024 * 65, false); - - ASSERT_TRUE(response->waitForEndStream()); - // The delayed close timeout should trigger since client is not closing the connection. - EXPECT_TRUE(codec_client_->waitForDisconnect(std::chrono::milliseconds(5000))); - EXPECT_EQ(codec_client_->lastConnectionEvent(), Network::ConnectionEvent::RemoteClose); - EXPECT_EQ(test_server_->counter("http.config_test.downstream_cx_delayed_close_timeout")->value(), - 1); -} - // Ensure multiple quic connections work, regardless of platform BPF support TEST_P(QuicHttpIntegrationTest, MultipleQuicConnectionsDefaultMode) { testMultipleQuicConnections(); @@ -566,18 +465,6 @@ TEST_P(QuicHttpIntegrationTest, CertVerificationFailure) { EXPECT_EQ(failure_reason, codec_client_->connection()->transportFailureReason()); } -TEST_P(QuicHttpIntegrationTest, RequestResponseWithTrailers) { - config_helper_.addConfigModifier(setEnableUpstreamTrailersHttp1()); - testTrailers(/*request_size=*/10, /*response_size=*/10, /*request_trailers_present=*/true, - /*response_trailers_present=*/true); -} - -// Multiple 1xx before the request completes. -TEST_P(QuicHttpIntegrationTest, EnvoyProxyingEarlyMultiple1xx) { - testEnvoyProxying1xx(/*continue_before_upstream_complete=*/true, /*with_encoder_filter=*/false, - /*with_multiple_1xx_headers=*/true); -} - // HTTP3 doesn't support 101 SwitchProtocol response code, the client should // reset the request. TEST_P(QuicHttpIntegrationTest, Reset101SwitchProtocolResponse) { @@ -621,38 +508,5 @@ TEST_P(QuicHttpIntegrationTest, ResetRequestWithoutAuthorityHeader) { EXPECT_EQ("400", response->headers().getStatusValue()); } -TEST_P(QuicHttpIntegrationTest, MultipleSetCookieAndCookieHeaders) { - initialize(); - - codec_client_ = makeHttpConnection(lookupPort("http")); - auto encoder_decoder = - codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "GET"}, - {":path", "/dynamo/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"cookie", "a=b"}, - {"cookie", "c=d"}}); - request_encoder_ = &encoder_decoder.first; - auto response = std::move(encoder_decoder.second); - codec_client_->sendData(*request_encoder_, 0, true); - waitForNextUpstreamRequest(); - if (Runtime::runtimeFeatureEnabled( - "envoy.reloadable_features.header_map_correctly_coalesce_cookies")) { - EXPECT_EQ(upstream_request_->headers().get(Http::Headers::get().Cookie)[0]->value(), - "a=b; c=d"); - } - - upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}, - {"set-cookie", "foo"}, - {"set-cookie", "bar"}}, - true); - ASSERT_TRUE(response->waitForEndStream()); - EXPECT_TRUE(response->complete()); - const auto out = response->headers().get(Http::LowerCaseString("set-cookie")); - ASSERT_EQ(out.size(), 2); - ASSERT_EQ(out[0]->value().getStringView(), "foo"); - ASSERT_EQ(out[1]->value().getStringView(), "bar"); -} - } // namespace Quic } // namespace Envoy