From c9fb5214ec9774b88f0b80f06b2f505b530c0ba8 Mon Sep 17 00:00:00 2001 From: "Vikas Choudhary (vikasc)" Date: Mon, 13 May 2024 21:48:33 +0530 Subject: [PATCH] Add integration test for upstream http filters in tcp tunneling case (#34085) Add integration test for tcp tunneling upstream http filters Signed-off-by: Vikas Choudhary --- test/integration/BUILD | 2 + .../tcp_tunneling_integration_test.cc | 52 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/test/integration/BUILD b/test/integration/BUILD index 555d93c0121d..76fd743bcc1f 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -1827,6 +1827,8 @@ envoy_cc_test( ":tcp_tunneling_integration_lib", "//source/extensions/filters/network/tcp_proxy:config", "//source/extensions/upstreams/http/tcp:config", + "//test/integration/filters:add_header_filter_config_lib", + "//test/integration/filters:add_header_filter_proto_cc_proto", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/access_loggers/file/v3:pkg_cc_proto", diff --git a/test/integration/tcp_tunneling_integration_test.cc b/test/integration/tcp_tunneling_integration_test.cc index 07c5740489df..63760daba054 100644 --- a/test/integration/tcp_tunneling_integration_test.cc +++ b/test/integration/tcp_tunneling_integration_test.cc @@ -6,6 +6,7 @@ #include "envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.pb.h" #include "envoy/extensions/upstreams/http/tcp/v3/tcp_connection_pool.pb.h" +#include "test/integration/filters/add_header_filter.pb.h" #include "test/integration/http_integration.h" #include "test/integration/http_protocol_integration.h" #include "test/integration/tcp_tunneling_integration.h" @@ -716,6 +717,8 @@ TEST_P(ProxyingConnectIntegrationTest, 2xxStatusCode) { cleanupUpstreamAndDownstream(); } +using HttpFilterProto = + envoy::extensions::filters::network::http_connection_manager::v3::HttpFilter; // Tunneling downstream TCP over an upstream HTTP CONNECT tunnel. class TcpTunnelingIntegrationTest : public BaseTcpTunnelingIntegrationTest { public: @@ -743,6 +746,39 @@ class TcpTunnelingIntegrationTest : public BaseTcpTunnelingIntegrationTest { BaseTcpTunnelingIntegrationTest::SetUp(); } + void addHttpUpstreamFilterToCluster(const HttpFilterProto& config) { + config_helper_.addConfigModifier([config](envoy::config::bootstrap::v3::Bootstrap& bootstrap) { + auto* cluster = bootstrap.mutable_static_resources()->mutable_clusters(0); + ConfigHelper::HttpProtocolOptions protocol_options = + MessageUtil::anyConvert( + (*cluster->mutable_typed_extension_protocol_options()) + ["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"]); + *protocol_options.add_http_filters() = config; + (*cluster->mutable_typed_extension_protocol_options()) + ["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"] + .PackFrom(protocol_options); + }); + } + + const HttpFilterProto getAddHeaderFilterConfig(const std::string& name, const std::string& key, + const std::string& value) { + HttpFilterProto filter_config; + filter_config.set_name(name); + auto configuration = test::integration::filters::AddHeaderFilterConfig(); + configuration.set_header_key(key); + configuration.set_header_value(value); + filter_config.mutable_typed_config()->PackFrom(configuration); + return filter_config; + } + + const HttpFilterProto getCodecFilterConfig() { + HttpFilterProto filter_config; + filter_config.set_name("envoy.filters.http.upstream_codec"); + auto configuration = envoy::extensions::filters::http::upstream_codec::v3::UpstreamCodec(); + filter_config.mutable_typed_config()->PackFrom(configuration); + return filter_config; + } + void setUpConnection(FakeHttpConnectionPtr& fake_upstream_connection) { // Start a connection, and verify the upgrade headers are received upstream. tcp_client_ = makeTcpConnection(lookupPort("tcp_proxy")); @@ -796,6 +832,22 @@ TEST_P(TcpTunnelingIntegrationTest, Basic) { closeConnection(fake_upstream_connection_); } +TEST_P(TcpTunnelingIntegrationTest, UpstreamHttpFilters) { + if (!(GetParam().tunneling_with_upstream_filters)) { + return; + } + addHttpUpstreamFilterToCluster(getAddHeaderFilterConfig("add_header", "foo", "bar")); + addHttpUpstreamFilterToCluster(getCodecFilterConfig()); + initialize(); + + setUpConnection(fake_upstream_connection_); + sendBidiData(fake_upstream_connection_); + EXPECT_EQ( + "bar", + upstream_request_->headers().get(Http::LowerCaseString("foo"))[0]->value().getStringView()); + closeConnection(fake_upstream_connection_); +} + TEST_P(TcpTunnelingIntegrationTest, SendDataUpstreamAfterUpstreamClose) { if (upstreamProtocol() == Http::CodecType::HTTP1) { // HTTP/1.1 can't frame with FIN bits.