From cda9ef281cc8f90588278f288c39f6f15fb5332c Mon Sep 17 00:00:00 2001 From: botengyao Date: Mon, 22 Jul 2024 20:20:45 -0400 Subject: [PATCH 01/26] tls: remove no_full_scan_certs_on_sni_mismatch runtime flag in the doc (#35214) --- docs/root/intro/arch_overview/security/ssl.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/root/intro/arch_overview/security/ssl.rst b/docs/root/intro/arch_overview/security/ssl.rst index 79c0da9d22f9..b44b109af693 100644 --- a/docs/root/intro/arch_overview/security/ssl.rst +++ b/docs/root/intro/arch_overview/security/ssl.rst @@ -154,9 +154,8 @@ Certificate selection rules: :ref:`full_scan_certs_on_sni_mismatch ` is introduced to determine if we continue full scan on SNI mismatch when the client provides SNI. SNI mismatch contains two cases in this context, one is there is no cert that matches to SNI, another one is there are certs matches to SNI while OCSP policy fails on those certs. The :ref:`full_scan_certs_on_sni_mismatch ` - defaults to false, so full scan is disabled by default. The runtime flag ``envoy.reloadable_features.no_full_scan_certs_on_sni_mismatch`` - can be used to override the default value of :ref:`full_scan_certs_on_sni_mismatch `. - If full scan is enabled, it will look for the cert from the whole cert list on SNI mismatch, this could be a problem for a potential DoS attack because of O(n) complexity. + defaults to false, so full scan is disabled by default. If full scan is enabled, it will look for the cert from the whole cert list on SNI mismatch, + this could be a problem for a potential DoS attack because of O(n) complexity. Only a single TLS certificate is supported today for :ref:`UpstreamTlsContexts From 383a624a3597b28e94f6d169593fe6ee5c75e8f0 Mon Sep 17 00:00:00 2001 From: Tianyu <72890320+tyxia@users.noreply.github.com> Date: Mon, 22 Jul 2024 20:27:57 -0400 Subject: [PATCH 02/26] rlqs: Add support for abandon action (#35244) [abandon action](https://github.com/envoyproxy/envoy/blob/deaecafceb3f2c474485635345a956c78df04a90/api/envoy/service/rate_limit_quota/v3/rlqs.proto#L199) is a simple (and empty)response from RLQS server that ask client to erase the cached bucket. --------- Signed-off-by: tyxia --- .../http/rate_limit_quota/client_impl.cc | 60 ++++++++++------ .../filters/http/rate_limit_quota/BUILD | 2 +- .../http/rate_limit_quota/integration_test.cc | 72 +++++++++++++++++++ 3 files changed, 111 insertions(+), 23 deletions(-) diff --git a/source/extensions/filters/http/rate_limit_quota/client_impl.cc b/source/extensions/filters/http/rate_limit_quota/client_impl.cc index 7c5d9578f569..b51e5725fda1 100644 --- a/source/extensions/filters/http/rate_limit_quota/client_impl.cc +++ b/source/extensions/filters/http/rate_limit_quota/client_impl.cc @@ -90,29 +90,45 @@ void RateLimitClientImpl::onReceiveMessage(RateLimitQuotaResponsePtr&& response) ENVOY_LOG(error, "The received response is not matched to any quota cache entry: ", response->ShortDebugString()); } else { - quota_buckets_[bucket_id]->bucket_action = action; - if (quota_buckets_[bucket_id]->bucket_action.has_quota_assignment_action()) { - auto rate_limit_strategy = quota_buckets_[bucket_id] - ->bucket_action.quota_assignment_action() - .rate_limit_strategy(); - - if (rate_limit_strategy.has_token_bucket()) { - const auto& interval_proto = rate_limit_strategy.token_bucket().fill_interval(); - // Convert absl::duration to int64_t seconds - int64_t fill_interval_sec = absl::ToInt64Seconds( - absl::Seconds(interval_proto.seconds()) + absl::Nanoseconds(interval_proto.nanos())); - double fill_rate_per_sec = - static_cast(rate_limit_strategy.token_bucket().tokens_per_fill().value()) / - fill_interval_sec; - uint32_t max_tokens = rate_limit_strategy.token_bucket().max_tokens(); - ENVOY_LOG( - trace, - "Created the token bucket limiter for hashed bucket id: {}, with max_tokens: {}; " - "fill_interval_sec: {}; fill_rate_per_sec: {}.", - bucket_id, max_tokens, fill_interval_sec, fill_rate_per_sec); - quota_buckets_[bucket_id]->token_bucket_limiter = - std::make_unique(max_tokens, time_source_, fill_rate_per_sec); + switch (action.bucket_action_case()) { + case envoy::service::rate_limit_quota::v3::RateLimitQuotaResponse_BucketAction:: + kQuotaAssignmentAction: { + quota_buckets_[bucket_id]->bucket_action = action; + if (quota_buckets_[bucket_id]->bucket_action.has_quota_assignment_action()) { + auto rate_limit_strategy = quota_buckets_[bucket_id] + ->bucket_action.quota_assignment_action() + .rate_limit_strategy(); + + if (rate_limit_strategy.has_token_bucket()) { + const auto& interval_proto = rate_limit_strategy.token_bucket().fill_interval(); + // Convert absl::duration to int64_t seconds + int64_t fill_interval_sec = + absl::ToInt64Seconds(absl::Seconds(interval_proto.seconds()) + + absl::Nanoseconds(interval_proto.nanos())); + double fill_rate_per_sec = + static_cast(rate_limit_strategy.token_bucket().tokens_per_fill().value()) / + fill_interval_sec; + uint32_t max_tokens = rate_limit_strategy.token_bucket().max_tokens(); + ENVOY_LOG(trace, + "Created the token bucket limiter for hashed bucket " + "id: {}, with max_tokens: {}; " + "fill_interval_sec: {}; fill_rate_per_sec: {}.", + bucket_id, max_tokens, fill_interval_sec, fill_rate_per_sec); + quota_buckets_[bucket_id]->token_bucket_limiter = + std::make_unique(max_tokens, time_source_, fill_rate_per_sec); + } } + break; + } + case envoy::service::rate_limit_quota::v3::RateLimitQuotaResponse_BucketAction:: + kAbandonAction: { + quota_buckets_.erase(bucket_id); + break; + } + default: { + ENVOY_LOG_EVERY_POW_2(error, "Unset bucket action type {}", action.bucket_action_case()); + break; + } } } } diff --git a/test/extensions/filters/http/rate_limit_quota/BUILD b/test/extensions/filters/http/rate_limit_quota/BUILD index 370231d06d9e..c1043a8565ea 100644 --- a/test/extensions/filters/http/rate_limit_quota/BUILD +++ b/test/extensions/filters/http/rate_limit_quota/BUILD @@ -104,7 +104,7 @@ envoy_extension_cc_test( size = "large", srcs = ["integration_test.cc"], extension_names = ["envoy.filters.http.rate_limit_quota"], - shard_count = 2, + shard_count = 4, tags = [ "cpu:3", "skip_on_windows", diff --git a/test/extensions/filters/http/rate_limit_quota/integration_test.cc b/test/extensions/filters/http/rate_limit_quota/integration_test.cc index f3d5b9a372dc..d342e3aca00c 100644 --- a/test/extensions/filters/http/rate_limit_quota/integration_test.cc +++ b/test/extensions/filters/http/rate_limit_quota/integration_test.cc @@ -927,6 +927,78 @@ TEST_P(RateLimitQuotaIntegrationTest, MultiSameRequestWithExpiredAssignmentAllow } } +TEST_P(RateLimitQuotaIntegrationTest, MultiSameRequestWithAbandonAction) { + initializeConfig(); + HttpIntegrationTest::initialize(); + absl::flat_hash_map custom_headers = {{"environment", "staging"}, + {"group", "envoy"}}; + + absl::flat_hash_map custom_headers_cpy = custom_headers; + custom_headers_cpy.insert({"name", "prod"}); + for (int i = 0; i < 3; ++i) { + // Send downstream client request to upstream. + sendClientRequest(&custom_headers); + + // 3rd downstream request will not trigger the reports to RLQS server since it is + // same as 2nd request, which will find the entry in the cache. + if (i != 2) { + envoy::service::rate_limit_quota::v3::RateLimitQuotaResponse rlqs_response; + + // 1st request will start the gRPC stream. + if (i == 0) { + // Start the gRPC stream to RLQS server on the first request. + ASSERT_TRUE(grpc_upstreams_[0]->waitForHttpConnection(*dispatcher_, rlqs_connection_)); + ASSERT_TRUE(rlqs_connection_->waitForNewStream(*dispatcher_, rlqs_stream_)); + + envoy::service::rate_limit_quota::v3::RateLimitQuotaUsageReports reports; + ASSERT_TRUE(rlqs_stream_->waitForGrpcMessage(*dispatcher_, reports)); + rlqs_stream_->startGrpcStream(); + + // Build the response. + auto* bucket_action = rlqs_response.add_bucket_action(); + + for (const auto& [key, value] : custom_headers_cpy) { + (*bucket_action->mutable_bucket_id()->mutable_bucket()).insert({key, value}); + } + + // Set up the abandon action. + bucket_action->mutable_abandon_action(); + } else { + // 2nd request will still send report to RLQS server as the previous abandon + // action has removed the cache entry. but it won't start gRPC stream + // again since it is kept open. + envoy::service::rate_limit_quota::v3::RateLimitQuotaUsageReports reports; + ASSERT_TRUE(rlqs_stream_->waitForGrpcMessage(*dispatcher_, reports)); + + // Build the rlqs server response. + auto* bucket_action = rlqs_response.add_bucket_action(); + + for (const auto& [key, value] : custom_headers_cpy) { + (*bucket_action->mutable_bucket_id()->mutable_bucket()).insert({key, value}); + } + } + + // Send the response from RLQS server. + rlqs_stream_->sendGrpcMessage(rlqs_response); + } + + ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_)); + ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request_)); + ASSERT_TRUE(upstream_request_->waitForEndStream(*dispatcher_)); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); + upstream_request_->encodeData(100, true); + + // Verify the response to downstream. + ASSERT_TRUE(response_->waitForEndStream()); + EXPECT_TRUE(response_->complete()); + EXPECT_EQ(response_->headers().getStatusValue(), "200"); + + // Clean up the upstream and downstream resource but keep the gRPC connection to RLQS server + // open. + cleanupUpstreamAndDownstream(); + } +} + } // namespace } // namespace RateLimitQuota } // namespace HttpFilters From 44ad1a7db101abe2d42752c21a24913060da8e06 Mon Sep 17 00:00:00 2001 From: code Date: Tue, 23 Jul 2024 08:32:58 +0800 Subject: [PATCH 03/26] Revert "Revert "generic proxy: move generic proxy from contrib into extension (#35134) Commit Message: Additional Description: Risk Level: Testing: Docs Changes: Release Notes: Platform Specific Features: [Optional Runtime guard:] [Optional Fixes #Issue] [Optional Fixes commit #PR or SHA] [Optional Deprecated:] [Optional [API Considerations](https://github.com/envoyproxy/envoy/blob/main/api/review_checklist.md):] --------- Signed-off-by: wbpcode --- CODEOWNERS | 2 + api/BUILD | 12 +- .../network/generic_proxy/action/v3/BUILD | 0 .../generic_proxy/action/v3/action.proto | 2 +- .../generic_proxy/codecs/dubbo/v3/BUILD | 0 .../generic_proxy/codecs/dubbo/v3/dubbo.proto | 2 +- .../generic_proxy/codecs/http1/v3/BUILD | 0 .../generic_proxy/codecs/http1/v3/http1.proto | 2 +- .../network/generic_proxy/matcher/v3/BUILD | 0 .../generic_proxy/matcher/v3/matcher.proto | 2 +- .../network/generic_proxy/router/v3/BUILD | 0 .../generic_proxy/router/v3/router.proto | 2 +- .../filters/network/generic_proxy/v3/BUILD | 0 .../generic_proxy/v3/generic_proxy.proto | 4 +- .../network/generic_proxy/v3/route.proto | 2 +- api/versioning/BUILD | 12 +- bazel/repository_locations.bzl | 2 +- contrib/contrib_build_config.bzl | 4 - contrib/extensions_metadata.yaml | 26 - .../filters/network/source/codecs/dubbo/BUILD | 24 - .../filters/network/source/codecs/kafka/BUILD | 2 +- .../network/source/codecs/kafka/config.h | 2 +- .../filters/network/source/interface/BUILD | 105 --- .../filters/network/test/codecs/kafka/BUILD | 2 +- .../network/test/codecs/kafka/config_test.cc | 2 +- .../filters/network/test/router/BUILD | 57 -- .../network_filters/generic_proxy_filter.rst | 2 +- source/extensions/extensions_build_config.bzl | 8 + source/extensions/extensions_metadata.yaml | 28 + .../filters/network/generic_proxy}/BUILD | 101 ++- .../network/generic_proxy}/access_log.cc | 9 +- .../network/generic_proxy}/access_log.h | 4 +- .../network/generic_proxy}/codec_callbacks.h | 4 +- .../network/generic_proxy/codecs/dubbo/BUILD | 24 + .../generic_proxy}/codecs/dubbo/config.cc | 2 +- .../generic_proxy}/codecs/dubbo/config.h | 37 +- .../network/generic_proxy}/codecs/http1/BUILD | 12 +- .../generic_proxy}/codecs/http1/config.cc | 86 ++- .../generic_proxy}/codecs/http1/config.h | 18 +- .../filters/network/generic_proxy}/config.cc | 6 +- .../filters/network/generic_proxy}/config.h | 9 +- .../network/generic_proxy}/file_access_log.h | 0 .../network/generic_proxy/filter_callbacks.h | 65 +- .../network/generic_proxy/interface/BUILD | 50 ++ .../network/generic_proxy}/interface/codec.h | 4 +- .../network/generic_proxy/interface/filter.h | 54 +- .../network/generic_proxy}/interface/stream.h | 11 +- .../filters/network/generic_proxy}/match.cc | 2 +- .../filters/network/generic_proxy}/match.h | 10 +- .../network/generic_proxy}/match_input.h | 2 +- .../filters/network/generic_proxy}/proxy.cc | 114 +-- .../filters/network/generic_proxy}/proxy.h | 30 +- .../network/generic_proxy}/proxy_config.h | 12 +- .../filters/network/generic_proxy}/rds.h | 10 +- .../filters/network/generic_proxy}/rds_impl.h | 12 +- .../filters/network/generic_proxy}/route.h | 6 +- .../network/generic_proxy/route_impl.cc | 6 +- .../network/generic_proxy/route_impl.h | 19 +- .../network/generic_proxy}/router/BUILD | 21 +- .../network/generic_proxy}/router/config.cc | 2 +- .../network/generic_proxy}/router/config.h | 9 +- .../network/generic_proxy}/router/router.cc | 71 +- .../network/generic_proxy}/router/router.h | 19 +- .../network/generic_proxy}/router/upstream.cc | 51 +- .../network/generic_proxy}/router/upstream.h | 6 +- .../filters/network/generic_proxy}/stats.cc | 2 +- .../filters/network/generic_proxy}/stats.h | 0 .../filters/network/generic_proxy}/tracing.cc | 2 +- .../filters/network/generic_proxy}/tracing.h | 2 +- .../filters/network/generic_proxy}/BUILD | 79 +- .../network/generic_proxy}/access_log_test.cc | 58 +- .../network/generic_proxy}/codecs/dubbo/BUILD | 8 +- .../codecs/dubbo/config_test.cc | 86 ++- .../network/generic_proxy}/codecs/http1/BUILD | 8 +- .../codecs/http1/config_test.cc | 685 ++++++++++++++++-- .../network/generic_proxy}/config_test.cc | 128 +++- .../network/generic_proxy}/fake_codec.cc | 2 +- .../network/generic_proxy}/fake_codec.h | 30 +- .../generic_proxy}/integration_test.cc | 11 +- .../network/generic_proxy}/match_test.cc | 125 ++-- .../network/generic_proxy}/mocks/BUILD | 11 +- .../network/generic_proxy}/mocks/codec.cc | 2 +- .../network/generic_proxy}/mocks/codec.h | 3 +- .../network/generic_proxy}/mocks/filter.cc | 2 +- .../network/generic_proxy}/mocks/filter.h | 5 +- .../network/generic_proxy}/mocks/route.cc | 2 +- .../network/generic_proxy}/mocks/route.h | 2 +- .../network/generic_proxy}/proxy_test.cc | 512 ++++++++++--- .../network/generic_proxy}/route_test.cc | 46 +- .../network/generic_proxy/router/BUILD | 57 ++ .../generic_proxy}/router/config_test.cc | 5 +- .../generic_proxy}/router/router_test.cc | 173 ++++- .../generic_proxy}/router/upstream_test.cc | 149 ++-- .../network/generic_proxy/stats_test.cc | 29 + .../network/generic_proxy/stream_test.cc | 93 +++ .../network/generic_proxy/tracing_test.cc | 55 ++ tools/code_format/config.yaml | 1 + tools/spelling/spelling_dictionary.txt | 1 + 98 files changed, 2559 insertions(+), 1019 deletions(-) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/action/v3/BUILD (100%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/action/v3/action.proto (95%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/BUILD (100%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/dubbo.proto (81%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/BUILD (100%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/http1.proto (94%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/matcher/v3/BUILD (100%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/matcher/v3/matcher.proto (95%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/router/v3/BUILD (100%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/router/v3/router.proto (93%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/v3/BUILD (100%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.proto (92%) rename api/{contrib => }/envoy/extensions/filters/network/generic_proxy/v3/route.proto (97%) delete mode 100644 contrib/generic_proxy/filters/network/source/codecs/dubbo/BUILD delete mode 100644 contrib/generic_proxy/filters/network/source/interface/BUILD delete mode 100644 contrib/generic_proxy/filters/network/test/router/BUILD rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/BUILD (56%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/access_log.cc (94%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/access_log.h (94%) rename {contrib/generic_proxy/filters/network/source/interface => source/extensions/filters/network/generic_proxy}/codec_callbacks.h (97%) create mode 100644 source/extensions/filters/network/generic_proxy/codecs/dubbo/BUILD rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/codecs/dubbo/config.cc (98%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/codecs/dubbo/config.h (88%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/codecs/http1/BUILD (59%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/codecs/http1/config.cc (90%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/codecs/http1/config.h (96%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/config.cc (97%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/config.h (81%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/file_access_log.h (100%) rename contrib/generic_proxy/filters/network/source/interface/filter.h => source/extensions/filters/network/generic_proxy/filter_callbacks.h (75%) create mode 100644 source/extensions/filters/network/generic_proxy/interface/BUILD rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/interface/codec.h (97%) rename contrib/generic_proxy/filters/network/source/interface/config.h => source/extensions/filters/network/generic_proxy/interface/filter.h (50%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/interface/stream.h (95%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/match.cc (98%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/match.h (96%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/match_input.h (96%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/proxy.cc (91%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/proxy.h (93%) rename {contrib/generic_proxy/filters/network/source/interface => source/extensions/filters/network/generic_proxy}/proxy_config.h (79%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/rds.h (60%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/rds_impl.h (58%) rename {contrib/generic_proxy/filters/network/source/interface => source/extensions/filters/network/generic_proxy}/route.h (93%) rename contrib/generic_proxy/filters/network/source/route.cc => source/extensions/filters/network/generic_proxy/route_impl.cc (97%) rename contrib/generic_proxy/filters/network/source/route.h => source/extensions/filters/network/generic_proxy/route_impl.h (91%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/router/BUILD (56%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/router/config.cc (92%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/router/config.h (78%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/router/router.cc (91%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/router/router.h (91%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/router/upstream.cc (92%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/router/upstream.h (98%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/stats.cc (98%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/stats.h (100%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/tracing.cc (93%) rename {contrib/generic_proxy/filters/network/source => source/extensions/filters/network/generic_proxy}/tracing.h (92%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/BUILD (53%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/access_log_test.cc (64%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/codecs/dubbo/BUILD (60%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/codecs/dubbo/config_test.cc (83%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/codecs/http1/BUILD (56%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/codecs/http1/config_test.cc (69%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/config_test.cc (78%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/fake_codec.cc (90%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/fake_codec.h (93%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/integration_test.cc (98%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/match_test.cc (78%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/mocks/BUILD (62%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/mocks/codec.cc (90%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/mocks/codec.h (97%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/mocks/filter.cc (97%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/mocks/filter.h (95%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/mocks/route.cc (91%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/mocks/route.h (94%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/proxy_test.cc (77%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/route_test.cc (94%) create mode 100644 test/extensions/filters/network/generic_proxy/router/BUILD rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/router/config_test.cc (90%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/router/router_test.cc (82%) rename {contrib/generic_proxy/filters/network/test => test/extensions/filters/network/generic_proxy}/router/upstream_test.cc (86%) create mode 100644 test/extensions/filters/network/generic_proxy/stats_test.cc create mode 100644 test/extensions/filters/network/generic_proxy/stream_test.cc create mode 100644 test/extensions/filters/network/generic_proxy/tracing_test.cc diff --git a/CODEOWNERS b/CODEOWNERS index b4432567632a..f9b3e48ec45c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -343,6 +343,8 @@ extensions/filters/http/oauth2 @derekargueta @mattklein123 /*/extensions/geoip_providers/maxmind @nezdolik @ravenblackx # Match delegate extension /*/extensions/filters/http/match_delegate @wbpcode @jstraceski @tyxia +# Generic proxy and related extensions +/*/extensions/filters/network/generic_proxy/ @wbpcode @soulxu /*/extensions/health_checkers/common @zuercher @botengyao diff --git a/api/BUILD b/api/BUILD index 1a65a88f889e..7a1db4f427aa 100644 --- a/api/BUILD +++ b/api/BUILD @@ -81,13 +81,7 @@ proto_library( "//contrib/envoy/extensions/filters/http/squash/v3:pkg", "//contrib/envoy/extensions/filters/http/sxg/v3alpha:pkg", "//contrib/envoy/extensions/filters/network/client_ssl_auth/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/action/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3:pkg", "//contrib/envoy/extensions/filters/network/generic_proxy/codecs/kafka/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/matcher/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/router/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/v3:pkg", "//contrib/envoy/extensions/filters/network/golang/v3alpha:pkg", "//contrib/envoy/extensions/filters/network/kafka_broker/v3:pkg", "//contrib/envoy/extensions/filters/network/kafka_mesh/v3alpha:pkg", @@ -230,6 +224,12 @@ proto_library( "//envoy/extensions/filters/network/dubbo_proxy/v3:pkg", "//envoy/extensions/filters/network/echo/v3:pkg", "//envoy/extensions/filters/network/ext_authz/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/action/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/codecs/http1/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/matcher/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/router/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/v3:pkg", "//envoy/extensions/filters/network/http_connection_manager/v3:pkg", "//envoy/extensions/filters/network/local_ratelimit/v3:pkg", "//envoy/extensions/filters/network/mongo_proxy/v3:pkg", diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/action/v3/BUILD b/api/envoy/extensions/filters/network/generic_proxy/action/v3/BUILD similarity index 100% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/action/v3/BUILD rename to api/envoy/extensions/filters/network/generic_proxy/action/v3/BUILD diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/action/v3/action.proto b/api/envoy/extensions/filters/network/generic_proxy/action/v3/action.proto similarity index 95% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/action/v3/action.proto rename to api/envoy/extensions/filters/network/generic_proxy/action/v3/action.proto index d7c3dd04df2e..3e1b7a790788 100644 --- a/api/contrib/envoy/extensions/filters/network/generic_proxy/action/v3/action.proto +++ b/api/envoy/extensions/filters/network/generic_proxy/action/v3/action.proto @@ -16,7 +16,7 @@ import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.network.generic_proxy.action.v3"; option java_outer_classname = "ActionProto"; option java_multiple_files = true; -option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/action/v3;actionv3"; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/action/v3;actionv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; option (xds.annotations.v3.file_status).work_in_progress = true; diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/BUILD b/api/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/BUILD similarity index 100% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/BUILD rename to api/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/BUILD diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/dubbo.proto b/api/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/dubbo.proto similarity index 81% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/dubbo.proto rename to api/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/dubbo.proto index 47a2af159394..d5b6782e6662 100644 --- a/api/contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/dubbo.proto +++ b/api/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/dubbo.proto @@ -9,7 +9,7 @@ import "udpa/annotations/status.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.network.generic_proxy.codecs.dubbo.v3"; option java_outer_classname = "DubboProto"; option java_multiple_files = true; -option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3;dubbov3"; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3;dubbov3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; option (xds.annotations.v3.file_status).work_in_progress = true; diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/BUILD b/api/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/BUILD similarity index 100% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/BUILD rename to api/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/BUILD diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/http1.proto b/api/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/http1.proto similarity index 94% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/http1.proto rename to api/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/http1.proto index 973a190d8138..2a57db6083f5 100644 --- a/api/contrib/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/http1.proto +++ b/api/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/http1.proto @@ -11,7 +11,7 @@ import "udpa/annotations/status.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.network.generic_proxy.codecs.http1.v3"; option java_outer_classname = "Http1Proto"; option java_multiple_files = true; -option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3;http1v3"; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3;http1v3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; option (xds.annotations.v3.file_status).work_in_progress = true; diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/matcher/v3/BUILD b/api/envoy/extensions/filters/network/generic_proxy/matcher/v3/BUILD similarity index 100% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/matcher/v3/BUILD rename to api/envoy/extensions/filters/network/generic_proxy/matcher/v3/BUILD diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/matcher/v3/matcher.proto b/api/envoy/extensions/filters/network/generic_proxy/matcher/v3/matcher.proto similarity index 95% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/matcher/v3/matcher.proto rename to api/envoy/extensions/filters/network/generic_proxy/matcher/v3/matcher.proto index 2490a0b9bffd..13990866e0fd 100644 --- a/api/contrib/envoy/extensions/filters/network/generic_proxy/matcher/v3/matcher.proto +++ b/api/envoy/extensions/filters/network/generic_proxy/matcher/v3/matcher.proto @@ -12,7 +12,7 @@ import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.network.generic_proxy.matcher.v3"; option java_outer_classname = "MatcherProto"; option java_multiple_files = true; -option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/matcher/v3;matcherv3"; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/matcher/v3;matcherv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; option (xds.annotations.v3.file_status).work_in_progress = true; diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/router/v3/BUILD b/api/envoy/extensions/filters/network/generic_proxy/router/v3/BUILD similarity index 100% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/router/v3/BUILD rename to api/envoy/extensions/filters/network/generic_proxy/router/v3/BUILD diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/router/v3/router.proto b/api/envoy/extensions/filters/network/generic_proxy/router/v3/router.proto similarity index 93% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/router/v3/router.proto rename to api/envoy/extensions/filters/network/generic_proxy/router/v3/router.proto index a7064152354e..67f14fecfd33 100644 --- a/api/contrib/envoy/extensions/filters/network/generic_proxy/router/v3/router.proto +++ b/api/envoy/extensions/filters/network/generic_proxy/router/v3/router.proto @@ -9,7 +9,7 @@ import "udpa/annotations/status.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.network.generic_proxy.router.v3"; option java_outer_classname = "RouterProto"; option java_multiple_files = true; -option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/router/v3;routerv3"; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/router/v3;routerv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; option (xds.annotations.v3.file_status).work_in_progress = true; diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/v3/BUILD b/api/envoy/extensions/filters/network/generic_proxy/v3/BUILD similarity index 100% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/v3/BUILD rename to api/envoy/extensions/filters/network/generic_proxy/v3/BUILD diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.proto b/api/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.proto similarity index 92% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.proto rename to api/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.proto index 7e35eabdb54c..9ae2560470cf 100644 --- a/api/contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.proto +++ b/api/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.proto @@ -2,10 +2,10 @@ syntax = "proto3"; package envoy.extensions.filters.network.generic_proxy.v3; -import "contrib/envoy/extensions/filters/network/generic_proxy/v3/route.proto"; import "envoy/config/accesslog/v3/accesslog.proto"; import "envoy/config/core/v3/config_source.proto"; import "envoy/config/core/v3/extension.proto"; +import "envoy/extensions/filters/network/generic_proxy/v3/route.proto"; import "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto"; import "xds/annotations/v3/status.proto"; @@ -16,7 +16,7 @@ import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.network.generic_proxy.v3"; option java_outer_classname = "GenericProxyProto"; option java_multiple_files = true; -option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/v3;generic_proxyv3"; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/v3;generic_proxyv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; option (xds.annotations.v3.file_status).work_in_progress = true; diff --git a/api/contrib/envoy/extensions/filters/network/generic_proxy/v3/route.proto b/api/envoy/extensions/filters/network/generic_proxy/v3/route.proto similarity index 97% rename from api/contrib/envoy/extensions/filters/network/generic_proxy/v3/route.proto rename to api/envoy/extensions/filters/network/generic_proxy/v3/route.proto index 2ac8b0f93377..c29826618d04 100644 --- a/api/contrib/envoy/extensions/filters/network/generic_proxy/v3/route.proto +++ b/api/envoy/extensions/filters/network/generic_proxy/v3/route.proto @@ -11,7 +11,7 @@ import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.network.generic_proxy.v3"; option java_outer_classname = "RouteProto"; option java_multiple_files = true; -option go_package = "github.com/envoyproxy/go-control-plane/contrib/envoy/extensions/filters/network/generic_proxy/v3;generic_proxyv3"; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/generic_proxy/v3;generic_proxyv3"; option (udpa.annotations.file_status).package_version_status = ACTIVE; option (xds.annotations.v3.file_status).work_in_progress = true; diff --git a/api/versioning/BUILD b/api/versioning/BUILD index 97772178dd97..96791470d5df 100644 --- a/api/versioning/BUILD +++ b/api/versioning/BUILD @@ -19,13 +19,7 @@ proto_library( "//contrib/envoy/extensions/filters/http/squash/v3:pkg", "//contrib/envoy/extensions/filters/http/sxg/v3alpha:pkg", "//contrib/envoy/extensions/filters/network/client_ssl_auth/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/action/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3:pkg", "//contrib/envoy/extensions/filters/network/generic_proxy/codecs/kafka/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/matcher/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/router/v3:pkg", - "//contrib/envoy/extensions/filters/network/generic_proxy/v3:pkg", "//contrib/envoy/extensions/filters/network/golang/v3alpha:pkg", "//contrib/envoy/extensions/filters/network/kafka_broker/v3:pkg", "//contrib/envoy/extensions/filters/network/kafka_mesh/v3alpha:pkg", @@ -168,6 +162,12 @@ proto_library( "//envoy/extensions/filters/network/dubbo_proxy/v3:pkg", "//envoy/extensions/filters/network/echo/v3:pkg", "//envoy/extensions/filters/network/ext_authz/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/action/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/codecs/http1/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/matcher/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/router/v3:pkg", + "//envoy/extensions/filters/network/generic_proxy/v3:pkg", "//envoy/extensions/filters/network/http_connection_manager/v3:pkg", "//envoy/extensions/filters/network/local_ratelimit/v3:pkg", "//envoy/extensions/filters/network/mongo_proxy/v3:pkg", diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 1f8a5359dc30..a9f9f3036731 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -851,7 +851,7 @@ REPOSITORY_LOCATIONS_SPEC = dict( strip_prefix = "hessian2-codec-{version}", urls = ["https://github.com/alibaba/hessian2-codec/archive/{version}.tar.gz"], use_category = ["dataplane_ext"], - extensions = ["envoy.filters.network.dubbo_proxy"], + extensions = ["envoy.filters.network.dubbo_proxy", "envoy.filters.network.generic_proxy", "envoy.generic_proxy.codecs.dubbo"], release_date = "2022-10-10", cpe = "N/A", license = "Apache-2.0", diff --git a/contrib/contrib_build_config.bzl b/contrib/contrib_build_config.bzl index 7be1cd02ffad..905788c00eca 100644 --- a/contrib/contrib_build_config.bzl +++ b/contrib/contrib_build_config.bzl @@ -27,7 +27,6 @@ CONTRIB_EXTENSIONS = { "envoy.filters.network.mysql_proxy": "//contrib/mysql_proxy/filters/network/source:config", "envoy.filters.network.postgres_proxy": "//contrib/postgres_proxy/filters/network/source:config", "envoy.filters.network.rocketmq_proxy": "//contrib/rocketmq_proxy/filters/network/source:config", - "envoy.filters.network.generic_proxy": "//contrib/generic_proxy/filters/network/source:config", "envoy.filters.network.golang": "//contrib/golang/filters/network/source:config", # @@ -71,9 +70,6 @@ CONTRIB_EXTENSIONS = { # # Extensions for generic proxy # - "envoy.filters.generic.router": "//contrib/generic_proxy/filters/network/source/router:config", - "envoy.generic_proxy.codecs.dubbo": "//contrib/generic_proxy/filters/network/source/codecs/dubbo:config", - "envoy.generic_proxy.codecs.http1": "//contrib/generic_proxy/filters/network/source/codecs/http1:config", "envoy.generic_proxy.codecs.kafka": "//contrib/generic_proxy/filters/network/source/codecs/kafka:config", # diff --git a/contrib/extensions_metadata.yaml b/contrib/extensions_metadata.yaml index 76218e5a2b85..4b704af159df 100644 --- a/contrib/extensions_metadata.yaml +++ b/contrib/extensions_metadata.yaml @@ -118,25 +118,6 @@ envoy.xds_delegates.kv_store: - envoy.xds_delegates security_posture: data_plane_agnostic status: wip -envoy.filters.network.generic_proxy: - categories: - - envoy.filters.network - security_posture: requires_trusted_downstream_and_upstream - status: wip -envoy.filters.generic.router: - categories: - - envoy.generic_proxy.filters - security_posture: requires_trusted_downstream_and_upstream - status: wip - type_urls: - - envoy.extensions.filters.network.generic_proxy.router.v3.Router -envoy.generic_proxy.codecs.dubbo: - categories: - - envoy.generic_proxy.codecs - security_posture: requires_trusted_downstream_and_upstream - status: wip - type_urls: - - envoy.extensions.filters.network.generic_proxy.codecs.dubbo.v3.DubboCodecConfig envoy.generic_proxy.codecs.kafka: categories: - envoy.generic_proxy.codecs @@ -144,13 +125,6 @@ envoy.generic_proxy.codecs.kafka: status: wip type_urls: - envoy.extensions.filters.network.generic_proxy.codecs.kafka.v3.KafkaCodecConfig -envoy.generic_proxy.codecs.http1: - categories: - - envoy.generic_proxy.codecs - security_posture: requires_trusted_downstream_and_upstream - status: wip - type_urls: - - envoy.extensions.filters.network.generic_proxy.codecs.http1.v3.Http1CodecConfig envoy.router.cluster_specifier_plugin.golang: categories: - envoy.router.cluster_specifier_plugin diff --git a/contrib/generic_proxy/filters/network/source/codecs/dubbo/BUILD b/contrib/generic_proxy/filters/network/source/codecs/dubbo/BUILD deleted file mode 100644 index 4533271d4701..000000000000 --- a/contrib/generic_proxy/filters/network/source/codecs/dubbo/BUILD +++ /dev/null @@ -1,24 +0,0 @@ -load( - "//bazel:envoy_build_system.bzl", - "envoy_cc_contrib_extension", - "envoy_contrib_package", -) - -licenses(["notice"]) # Apache 2 - -envoy_contrib_package() - -envoy_cc_contrib_extension( - name = "config", - srcs = [ - "config.cc", - ], - hdrs = [ - "config.h", - ], - deps = [ - "//contrib/generic_proxy/filters/network/source/interface:codec_interface", - "//source/extensions/common/dubbo:codec_lib", - "@envoy_api//contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3:pkg_cc_proto", - ], -) diff --git a/contrib/generic_proxy/filters/network/source/codecs/kafka/BUILD b/contrib/generic_proxy/filters/network/source/codecs/kafka/BUILD index 807d8a1c160b..e96582eba3a1 100644 --- a/contrib/generic_proxy/filters/network/source/codecs/kafka/BUILD +++ b/contrib/generic_proxy/filters/network/source/codecs/kafka/BUILD @@ -17,9 +17,9 @@ envoy_cc_contrib_extension( "config.h", ], deps = [ - "//contrib/generic_proxy/filters/network/source/interface:codec_interface", "//contrib/kafka/filters/network/source:kafka_request_codec_lib", "//contrib/kafka/filters/network/source:kafka_response_codec_lib", + "//source/extensions/filters/network/generic_proxy/interface:codec_interface", "@envoy_api//contrib/envoy/extensions/filters/network/generic_proxy/codecs/kafka/v3:pkg_cc_proto", ], ) diff --git a/contrib/generic_proxy/filters/network/source/codecs/kafka/config.h b/contrib/generic_proxy/filters/network/source/codecs/kafka/config.h index b4b9f9d65ff6..44b59895af3b 100644 --- a/contrib/generic_proxy/filters/network/source/codecs/kafka/config.h +++ b/contrib/generic_proxy/filters/network/source/codecs/kafka/config.h @@ -1,9 +1,9 @@ #pragma once #include "source/common/buffer/buffer_impl.h" +#include "source/extensions/filters/network/generic_proxy/interface/codec.h" #include "contrib/envoy/extensions/filters/network/generic_proxy/codecs/kafka/v3/kafka.pb.h" -#include "contrib/generic_proxy/filters/network/source/interface/codec.h" #include "contrib/kafka/filters/network/source/request_codec.h" #include "contrib/kafka/filters/network/source/response_codec.h" diff --git a/contrib/generic_proxy/filters/network/source/interface/BUILD b/contrib/generic_proxy/filters/network/source/interface/BUILD deleted file mode 100644 index c799b0f7b939..000000000000 --- a/contrib/generic_proxy/filters/network/source/interface/BUILD +++ /dev/null @@ -1,105 +0,0 @@ -load( - "//bazel:envoy_build_system.bzl", - "envoy_cc_library", - "envoy_contrib_package", -) - -licenses(["notice"]) # Apache 2 - -envoy_contrib_package() - -envoy_cc_library( - name = "stream_interface", - hdrs = [ - "stream.h", - ], - deps = [ - "//envoy/tracing:trace_context_interface", - ], -) - -envoy_cc_library( - name = "codec_callbacks_interface", - hdrs = [ - "codec_callbacks.h", - ], - deps = [ - ":route_interface", - ":stream_interface", - "//envoy/buffer:buffer_interface", - "//envoy/network:drain_decision_interface", - ], -) - -envoy_cc_library( - name = "codec_interface", - hdrs = [ - "codec.h", - ], - deps = [ - ":codec_callbacks_interface", - ":stream_interface", - "//envoy/buffer:buffer_interface", - "//envoy/config:typed_config_interface", - "//envoy/network:filter_interface", - "//envoy/server:factory_context_interface", - ], -) - -envoy_cc_library( - name = "filter_interface", - hdrs = [ - "filter.h", - ], - deps = [ - ":codec_interface", - ":route_interface", - ":stream_interface", - ], -) - -envoy_cc_library( - name = "route_interface", - hdrs = [ - "route.h", - ], - deps = [ - ":stream_interface", - "//contrib/generic_proxy/filters/network/source:match_input_lib", - "//envoy/config:typed_metadata_interface", - "//envoy/event:dispatcher_interface", - "//envoy/network:connection_interface", - "//envoy/rds:rds_config_interface", - "//envoy/router:router_interface", - "//envoy/stream_info:stream_info_interface", - "@envoy_api//envoy/config/core/v3:pkg_cc_proto", - ], -) - -envoy_cc_library( - name = "config_interface", - hdrs = [ - "config.h", - ], - deps = [ - ":filter_interface", - "//envoy/config:typed_config_interface", - "//envoy/server:factory_context_interface", - ], -) - -envoy_cc_library( - name = "proxy_config_interface", - hdrs = [ - "proxy_config.h", - ], - deps = [ - ":codec_interface", - ":filter_interface", - ":route_interface", - "//contrib/generic_proxy/filters/network/source:access_log_lib", - "//contrib/generic_proxy/filters/network/source:match_input_lib", - "//envoy/tracing:trace_config_interface", - "//envoy/tracing:tracer_interface", - ], -) diff --git a/contrib/generic_proxy/filters/network/test/codecs/kafka/BUILD b/contrib/generic_proxy/filters/network/test/codecs/kafka/BUILD index d3c54211c8ea..43f68dcdc968 100644 --- a/contrib/generic_proxy/filters/network/test/codecs/kafka/BUILD +++ b/contrib/generic_proxy/filters/network/test/codecs/kafka/BUILD @@ -15,7 +15,7 @@ envoy_cc_test( ], deps = [ "//contrib/generic_proxy/filters/network/source/codecs/kafka:config", - "//contrib/generic_proxy/filters/network/test/mocks:codec_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:codec_mocks", "//test/mocks/server:factory_context_mocks", ], ) diff --git a/contrib/generic_proxy/filters/network/test/codecs/kafka/config_test.cc b/contrib/generic_proxy/filters/network/test/codecs/kafka/config_test.cc index a5e97bc932ff..d6d4c46819e2 100644 --- a/contrib/generic_proxy/filters/network/test/codecs/kafka/config_test.cc +++ b/contrib/generic_proxy/filters/network/test/codecs/kafka/config_test.cc @@ -1,10 +1,10 @@ #include #include +#include "test/extensions/filters/network/generic_proxy/mocks/codec.h" #include "test/mocks/server/factory_context.h" #include "contrib/generic_proxy/filters/network/source/codecs/kafka/config.h" -#include "contrib/generic_proxy/filters/network/test/mocks/codec.h" #include "contrib/kafka/filters/network/source/external/requests.h" #include "contrib/kafka/filters/network/source/external/responses.h" #include "gtest/gtest.h" diff --git a/contrib/generic_proxy/filters/network/test/router/BUILD b/contrib/generic_proxy/filters/network/test/router/BUILD deleted file mode 100644 index 1b3de5d4d0ea..000000000000 --- a/contrib/generic_proxy/filters/network/test/router/BUILD +++ /dev/null @@ -1,57 +0,0 @@ -load( - "//bazel:envoy_build_system.bzl", - "envoy_cc_test", - "envoy_contrib_package", -) - -licenses(["notice"]) # Apache 2 - -envoy_contrib_package() - -envoy_cc_test( - name = "router_test", - srcs = [ - "router_test.cc", - ], - deps = [ - "//contrib/generic_proxy/filters/network/source/router:router_lib", - "//contrib/generic_proxy/filters/network/test:fake_codec_lib", - "//contrib/generic_proxy/filters/network/test/mocks:codec_mocks", - "//contrib/generic_proxy/filters/network/test/mocks:filter_mocks", - "//contrib/generic_proxy/filters/network/test/mocks:route_mocks", - "//source/common/buffer:buffer_lib", - "//test/mocks/server:factory_context_mocks", - "//test/test_common:registry_lib", - "//test/test_common:utility_lib", - ], -) - -envoy_cc_test( - name = "upstream_test", - srcs = [ - "upstream_test.cc", - ], - deps = [ - "//contrib/generic_proxy/filters/network/source/router:router_lib", - "//contrib/generic_proxy/filters/network/test:fake_codec_lib", - "//contrib/generic_proxy/filters/network/test/mocks:codec_mocks", - "//contrib/generic_proxy/filters/network/test/mocks:filter_mocks", - "//contrib/generic_proxy/filters/network/test/mocks:route_mocks", - "//source/common/buffer:buffer_lib", - "//test/mocks/server:factory_context_mocks", - "//test/test_common:registry_lib", - "//test/test_common:utility_lib", - ], -) - -envoy_cc_test( - name = "config_test", - srcs = [ - "config_test.cc", - ], - deps = [ - "//contrib/generic_proxy/filters/network/source/router:config", - "//contrib/generic_proxy/filters/network/test/mocks:filter_mocks", - "//test/mocks/server:factory_context_mocks", - ], -) diff --git a/docs/root/configuration/listeners/network_filters/generic_proxy_filter.rst b/docs/root/configuration/listeners/network_filters/generic_proxy_filter.rst index 3923dc48970b..0c42b97eae14 100644 --- a/docs/root/configuration/listeners/network_filters/generic_proxy_filter.rst +++ b/docs/root/configuration/listeners/network_filters/generic_proxy_filter.rst @@ -118,7 +118,7 @@ The community has implemented a :ref:`dubbo codec ) -> FormatterProviderPtr { return std::make_unique(); }}, @@ -168,7 +165,7 @@ namespace Formatter { using FormatterContext = Extensions::NetworkFilters::GenericProxy::FormatterContext; using SimpleCommandParser = Extensions::NetworkFilters::GenericProxy::SimpleCommandParser; -// Regiter the built-in command parsers for the FormatterContext. +// Register the built-in command parsers for the FormatterContext. REGISTER_BUILT_IN_COMMAND_PARSER(FormatterContext, SimpleCommandParser); } // namespace Formatter diff --git a/contrib/generic_proxy/filters/network/source/access_log.h b/source/extensions/filters/network/generic_proxy/access_log.h similarity index 94% rename from contrib/generic_proxy/filters/network/source/access_log.h rename to source/extensions/filters/network/generic_proxy/access_log.h index 3c8dbf11b00c..dba0a2dbd4ee 100644 --- a/contrib/generic_proxy/filters/network/source/access_log.h +++ b/source/extensions/filters/network/generic_proxy/access_log.h @@ -1,7 +1,7 @@ #pragma once -#include "contrib/generic_proxy/filters/network/source/file_access_log.h" -#include "contrib/generic_proxy/filters/network/source/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/file_access_log.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/interface/codec_callbacks.h b/source/extensions/filters/network/generic_proxy/codec_callbacks.h similarity index 97% rename from contrib/generic_proxy/filters/network/source/interface/codec_callbacks.h rename to source/extensions/filters/network/generic_proxy/codec_callbacks.h index 367cb8783e4b..2831447066cd 100644 --- a/contrib/generic_proxy/filters/network/source/interface/codec_callbacks.h +++ b/source/extensions/filters/network/generic_proxy/codec_callbacks.h @@ -5,8 +5,8 @@ #include "envoy/network/connection.h" #include "envoy/network/drain_decision.h" -#include "contrib/generic_proxy/filters/network/source/interface/route.h" -#include "contrib/generic_proxy/filters/network/source/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/route.h" namespace Envoy { namespace Extensions { diff --git a/source/extensions/filters/network/generic_proxy/codecs/dubbo/BUILD b/source/extensions/filters/network/generic_proxy/codecs/dubbo/BUILD new file mode 100644 index 000000000000..4bb315e533c0 --- /dev/null +++ b/source/extensions/filters/network/generic_proxy/codecs/dubbo/BUILD @@ -0,0 +1,24 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_extension", + "envoy_extension_package", +) + +licenses(["notice"]) # Apache 2 + +envoy_extension_package() + +envoy_cc_extension( + name = "config", + srcs = [ + "config.cc", + ], + hdrs = [ + "config.h", + ], + deps = [ + "//source/extensions/common/dubbo:codec_lib", + "//source/extensions/filters/network/generic_proxy/interface:codec_interface", + "@envoy_api//envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3:pkg_cc_proto", + ], +) diff --git a/contrib/generic_proxy/filters/network/source/codecs/dubbo/config.cc b/source/extensions/filters/network/generic_proxy/codecs/dubbo/config.cc similarity index 98% rename from contrib/generic_proxy/filters/network/source/codecs/dubbo/config.cc rename to source/extensions/filters/network/generic_proxy/codecs/dubbo/config.cc index ef172852d55d..d6ac161c4364 100644 --- a/contrib/generic_proxy/filters/network/source/codecs/dubbo/config.cc +++ b/source/extensions/filters/network/generic_proxy/codecs/dubbo/config.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/source/codecs/dubbo/config.h" +#include "source/extensions/filters/network/generic_proxy/codecs/dubbo/config.h" #include diff --git a/contrib/generic_proxy/filters/network/source/codecs/dubbo/config.h b/source/extensions/filters/network/generic_proxy/codecs/dubbo/config.h similarity index 88% rename from contrib/generic_proxy/filters/network/source/codecs/dubbo/config.h rename to source/extensions/filters/network/generic_proxy/codecs/dubbo/config.h index 379784363c15..a64cee717131 100644 --- a/contrib/generic_proxy/filters/network/source/codecs/dubbo/config.h +++ b/source/extensions/filters/network/generic_proxy/codecs/dubbo/config.h @@ -2,12 +2,12 @@ #include +#include "envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/dubbo.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/dubbo.pb.validate.h" + #include "source/common/common/logger.h" #include "source/extensions/common/dubbo/codec.h" - -#include "contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/dubbo.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/codecs/dubbo/v3/dubbo.pb.validate.h" -#include "contrib/generic_proxy/filters/network/source/interface/codec.h" +#include "source/extensions/filters/network/generic_proxy/interface/codec.h" namespace Envoy { namespace Extensions { @@ -28,14 +28,12 @@ class DubboRequest : public Request { ASSERT(inner_metadata_ != nullptr); ASSERT(inner_metadata_->hasContext()); ASSERT(inner_metadata_->hasRequest()); + ASSERT(!inner_metadata_->heartbeat()); // Heartbeat should be handled by codec directly. uint32_t frame_flags = FrameFlags::FLAG_END_STREAM; // Dubbo message only has one frame. if (!inner_metadata_->context().isTwoWay()) { frame_flags |= FrameFlags::FLAG_ONE_WAY; } - if (inner_metadata_->context().heartbeat()) { - frame_flags |= FrameFlags::FLAG_HEARTBEAT; - } stream_frame_flags_ = {static_cast(inner_metadata_->requestId()), frame_flags}; } @@ -66,17 +64,11 @@ class DubboResponse : public Response { ASSERT(inner_metadata_ != nullptr); ASSERT(inner_metadata_->hasContext()); ASSERT(inner_metadata_->hasResponse()); - refreshStatus(); + ASSERT(!inner_metadata_->heartbeat()); // Heartbeat should be handled by codec directly. - uint32_t frame_flags = FrameFlags::FLAG_END_STREAM; // Dubbo message only has one frame. - if (!inner_metadata_->context().isTwoWay()) { - frame_flags |= FrameFlags::FLAG_ONE_WAY; - } - if (inner_metadata_->context().heartbeat()) { - frame_flags |= FrameFlags::FLAG_HEARTBEAT; - } + refreshStatus(); - stream_frame_flags_ = {static_cast(inner_metadata_->requestId()), frame_flags}; + stream_frame_flags_ = {static_cast(inner_metadata_->requestId())}; } void refreshStatus(); @@ -114,7 +106,7 @@ class DubboDecoderBase : public DubboCodecBase, public CodecType { metadata_ = std::make_shared(); } - try { + TRY_NEEDS_AUDIT { Common::Dubbo::DecodeStatus decode_status{Common::Dubbo::DecodeStatus::Success}; if (!metadata_->hasContext()) { ENVOY_LOG(debug, "Dubbo codec: try to decode new dubbo request/response header"); @@ -127,12 +119,8 @@ class DubboDecoderBase : public DubboCodecBase, public CodecType { decode_status = codec_->decodeData(buffer, *metadata_); } - if (decode_status == Common::Dubbo::DecodeStatus::Failure) { - ENVOY_LOG(warn, "Dubbo codec: unexpected decoding error"); - metadata_.reset(); - callback_->onDecodingFailure(); - return Common::Dubbo::DecodeStatus::Failure; - } + // Ignore DecodeStatus::Failure as the codec will never return it. + // TODO(wbpcode): make the codec exception free and handle the error status of the codec. if (decode_status == Common::Dubbo::DecodeStatus::Waiting) { ENVOY_LOG(debug, "Dubbo codec: waiting for more input data"); @@ -164,7 +152,8 @@ class DubboDecoderBase : public DubboCodecBase, public CodecType { callback_->onDecodingSuccess(std::move(message)); return Common::Dubbo::DecodeStatus::Success; - } catch (const EnvoyException& error) { + } + END_TRY catch (const EnvoyException& error) { ENVOY_LOG(warn, "Dubbo codec: decoding error: {}", error.what()); metadata_.reset(); diff --git a/contrib/generic_proxy/filters/network/source/codecs/http1/BUILD b/source/extensions/filters/network/generic_proxy/codecs/http1/BUILD similarity index 59% rename from contrib/generic_proxy/filters/network/source/codecs/http1/BUILD rename to source/extensions/filters/network/generic_proxy/codecs/http1/BUILD index adbc830baa9d..3c5925ff783d 100644 --- a/contrib/generic_proxy/filters/network/source/codecs/http1/BUILD +++ b/source/extensions/filters/network/generic_proxy/codecs/http1/BUILD @@ -1,14 +1,14 @@ load( "//bazel:envoy_build_system.bzl", - "envoy_cc_contrib_extension", - "envoy_contrib_package", + "envoy_cc_extension", + "envoy_extension_package", ) licenses(["notice"]) # Apache 2 -envoy_contrib_package() +envoy_extension_package() -envoy_cc_contrib_extension( +envoy_cc_extension( name = "config", srcs = [ "config.cc", @@ -17,12 +17,12 @@ envoy_cc_contrib_extension( "config.h", ], deps = [ - "//contrib/generic_proxy/filters/network/source/interface:codec_interface", "//source/common/http:codes_lib", "//source/common/http:header_utility_lib", "//source/common/http:headers_lib", "//source/common/http:utility_lib", "//source/common/http/http1:balsa_parser_lib", - "@envoy_api//contrib/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3:pkg_cc_proto", + "//source/extensions/filters/network/generic_proxy/interface:codec_interface", + "@envoy_api//envoy/extensions/filters/network/generic_proxy/codecs/http1/v3:pkg_cc_proto", ], ) diff --git a/contrib/generic_proxy/filters/network/source/codecs/http1/config.cc b/source/extensions/filters/network/generic_proxy/codecs/http1/config.cc similarity index 90% rename from contrib/generic_proxy/filters/network/source/codecs/http1/config.cc rename to source/extensions/filters/network/generic_proxy/codecs/http1/config.cc index c5167e14fb5f..49e336e3c274 100644 --- a/contrib/generic_proxy/filters/network/source/codecs/http1/config.cc +++ b/source/extensions/filters/network/generic_proxy/codecs/http1/config.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/source/codecs/http1/config.h" +#include "source/extensions/filters/network/generic_proxy/codecs/http1/config.h" #include "source/common/http/codes.h" #include "source/common/http/header_utility.h" @@ -28,6 +28,7 @@ static constexpr uint32_t DEFAULT_MAX_BUFFER_SIZE = 8 * 1024 * 1024; static constexpr absl::string_view _100_CONTINUE_RESPONSE = "HTTP/1.1 100 Continue\r\n" "content-length: 0\r\n" "\r\n"; +static constexpr absl::string_view ZERO_VIEW = "0"; void encodeNormalHeaders(Buffer::Instance& buffer, const Http::RequestOrResponseHeaderMap& headers, bool chunk_encoding) { @@ -49,7 +50,7 @@ void encodeNormalHeaders(Buffer::Instance& buffer, const Http::RequestOrResponse if (chunk_encoding) { if (headers.TransferEncoding() == nullptr) { - buffer.add("Transfer-Encoding: chunked\r\n"); + buffer.add("transfer-encoding: chunked\r\n"); } } } @@ -117,8 +118,7 @@ absl::Status Utility::validateRequestHeaders(Http::RequestHeaderMap& headers) { return absl::OkStatus(); } -absl::Status Utility::validateResponseHeaders(Http::ResponseHeaderMap& headers, - Envoy::Http::Code code) { +absl::Status Utility::validateResponseHeaders(Http::ResponseHeaderMap& headers, Http::Code code) { if (auto status = validateCommonHeaders(headers); !status.ok()) { return status; } @@ -126,21 +126,18 @@ absl::Status Utility::validateResponseHeaders(Http::ResponseHeaderMap& headers, ASSERT(headers.Status() != nullptr); if (code < Http::Code::OK || code == Http::Code::NoContent || code == Http::Code::NotModified) { - // There is no clear description in the RFC about the transfer-encoding behavior - // of NotModified response. But 1xx, 204 responses should not have transfer-encoding. - // See https://datatracker.ietf.org/doc/html/rfc9112#section-6.1-6 - if (code != Http::Code::NotModified) { - if (headers.TransferEncoding() != nullptr) { - return absl::InvalidArgumentError("transfer-encoding is set for 1xx, 204 response"); - } + // 1xx, 204 responses should not have transfer-encoding. See + // https://datatracker.ietf.org/doc/html/rfc9112#section-6.1-6. + // There is no clear description in the RFC about the transfer-encoding behavior of NotModified + // response. But it is safe to treat it as same as 1xx and 204 responses. + if (headers.TransferEncoding() != nullptr) { + return absl::InvalidArgumentError("transfer-encoding is set for 1xx/204/304 response"); } // 1xx, 204, 304 responses should not have body. - if (headers.ContentLength() != nullptr) { - if (headers.ContentLength()->value().getStringView() != "0") { - return absl::InvalidArgumentError( - "content-length (non-zero) is set for 1xx, 204, 304 response"); - } + const auto content_length = headers.ContentLength(); + if (content_length != nullptr && content_length->value().getStringView() != ZERO_VIEW) { + return absl::InvalidArgumentError("non-zero content-length is set for 1xx/204/304 response"); } } @@ -280,51 +277,49 @@ bool Http1CodecBase::decodeBuffer(Buffer::Instance& buffer) { const auto slice = decoding_buffer_.frontSlice(); const auto nread = parser_->execute(static_cast(slice.mem_), slice.len_); decoding_buffer_.drain(nread); - const auto status = parser_->getStatus(); - // Parser is paused by the callback. Do nothing and return. Don't handle the buffered body - // because parser is paused and no callback should be called. - if (status == Http::Http1::ParserStatus::Paused) { - return true; - } - // Parser has encountered an error. Return false to indicate decoding failure. Ignore the - // buffered body. - if (status == Http::Http1::ParserStatus::Error) { - // Decoding error. + if (const auto status = parser_->getStatus(); status == Http::Http1::ParserStatus::Error) { + // Parser has encountered an error. Return false to indicate decoding failure. Ignore the + // buffered body. return false; - } - // No more data to read and parser is not paused, break to avoid infinite loop. This is - // preventive check. The parser should not be in this state in normal cases. - if (nread == 0) { + } else if (status == Http::Http1::ParserStatus::Paused || nread == 0) { + // If parser is paused by the callback. Do nothing and return. Don't handle the buffered body + // because parser is paused and no callback should be called. + // If consumed buffer size is 0 means no more data to read, break to avoid infinite loop. This + // is preventive check. The parser should not be in this state in normal cases. return true; } } - // Try to dispatch any buffered body. If the message is complete then this will be a no-op. - dispatchBufferedBody(false); - return true; + + // Try to dispatch any buffered body. We assume the headers should be handled in the callbacks. + // And if the headers are not handled then the buffered body should be empty, this should be a + // no-op. And if the message is complete then this will also be a no-op. + return dispatchBufferedBody(false); } -void Http1CodecBase::dispatchBufferedBody(bool end_stream) { +bool Http1CodecBase::dispatchBufferedBody(bool end_stream) { if (single_frame_mode_) { - // Do nothing until the onMessageComplete callback if we are in single frame mode. + // Do nothing to the buffered body until the onMessageComplete callback if we are in single + // frame mode. // Check if the buffered body is too large. if (bufferedBodyOverflow()) { // Pause the parser to avoid further parsing. parser_->pause(); // Tell the caller that the decoding failed. - onDecodingFailure(); + return false; } - return; + return true; } if (buffered_body_.length() > 0 || end_stream) { - ENVOY_LOG(debug, - "Generic proxy HTTP1 codec: decoding request/response body (end_stream={} size={})", + ENVOY_LOG(debug, "Generic proxy HTTP1 codec: decoding message body (end_stream={} size={})", end_stream, buffered_body_.length()); auto frame = std::make_unique(buffered_body_, end_stream); onDecodingSuccess(std::move(frame)); } + + return true; } bool Http1CodecBase::bufferedBodyOverflow() { @@ -368,6 +363,7 @@ Http::Http1::CallbackResult Http1ServerCodec::onHeadersCompleteImpl() { } const bool non_end_stream = Utility::hasBody(*parser_, false, false); + active_request_->request_has_body_ = non_end_stream; ENVOY_LOG(debug, "decoding request headers complete (end_stream={}):\n{}", !non_end_stream, *active_request_->request_headers_); @@ -435,6 +431,11 @@ Http::Http1::CallbackResult Http1ServerCodec::onMessageCompleteImpl() { } EncodingResult Http1ServerCodec::encode(const StreamFrame& frame, EncodingContext&) { + if (!active_request_.has_value()) { + ENVOY_LOG(debug, "Generic proxy HTTP1 server codec: no request for coming response"); + return absl::InvalidArgumentError("no request for coming response"); + } + const bool response_end_stream = frame.frameFlags().endStream(); if (auto* headers = dynamic_cast(&frame); headers != nullptr) { @@ -474,11 +475,6 @@ EncodingResult Http1ServerCodec::encode(const StreamFrame& frame, EncodingContex ASSERT(encoding_buffer_.length() == 0); if (response_end_stream) { - if (!active_request_.has_value()) { - ENVOY_LOG(debug, "Generic proxy HTTP1 server codec: response complete without request"); - return absl::InvalidArgumentError("response complete without request"); - } - if (!active_request_->request_complete_) { ENVOY_LOG(debug, "Generic proxy HTTP1 server codec: response complete before request complete"); @@ -571,7 +567,7 @@ Http::Http1::CallbackResult Http1ClientCodec::onHeadersCompleteImpl() { } const bool non_end_stream = Utility::hasBody(*parser_, true, expect_response_->head_request_); - + expect_response_->response_has_body_ = non_end_stream; ENVOY_LOG(debug, "decoding response headers complete (end_stream={}):\n{}", !non_end_stream, *expect_response_->response_headers_); diff --git a/contrib/generic_proxy/filters/network/source/codecs/http1/config.h b/source/extensions/filters/network/generic_proxy/codecs/http1/config.h similarity index 96% rename from contrib/generic_proxy/filters/network/source/codecs/http1/config.h rename to source/extensions/filters/network/generic_proxy/codecs/http1/config.h index f96223bcb35b..ab9fd0206276 100644 --- a/contrib/generic_proxy/filters/network/source/codecs/http1/config.h +++ b/source/extensions/filters/network/generic_proxy/codecs/http1/config.h @@ -1,12 +1,12 @@ #pragma once +#include "envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/http1.pb.h" + #include "source/common/buffer/buffer_impl.h" #include "source/common/http/header_map_impl.h" #include "source/common/http/http1/balsa_parser.h" #include "source/common/http/http1/parser.h" - -#include "contrib/envoy/extensions/filters/network/generic_proxy/codecs/http1/v3/http1.pb.h" -#include "contrib/generic_proxy/filters/network/source/interface/codec.h" +#include "source/extensions/filters/network/generic_proxy/interface/codec.h" namespace Envoy { namespace Extensions { @@ -144,15 +144,21 @@ class Utility { static uint64_t statusToHttpStatus(absl::StatusCode status_code); }; +// ActiveRequest is used to store the state of server codec for decoding a request +// and encoding a response. struct ActiveRequest { Http::RequestHeaderMapPtr request_headers_; + bool request_has_body_{}; bool request_complete_{}; bool response_chunk_encoding_{}; }; +// ExpectResponse is used to store the state of client codec for decoding a response +// and encoding a request. struct ExpectResponse { Http::ResponseHeaderMapPtr response_headers_; + bool response_has_body_{}; bool request_complete_{}; bool head_request_{}; @@ -245,7 +251,7 @@ class Http1CodecBase : public Http::Http1::ParserCallbacks, bool decodeBuffer(Buffer::Instance& buffer); - void dispatchBufferedBody(bool end_stream); + bool dispatchBufferedBody(bool end_stream); bool bufferedBodyOverflow(); virtual Http::HeaderMap& headerMap() PURE; @@ -296,7 +302,7 @@ class Http1ServerCodec : public Http1CodecBase, public ServerCodec { void setCodecCallbacks(ServerCodecCallbacks& callbacks) override { callbacks_ = &callbacks; } void decode(Envoy::Buffer::Instance& buffer, bool) override { if (!decodeBuffer(buffer)) { - callbacks_->onDecodingFailure(); + onDecodingFailure(); } } EncodingResult encode(const StreamFrame& frame, EncodingContext& ctx) override; @@ -357,7 +363,7 @@ class Http1ClientCodec : public Http1CodecBase, public ClientCodec { void setCodecCallbacks(ClientCodecCallbacks& callbacks) override { callbacks_ = &callbacks; } void decode(Envoy::Buffer::Instance& buffer, bool) override { if (!decodeBuffer(buffer)) { - callbacks_->onDecodingFailure(); + onDecodingFailure(); } } EncodingResult encode(const StreamFrame& frame, EncodingContext& ctx) override; diff --git a/contrib/generic_proxy/filters/network/source/config.cc b/source/extensions/filters/network/generic_proxy/config.cc similarity index 97% rename from contrib/generic_proxy/filters/network/source/config.cc rename to source/extensions/filters/network/generic_proxy/config.cc index 6a10fd79446d..dd43702e0432 100644 --- a/contrib/generic_proxy/filters/network/source/config.cc +++ b/source/extensions/filters/network/generic_proxy/config.cc @@ -1,11 +1,11 @@ -#include "contrib/generic_proxy/filters/network/source/config.h" +#include "source/extensions/filters/network/generic_proxy/config.h" #include "source/common/access_log/access_log_impl.h" #include "source/common/tracing/tracer_manager_impl.h" +#include "source/extensions/filters/network/generic_proxy/rds.h" +#include "source/extensions/filters/network/generic_proxy/rds_impl.h" #include "access_log.h" -#include "contrib/generic_proxy/filters/network/source/rds.h" -#include "contrib/generic_proxy/filters/network/source/rds_impl.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/config.h b/source/extensions/filters/network/generic_proxy/config.h similarity index 81% rename from contrib/generic_proxy/filters/network/source/config.h rename to source/extensions/filters/network/generic_proxy/config.h index b6d59b69a454..8708223d1e65 100644 --- a/contrib/generic_proxy/filters/network/source/config.h +++ b/source/extensions/filters/network/generic_proxy/config.h @@ -1,13 +1,12 @@ #pragma once +#include "envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.validate.h" #include "envoy/registry/registry.h" #include "source/extensions/filters/network/common/factory_base.h" - -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.validate.h" -#include "contrib/generic_proxy/filters/network/source/interface/config.h" -#include "contrib/generic_proxy/filters/network/source/proxy.h" +#include "source/extensions/filters/network/generic_proxy/interface/filter.h" +#include "source/extensions/filters/network/generic_proxy/proxy.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/file_access_log.h b/source/extensions/filters/network/generic_proxy/file_access_log.h similarity index 100% rename from contrib/generic_proxy/filters/network/source/file_access_log.h rename to source/extensions/filters/network/generic_proxy/file_access_log.h diff --git a/contrib/generic_proxy/filters/network/source/interface/filter.h b/source/extensions/filters/network/generic_proxy/filter_callbacks.h similarity index 75% rename from contrib/generic_proxy/filters/network/source/interface/filter.h rename to source/extensions/filters/network/generic_proxy/filter_callbacks.h index 1c10487ee7ae..beefeeac8108 100644 --- a/contrib/generic_proxy/filters/network/source/interface/filter.h +++ b/source/extensions/filters/network/generic_proxy/filter_callbacks.h @@ -4,9 +4,9 @@ #include "envoy/network/connection.h" #include "envoy/stream_info/stream_info.h" -#include "contrib/generic_proxy/filters/network/source/interface/codec.h" -#include "contrib/generic_proxy/filters/network/source/interface/route.h" -#include "contrib/generic_proxy/filters/network/source/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/interface/codec.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/route.h" namespace Envoy { namespace Extensions { @@ -62,7 +62,6 @@ class StreamFilterCallbacks { /** * @return StreamInfo::StreamInfo& the stream info object associated with the stream. */ - virtual const StreamInfo::StreamInfo& streamInfo() const PURE; virtual StreamInfo::StreamInfo& streamInfo() PURE; /** @@ -137,49 +136,9 @@ class EncoderFilterCallback : public virtual StreamFilterCallbacks { virtual void continueEncoding() PURE; }; -// The status of the filter chain. -// 1. Continue: If Continue is returned, the filter chain will continue to the next filter in the -// chain. -// 2. StopIteration: If StopIteration is returned, the filter chain will stop and not continue -// to the next filter in the chain until the continueDecoding/continueEncoding is called. -enum class HeaderFilterStatus { Continue, StopIteration }; - -// The status of the filter chain. -// 1. Continue: If Continue is returned, the filter chain will continue to the next filter in the -// chain. -// 2. StopIteration: If StopIteration is returned, the filter chain will stop and not continue -// to the next filter in the chain until the continueDecoding/continueEncoding is called. -enum class CommonFilterStatus { Continue, StopIteration }; - -class DecoderFilter { -public: - virtual ~DecoderFilter() = default; - - virtual void onDestroy() PURE; - - virtual void setDecoderFilterCallbacks(DecoderFilterCallback& callbacks) PURE; - - virtual HeaderFilterStatus decodeHeaderFrame(RequestHeaderFrame& request) PURE; - virtual CommonFilterStatus decodeCommonFrame(RequestCommonFrame& request) PURE; -}; - -class EncoderFilter { -public: - virtual ~EncoderFilter() = default; - - virtual void onDestroy() PURE; - - virtual void setEncoderFilterCallbacks(EncoderFilterCallback& callbacks) PURE; - - virtual HeaderFilterStatus encodeHeaderFrame(ResponseHeaderFrame& response) PURE; - virtual CommonFilterStatus encodeCommonFrame(ResponseCommonFrame& response) PURE; -}; - -class StreamFilter : public DecoderFilter, public EncoderFilter {}; - -using DecoderFilterSharedPtr = std::shared_ptr; -using EncoderFilterSharedPtr = std::shared_ptr; -using StreamFilterSharedPtr = std::shared_ptr; +class DecoderFilter; +class EncoderFilter; +class StreamFilter; class FilterChainFactoryCallbacks { public: @@ -189,23 +148,21 @@ class FilterChainFactoryCallbacks { * Add a decoder filter that is used when reading connection data. * @param filter supplies the filter to add. */ - virtual void addDecoderFilter(DecoderFilterSharedPtr filter) PURE; + virtual void addDecoderFilter(std::shared_ptr filter) PURE; /** * Add a encoder filter that is used when writing connection data. * @param filter supplies the filter to add. */ - virtual void addEncoderFilter(EncoderFilterSharedPtr filter) PURE; + virtual void addEncoderFilter(std::shared_ptr filter) PURE; /** * Add a decoder/encoder filter that is used both when reading and writing connection data. * @param filter supplies the filter to add. */ - virtual void addFilter(StreamFilterSharedPtr filter) PURE; + virtual void addFilter(std::shared_ptr filter) PURE; }; -using FilterFactoryCb = std::function; - /** * Simple struct of additional contextual information of filter, e.g. filter config name * from configuration. @@ -213,11 +170,13 @@ using FilterFactoryCb = std::function; + /** * The filter chain manager is provided by the connection manager to the filter chain factory. * The filter chain factory will post the filter factory context and filter factory to the diff --git a/source/extensions/filters/network/generic_proxy/interface/BUILD b/source/extensions/filters/network/generic_proxy/interface/BUILD new file mode 100644 index 000000000000..967cec3749b7 --- /dev/null +++ b/source/extensions/filters/network/generic_proxy/interface/BUILD @@ -0,0 +1,50 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_library", + "envoy_extension_package", +) + +licenses(["notice"]) # Apache 2 + +envoy_extension_package() + +envoy_cc_library( + name = "stream_interface", + hdrs = [ + "stream.h", + ], + visibility = ["//visibility:public"], + deps = [ + "//envoy/tracing:trace_context_interface", + ], +) + +envoy_cc_library( + name = "codec_interface", + hdrs = [ + "codec.h", + ], + visibility = ["//visibility:public"], + deps = [ + ":stream_interface", + "//envoy/buffer:buffer_interface", + "//envoy/config:typed_config_interface", + "//envoy/network:filter_interface", + "//envoy/server:factory_context_interface", + "//source/extensions/filters/network/generic_proxy:codec_callbacks_interface", + ], +) + +envoy_cc_library( + name = "filter_interface", + hdrs = [ + "filter.h", + ], + visibility = ["//visibility:public"], + deps = [ + ":codec_interface", + ":stream_interface", + "//source/extensions/filters/network/generic_proxy:filter_callbacks_interface", + "//source/extensions/filters/network/generic_proxy:route_interface", + ], +) diff --git a/contrib/generic_proxy/filters/network/source/interface/codec.h b/source/extensions/filters/network/generic_proxy/interface/codec.h similarity index 97% rename from contrib/generic_proxy/filters/network/source/interface/codec.h rename to source/extensions/filters/network/generic_proxy/interface/codec.h index e9ca99af5674..2b1ba02ceefc 100644 --- a/contrib/generic_proxy/filters/network/source/interface/codec.h +++ b/source/extensions/filters/network/generic_proxy/interface/codec.h @@ -5,8 +5,8 @@ #include "envoy/network/filter.h" #include "envoy/server/factory_context.h" -#include "contrib/generic_proxy/filters/network/source/interface/codec_callbacks.h" -#include "contrib/generic_proxy/filters/network/source/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/codec_callbacks.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/interface/config.h b/source/extensions/filters/network/generic_proxy/interface/filter.h similarity index 50% rename from contrib/generic_proxy/filters/network/source/interface/config.h rename to source/extensions/filters/network/generic_proxy/interface/filter.h index f3716cd1e08a..6d82082a0ca7 100644 --- a/contrib/generic_proxy/filters/network/source/interface/config.h +++ b/source/extensions/filters/network/generic_proxy/interface/filter.h @@ -1,15 +1,63 @@ #pragma once -#include "envoy/config/typed_config.h" -#include "envoy/server/factory_context.h" +#include "envoy/event/dispatcher.h" +#include "envoy/network/connection.h" +#include "envoy/stream_info/stream_info.h" -#include "contrib/generic_proxy/filters/network/source/interface/filter.h" +#include "source/extensions/filters/network/generic_proxy/filter_callbacks.h" +#include "source/extensions/filters/network/generic_proxy/interface/codec.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/route.h" namespace Envoy { namespace Extensions { namespace NetworkFilters { namespace GenericProxy { +// The status of the filter chain. +// 1. Continue: If Continue is returned, the filter chain will continue to the next filter in the +// chain. +// 2. StopIteration: If StopIteration is returned, the filter chain will stop and not continue +// to the next filter in the chain until the continueDecoding/continueEncoding is called. +enum class HeaderFilterStatus { Continue, StopIteration }; + +// The status of the filter chain. +// 1. Continue: If Continue is returned, the filter chain will continue to the next filter in the +// chain. +// 2. StopIteration: If StopIteration is returned, the filter chain will stop and not continue +// to the next filter in the chain until the continueDecoding/continueEncoding is called. +enum class CommonFilterStatus { Continue, StopIteration }; + +class DecoderFilter { +public: + virtual ~DecoderFilter() = default; + + virtual void onDestroy() PURE; + + virtual void setDecoderFilterCallbacks(DecoderFilterCallback& callbacks) PURE; + + virtual HeaderFilterStatus decodeHeaderFrame(RequestHeaderFrame& request) PURE; + virtual CommonFilterStatus decodeCommonFrame(RequestCommonFrame& request) PURE; +}; + +class EncoderFilter { +public: + virtual ~EncoderFilter() = default; + + virtual void onDestroy() PURE; + + virtual void setEncoderFilterCallbacks(EncoderFilterCallback& callbacks) PURE; + + virtual HeaderFilterStatus encodeHeaderFrame(ResponseHeaderFrame& response) PURE; + virtual CommonFilterStatus encodeCommonFrame(ResponseCommonFrame& response) PURE; +}; + +class StreamFilter : public DecoderFilter, public EncoderFilter {}; + +using DecoderFilterSharedPtr = std::shared_ptr; +using EncoderFilterSharedPtr = std::shared_ptr; +using StreamFilterSharedPtr = std::shared_ptr; + using TypedExtensionConfig = envoy::config::core::v3::TypedExtensionConfig; /** diff --git a/contrib/generic_proxy/filters/network/source/interface/stream.h b/source/extensions/filters/network/generic_proxy/interface/stream.h similarity index 95% rename from contrib/generic_proxy/filters/network/source/interface/stream.h rename to source/extensions/filters/network/generic_proxy/interface/stream.h index 41e66ca7c865..8a1b68d61d09 100644 --- a/contrib/generic_proxy/filters/network/source/interface/stream.h +++ b/source/extensions/filters/network/generic_proxy/interface/stream.h @@ -57,6 +57,11 @@ class FrameFlags { */ uint32_t frameTags() const { return frame_tags_; } + /** + * @return the raw flags of the current stream frame. + */ + uint32_t rawFlags() const { return flags_; } + /** * @return whether the current frame is the last frame of the request or response. */ @@ -78,9 +83,11 @@ class FrameFlags { /** * @return whether the current request/response is a heartbeat request/response. - * NOTE: Only the header frame's isHeartbeat() flag will be used. + * NOTE: Only the header frame's heartbeat() flag will be used. In most cases, the heartbeat + * should be handled directly by the underlying codec and should not be exposed to the generic + * proxy filter. This should only be used when we need to send the heartbeat to the peer. */ - bool isHeartbeat() const { return flags_ & FLAG_HEARTBEAT; } + bool heartbeat() const { return flags_ & FLAG_HEARTBEAT; } private: uint64_t stream_id_{}; diff --git a/contrib/generic_proxy/filters/network/source/match.cc b/source/extensions/filters/network/generic_proxy/match.cc similarity index 98% rename from contrib/generic_proxy/filters/network/source/match.cc rename to source/extensions/filters/network/generic_proxy/match.cc index a65b65f1de90..b9244deedd56 100644 --- a/contrib/generic_proxy/filters/network/source/match.cc +++ b/source/extensions/filters/network/generic_proxy/match.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/source/match.h" +#include "source/extensions/filters/network/generic_proxy/match.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/match.h b/source/extensions/filters/network/generic_proxy/match.h similarity index 96% rename from contrib/generic_proxy/filters/network/source/match.h rename to source/extensions/filters/network/generic_proxy/match.h index 36ca5d1e73f2..8eedc9c6ec2b 100644 --- a/contrib/generic_proxy/filters/network/source/match.h +++ b/source/extensions/filters/network/generic_proxy/match.h @@ -3,12 +3,12 @@ #include #include -#include "source/common/matcher/matcher.h" +#include "envoy/extensions/filters/network/generic_proxy/matcher/v3/matcher.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/matcher/v3/matcher.pb.validate.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/matcher/v3/matcher.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/matcher/v3/matcher.pb.validate.h" -#include "contrib/generic_proxy/filters/network/source/interface/stream.h" -#include "contrib/generic_proxy/filters/network/source/match_input.h" +#include "source/common/matcher/matcher.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/match_input.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/match_input.h b/source/extensions/filters/network/generic_proxy/match_input.h similarity index 96% rename from contrib/generic_proxy/filters/network/source/match_input.h rename to source/extensions/filters/network/generic_proxy/match_input.h index ccd102dbf146..1df97345049c 100644 --- a/contrib/generic_proxy/filters/network/source/match_input.h +++ b/source/extensions/filters/network/generic_proxy/match_input.h @@ -4,7 +4,7 @@ #include "envoy/stream_info/stream_info.h" -#include "contrib/generic_proxy/filters/network/source/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/proxy.cc b/source/extensions/filters/network/generic_proxy/proxy.cc similarity index 91% rename from contrib/generic_proxy/filters/network/source/proxy.cc rename to source/extensions/filters/network/generic_proxy/proxy.cc index 310058f54aaa..fad6c85444db 100644 --- a/contrib/generic_proxy/filters/network/source/proxy.cc +++ b/source/extensions/filters/network/generic_proxy/proxy.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/source/proxy.h" +#include "source/extensions/filters/network/generic_proxy/proxy.h" #include @@ -8,10 +8,8 @@ #include "source/common/config/utility.h" #include "source/common/protobuf/protobuf.h" #include "source/common/stream_info/stream_info_impl.h" - -#include "contrib/generic_proxy/filters/network/source/interface/config.h" -#include "contrib/generic_proxy/filters/network/source/interface/filter.h" -#include "contrib/generic_proxy/filters/network/source/route.h" +#include "source/extensions/filters/network/generic_proxy/interface/filter.h" +#include "source/extensions/filters/network/generic_proxy/route_impl.h" namespace Envoy { namespace Extensions { @@ -68,15 +66,15 @@ ActiveStream::ActiveStream(Filter& parent, RequestHeaderFramePtr request, parent_.stats_helper_.onRequest(); - connection_manager_tracing_config_ = parent_.config_->tracingConfig(); + conn_manager_tracing_config_ = parent_.config_->tracingConfig(); auto tracer = parent_.config_->tracingProvider(); - if (!connection_manager_tracing_config_.has_value() || !tracer.has_value()) { + if (!conn_manager_tracing_config_.has_value() || !tracer.has_value()) { return; } - auto decision = tracingDecision(connection_manager_tracing_config_.value(), parent_.runtime_); + auto decision = tracingDecision(conn_manager_tracing_config_.value(), parent_.runtime_); if (decision.traced) { stream_info_.setTraceReason(decision.reason); } @@ -86,28 +84,28 @@ ActiveStream::ActiveStream(Filter& parent, RequestHeaderFramePtr request, } Tracing::OperationName ActiveStream::operationName() const { - ASSERT(connection_manager_tracing_config_.has_value()); - return connection_manager_tracing_config_->operationName(); + ASSERT(conn_manager_tracing_config_.has_value()); + return conn_manager_tracing_config_->operationName(); } const Tracing::CustomTagMap* ActiveStream::customTags() const { - ASSERT(connection_manager_tracing_config_.has_value()); - return &connection_manager_tracing_config_->getCustomTags(); + ASSERT(conn_manager_tracing_config_.has_value()); + return &conn_manager_tracing_config_->getCustomTags(); } bool ActiveStream::verbose() const { - ASSERT(connection_manager_tracing_config_.has_value()); - return connection_manager_tracing_config_->verbose(); + ASSERT(conn_manager_tracing_config_.has_value()); + return conn_manager_tracing_config_->verbose(); } uint32_t ActiveStream::maxPathTagLength() const { - ASSERT(connection_manager_tracing_config_.has_value()); - return connection_manager_tracing_config_->maxPathTagLength(); + ASSERT(conn_manager_tracing_config_.has_value()); + return conn_manager_tracing_config_->maxPathTagLength(); } bool ActiveStream::spawnUpstreamSpan() const { - ASSERT(connection_manager_tracing_config_.has_value()); - return connection_manager_tracing_config_->spawnUpstreamSpan(); + ASSERT(conn_manager_tracing_config_.has_value()); + return conn_manager_tracing_config_->spawnUpstreamSpan(); } Envoy::Event::Dispatcher& ActiveStream::dispatcher() { @@ -147,7 +145,7 @@ bool ActiveStream::sendFrameToDownstream(const StreamFrame& frame, bool header_f void ActiveStream::sendLocalReply(Status status, absl::string_view data, ResponseUpdateFunction func) { // To ensure only one response header frame is sent for local reply. - // If there is a previsous response header but has not been sent to the downstream, + // If there is a previous response header but has not been sent to the downstream, // we should send the latest local reply to the downstream directly without any // filter processing. // If the previous response header has been sent to the downstream, it is an invalid @@ -277,18 +275,18 @@ void ActiveStream::processRequestCommonFrame() { ENVOY_LOG(debug, "Generic proxy: complete decoder filters for common frame (end_stream: {})", request_common_frame_->frameFlags().endStream()); + RequestCommonFramePtr local_common_frame = std::move(request_common_frame_); + // Reset the iterator and frame for the next common frame. + request_common_frame_ = nullptr; + decoder_filter_iter_common_ = decoder_filters_.begin(); + // Transfer the active common frame to the request stream frame handler. if (request_stream_frames_handler_ != nullptr) { - request_stream_frames_handler_->onRequestCommonFrame(std::move(request_common_frame_)); + request_stream_frames_handler_->onRequestCommonFrame(std::move(local_common_frame)); if (stream_reset_or_complete_) { stop_decoder_filter_chain_ = true; - return; } } - - // Reset the iter and frame for the next common frame. - request_common_frame_ = nullptr; - decoder_filter_iter_common_ = decoder_filters_.begin(); } void ActiveStream::processResponseHeaderFrame() { @@ -356,15 +354,15 @@ void ActiveStream::processResponseCommonFrame() { ENVOY_LOG(debug, "Generic proxy: complete encoder filters for common frame (end_stream: {})", response_common_frame_->frameFlags().endStream()); + auto local_common_frame = std::move(response_common_frame_); + // Reset the iterator and frame for the next common frame. + response_common_frame_ = nullptr; + encoder_filter_iter_common_ = encoder_filters_.begin(); + // Send the common frame to downstream. - if (!sendFrameToDownstream(*response_common_frame_, false)) { + if (!sendFrameToDownstream(*local_common_frame, false)) { stop_encoder_filter_chain_ = true; - return; } - - // Reset the iter and frame for the next common frame. - response_common_frame_ = nullptr; - encoder_filter_iter_common_ = encoder_filters_.begin(); }; // Handle the special case where no filter is added to the encoder filter chain. @@ -437,16 +435,19 @@ void ActiveStream::continueDecoding() { return; } - // Handle the active request common frame if exists. + // Handle the active request common frame first if exists. if (request_common_frame_ != nullptr) { processRequestCommonFrame(); } - if (stop_decoder_filter_chain_) { - return; - } // Handle the other request common frames if exists. while (!request_common_frames_.empty()) { + // Check the stop flag first because the filter chain may be + // stopped by the previous active request frame. + if (stop_decoder_filter_chain_) { + break; + } + ASSERT(request_common_frame_ == nullptr); ASSERT(decoder_filter_iter_common_ == decoder_filters_.begin()); @@ -456,9 +457,6 @@ void ActiveStream::continueDecoding() { request_common_frame_ = std::move(frame); processRequestCommonFrame(); - if (stop_decoder_filter_chain_) { - break; - } } } @@ -542,16 +540,19 @@ void ActiveStream::continueEncoding() { return; } - // Handle the active response common frame if exists. + // Handle the active response common frame first if exists. if (response_common_frame_ != nullptr) { processResponseCommonFrame(); } - if (stop_encoder_filter_chain_) { - return; - } // Handle the other response common frames if exists. while (!response_common_frames_.empty()) { + // Check the stop flag first because the filter chain may be + // stopped by the previous active response frame. + if (stop_encoder_filter_chain_) { + break; + } + ASSERT(response_common_frame_ == nullptr); ASSERT(encoder_filter_iter_common_ == encoder_filters_.begin()); @@ -561,9 +562,6 @@ void ActiveStream::continueEncoding() { response_common_frame_ = std::move(frame); processResponseCommonFrame(); - if (stop_encoder_filter_chain_) { - break; - } } } @@ -614,7 +612,8 @@ void ActiveStream::completeStream(absl::optional re stream_info_.onRequestComplete(); bool error_reply = false; - // This response frame may be nullptr if the request is one-way. + // This response frame may be nullptr if the request is one-way or the response is not + // sent to the downstream. if (response_header_frame_ != nullptr) { error_reply = !response_header_frame_->status().ok(); } @@ -656,6 +655,12 @@ Envoy::Network::FilterStatus Filter::onData(Envoy::Buffer::Instance& data, bool void Filter::onDecodingSuccess(RequestHeaderFramePtr request_header_frame, absl::optional start_time) { + if (request_header_frame == nullptr) { + ENVOY_LOG(error, "generic proxy: request header frame from codec is null"); + onDecodingFailure(); + return; + } + const uint64_t stream_id = request_header_frame->frameFlags().streamId(); if (!frame_handlers_.empty()) { // Quick empty check to avoid the map lookup. @@ -670,6 +675,12 @@ void Filter::onDecodingSuccess(RequestHeaderFramePtr request_header_frame, } void Filter::onDecodingSuccess(RequestCommonFramePtr request_common_frame) { + if (request_common_frame == nullptr) { + ENVOY_LOG(error, "generic proxy: request common frame from codec is null"); + onDecodingFailure(); + return; + } + const uint64_t stream_id = request_common_frame->frameFlags().streamId(); // One existing stream expects this frame. if (auto iter = frame_handlers_.find(stream_id); iter != frame_handlers_.end()) { @@ -705,15 +716,8 @@ OptRef Filter::connection() { } void Filter::registerFrameHandler(uint64_t stream_id, ActiveStream* raw_stream) { - // If the stream expects variable length frames, then add it to the frame - // handler map. - // This map entry will be removed when the request or response end frame is - // received. - if (frame_handlers_.contains(stream_id)) { - ENVOY_LOG(error, "generic proxy: repetitive stream id: {} at same time", stream_id); - onDecodingFailure(); - return; - } + // Repeated stream id will be detected in the onDecodingSuccess method. + ASSERT(frame_handlers_.find(stream_id) == frame_handlers_.end()); frame_handlers_[stream_id] = raw_stream; } diff --git a/contrib/generic_proxy/filters/network/source/proxy.h b/source/extensions/filters/network/generic_proxy/proxy.h similarity index 93% rename from contrib/generic_proxy/filters/network/source/proxy.h rename to source/extensions/filters/network/generic_proxy/proxy.h index 5b37e9e0f5eb..27c1f63b9d58 100644 --- a/contrib/generic_proxy/filters/network/source/proxy.h +++ b/source/extensions/filters/network/generic_proxy/proxy.h @@ -5,6 +5,9 @@ #include #include "envoy/config/core/v3/extension.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.validate.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/route.pb.h" #include "envoy/network/connection.h" #include "envoy/network/filter.h" #include "envoy/server/factory_context.h" @@ -18,19 +21,15 @@ #include "source/common/stream_info/stream_info_impl.h" #include "source/common/tracing/tracer_config_impl.h" #include "source/common/tracing/tracer_impl.h" - -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.validate.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/route.pb.h" -#include "contrib/generic_proxy/filters/network/source/interface/filter.h" -#include "contrib/generic_proxy/filters/network/source/interface/proxy_config.h" -#include "contrib/generic_proxy/filters/network/source/interface/route.h" -#include "contrib/generic_proxy/filters/network/source/interface/stream.h" -#include "contrib/generic_proxy/filters/network/source/rds.h" -#include "contrib/generic_proxy/filters/network/source/rds_impl.h" -#include "contrib/generic_proxy/filters/network/source/route.h" -#include "contrib/generic_proxy/filters/network/source/stats.h" -#include "contrib/generic_proxy/filters/network/source/tracing.h" +#include "source/extensions/filters/network/generic_proxy/interface/filter.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/proxy_config.h" +#include "source/extensions/filters/network/generic_proxy/rds.h" +#include "source/extensions/filters/network/generic_proxy/rds_impl.h" +#include "source/extensions/filters/network/generic_proxy/route.h" +#include "source/extensions/filters/network/generic_proxy/route_impl.h" +#include "source/extensions/filters/network/generic_proxy/stats.h" +#include "source/extensions/filters/network/generic_proxy/tracing.h" namespace Envoy { namespace Extensions { @@ -146,7 +145,6 @@ class ActiveStream : public FilterChainManager, } return nullptr; } - const StreamInfo::StreamInfo& streamInfo() const override { return parent_.stream_info_; } StreamInfo::StreamInfo& streamInfo() override { return parent_.stream_info_; } Tracing::Span& activeSpan() override { return parent_.activeSpan(); } OptRef tracingConfig() const override { return parent_.tracingConfig(); } @@ -276,7 +274,7 @@ class ActiveStream : public FilterChainManager, } OptRef tracingConfig() const { - if (connection_manager_tracing_config_.has_value()) { + if (conn_manager_tracing_config_.has_value()) { return {*this}; } return {}; @@ -349,7 +347,7 @@ class ActiveStream : public FilterChainManager, StreamInfo::StreamInfoImpl stream_info_; - OptRef connection_manager_tracing_config_; + OptRef conn_manager_tracing_config_; Tracing::SpanPtr active_span_; }; using ActiveStreamPtr = std::unique_ptr; diff --git a/contrib/generic_proxy/filters/network/source/interface/proxy_config.h b/source/extensions/filters/network/generic_proxy/proxy_config.h similarity index 79% rename from contrib/generic_proxy/filters/network/source/interface/proxy_config.h rename to source/extensions/filters/network/generic_proxy/proxy_config.h index a744ae06c448..a91a35068dd6 100644 --- a/contrib/generic_proxy/filters/network/source/interface/proxy_config.h +++ b/source/extensions/filters/network/generic_proxy/proxy_config.h @@ -3,12 +3,12 @@ #include "envoy/tracing/trace_config.h" #include "envoy/tracing/tracer.h" -#include "contrib/generic_proxy/filters/network/source/access_log.h" -#include "contrib/generic_proxy/filters/network/source/interface/codec.h" -#include "contrib/generic_proxy/filters/network/source/interface/filter.h" -#include "contrib/generic_proxy/filters/network/source/interface/route.h" -#include "contrib/generic_proxy/filters/network/source/match_input.h" -#include "contrib/generic_proxy/filters/network/source/stats.h" +#include "source/extensions/filters/network/generic_proxy/access_log.h" +#include "source/extensions/filters/network/generic_proxy/interface/codec.h" +#include "source/extensions/filters/network/generic_proxy/interface/filter.h" +#include "source/extensions/filters/network/generic_proxy/match_input.h" +#include "source/extensions/filters/network/generic_proxy/route.h" +#include "source/extensions/filters/network/generic_proxy/stats.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/rds.h b/source/extensions/filters/network/generic_proxy/rds.h similarity index 60% rename from contrib/generic_proxy/filters/network/source/rds.h rename to source/extensions/filters/network/generic_proxy/rds.h index 301239728989..e450f4f26626 100644 --- a/contrib/generic_proxy/filters/network/source/rds.h +++ b/source/extensions/filters/network/generic_proxy/rds.h @@ -2,12 +2,12 @@ #include -#include "source/common/rds/common/route_config_provider_manager.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.validate.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/route.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/route.pb.validate.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.validate.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/route.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/route.pb.validate.h" +#include "source/common/rds/common/route_config_provider_manager.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/rds_impl.h b/source/extensions/filters/network/generic_proxy/rds_impl.h similarity index 58% rename from contrib/generic_proxy/filters/network/source/rds_impl.h rename to source/extensions/filters/network/generic_proxy/rds_impl.h index 39248e9c2343..f600a3d7adfd 100644 --- a/contrib/generic_proxy/filters/network/source/rds_impl.h +++ b/source/extensions/filters/network/generic_proxy/rds_impl.h @@ -2,13 +2,13 @@ #include -#include "source/common/rds/common/route_config_provider_manager_impl.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.validate.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/route.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/route.pb.validate.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.validate.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/route.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/route.pb.validate.h" -#include "contrib/generic_proxy/filters/network/source/route.h" +#include "source/common/rds/common/route_config_provider_manager_impl.h" +#include "source/extensions/filters/network/generic_proxy/route_impl.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/interface/route.h b/source/extensions/filters/network/generic_proxy/route.h similarity index 93% rename from contrib/generic_proxy/filters/network/source/interface/route.h rename to source/extensions/filters/network/generic_proxy/route.h index 9fa58ae960c7..5f705d61941d 100644 --- a/contrib/generic_proxy/filters/network/source/interface/route.h +++ b/source/extensions/filters/network/generic_proxy/route.h @@ -7,8 +7,8 @@ #include "envoy/rds/config.h" #include "envoy/router/router.h" -#include "contrib/generic_proxy/filters/network/source/interface/stream.h" -#include "contrib/generic_proxy/filters/network/source/match_input.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/match_input.h" namespace Envoy { namespace Extensions { @@ -22,7 +22,7 @@ class RouteSpecificFilterConfig { using RouteSpecificFilterConfigConstSharedPtr = std::shared_ptr; /** - * Interface of typed metadata factory. Reuse the same interface as the HTTP's router filter because + * Interface of typed metadata factory. Reuse the same interface as the HTTP router filter because * part of these abstractions are protocol independent. */ using RouteTypedMetadataFactory = Envoy::Router::HttpRouteTypedMetadataFactory; diff --git a/contrib/generic_proxy/filters/network/source/route.cc b/source/extensions/filters/network/generic_proxy/route_impl.cc similarity index 97% rename from contrib/generic_proxy/filters/network/source/route.cc rename to source/extensions/filters/network/generic_proxy/route_impl.cc index e7524d0c80cc..91eb7635cb41 100644 --- a/contrib/generic_proxy/filters/network/source/route.cc +++ b/source/extensions/filters/network/generic_proxy/route_impl.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/source/route.h" +#include "source/extensions/filters/network/generic_proxy/route_impl.h" #include @@ -7,9 +7,9 @@ #include "source/common/common/assert.h" #include "source/common/common/matchers.h" #include "source/common/config/utility.h" +#include "source/extensions/filters/network/generic_proxy/interface/filter.h" +#include "source/extensions/filters/network/generic_proxy/route.h" -#include "contrib/generic_proxy/filters/network/source/interface/config.h" -#include "contrib/generic_proxy/filters/network/source/interface/route.h" #include "interface/stream.h" namespace Envoy { diff --git a/contrib/generic_proxy/filters/network/source/route.h b/source/extensions/filters/network/generic_proxy/route_impl.h similarity index 91% rename from contrib/generic_proxy/filters/network/source/route.h rename to source/extensions/filters/network/generic_proxy/route_impl.h index eee27ef6704c..62118b8856f6 100644 --- a/contrib/generic_proxy/filters/network/source/route.h +++ b/source/extensions/filters/network/generic_proxy/route_impl.h @@ -6,20 +6,19 @@ #include "envoy/config/core/v3/base.pb.h" #include "envoy/config/route/v3/route_components.pb.h" #include "envoy/config/typed_metadata.h" +#include "envoy/extensions/filters/network/generic_proxy/action/v3/action.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/action/v3/action.pb.validate.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/route.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/route.pb.validate.h" #include "envoy/server/factory_context.h" #include "source/common/common/matchers.h" #include "source/common/config/metadata.h" #include "source/common/http/header_utility.h" #include "source/common/matcher/matcher.h" - -#include "contrib/envoy/extensions/filters/network/generic_proxy/action/v3/action.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/action/v3/action.pb.validate.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/route.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/route.pb.validate.h" -#include "contrib/generic_proxy/filters/network/source/interface/route.h" -#include "contrib/generic_proxy/filters/network/source/interface/stream.h" -#include "contrib/generic_proxy/filters/network/source/match_input.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/match_input.h" +#include "source/extensions/filters/network/generic_proxy/route.h" namespace Envoy { namespace Extensions { @@ -139,6 +138,8 @@ class RouteMatcherImpl : public RouteMatcher, Logger::Loggable, std::greater<>>; @@ -147,8 +148,6 @@ class RouteMatcherImpl : public RouteMatcher, Logger::Loggable virtual_hosts_; diff --git a/contrib/generic_proxy/filters/network/source/router/BUILD b/source/extensions/filters/network/generic_proxy/router/BUILD similarity index 56% rename from contrib/generic_proxy/filters/network/source/router/BUILD rename to source/extensions/filters/network/generic_proxy/router/BUILD index e1ea8a338e36..d3e4d60b729c 100644 --- a/contrib/generic_proxy/filters/network/source/router/BUILD +++ b/source/extensions/filters/network/generic_proxy/router/BUILD @@ -1,13 +1,13 @@ load( "//bazel:envoy_build_system.bzl", - "envoy_cc_contrib_extension", + "envoy_cc_extension", "envoy_cc_library", - "envoy_contrib_package", + "envoy_extension_package", ) licenses(["notice"]) # Apache 2 -envoy_contrib_package() +envoy_extension_package() envoy_cc_library( name = "router_lib", @@ -20,10 +20,6 @@ envoy_cc_library( "upstream.h", ], deps = [ - "//contrib/generic_proxy/filters/network/source:tracing_lib", - "//contrib/generic_proxy/filters/network/source/interface:codec_interface", - "//contrib/generic_proxy/filters/network/source/interface:config_interface", - "//contrib/generic_proxy/filters/network/source/interface:filter_interface", "//source/common/buffer:buffer_lib", "//source/common/common:linked_object", "//source/common/common:minimal_logger_lib", @@ -32,12 +28,15 @@ envoy_cc_library( "//source/common/stream_info:stream_info_lib", "//source/common/tracing:tracer_lib", "//source/common/upstream:load_balancer_context_base_lib", + "//source/extensions/filters/network/generic_proxy:tracing_lib", + "//source/extensions/filters/network/generic_proxy/interface:codec_interface", + "//source/extensions/filters/network/generic_proxy/interface:filter_interface", "@com_github_google_quiche//:quiche_common_lib", - "@envoy_api//contrib/envoy/extensions/filters/network/generic_proxy/router/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/filters/network/generic_proxy/router/v3:pkg_cc_proto", ], ) -envoy_cc_contrib_extension( +envoy_cc_extension( name = "config", srcs = [ "config.cc", @@ -47,8 +46,8 @@ envoy_cc_contrib_extension( ], deps = [ ":router_lib", - "//contrib/generic_proxy/filters/network/source/interface:config_interface", "//envoy/registry", - "@envoy_api//contrib/envoy/extensions/filters/network/generic_proxy/router/v3:pkg_cc_proto", + "//source/extensions/filters/network/generic_proxy/interface:filter_interface", + "@envoy_api//envoy/extensions/filters/network/generic_proxy/router/v3:pkg_cc_proto", ], ) diff --git a/contrib/generic_proxy/filters/network/source/router/config.cc b/source/extensions/filters/network/generic_proxy/router/config.cc similarity index 92% rename from contrib/generic_proxy/filters/network/source/router/config.cc rename to source/extensions/filters/network/generic_proxy/router/config.cc index 053950c21d1f..4294c8928100 100644 --- a/contrib/generic_proxy/filters/network/source/router/config.cc +++ b/source/extensions/filters/network/generic_proxy/router/config.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/source/router/config.h" +#include "source/extensions/filters/network/generic_proxy/router/config.h" #include "envoy/registry/registry.h" diff --git a/contrib/generic_proxy/filters/network/source/router/config.h b/source/extensions/filters/network/generic_proxy/router/config.h similarity index 78% rename from contrib/generic_proxy/filters/network/source/router/config.h rename to source/extensions/filters/network/generic_proxy/router/config.h index 04de5e949fa8..3e0995023ec9 100644 --- a/contrib/generic_proxy/filters/network/source/router/config.h +++ b/source/extensions/filters/network/generic_proxy/router/config.h @@ -1,9 +1,10 @@ #pragma once -#include "contrib/envoy/extensions/filters/network/generic_proxy/router/v3/router.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/router/v3/router.pb.validate.h" -#include "contrib/generic_proxy/filters/network/source/interface/config.h" -#include "contrib/generic_proxy/filters/network/source/router/router.h" +#include "envoy/extensions/filters/network/generic_proxy/router/v3/router.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/router/v3/router.pb.validate.h" + +#include "source/extensions/filters/network/generic_proxy/interface/filter.h" +#include "source/extensions/filters/network/generic_proxy/router/router.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/router/router.cc b/source/extensions/filters/network/generic_proxy/router/router.cc similarity index 91% rename from contrib/generic_proxy/filters/network/source/router/router.cc rename to source/extensions/filters/network/generic_proxy/router/router.cc index 8ebf60642c46..c219aef86db4 100644 --- a/contrib/generic_proxy/filters/network/source/router/router.cc +++ b/source/extensions/filters/network/generic_proxy/router/router.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/source/router/router.h" +#include "source/extensions/filters/network/generic_proxy/router/router.h" #include @@ -9,9 +9,8 @@ #include "source/common/config/well_known_names.h" #include "source/common/router/metadatamatchcriteria_impl.h" #include "source/common/tracing/tracer_impl.h" - -#include "contrib/generic_proxy/filters/network/source/interface/filter.h" -#include "contrib/generic_proxy/filters/network/source/tracing.h" +#include "source/extensions/filters/network/generic_proxy/interface/filter.h" +#include "source/extensions/filters/network/generic_proxy/tracing.h" namespace Envoy { namespace Extensions { @@ -48,7 +47,7 @@ UpstreamRequest::UpstreamRequest(RouterFilter& parent, FrameFlags header_frame_f stream_id_(header_frame_flags.streamId()), expects_response_(!header_frame_flags.oneWayStream()) { - // Host is known at this point and set the initial upstream host. + // Host is known at this point and set the upstream host. onUpstreamHostSelected(generic_upstream_->upstreamHost()); auto filter_callbacks = parent_.callbacks_; @@ -124,10 +123,10 @@ void UpstreamRequest::clearStream(bool close_connection) { } void UpstreamRequest::deferredDelete() { - if (inserted()) { - // Remove this stream from the parent's list of upstream requests and delete it at - // next event loop iteration. - parent_.callbacks_->dispatcher().deferredDelete(removeFromList(parent_.upstream_requests_)); + if (parent_.upstream_request_.get() == this) { + // Remove this stream from the parent and delete it at next event loop iteration. + parent_.callbacks_->dispatcher().deferredDelete(std::move(parent_.upstream_request_)); + parent_.upstream_request_.reset(); } } @@ -232,6 +231,8 @@ void UpstreamRequest::onDecodingSuccess(ResponseHeaderFramePtr response_header_f absl::optional start_time) { if (response_stream_header_received_) { ENVOY_LOG(error, "upstream request: multiple StreamResponse received"); + resetStream(StreamResetReason::ProtocolError, {}); + return; } response_stream_header_received_ = true; @@ -288,23 +289,14 @@ void UpstreamRequest::onConnectionClose(Network::ConnectionEvent event) { return; } - switch (event) { - case Network::ConnectionEvent::LocalClose: - resetStream(StreamResetReason::LocalReset, {}); - break; - case Network::ConnectionEvent::RemoteClose: + if (event == Network::ConnectionEvent::RemoteClose) { resetStream(StreamResetReason::ConnectionTermination, {}); - break; - default: - break; + } else if (event == Network::ConnectionEvent::LocalClose) { + resetStream(StreamResetReason::LocalReset, {}); } } void UpstreamRequest::onUpstreamHostSelected(Upstream::HostDescriptionConstSharedPtr host) { - if (host == nullptr || host == upstream_info_->upstream_host_) { - return; - } - ENVOY_LOG(debug, "upstream request: selected host {}", host->address()->asStringView()); upstream_info_->upstream_host_ = std::move(host); } @@ -342,6 +334,8 @@ void RouterFilter::onUpstreamRequestReset(UpstreamRequest&, StreamResetReason re return; } + ASSERT(upstream_request_ == nullptr); + // Retry is the upstream request is reset because of the connection failure or the // protocol error. if (couldRetry(reason)) { @@ -349,7 +343,9 @@ void RouterFilter::onUpstreamRequestReset(UpstreamRequest&, StreamResetReason re return; } - resetStream(reason, reason_detail); + // Complete the filter/request and send the local reply to the downstream if no retry. + const auto [view, flag] = resetReasonToViewAndFlag(reason); + completeAndSendLocalReply(Status(StatusCode::kUnavailable, view), reason_detail, flag); } void RouterFilter::onFilterComplete() { @@ -360,8 +356,8 @@ void RouterFilter::onFilterComplete() { filter_complete_ = true; // Clean up all pending upstream requests. - while (!upstream_requests_.empty()) { - auto* upstream_request = upstream_requests_.back().get(); + if (upstream_request_ != nullptr) { + auto* upstream_request = upstream_request_.get(); // Remove the upstream request from the upstream request list first. The resetStream() will // also do this. But in some corner cases, the upstream request is already reset and triggers // the router filter to call onFilterComplete(). But note because the upstream request is @@ -399,16 +395,6 @@ void RouterFilter::onTimeout() { void RouterFilter::onDestroy() { onFilterComplete(); } -void RouterFilter::resetStream(StreamResetReason reason, absl::string_view reason_detail) { - // Ensure this method is called only once strictly and never called after - // onFilterComplete(). - if (filter_complete_) { - return; - } - const auto [view, flag] = resetReasonToViewAndFlag(reason); - completeAndSendLocalReply(Status(StatusCode::kUnavailable, view), reason_detail, flag); -} - void RouterFilter::completeAndSendLocalReply(absl::Status status, absl::string_view details, absl::optional flag) { if (flag.has_value()) { @@ -419,6 +405,8 @@ void RouterFilter::completeAndSendLocalReply(absl::Status status, absl::string_v } void RouterFilter::kickOffNewUpstreamRequest() { + ASSERT(upstream_request_ == nullptr); + num_retries_++; const auto& cluster_name = route_entry_->clusterName(); @@ -449,23 +437,18 @@ void RouterFilter::kickOffNewUpstreamRequest() { return; } - auto upstream_request = std::make_unique(*this, request_stream_->frameFlags(), - std::move(generic_upstream)); - auto raw_upstream_request = upstream_request.get(); - LinkedList::moveIntoList(std::move(upstream_request), upstream_requests_); - raw_upstream_request->startStream(); + upstream_request_ = std::make_unique(*this, request_stream_->frameFlags(), + std::move(generic_upstream)); + upstream_request_->startStream(); } void RouterFilter::onRequestCommonFrame(RequestCommonFramePtr frame) { mayRequestStreamEnd(frame->frameFlags().endStream()); request_stream_frames_.emplace_back(std::move(frame)); - - if (upstream_requests_.empty()) { - return; + if (upstream_request_ != nullptr) { + upstream_request_->sendCommonFrameToUpstream(); } - - upstream_requests_.front()->sendCommonFrameToUpstream(); } HeaderFilterStatus RouterFilter::decodeHeaderFrame(StreamRequest& request) { diff --git a/contrib/generic_proxy/filters/network/source/router/router.h b/source/extensions/filters/network/generic_proxy/router/router.h similarity index 91% rename from contrib/generic_proxy/filters/network/source/router/router.h rename to source/extensions/filters/network/generic_proxy/router/router.h index a2effd2c1db6..6907e1600aab 100644 --- a/contrib/generic_proxy/filters/network/source/router/router.h +++ b/source/extensions/filters/network/generic_proxy/router/router.h @@ -2,6 +2,8 @@ #include +#include "envoy/extensions/filters/network/generic_proxy/router/v3/router.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/router/v3/router.pb.validate.h" #include "envoy/network/connection.h" #include "envoy/server/factory_context.h" @@ -9,13 +11,11 @@ #include "source/common/common/linked_object.h" #include "source/common/stream_info/stream_info_impl.h" #include "source/common/upstream/load_balancer_context_base.h" +#include "source/extensions/filters/network/generic_proxy/interface/codec.h" +#include "source/extensions/filters/network/generic_proxy/interface/filter.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/router/upstream.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/router/v3/router.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/router/v3/router.pb.validate.h" -#include "contrib/generic_proxy/filters/network/source/interface/codec.h" -#include "contrib/generic_proxy/filters/network/source/interface/filter.h" -#include "contrib/generic_proxy/filters/network/source/interface/stream.h" -#include "contrib/generic_proxy/filters/network/source/router/upstream.h" #include "quiche/common/quiche_linked_hash_map.h" namespace Envoy { @@ -154,7 +154,7 @@ class RouterFilter : public DecoderFilter, max_retries_ = route_entry_ ? route_entry->retryPolicy().numRetries() : 1; } - size_t upstreamRequestsSize() { return upstream_requests_.size(); } + size_t upstreamRequestsSize() { return upstream_request_ != nullptr ? 1 : 0; } // Upstream::LoadBalancerContextBase const Envoy::Router::MetadataMatchCriteria* metadataMatchCriteria() override; @@ -168,7 +168,6 @@ class RouterFilter : public DecoderFilter, friend class UpstreamManagerImpl; void kickOffNewUpstreamRequest(); - void resetStream(StreamResetReason reason, absl::string_view reason_detail); void completeAndSendLocalReply(absl::Status status, absl::string_view details, absl::optional flag = {}); @@ -204,7 +203,9 @@ class RouterFilter : public DecoderFilter, Envoy::Router::MetadataMatchCriteriaConstPtr metadata_match_; - std::list upstream_requests_; + // Only allow one upstream request at a time. This is a simplification of the code that may be + // changed in the future. + UpstreamRequestPtr upstream_request_; Envoy::Event::TimerPtr timeout_timer_; DecoderFilterCallback* callbacks_{}; diff --git a/contrib/generic_proxy/filters/network/source/router/upstream.cc b/source/extensions/filters/network/generic_proxy/router/upstream.cc similarity index 92% rename from contrib/generic_proxy/filters/network/source/router/upstream.cc rename to source/extensions/filters/network/generic_proxy/router/upstream.cc index d99560f2397f..0cbef86bddea 100644 --- a/contrib/generic_proxy/filters/network/source/router/upstream.cc +++ b/source/extensions/filters/network/generic_proxy/router/upstream.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/source/router/upstream.h" +#include "source/extensions/filters/network/generic_proxy/router/upstream.h" namespace Envoy { namespace Extensions { @@ -32,13 +32,13 @@ void SharedRequestManager::onDecodingSuccess(ResponseHeaderFramePtr header_frame const bool end_stream = header_frame->frameFlags().endStream(); auto it = pending_requests_.find(stream_id); - auto cb = it->second; - if (it == pending_requests_.end()) { - ENVOY_LOG(error, "generic proxy: id {} not found for frame", stream_id); + ENVOY_LOG(error, "generic proxy: id {} not found for header frame", stream_id); return; } + auto cb = it->second; + // If the response stream is end, remove the callbacks from the map because we // no longer need to track the response. if (end_stream) { @@ -52,13 +52,13 @@ void SharedRequestManager::onDecodingSuccess(ResponseCommonFramePtr common_frame const bool end_stream = common_frame->frameFlags().endStream(); auto it = pending_requests_.find(stream_id); - auto cb = it->second; - if (it == pending_requests_.end()) { - ENVOY_LOG(error, "generic proxy: id {} not found for frame", stream_id); + ENVOY_LOG(error, "generic proxy: id {} not found for common frame", stream_id); return; } + auto cb = it->second; + // If the response stream is end, remove the callbacks from the map because we // no longer need to track the response. if (end_stream) { @@ -87,10 +87,7 @@ void UniqueRequestManager::appendUpstreamRequest(uint64_t, pending_request_ = pending_request; } -void UniqueRequestManager::removeUpstreamRequest(uint64_t) { - ASSERT(pending_request_ != nullptr); - pending_request_ = nullptr; -} +void UniqueRequestManager::removeUpstreamRequest(uint64_t) { pending_request_ = nullptr; } void UniqueRequestManager::onConnectionClose(Network::ConnectionEvent event) { if (pending_request_ != nullptr) { @@ -219,17 +216,15 @@ void BoundGenericUpstream::cleanUp(bool close_connection) { } void BoundGenericUpstream::onEvent(Network::ConnectionEvent event) { - if (event == Network::ConnectionEvent::Connected || - event == Network::ConnectionEvent::ConnectedZeroRtt) { - return; - } + if (event == Network::ConnectionEvent::LocalClose || + event == Network::ConnectionEvent::RemoteClose) { + if (encoder_decoder_ != nullptr) { + encoder_decoder_->onConnectionClose(event); + } - if (encoder_decoder_ != nullptr) { - encoder_decoder_->onConnectionClose(event); + // If the downstream connection is not closed, close it. + downstream_conn_.close(Network::ConnectionCloseType::FlushWrite); } - - // If the downstream connection is not closed, close it. - downstream_conn_.close(Network::ConnectionCloseType::FlushWrite); } void BoundGenericUpstream::onUpstreamSuccess() { @@ -286,25 +281,25 @@ void OwnedGenericUpstream::appendUpstreamRequest(uint64_t, } void OwnedGenericUpstream::removeUpstreamRequest(uint64_t) { - ASSERT(upstream_request_ != nullptr); - upstream_request_ = nullptr; if (encoder_decoder_ != nullptr) { encoder_decoder_->removeUpstreamRequest({}); } + upstream_request_ = nullptr; } void OwnedGenericUpstream::onEvent(Network::ConnectionEvent event) { - if (event == Network::ConnectionEvent::Connected || - event == Network::ConnectionEvent::ConnectedZeroRtt) { - return; - } - if (encoder_decoder_ != nullptr) { - encoder_decoder_->onConnectionClose(event); + if (event == Network::ConnectionEvent::LocalClose || + event == Network::ConnectionEvent::RemoteClose) { + if (encoder_decoder_ != nullptr) { + encoder_decoder_->onConnectionClose(event); + } } } void OwnedGenericUpstream::onUpstreamSuccess() { ASSERT(upstream_request_ != nullptr); + ASSERT(encoder_decoder_ != nullptr); + auto upstream_request = upstream_request_; upstream_request_ = nullptr; diff --git a/contrib/generic_proxy/filters/network/source/router/upstream.h b/source/extensions/filters/network/generic_proxy/router/upstream.h similarity index 98% rename from contrib/generic_proxy/filters/network/source/router/upstream.h rename to source/extensions/filters/network/generic_proxy/router/upstream.h index dd65a04613c5..2c3cc97038c8 100644 --- a/contrib/generic_proxy/filters/network/source/router/upstream.h +++ b/source/extensions/filters/network/generic_proxy/router/upstream.h @@ -5,8 +5,8 @@ #include "envoy/network/connection.h" #include "source/common/buffer/buffer_impl.h" +#include "source/extensions/filters/network/generic_proxy/interface/codec.h" -#include "contrib/generic_proxy/filters/network/source/interface/codec.h" #include "quiche/common/quiche_linked_hash_map.h" namespace Envoy { @@ -350,13 +350,13 @@ class BoundGenericUpstream : public BoundGenericUpstreamBase, EventWatcher connection_event_watcher_; absl::optional upstream_conn_ok_; - // This ensure the requests that are waiting upstream connectin will be list in the order in + // This ensure the requests that are waiting upstream connection will be list in the order in // which the requests were received. By this way, the protocols that require the requests and // responses be handled in pipeline could works properly. // Note we need not do that for the requests that are waiting responses. Because we assume that // the clients of these protocols will send requests in order. Then when the connection is ready, // generic proxy will send requests to server in order. Finally, the upstream server of these - // protocols will send respnoses in order. We also assume that the L7 filter chain of these + // protocols will send responses in order. We also assume that the L7 filter chain of these // protocols will not change the processing order. using LinkedAbslHashMap = quiche::QuicheLinkedHashMap; LinkedAbslHashMap pending_requests_; diff --git a/contrib/generic_proxy/filters/network/source/stats.cc b/source/extensions/filters/network/generic_proxy/stats.cc similarity index 98% rename from contrib/generic_proxy/filters/network/source/stats.cc rename to source/extensions/filters/network/generic_proxy/stats.cc index dd9e61977810..1c008c196331 100644 --- a/contrib/generic_proxy/filters/network/source/stats.cc +++ b/source/extensions/filters/network/generic_proxy/stats.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/source/stats.h" +#include "source/extensions/filters/network/generic_proxy/stats.h" #include "source/common/stream_info/utility.h" diff --git a/contrib/generic_proxy/filters/network/source/stats.h b/source/extensions/filters/network/generic_proxy/stats.h similarity index 100% rename from contrib/generic_proxy/filters/network/source/stats.h rename to source/extensions/filters/network/generic_proxy/stats.h diff --git a/contrib/generic_proxy/filters/network/source/tracing.cc b/source/extensions/filters/network/generic_proxy/tracing.cc similarity index 93% rename from contrib/generic_proxy/filters/network/source/tracing.cc rename to source/extensions/filters/network/generic_proxy/tracing.cc index 10d0d7bd4af4..2f712ea57c4c 100644 --- a/contrib/generic_proxy/filters/network/source/tracing.cc +++ b/source/extensions/filters/network/generic_proxy/tracing.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/source/tracing.h" +#include "source/extensions/filters/network/generic_proxy/tracing.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/source/tracing.h b/source/extensions/filters/network/generic_proxy/tracing.h similarity index 92% rename from contrib/generic_proxy/filters/network/source/tracing.h rename to source/extensions/filters/network/generic_proxy/tracing.h index 43ed9f59dec9..874d403535d4 100644 --- a/contrib/generic_proxy/filters/network/source/tracing.h +++ b/source/extensions/filters/network/generic_proxy/tracing.h @@ -2,7 +2,7 @@ #include "envoy/tracing/trace_context.h" -#include "contrib/generic_proxy/filters/network/source/interface/stream.h" +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" namespace Envoy { namespace Extensions { diff --git a/contrib/generic_proxy/filters/network/test/BUILD b/test/extensions/filters/network/generic_proxy/BUILD similarity index 53% rename from contrib/generic_proxy/filters/network/test/BUILD rename to test/extensions/filters/network/generic_proxy/BUILD index 9c6e7e566c6e..c4b949330d36 100644 --- a/contrib/generic_proxy/filters/network/test/BUILD +++ b/test/extensions/filters/network/generic_proxy/BUILD @@ -2,12 +2,12 @@ load( "//bazel:envoy_build_system.bzl", "envoy_cc_test", "envoy_cc_test_library", - "envoy_contrib_package", + "envoy_package", ) licenses(["notice"]) # Apache 2 -envoy_contrib_package() +envoy_package() envoy_cc_test_library( name = "fake_codec_lib", @@ -16,8 +16,9 @@ envoy_cc_test_library( ], hdrs = ["fake_codec.h"], deps = [ - "//contrib/generic_proxy/filters/network/source/interface:codec_interface", "//source/common/buffer:buffer_lib", + "//source/extensions/filters/network/generic_proxy:access_log_lib", + "//source/extensions/filters/network/generic_proxy/interface:codec_interface", ], ) @@ -28,10 +29,10 @@ envoy_cc_test( ], deps = [ ":fake_codec_lib", - "//contrib/generic_proxy/filters/network/source:route_lib", - "//contrib/generic_proxy/filters/network/test/mocks:filter_mocks", - "//contrib/generic_proxy/filters/network/test/mocks:route_mocks", "//source/common/buffer:buffer_lib", + "//source/extensions/filters/network/generic_proxy:route_lib", + "//test/extensions/filters/network/generic_proxy/mocks:filter_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:route_mocks", "//test/mocks/server:factory_context_mocks", "//test/test_common:registry_lib", "//test/test_common:test_runtime_lib", @@ -46,11 +47,11 @@ envoy_cc_test( ], deps = [ ":fake_codec_lib", - "//contrib/generic_proxy/filters/network/source:proxy_lib", - "//contrib/generic_proxy/filters/network/test/mocks:codec_mocks", - "//contrib/generic_proxy/filters/network/test/mocks:filter_mocks", - "//contrib/generic_proxy/filters/network/test/mocks:route_mocks", "//source/common/buffer:buffer_lib", + "//source/extensions/filters/network/generic_proxy:proxy_lib", + "//test/extensions/filters/network/generic_proxy/mocks:codec_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:filter_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:route_mocks", "//test/mocks/server:factory_context_mocks", "//test/test_common:registry_lib", "//test/test_common:utility_lib", @@ -64,19 +65,20 @@ envoy_cc_test( ], deps = [ ":fake_codec_lib", - "//contrib/generic_proxy/filters/network/source:config", - "//contrib/generic_proxy/filters/network/test/mocks:codec_mocks", - "//contrib/generic_proxy/filters/network/test/mocks:filter_mocks", - "//contrib/generic_proxy/filters/network/test/mocks:route_mocks", "//source/common/buffer:buffer_lib", + "//source/extensions/filters/network/generic_proxy:config", + "//source/extensions/filters/network/generic_proxy/router:config", "//source/extensions/tracers/zipkin:config", + "//test/extensions/filters/network/generic_proxy/mocks:codec_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:filter_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:route_mocks", "//test/mocks/network:network_mocks", "//test/mocks/server:factory_context_mocks", "//test/test_common:registry_lib", "//test/test_common:test_runtime_lib", "//test/test_common:utility_lib", - "@envoy_api//contrib/envoy/extensions/filters/network/generic_proxy/v3:pkg_cc_proto", "@envoy_api//envoy/admin/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/filters/network/generic_proxy/v3:pkg_cc_proto", ], ) @@ -90,18 +92,19 @@ envoy_cc_test( ], deps = [ ":fake_codec_lib", - "//contrib/generic_proxy/filters/network/source:config", - "//contrib/generic_proxy/filters/network/source:proxy_lib", - "//contrib/generic_proxy/filters/network/test/mocks:codec_mocks", - "//contrib/generic_proxy/filters/network/test/mocks:filter_mocks", - "//contrib/generic_proxy/filters/network/test/mocks:route_mocks", "//envoy/event:timer_interface", "//source/common/buffer:buffer_lib", "//source/common/common:thread_annotations", "//source/common/network:socket_option_lib", "//source/extensions/access_loggers/file:config", + "//source/extensions/filters/network/generic_proxy:config", + "//source/extensions/filters/network/generic_proxy:proxy_lib", + "//source/extensions/filters/network/generic_proxy/router:config", "//source/extensions/transport_sockets/raw_buffer:config", "//test/common/upstream:utility_lib", + "//test/extensions/filters/network/generic_proxy/mocks:codec_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:filter_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:route_mocks", "//test/integration:base_integration_test_lib", "//test/integration:common_extensions_lib", "//test/mocks/server:factory_context_mocks", @@ -118,7 +121,7 @@ envoy_cc_test( ], deps = [ ":fake_codec_lib", - "//contrib/generic_proxy/filters/network/source:match_lib", + "//source/extensions/filters/network/generic_proxy:match_lib", "//test/mocks/server:factory_context_mocks", ], ) @@ -130,7 +133,39 @@ envoy_cc_test( ], deps = [ ":fake_codec_lib", - "//contrib/generic_proxy/filters/network/source:access_log_lib", + "//source/extensions/filters/network/generic_proxy:access_log_lib", "//test/mocks/stream_info:stream_info_mocks", ], ) + +envoy_cc_test( + name = "stream_test", + srcs = [ + "stream_test.cc", + ], + deps = [ + "//source/extensions/filters/network/generic_proxy/interface:stream_interface", + ], +) + +envoy_cc_test( + name = "tracing_test", + srcs = [ + "tracing_test.cc", + ], + deps = [ + ":fake_codec_lib", + "//source/extensions/filters/network/generic_proxy:tracing_lib", + ], +) + +envoy_cc_test( + name = "stats_test", + srcs = [ + "stats_test.cc", + ], + deps = [ + "//source/extensions/filters/network/generic_proxy:stats_lib", + "//test/mocks/server:factory_context_mocks", + ], +) diff --git a/contrib/generic_proxy/filters/network/test/access_log_test.cc b/test/extensions/filters/network/generic_proxy/access_log_test.cc similarity index 64% rename from contrib/generic_proxy/filters/network/test/access_log_test.cc rename to test/extensions/filters/network/generic_proxy/access_log_test.cc index ab2f9470ada1..b0041c6d08dd 100644 --- a/contrib/generic_proxy/filters/network/test/access_log_test.cc +++ b/test/extensions/filters/network/generic_proxy/access_log_test.cc @@ -1,7 +1,8 @@ +#include "source/extensions/filters/network/generic_proxy/access_log.h" + +#include "test/extensions/filters/network/generic_proxy/fake_codec.h" #include "test/mocks/stream_info/mocks.h" -#include "contrib/generic_proxy/filters/network/source/access_log.h" -#include "contrib/generic_proxy/filters/network/test/fake_codec.h" #include "gtest/gtest.h" namespace Envoy { @@ -10,6 +11,53 @@ namespace NetworkFilters { namespace GenericProxy { namespace { +TEST(GenericStatusCodeFormatterProviderTest, GenericStatusCodeFormatterProviderTest) { + FormatterContext context; + GenericStatusCodeFormatterProvider formatter; + StreamInfo::MockStreamInfo stream_info; + + EXPECT_EQ(formatter.formatWithContext(context, stream_info), absl::nullopt); + EXPECT_TRUE(formatter.formatValueWithContext(context, stream_info).has_null_value()); + + FakeStreamCodecFactory::FakeResponse response; + response.status_ = {1234, false}; + context.response_ = &response; + + EXPECT_EQ(formatter.formatWithContext(context, stream_info).value(), "1234"); + EXPECT_EQ(formatter.formatValueWithContext(context, stream_info).number_value(), 1234.0); +} + +TEST(StringValueFormatterProviderTest, StringValueFormatterProviderTest) { + { + + FormatterContext context; + StringValueFormatterProvider formatter( + [](const FormatterContext& context, + const StreamInfo::StreamInfo&) -> absl::optional { + if (context.request_ == nullptr) { + return absl::nullopt; + } + return std::string(context.request_->path()); + }, + 9); + StreamInfo::MockStreamInfo stream_info; + + EXPECT_EQ(formatter.formatWithContext(context, stream_info), absl::nullopt); + EXPECT_TRUE(formatter.formatValueWithContext(context, stream_info).has_null_value()); + + FakeStreamCodecFactory::FakeRequest request; + request.path_ = "ANYTHING"; + context.request_ = &request; + + EXPECT_EQ(formatter.formatWithContext(context, stream_info).value(), "ANYTHING"); + EXPECT_EQ(formatter.formatValueWithContext(context, stream_info).string_value(), "ANYTHING"); + + request.path_ = "ANYTHING_LONGER_THAN_9"; + EXPECT_EQ(formatter.formatWithContext(context, stream_info).value(), "ANYTHING_"); + EXPECT_EQ(formatter.formatValueWithContext(context, stream_info).string_value(), "ANYTHING_"); + } +} + TEST(AccessLogFormatterTest, AccessLogFormatterTest) { { @@ -109,11 +157,9 @@ TEST(AccessLogFormatterTest, AccessLogFormatterTest) { } { - // Test for %RESPONSE_CODE%. - // This command overrides the default one which is defined in the - // source/common/formatter/stream_info_formatter.cc. + // Test for %GENERIC_RESPONSE_CODE%. FormatterContext context; - Envoy::Formatter::FormatterBaseImpl formatter("%RESPONSE_CODE%"); + Envoy::Formatter::FormatterBaseImpl formatter("%GENERIC_RESPONSE_CODE%"); StreamInfo::MockStreamInfo stream_info; EXPECT_EQ(formatter.formatWithContext(context, stream_info), "-"); diff --git a/contrib/generic_proxy/filters/network/test/codecs/dubbo/BUILD b/test/extensions/filters/network/generic_proxy/codecs/dubbo/BUILD similarity index 60% rename from contrib/generic_proxy/filters/network/test/codecs/dubbo/BUILD rename to test/extensions/filters/network/generic_proxy/codecs/dubbo/BUILD index 993056a11fae..38b9b8fdb12c 100644 --- a/contrib/generic_proxy/filters/network/test/codecs/dubbo/BUILD +++ b/test/extensions/filters/network/generic_proxy/codecs/dubbo/BUILD @@ -1,12 +1,12 @@ load( "//bazel:envoy_build_system.bzl", "envoy_cc_test", - "envoy_contrib_package", + "envoy_package", ) licenses(["notice"]) # Apache 2 -envoy_contrib_package() +envoy_package() envoy_cc_test( name = "config_test", @@ -14,9 +14,9 @@ envoy_cc_test( "config_test.cc", ], deps = [ - "//contrib/generic_proxy/filters/network/source/codecs/dubbo:config", - "//contrib/generic_proxy/filters/network/test/mocks:codec_mocks", + "//source/extensions/filters/network/generic_proxy/codecs/dubbo:config", "//test/extensions/common/dubbo:mocks_lib", + "//test/extensions/filters/network/generic_proxy/mocks:codec_mocks", "//test/mocks/server:factory_context_mocks", ], ) diff --git a/contrib/generic_proxy/filters/network/test/codecs/dubbo/config_test.cc b/test/extensions/filters/network/generic_proxy/codecs/dubbo/config_test.cc similarity index 83% rename from contrib/generic_proxy/filters/network/test/codecs/dubbo/config_test.cc rename to test/extensions/filters/network/generic_proxy/codecs/dubbo/config_test.cc index 17792dc903ed..e2b1aff1f40d 100644 --- a/contrib/generic_proxy/filters/network/test/codecs/dubbo/config_test.cc +++ b/test/extensions/filters/network/generic_proxy/codecs/dubbo/config_test.cc @@ -2,12 +2,12 @@ #include #include "source/extensions/common/dubbo/message.h" +#include "source/extensions/filters/network/generic_proxy/codecs/dubbo/config.h" #include "test/extensions/common/dubbo/mocks.h" +#include "test/extensions/filters/network/generic_proxy/mocks/codec.h" #include "test/mocks/server/factory_context.h" -#include "contrib/generic_proxy/filters/network/source/codecs/dubbo/config.h" -#include "contrib/generic_proxy/filters/network/test/mocks/codec.h" #include "gtest/gtest.h" namespace Envoy { @@ -49,6 +49,15 @@ MessageMetadataSharedPtr createDubboResponse(DubboRequest& request, ResponseStat TEST(DubboRequestTest, DubboRequestTest) { DubboRequest request(createDubboRequst(false)); + { + auto frame_flags = request.frameFlags(); + EXPECT_EQ(frame_flags.streamId(), 123456); + EXPECT_EQ(frame_flags.endStream(), true); + EXPECT_EQ(frame_flags.heartbeat(), false); + EXPECT_EQ(frame_flags.oneWayStream(), false); + EXPECT_EQ(frame_flags.drainClose(), false); + } + // Static attributes test. { EXPECT_EQ("dubbo", request.protocol()); } @@ -80,11 +89,54 @@ TEST(DubboRequestTest, DubboRequestTest) { // Version is not part of attachments. So there are only 2 attachments. EXPECT_EQ(2, attachment_size); } + // Iterate headers and break; + { + size_t attachment_size = 0; + request.forEach([&attachment_size](absl::string_view, absl::string_view) { + attachment_size++; + return false; + }); + // Version is not part of attachments. So there are only 2 attachments. + EXPECT_EQ(1, attachment_size); + } + + // Erase headers. + { + request.erase("group"); + EXPECT_EQ(false, request.get("group").has_value()); + + request.erase("custom_key"); + EXPECT_EQ(false, request.get("custom_key").has_value()); + } +} + +TEST(DubboRequestTest, OneWayDubboRequestTest) { + DubboRequest request(createDubboRequst(true)); + + { + auto frame_flags = request.frameFlags(); + EXPECT_EQ(frame_flags.streamId(), 123456); + EXPECT_EQ(frame_flags.endStream(), true); + EXPECT_EQ(frame_flags.heartbeat(), false); + EXPECT_EQ(frame_flags.oneWayStream(), true); + EXPECT_EQ(frame_flags.drainClose(), false); + } } TEST(DubboResponseTest, DubboResponseTest) { DubboRequest request(createDubboRequst(false)); + { + DubboResponse response( + createDubboResponse(request, ResponseStatus::Ok, RpcResponseType::ResponseWithValue)); + auto frame_flags = response.frameFlags(); + EXPECT_EQ(frame_flags.streamId(), 123456); + EXPECT_EQ(frame_flags.endStream(), true); + EXPECT_EQ(frame_flags.heartbeat(), false); + EXPECT_EQ(frame_flags.oneWayStream(), false); + EXPECT_EQ(frame_flags.drainClose(), false); + } + // Static attributes test. { DubboResponse response( @@ -240,6 +292,21 @@ TEST(DubboServerCodecTest, DubboServerCodecTest) { server_codec.decode(buffer, false); } + // Decode heartbeat request. + { + server_codec.metadata_.reset(); + + Buffer::OwnedImpl buffer; + buffer.add(std::string({'\xda', '\xbb', '\xe2', 00})); + buffer.writeBEInt(1); + buffer.writeBEInt(1); + buffer.writeByte('N'); + + EXPECT_CALL(*raw_serializer, deserializeRpcRequest(_, _)); + EXPECT_CALL(callbacks, writeToConnection(_)); + server_codec.decode(buffer, false); + } + // Encode response. { @@ -366,6 +433,21 @@ TEST(DubboClientCodecTest, DubboClientCodecTest) { client_codec.decode(buffer, false); } + // Decode heartbeat request. + { + client_codec.metadata_.reset(); + + Buffer::OwnedImpl buffer; + buffer.add(std::string({'\xda', '\xbb', '\xe2', 00})); + buffer.writeBEInt(1); + buffer.writeBEInt(1); + buffer.writeByte('N'); + + EXPECT_CALL(*raw_serializer, deserializeRpcRequest(_, _)); + EXPECT_CALL(callbacks, writeToConnection(_)); + client_codec.decode(buffer, false); + } + // Encode normal request. { MockEncodingContext encoding_context; diff --git a/contrib/generic_proxy/filters/network/test/codecs/http1/BUILD b/test/extensions/filters/network/generic_proxy/codecs/http1/BUILD similarity index 56% rename from contrib/generic_proxy/filters/network/test/codecs/http1/BUILD rename to test/extensions/filters/network/generic_proxy/codecs/http1/BUILD index d13a77613895..e0b72f498825 100644 --- a/contrib/generic_proxy/filters/network/test/codecs/http1/BUILD +++ b/test/extensions/filters/network/generic_proxy/codecs/http1/BUILD @@ -1,12 +1,12 @@ load( "//bazel:envoy_build_system.bzl", "envoy_cc_test", - "envoy_contrib_package", + "envoy_package", ) licenses(["notice"]) # Apache 2 -envoy_contrib_package() +envoy_package() envoy_cc_test( name = "config_test", @@ -14,8 +14,8 @@ envoy_cc_test( "config_test.cc", ], deps = [ - "//contrib/generic_proxy/filters/network/source/codecs/http1:config", - "//contrib/generic_proxy/filters/network/test/mocks:codec_mocks", + "//source/extensions/filters/network/generic_proxy/codecs/http1:config", + "//test/extensions/filters/network/generic_proxy/mocks:codec_mocks", "//test/mocks/server:factory_context_mocks", ], ) diff --git a/contrib/generic_proxy/filters/network/test/codecs/http1/config_test.cc b/test/extensions/filters/network/generic_proxy/codecs/http1/config_test.cc similarity index 69% rename from contrib/generic_proxy/filters/network/test/codecs/http1/config_test.cc rename to test/extensions/filters/network/generic_proxy/codecs/http1/config_test.cc index 5441bd19ddfe..ba774324ca36 100644 --- a/contrib/generic_proxy/filters/network/test/codecs/http1/config_test.cc +++ b/test/extensions/filters/network/generic_proxy/codecs/http1/config_test.cc @@ -1,10 +1,11 @@ #include #include +#include "source/extensions/filters/network/generic_proxy/codecs/http1/config.h" + +#include "test/extensions/filters/network/generic_proxy/mocks/codec.h" #include "test/mocks/server/factory_context.h" -#include "contrib/generic_proxy/filters/network/source/codecs/http1/config.h" -#include "contrib/generic_proxy/filters/network/test/mocks/codec.h" #include "gtest/gtest.h" namespace Envoy { @@ -48,6 +49,28 @@ TEST(Http1MessageFrameTest, Http1MessageFrameTest) { EXPECT_EQ(count, 4); } + // ForEach but return break; + { + auto headers = Http::RequestHeaderMapImpl::create(); + // Add some headers. + headers->addCopy(Http::Headers::get().HostLegacy, "host"); + headers->addCopy(Http::Headers::get().Path, "/path"); + headers->addCopy(Http::Headers::get().Method, "GET"); + // Add some custom headers. + headers->addCopy(Http::LowerCaseString("custom"), "value"); + + HttpRequestFrame frame(std::move(headers), true); + + // Check that the headers are iterated correctly. + size_t count = 0; + frame.forEach([&count](absl::string_view, absl::string_view) -> bool { + count++; + return false; + }); + + EXPECT_EQ(count, 1); + } + // Get. { auto headers = Http::RequestHeaderMapImpl::create(); @@ -234,10 +257,14 @@ class Http1ServerCodecTest : public testing::Test { std::unique_ptr codec_; }; -TEST_F(Http1ServerCodecTest, HeaderOnlyRequestDecodingTest) { +TEST_F(Http1ServerCodecTest, DecodeHeaderOnlyRequest) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + // Empty methods. Call these methods to increase coverage. + codec_->onStatusImpl("", 0); + codec_->onDecodingSuccess(ResponseHeaderFramePtr{nullptr}, {}); + Buffer::OwnedImpl buffer; buffer.add("GET / HTTP/1.1\r\n" @@ -265,7 +292,7 @@ TEST_F(Http1ServerCodecTest, HeaderOnlyRequestDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ServerCodecTest, RequestDecodingTest) { +TEST_F(Http1ServerCodecTest, DecodeRequestWithBody) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -304,7 +331,50 @@ TEST_F(Http1ServerCodecTest, RequestDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ServerCodecTest, ChunkedRequestDecodingTest) { +TEST_F(Http1ServerCodecTest, DecodeRequestAndCloseConnectionAfterHeader) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + Buffer::OwnedImpl buffer; + + buffer.add("GET / HTTP/1.1\r\n" + "Host: host\r\n" + "Content-Length: 4\r\n" + "custom: value\r\n" + "\r\n" + "body"); + + EXPECT_CALL(codec_callbacks_, onDecodingSuccess(_, _)) + .WillOnce(Invoke([this](RequestHeaderFramePtr, absl::optional) { + mock_connection_.close(Network::ConnectionCloseType::NoFlush); + })); + + codec_->decode(buffer, false); +} + +TEST_F(Http1ServerCodecTest, DecodeRequestAndCloseConnectionAfterBody) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + Buffer::OwnedImpl buffer; + + buffer.add("GET / HTTP/1.1\r\n" + "Host: host\r\n" + "Content-Length: 4\r\n" + "custom: value\r\n" + "\r\n" + "body"); + + EXPECT_CALL(codec_callbacks_, onDecodingSuccess(_, _)); + EXPECT_CALL(codec_callbacks_, onDecodingSuccess(_)) + .WillOnce(Invoke([this](RequestCommonFramePtr) { + mock_connection_.close(Network::ConnectionCloseType::NoFlush); + })); + + codec_->decode(buffer, false); +} + +TEST_F(Http1ServerCodecTest, DecodeRequestWithChunkedBody) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -315,11 +385,12 @@ TEST_F(Http1ServerCodecTest, ChunkedRequestDecodingTest) { "Transfer-Encoding: chunked\r\n" "custom: value\r\n" "\r\n" - "4\r\n" // Chunk header. - "body" // Chunk body. - "\r\n" // Chunk footer. - "0\r\n" // Last chunk header. - "\r\n"); // Last chunk footer. + "4\r\n" // Chunk header. + "body" // Chunk body. + "\r\n" // Chunk footer. + "0\r\n" // Last chunk header. + "trailer-key: trailer-value\r\n" // Trailers in the last chunk. Will be ignored. + "\r\n"); // Last chunk footer. EXPECT_CALL(codec_callbacks_, onDecodingSuccess(_, _)) .WillOnce(Invoke([](RequestHeaderFramePtr frame, absl::optional) { @@ -351,7 +422,7 @@ TEST_F(Http1ServerCodecTest, ChunkedRequestDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ServerCodecTest, MultipleBufferChunkedRequestDecodingTest) { +TEST_F(Http1ServerCodecTest, DecodeRequestWithChunkedBodyWithMultipleFrames) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -406,7 +477,7 @@ TEST_F(Http1ServerCodecTest, MultipleBufferChunkedRequestDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ServerCodecTest, UnexpectedRequestTest) { +TEST_F(Http1ServerCodecTest, DecodeUnexpectedRequest) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -497,7 +568,7 @@ TEST_F(Http1ServerCodecTest, UnexpectedRequestTest) { } } -TEST_F(Http1ServerCodecTest, RespondTest) { +TEST_F(Http1ServerCodecTest, Respond) { // Create a request. auto headers = Http::RequestHeaderMapImpl::create(); headers->addCopy(Http::Headers::get().HostLegacy, "host"); @@ -509,7 +580,7 @@ TEST_F(Http1ServerCodecTest, RespondTest) { // Respond with a response. { - for (int i = 0; i <= 16; i++) { + for (int i = 0; i <= 20; i++) { auto response = codec_->respond(absl::Status(static_cast(i), ""), "", request); @@ -523,9 +594,10 @@ TEST_F(Http1ServerCodecTest, RespondTest) { } } -TEST_F(Http1ServerCodecTest, HeaderOnlyResponseEncodingTest) { +TEST_F(Http1ServerCodecTest, EncodeHeaderOnlyResponse) { // Mock request. - codec_->active_request_ = ActiveRequest{nullptr, true}; + codec_->active_request_ = + ActiveRequest{nullptr, /*request_has_body_*/ false, /*request_complete_*/ true}; // Create a response. auto headers = Http::ResponseHeaderMapImpl::create(); @@ -548,9 +620,10 @@ TEST_F(Http1ServerCodecTest, HeaderOnlyResponseEncodingTest) { } } -TEST_F(Http1ServerCodecTest, MissingRequiredHeadersEncodingTest) { +TEST_F(Http1ServerCodecTest, EncodeResponseWhichMissRequiredHeaders) { // Mock request. - codec_->active_request_ = ActiveRequest{nullptr, true}; + codec_->active_request_ = + ActiveRequest{nullptr, /*request_has_body_*/ false, /*request_complete_*/ true}; // Create a request without method. auto headers = Http::ResponseHeaderMapImpl::create(); @@ -567,9 +640,29 @@ TEST_F(Http1ServerCodecTest, MissingRequiredHeadersEncodingTest) { } } -TEST_F(Http1ServerCodecTest, ResponseEncodingTest) { +TEST_F(Http1ServerCodecTest, EncodeResponseButNoActiveRequest) { + // No active request. + codec_->active_request_.reset(); + + NiceMock encoding_context; + + // Create a response. + auto headers = Http::ResponseHeaderMapImpl::create(); + headers->setStatus(200); + HttpResponseFrame response(std::move(headers), true); + + // Encode the response. + { + auto status_or = codec_->encode(response, encoding_context); + EXPECT_FALSE(status_or.ok()); + EXPECT_EQ(status_or.status().message(), "no request for coming response"); + } +} + +TEST_F(Http1ServerCodecTest, EncodeResponseWithBody) { // Mock request. - codec_->active_request_ = ActiveRequest{nullptr, true}; + codec_->active_request_ = + ActiveRequest{nullptr, /*request_has_body_*/ false, /*request_complete_*/ true}; // Create a response. auto headers = Http::ResponseHeaderMapImpl::create(); @@ -605,9 +698,10 @@ TEST_F(Http1ServerCodecTest, ResponseEncodingTest) { } } -TEST_F(Http1ServerCodecTest, ChunkedResponseEncodingTest) { +TEST_F(Http1ServerCodecTest, EncodeResponseWithChunkedBody) { // Mock request. - codec_->active_request_ = ActiveRequest{nullptr, true}; + codec_->active_request_ = + ActiveRequest{nullptr, /*request_has_body_*/ false, /*request_complete_*/ true}; // Create a response. auto headers = Http::ResponseHeaderMapImpl::create(); @@ -646,8 +740,51 @@ TEST_F(Http1ServerCodecTest, ChunkedResponseEncodingTest) { EXPECT_TRUE(codec_->encode(body, encoding_context).ok()); } } +TEST_F(Http1ServerCodecTest, EncodeResponseWithChunkedBodyButNotSetChunkHeader) { + // Mock request. + codec_->active_request_ = + ActiveRequest{nullptr, /*request_has_body_*/ false, /*request_complete_*/ true}; + + // Create a response. + auto headers = Http::ResponseHeaderMapImpl::create(); + headers->setStatus(200); + + HttpResponseFrame response(std::move(headers), false); + + Buffer::OwnedImpl body_buffer("body"); + HttpRawBodyFrame body(body_buffer, true); + + NiceMock encoding_context; + + // Encode the response. + { + EXPECT_CALL(codec_callbacks_, writeToConnection(_)) + .WillOnce(Invoke([](Buffer::Instance& buffer) { + EXPECT_EQ(buffer.toString(), + "HTTP/1.1 200 OK\r\n" + "transfer-encoding: chunked\r\n" // Codec will add this header for chunked + // response by default if it is not set. + "\r\n"); + buffer.drain(buffer.length()); + })); + + EXPECT_TRUE(codec_->encode(response, encoding_context).ok()); + + EXPECT_CALL(codec_callbacks_, writeToConnection(_)) + .WillOnce(Invoke([](Buffer::Instance& buffer) { + EXPECT_EQ(buffer.toString(), "4\r\n" // Chunk header. + "body" // Chunk body. + "\r\n" // Chunk footer. + "0\r\n" // Last chunk header. + "\r\n"); // Last chunk footer. + buffer.drain(buffer.length()); + })); + + EXPECT_TRUE(codec_->encode(body, encoding_context).ok()); + } +} -TEST_F(Http1ServerCodecTest, RequestAndResponseTest) { +TEST_F(Http1ServerCodecTest, DecodeRequestAndEncodeResponse) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -690,7 +827,48 @@ TEST_F(Http1ServerCodecTest, RequestAndResponseTest) { } } -TEST_F(Http1ServerCodecTest, ResponseCompleteBeforeRequestCompleteTest) { +TEST_F(Http1ServerCodecTest, DecodeExpectRequestAndItWillBeRepliedDirectly) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + Buffer::OwnedImpl buffer; + + buffer.add("GET / HTTP/1.1\r\n" + "Host: host\r\n" + "custom: value\r\n" + "Expect: 100-continue\r\n" + "\r\n"); + + EXPECT_CALL(codec_callbacks_, writeToConnection(_)).WillOnce(Invoke([](Buffer::Instance& buffer) { + EXPECT_EQ(buffer.toString(), "HTTP/1.1 100 Continue\r\n" + "content-length: 0\r\n" + "\r\n"); + buffer.drain(buffer.length()); + })); + + EXPECT_CALL(codec_callbacks_, onDecodingSuccess(_, _)) + .WillOnce(Invoke([](RequestHeaderFramePtr frame, absl::optional) { + EXPECT_EQ(frame->frameFlags().endStream(), true); + + auto* request = dynamic_cast(frame.get()); + + EXPECT_EQ(request->host(), "host"); + EXPECT_EQ(request->path(), "/"); + EXPECT_EQ(request->method(), "GET"); + EXPECT_EQ(request->get("host").value(), "host"); + EXPECT_EQ(request->get(":authority").value(), "host"); + EXPECT_EQ(request->get(":path").value(), "/"); + EXPECT_EQ(request->get(":method").value(), "GET"); + EXPECT_EQ(request->get("custom").value(), "value"); + + // Expect header should be replied directly and then be removed from the request. + EXPECT_FALSE(request->get("expect").has_value()); + })); + + codec_->decode(buffer, false); +} + +TEST_F(Http1ServerCodecTest, ResponseCompleteBeforeRequestComplete) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -734,7 +912,7 @@ TEST_F(Http1ServerCodecTest, ResponseCompleteBeforeRequestCompleteTest) { EXPECT_EQ(status_or.status().message(), "response complete before request complete"); } -TEST_F(Http1ServerCodecTest, NewRequestBeforeFirstRequestCompleteTest) { +TEST_F(Http1ServerCodecTest, NewRequestBeforeFirstRequestComplete) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -764,7 +942,7 @@ TEST_F(Http1ServerCodecTest, NewRequestBeforeFirstRequestCompleteTest) { codec_->decode(buffer2, false); } -TEST_F(Http1ServerCodecTest, SingleFrameModeRequestDecodingTest) { +TEST_F(Http1ServerCodecTest, DecodeRequestInSingleFrameMode) { initializeCodec(true, 8 * 1024 * 1024); ON_CALL(codec_callbacks_, connection()) @@ -801,7 +979,7 @@ TEST_F(Http1ServerCodecTest, SingleFrameModeRequestDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ServerCodecTest, SingleFrameModeRequestTooLargeTest) { +TEST_F(Http1ServerCodecTest, DecodeRequestInSingleFrameModeButBodyTooLarge1) { initializeCodec(true, 4); ON_CALL(codec_callbacks_, connection()) @@ -811,16 +989,35 @@ TEST_F(Http1ServerCodecTest, SingleFrameModeRequestTooLargeTest) { buffer.add("GET / HTTP/1.1\r\n" "Host: host\r\n" - "Content-Length: 4\r\n" + "Content-Length: 5\r\n" "custom: value\r\n" "\r\n" - "body~"); + "body~"); // Request is complete and the body is too large. EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); codec_->decode(buffer, false); } -TEST_F(Http1ServerCodecTest, SingleFrameModeChunkedRequestDecodingTest) { +TEST_F(Http1ServerCodecTest, DecodeRequestInSingleFrameModeButBodyTooLarge2) { + initializeCodec(true, 4); + + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + Buffer::OwnedImpl buffer; + + buffer.add("GET / HTTP/1.1\r\n" + "Host: host\r\n" + "Content-Length: 8\r\n" + "custom: value\r\n" + "\r\n" + "xxxxx"); // Request is not complete but the body is too large. + + EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); + codec_->decode(buffer, false); +} + +TEST_F(Http1ServerCodecTest, DecodeRequestWithChunkedBodyInSingleFrameMode) { initializeCodec(true, 8 * 1024 * 1024); ON_CALL(codec_callbacks_, connection()) @@ -861,7 +1058,7 @@ TEST_F(Http1ServerCodecTest, SingleFrameModeChunkedRequestDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ServerCodecTest, SingleFrameModeMultipleBufferChunkedRequestDecodingTest) { +TEST_F(Http1ServerCodecTest, DecodeRequestWithChunkedBodyWithMultipleFramesInSingleFrameMode) { initializeCodec(true, 8 * 1024 * 1024); ON_CALL(codec_callbacks_, connection()) @@ -907,9 +1104,10 @@ TEST_F(Http1ServerCodecTest, SingleFrameModeMultipleBufferChunkedRequestDecoding codec_->decode(buffer, false); } -TEST_F(Http1ServerCodecTest, SingleFrameModeResponseEncodingTest) { +TEST_F(Http1ServerCodecTest, EncodeResponseInSingleFrameMode) { // Mock request. - codec_->active_request_ = ActiveRequest{nullptr, true}; + codec_->active_request_ = + ActiveRequest{nullptr, /*request_has_body_*/ false, /*request_complete_*/ true}; // Create a response. auto headers = Http::ResponseHeaderMapImpl::create(); @@ -946,7 +1144,7 @@ class Http1ClientCodecTest : public testing::Test { codec_->setCodecCallbacks(codec_callbacks_); } - void encodingOneRequest() { + void encodingGetRequest() { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -987,16 +1185,50 @@ class Http1ClientCodecTest : public testing::Test { } } + void encodingHeadRequest() { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + // Create a request. + auto headers = Http::RequestHeaderMapImpl::create(); + headers->addCopy(Http::Headers::get().HostLegacy, "host"); + headers->addCopy(Http::Headers::get().Path, "/path"); + headers->addCopy(Http::Headers::get().Method, "HEAD"); + headers->addCopy(Http::Headers::get().ContentLength, "0"); + + HttpRequestFrame request(std::move(headers), true); + + NiceMock encoding_context; + + // Encode the request. + { + EXPECT_CALL(codec_callbacks_, writeToConnection(_)) + .WillOnce(Invoke([](Buffer::Instance& buffer) { + EXPECT_EQ(buffer.toString(), "HEAD /path HTTP/1.1\r\n" + "host: host\r\n" + "content-length: 0\r\n" + "\r\n"); + buffer.drain(buffer.length()); + })); + + EXPECT_TRUE(codec_->encode(request, encoding_context).ok()); + } + } + NiceMock codec_callbacks_; NiceMock mock_connection_; std::unique_ptr codec_; }; -TEST_F(Http1ClientCodecTest, HeaderOnlyResponseDecodingTest) { +TEST_F(Http1ClientCodecTest, DecodeHeaderOnlyResponse) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); - encodingOneRequest(); + // Empty methods. Call these methods to increase coverage. + codec_->onUrlImpl("", 0); + codec_->onDecodingSuccess(RequestHeaderFramePtr{nullptr}, {}); + + encodingGetRequest(); Buffer::OwnedImpl buffer; @@ -1016,11 +1248,101 @@ TEST_F(Http1ClientCodecTest, HeaderOnlyResponseDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ClientCodecTest, ResponseDecodingTest) { +TEST_F(Http1ClientCodecTest, ResponseComesBeforeRequest) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); - encodingOneRequest(); + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 200 OK\r\n" + "content-length: 0\r\n" + "\r\n"); + + EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); + codec_->decode(buffer, false); +} + +TEST_F(Http1ClientCodecTest, DecodeHTTP10Response) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.0 200 OK\r\n" + "content-length: 0\r\n" + "\r\n"); + + EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); + codec_->decode(buffer, false); +} + +TEST_F(Http1ClientCodecTest, DecodeResponseForHeadRequest) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + encodingHeadRequest(); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 200 OK\r\n" + "Content-Length: 0\r\n" + "custom: value\r\n" + "\r\n"); + + EXPECT_CALL(codec_callbacks_, onDecodingSuccess(_, _)) + .WillOnce(Invoke([](ResponseHeaderFramePtr frame, absl::optional) { + auto* response = dynamic_cast(frame.get()); + EXPECT_EQ(frame->frameFlags().endStream(), true); + EXPECT_EQ(response->response_->getStatusValue(), "200"); + EXPECT_EQ(response->get("custom").value(), "value"); + })); + + codec_->decode(buffer, false); +} + +TEST_F(Http1ClientCodecTest, DecodeResponseShouldNotHasBody) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + encodingGetRequest(); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 304 OK\r\n" + "Content-Length: 0\r\n" + "custom: value\r\n" + "\r\n"); + + EXPECT_CALL(codec_callbacks_, onDecodingSuccess(_, _)) + .WillOnce(Invoke([](ResponseHeaderFramePtr frame, absl::optional) { + auto* response = dynamic_cast(frame.get()); + EXPECT_EQ(frame->frameFlags().endStream(), true); + EXPECT_EQ(response->response_->getStatusValue(), "304"); + EXPECT_EQ(response->get("custom").value(), "value"); + })); + + codec_->decode(buffer, false); +} + +TEST_F(Http1ClientCodecTest, Decode1xxResponseAndItWillBeIgnored) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + encodingGetRequest(); + + Buffer::OwnedImpl buffer; + buffer.add("HTTP/1.1 100 Continue\r\n" + "\r\n"); + + EXPECT_CALL(codec_callbacks_, onDecodingSuccess(_)).Times(0); + codec_->decode(buffer, false); +} + +TEST_F(Http1ClientCodecTest, DecodeResponseWithBody) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + encodingGetRequest(); Buffer::OwnedImpl buffer; @@ -1051,11 +1373,56 @@ TEST_F(Http1ClientCodecTest, ResponseDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ClientCodecTest, ChunkedResponseDecodingTest) { +TEST_F(Http1ClientCodecTest, DecodeResponseAndCloseConnectionAfterHeader) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); - encodingOneRequest(); + encodingGetRequest(); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 200 OK\r\n" + "Content-Length: 4\r\n" + "custom: value\r\n" + "\r\n" + "body"); + + EXPECT_CALL(codec_callbacks_, onDecodingSuccess(_, _)) + .WillOnce(Invoke([this](ResponseHeaderFramePtr, absl::optional) { + mock_connection_.close(Network::ConnectionCloseType::NoFlush); + })); + + codec_->decode(buffer, false); +} + +TEST_F(Http1ClientCodecTest, DecodeResponseAndCloseConnectionAfterBody) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + encodingGetRequest(); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 200 OK\r\n" + "Content-Length: 4\r\n" + "custom: value\r\n" + "\r\n" + "body"); + + EXPECT_CALL(codec_callbacks_, onDecodingSuccess(_, _)); + EXPECT_CALL(codec_callbacks_, onDecodingSuccess(_)) + .WillOnce(Invoke([this](ResponseCommonFramePtr) { + mock_connection_.close(Network::ConnectionCloseType::NoFlush); + })); + + codec_->decode(buffer, false); +} + +TEST_F(Http1ClientCodecTest, DecodeResponseWithChunkedBody) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + encodingGetRequest(); Buffer::OwnedImpl buffer; @@ -1092,11 +1459,11 @@ TEST_F(Http1ClientCodecTest, ChunkedResponseDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ClientCodecTest, MultipleBufferChunkedResponseDecodingTest) { +TEST_F(Http1ClientCodecTest, DecodeResponseWithChunkedBodyWithMultipleFrames) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); - encodingOneRequest(); + encodingGetRequest(); Buffer::OwnedImpl buffer; @@ -1141,7 +1508,7 @@ TEST_F(Http1ClientCodecTest, MultipleBufferChunkedResponseDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ClientCodecTest, UnexpectedResponseTest) { +TEST_F(Http1ClientCodecTest, DecodeUnexpectedResponse) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -1149,7 +1516,7 @@ TEST_F(Http1ClientCodecTest, UnexpectedResponseTest) { { initializeCodec(); - encodingOneRequest(); + encodingGetRequest(); Buffer::OwnedImpl buffer; @@ -1172,7 +1539,7 @@ TEST_F(Http1ClientCodecTest, UnexpectedResponseTest) { { initializeCodec(); - encodingOneRequest(); + encodingGetRequest(); Buffer::OwnedImpl buffer; @@ -1189,9 +1556,129 @@ TEST_F(Http1ClientCodecTest, UnexpectedResponseTest) { EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); codec_->decode(buffer, false); } + + // Transfer-Encoding header for 204 response. + { + initializeCodec(); + + encodingGetRequest(); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 204 OK\r\n" + "Transfer-Encoding: chunked\r\n" + "custom: value\r\n" + "\r\n" + "4\r\n" // Chunk header. + "body" // Chunk body. + "\r\n" // Chunk footer. + "0\r\n" // Last chunk header. + "\r\n"); // Last chunk footer. + + EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); + codec_->decode(buffer, false); + } + + // Transfer-Encoding header for 1xx response. + { + initializeCodec(); + + encodingGetRequest(); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 100 Continue\r\n" + "Transfer-Encoding: chunked\r\n" + "custom: value\r\n" + "\r\n" + "4\r\n" // Chunk header. + "body" // Chunk body. + "\r\n" // Chunk footer. + "0\r\n" // Last chunk header. + "\r\n"); // Last chunk footer. + + EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); + codec_->decode(buffer, false); + } + + // Transfer-Encoding header for 304 response. + { + initializeCodec(); + + encodingGetRequest(); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 304 Not Modified\r\n" + "Transfer-Encoding: chunked\r\n" + "custom: value\r\n" + "\r\n" + "4\r\n" // Chunk header. + "body" // Chunk body. + "\r\n" // Chunk footer. + "0\r\n" // Last chunk header. + "\r\n"); // Last chunk footer. + + EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); + codec_->decode(buffer, false); + } + + // Non-zero Content-Length for 204 response. + { + initializeCodec(); + + encodingGetRequest(); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 204 OK\r\n" + "Content-Length: 4\r\n" + "custom: value\r\n" + "\r\n" + "body"); + + EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); + codec_->decode(buffer, false); + } + + // Non-zero Content-Length for 1xx response. + { + initializeCodec(); + + encodingGetRequest(); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 100 Continue\r\n" + "Content-Length: 4\r\n" + "custom: value\r\n" + "\r\n" + "body"); + + EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); + codec_->decode(buffer, false); + } + + // Non-zero Content-Length for 304 response. + { + initializeCodec(); + + encodingGetRequest(); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 304 Not Modified\r\n" + "Content-Length: 4\r\n" + "custom: value\r\n" + "\r\n" + "body"); + + EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); + codec_->decode(buffer, false); + } } -TEST_F(Http1ClientCodecTest, HeaderOnlyRequestEncodingTest) { +TEST_F(Http1ClientCodecTest, EncodeHeaderOnlyRequest) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -1214,13 +1701,14 @@ TEST_F(Http1ClientCodecTest, HeaderOnlyRequestEncodingTest) { "host: host\r\n" "custom: value\r\n" "\r\n"); + buffer.drain(buffer.length()); })); EXPECT_TRUE(codec_->encode(request, encoding_context).ok()); } } -TEST_F(Http1ClientCodecTest, MissingRequiredHeadersEncodingTest) { +TEST_F(Http1ClientCodecTest, EncodeRequestMissRequiredHeaders) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -1242,9 +1730,48 @@ TEST_F(Http1ClientCodecTest, MissingRequiredHeadersEncodingTest) { } } -TEST_F(Http1ClientCodecTest, RequestEncodingTest) { encodingOneRequest(); } +TEST_F(Http1ClientCodecTest, EncodeRequestWithBody) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); -TEST_F(Http1ClientCodecTest, ChunkedRequestEncodingTest) { + // Create a request. + auto headers = Http::RequestHeaderMapImpl::create(); + headers->addCopy(Http::Headers::get().HostLegacy, "host"); + headers->addCopy(Http::Headers::get().Path, "/path"); + headers->addCopy(Http::Headers::get().Method, "POST"); + headers->addCopy(Http::Headers::get().ContentLength, "4"); + + HttpRequestFrame request(std::move(headers), false); + + Buffer::OwnedImpl body_buffer("body"); + HttpRawBodyFrame body(body_buffer, true); + + NiceMock encoding_context; + + // Encode the request. + { + EXPECT_CALL(codec_callbacks_, writeToConnection(_)) + .WillOnce(Invoke([](Buffer::Instance& buffer) { + EXPECT_EQ(buffer.toString(), "POST /path HTTP/1.1\r\n" + "host: host\r\n" + "content-length: 4\r\n" + "\r\n"); + buffer.drain(buffer.length()); + })); + + EXPECT_TRUE(codec_->encode(request, encoding_context).ok()); + + EXPECT_CALL(codec_callbacks_, writeToConnection(_)) + .WillOnce(Invoke([](Buffer::Instance& buffer) { + EXPECT_EQ(buffer.toString(), "body"); + buffer.drain(buffer.length()); + })); + + EXPECT_TRUE(codec_->encode(body, encoding_context).ok()); + } +} + +TEST_F(Http1ClientCodecTest, EncodeRequestWithChunkdBody) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -1289,7 +1816,7 @@ TEST_F(Http1ClientCodecTest, ChunkedRequestEncodingTest) { } } -TEST_F(Http1ClientCodecTest, RequestAndResponseTest) { +TEST_F(Http1ClientCodecTest, EncodeRequestAndDecodeResponse) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -1334,7 +1861,7 @@ TEST_F(Http1ClientCodecTest, RequestAndResponseTest) { } } -TEST_F(Http1ClientCodecTest, ResponseCompleteBeforeRequestCompleteTest) { +TEST_F(Http1ClientCodecTest, ResponseCompleteBeforeRequestComplete) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -1375,7 +1902,7 @@ TEST_F(Http1ClientCodecTest, ResponseCompleteBeforeRequestCompleteTest) { codec_->decode(buffer, false); } -TEST_F(Http1ClientCodecTest, SingleFrameModeRequestEncodingTest) { +TEST_F(Http1ClientCodecTest, EncodeRequestInSingleFrameMode) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); @@ -1402,18 +1929,19 @@ TEST_F(Http1ClientCodecTest, SingleFrameModeRequestEncodingTest) { "content-length: 4\r\n" "\r\n" "body"); + buffer.drain(buffer.length()); })); EXPECT_TRUE(codec_->encode(request, encoding_context).ok()); } } -TEST_F(Http1ClientCodecTest, SingleFrameModeResponseDecodingTest) { +TEST_F(Http1ClientCodecTest, DecodeResponseInSingleFrameMode) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); initializeCodec(true, 8 * 1024 * 1024); - encodingOneRequest(); + encodingGetRequest(); Buffer::OwnedImpl buffer; @@ -1439,13 +1967,13 @@ TEST_F(Http1ClientCodecTest, SingleFrameModeResponseDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ClientCodecTest, SingleFrameModeResponseTooLargeTest) { +TEST_F(Http1ClientCodecTest, DecodeResponseInSingleFrameModeButBodyIsTooLarge1) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); initializeCodec(true, 4); - encodingOneRequest(); + encodingGetRequest(); Buffer::OwnedImpl buffer; @@ -1453,19 +1981,39 @@ TEST_F(Http1ClientCodecTest, SingleFrameModeResponseTooLargeTest) { "Content-Length: 5\r\n" "custom: value\r\n" "\r\n" - "body~"); + "body~"); // The response is complete and the body is too large. + + EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); + codec_->decode(buffer, false); +} + +TEST_F(Http1ClientCodecTest, DecodeResponseInSingleFrameModeButBodyIsTooLarge2) { + ON_CALL(codec_callbacks_, connection()) + .WillByDefault(testing::Return(makeOptRef(mock_connection_))); + + initializeCodec(true, 4); + + encodingGetRequest(); + + Buffer::OwnedImpl buffer; + + buffer.add("HTTP/1.1 200 OK\r\n" + "Content-Length: 8\r\n" + "custom: value\r\n" + "\r\n" + "xxxxx"); // The response is not complete but the body is too large. EXPECT_CALL(codec_callbacks_, onDecodingFailure(_)); codec_->decode(buffer, false); } -TEST_F(Http1ClientCodecTest, SingleFrameModeChunkedResponseDecodingTest) { +TEST_F(Http1ClientCodecTest, DecodeResponseWithChunkedBodyInSingleFrameMode) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); initializeCodec(true, 8 * 1024 * 1024); - encodingOneRequest(); + encodingGetRequest(); Buffer::OwnedImpl buffer; @@ -1495,13 +2043,13 @@ TEST_F(Http1ClientCodecTest, SingleFrameModeChunkedResponseDecodingTest) { codec_->decode(buffer, false); } -TEST_F(Http1ClientCodecTest, SingleFrameModeMultipleBufferChunkedResponseDecodingTest) { +TEST_F(Http1ClientCodecTest, DecodeResponseWithChunkedBodyWithMultipleFramesInSingleFrameMode) { ON_CALL(codec_callbacks_, connection()) .WillByDefault(testing::Return(makeOptRef(mock_connection_))); initializeCodec(true, 8 * 1024 * 1024); - encodingOneRequest(); + encodingGetRequest(); Buffer::OwnedImpl buffer; @@ -1536,6 +2084,21 @@ TEST_F(Http1ClientCodecTest, SingleFrameModeMultipleBufferChunkedResponseDecodin codec_->decode(buffer, false); } +TEST(Http1CodecFactoryTest, Http1CodecFactoryTest) { + NiceMock context; + ProtoConfig proto_config; + + Http1CodecFactoryConfig config_factory; + + auto codec_factory = config_factory.createCodecFactory(proto_config, context); + + auto client_factory = codec_factory->createClientCodec(); + auto server_factory = codec_factory->createServerCodec(); + + EXPECT_NE(dynamic_cast(client_factory.get()), nullptr); + EXPECT_NE(dynamic_cast(server_factory.get()), nullptr); +} + } // namespace } // namespace Http1 } // namespace Codec diff --git a/contrib/generic_proxy/filters/network/test/config_test.cc b/test/extensions/filters/network/generic_proxy/config_test.cc similarity index 78% rename from contrib/generic_proxy/filters/network/test/config_test.cc rename to test/extensions/filters/network/generic_proxy/config_test.cc index 7faaa94afd50..7197e810c354 100644 --- a/contrib/generic_proxy/filters/network/test/config_test.cc +++ b/test/extensions/filters/network/generic_proxy/config_test.cc @@ -1,20 +1,21 @@ #include "envoy/admin/v3/config_dump_shared.pb.h" #include "envoy/admin/v3/config_dump_shared.pb.validate.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.validate.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/route.pb.h" +#include "envoy/extensions/filters/network/generic_proxy/v3/route.pb.validate.h" +#include "source/extensions/filters/network/generic_proxy/config.h" + +#include "test/extensions/filters/network/generic_proxy/fake_codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/filter.h" +#include "test/extensions/filters/network/generic_proxy/mocks/route.h" #include "test/mocks/network/mocks.h" #include "test/mocks/server/factory_context.h" #include "test/test_common/registry.h" #include "test/test_common/utility.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/generic_proxy.pb.validate.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/route.pb.h" -#include "contrib/envoy/extensions/filters/network/generic_proxy/v3/route.pb.validate.h" -#include "contrib/generic_proxy/filters/network/source/config.h" -#include "contrib/generic_proxy/filters/network/test/fake_codec.h" -#include "contrib/generic_proxy/filters/network/test/mocks/codec.h" -#include "contrib/generic_proxy/filters/network/test/mocks/filter.h" -#include "contrib/generic_proxy/filters/network/test/mocks/route.h" #include "gtest/gtest.h" namespace Envoy { @@ -25,7 +26,6 @@ namespace { using ::testing::Return; -// Keep empty until merge the latest API from main. TEST(FactoryTest, FactoryTest) { const std::string yaml_config = R"EOF( stat_prefix: config_test @@ -453,6 +453,114 @@ TEST(BasicFilterConfigTest, TestConfigurationWithAccessLog) { cb(filter_manager); } +TEST(BasicFilterConfigTest, TestConfigurationWithAccessLogAndLogFilter1) { + const std::string config_yaml = R"EOF( + stat_prefix: ingress + filters: + - name: envoy.filters.generic.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.generic_proxy.router.v3.Router + codec_config: + name: mock + typed_config: + "@type": type.googleapis.com/xds.type.v3.TypedStruct + type_url: envoy.generic_proxy.codecs.mock.type + value: {} + generic_rds: + config_source: { ads: {} } + route_config_name: test_route + access_log: + - name: envoy.generic_proxy.access_loggers.file + filter: + not_health_check_filter: {} + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: "/dev/stdout" + log_format: + text_format_source: + inline_string: "%METHOD% %PATH% %HOST% %PROTOCOL% %REQUEST_PROPERTY(key)% RESPONSE_PROPERTY(key)\n" + )EOF"; + + NiceMock codec_factory_config; + Registry::InjectFactory registration(codec_factory_config); + + NiceMock factory_context; + + Factory factory; + + envoy::extensions::filters::network::generic_proxy::v3::GenericProxy config; + TestUtility::loadFromYaml(config_yaml, config); + + auto mock_codec_factory = std::make_unique>(); + + EXPECT_CALL(codec_factory_config, createCodecFactory(_, _)) + .WillOnce(Return(testing::ByMove(std::move(mock_codec_factory)))); + + EXPECT_THROW_WITH_MESSAGE( + { auto status_or = factory.createFilterFactoryFromProto(config, factory_context); }, + EnvoyException, + "Access log filter: only extension filter is supported by non-HTTP access loggers."); +} + +TEST(BasicFilterConfigTest, TestConfigurationWithAccessLogAndLogFilter2) { + const std::string config_yaml = R"EOF( + stat_prefix: ingress + filters: + - name: envoy.filters.generic.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.generic_proxy.router.v3.Router + codec_config: + name: mock + typed_config: + "@type": type.googleapis.com/xds.type.v3.TypedStruct + type_url: envoy.generic_proxy.codecs.mock.type + value: {} + generic_rds: + config_source: { ads: {} } + route_config_name: test_route + access_log: + - name: envoy.generic_proxy.access_loggers.file + filter: + extension_filter: + name: envoy.generic_proxy.access_log.fake + typed_config: + "@type": type.googleapis.com/xds.type.v3.TypedStruct + type_url: envoy.generic_proxy.access_log.fake.type + value: {} + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: "/dev/stdout" + log_format: + text_format_source: + inline_string: "%METHOD% %PATH% %HOST% %PROTOCOL% %REQUEST_PROPERTY(key)% RESPONSE_PROPERTY(key)\n" + )EOF"; + + NiceMock codec_factory_config; + Registry::InjectFactory registration(codec_factory_config); + + FakeAccessLogExtensionFilterFactory fake_access_log_extension_filter_factory; + Registry::InjectFactory registration_log( + fake_access_log_extension_filter_factory); + + NiceMock factory_context; + + Factory factory; + + envoy::extensions::filters::network::generic_proxy::v3::GenericProxy config; + TestUtility::loadFromYaml(config_yaml, config); + + auto mock_codec_factory = std::make_unique>(); + + EXPECT_CALL(codec_factory_config, createCodecFactory(_, _)) + .WillOnce(Return(testing::ByMove(std::move(mock_codec_factory)))); + + Network::FilterFactoryCb cb = + factory.createFilterFactoryFromProto(config, factory_context).value(); + EXPECT_NE(nullptr, cb); + NiceMock filter_manager; + cb(filter_manager); +} + } // namespace } // namespace GenericProxy } // namespace NetworkFilters diff --git a/contrib/generic_proxy/filters/network/test/fake_codec.cc b/test/extensions/filters/network/generic_proxy/fake_codec.cc similarity index 90% rename from contrib/generic_proxy/filters/network/test/fake_codec.cc rename to test/extensions/filters/network/generic_proxy/fake_codec.cc index 83e42a3118b6..2eba57e0576a 100644 --- a/contrib/generic_proxy/filters/network/test/fake_codec.cc +++ b/test/extensions/filters/network/generic_proxy/fake_codec.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/test/fake_codec.h" +#include "test/extensions/filters/network/generic_proxy/fake_codec.h" #include diff --git a/contrib/generic_proxy/filters/network/test/fake_codec.h b/test/extensions/filters/network/generic_proxy/fake_codec.h similarity index 93% rename from contrib/generic_proxy/filters/network/test/fake_codec.h rename to test/extensions/filters/network/generic_proxy/fake_codec.h index b03e1a61f476..3c0b25bf9d3b 100644 --- a/contrib/generic_proxy/filters/network/test/fake_codec.h +++ b/test/extensions/filters/network/generic_proxy/fake_codec.h @@ -3,8 +3,8 @@ #include #include "source/common/buffer/buffer_impl.h" - -#include "contrib/generic_proxy/filters/network/source/interface/codec.h" +#include "source/extensions/filters/network/generic_proxy/access_log.h" +#include "source/extensions/filters/network/generic_proxy/interface/codec.h" namespace Envoy { namespace Extensions { @@ -43,7 +43,7 @@ template class FakeStreamBase : public InterfaceType { * Fake request message format: * FAKE-REQ|:;* * Fake response message format: - FAKE-RSP|:;* + * FAKE-RSP|:;* */ class FakeStreamCodecFactory : public CodecFactory { public: @@ -421,6 +421,30 @@ class FakeStreamCodecFactoryConfig : public CodecFactoryConfig { std::string name() const override { return "envoy.generic_proxy.codecs.fake"; } }; +class FakeAccessLogExtensionFilter : public AccessLogFilter { + bool evaluate(const FormatterContext&, const StreamInfo::StreamInfo&) const override { + return true; + } +}; + +class FakeAccessLogExtensionFilterFactory : public AccessLogFilterFactory { +public: + // AccessLogFilterFactory + AccessLogFilterPtr createFilter(const envoy::config::accesslog::v3::ExtensionFilter&, + Server::Configuration::FactoryContext&) override { + return std::make_unique(); + } + + std::set configTypes() override { + return {"envoy.generic_proxy.access_log.fake.type"}; + } + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return std::make_unique(); + } + std::string name() const override { return "envoy.generic_proxy.access_log.fake"; } +}; + } // namespace GenericProxy } // namespace NetworkFilters } // namespace Extensions diff --git a/contrib/generic_proxy/filters/network/test/integration_test.cc b/test/extensions/filters/network/generic_proxy/integration_test.cc similarity index 98% rename from contrib/generic_proxy/filters/network/test/integration_test.cc rename to test/extensions/filters/network/generic_proxy/integration_test.cc index f6c441f88f6a..73111aa899e6 100644 --- a/contrib/generic_proxy/filters/network/test/integration_test.cc +++ b/test/extensions/filters/network/generic_proxy/integration_test.cc @@ -4,16 +4,17 @@ #include #include +#include "source/extensions/filters/network/generic_proxy/proxy.h" + +#include "test/extensions/filters/network/generic_proxy/fake_codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/filter.h" +#include "test/extensions/filters/network/generic_proxy/mocks/route.h" #include "test/integration/base_integration_test.h" #include "test/mocks/server/factory_context.h" #include "test/test_common/registry.h" #include "test/test_common/utility.h" -#include "contrib/generic_proxy/filters/network/source/proxy.h" -#include "contrib/generic_proxy/filters/network/test/fake_codec.h" -#include "contrib/generic_proxy/filters/network/test/mocks/codec.h" -#include "contrib/generic_proxy/filters/network/test/mocks/filter.h" -#include "contrib/generic_proxy/filters/network/test/mocks/route.h" #include "gtest/gtest.h" namespace Envoy { diff --git a/contrib/generic_proxy/filters/network/test/match_test.cc b/test/extensions/filters/network/generic_proxy/match_test.cc similarity index 78% rename from contrib/generic_proxy/filters/network/test/match_test.cc rename to test/extensions/filters/network/generic_proxy/match_test.cc index 698d1742e5e3..f8004e58d893 100644 --- a/contrib/generic_proxy/filters/network/test/match_test.cc +++ b/test/extensions/filters/network/generic_proxy/match_test.cc @@ -1,9 +1,10 @@ #include +#include "source/extensions/filters/network/generic_proxy/match.h" + +#include "test/extensions/filters/network/generic_proxy/fake_codec.h" #include "test/mocks/server/factory_context.h" -#include "contrib/generic_proxy/filters/network/source/match.h" -#include "contrib/generic_proxy/filters/network/test/fake_codec.h" #include "gtest/gtest.h" using testing::NiceMock; @@ -116,18 +117,24 @@ TEST(RequestMatchDataInputTest, RequestMatchDataInputTest) { auto input = factory.createDataInputFactoryCb(*proto_config, factory_context.messageValidationVisitor())(); + EXPECT_EQ(input->dataInputType(), + "Envoy::Extensions::NetworkFilters::GenericProxy::RequestMatchData"); + FakeStreamCodecFactory::FakeRequest request; NiceMock stream_info; MatchInput match_input(request, stream_info, MatchAction::RouteAction); - EXPECT_EQ(&request, - &dynamic_cast( - absl::get>(input->get(match_input).data_) - .get()) - ->data() - .requestHeader()); + EXPECT_EQ(&request, &match_input.requestHeader()); + EXPECT_EQ(&stream_info, &match_input.streamInfo()); + EXPECT_EQ(MatchAction::RouteAction, match_input.expectAction()); + + auto custom_match_data = + absl::get>(input->get(match_input).data_); + EXPECT_EQ(&match_input, &dynamic_cast(custom_match_data.get())->data()); } +class FakeCustomMatchData : public Matcher::CustomMatchData {}; + TEST(RequestMatchInputMatcherTest, RequestMatchInputMatcherTest) { NiceMock factory_context; RequestMatchDataInputMatcherFactory factory; @@ -135,6 +142,9 @@ TEST(RequestMatchInputMatcherTest, RequestMatchInputMatcherTest) { auto matcher = factory.createInputMatcherFactoryCb(*proto_config, factory_context.serverFactoryContext())(); + EXPECT_EQ(*matcher->supportedDataInputTypes().begin(), + "Envoy::Extensions::NetworkFilters::GenericProxy::RequestMatchData"); + { Matcher::MatchingDataType input; EXPECT_FALSE(matcher->match(input)); @@ -145,6 +155,11 @@ TEST(RequestMatchInputMatcherTest, RequestMatchInputMatcherTest) { EXPECT_FALSE(matcher->match(input)); } + { + Matcher::MatchingDataType input = std::make_shared(); + EXPECT_FALSE(matcher->match(input)); + } + { FakeStreamCodecFactory::FakeRequest request; NiceMock stream_info; @@ -166,19 +181,27 @@ TEST(RequestMatchInputMatcherTest, SpecificRequestMatchInputMatcherTest) { EXPECT_TRUE(matcher.match(request)); } - // Host match failed. - { - RequestMatcherProto matcher_proto; + RequestMatcherProto matcher_proto; - const std::string config_yaml = R"EOF( + const std::string config_yaml = R"EOF( host: exact: fake_host + path: + exact: fake_path + method: + exact: fake_method + properties: + - name: key_0 + string_match: + exact: value_0 )EOF"; - TestUtility::loadFromYaml(config_yaml, matcher_proto); + TestUtility::loadFromYaml(config_yaml, matcher_proto); - RequestMatchInputMatcher matcher(matcher_proto, context.serverFactoryContext()); + RequestMatchInputMatcher matcher(matcher_proto, context.serverFactoryContext()); + // Host match failed. + { FakeStreamCodecFactory::FakeRequest request; request.host_ = "another_fake_host"; EXPECT_FALSE(matcher.match(request)); @@ -186,19 +209,6 @@ TEST(RequestMatchInputMatcherTest, SpecificRequestMatchInputMatcherTest) { // Path match failed. { - RequestMatcherProto matcher_proto; - - const std::string config_yaml = R"EOF( - host: - exact: fake_host - path: - exact: fake_path - )EOF"; - - TestUtility::loadFromYaml(config_yaml, matcher_proto); - - RequestMatchInputMatcher matcher(matcher_proto, context.serverFactoryContext()); - FakeStreamCodecFactory::FakeRequest request; request.host_ = "fake_host"; request.path_ = "another_fake_path"; @@ -207,21 +217,6 @@ TEST(RequestMatchInputMatcherTest, SpecificRequestMatchInputMatcherTest) { // Method match failed. { - RequestMatcherProto matcher_proto; - - const std::string config_yaml = R"EOF( - host: - exact: fake_host - path: - exact: fake_path - method: - exact: fake_method - )EOF"; - - TestUtility::loadFromYaml(config_yaml, matcher_proto); - - RequestMatchInputMatcher matcher(matcher_proto, context.serverFactoryContext()); - FakeStreamCodecFactory::FakeRequest request; request.host_ = "fake_host"; request.path_ = "fake_path"; @@ -231,24 +226,6 @@ TEST(RequestMatchInputMatcherTest, SpecificRequestMatchInputMatcherTest) { // Property match failed. { - RequestMatcherProto matcher_proto; - - const std::string config_yaml = R"EOF( - host: - exact: fake_host - path: - exact: fake_path - method: - exact: fake_method - properties: - - name: key_0 - string_match: - exact: value_0 - )EOF"; - - TestUtility::loadFromYaml(config_yaml, matcher_proto); - - RequestMatchInputMatcher matcher(matcher_proto, context.serverFactoryContext()); FakeStreamCodecFactory::FakeRequest request; request.host_ = "fake_host"; @@ -258,27 +235,17 @@ TEST(RequestMatchInputMatcherTest, SpecificRequestMatchInputMatcherTest) { EXPECT_FALSE(matcher.match(request)); } - // All match. + // Property is missing. { - RequestMatcherProto matcher_proto; - - const std::string config_yaml = R"EOF( - host: - exact: fake_host - path: - exact: fake_path - method: - exact: fake_method - properties: - - name: key_0 - string_match: - exact: value_0 - )EOF"; - - TestUtility::loadFromYaml(config_yaml, matcher_proto); - - RequestMatchInputMatcher matcher(matcher_proto, context.serverFactoryContext()); + FakeStreamCodecFactory::FakeRequest request; + request.host_ = "fake_host"; + request.path_ = "fake_path"; + request.method_ = "fake_method"; + EXPECT_FALSE(matcher.match(request)); + } + // All match. + { FakeStreamCodecFactory::FakeRequest request; request.host_ = "fake_host"; request.path_ = "fake_path"; diff --git a/contrib/generic_proxy/filters/network/test/mocks/BUILD b/test/extensions/filters/network/generic_proxy/mocks/BUILD similarity index 62% rename from contrib/generic_proxy/filters/network/test/mocks/BUILD rename to test/extensions/filters/network/generic_proxy/mocks/BUILD index 9599804e0706..bbec71ba2c33 100644 --- a/contrib/generic_proxy/filters/network/test/mocks/BUILD +++ b/test/extensions/filters/network/generic_proxy/mocks/BUILD @@ -1,21 +1,20 @@ load( "//bazel:envoy_build_system.bzl", "envoy_cc_mock", - "envoy_contrib_package", + "envoy_package", ) licenses(["notice"]) # Apache 2 -envoy_contrib_package() +envoy_package() envoy_cc_mock( name = "filter_mocks", srcs = ["filter.cc"], hdrs = ["filter.h"], deps = [ - "//contrib/generic_proxy/filters/network/source/interface:config_interface", - "//contrib/generic_proxy/filters/network/source/interface:filter_interface", "//source/common/protobuf", + "//source/extensions/filters/network/generic_proxy/interface:filter_interface", "//test/mocks/network:network_mocks", "//test/mocks/tcp:tcp_mocks", "//test/mocks/upstream:host_mocks", @@ -27,8 +26,8 @@ envoy_cc_mock( srcs = ["route.cc"], hdrs = ["route.h"], deps = [ - "//contrib/generic_proxy/filters/network/source/interface:route_interface", "//source/common/config:metadata_lib", + "//source/extensions/filters/network/generic_proxy:route_interface", ], ) @@ -37,6 +36,6 @@ envoy_cc_mock( srcs = ["codec.cc"], hdrs = ["codec.h"], deps = [ - "//contrib/generic_proxy/filters/network/source/interface:codec_interface", + "//source/extensions/filters/network/generic_proxy/interface:codec_interface", ], ) diff --git a/contrib/generic_proxy/filters/network/test/mocks/codec.cc b/test/extensions/filters/network/generic_proxy/mocks/codec.cc similarity index 90% rename from contrib/generic_proxy/filters/network/test/mocks/codec.cc rename to test/extensions/filters/network/generic_proxy/mocks/codec.cc index 049076ef808c..67b421606133 100644 --- a/contrib/generic_proxy/filters/network/test/mocks/codec.cc +++ b/test/extensions/filters/network/generic_proxy/mocks/codec.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/test/mocks/codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/codec.h" #include diff --git a/contrib/generic_proxy/filters/network/test/mocks/codec.h b/test/extensions/filters/network/generic_proxy/mocks/codec.h similarity index 97% rename from contrib/generic_proxy/filters/network/test/mocks/codec.h rename to test/extensions/filters/network/generic_proxy/mocks/codec.h index baff48a13746..e1c7ff8c167e 100644 --- a/contrib/generic_proxy/filters/network/test/mocks/codec.h +++ b/test/extensions/filters/network/generic_proxy/mocks/codec.h @@ -1,6 +1,7 @@ #pragma once -#include "contrib/generic_proxy/filters/network/source/interface/codec.h" +#include "source/extensions/filters/network/generic_proxy/interface/codec.h" + #include "gmock/gmock.h" namespace Envoy { diff --git a/contrib/generic_proxy/filters/network/test/mocks/filter.cc b/test/extensions/filters/network/generic_proxy/mocks/filter.cc similarity index 97% rename from contrib/generic_proxy/filters/network/test/mocks/filter.cc rename to test/extensions/filters/network/generic_proxy/mocks/filter.cc index 4e3a4815a666..4e5e3cf48726 100644 --- a/contrib/generic_proxy/filters/network/test/mocks/filter.cc +++ b/test/extensions/filters/network/generic_proxy/mocks/filter.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/test/mocks/filter.h" +#include "test/extensions/filters/network/generic_proxy/mocks/filter.h" #include diff --git a/contrib/generic_proxy/filters/network/test/mocks/filter.h b/test/extensions/filters/network/generic_proxy/mocks/filter.h similarity index 95% rename from contrib/generic_proxy/filters/network/test/mocks/filter.h rename to test/extensions/filters/network/generic_proxy/mocks/filter.h index 1a52ac450f24..492e431e72c3 100644 --- a/contrib/generic_proxy/filters/network/test/mocks/filter.h +++ b/test/extensions/filters/network/generic_proxy/mocks/filter.h @@ -1,10 +1,10 @@ #pragma once +#include "source/extensions/filters/network/generic_proxy/interface/filter.h" + #include "test/mocks/tcp/mocks.h" #include "test/mocks/upstream/host.h" -#include "contrib/generic_proxy/filters/network/source/interface/config.h" -#include "contrib/generic_proxy/filters/network/source/interface/filter.h" #include "gmock/gmock.h" namespace Envoy { @@ -106,7 +106,6 @@ template class MockStreamFilterCallbacks : public Base { MOCK_METHOD(const CodecFactory&, codecFactory, ()); MOCK_METHOD(const RouteEntry*, routeEntry, (), (const)); MOCK_METHOD(const RouteSpecificFilterConfig*, perFilterConfig, (), (const)); - MOCK_METHOD(const StreamInfo::StreamInfo&, streamInfo, (), (const)); MOCK_METHOD(StreamInfo::StreamInfo&, streamInfo, ()); MOCK_METHOD(Tracing::Span&, activeSpan, ()); MOCK_METHOD(OptRef, tracingConfig, (), (const)); diff --git a/contrib/generic_proxy/filters/network/test/mocks/route.cc b/test/extensions/filters/network/generic_proxy/mocks/route.cc similarity index 91% rename from contrib/generic_proxy/filters/network/test/mocks/route.cc rename to test/extensions/filters/network/generic_proxy/mocks/route.cc index f92069623542..e5f5897d0602 100644 --- a/contrib/generic_proxy/filters/network/test/mocks/route.cc +++ b/test/extensions/filters/network/generic_proxy/mocks/route.cc @@ -1,4 +1,4 @@ -#include "contrib/generic_proxy/filters/network/test/mocks/route.h" +#include "test/extensions/filters/network/generic_proxy/mocks/route.h" using testing::_; using testing::Return; diff --git a/contrib/generic_proxy/filters/network/test/mocks/route.h b/test/extensions/filters/network/generic_proxy/mocks/route.h similarity index 94% rename from contrib/generic_proxy/filters/network/test/mocks/route.h rename to test/extensions/filters/network/generic_proxy/mocks/route.h index e8efa8cfd336..322a28727152 100644 --- a/contrib/generic_proxy/filters/network/test/mocks/route.h +++ b/test/extensions/filters/network/generic_proxy/mocks/route.h @@ -1,8 +1,8 @@ #pragma once #include "source/common/config/metadata.h" +#include "source/extensions/filters/network/generic_proxy/route.h" -#include "contrib/generic_proxy/filters/network/source/interface/route.h" #include "gmock/gmock.h" namespace Envoy { diff --git a/contrib/generic_proxy/filters/network/test/proxy_test.cc b/test/extensions/filters/network/generic_proxy/proxy_test.cc similarity index 77% rename from contrib/generic_proxy/filters/network/test/proxy_test.cc rename to test/extensions/filters/network/generic_proxy/proxy_test.cc index 75246e829e3f..6f6121a64d8e 100644 --- a/contrib/generic_proxy/filters/network/test/proxy_test.cc +++ b/test/extensions/filters/network/generic_proxy/proxy_test.cc @@ -3,16 +3,16 @@ #include #include "source/common/tracing/tracer_manager_impl.h" +#include "source/extensions/filters/network/generic_proxy/proxy.h" +#include "test/extensions/filters/network/generic_proxy/fake_codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/filter.h" +#include "test/extensions/filters/network/generic_proxy/mocks/route.h" #include "test/mocks/server/factory_context.h" #include "test/test_common/registry.h" #include "test/test_common/utility.h" -#include "contrib/generic_proxy/filters/network/source/proxy.h" -#include "contrib/generic_proxy/filters/network/test/fake_codec.h" -#include "contrib/generic_proxy/filters/network/test/mocks/codec.h" -#include "contrib/generic_proxy/filters/network/test/mocks/filter.h" -#include "contrib/generic_proxy/filters/network/test/mocks/route.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -29,7 +29,7 @@ namespace { static const std::string DEFAULT_LOG_FORMAT = "%HOST% %PATH% %METHOD% %PROTOCOL% %REQUEST_PROPERTY(request-key)% " "%RESPONSE_PROPERTY(response-key)% " - "%REQUEST_PROPERTY(non-exist-key)% %RESPONSE_CODE% %RESPONSE_CODE_DETAILS%"; + "%REQUEST_PROPERTY(non-exist-key)% %GENERIC_RESPONSE_CODE% %RESPONSE_CODE_DETAILS%"; class MockRouteConfigProvider : public Rds::RouteConfigProvider { public: @@ -45,12 +45,14 @@ class MockRouteConfigProvider : public Rds::RouteConfigProvider { class FilterConfigTest : public testing::Test { public: - void initializeFilterConfig(bool with_tracing = false, AccessLogInstanceSharedPtr logger = {}) { + void initializeFilterConfig(bool with_tracing = false, AccessLogInstanceSharedPtr logger = {}, + bool allow_no_decoder_filter = false) { if (with_tracing) { tracer_ = std::make_shared>(); const std::string tracing_config_yaml = R"EOF( - max_path_tag_length: 128 + max_path_tag_length: 256 + spawn_upstream_span: true )EOF"; Tracing::ConnectionManagerTracingConfigProto tracing_config; @@ -63,7 +65,7 @@ class FilterConfigTest : public testing::Test { std::vector factories; - if (mock_decoder_filters_.empty() && mock_stream_filters_.empty()) { + if (mock_decoder_filters_.empty() && mock_stream_filters_.empty() && !allow_no_decoder_filter) { // At least one decoder filter for generic proxy. mock_decoder_filters_.push_back( {"mock_default_decoder_filter", std::make_shared>()}); @@ -187,8 +189,9 @@ TEST_F(FilterConfigTest, CodecFactory) { class FilterTest : public FilterConfigTest { public: - void initializeFilter(bool with_tracing = false, AccessLogInstanceSharedPtr logger = {}) { - FilterConfigTest::initializeFilterConfig(with_tracing, logger); + void initializeFilter(bool with_tracing = false, AccessLogInstanceSharedPtr logger = {}, + bool allow_no_decoder_filter = false) { + FilterConfigTest::initializeFilterConfig(with_tracing, logger, allow_no_decoder_filter); auto server_codec = std::make_unique>(); server_codec_ = server_codec.get(); @@ -292,7 +295,7 @@ TEST_F(FilterTest, OnConnectionClosedEvent) { Buffer::OwnedImpl fake_empty_buffer; - // Return directly. + // Return directly if connection is closed. EXPECT_EQ(Network::FilterStatus::StopIteration, filter_->onData(fake_empty_buffer, false)); } @@ -300,42 +303,70 @@ TEST_F(FilterTest, GetConnection) { initializeFilter(); EXPECT_EQ(&(filter_callbacks_.connection_), &filter_->downstreamConnection()); + // Return valid connection if connection is not closed. + EXPECT_EQ(&(filter_callbacks_.connection_), filter_->connection().ptr()); + + // Mock connection close. + filter_callbacks_.connection_.close(Network::ConnectionCloseType::NoFlush); + + EXPECT_EQ(&(filter_callbacks_.connection_), &filter_->downstreamConnection()); + // Return nullopt if connection is closed. + EXPECT_EQ(nullptr, filter_->connection().ptr()); } -TEST_F(FilterTest, NewStreamAndResetStream) { +TEST_F(FilterTest, BufferWaterMarkTest) { initializeFilter(); + filter_->onAboveWriteBufferHighWatermark(); + filter_->onBelowWriteBufferLowWatermark(); +} - auto request = std::make_unique(); +TEST_F(FilterTest, NullHeaderFrame) { + initializeFilter(); - filter_->onDecodingSuccess(std::move(request)); - EXPECT_EQ(1, filter_->activeStreamsForTest().size()); + EXPECT_CALL(filter_callbacks_.connection_, close(_)); + filter_->onDecodingSuccess(nullptr, {}); - EXPECT_EQ(filter_config_->stats().downstream_rq_total_.value(), 1); - EXPECT_EQ(filter_config_->stats().downstream_rq_active_.value(), 1); + // Calling again will not cause any issue. + filter_->onDecodingSuccess(nullptr, {}); +} - auto active_stream = filter_->activeStreamsForTest().begin()->get(); - active_stream->resetStream(DownstreamStreamResetReason::ConnectionTermination); +TEST_F(FilterTest, NullCommonFrame) { + initializeFilter(); - EXPECT_EQ(0, filter_->activeStreamsForTest().size()); + EXPECT_CALL(filter_callbacks_.connection_, close(_)); + filter_->onDecodingSuccess(RequestCommonFramePtr(nullptr)); - EXPECT_EQ(filter_config_->stats().downstream_rq_total_.value(), 1); - EXPECT_EQ(filter_config_->stats().downstream_rq_active_.value(), 0); - EXPECT_EQ(filter_config_->stats().downstream_rq_reset_.value(), 1); + // Calling again will not cause any issue. + filter_->onDecodingSuccess(RequestCommonFramePtr(nullptr)); +} - EXPECT_EQ( - factory_context_.store_.counter("generic_proxy.test_prefix.downstream_rq_flag.DC").value(), - 1); +TEST_F(FilterTest, RepeatedStreamIdForTwoStreams) { + initializeFilter(); + + auto request_0 = std::make_unique(); + request_0->stream_frame_flags_ = {0, FrameFlags::FLAG_EMPTY}; + auto request_1 = std::make_unique(); + request_1->stream_frame_flags_ = {0, FrameFlags::FLAG_EMPTY}; + + filter_->onDecodingSuccess(std::move(request_0)); + + EXPECT_EQ(1, filter_->activeStreamsForTest().size()); + + EXPECT_CALL(filter_callbacks_.connection_, close(_)); + filter_->onDecodingSuccess(std::move(request_1)); + + EXPECT_EQ(0, filter_->activeStreamsForTest().size()); } -TEST_F(FilterTest, SimpleBufferWaterMarkTest) { +TEST_F(FilterTest, CommonFrameBeforeHeaderFrame) { initializeFilter(); - filter_->onAboveWriteBufferHighWatermark(); - filter_->onBelowWriteBufferLowWatermark(); + + auto request_frame = std::make_unique(); + EXPECT_CALL(filter_callbacks_.connection_, close(_)); + filter_->onDecodingSuccess(std::move(request_frame)); } TEST_F(FilterTest, NewStreamAndDispatcher) { - mock_stream_filters_.push_back({"mock_0", std::make_shared>()}); - initializeFilter(); auto request = std::make_unique(); @@ -346,13 +377,14 @@ TEST_F(FilterTest, NewStreamAndDispatcher) { EXPECT_EQ(filter_config_->stats().downstream_rq_total_.value(), 1); EXPECT_EQ(filter_config_->stats().downstream_rq_active_.value(), 1); - auto active_stream = filter_->activeStreamsForTest().begin()->get(); - - EXPECT_EQ(&active_stream->decoderFiltersForTest()[0]->dispatcher(), &active_stream->dispatcher()); + EXPECT_EQ("mock_default_decoder_filter", + mock_decoder_filters_[0].second->decoder_callbacks_->filterConfigName()); + mock_decoder_filters_[0].second->decoder_callbacks_->dispatcher(); } TEST_F(FilterTest, NewStreamWithStartTime) { - mock_stream_filters_.push_back({"mock_0", std::make_shared>()}); + auto mock_stream_filter_0 = std::make_shared>(); + mock_stream_filters_.push_back({"mock_0", mock_stream_filter_0}); initializeFilter(); @@ -365,12 +397,15 @@ TEST_F(FilterTest, NewStreamWithStartTime) { std::chrono::time_point(std::chrono::milliseconds(222222222)); filter_->onDecodingSuccess(std::move(request), std::move(start_time)); - auto active_stream = filter_->activeStreamsForTest().begin()->get(); - EXPECT_EQ(111111111LL, std::chrono::duration_cast( - active_stream->streamInfo().startTime().time_since_epoch()) - .count()); + EXPECT_EQ( + 111111111LL, + std::chrono::duration_cast( + mock_stream_filter_0->decoder_callbacks_->streamInfo().startTime().time_since_epoch()) + .count()); EXPECT_EQ(222222222LL, std::chrono::duration_cast( - active_stream->streamInfo().startTimeMonotonic().time_since_epoch()) + mock_stream_filter_0->decoder_callbacks_->streamInfo() + .startTimeMonotonic() + .time_since_epoch()) .count()); } @@ -426,7 +461,7 @@ TEST_F(FilterTest, OnEncodingFailureWithActiveStreams) { EXPECT_CALL(*server_codec_, encode(_, _)) .WillOnce(Return(EncodingResult{absl::InvalidArgumentError("encoding-error")})); auto response_0 = std::make_unique(); - filter_->activeStreamsForTest().begin()->get()->onResponseHeaderFrame(std::move(response_0)); + mock_decoder_filters_[0].second->decoder_callbacks_->onResponseHeaderFrame(std::move(response_0)); EXPECT_EQ(1, filter_->activeStreamsForTest().size()); @@ -465,18 +500,9 @@ TEST_F(FilterTest, ActiveStreamPerFilterConfig) { filter_->onDecodingSuccess(std::move(request)); EXPECT_EQ(1, filter_->activeStreamsForTest().size()); - auto active_stream = filter_->activeStreamsForTest().begin()->get(); - - EXPECT_EQ(1, active_stream->decoderFiltersForTest().size()); - EXPECT_EQ(1, active_stream->encoderFiltersForTest().size()); - EXPECT_EQ(active_stream->decoderFiltersForTest().end(), - active_stream->nextDecoderHeaderFilterForTest()); - EXPECT_EQ(active_stream->encoderFiltersForTest().begin(), - active_stream->nextEncoderHeaderFilterForTest()); - EXPECT_CALL(*mock_route_entry_, perFilterConfig("fake_test_filter_name_0")) .WillOnce(Return(nullptr)); - EXPECT_EQ(nullptr, active_stream->decoderFiltersForTest()[0]->perFilterConfig()); + EXPECT_EQ(nullptr, mock_stream_filters_[0].second->decoder_callbacks_->perFilterConfig()); } TEST_F(FilterTest, ActiveStreamPerFilterConfigNoRouteEntry) { @@ -491,16 +517,7 @@ TEST_F(FilterTest, ActiveStreamPerFilterConfigNoRouteEntry) { filter_->onDecodingSuccess(std::move(request)); EXPECT_EQ(1, filter_->activeStreamsForTest().size()); - auto active_stream = filter_->activeStreamsForTest().begin()->get(); - - EXPECT_EQ(1, active_stream->decoderFiltersForTest().size()); - EXPECT_EQ(1, active_stream->encoderFiltersForTest().size()); - EXPECT_EQ(active_stream->decoderFiltersForTest().end(), - active_stream->nextDecoderHeaderFilterForTest()); - EXPECT_EQ(active_stream->encoderFiltersForTest().begin(), - active_stream->nextEncoderHeaderFilterForTest()); - - EXPECT_EQ(nullptr, active_stream->decoderFiltersForTest()[0]->perFilterConfig()); + EXPECT_EQ(nullptr, mock_stream_filters_[0].second->decoder_callbacks_->perFilterConfig()); } TEST_F(FilterTest, ActiveStreamConnection) { @@ -513,17 +530,20 @@ TEST_F(FilterTest, ActiveStreamConnection) { filter_->onDecodingSuccess(std::move(request)); EXPECT_EQ(1, filter_->activeStreamsForTest().size()); - auto active_stream = filter_->activeStreamsForTest().begin()->get(); + EXPECT_EQ(&filter_callbacks_.connection_, + mock_stream_filters_[0].second->decoder_callbacks_->connection()); +} - EXPECT_EQ(1, active_stream->decoderFiltersForTest().size()); - EXPECT_EQ(1, active_stream->encoderFiltersForTest().size()); - EXPECT_EQ(active_stream->decoderFiltersForTest().end(), - active_stream->nextDecoderHeaderFilterForTest()); - EXPECT_EQ(active_stream->encoderFiltersForTest().begin(), - active_stream->nextEncoderHeaderFilterForTest()); +TEST_F(FilterTest, ActiveStreamNoDecoderFilter) { + initializeFilter(false, loggerFormFormat(), true); - EXPECT_EQ(&filter_callbacks_.connection_, - active_stream->decoderFiltersForTest()[0]->connection()); + auto request = std::make_unique(); + + filter_->onDecodingSuccess(std::move(request)); + EXPECT_EQ(0, filter_->activeStreamsForTest().size()); + + // The stream will be reset directly. + EXPECT_EQ(filter_config_->stats().downstream_rq_reset_.value(), 1); } TEST_F(FilterTest, ActiveStreamAddFilters) { @@ -647,7 +667,7 @@ TEST_F(FilterTest, ActiveStreamSingleFrameFiltersContinueDecodingAfterSendLocalR EXPECT_CALL(*mock_stream_filter_1, decodeHeaderFrame(_)) .WillOnce(Invoke([&](const RequestHeaderFrame&) { - EXPECT_CALL(*server_codec_, encode(_, _)); + EXPECT_CALL(*server_codec_, encode(_, _)); // Local reply will be encoded and sent. active_stream->sendLocalReply(Status(StatusCode::kUnknown, "test_detail"), {}, nullptr); // Make no sense because the filter chain will be always stopped if // the stream is reset or completed. @@ -655,17 +675,20 @@ TEST_F(FilterTest, ActiveStreamSingleFrameFiltersContinueDecodingAfterSendLocalR })); mock_stream_filter_0->decoder_callbacks_->continueDecoding(); - // Decoding is stopped when `decodeHeaderFrame` of `mock_stream_filter_1` is called. - // Next filter is still `mock_1` because the iter is not increased. + // Stream is reset or complete when `decodeHeaderFrame` of `mock_stream_filter_1` is called. + // Next filter is still `mock_1` because the iterator is not increased. EXPECT_EQ("mock_1", (*active_stream->nextDecoderHeaderFilterForTest())->filterConfigName()); mock_stream_filter_1->decoder_callbacks_->continueDecoding(); // The stream is reset after `sendLocalReply` is called and continue decoding will be ignored. EXPECT_EQ("mock_1", (*active_stream->nextDecoderHeaderFilterForTest())->filterConfigName()); + + EXPECT_EQ(filter_config_->stats().downstream_rq_reset_.value(), 0); + EXPECT_EQ(filter_config_->stats().downstream_rq_local_.value(), 1); } -TEST_F(FilterTest, ActiveStreamSingleFrameFiltersContinueEncoding) { +TEST_F(FilterTest, FilterSendLocalReplyButRespondReturnNull) { auto mock_stream_filter_0 = std::make_shared>(); auto mock_stream_filter_1 = std::make_shared>(); auto mock_stream_filter_2 = std::make_shared>(); @@ -676,12 +699,45 @@ TEST_F(FilterTest, ActiveStreamSingleFrameFiltersContinueEncoding) { initializeFilter(); + EXPECT_CALL(*mock_stream_filter_0, decodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::StopIteration)); + + auto request = std::make_unique(); + filter_->onDecodingSuccess(std::move(request)); + auto active_stream = filter_->activeStreamsForTest().begin()->get(); + + EXPECT_CALL(*server_codec_, respond(_, _, _)).WillOnce(Return(ByMove(nullptr))); + EXPECT_CALL(*mock_stream_filter_1, decodeHeaderFrame(_)) + .WillOnce(Invoke([&](const RequestHeaderFrame&) { + // No response will be sent and stream will be reset directly. + active_stream->sendLocalReply(Status(StatusCode::kUnknown, "test_detail"), {}, nullptr); + // Make no sense because the filter chain will be always stopped if + // the stream is reset or completed. + return HeaderFilterStatus::StopIteration; + })); + mock_stream_filter_0->decoder_callbacks_->continueDecoding(); + + EXPECT_EQ(filter_config_->stats().downstream_rq_reset_.value(), 1); + EXPECT_EQ(filter_config_->stats().downstream_rq_local_.value(), 0); +} + +TEST_F(FilterTest, ActiveStreamSingleFrameFiltersContinueEncoding) { + auto mock_encoder_filter_0 = std::make_shared>(); + auto mock_encoder_filter_1 = std::make_shared>(); + auto mock_encoder_filter_2 = std::make_shared>(); + + mock_encoder_filters_ = {{"mock_0", mock_encoder_filter_0}, + {"mock_1", mock_encoder_filter_1}, + {"mock_2", mock_encoder_filter_2}}; + + initializeFilter(); + auto request = std::make_unique(); filter_->onDecodingSuccess(std::move(request)); auto active_stream = filter_->activeStreamsForTest().begin()->get(); - EXPECT_CALL(*mock_stream_filter_2, encodeHeaderFrame(_)) + EXPECT_CALL(*mock_encoder_filter_2, encodeHeaderFrame(_)) .WillOnce(Return(HeaderFilterStatus::StopIteration)); auto response = std::make_unique(); @@ -692,10 +748,10 @@ TEST_F(FilterTest, ActiveStreamSingleFrameFiltersContinueEncoding) { // Next filter is `mock_1`. EXPECT_EQ("mock_1", (*active_stream->nextEncoderHeaderFilterForTest())->filterConfigName()); - EXPECT_CALL(*mock_stream_filter_1, encodeHeaderFrame(_)) + EXPECT_CALL(*mock_encoder_filter_1, encodeHeaderFrame(_)) .WillOnce(Return(HeaderFilterStatus::StopIteration)); - mock_stream_filter_2->encoder_callbacks_->continueEncoding(); + mock_encoder_filter_2->encoder_callbacks_->continueEncoding(); // Encoding is stopped when `encodeHeaderFrame` of `mock_stream_filter_1` is called. // Next filter is `mock_0`. @@ -713,7 +769,7 @@ TEST_F(FilterTest, ActiveStreamSingleFrameFiltersContinueEncoding) { return EncodingResult{4}; })); - mock_stream_filter_1->encoder_callbacks_->continueEncoding(); + mock_encoder_filter_1->encoder_callbacks_->continueEncoding(); } TEST_F(FilterTest, ActiveStreamSingleFrameFiltersContinueEncodingButResponseEncodingFailure) { @@ -799,7 +855,7 @@ TEST_F(FilterTest, ActiveStreamSingleFrameFiltersContinueEncodingAfterSendLocalR mock_stream_filter_2->encoder_callbacks_->continueEncoding(); // Encoding will be stopped when `encodeHeaderFrame` of `mock_stream_filter_1` is called. - // Next filter is still `mock_1` because the iter is not increased. + // Next filter is still `mock_1` because the iterator is not increased. EXPECT_EQ("mock_1", (*active_stream->nextEncoderHeaderFilterForTest())->filterConfigName()); mock_stream_filter_1->encoder_callbacks_->continueEncoding(); @@ -881,7 +937,7 @@ TEST_F(FilterTest, ActiveStreamMultipleFrameFiltersContinueDecoding) { EXPECT_EQ("mock_0", (*active_stream->nextDecoderCommonFilterForTest())->filterConfigName()); EXPECT_CALL(mock_request_frames_handler, onRequestCommonFrame(_)); - // The last common frame will be handled dircetly because all the previous common frames are + // The last common frame will be handled directly because all the previous common frames are // completed and the filter chain will not be stopped by the last common frame. filter_->onDecodingSuccess(std::move(request_frame_2)); } @@ -977,7 +1033,7 @@ TEST_F(FilterTest, ActiveStreamMultipleFrameFiltersContinueEncoding) { EXPECT_CALL(*server_codec_, encode(_, _)) .WillOnce(Invoke([](const StreamFrame&, EncodingContext&) { return EncodingResult{0}; })); - // The last common frame will be handled dircetly because all the previous common frames are + // The last common frame will be handled directly because all the previous common frames are // completed. active_stream->onResponseCommonFrame(std::move(response_frame_2)); } @@ -1205,24 +1261,115 @@ TEST_F(FilterTest, ActiveStreamSendLocalReply) { request->protocol_ = "protocol-value"; request->data_["request-key"] = "request-value"; - filter_->onDecodingSuccess(std::move(request)); - EXPECT_EQ(1, filter_->activeStreamsForTest().size()); + testing::InSequence s; - EXPECT_EQ(filter_config_->stats().downstream_rq_total_.value(), 1); - EXPECT_EQ(filter_config_->stats().downstream_rq_active_.value(), 1); - EXPECT_EQ(filter_config_->stats().downstream_rq_local_.value(), 0); + // Decoder filter chain processing. + EXPECT_CALL(*mock_stream_filter_0, decodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_1, decodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_2, decodeHeaderFrame(_)).WillOnce(Invoke([&](auto&) { + mock_stream_filter_2->decoder_callbacks_->sendLocalReply( + Status(StatusCode::kUnknown, "test_detail"), {}, + [](StreamResponse& response) { response.set("response-key", "response-value"); }); + return HeaderFilterStatus::StopIteration; + })); - auto active_stream = filter_->activeStreamsForTest().begin()->get(); + // Encoder filter chain processing. + EXPECT_CALL(*mock_stream_filter_2, encodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_1, encodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_0, encodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + // Send reply to the downstream. + EXPECT_CALL(*server_codec_, encode(_, _)) + .WillOnce(Invoke([&](const StreamFrame& response, EncodingContext&) { + Buffer::OwnedImpl buffer; + EXPECT_EQ(dynamic_cast(&response)->status().code(), + static_cast(StatusCode::kUnknown)); + buffer.add("test"); + + server_codec_callbacks_->writeToConnection(buffer); + buffer.drain(buffer.length()); + + return EncodingResult{4}; + })); + EXPECT_CALL(filter_callbacks_.connection_, write(BufferStringEqual("test"), false)); + + // Clean up the stream and log the access log. + EXPECT_CALL(filter_callbacks_.connection_.dispatcher_, deferredDelete_(_)); EXPECT_CALL(*factory_context_.server_factory_context_.access_log_manager_.file_, write("host-value /path-value method-value protocol-value request-value " "response-value - 2 test_detail")); + // Check the drain manager. EXPECT_CALL(factory_context_.drain_manager_, drainClose()).WillOnce(Return(false)); - EXPECT_CALL(filter_callbacks_.connection_.dispatcher_, deferredDelete_(_)); - EXPECT_CALL(filter_callbacks_.connection_, write(BufferStringEqual("test"), false)); + filter_->onDecodingSuccess(std::move(request)); + + EXPECT_EQ(filter_config_->stats().downstream_rq_total_.value(), 1); + EXPECT_EQ(filter_config_->stats().downstream_rq_active_.value(), 0); + EXPECT_EQ(filter_config_->stats().downstream_rq_local_.value(), 1); +} + +TEST_F(FilterTest, ActiveStreamSendLocalReplyWhenProcessingBody) { + auto mock_stream_filter_0 = std::make_shared>(); + auto mock_stream_filter_1 = std::make_shared>(); + auto mock_stream_filter_2 = std::make_shared>(); + + mock_stream_filters_ = {{"mock_0", mock_stream_filter_0}, + {"mock_1", mock_stream_filter_1}, + {"mock_2", mock_stream_filter_2}}; + + initializeFilter(false, loggerFormFormat()); + auto request = std::make_unique(); + request->host_ = "host-value"; + request->path_ = "/path-value"; + request->method_ = "method-value"; + request->protocol_ = "protocol-value"; + request->data_["request-key"] = "request-value"; + request->stream_frame_flags_ = FrameFlags(0, FrameFlags::FLAG_EMPTY); + + testing::InSequence s1; + // Decoder filter chain processing for header frame. + EXPECT_CALL(*mock_stream_filter_0, decodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_1, decodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_2, decodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + + filter_->onDecodingSuccess(std::move(request)); + + EXPECT_EQ(filter_config_->stats().downstream_rq_total_.value(), 1); + EXPECT_EQ(filter_config_->stats().downstream_rq_active_.value(), 1); + EXPECT_EQ(filter_config_->stats().downstream_rq_local_.value(), 0); + + testing::InSequence s2; + // Decoder filter chain processing for common frame. + EXPECT_CALL(*mock_stream_filter_0, decodeCommonFrame(_)) + .WillOnce(Return(CommonFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_1, decodeCommonFrame(_)) + .WillOnce(Return(CommonFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_2, decodeCommonFrame(_)).WillOnce(Invoke([&](auto&) { + mock_stream_filter_2->decoder_callbacks_->sendLocalReply( + Status(StatusCode::kUnknown, "test_detail"), {}, + [](StreamResponse& response) { response.set("response-key", "response-value"); }); + return CommonFilterStatus::StopIteration; + })); + + // Encoder filter chain processing. + EXPECT_CALL(*mock_stream_filter_2, encodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_1, encodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_0, encodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + + // Send reply to the downstream. EXPECT_CALL(*server_codec_, encode(_, _)) .WillOnce(Invoke([&](const StreamFrame& response, EncodingContext&) { Buffer::OwnedImpl buffer; @@ -1235,8 +1382,83 @@ TEST_F(FilterTest, ActiveStreamSendLocalReply) { return EncodingResult{4}; })); + EXPECT_CALL(filter_callbacks_.connection_, write(BufferStringEqual("test"), false)); - testing::InSequence s; + // Clean up the stream and log the access log. + EXPECT_CALL(filter_callbacks_.connection_.dispatcher_, deferredDelete_(_)); + EXPECT_CALL(*factory_context_.server_factory_context_.access_log_manager_.file_, + write("host-value /path-value method-value protocol-value request-value " + "response-value - 2 test_detail")); + + // Check the drain manager. + EXPECT_CALL(factory_context_.drain_manager_, drainClose()).WillOnce(Return(false)); + + auto request_frame = std::make_unique(); + filter_->onDecodingSuccess(std::move(request_frame)); + + EXPECT_EQ(filter_config_->stats().downstream_rq_total_.value(), 1); + EXPECT_EQ(filter_config_->stats().downstream_rq_active_.value(), 0); + EXPECT_EQ(filter_config_->stats().downstream_rq_local_.value(), 1); +} + +TEST_F(FilterTest, ActiveStreamSendLocalReplyWhenTransferringBody) { + NiceMock mock_request_frames_handler; + + auto mock_stream_filter_0 = std::make_shared>(); + auto mock_stream_filter_1 = std::make_shared>(); + auto mock_stream_filter_2 = std::make_shared>(); + + mock_stream_filters_ = {{"mock_0", mock_stream_filter_0}, + {"mock_1", mock_stream_filter_1}, + {"mock_2", mock_stream_filter_2}}; + + // Set the request handler. + ON_CALL(*mock_stream_filter_2, setDecoderFilterCallbacks(_)).WillByDefault(Invoke([&](auto& cb) { + mock_stream_filter_2->decoder_callbacks_ = &cb; + cb.setRequestFramesHandler(&mock_request_frames_handler); + })); + + initializeFilter(false, loggerFormFormat()); + + auto request = std::make_unique(); + request->host_ = "host-value"; + request->path_ = "/path-value"; + request->method_ = "method-value"; + request->protocol_ = "protocol-value"; + request->data_["request-key"] = "request-value"; + request->stream_frame_flags_ = FrameFlags(0, FrameFlags::FLAG_EMPTY); + + testing::InSequence s1; + // Decoder filter chain processing for header frame. + EXPECT_CALL(*mock_stream_filter_0, decodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_1, decodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_2, decodeHeaderFrame(_)) + .WillOnce(Return(HeaderFilterStatus::Continue)); + + filter_->onDecodingSuccess(std::move(request)); + + EXPECT_EQ(filter_config_->stats().downstream_rq_total_.value(), 1); + EXPECT_EQ(filter_config_->stats().downstream_rq_active_.value(), 1); + EXPECT_EQ(filter_config_->stats().downstream_rq_local_.value(), 0); + + testing::InSequence s2; + // Decoder filter chain processing for common frame. + EXPECT_CALL(*mock_stream_filter_0, decodeCommonFrame(_)) + .WillOnce(Return(CommonFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_1, decodeCommonFrame(_)) + .WillOnce(Return(CommonFilterStatus::Continue)); + EXPECT_CALL(*mock_stream_filter_2, decodeCommonFrame(_)) + .WillOnce(Return(CommonFilterStatus::StopIteration)); + + EXPECT_CALL(mock_request_frames_handler, onRequestCommonFrame(_)).WillOnce(Invoke([&](auto&&) { + mock_stream_filter_2->decoder_callbacks_->sendLocalReply( + Status(StatusCode::kUnknown, "test_detail"), {}, + [](StreamResponse& response) { response.set("response-key", "response-value"); }); + })); + + // Encoder filter chain processing. EXPECT_CALL(*mock_stream_filter_2, encodeHeaderFrame(_)) .WillOnce(Return(HeaderFilterStatus::Continue)); EXPECT_CALL(*mock_stream_filter_1, encodeHeaderFrame(_)) @@ -1244,9 +1466,32 @@ TEST_F(FilterTest, ActiveStreamSendLocalReply) { EXPECT_CALL(*mock_stream_filter_0, encodeHeaderFrame(_)) .WillOnce(Return(HeaderFilterStatus::Continue)); - active_stream->sendLocalReply( - Status(StatusCode::kUnknown, "test_detail"), {}, - [](StreamResponse& response) { response.set("response-key", "response-value"); }); + // Send reply to the downstream. + EXPECT_CALL(*server_codec_, encode(_, _)) + .WillOnce(Invoke([&](const StreamFrame& response, EncodingContext&) { + Buffer::OwnedImpl buffer; + EXPECT_EQ(dynamic_cast(&response)->status().code(), + static_cast(StatusCode::kUnknown)); + buffer.add("test"); + + server_codec_callbacks_->writeToConnection(buffer); + buffer.drain(buffer.length()); + + return EncodingResult{4}; + })); + EXPECT_CALL(filter_callbacks_.connection_, write(BufferStringEqual("test"), false)); + + // Clean up the stream and log the access log. + EXPECT_CALL(filter_callbacks_.connection_.dispatcher_, deferredDelete_(_)); + EXPECT_CALL(*factory_context_.server_factory_context_.access_log_manager_.file_, + write("host-value /path-value method-value protocol-value request-value " + "response-value - 2 test_detail")); + + // Check the drain manager. + EXPECT_CALL(factory_context_.drain_manager_, drainClose()).WillOnce(Return(false)); + + auto request_frame = std::make_unique(); + filter_->onDecodingSuccess(std::move(request_frame)); EXPECT_EQ(filter_config_->stats().downstream_rq_total_.value(), 1); EXPECT_EQ(filter_config_->stats().downstream_rq_active_.value(), 0); @@ -1311,6 +1556,13 @@ TEST_F(FilterTest, NewStreamAndReplyNormally) { request->protocol_ = "protocol-value"; request->data_["request-key"] = "request-value"; + EXPECT_CALL(*mock_decoder_filter_0, decodeHeaderFrame(_)).WillOnce(Invoke([&](auto&) { + auto cb = mock_decoder_filter_0->decoder_callbacks_; + EXPECT_EQ(&cb->activeSpan(), &Tracing::NullSpan::instance()); + EXPECT_FALSE(cb->tracingConfig().has_value()); + return HeaderFilterStatus::Continue; + })); + filter_->onDecodingSuccess(std::move(request)); EXPECT_EQ(1, filter_->activeStreamsForTest().size()); @@ -1550,6 +1802,78 @@ TEST_F(FilterTest, NewStreamAndReplyNormallyWithTracing) { return span; })); + EXPECT_CALL(*mock_decoder_filter_0, decodeHeaderFrame(_)) + .WillOnce(Invoke([&](const RequestHeaderFrame&) { + EXPECT_NE(&mock_decoder_filter_0->decoder_callbacks_->activeSpan(), + &Tracing::NullSpan::instance()); + EXPECT_TRUE(mock_decoder_filter_0->decoder_callbacks_->tracingConfig().has_value()); + EXPECT_EQ(mock_decoder_filter_0->decoder_callbacks_->tracingConfig()->maxPathTagLength(), + 256); + EXPECT_EQ(mock_decoder_filter_0->decoder_callbacks_->tracingConfig()->spawnUpstreamSpan(), + true); + return HeaderFilterStatus::Continue; + })); + + filter_->onDecodingSuccess(std::move(request)); + EXPECT_EQ(1, filter_->activeStreamsForTest().size()); + + auto active_stream = filter_->activeStreamsForTest().begin()->get(); + + EXPECT_CALL(*span, setTag(_, _)).Times(testing::AnyNumber()); + EXPECT_CALL(*span, finishSpan()); + + EXPECT_CALL(filter_callbacks_.connection_, write(BufferStringEqual("test"), false)); + + EXPECT_CALL(*server_codec_, encode(_, _)) + .WillOnce(Invoke([&](const StreamFrame&, EncodingContext&) { + Buffer::OwnedImpl buffer; + buffer.add("test"); + + server_codec_callbacks_->writeToConnection(buffer); + buffer.drain(buffer.length()); + + return EncodingResult{4}; + })); + + EXPECT_CALL(factory_context_.drain_manager_, drainClose()).WillOnce(Return(false)); + EXPECT_CALL(filter_callbacks_.connection_.dispatcher_, deferredDelete_(_)); + + auto response = std::make_unique(); + active_stream->onResponseHeaderFrame(std::move(response)); +} + +TEST_F(FilterTest, NewStreamAndReplyNormallyWithTracingAndSamplingToTrue) { + auto mock_decoder_filter_0 = std::make_shared>(); + mock_decoder_filters_ = {{"mock_0", mock_decoder_filter_0}}; + + initializeFilter(true); + + auto request = std::make_unique(); + + auto* span = new NiceMock(); + EXPECT_CALL(*tracer_, startSpan_(_, _, _, _)) + .WillOnce( + Invoke([&](const Tracing::Config& config, Tracing::TraceContext&, + const StreamInfo::StreamInfo&, const Tracing::Decision) -> Tracing::Span* { + EXPECT_EQ(Tracing::OperationName::Egress, config.operationName()); + return span; + })); + + EXPECT_CALL(*mock_decoder_filter_0, decodeHeaderFrame(_)).WillOnce(Invoke([&](auto&) { + auto cb = mock_decoder_filter_0->decoder_callbacks_; + + EXPECT_NE(&cb->activeSpan(), &Tracing::NullSpan::instance()); + EXPECT_TRUE(cb->tracingConfig().has_value()); + EXPECT_EQ(cb->tracingConfig()->maxPathTagLength(), 256); + EXPECT_EQ(cb->tracingConfig()->spawnUpstreamSpan(), true); + return HeaderFilterStatus::Continue; + })); + + EXPECT_CALL(factory_context_.server_factory_context_.runtime_loader_.snapshot_, + featureEnabled("tracing.random_sampling", + testing::An())) + .WillOnce(Return(true)); + filter_->onDecodingSuccess(std::move(request)); EXPECT_EQ(1, filter_->activeStreamsForTest().size()); diff --git a/contrib/generic_proxy/filters/network/test/route_test.cc b/test/extensions/filters/network/generic_proxy/route_test.cc similarity index 94% rename from contrib/generic_proxy/filters/network/test/route_test.cc rename to test/extensions/filters/network/generic_proxy/route_test.cc index 3084016f3cc0..56aa14d4e114 100644 --- a/contrib/generic_proxy/filters/network/test/route_test.cc +++ b/test/extensions/filters/network/generic_proxy/route_test.cc @@ -1,17 +1,17 @@ #include #include "source/common/config/metadata.h" +#include "source/extensions/filters/network/generic_proxy/match.h" +#include "source/extensions/filters/network/generic_proxy/route_impl.h" +#include "test/extensions/filters/network/generic_proxy/fake_codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/filter.h" +#include "test/extensions/filters/network/generic_proxy/mocks/route.h" #include "test/mocks/server/factory_context.h" #include "test/test_common/registry.h" #include "test/test_common/test_runtime.h" #include "test/test_common/utility.h" -#include "contrib/generic_proxy/filters/network/source/match.h" -#include "contrib/generic_proxy/filters/network/source/route.h" -#include "contrib/generic_proxy/filters/network/test/fake_codec.h" -#include "contrib/generic_proxy/filters/network/test/mocks/filter.h" -#include "contrib/generic_proxy/filters/network/test/mocks/route.h" #include "gtest/gtest.h" using testing::Invoke; @@ -44,14 +44,16 @@ class RouteEntryImplTest : public testing::Test { }; /** - * Test the method that get cluster name from route entry. + * Test the method that get route name and cluster name from route entry. */ -TEST_F(RouteEntryImplTest, SimpleClusterName) { +TEST_F(RouteEntryImplTest, SimpleRouteNameAndClusterName) { const std::string yaml_config = R"EOF( + name: route_0 cluster: cluster_0 )EOF"; initialize(yaml_config); + EXPECT_EQ(route_->name(), "route_0"); EXPECT_EQ(route_->clusterName(), "cluster_0"); }; @@ -342,6 +344,20 @@ class RouteMatcherImplTest : public testing::Test { std::unique_ptr route_matcher_; }; +TEST(NullRouteMatcherTest, NullRouteMatcherTest) { + NullRouteMatcherImpl matcher; + + NiceMock stream_info; + + FakeStreamCodecFactory::FakeRequest fake_request_0; + fake_request_0.host_ = "service_0"; + fake_request_0.method_ = "method_0"; + fake_request_0.data_.insert({"key_0", "value_0"}); + const MatchInput match_input_0(fake_request_0, stream_info, MatchAction::RouteAction); + + EXPECT_EQ(nullptr, matcher.routeEntry(match_input_0)); +} + static const std::string RouteConfigurationYaml = R"EOF( name: test_matcher_tree virtual_hosts: @@ -589,6 +605,19 @@ TEST_F(RouteMatcherImplTest, RouteMatch) { EXPECT_EQ(route_entry_0->clusterName(), "cluster_1"); } + // Suffix host searching but not match. + { + NiceMock stream_info; + + FakeStreamCodecFactory::FakeRequest fake_request_0; + fake_request_0.host_ = "suffix"; + fake_request_0.method_ = "method_0"; + const MatchInput match_input_0(fake_request_0, stream_info, MatchAction::RouteAction); + + EXPECT_EQ("catch_all", route_matcher_->findVirtualHost(match_input_0)->name()); + EXPECT_EQ(nullptr, route_matcher_->routeEntry(match_input_0)); + } + // Suffix host searching. { NiceMock stream_info; @@ -655,6 +684,7 @@ TEST_F(RouteMatcherImplTest, RouteNotMatch) { fake_request.data_.insert({"key_0", "value_0"}); const MatchInput match_input(fake_request, stream_info, MatchAction::RouteAction); + EXPECT_EQ("prefix", route_matcher_->findVirtualHost(match_input)->name()); EXPECT_EQ(nullptr, route_matcher_->routeEntry(match_input)); } @@ -666,6 +696,7 @@ TEST_F(RouteMatcherImplTest, RouteNotMatch) { fake_request.data_.insert({"key_0", "value_0"}); const MatchInput match_input(fake_request, stream_info, MatchAction::RouteAction); + EXPECT_EQ("service", route_matcher_->findVirtualHost(match_input)->name()); EXPECT_EQ(nullptr, route_matcher_->routeEntry(match_input)); } @@ -676,6 +707,7 @@ TEST_F(RouteMatcherImplTest, RouteNotMatch) { fake_request.method_ = "method_0"; const MatchInput match_input(fake_request, stream_info, MatchAction::RouteAction); + EXPECT_EQ("service", route_matcher_->findVirtualHost(match_input)->name()); EXPECT_EQ(nullptr, route_matcher_->routeEntry(match_input)); } } diff --git a/test/extensions/filters/network/generic_proxy/router/BUILD b/test/extensions/filters/network/generic_proxy/router/BUILD new file mode 100644 index 000000000000..106be68d444d --- /dev/null +++ b/test/extensions/filters/network/generic_proxy/router/BUILD @@ -0,0 +1,57 @@ +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_test", + "envoy_package", +) + +licenses(["notice"]) # Apache 2 + +envoy_package() + +envoy_cc_test( + name = "router_test", + srcs = [ + "router_test.cc", + ], + deps = [ + "//source/common/buffer:buffer_lib", + "//source/extensions/filters/network/generic_proxy/router:router_lib", + "//test/extensions/filters/network/generic_proxy:fake_codec_lib", + "//test/extensions/filters/network/generic_proxy/mocks:codec_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:filter_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:route_mocks", + "//test/mocks/server:factory_context_mocks", + "//test/test_common:registry_lib", + "//test/test_common:utility_lib", + ], +) + +envoy_cc_test( + name = "upstream_test", + srcs = [ + "upstream_test.cc", + ], + deps = [ + "//source/common/buffer:buffer_lib", + "//source/extensions/filters/network/generic_proxy/router:router_lib", + "//test/extensions/filters/network/generic_proxy:fake_codec_lib", + "//test/extensions/filters/network/generic_proxy/mocks:codec_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:filter_mocks", + "//test/extensions/filters/network/generic_proxy/mocks:route_mocks", + "//test/mocks/server:factory_context_mocks", + "//test/test_common:registry_lib", + "//test/test_common:utility_lib", + ], +) + +envoy_cc_test( + name = "config_test", + srcs = [ + "config_test.cc", + ], + deps = [ + "//source/extensions/filters/network/generic_proxy/router:config", + "//test/extensions/filters/network/generic_proxy/mocks:filter_mocks", + "//test/mocks/server:factory_context_mocks", + ], +) diff --git a/contrib/generic_proxy/filters/network/test/router/config_test.cc b/test/extensions/filters/network/generic_proxy/router/config_test.cc similarity index 90% rename from contrib/generic_proxy/filters/network/test/router/config_test.cc rename to test/extensions/filters/network/generic_proxy/router/config_test.cc index d9384a5d8a8d..6b9edb67a418 100644 --- a/contrib/generic_proxy/filters/network/test/router/config_test.cc +++ b/test/extensions/filters/network/generic_proxy/router/config_test.cc @@ -1,7 +1,8 @@ +#include "source/extensions/filters/network/generic_proxy/router/config.h" + +#include "test/extensions/filters/network/generic_proxy/mocks/filter.h" #include "test/mocks/server/factory_context.h" -#include "contrib/generic_proxy/filters/network/source/router/config.h" -#include "contrib/generic_proxy/filters/network/test/mocks/filter.h" #include "gtest/gtest.h" namespace Envoy { diff --git a/contrib/generic_proxy/filters/network/test/router/router_test.cc b/test/extensions/filters/network/generic_proxy/router/router_test.cc similarity index 82% rename from contrib/generic_proxy/filters/network/test/router/router_test.cc rename to test/extensions/filters/network/generic_proxy/router/router_test.cc index c1cbdebefefe..8c2fd694efbc 100644 --- a/contrib/generic_proxy/filters/network/test/router/router_test.cc +++ b/test/extensions/filters/network/generic_proxy/router/router_test.cc @@ -1,16 +1,16 @@ #include #include "source/common/tracing/common_values.h" +#include "source/extensions/filters/network/generic_proxy/router/router.h" +#include "test/extensions/filters/network/generic_proxy/fake_codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/filter.h" +#include "test/extensions/filters/network/generic_proxy/mocks/route.h" #include "test/mocks/server/factory_context.h" #include "test/test_common/registry.h" #include "test/test_common/utility.h" -#include "contrib/generic_proxy/filters/network/source/router/router.h" -#include "contrib/generic_proxy/filters/network/test/fake_codec.h" -#include "contrib/generic_proxy/filters/network/test/mocks/codec.h" -#include "contrib/generic_proxy/filters/network/test/mocks/filter.h" -#include "contrib/generic_proxy/filters/network/test/mocks/route.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -119,26 +119,33 @@ class RouterFilterTest : public testing::Test { mock_generic_upstream_->requests_.begin()->second->onUpstreamSuccess(); } - void notifyDecodingSuccess(ResponseHeaderFramePtr&& response, - absl::optional start_time = {}) { + UpstreamRequestCallbacks* notifyDecodingSuccess(ResponseHeaderFramePtr&& response, + absl::optional start_time = {}) { ASSERT(filter_->upstreamRequestsSize() != 0); - mock_generic_upstream_->requests_.begin()->second->onDecodingSuccess(std::move(response), - start_time); + auto upstream_request = mock_generic_upstream_->requests_.begin()->second; + upstream_request->onDecodingSuccess(std::move(response), start_time); + return upstream_request; } - void notifyDecodingSuccess(ResponseCommonFramePtr&& response) { + UpstreamRequestCallbacks* notifyDecodingSuccess(ResponseCommonFramePtr&& response) { ASSERT(filter_->upstreamRequestsSize() != 0); - mock_generic_upstream_->requests_.begin()->second->onDecodingSuccess(std::move(response)); + auto upstream_request = mock_generic_upstream_->requests_.begin()->second; + upstream_request->onDecodingSuccess(std::move(response)); + return upstream_request; } - void notifyDecodingFailure(absl::string_view reason) { + UpstreamRequestCallbacks* notifyDecodingFailure(absl::string_view reason) { ASSERT(filter_->upstreamRequestsSize() != 0); - mock_generic_upstream_->requests_.begin()->second->onDecodingFailure(reason); + auto upstream_request = mock_generic_upstream_->requests_.begin()->second; + upstream_request->onDecodingFailure(reason); + return upstream_request; } - void notifyConnectionClose(Network::ConnectionEvent event) { + UpstreamRequestCallbacks* notifyConnectionClose(Network::ConnectionEvent event) { ASSERT(filter_->upstreamRequestsSize() != 0); - mock_generic_upstream_->requests_.begin()->second->onConnectionClose(event); + auto upstream_request = mock_generic_upstream_->requests_.begin()->second; + upstream_request->onConnectionClose(event); + return upstream_request; } void expectNewUpstreamRequest(bool with_tracing = false) { @@ -204,7 +211,8 @@ class RouterFilterTest : public testing::Test { .mutable_filter_metadata())[Envoy::Config::MetadataFilters::get().ENVOY_LB] = request_struct; - auto match = filter_->metadataMatchCriteria()->metadataMatchCriteria(); + auto match_criteria = filter_->metadataMatchCriteria(); + auto match = match_criteria->metadataMatchCriteria(); EXPECT_EQ(match.size(), 3); auto it = match.begin(); @@ -222,6 +230,8 @@ class RouterFilterTest : public testing::Test { EXPECT_EQ((*it)->name(), "xkey_in_request"); EXPECT_EQ((*it)->value().value().string_value(), "1"); + + EXPECT_EQ(match_criteria, filter_->metadataMatchCriteria()); } void expectResponseTimerCreate() { @@ -407,9 +417,12 @@ TEST_F(RouterFilterTest, UpstreamRequestResetBeforePoolCallback) { EXPECT_CALL(*mock_generic_upstream_, removeUpstreamRequest(_)); EXPECT_CALL(*mock_generic_upstream_, cleanUp(true)); - notifyConnectionClose(Network::ConnectionEvent::LocalClose); + auto* upstream_request = notifyConnectionClose(Network::ConnectionEvent::LocalClose); EXPECT_EQ(0, filter_->upstreamRequestsSize()); + // Calling resetStream() again should do nothing. + dynamic_cast(upstream_request)->resetStream(StreamResetReason::LocalReset, {}); + // Mock downstream closing. mock_downstream_connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); } @@ -557,7 +570,9 @@ TEST_F(RouterFilterTest, UpstreamRequestPoolReadyButConnectionErrorBeforeRespons EXPECT_CALL(*mock_generic_upstream_, cleanUp(true)); // Mock connection close event. - notifyConnectionClose(Network::ConnectionEvent::LocalClose); + auto upstream_request = notifyConnectionClose(Network::ConnectionEvent::LocalClose); + // Calling onConnectionClose() again should do nothing. + upstream_request->onConnectionClose(Network::ConnectionEvent::LocalClose); // Mock downstream closing. mock_downstream_connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -610,23 +625,50 @@ TEST_F(RouterFilterTest, UpstreamRequestPoolReadyAndResponse) { setup(); kickOffNewUpstreamRequest(true); - EXPECT_CALL(mock_generic_upstream_->mock_client_codec_, encode(_, _)); + EXPECT_CALL(mock_generic_upstream_->mock_client_codec_, encode(_, _)) + .WillOnce(Invoke([this](const StreamFrame&, EncodingContext& ctx) -> EncodingResult { + EXPECT_EQ(ctx.routeEntry().ptr(), &mock_route_entry_); + return 0; + })); expectInjectContextToUpstreamRequest(); notifyUpstreamSuccess(); - expectFinalizeUpstreamSpanAny(); + EXPECT_CALL(mock_filter_callback_, onResponseHeaderFrame(_)).WillOnce(Invoke([this](ResponsePtr) { + // When the response is sent to callback, the upstream request should be removed. + EXPECT_EQ(0, filter_->upstreamRequestsSize()); + })); EXPECT_CALL(*mock_generic_upstream_, removeUpstreamRequest(_)); EXPECT_CALL(*mock_generic_upstream_, cleanUp(false)); + expectFinalizeUpstreamSpanAny(); + + auto response = std::make_unique(); + notifyDecodingSuccess(std::move(response), {}); + + // Mock downstream closing. + mock_downstream_connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); +} + +TEST_F(RouterFilterTest, UpstreamRequestPoolReadyButDecodeFailureAfterResponse) { + setup(); + kickOffNewUpstreamRequest(false); + + EXPECT_CALL(mock_generic_upstream_->mock_client_codec_, encode(_, _)); + notifyUpstreamSuccess(); EXPECT_CALL(mock_filter_callback_, onResponseHeaderFrame(_)).WillOnce(Invoke([this](ResponsePtr) { // When the response is sent to callback, the upstream request should be removed. EXPECT_EQ(0, filter_->upstreamRequestsSize()); })); + EXPECT_CALL(*mock_generic_upstream_, removeUpstreamRequest(_)); + EXPECT_CALL(*mock_generic_upstream_, cleanUp(false)); auto response = std::make_unique(); - notifyDecodingSuccess(std::move(response), {}); + auto upstream_request = notifyDecodingSuccess(std::move(response), {}); + + EXPECT_CALL(*mock_generic_upstream_, cleanUp(true)); + upstream_request->onDecodingFailure("decode-failure"); // Mock downstream closing. mock_downstream_connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -698,6 +740,43 @@ TEST_F(RouterFilterTest, UpstreamRequestPoolReadyAndResponseAndTimeout) { mock_downstream_connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); } +TEST_F(RouterFilterTest, UpstreamRequestPoolReadyButEncodingFailure) { + // There are multiple frames in the request. + setup(FrameFlags(0, FrameFlags::FLAG_EMPTY)); + kickOffNewUpstreamRequest(true); + + auto frame_1 = std::make_unique(); + frame_1->stream_frame_flags_ = FrameFlags(0, FrameFlags::FLAG_EMPTY); + EXPECT_EQ(CommonFilterStatus::StopIteration, filter_->decodeCommonFrame(*frame_1)); + // This only store the frame and does nothing else because the pool is not ready yet. + filter_->onRequestCommonFrame(std::move(frame_1)); + + // End stream is set to true by default. + auto frame_2 = std::make_unique(); + EXPECT_EQ(CommonFilterStatus::StopIteration, filter_->decodeCommonFrame(*frame_2)); + // This only store the frame and does nothing else because the pool is not ready yet. + filter_->onRequestCommonFrame(std::move(frame_2)); + + testing::InSequence s; + expectInjectContextToUpstreamRequest(); + // Encode header frame success. + EXPECT_CALL(mock_generic_upstream_->mock_client_codec_, encode(_, _)) + .WillOnce(Return(EncodingResult(0))); + // Encode common frame failure. + EXPECT_CALL(mock_generic_upstream_->mock_client_codec_, encode(_, _)) + .WillOnce(Return(absl::UnknownError("encode-failure"))); + + EXPECT_CALL(*mock_generic_upstream_, removeUpstreamRequest(_)); + EXPECT_CALL(*mock_generic_upstream_, cleanUp(true)); + expectFinalizeUpstreamSpanAny(); + + // This will trigger frames to be encoded. + notifyUpstreamSuccess(); + + // Mock downstream closing. + mock_downstream_connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); +} + TEST_F(RouterFilterTest, UpstreamRequestPoolReadyAndResponseWithMultipleFrames) { // There are multiple frames in the request. setup(FrameFlags(0, FrameFlags::FLAG_EMPTY)); @@ -721,7 +800,7 @@ TEST_F(RouterFilterTest, UpstreamRequestPoolReadyAndResponseWithMultipleFrames) // End stream is set to true by default. auto frame_2 = std::make_unique(); - EXPECT_EQ(CommonFilterStatus::StopIteration, filter_->decodeCommonFrame(*frame_1)); + EXPECT_EQ(CommonFilterStatus::StopIteration, filter_->decodeCommonFrame(*frame_2)); // This will trigger the last frame to be sent directly because connection is ready and other // frames are already sent. @@ -760,6 +839,56 @@ TEST_F(RouterFilterTest, UpstreamRequestPoolReadyAndResponseWithMultipleFrames) mock_downstream_connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); } +TEST_F(RouterFilterTest, + UpstreamRequestPoolReadyAndResponseWithMultipleFramesButWithRepeatedHeaders) { + setup(); + kickOffNewUpstreamRequest(false); + + EXPECT_CALL(mock_generic_upstream_->mock_client_codec_, encode(_, _)); + notifyUpstreamSuccess(); + + // Request complete and response starts. + + EXPECT_CALL(mock_filter_callback_, onResponseHeaderFrame(_)); + + auto response = std::make_unique(); + response->stream_frame_flags_ = FrameFlags(0, FrameFlags::FLAG_EMPTY); + notifyDecodingSuccess(std::move(response)); + + EXPECT_CALL(*mock_generic_upstream_, removeUpstreamRequest(_)); + EXPECT_CALL(*mock_generic_upstream_, cleanUp(true)); + + auto response_2 = std::make_unique(); + response_2->stream_frame_flags_ = FrameFlags(0, FrameFlags::FLAG_EMPTY); + + notifyDecodingSuccess(std::move(response_2)); + + // Mock downstream closing. + mock_downstream_connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); +} + +TEST_F(RouterFilterTest, + UpstreamRequestPoolReadyAndResponseWithMultipleFramesButCommonFrameBeforeHeader) { + setup(); + kickOffNewUpstreamRequest(false); + + EXPECT_CALL(mock_generic_upstream_->mock_client_codec_, encode(_, _)); + notifyUpstreamSuccess(); + + // Request complete and response starts. + + auto response = std::make_unique(); + response->stream_frame_flags_ = FrameFlags(0, FrameFlags::FLAG_EMPTY); + + EXPECT_CALL(*mock_generic_upstream_, removeUpstreamRequest(_)); + EXPECT_CALL(*mock_generic_upstream_, cleanUp(true)); + + notifyDecodingSuccess(std::move(response)); + + // Mock downstream closing. + mock_downstream_connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); +} + TEST_F(RouterFilterTest, UpstreamRequestPoolReadyAndResponseWithDrainCloseSetInResponse) { setup(); kickOffNewUpstreamRequest(); diff --git a/contrib/generic_proxy/filters/network/test/router/upstream_test.cc b/test/extensions/filters/network/generic_proxy/router/upstream_test.cc similarity index 86% rename from contrib/generic_proxy/filters/network/test/router/upstream_test.cc rename to test/extensions/filters/network/generic_proxy/router/upstream_test.cc index 856b3afb3fde..889312d0adce 100644 --- a/contrib/generic_proxy/filters/network/test/router/upstream_test.cc +++ b/test/extensions/filters/network/generic_proxy/router/upstream_test.cc @@ -1,16 +1,16 @@ #include #include "source/common/tracing/common_values.h" +#include "source/extensions/filters/network/generic_proxy/router/router.h" +#include "test/extensions/filters/network/generic_proxy/fake_codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/codec.h" +#include "test/extensions/filters/network/generic_proxy/mocks/filter.h" +#include "test/extensions/filters/network/generic_proxy/mocks/route.h" #include "test/mocks/server/factory_context.h" #include "test/test_common/registry.h" #include "test/test_common/utility.h" -#include "contrib/generic_proxy/filters/network/source/router/router.h" -#include "contrib/generic_proxy/filters/network/test/fake_codec.h" -#include "contrib/generic_proxy/filters/network/test/mocks/codec.h" -#include "contrib/generic_proxy/filters/network/test/mocks/filter.h" -#include "contrib/generic_proxy/filters/network/test/mocks/route.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -79,6 +79,19 @@ class MockUpstreamRequestCallbacks : public UpstreamRequestCallbacks { GenericUpstream* upstream_{}; }; +TEST(SenseLessTest, SenseLessTest) { + UniqueRequestManager request_manager; + MockUpstreamRequestCallbacks mock_upstream_request_callbacks; + + EXPECT_FALSE(request_manager.contains(0)); + request_manager.appendUpstreamRequest(0, &mock_upstream_request_callbacks); + EXPECT_TRUE(request_manager.contains(0)); + + EventWatcher watcher(nullptr); + watcher.onAboveWriteBufferHighWatermark(); + watcher.onBelowWriteBufferLowWatermark(); +} + class UpstreamTest : public testing::Test { public: UpstreamTest() { @@ -342,6 +355,11 @@ TEST_F(UpstreamTest, BoundGenericUpstreamOnPoolFailure) { EXPECT_EQ(0, generic_upstream->waitingUpstreamRequestsSize()); EXPECT_EQ(0, generic_upstream->waitingResponseRequestsSize()); + + // Try append again but make no sense. + generic_upstream->appendUpstreamRequest(1, &mock_upstream_request_callbacks_1); + EXPECT_EQ(0, generic_upstream->waitingUpstreamRequestsSize()); + EXPECT_EQ(0, generic_upstream->waitingResponseRequestsSize()); } TEST_F(UpstreamTest, BoundGenericUpstreamDecodingSuccess) { @@ -376,19 +394,25 @@ TEST_F(UpstreamTest, BoundGenericUpstreamDecodingSuccess) { EXPECT_EQ(0, generic_upstream->waitingUpstreamRequestsSize()); EXPECT_EQ(2, generic_upstream->waitingResponseRequestsSize()); - auto request_1 = std::make_unique(); - request_1->stream_frame_flags_ = FrameFlags(1); + auto response_1 = std::make_unique(); + response_1->stream_frame_flags_ = FrameFlags(1); + + auto response_2 = std::make_unique(); + response_2->stream_frame_flags_ = FrameFlags(2); - auto request_2 = std::make_unique(); - request_2->stream_frame_flags_ = FrameFlags(2); + auto unknown_response = std::make_unique(); + unknown_response->stream_frame_flags_ = FrameFlags(3); EXPECT_CALL(*mock_client_codec_raw_, decode(_, _)) .WillOnce(testing::Invoke([&](Buffer::Instance&, bool) { + // Will be ignored. + cocec_callbacks_->onDecodingSuccess(std::move(unknown_response), {}); + EXPECT_CALL(mock_upstream_request_callbacks_2, onDecodingSuccess(_, _)); - cocec_callbacks_->onDecodingSuccess(std::move(request_2), {}); + cocec_callbacks_->onDecodingSuccess(std::move(response_2), {}); EXPECT_CALL(mock_upstream_request_callbacks_1, onDecodingSuccess(_, _)); - cocec_callbacks_->onDecodingSuccess(std::move(request_1), {}); + cocec_callbacks_->onDecodingSuccess(std::move(response_1), {}); })); Buffer::OwnedImpl fake_buffer; @@ -430,19 +454,25 @@ TEST_F(UpstreamTest, BoundGenericUpstreamDecodingSuccessWithMultipleFrames) { EXPECT_EQ(0, generic_upstream->waitingUpstreamRequestsSize()); EXPECT_EQ(2, generic_upstream->waitingResponseRequestsSize()); - auto request_1 = std::make_unique(); - request_1->stream_frame_flags_ = FrameFlags(1, FrameFlags::FLAG_EMPTY); + auto response_1 = std::make_unique(); + response_1->stream_frame_flags_ = FrameFlags(1, FrameFlags::FLAG_EMPTY); + + auto response_2 = std::make_unique(); + response_2->stream_frame_flags_ = FrameFlags(2, FrameFlags::FLAG_EMPTY); - auto request_2 = std::make_unique(); - request_2->stream_frame_flags_ = FrameFlags(2, FrameFlags::FLAG_EMPTY); + auto unknown_response = std::make_unique(); + unknown_response->stream_frame_flags_ = FrameFlags(3); EXPECT_CALL(*mock_client_codec_raw_, decode(_, _)) .WillOnce(testing::Invoke([&](Buffer::Instance&, bool) { + // Will be ignored. + cocec_callbacks_->onDecodingSuccess(std::move(unknown_response), {}); + EXPECT_CALL(mock_upstream_request_callbacks_1, onDecodingSuccess(_, _)); - cocec_callbacks_->onDecodingSuccess(std::move(request_1), {}); + cocec_callbacks_->onDecodingSuccess(std::move(response_1), {}); EXPECT_CALL(mock_upstream_request_callbacks_2, onDecodingSuccess(_, _)); - cocec_callbacks_->onDecodingSuccess(std::move(request_2), {}); + cocec_callbacks_->onDecodingSuccess(std::move(response_2), {}); })); Buffer::OwnedImpl fake_buffer; @@ -452,21 +482,27 @@ TEST_F(UpstreamTest, BoundGenericUpstreamDecodingSuccessWithMultipleFrames) { EXPECT_EQ(0, generic_upstream->waitingUpstreamRequestsSize()); EXPECT_EQ(2, generic_upstream->waitingResponseRequestsSize()); - auto request_1_frame = std::make_unique(); - request_1_frame->stream_frame_flags_ = FrameFlags(1); + auto response_1_frame = std::make_unique(); + response_1_frame->stream_frame_flags_ = FrameFlags(1); - auto request_2_frame = std::make_unique(); - request_2_frame->stream_frame_flags_ = FrameFlags(2); + auto response_2_frame = std::make_unique(); + response_2_frame->stream_frame_flags_ = FrameFlags(2); + + auto unknown_response_frame = std::make_unique(); + unknown_response_frame->stream_frame_flags_ = FrameFlags(3); EXPECT_CALL(*mock_client_codec_raw_, decode(_, _)) .WillOnce(testing::Invoke([&](Buffer::Instance&, bool) { + // Will be ignored. + cocec_callbacks_->onDecodingSuccess(std::move(unknown_response_frame)); + EXPECT_CALL(mock_upstream_connection_, close(_)).Times(0); EXPECT_CALL(mock_upstream_request_callbacks_2, onDecodingSuccess(_)); - cocec_callbacks_->onDecodingSuccess(std::move(request_2_frame)); + cocec_callbacks_->onDecodingSuccess(std::move(response_2_frame)); EXPECT_CALL(mock_upstream_connection_, close(_)).Times(0); EXPECT_CALL(mock_upstream_request_callbacks_1, onDecodingSuccess(_)); - cocec_callbacks_->onDecodingSuccess(std::move(request_1_frame)); + cocec_callbacks_->onDecodingSuccess(std::move(response_1_frame)); })); generic_upstream->onUpstreamData(fake_buffer, false); @@ -503,17 +539,17 @@ TEST_F(UpstreamTest, BoundGenericUpstreamDecodingFailureAndNoUpstreamConnectionC EXPECT_EQ(0, generic_upstream->waitingUpstreamRequestsSize()); EXPECT_EQ(2, generic_upstream->waitingResponseRequestsSize()); - auto request_1 = std::make_unique(); - request_1->stream_frame_flags_ = FrameFlags(1); + auto response_1 = std::make_unique(); + response_1->stream_frame_flags_ = FrameFlags(1); - auto request_2 = std::make_unique(); - request_2->stream_frame_flags_ = FrameFlags(2); + auto response_2 = std::make_unique(); + response_2->stream_frame_flags_ = FrameFlags(2); EXPECT_CALL(*mock_client_codec_raw_, decode(_, _)) .WillOnce(testing::Invoke([&](Buffer::Instance&, bool) { // Upstream is not set into the mock upstream request callbacks. So the // onDecodingFailure() will not clean up the upstream and will not result - // in the upstream connection clos. + // in the upstream connection close. EXPECT_CALL(mock_upstream_request_callbacks_1, onDecodingFailure(_)); EXPECT_CALL(mock_upstream_request_callbacks_2, onDecodingFailure(_)); @@ -556,14 +592,18 @@ TEST_F(UpstreamTest, BoundGenericUpstreamDecodingFailure) { EXPECT_EQ(0, generic_upstream->waitingUpstreamRequestsSize()); EXPECT_EQ(2, generic_upstream->waitingResponseRequestsSize()); - auto request_1 = std::make_unique(); - request_1->stream_frame_flags_ = FrameFlags(1); + auto response_1 = std::make_unique(); + response_1->stream_frame_flags_ = FrameFlags(1); - auto request_2 = std::make_unique(); - request_2->stream_frame_flags_ = FrameFlags(2); + auto response_2 = std::make_unique(); + response_2->stream_frame_flags_ = FrameFlags(2); EXPECT_CALL(*mock_client_codec_raw_, decode(_, _)) .WillOnce(testing::Invoke([&](Buffer::Instance&, bool) { + EXPECT_EQ(cocec_callbacks_->connection().ptr(), &mock_upstream_connection_); + EXPECT_EQ(cocec_callbacks_->upstreamCluster().ptr(), + &thread_local_cluster_.tcp_conn_pool_.host_->cluster_); + std::vector called_decoding_failure; std::vector called_connection_close; @@ -661,6 +701,23 @@ TEST_F(UpstreamTest, BoundGenericUpstreamUpstreamConnectionClose) { EXPECT_EQ(0, generic_upstream->waitingResponseRequestsSize()); } +TEST_F(UpstreamTest, OwnedGenericUpstreamInitializeAndDestroyUpstreamBeforePoolReady) { + EXPECT_CALL(thread_local_cluster_, tcpConnPool(_, _)); + auto generic_upstream = createOwnedGenericUpstream(); + + NiceMock mock_upstream_request_callbacks_1; + mock_upstream_request_callbacks_1.upstream_ = generic_upstream.get(); + + EXPECT_CALL(thread_local_cluster_.tcp_conn_pool_, newConnection(_)); + + generic_upstream->appendUpstreamRequest(1, &mock_upstream_request_callbacks_1); + + EXPECT_FALSE(generic_upstream->upstreamConnection().has_value()); + + // Destroy the upstream before the pool ready and no clean up. + generic_upstream.reset(); +} + TEST_F(UpstreamTest, OwnedGenericUpstreamInitializeAndPoolReady) { EXPECT_CALL(thread_local_cluster_, tcpConnPool(_, _)); auto generic_upstream = createOwnedGenericUpstream(); @@ -732,16 +789,18 @@ TEST_F(UpstreamTest, OwnedGenericUpstreamDecodingSuccess) { EXPECT_EQ(0, generic_upstream->waitingUpstreamRequestsSize()); EXPECT_EQ(1, generic_upstream->waitingResponseRequestsSize()); - auto request_1 = std::make_unique(); - request_1->stream_frame_flags_ = FrameFlags(1); + auto response_1 = std::make_unique(); + response_1->stream_frame_flags_ = FrameFlags(1); EXPECT_CALL(*mock_client_codec_raw_, decode(_, _)) .WillOnce(testing::Invoke([&](Buffer::Instance&, bool) { EXPECT_CALL(mock_upstream_request_callbacks_1, onDecodingSuccess(_, _)); - cocec_callbacks_->onDecodingSuccess(std::move(request_1), {}); + cocec_callbacks_->onDecodingSuccess(std::move(response_1), {}); })); Buffer::OwnedImpl fake_buffer; + // Empty buffer will be ignored. + generic_upstream->onUpstreamData(fake_buffer, false); fake_buffer.add("fake data"); generic_upstream->onUpstreamData(fake_buffer, false); @@ -751,7 +810,7 @@ TEST_F(UpstreamTest, OwnedGenericUpstreamDecodingSuccess) { TEST_F(UpstreamTest, OwnedGenericUpstreamDecodingSuccessWithMultipleFrames) { EXPECT_CALL(thread_local_cluster_, tcpConnPool(_, _)); - auto generic_upstream = createBoundGenericUpstream(); + auto generic_upstream = createOwnedGenericUpstream(); NiceMock mock_upstream_request_callbacks_1; mock_upstream_request_callbacks_1.upstream_ = generic_upstream.get(); @@ -772,30 +831,32 @@ TEST_F(UpstreamTest, OwnedGenericUpstreamDecodingSuccessWithMultipleFrames) { EXPECT_EQ(0, generic_upstream->waitingUpstreamRequestsSize()); EXPECT_EQ(1, generic_upstream->waitingResponseRequestsSize()); - auto request_1 = std::make_unique(); - request_1->stream_frame_flags_ = FrameFlags(1, FrameFlags::FLAG_EMPTY); + auto response_1 = std::make_unique(); + response_1->stream_frame_flags_ = FrameFlags(1, FrameFlags::FLAG_EMPTY); EXPECT_CALL(*mock_client_codec_raw_, decode(_, _)) .WillOnce(testing::Invoke([&](Buffer::Instance&, bool) { EXPECT_CALL(mock_upstream_request_callbacks_1, onDecodingSuccess(_, _)); - cocec_callbacks_->onDecodingSuccess(std::move(request_1), {}); + cocec_callbacks_->onDecodingSuccess(std::move(response_1), {}); })); Buffer::OwnedImpl fake_buffer; + // Empty buffer will be ignored. + generic_upstream->onUpstreamData(fake_buffer, false); fake_buffer.add("fake data"); generic_upstream->onUpstreamData(fake_buffer, false); EXPECT_EQ(0, generic_upstream->waitingUpstreamRequestsSize()); EXPECT_EQ(1, generic_upstream->waitingResponseRequestsSize()); - auto request_1_frame = std::make_unique(); - request_1_frame->stream_frame_flags_ = FrameFlags(1); + auto response_1_frame = std::make_unique(); + response_1_frame->stream_frame_flags_ = FrameFlags(1); EXPECT_CALL(*mock_client_codec_raw_, decode(_, _)) .WillOnce(testing::Invoke([&](Buffer::Instance&, bool) { EXPECT_CALL(mock_upstream_connection_, close(_)).Times(0); EXPECT_CALL(mock_upstream_request_callbacks_1, onDecodingSuccess(_)); - cocec_callbacks_->onDecodingSuccess(std::move(request_1_frame)); + cocec_callbacks_->onDecodingSuccess(std::move(response_1_frame)); })); generic_upstream->onUpstreamData(fake_buffer, false); @@ -806,7 +867,7 @@ TEST_F(UpstreamTest, OwnedGenericUpstreamDecodingSuccessWithMultipleFrames) { TEST_F(UpstreamTest, OwnedGenericUpstreamDecodingFailure) { EXPECT_CALL(thread_local_cluster_, tcpConnPool(_, _)); - auto generic_upstream = createBoundGenericUpstream(); + auto generic_upstream = createOwnedGenericUpstream(); NiceMock mock_upstream_request_callbacks_1; mock_upstream_request_callbacks_1.upstream_ = generic_upstream.get(); @@ -845,7 +906,7 @@ TEST_F(UpstreamTest, OwnedGenericUpstreamDecodingFailure) { TEST_F(UpstreamTest, OwnedGenericUpstreamUpstreamConnectionClose) { EXPECT_CALL(thread_local_cluster_, tcpConnPool(_, _)); - auto generic_upstream = createBoundGenericUpstream(); + auto generic_upstream = createOwnedGenericUpstream(); NiceMock mock_upstream_request_callbacks_1; mock_upstream_request_callbacks_1.upstream_ = generic_upstream.get(); diff --git a/test/extensions/filters/network/generic_proxy/stats_test.cc b/test/extensions/filters/network/generic_proxy/stats_test.cc new file mode 100644 index 000000000000..738952a872a9 --- /dev/null +++ b/test/extensions/filters/network/generic_proxy/stats_test.cc @@ -0,0 +1,29 @@ +#include "source/extensions/filters/network/generic_proxy/stats.h" + +#include "test/mocks/server/factory_context.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace NetworkFilters { +namespace GenericProxy { +namespace { + +TEST(StatsTest, StatsTest) { + NiceMock factory_context; + CodeOrFlags code_or_flags(factory_context); + + // Max code is 999 for now. + { + EXPECT_EQ("-", + factory_context.store_.symbolTable().toString(code_or_flags.statNameFromCode(1000))); + } +} + +} // namespace +} // namespace GenericProxy +} // namespace NetworkFilters +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/filters/network/generic_proxy/stream_test.cc b/test/extensions/filters/network/generic_proxy/stream_test.cc new file mode 100644 index 000000000000..4fc0e5a62e06 --- /dev/null +++ b/test/extensions/filters/network/generic_proxy/stream_test.cc @@ -0,0 +1,93 @@ +#include + +#include "source/extensions/filters/network/generic_proxy/interface/stream.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace NetworkFilters { +namespace GenericProxy { +namespace { + +bool operator==(const FrameFlags& lhs, const FrameFlags& rhs) { + return lhs.streamId() == rhs.streamId() && lhs.frameTags() == rhs.frameTags() && + lhs.rawFlags() == rhs.rawFlags(); +} + +class TestResponseHeaderFrame : public ResponseHeaderFrame { +public: + absl::string_view protocol() const override { return "test"; } +}; + +class TestRequestHeaderFrame : public RequestHeaderFrame { +public: + absl::string_view protocol() const override { return "test"; } +}; + +TEST(StreamInterfaceTest, StreamInterfaceTest) { + { + // FrameFlags Test. + FrameFlags flags; // All flags are default values. + EXPECT_EQ(flags.streamId(), 0); + EXPECT_EQ(flags.frameTags(), 0); + EXPECT_EQ(flags.endStream(), true); + EXPECT_EQ(flags.oneWayStream(), false); + EXPECT_EQ(flags.drainClose(), false); + EXPECT_EQ(flags.heartbeat(), false); + + FrameFlags flags1(1, FrameFlags::FLAG_EMPTY, 0); + EXPECT_EQ(flags1.streamId(), 1); + EXPECT_EQ(flags1.frameTags(), 0); + EXPECT_EQ(flags1.endStream(), false); + EXPECT_EQ(flags1.oneWayStream(), false); + EXPECT_EQ(flags1.drainClose(), false); + EXPECT_EQ(flags1.heartbeat(), false); + + FrameFlags flags2(2, + FrameFlags::FLAG_ONE_WAY | FrameFlags::FLAG_HEARTBEAT | + FrameFlags::FLAG_END_STREAM | FrameFlags::FLAG_DRAIN_CLOSE, + 3); + EXPECT_EQ(flags2.streamId(), 2); + EXPECT_EQ(flags2.frameTags(), 3); + EXPECT_EQ(flags2.endStream(), true); + EXPECT_EQ(flags2.oneWayStream(), true); + EXPECT_EQ(flags2.drainClose(), true); + EXPECT_EQ(flags2.heartbeat(), true); + } + + TestRequestHeaderFrame request_frame; + + EXPECT_EQ(request_frame.protocol(), "test"); + + // Default implementation does nothing. + EXPECT_TRUE(request_frame.frameFlags() == FrameFlags()); + EXPECT_EQ(request_frame.path(), ""); + EXPECT_EQ(request_frame.method(), ""); + EXPECT_EQ(request_frame.host(), ""); + request_frame.set("key", "val"); + EXPECT_EQ(absl::nullopt, request_frame.get("key")); + request_frame.erase("key"); + request_frame.forEach(nullptr); + + TestResponseHeaderFrame response_frame; + + EXPECT_EQ(response_frame.protocol(), "test"); + response_frame.frameFlags(); + + // Default implementation does nothing. + EXPECT_TRUE(response_frame.frameFlags() == FrameFlags()); + EXPECT_EQ(response_frame.status().code(), 0); + EXPECT_EQ(response_frame.status().ok(), true); + response_frame.set("key", "val"); + EXPECT_EQ(absl::nullopt, response_frame.get("key")); + response_frame.erase("key"); + response_frame.forEach(nullptr); +} + +} // namespace +} // namespace GenericProxy +} // namespace NetworkFilters +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/filters/network/generic_proxy/tracing_test.cc b/test/extensions/filters/network/generic_proxy/tracing_test.cc new file mode 100644 index 000000000000..dd456810f56c --- /dev/null +++ b/test/extensions/filters/network/generic_proxy/tracing_test.cc @@ -0,0 +1,55 @@ +#include "source/extensions/filters/network/generic_proxy/tracing.h" + +#include "test/extensions/filters/network/generic_proxy/fake_codec.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace NetworkFilters { +namespace GenericProxy { +namespace { + +TEST(TraceContextBridgeTest, TraceContextBridgeTest) { + + FakeStreamCodecFactory::FakeRequest request; + request.protocol_ = "test_protocol"; + request.host_ = "test_host"; + request.method_ = "test_method"; + request.path_ = "test_path"; + + request.data_ = {{"key1", "value1"}, {"key2", "value2"}}; + + TraceContextBridge bridge(request); + + EXPECT_EQ(bridge.protocol(), "test_protocol"); + EXPECT_EQ(bridge.host(), "test_host"); + EXPECT_EQ(bridge.method(), "test_method"); + EXPECT_EQ(bridge.path(), "test_path"); + + EXPECT_EQ(bridge.get("key1"), "value1"); + EXPECT_EQ(bridge.get("key2"), "value2"); + EXPECT_FALSE(bridge.get("key3").has_value()); + + bridge.set("key3", "value3"); + EXPECT_EQ(bridge.get("key3"), "value3"); + EXPECT_EQ(request.data_.at("key3"), "value3"); + + bridge.remove("key3"); + EXPECT_FALSE(bridge.get("key3").has_value()); + + size_t count = 0; + bridge.forEach([&count](absl::string_view, absl::string_view) { + count++; + return true; + }); + + EXPECT_EQ(count, 2); +} + +} // namespace +} // namespace GenericProxy +} // namespace NetworkFilters +} // namespace Extensions +} // namespace Envoy diff --git a/tools/code_format/config.yaml b/tools/code_format/config.yaml index 9959a9fda003..b4277350d9be 100644 --- a/tools/code_format/config.yaml +++ b/tools/code_format/config.yaml @@ -411,6 +411,7 @@ visibility_excludes: - source/extensions/early_data/BUILD - source/extensions/filters/http/buffer/BUILD - source/extensions/filters/network/common/BUILD +- source/extensions/filters/network/generic_proxy/interface/BUILD - source/extensions/http/header_validators/envoy_default/BUILD - source/extensions/transport_sockets/common/BUILD - source/extensions/transport_sockets/tap/BUILD diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt index bad86d13385e..79aba63e8e6c 100644 --- a/tools/spelling/spelling_dictionary.txt +++ b/tools/spelling/spelling_dictionary.txt @@ -1521,3 +1521,4 @@ CNAME NAT NXDOMAIN DNAT +RSP From e6e2d25d1d9c93c37136214a5d5125f3fccea823 Mon Sep 17 00:00:00 2001 From: code Date: Tue, 23 Jul 2024 13:39:03 +0800 Subject: [PATCH 04/26] route: move virtualHost() to Route from RouteEntry (#35168) Move the virtualHost() method to the Route from RouteEntry. By this way, the filters could access the virtual host even it has no valid routeEntry(). Move the virtualCluster() to the VirtualHost from RouteEntry because similar reason. For example, in pevious implementation, when the users want to log the metadata of vh by `%METADATA(VIRTUAL_HOST)%`, if direct response is used in the matched route, then users cannot access the metadata of vh. This PR make it's possbile. Risk Level: low. Testing: n/a. Docs Changes: n/a. Release Notes: n/a. Platform Specific Features: n/a. Signed-off-by: wbpcode --- envoy/router/router.h | 24 +- source/common/http/null_route_impl.cc | 2 +- source/common/http/null_route_impl.h | 10 +- source/common/http/utility.h | 3 +- source/common/router/config_impl.cc | 8 +- source/common/router/config_impl.h | 23 +- source/common/router/delegating_route_impl.cc | 10 +- source/common/router/delegating_route_impl.h | 3 +- source/common/router/router.cc | 9 +- .../filters/http/cors/cors_filter.cc | 2 +- .../http/local_ratelimit/local_ratelimit.cc | 4 +- .../filters/http/ratelimit/ratelimit.cc | 6 +- .../extensions/formatter/metadata/metadata.cc | 7 +- test/common/http/async_client_impl_test.cc | 16 +- test/common/http/conn_manager_impl_test.cc | 12 +- test/common/router/config_impl_test.cc | 621 +++++++++--------- .../router/delegating_route_impl_test.cc | 3 +- test/common/router/router_2_test.cc | 32 +- test/common/router/router_ratelimit_test.cc | 7 +- test/common/router/router_test.cc | 254 +++---- test/common/router/router_test_base.cc | 12 +- .../filters/http/cors/cors_filter_test.cc | 11 +- .../http/local_ratelimit/filter_test.cc | 23 +- .../filters/http/ratelimit/ratelimit_test.cc | 33 +- .../formatter/metadata/metadata_test.cc | 5 +- test/mocks/router/mocks.cc | 4 +- test/mocks/router/mocks.h | 8 +- test/tools/router_check/router.cc | 6 +- 28 files changed, 575 insertions(+), 583 deletions(-) diff --git a/envoy/router/router.h b/envoy/router/router.h index 5e7f221546d9..b6d23856649e 100644 --- a/envoy/router/router.h +++ b/envoy/router/router.h @@ -710,6 +710,13 @@ class VirtualHost { * for this virtual host. */ virtual const Envoy::Config::TypedMetadata& typedMetadata() const PURE; + + /** + * Determine whether a specific request path belongs to a virtual cluster for use in stats, etc. + * @param headers supplies the request headers. + * @return the virtual cluster or nullptr if there is no match. + */ + virtual const VirtualCluster* virtualCluster(const Http::HeaderMap& headers) const PURE; }; /** @@ -1044,18 +1051,6 @@ class RouteEntry : public ResponseEntry { */ virtual absl::optional grpcTimeoutOffset() const PURE; - /** - * Determine whether a specific request path belongs to a virtual cluster for use in stats, etc. - * @param headers supplies the request headers. - * @return the virtual cluster or nullptr if there is no match. - */ - virtual const VirtualCluster* virtualCluster(const Http::HeaderMap& headers) const PURE; - - /** - * @return const VirtualHost& the virtual host that owns the route. - */ - virtual const VirtualHost& virtualHost() const PURE; - /** * @return bool true if the :authority header should be overwritten with the upstream hostname. */ @@ -1264,6 +1259,11 @@ class Route { * @return std::string& the name of the route. */ virtual const std::string& routeName() const PURE; + + /** + * @return const VirtualHost& the virtual host that owns the route. + */ + virtual const VirtualHost& virtualHost() const PURE; }; using RouteConstSharedPtr = std::shared_ptr; diff --git a/source/common/http/null_route_impl.cc b/source/common/http/null_route_impl.cc index 3c5e32864400..b23e1c00dd7d 100644 --- a/source/common/http/null_route_impl.cc +++ b/source/common/http/null_route_impl.cc @@ -12,7 +12,7 @@ const Router::InternalRedirectPolicyImpl RouteEntryImpl::internal_redirect_polic const Router::PathMatcherSharedPtr RouteEntryImpl::path_matcher_; const Router::PathRewriterSharedPtr RouteEntryImpl::path_rewriter_; const std::vector RouteEntryImpl::shadow_policies_; -const NullVirtualHost RouteEntryImpl::virtual_host_; +const NullVirtualHost NullRouteImpl::virtual_host_; const NullRateLimitPolicy NullVirtualHost::rate_limit_policy_; const NullCommonConfig NullVirtualHost::route_configuration_; const std::multimap RouteEntryImpl::opaque_config_; diff --git a/source/common/http/null_route_impl.h b/source/common/http/null_route_impl.h index d699611b53de..6afaebf2e940 100644 --- a/source/common/http/null_route_impl.h +++ b/source/common/http/null_route_impl.h @@ -76,6 +76,9 @@ struct NullVirtualHost : public Router::VirtualHost { const Envoy::Config::TypedMetadata& typedMetadata() const override { return Router::DefaultRouteMetadataPack::get().typed_metadata_; } + const Router::VirtualCluster* virtualCluster(const Http::HeaderMap&) const override { + return nullptr; + } static const NullRateLimitPolicy rate_limit_policy_; static const NullCommonConfig route_configuration_; @@ -164,16 +167,12 @@ struct RouteEntryImpl : public Router::RouteEntry { absl::optional grpcTimeoutOffset() const override { return absl::nullopt; } - const Router::VirtualCluster* virtualCluster(const Http::HeaderMap&) const override { - return nullptr; - } const Router::TlsContextMatchCriteria* tlsContextMatchCriteria() const override { return nullptr; } const std::multimap& opaqueConfig() const override { return opaque_config_; } - const Router::VirtualHost& virtualHost() const override { return virtual_host_; } bool autoHostRewrite() const override { return false; } bool appendXfh() const override { return false; } bool includeVirtualHostRateLimits() const override { return true; } @@ -197,7 +196,6 @@ struct RouteEntryImpl : public Router::RouteEntry { static const Router::PathMatcherSharedPtr path_matcher_; static const Router::PathRewriterSharedPtr path_rewriter_; static const std::vector shadow_policies_; - static const NullVirtualHost virtual_host_; static const std::multimap opaque_config_; static const NullPathMatchCriterion path_match_criterion_; @@ -238,8 +236,10 @@ struct NullRouteImpl : public Router::Route { } absl::optional filterDisabled(absl::string_view) const override { return {}; } const std::string& routeName() const override { return EMPTY_STRING; } + const Router::VirtualHost& virtualHost() const override { return virtual_host_; } RouteEntryImpl route_entry_; + static const NullVirtualHost virtual_host_; }; } // namespace Http diff --git a/source/common/http/utility.h b/source/common/http/utility.h index 33139abe0821..0ae26c10412a 100644 --- a/source/common/http/utility.h +++ b/source/common/http/utility.h @@ -519,7 +519,8 @@ void transformUpgradeResponseFromH3toH1(ResponseHeaderMap& headers, absl::string * order is: * - the routeEntry() (for config that's applied on weighted clusters) * - the route - * - and finally from the virtual host object (routeEntry()->virtualhost()). + * - the virtual host object + * - the route configuration * * To use, simply: * diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc index 5aa0f35ed991..159845873a3f 100644 --- a/source/common/router/config_impl.cc +++ b/source/common/router/config_impl.cc @@ -1909,6 +1909,7 @@ VirtualHostImpl::VirtualHostImpl( ssl_requirements_ = SslRequirements::All; break; } + ssl_redirect_route_ = std::make_shared(shared_virtual_host_); if (virtual_host.has_matcher()) { RouteActionContext context{shared_virtual_host_, factory_context}; @@ -1935,8 +1936,7 @@ VirtualHostImpl::VirtualHostImpl( } } -const std::shared_ptr VirtualHostImpl::SSL_REDIRECT_ROUTE{ - new SslRedirectRoute()}; +const VirtualHost& SslRedirectRoute::virtualHost() const { return *virtual_host_; } RouteConstSharedPtr VirtualHostImpl::getRouteFromRoutes( const RouteCallback& cb, const Http::RequestHeaderMap& headers, @@ -1992,10 +1992,10 @@ RouteConstSharedPtr VirtualHostImpl::getRouteFromEntries(const RouteCallback& cb // First check for ssl redirect. if (ssl_requirements_ == SslRequirements::All && scheme != "https") { - return SSL_REDIRECT_ROUTE; + return ssl_redirect_route_; } else if (ssl_requirements_ == SslRequirements::ExternalOnly && scheme != "https" && !Http::HeaderUtility::isEnvoyInternalRequest(headers)) { - return SSL_REDIRECT_ROUTE; + return ssl_redirect_route_; } if (matcher_) { diff --git a/source/common/router/config_impl.h b/source/common/router/config_impl.h index b27fe572645f..1e5b8ebee210 100644 --- a/source/common/router/config_impl.h +++ b/source/common/router/config_impl.h @@ -136,8 +136,13 @@ class SslRedirector : public DirectResponseEntry { const std::string& responseBody() const override { return EMPTY_STRING; } }; +class CommonVirtualHostImpl; +using CommonVirtualHostSharedPtr = std::shared_ptr; + class SslRedirectRoute : public Route { public: + SslRedirectRoute(CommonVirtualHostSharedPtr virtual_host) : virtual_host_(virtual_host) {} + // Router::Route const DirectResponseEntry* directResponseEntry() const override { return &SSL_REDIRECTOR; } const RouteEntry* routeEntry() const override { return nullptr; } @@ -153,8 +158,11 @@ class SslRedirectRoute : public Route { const envoy::config::core::v3::Metadata& metadata() const override { return metadata_; } const Envoy::Config::TypedMetadata& typedMetadata() const override { return typed_metadata_; } const std::string& routeName() const override { return EMPTY_STRING; } + const VirtualHost& virtualHost() const override; private: + CommonVirtualHostSharedPtr virtual_host_; + static const SslRedirector SSL_REDIRECTOR; static const envoy::config::core::v3::Metadata metadata_; static const Envoy::Config::TypedMetadataImpl @@ -306,6 +314,9 @@ class CommonVirtualHostImpl : public VirtualHost, Logger::Loggable cb) const override; const envoy::config::core::v3::Metadata& metadata() const override; const Envoy::Config::TypedMetadata& typedMetadata() const override; + const VirtualCluster* virtualCluster(const Http::HeaderMap& headers) const override { + return virtualClusterFromEntries(headers); + } private: CommonVirtualHostImpl(const envoy::config::route::v3::VirtualHost& virtual_host, @@ -376,8 +387,6 @@ class CommonVirtualHostImpl : public VirtualHost, Logger::Loggable; - /** * Virtual host that holds a collection of routes. */ @@ -404,10 +413,9 @@ class VirtualHostImpl : Logger::Loggable { private: enum class SslRequirements : uint8_t { None, ExternalOnly, All }; - static const std::shared_ptr SSL_REDIRECT_ROUTE; - CommonVirtualHostSharedPtr shared_virtual_host_; + std::shared_ptr ssl_redirect_route_; SslRequirements ssl_requirements_; std::vector routes_; @@ -744,9 +752,6 @@ class RouteEntryImplBase : public RouteEntryAndRoute, uint32_t retryShadowBufferLimit() const override { return retry_shadow_buffer_limit_; } const std::vector& shadowPolicies() const override { return shadow_policies_; } - const VirtualCluster* virtualCluster(const Http::HeaderMap& headers) const override { - return vhost_->virtualClusterFromEntries(headers); - } std::chrono::milliseconds timeout() const override { return timeout_; } bool usingNewTimeouts() const override { return using_new_timeouts_; } @@ -913,10 +918,6 @@ class RouteEntryImplBase : public RouteEntryAndRoute, return parent_->tlsContextMatchCriteria(); } - const VirtualCluster* virtualCluster(const Http::HeaderMap& headers) const override { - return parent_->virtualCluster(headers); - } - const std::multimap& opaqueConfig() const override { return parent_->opaqueConfig(); } diff --git a/source/common/router/delegating_route_impl.cc b/source/common/router/delegating_route_impl.cc index 42116b25282c..4b7afc9fee77 100644 --- a/source/common/router/delegating_route_impl.cc +++ b/source/common/router/delegating_route_impl.cc @@ -14,6 +14,8 @@ const Decorator* DelegatingRoute::decorator() const { return base_route_->decora const RouteTracing* DelegatingRoute::tracingConfig() const { return base_route_->tracingConfig(); } +const VirtualHost& DelegatingRoute::virtualHost() const { return base_route_->virtualHost(); } + // Router:DelegatingRouteEntry void DelegatingRouteEntry::finalizeResponseHeaders( Http::ResponseHeaderMap& headers, const StreamInfo::StreamInfo& stream_info) const { @@ -128,14 +130,6 @@ absl::optional DelegatingRouteEntry::grpcTimeoutOffse return base_route_->routeEntry()->grpcTimeoutOffset(); } -const VirtualCluster* DelegatingRouteEntry::virtualCluster(const Http::HeaderMap& headers) const { - return base_route_->routeEntry()->virtualCluster(headers); -} - -const VirtualHost& DelegatingRouteEntry::virtualHost() const { - return base_route_->routeEntry()->virtualHost(); -} - bool DelegatingRouteEntry::autoHostRewrite() const { return base_route_->routeEntry()->autoHostRewrite(); } diff --git a/source/common/router/delegating_route_impl.h b/source/common/router/delegating_route_impl.h index 2212615fcaaa..91d0b99f86c1 100644 --- a/source/common/router/delegating_route_impl.h +++ b/source/common/router/delegating_route_impl.h @@ -47,6 +47,7 @@ class DelegatingRoute : public Router::Route { return base_route_->filterDisabled(name); } const std::string& routeName() const override { return base_route_->routeName(); } + const VirtualHost& virtualHost() const override; private: const Router::RouteConstSharedPtr base_route_; @@ -101,8 +102,6 @@ class DelegatingRouteEntry : public Router::RouteEntry { absl::optional grpcTimeoutHeaderOffset() const override; absl::optional maxGrpcTimeout() const override; absl::optional grpcTimeoutOffset() const override; - const VirtualCluster* virtualCluster(const Http::HeaderMap& headers) const override; - const VirtualHost& virtualHost() const override; bool autoHostRewrite() const override; bool appendXfh() const override; const MetadataMatchCriteria* metadataMatchCriteria() const override; diff --git a/source/common/router/router.cc b/source/common/router/router.cc index 7e4f4b786485..712db5659948 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -384,7 +384,7 @@ void Filter::chargeUpstreamCode(uint64_t response_status_code, config_->empty_stat_name_, response_status_code, internal_request, - route_entry_->virtualHost().statName(), + route_->virtualHost().statName(), request_vcluster_ ? request_vcluster_->statName() : config_->empty_stat_name_, route_stats_context_.has_value() ? route_stats_context_->statName() : config_->empty_stat_name_, @@ -516,7 +516,7 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, cluster_ = cluster->info(); // Set up stat prefixes, etc. - request_vcluster_ = route_entry_->virtualCluster(headers); + request_vcluster_ = route_->virtualHost().virtualCluster(headers); if (request_vcluster_ != nullptr) { callbacks_->streamInfo().setVirtualClusterName(request_vcluster_->name()); } @@ -755,8 +755,7 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, const bool can_send_early_data = route_entry_->earlyDataPolicy().allowsEarlyDataForRequest(*downstream_headers_); - include_timeout_retry_header_in_request_ = - route_entry_->virtualHost().includeIsTimeoutRetryHeader(); + include_timeout_retry_header_in_request_ = route_->virtualHost().includeIsTimeoutRetryHeader(); // Set initial HTTP/3 use based on the presence of HTTP/1.1 proxy config. // For retries etc, HTTP/3 usability may transition from true to false, but @@ -1768,7 +1767,7 @@ void Filter::onUpstreamComplete(UpstreamRequest& upstream_request) { response_time, upstream_request.upstreamCanary(), internal_request, - route_entry_->virtualHost().statName(), + route_->virtualHost().statName(), request_vcluster_ ? request_vcluster_->statName() : config_->empty_stat_name_, route_stats_context_.has_value() ? route_stats_context_->statName() : config_->empty_stat_name_, diff --git a/source/extensions/filters/http/cors/cors_filter.cc b/source/extensions/filters/http/cors/cors_filter.cc index bcbfa863c254..4cc33d7d116e 100644 --- a/source/extensions/filters/http/cors/cors_filter.cc +++ b/source/extensions/filters/http/cors/cors_filter.cc @@ -72,7 +72,7 @@ void CorsFilter::initializeCorsPolicies() { if (policies_.empty()) { policies_ = { decoder_callbacks_->route()->routeEntry()->corsPolicy(), - decoder_callbacks_->route()->routeEntry()->virtualHost().corsPolicy(), + decoder_callbacks_->route()->virtualHost().corsPolicy(), }; } } diff --git a/source/extensions/filters/http/local_ratelimit/local_ratelimit.cc b/source/extensions/filters/http/local_ratelimit/local_ratelimit.cc index 898fd9c54cd7..8356fa49b652 100644 --- a/source/extensions/filters/http/local_ratelimit/local_ratelimit.cc +++ b/source/extensions/filters/http/local_ratelimit/local_ratelimit.cc @@ -241,11 +241,11 @@ void Filter::populateDescriptors(std::vector& descri case VhRateLimitOptions::Ignore: return; case VhRateLimitOptions::Include: - populateDescriptors(route_entry->virtualHost().rateLimitPolicy(), descriptors, headers); + populateDescriptors(route->virtualHost().rateLimitPolicy(), descriptors, headers); return; case VhRateLimitOptions::Override: if (route_entry->rateLimitPolicy().empty()) { - populateDescriptors(route_entry->virtualHost().rateLimitPolicy(), descriptors, headers); + populateDescriptors(route->virtualHost().rateLimitPolicy(), descriptors, headers); } return; } diff --git a/source/extensions/filters/http/ratelimit/ratelimit.cc b/source/extensions/filters/http/ratelimit/ratelimit.cc index 5a462979bea7..382029e5f3db 100644 --- a/source/extensions/filters/http/ratelimit/ratelimit.cc +++ b/source/extensions/filters/http/ratelimit/ratelimit.cc @@ -55,13 +55,11 @@ void Filter::initiateCall(const Http::RequestHeaderMap& headers) { case VhRateLimitOptions::Ignore: break; case VhRateLimitOptions::Include: - populateRateLimitDescriptors(route_entry->virtualHost().rateLimitPolicy(), descriptors, - headers); + populateRateLimitDescriptors(route->virtualHost().rateLimitPolicy(), descriptors, headers); break; case VhRateLimitOptions::Override: if (route_entry->rateLimitPolicy().empty()) { - populateRateLimitDescriptors(route_entry->virtualHost().rateLimitPolicy(), descriptors, - headers); + populateRateLimitDescriptors(route->virtualHost().rateLimitPolicy(), descriptors, headers); } break; } diff --git a/source/extensions/formatter/metadata/metadata.cc b/source/extensions/formatter/metadata/metadata.cc index 14cbe93ff105..a4504ebe8ec1 100644 --- a/source/extensions/formatter/metadata/metadata.cc +++ b/source/extensions/formatter/metadata/metadata.cc @@ -60,12 +60,7 @@ class VirtualHostMetadataFormatter : public ::Envoy::Formatter::MetadataFormatte if (route == nullptr) { return nullptr; } - const Router::RouteEntry* route_entry = - route->routeEntry(); - if (route_entry == nullptr) { - return nullptr; - } - return &route_entry->virtualHost().metadata(); + return &route->virtualHost().metadata(); }) {} }; diff --git a/test/common/http/async_client_impl_test.cc b/test/common/http/async_client_impl_test.cc index a72d5f5aed3b..6d3324fe9314 100644 --- a/test/common/http/async_client_impl_test.cc +++ b/test/common/http/async_client_impl_test.cc @@ -2171,7 +2171,7 @@ TEST_F(AsyncClientImplTest, RdsGettersTest) { auto& path_match_criterion = route_entry->pathMatchCriterion(); EXPECT_EQ("", path_match_criterion.matcher()); EXPECT_EQ(Router::PathMatchType::None, path_match_criterion.matchType()); - const auto& route_config = route_entry->virtualHost().routeConfig(); + const auto& route_config = route->virtualHost().routeConfig(); EXPECT_EQ("", route_config.name()); EXPECT_EQ(0, route_config.internalOnlyHeaders().size()); auto cluster_info = filter_callbacks->clusterInfo(); @@ -2209,9 +2209,9 @@ class AsyncClientImplUnitTest : public AsyncClientImplTest { retry_policy_ = std::move(policy_or_error.value()); EXPECT_TRUE(retry_policy_.get()); - route_impl_.reset(new NullRouteImpl( + route_impl_ = std::make_unique( client_.cluster_->name(), *retry_policy_, regex_engine_, absl::nullopt, - Protobuf::RepeatedPtrField())); + Protobuf::RepeatedPtrField()); } std::unique_ptr retry_policy_; @@ -2279,11 +2279,11 @@ TEST_F(AsyncClientImplUnitTest, NullRouteImplInitTest) { EXPECT_TRUE(route_entry.upgradeMap().empty()); EXPECT_EQ(false, route_entry.internalRedirectPolicy().enabled()); EXPECT_TRUE(route_entry.shadowPolicies().empty()); - EXPECT_TRUE(route_entry.virtualHost().rateLimitPolicy().empty()); - EXPECT_EQ(nullptr, route_entry.virtualHost().corsPolicy()); - EXPECT_FALSE(route_entry.virtualHost().includeAttemptCountInRequest()); - EXPECT_FALSE(route_entry.virtualHost().includeAttemptCountInResponse()); - EXPECT_FALSE(route_entry.virtualHost().routeConfig().usesVhds()); + EXPECT_TRUE(route_impl_->virtualHost().rateLimitPolicy().empty()); + EXPECT_EQ(nullptr, route_impl_->virtualHost().corsPolicy()); + EXPECT_FALSE(route_impl_->virtualHost().includeAttemptCountInRequest()); + EXPECT_FALSE(route_impl_->virtualHost().includeAttemptCountInResponse()); + EXPECT_FALSE(route_impl_->virtualHost().routeConfig().usesVhds()); EXPECT_EQ(nullptr, route_entry.tlsContextMatchCriteria()); } diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc index 51cc25624285..791b237673fb 100644 --- a/test/common/http/conn_manager_impl_test.cc +++ b/test/common/http/conn_manager_impl_test.cc @@ -1258,13 +1258,13 @@ TEST_F(HttpConnectionManagerImplTest, DelegatingRouteEntryAllCalls) { delegating_route_foo->routeEntry()->maxGrpcTimeout()); EXPECT_EQ(default_route->routeEntry()->grpcTimeoutOffset(), delegating_route_foo->routeEntry()->grpcTimeoutOffset()); - EXPECT_EQ(default_route->routeEntry()->virtualCluster(test_req_headers), - delegating_route_foo->routeEntry()->virtualCluster(test_req_headers)); + EXPECT_EQ(default_route->virtualHost().virtualCluster(test_req_headers), + delegating_route_foo->virtualHost().virtualCluster(test_req_headers)); - EXPECT_EQ(default_route->routeEntry()->virtualHost().corsPolicy(), - delegating_route_foo->routeEntry()->virtualHost().corsPolicy()); - EXPECT_EQ(default_route->routeEntry()->virtualHost().rateLimitPolicy().empty(), - delegating_route_foo->routeEntry()->virtualHost().rateLimitPolicy().empty()); + EXPECT_EQ(default_route->virtualHost().corsPolicy(), + delegating_route_foo->virtualHost().corsPolicy()); + EXPECT_EQ(default_route->virtualHost().rateLimitPolicy().empty(), + delegating_route_foo->virtualHost().rateLimitPolicy().empty()); EXPECT_EQ(default_route->routeEntry()->autoHostRewrite(), delegating_route_foo->routeEntry()->autoHostRewrite()); diff --git a/test/common/router/config_impl_test.cc b/test/common/router/config_impl_test.cc index 712ed4721145..93bc3b972e58 100644 --- a/test/common/router/config_impl_test.cc +++ b/test/common/router/config_impl_test.cc @@ -171,13 +171,13 @@ class ConfigImplTestBase { ON_CALL(factory_context_, api()).WillByDefault(ReturnRef(*api_)); } - std::string virtualHostName(const RouteEntry* route) { + std::string virtualHostName(const Route* route) { Stats::StatName name = route->virtualHost().statName(); return factory_context_.scope().symbolTable().toString(name); } - std::string virtualClusterName(const RouteEntry* route, Http::TestRequestHeaderMapImpl& headers) { - Stats::StatName name = route->virtualCluster(headers)->statName(); + std::string virtualClusterName(const Route* route, Http::TestRequestHeaderMapImpl& headers) { + Stats::StatName name = route->virtualHost().virtualCluster(headers)->statName(); return factory_context_.scope().symbolTable().toString(name); } @@ -434,9 +434,9 @@ TEST_F(RouteMatcherTest, TestConnectRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("bat3.com", "/api/locations?works=true", "CONNECT"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/rewrote?works=true", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/rewrote?works=true", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/rewrote?works=true", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("bat3.com", headers.get_(Http::Headers::get().Host)); } @@ -456,16 +456,16 @@ TEST_F(RouteMatcherTest, TestConnectRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("bat3.com", "/api/locations?works=true", "CONNECT"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("bat3.com:10", headers.get_(Http::Headers::get().Host)); } // No port addition for CONNECT with port { Http::TestRequestHeaderMapImpl headers = genHeaders("bat3.com:20", "/api/locations?works=true", "CONNECT"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("bat3.com:20", headers.get_(Http::Headers::get().Host)); } @@ -845,11 +845,12 @@ TEST_F(RouteMatcherTest, TestRoutes) { // Prefix rewrite testing. { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/new_endpoint/foo", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("www2", route->clusterName()); - EXPECT_EQ("www2", virtualHostName(route)); - EXPECT_EQ("/api/new_endpoint/foo", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteConstSharedPtr route = config.route(headers, 0); + const RouteEntry* route_entry = route->routeEntry(); + EXPECT_EQ("www2", route_entry->clusterName()); + EXPECT_EQ("www2", virtualHostName(route.get())); + EXPECT_EQ("/api/new_endpoint/foo", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/api/new_endpoint/foo", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("/new_endpoint/foo", headers.get_(Http::Headers::get().EnvoyOriginalPath)); } @@ -857,11 +858,12 @@ TEST_F(RouteMatcherTest, TestRoutes) { // Prefix rewrite testing (x-envoy-* headers suppressed). { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/new_endpoint/foo", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("www2", route->clusterName()); - EXPECT_EQ("www2", virtualHostName(route)); - EXPECT_EQ("/api/new_endpoint/foo", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, false); + const RouteConstSharedPtr route = config.route(headers, 0); + const RouteEntry* route_entry = route->routeEntry(); + EXPECT_EQ("www2", route_entry->clusterName()); + EXPECT_EQ("www2", virtualHostName(route.get())); + EXPECT_EQ("/api/new_endpoint/foo", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, false); EXPECT_EQ("/api/new_endpoint/foo", headers.get_(Http::Headers::get().Path)); EXPECT_FALSE(headers.has(Http::Headers::get().EnvoyOriginalPath)); } @@ -870,17 +872,17 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/api/locations?works=true", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/rewrote?works=true", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/rewrote?works=true", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/rewrote?works=true", headers.get_(Http::Headers::get().Path)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/foo", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/bar", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/bar", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/bar", headers.get_(Http::Headers::get().Path)); } @@ -888,11 +890,12 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/newforreg1_endpoint/foo", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("www2", route->clusterName()); - EXPECT_EQ("www2", virtualHostName(route)); - EXPECT_EQ("/forreg1_rewritten_endpoint/foo", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteConstSharedPtr route = config.route(headers, 0); + const RouteEntry* route_entry = route->routeEntry(); + EXPECT_EQ("www2", route_entry->clusterName()); + EXPECT_EQ("www2", virtualHostName(route.get())); + EXPECT_EQ("/forreg1_rewritten_endpoint/foo", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/forreg1_rewritten_endpoint/foo", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("/newforreg1_endpoint/foo", headers.get_(Http::Headers::get().EnvoyOriginalPath)); } @@ -902,11 +905,12 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/newforreg2_endpoint/tee?test=me", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("www2", route->clusterName()); - EXPECT_EQ("www2", virtualHostName(route)); - EXPECT_EQ("/nXwforrXg2_Xndpoint/tXX?test=me", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteConstSharedPtr route = config.route(headers, 0); + const RouteEntry* route_entry = route->routeEntry(); + EXPECT_EQ("www2", route_entry->clusterName()); + EXPECT_EQ("www2", virtualHostName(route.get())); + EXPECT_EQ("/nXwforrXg2_Xndpoint/tXX?test=me", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/nXwforrXg2_Xndpoint/tXX?test=me", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("/newforreg2_endpoint/tee?test=me", headers.get_(Http::Headers::get().EnvoyOriginalPath)); @@ -916,11 +920,12 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/exact/path/for/regex1", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("www2", route->clusterName()); - EXPECT_EQ("www2", virtualHostName(route)); - EXPECT_EQ("/VxVct/pVth/fVr/rVgVx1", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteConstSharedPtr route = config.route(headers, 0); + const RouteEntry* route_entry = route->routeEntry(); + EXPECT_EQ("www2", route_entry->clusterName()); + EXPECT_EQ("www2", virtualHostName(route.get())); + EXPECT_EQ("/VxVct/pVth/fVr/rVgVx1", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/VxVct/pVth/fVr/rVgVx1", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("/exact/path/for/regex1", headers.get_(Http::Headers::get().EnvoyOriginalPath)); } @@ -930,11 +935,13 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/exact/path/for/regex1?test=aeiou", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("www2", route->clusterName()); - EXPECT_EQ("www2", virtualHostName(route)); - EXPECT_EQ("/VxVct/pVth/fVr/rVgVx1?test=aeiou", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteConstSharedPtr route = config.route(headers, 0); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("www2", route_entry->clusterName()); + EXPECT_EQ("www2", virtualHostName(route.get())); + EXPECT_EQ("/VxVct/pVth/fVr/rVgVx1?test=aeiou", + route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/VxVct/pVth/fVr/rVgVx1?test=aeiou", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("/exact/path/for/regex1?test=aeiou", headers.get_(Http::Headers::get().EnvoyOriginalPath)); @@ -943,10 +950,11 @@ TEST_F(RouteMatcherTest, TestRoutes) { // Host rewrite testing. { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/host/rewrite/me", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ(absl::optional(), route->currentUrlPathAfterRewrite(headers)); - EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value()); - route->finalizeRequestHeaders(headers, stream_info, true); + + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ(absl::optional(), route_entry->currentUrlPathAfterRewrite(headers)); + EXPECT_FALSE(route_entry->currentUrlPathAfterRewrite(headers).has_value()); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("new_host", headers.get_(Http::Headers::get().Host)); // Config setting append_x_forwarded_host is false (by default). Expect empty x-forwarded-host // header value. @@ -957,9 +965,9 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/rewrite-host-with-header-value", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value()); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_FALSE(route_entry->currentUrlPathAfterRewrite(headers).has_value()); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("rewrote", headers.get_(Http::Headers::get().Host)); EXPECT_EQ("api.lyft.com", headers.get_(Http::Headers::get().ForwardedHost)); } @@ -968,9 +976,9 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/do-not-rewrite-host-with-header-value", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value()); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_FALSE(route_entry->currentUrlPathAfterRewrite(headers).has_value()); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("api.lyft.com", headers.get_(Http::Headers::get().Host)); EXPECT_EQ("", headers.get_(Http::Headers::get().ForwardedHost)); } @@ -979,9 +987,9 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/rewrite-host-with-path-regex/envoyproxy.io", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value()); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_FALSE(route_entry->currentUrlPathAfterRewrite(headers).has_value()); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("envoyproxy.io", headers.get_(Http::Headers::get().Host)); EXPECT_EQ("api.lyft.com", headers.get_(Http::Headers::get().ForwardedHost)); } @@ -990,9 +998,9 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders( "api.lyft.com", "/rewrite-host-with-path-regex/envoyproxy.io?query=query", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value()); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_FALSE(route_entry->currentUrlPathAfterRewrite(headers).has_value()); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("envoyproxy.io", headers.get_(Http::Headers::get().Host)); EXPECT_EQ("api.lyft.com", headers.get_(Http::Headers::get().ForwardedHost)); } @@ -1001,34 +1009,34 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/API/locations?works=true", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/rewrote?works=true", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/rewrote?works=true", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/rewrote?works=true", headers.get_(Http::Headers::get().Path)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/fooD", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/cAndy", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/cAndy", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/cAndy", headers.get_(Http::Headers::get().Path)); } // Case sensitive is set to true and will not rewrite { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/FOO", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value()); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_FALSE(route_entry->currentUrlPathAfterRewrite(headers).has_value()); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/FOO", headers.get_(Http::Headers::get().Path)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/ApPles", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value()); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_FALSE(route_entry->currentUrlPathAfterRewrite(headers).has_value()); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/ApPles", headers.get_(Http::Headers::get().Path)); } @@ -1036,17 +1044,17 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/oLDhost/rewrite/me", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("api.lyft.com", headers.get_(Http::Headers::get().Host)); } // Case sensitive is set to false and will not rewrite { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/Tart", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value()); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_FALSE(route_entry->currentUrlPathAfterRewrite(headers).has_value()); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/Tart", headers.get_(Http::Headers::get().Path)); } @@ -1054,42 +1062,42 @@ TEST_F(RouteMatcherTest, TestRoutes) { { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/newhost/rewrite/me", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("new_host", headers.get_(Http::Headers::get().Host)); } // Prefix rewrite for regular expression matching { Http::TestRequestHeaderMapImpl headers = genHeaders("bat.com", "/647", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/rewrote", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/rewrote", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/rewrote", headers.get_(Http::Headers::get().Path)); } // Prefix rewrite for regular expression matching with query string { Http::TestRequestHeaderMapImpl headers = genHeaders("bat.com", "/970?foo=true", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/rewrote?foo=true", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/rewrote?foo=true", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/rewrote?foo=true", headers.get_(Http::Headers::get().Path)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("bat.com", "/foo/bar/238?bar=true", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/rewrote?bar=true", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/rewrote?bar=true", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/rewrote?bar=true", headers.get_(Http::Headers::get().Path)); } // Regular expression rewrite for regular expression matching { Http::TestRequestHeaderMapImpl headers = genHeaders("bat.com", "/xx/yy/6472", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/four/6472/endpoint/xx/yy", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/four/6472/endpoint/xx/yy", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/four/6472/endpoint/xx/yy", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("/xx/yy/6472", headers.get_(Http::Headers::get().EnvoyOriginalPath)); } @@ -1097,9 +1105,10 @@ TEST_F(RouteMatcherTest, TestRoutes) { // Regular expression rewrite for regular expression matching, with query parameters. { Http::TestRequestHeaderMapImpl headers = genHeaders("bat.com", "/xx/yy/6472?test=foo", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/four/6472/endpoint/xx/yy?test=foo", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/four/6472/endpoint/xx/yy?test=foo", + route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/four/6472/endpoint/xx/yy?test=foo", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("/xx/yy/6472?test=foo", headers.get_(Http::Headers::get().EnvoyOriginalPath)); } @@ -1107,45 +1116,44 @@ TEST_F(RouteMatcherTest, TestRoutes) { // Virtual cluster testing. { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/rides", "GET"); - EXPECT_EQ("other", virtualClusterName(config.route(headers, 0)->routeEntry(), headers)); + EXPECT_EQ("other", virtualClusterName(config.route(headers, 0).get(), headers)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/rides/blah", "POST"); - EXPECT_EQ("other", virtualClusterName(config.route(headers, 0)->routeEntry(), headers)); + EXPECT_EQ("other", virtualClusterName(config.route(headers, 0).get(), headers)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/rides", "POST"); - EXPECT_EQ("ride_request", virtualClusterName(config.route(headers, 0)->routeEntry(), headers)); + EXPECT_EQ("ride_request", virtualClusterName(config.route(headers, 0).get(), headers)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/rides/123", "PUT"); - EXPECT_EQ("update_ride", virtualClusterName(config.route(headers, 0)->routeEntry(), headers)); + EXPECT_EQ("update_ride", virtualClusterName(config.route(headers, 0).get(), headers)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/rides/123/456", "POST"); - EXPECT_EQ("other", virtualClusterName(config.route(headers, 0)->routeEntry(), headers)); + EXPECT_EQ("other", virtualClusterName(config.route(headers, 0).get(), headers)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/foo/bar", "PUT"); - EXPECT_EQ("other", virtualClusterName(config.route(headers, 0)->routeEntry(), headers)); + EXPECT_EQ("other", virtualClusterName(config.route(headers, 0).get(), headers)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/users", "POST"); - EXPECT_EQ("create_user_login", - virtualClusterName(config.route(headers, 0)->routeEntry(), headers)); + EXPECT_EQ("create_user_login", virtualClusterName(config.route(headers, 0).get(), headers)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/users/123", "PUT"); - EXPECT_EQ("update_user", virtualClusterName(config.route(headers, 0)->routeEntry(), headers)); + EXPECT_EQ("update_user", virtualClusterName(config.route(headers, 0).get(), headers)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/users/123/location", "POST"); - EXPECT_EQ("ulu", virtualClusterName(config.route(headers, 0)->routeEntry(), headers)); + EXPECT_EQ("ulu", virtualClusterName(config.route(headers, 0).get(), headers)); } { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/something/else", "GET"); - EXPECT_EQ("other", virtualClusterName(config.route(headers, 0)->routeEntry(), headers)); + EXPECT_EQ("other", virtualClusterName(config.route(headers, 0).get(), headers)); } } @@ -1228,7 +1236,8 @@ TEST_F(RouteMatcherTest, TestRoutesWithInvalidVirtualCluster) { )EOF"; factory_context_.cluster_manager_.initializeClusters({"regex"}, {}); - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ(creation_status_.message(), "virtual clusters must define 'headers'"); } @@ -1297,15 +1306,15 @@ TEST_F(RouteMatcherTest, TestMatchTree) { { Http::TestRequestHeaderMapImpl headers = genHeaders("lyft.com", "/new_endpoint/foo", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("match_tree", headers.get_("x-route-header")); } { Http::TestRequestHeaderMapImpl headers = genHeaders("lyft.com", "/new_endpoint/bar", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("match_tree_2", headers.get_("x-route-header")); } Http::TestRequestHeaderMapImpl headers = genHeaders("lyft.com", "/new_endpoint/baz", "GET"); @@ -1346,7 +1355,8 @@ TEST_F(RouteMatcherTest, TestMatchInvalidInput) { NiceMock stream_info; factory_context_.cluster_manager_.initializeClusters( {"www2", "root_www2", "www2_staging", "instant-server"}, {}); - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ( creation_status_.message(), "requirement violation while creating route match tree: INVALID_ARGUMENT: Route table can " @@ -1391,7 +1401,8 @@ TEST_F(RouteMatcherTest, TestMatchInvalidInputTwoMatchers) { NiceMock stream_info; factory_context_.cluster_manager_.initializeClusters( {"www2", "root_www2", "www2_staging", "instant-server"}, {}); - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ(creation_status_.message(), "cannot set both matcher and routes on virtual host"); } @@ -1512,16 +1523,16 @@ TEST_F(RouteMatcherTest, TestRouteList) { { Http::TestRequestHeaderMapImpl headers = genHeaders("lyft.com", "/new_endpoint/foo/1", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("match_tree_1_1", headers.get_("x-route-header")); } { Http::TestRequestHeaderMapImpl headers = genHeaders("lyft.com", "/new_endpoint/foo/2/bar", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("match_tree_1_2", headers.get_("x-route-header")); } @@ -1529,8 +1540,8 @@ TEST_F(RouteMatcherTest, TestRouteList) { Http::TestRequestHeaderMapImpl headers = genHeaders("lyft.com", "/new_endpoint/foo/match_header", "GET"); headers.setCopy(Http::LowerCaseString("x-match-header"), "matched"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("match_tree_1_3", headers.get_("x-route-header")); } @@ -1541,8 +1552,8 @@ TEST_F(RouteMatcherTest, TestRouteList) { { Http::TestRequestHeaderMapImpl headers = genHeaders("lyft.com", "/new_endpoint/bar", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("match_tree_2", headers.get_("x-route-header")); } Http::TestRequestHeaderMapImpl headers = genHeaders("lyft.com", "/new_endpoint/baz", "GET"); @@ -1696,12 +1707,12 @@ TEST_F(RouteMatcherTest, TestAddRemoveRequestHeaders) { { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/new_endpoint/foo", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("route-override", headers.get_("x-global-header1")); EXPECT_EQ("route-override", headers.get_("x-vhost-header1")); EXPECT_EQ("route-new_endpoint", headers.get_("x-route-header")); - auto transforms = route->requestHeaderTransforms(stream_info); + auto transforms = route_entry->requestHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, ElementsAre(Pair(Http::LowerCaseString("x-global-header1"), "route-override"), Pair(Http::LowerCaseString("x-vhost-header1"), "route-override"), @@ -1719,12 +1730,12 @@ TEST_F(RouteMatcherTest, TestAddRemoveRequestHeaders) { // Multiple routes can have same route-level headers with different values. { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("vhost-override", headers.get_("x-global-header1")); EXPECT_EQ("vhost1-www2", headers.get_("x-vhost-header1")); EXPECT_EQ("route-allpath", headers.get_("x-route-header")); - auto transforms = route->requestHeaderTransforms(stream_info); + auto transforms = route_entry->requestHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, ElementsAre(Pair(Http::LowerCaseString("x-route-header"), "route-allpath"), Pair(Http::LowerCaseString("x-global-header1"), "vhost-override"), @@ -1740,12 +1751,12 @@ TEST_F(RouteMatcherTest, TestAddRemoveRequestHeaders) { // Multiple virtual hosts can have same virtual host level headers with different values. { Http::TestRequestHeaderMapImpl headers = genHeaders("www-staging.lyft.net", "/foo", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("global1", headers.get_("x-global-header1")); EXPECT_EQ("vhost1-www2_staging", headers.get_("x-vhost-header1")); EXPECT_EQ("route-allprefix", headers.get_("x-route-header")); - auto transforms = route->requestHeaderTransforms(stream_info); + auto transforms = route_entry->requestHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, ElementsAre(Pair(Http::LowerCaseString("x-route-header"), "route-allprefix"), Pair(Http::LowerCaseString("x-vhost-header1"), "vhost1-www2_staging"), @@ -1760,10 +1771,10 @@ TEST_F(RouteMatcherTest, TestAddRemoveRequestHeaders) { // Global headers. { Http::TestRequestHeaderMapImpl headers = genHeaders("api.lyft.com", "/", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("global1", headers.get_("x-global-header1")); - auto transforms = route->requestHeaderTransforms(stream_info); + auto transforms = route_entry->requestHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, ElementsAre(Pair(Http::LowerCaseString("x-global-header1"), "global1"))); EXPECT_THAT(transforms.headers_to_overwrite_or_add, IsEmpty()); @@ -1788,8 +1799,8 @@ TEST_F(RouteMatcherTest, TestRequestHeadersToAddWithAppendFalse) { // Global and virtual host override route, route overrides route action. { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/endpoint", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); // Added headers. EXPECT_EQ("global", headers.get_("x-global-header")); EXPECT_EQ("vhost-www2", headers.get_("x-vhost-header")); @@ -1798,7 +1809,7 @@ TEST_F(RouteMatcherTest, TestRequestHeadersToAddWithAppendFalse) { EXPECT_FALSE(headers.has("x-global-nope")); EXPECT_FALSE(headers.has("x-vhost-nope")); EXPECT_FALSE(headers.has("x-route-nope")); - auto transforms = route->requestHeaderTransforms(stream_info); + auto transforms = route_entry->requestHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, IsEmpty()); EXPECT_THAT(transforms.headers_to_overwrite_or_add, ElementsAre(Pair(Http::LowerCaseString("x-global-header"), "route-endpoint"), @@ -1816,8 +1827,8 @@ TEST_F(RouteMatcherTest, TestRequestHeadersToAddWithAppendFalse) { // Global overrides virtual host. { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); // Added headers. EXPECT_EQ("global", headers.get_("x-global-header")); EXPECT_EQ("vhost-www2", headers.get_("x-vhost-header")); @@ -1826,7 +1837,7 @@ TEST_F(RouteMatcherTest, TestRequestHeadersToAddWithAppendFalse) { EXPECT_FALSE(headers.has("x-global-nope")); EXPECT_FALSE(headers.has("x-vhost-nope")); EXPECT_TRUE(headers.has("x-route-nope")); - auto transforms = route->requestHeaderTransforms(stream_info); + auto transforms = route_entry->requestHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, IsEmpty()); EXPECT_THAT(transforms.headers_to_overwrite_or_add, ElementsAre(Pair(Http::LowerCaseString("x-global-header"), "vhost-www2"), @@ -1840,8 +1851,8 @@ TEST_F(RouteMatcherTest, TestRequestHeadersToAddWithAppendFalse) { // Global only. { Http::TestRequestHeaderMapImpl headers = genHeaders("www.example.com", "/", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); // Added headers. EXPECT_EQ("global", headers.get_("x-global-header")); EXPECT_FALSE(headers.has("x-vhost-header")); @@ -1850,7 +1861,7 @@ TEST_F(RouteMatcherTest, TestRequestHeadersToAddWithAppendFalse) { EXPECT_FALSE(headers.has("x-global-nope")); EXPECT_TRUE(headers.has("x-vhost-nope")); EXPECT_TRUE(headers.has("x-route-nope")); - auto transforms = route->requestHeaderTransforms(stream_info); + auto transforms = route_entry->requestHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, IsEmpty()); EXPECT_THAT(transforms.headers_to_overwrite_or_add, ElementsAre(Pair(Http::LowerCaseString("x-global-header"), "global"))); @@ -1870,8 +1881,8 @@ TEST_F(RouteMatcherTest, TestRequestHeadersToAddWithAppendFalseMostSpecificWins) // Route overrides vhost and global. { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/endpoint", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); // Added headers. EXPECT_EQ("route-endpoint", headers.get_("x-global-header")); EXPECT_EQ("route-endpoint", headers.get_("x-vhost-header")); @@ -1880,7 +1891,7 @@ TEST_F(RouteMatcherTest, TestRequestHeadersToAddWithAppendFalseMostSpecificWins) EXPECT_FALSE(headers.has("x-global-nope")); EXPECT_FALSE(headers.has("x-vhost-nope")); EXPECT_FALSE(headers.has("x-route-nope")); - auto transforms = route->requestHeaderTransforms(stream_info); + auto transforms = route_entry->requestHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, IsEmpty()); EXPECT_THAT(transforms.headers_to_overwrite_or_add, ElementsAre(Pair(Http::LowerCaseString("x-global-header"), "global"), @@ -1897,8 +1908,8 @@ TEST_F(RouteMatcherTest, TestRequestHeadersToAddWithAppendFalseMostSpecificWins) // Virtual overrides global. { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); // Added headers. EXPECT_EQ("vhost-www2", headers.get_("x-global-header")); EXPECT_EQ("vhost-www2", headers.get_("x-vhost-header")); @@ -1907,7 +1918,7 @@ TEST_F(RouteMatcherTest, TestRequestHeadersToAddWithAppendFalseMostSpecificWins) EXPECT_FALSE(headers.has("x-global-nope")); EXPECT_FALSE(headers.has("x-vhost-nope")); EXPECT_TRUE(headers.has("x-route-nope")); - auto transforms = route->requestHeaderTransforms(stream_info); + auto transforms = route_entry->requestHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, IsEmpty()); EXPECT_THAT(transforms.headers_to_overwrite_or_add, ElementsAre(Pair(Http::LowerCaseString("x-global-header"), "global"), @@ -1933,13 +1944,13 @@ TEST_F(RouteMatcherTest, TestAddRemoveResponseHeaders) { { Http::TestRequestHeaderMapImpl req_headers = genHeaders("www.lyft.com", "/new_endpoint/foo", "GET"); - const RouteEntry* route = config.route(req_headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(req_headers, 0)->routeEntry(); Http::TestResponseHeaderMapImpl headers; - route->finalizeResponseHeaders(headers, stream_info); + route_entry->finalizeResponseHeaders(headers, stream_info); EXPECT_EQ("route-override", headers.get_("x-global-header1")); EXPECT_EQ("route-override", headers.get_("x-vhost-header1")); EXPECT_EQ("route-override", headers.get_("x-route-header")); - auto transforms = route->responseHeaderTransforms(stream_info); + auto transforms = route_entry->responseHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, ElementsAre(Pair(Http::LowerCaseString("x-route-header"), "route-override"), Pair(Http::LowerCaseString("x-global-header1"), "route-override"), @@ -1956,13 +1967,13 @@ TEST_F(RouteMatcherTest, TestAddRemoveResponseHeaders) { // Multiple routes can have same route-level headers with different values. { Http::TestRequestHeaderMapImpl req_headers = genHeaders("www.lyft.com", "/", "GET"); - const RouteEntry* route = config.route(req_headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(req_headers, 0)->routeEntry(); Http::TestResponseHeaderMapImpl headers; - route->finalizeResponseHeaders(headers, stream_info); + route_entry->finalizeResponseHeaders(headers, stream_info); EXPECT_EQ("vhost-override", headers.get_("x-global-header1")); EXPECT_EQ("vhost1-www2", headers.get_("x-vhost-header1")); EXPECT_EQ("route-allpath", headers.get_("x-route-header")); - auto transforms = route->responseHeaderTransforms(stream_info); + auto transforms = route_entry->responseHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, ElementsAre(Pair(Http::LowerCaseString("x-route-header"), "route-allpath"), Pair(Http::LowerCaseString("x-global-header1"), "vhost-override"), @@ -1979,13 +1990,13 @@ TEST_F(RouteMatcherTest, TestAddRemoveResponseHeaders) { { Http::TestRequestHeaderMapImpl req_headers = genHeaders("www-staging.lyft.net", "/foo", "GET"); - const RouteEntry* route = config.route(req_headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(req_headers, 0)->routeEntry(); Http::TestResponseHeaderMapImpl headers; - route->finalizeResponseHeaders(headers, stream_info); + route_entry->finalizeResponseHeaders(headers, stream_info); EXPECT_EQ("global1", headers.get_("x-global-header1")); EXPECT_EQ("vhost1-www2_staging", headers.get_("x-vhost-header1")); EXPECT_EQ("route-allprefix", headers.get_("x-route-header")); - auto transforms = route->responseHeaderTransforms(stream_info); + auto transforms = route_entry->responseHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, ElementsAre(Pair(Http::LowerCaseString("x-route-header"), "route-allprefix"), Pair(Http::LowerCaseString("x-vhost-header1"), "vhost1-www2_staging"), @@ -1998,11 +2009,11 @@ TEST_F(RouteMatcherTest, TestAddRemoveResponseHeaders) { // Global headers. { Http::TestRequestHeaderMapImpl req_headers = genHeaders("api.lyft.com", "/", "GET"); - const RouteEntry* route = config.route(req_headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(req_headers, 0)->routeEntry(); Http::TestResponseHeaderMapImpl headers; - route->finalizeResponseHeaders(headers, stream_info); + route_entry->finalizeResponseHeaders(headers, stream_info); EXPECT_EQ("global1", headers.get_("x-global-header1")); - auto transforms = route->responseHeaderTransforms(stream_info); + auto transforms = route_entry->responseHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, ElementsAre(Pair(Http::LowerCaseString("x-global-header1"), "global1"))); EXPECT_THAT(transforms.headers_to_overwrite_or_add, IsEmpty()); @@ -2025,14 +2036,14 @@ TEST_F(RouteMatcherTest, TestAddRemoveResponseHeadersOverwriteIfExistOrAdd) { Http::TestRequestHeaderMapImpl req_headers = genHeaders("www.lyft.com", "/new_endpoint/foo", "GET"); - const RouteEntry* route = config.route(req_headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(req_headers, 0)->routeEntry(); Http::TestResponseHeaderMapImpl headers; - route->finalizeResponseHeaders(headers, stream_info); + route_entry->finalizeResponseHeaders(headers, stream_info); EXPECT_EQ("global1", headers.get_("x-global-header1")); EXPECT_EQ("vhost1-www2", headers.get_("x-vhost-header1")); EXPECT_EQ("route-override", headers.get_("x-route-header")); - auto transforms = route->responseHeaderTransforms(stream_info); + auto transforms = route_entry->responseHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, IsEmpty()); EXPECT_THAT(transforms.headers_to_overwrite_or_add, ElementsAre(Pair(Http::LowerCaseString("x-route-header"), "route-override"), @@ -2055,15 +2066,15 @@ TEST_F(RouteMatcherTest, TestAddRemoveResponseHeadersAddIfAbsent) { Http::TestRequestHeaderMapImpl req_headers = genHeaders("www.lyft.com", "/new_endpoint/foo", "GET"); - const RouteEntry* route = config.route(req_headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(req_headers, 0)->routeEntry(); Http::TestResponseHeaderMapImpl headers{{":status", "200"}, {"x-route-header", "exist-value"}}; - route->finalizeResponseHeaders(headers, stream_info); + route_entry->finalizeResponseHeaders(headers, stream_info); EXPECT_EQ("route-override", headers.get_("x-global-header1")); EXPECT_EQ("route-override", headers.get_("x-vhost-header1")); // If related header is exist in the headers then do nothing. EXPECT_EQ("exist-value", headers.get_("x-route-header")); - auto transforms = route->responseHeaderTransforms(stream_info); + auto transforms = route_entry->responseHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, IsEmpty()); EXPECT_THAT(transforms.headers_to_overwrite_or_add, IsEmpty()); EXPECT_THAT(transforms.headers_to_add_if_absent, @@ -2087,14 +2098,14 @@ TEST_F(RouteMatcherTest, TestAddRemoveResponseHeadersAppendMostSpecificWins) { Http::TestRequestHeaderMapImpl req_headers = genHeaders("www.lyft.com", "/new_endpoint/foo", "GET"); - const RouteEntry* route = config.route(req_headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(req_headers, 0)->routeEntry(); Http::TestResponseHeaderMapImpl headers; - route->finalizeResponseHeaders(headers, stream_info); + route_entry->finalizeResponseHeaders(headers, stream_info); EXPECT_EQ("route-override", headers.get_("x-global-header1")); EXPECT_EQ("route-override", headers.get_("x-vhost-header1")); EXPECT_EQ("route-override", headers.get_("x-route-header")); - auto transforms = route->responseHeaderTransforms(stream_info); + auto transforms = route_entry->responseHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, IsEmpty()); EXPECT_THAT(transforms.headers_to_overwrite_or_add, ElementsAre(Pair(Http::LowerCaseString("x-global-header1"), "global1"), @@ -2145,19 +2156,20 @@ class HeaderTransformsDoFormattingTest : public RouteMatcherTest { Http::TestRequestHeaderMapImpl req_headers = genHeaders("www.lyft.com", "/new_endpoint/foo", "GET"); - const RouteEntry* route = config.route(req_headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(req_headers, 0)->routeEntry(); Http::TestResponseHeaderMapImpl headers; - route->finalizeResponseHeaders(headers, stream_info); + route_entry->finalizeResponseHeaders(headers, stream_info); - auto transforms = run_request_header_test - ? route->requestHeaderTransforms(stream_info, /*do_formatting=*/true) - : route->responseHeaderTransforms(stream_info, /*do_formatting=*/true); + auto transforms = + run_request_header_test + ? route_entry->requestHeaderTransforms(stream_info, /*do_formatting=*/true) + : route_entry->responseHeaderTransforms(stream_info, /*do_formatting=*/true); EXPECT_THAT(transforms.headers_to_overwrite_or_add, ElementsAre(Pair(Http::LowerCaseString("x-has-variable"), "test_value"))); transforms = run_request_header_test - ? route->requestHeaderTransforms(stream_info, /*do_formatting=*/false) - : route->responseHeaderTransforms(stream_info, /*do_formatting=*/false); + ? route_entry->requestHeaderTransforms(stream_info, /*do_formatting=*/false) + : route_entry->responseHeaderTransforms(stream_info, /*do_formatting=*/false); EXPECT_THAT( transforms.headers_to_overwrite_or_add, ElementsAre(Pair(Http::LowerCaseString("x-has-variable"), "%PER_REQUEST_STATE(testing)%"))); @@ -2200,17 +2212,17 @@ most_specific_header_mutations_wins: true { Http::TestRequestHeaderMapImpl req_headers = genHeaders("www.lyft.com", "/cacheable", "GET"); - const RouteEntry* route = config.route(req_headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(req_headers, 0)->routeEntry(); Http::TestResponseHeaderMapImpl headers; - route->finalizeResponseHeaders(headers, stream_info); + route_entry->finalizeResponseHeaders(headers, stream_info); EXPECT_FALSE(headers.has("cache-control")); } { Http::TestRequestHeaderMapImpl req_headers = genHeaders("www.lyft.com", "/foo", "GET"); - const RouteEntry* route = config.route(req_headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(req_headers, 0)->routeEntry(); Http::TestResponseHeaderMapImpl headers; - route->finalizeResponseHeaders(headers, stream_info); + route_entry->finalizeResponseHeaders(headers, stream_info); EXPECT_EQ("private", headers.get_("cache-control")); } } @@ -3487,9 +3499,9 @@ TEST_F(RouteMatcherTest, ClusterHeader) { route->routeEntry()->rateLimitPolicy(); route->routeEntry()->retryPolicy(); route->routeEntry()->shadowPolicies(); - route->routeEntry()->virtualCluster(headers); - route->routeEntry()->virtualHost(); - route->routeEntry()->virtualHost().rateLimitPolicy(); + route->virtualHost().virtualCluster(headers); + route->virtualHost(); + route->virtualHost().rateLimitPolicy(); route->routeEntry()->pathMatchCriterion(); route->routeEntry()->hedgePolicy(); route->routeEntry()->maxGrpcTimeout(); @@ -3633,7 +3645,8 @@ TEST_F(RouteMatcherTest, UnknownClusterSpecifierPlugin) { )EOF"; NiceMock stream_info; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_THAT(creation_status_.message(), testing::ContainsRegex("Didn't find a registered implementation for.*")); } @@ -3805,7 +3818,8 @@ TEST_F(RouteMatcherTest, UnknownClusterSpecifierPluginName) { })); NiceMock stream_info; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ(creation_status_.message(), "Unknown cluster specifier plugin name: test4 is used in the route"); } @@ -4021,7 +4035,8 @@ TEST_F(RouteMatcherTest, ClusterNotFound) { cluster: www2 )EOF"; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_THAT(creation_status_.message(), testing::ContainsRegex("route: unknown cluster*")); } @@ -4041,7 +4056,8 @@ TEST_F(RouteMatcherTest, ShadowClusterNotFound) { )EOF"; factory_context_.cluster_manager_.initializeClusters({"www2"}, {}); - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ(creation_status_.message(), "route: unknown shadow cluster 'some_cluster'"); } @@ -4121,7 +4137,6 @@ TEST_F(RouteMatcherTest, EnableIsTimeoutRetryHeader) { creation_status_); EXPECT_TRUE(config.route(genHeaders("www.example.com", "/foo", "GET"), 0) - ->routeEntry() ->virtualHost() .includeIsTimeoutRetryHeader()); } @@ -4142,7 +4157,6 @@ TEST_F(RouteMatcherTest, NoIsTimeoutRetryHeader) { creation_status_); EXPECT_FALSE(config.route(genHeaders("www.example.com", "/foo", "GET"), 0) - ->routeEntry() ->virtualHost() .includeIsTimeoutRetryHeader()); } @@ -4330,7 +4344,8 @@ TEST_F(RouteMatcherTest, RequestMirrorPoliciesWithBothClusterAndClusterHeader) { cluster: www2 )EOF"; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_THAT(creation_status_.message(), testing::ContainsRegex("Only one of cluster '.*' or cluster_header '.*' in request " "mirror policy can be specified")); @@ -4355,7 +4370,8 @@ TEST_F(RouteMatcherTest, RequestMirrorPoliciesWithNoClusterSpecifier) { cluster: www2 )EOF"; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ( creation_status_.message(), "Exactly one of cluster or cluster_header in request mirror policy need to be specified"); @@ -5467,7 +5483,8 @@ TEST_F(RouteMatcherTest, TestPrefixAndRegexRewrites) { cluster: www2 )EOF"; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ(creation_status_.message(), "Specify only one of prefix_rewrite, regex_rewrite or path_rewrite_policy"); } @@ -6399,10 +6416,10 @@ class WeightedClustersHeaderTransformationsTest : public RouteMatcherTest { Http::TestRequestHeaderMapImpl req_headers = genHeaders("www.lyft.com", "/", "GET"); RouteConstSharedPtr owned_route = config.route(req_headers, 0); - const RouteEntry* route = owned_route->routeEntry(); + const RouteEntry* route_entry = owned_route->routeEntry(); - auto transforms = run_request_header_test ? route->requestHeaderTransforms(stream_info) - : route->responseHeaderTransforms(stream_info); + auto transforms = run_request_header_test ? route_entry->requestHeaderTransforms(stream_info) + : route_entry->responseHeaderTransforms(stream_info); EXPECT_THAT(transforms.headers_to_append_or_add, ElementsAre(Pair(Http::LowerCaseString("x-cluster-header"), "cluster1"), Pair(Http::LowerCaseString("x-route-header"), "route-override"), @@ -6543,7 +6560,8 @@ TEST_F(RouteMatcherTest, WeightedClustersSumOfWeightsTooLarge) { weight: 2394967295 )EOF"; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ(creation_status_.message(), "The sum of weights of all weighted clusters of route lyft_route exceeds 4294967295"); } @@ -6592,7 +6610,8 @@ TEST_F(RouteMatcherTest, TestWeightedClusterInvalidClusterName) { weight: 34 )EOF"; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_FALSE(creation_status_.ok()); } @@ -6640,14 +6659,14 @@ TEST_F(RouteMatcherTest, TestWeightedClusterHeaderManipulation) { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/foo", "GET"); Http::TestResponseHeaderMapImpl resp_headers({{"x-remove-cluster1", "value"}}); RouteConstSharedPtr cached_route = config.route(headers, 0); - const RouteEntry* route = cached_route->routeEntry(); - EXPECT_EQ("cluster1", route->clusterName()); + const RouteEntry* route_entry = cached_route->routeEntry(); + EXPECT_EQ("cluster1", route_entry->clusterName()); - route->finalizeRequestHeaders(headers, stream_info, true); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("cluster1", headers.get_("x-req-cluster")); EXPECT_EQ("new_host1", headers.getHostValue()); - route->finalizeResponseHeaders(resp_headers, stream_info); + route_entry->finalizeResponseHeaders(resp_headers, stream_info); EXPECT_EQ("cluster1", resp_headers.get_("x-resp-cluster")); EXPECT_FALSE(resp_headers.has("x-remove-cluster1")); } @@ -6656,13 +6675,13 @@ TEST_F(RouteMatcherTest, TestWeightedClusterHeaderManipulation) { Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/foo", "GET"); Http::TestResponseHeaderMapImpl resp_headers({{"x-remove-cluster2", "value"}}); RouteConstSharedPtr cached_route = config.route(headers, 55); - const RouteEntry* route = cached_route->routeEntry(); - EXPECT_EQ("cluster2", route->clusterName()); + const RouteEntry* route_entry = cached_route->routeEntry(); + EXPECT_EQ("cluster2", route_entry->clusterName()); - route->finalizeRequestHeaders(headers, stream_info, true); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("cluster2", headers.get_("x-req-cluster")); - route->finalizeResponseHeaders(resp_headers, stream_info); + route_entry->finalizeResponseHeaders(resp_headers, stream_info); EXPECT_EQ("cluster2", resp_headers.get_("x-resp-cluster")); EXPECT_FALSE(resp_headers.has("x-remove-cluster2")); } @@ -6702,14 +6721,14 @@ TEST_F(RouteMatcherTest, TestWeightedClusterClusterHeaderHeaderManipulation) { headers.addCopy("x-route-to-this-cluster", "cluster1"); Http::TestResponseHeaderMapImpl resp_headers({{"x-header-to-remove-cluster", "value"}}); auto dynamic_route = config.route(headers, 0); - const RouteEntry* route = dynamic_route->routeEntry(); - EXPECT_EQ("cluster1", route->clusterName()); + const RouteEntry* route_entry = dynamic_route->routeEntry(); + EXPECT_EQ("cluster1", route_entry->clusterName()); - route->finalizeRequestHeaders(headers, stream_info, true); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("cluster-adding-this-value", headers.get_("x-req-cluster")); EXPECT_EQ("new_host1", headers.getHostValue()); - route->finalizeResponseHeaders(resp_headers, stream_info); + route_entry->finalizeResponseHeaders(resp_headers, stream_info); EXPECT_EQ("cluster-adding-this-value", resp_headers.get_("x-resp-cluster")); EXPECT_FALSE(resp_headers.has("x-remove-cluster1")); } @@ -7104,10 +7123,7 @@ TEST_F(RoutePropertyTest, DEPRECATED_FEATURE_TEST(TestVHostCorsConfig)) { creation_status_); const Router::CorsPolicy* cors_policy = - config.route(genHeaders("api.lyft.com", "/api", "GET"), 0) - ->routeEntry() - ->virtualHost() - .corsPolicy(); + config.route(genHeaders("api.lyft.com", "/api", "GET"), 0)->virtualHost().corsPolicy(); EXPECT_EQ(cors_policy->enabled(), false); EXPECT_EQ(cors_policy->shadowEnabled(), true); @@ -7338,8 +7354,8 @@ TEST_F(CustomRequestHeadersTest, AddNewHeader) { TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/new_endpoint/foo", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("127.0.0.1", headers.get_("x-client-ip")); } @@ -7808,7 +7824,6 @@ metadata: { filter_metadata: { com.bar.foo: { baz: test_config_value }, baz: {na const auto route = config.route(genHeaders("www.foo.com", "/", "GET"), 0); checkPathMatchCriterion(route.get(), "/", PathMatchType::Prefix); - const auto route_entry = route->routeEntry(); const auto& metadata = route->metadata(); const auto& typed_metadata = route->typedMetadata(); @@ -7817,12 +7832,12 @@ metadata: { filter_metadata: { com.bar.foo: { baz: test_config_value }, baz: {na EXPECT_NE(nullptr, typed_metadata.get(baz_factory.name())); EXPECT_EQ("bluh", typed_metadata.get(baz_factory.name())->name); - EXPECT_EQ("bar", symbol_table_->toString(route_entry->virtualHost().statName())); - EXPECT_EQ("foo", route_entry->virtualHost().routeConfig().name()); + EXPECT_EQ("bar", symbol_table_->toString(route->virtualHost().statName())); + EXPECT_EQ("foo", route->virtualHost().routeConfig().name()); // Get metadata of virtual host. - const auto& vh_metadata = route_entry->virtualHost().metadata(); - const auto& vh_typed_metadata = route_entry->virtualHost().typedMetadata(); + const auto& vh_metadata = route->virtualHost().metadata(); + const auto& vh_typed_metadata = route->virtualHost().typedMetadata(); EXPECT_EQ( "test_vh_value", @@ -7831,8 +7846,8 @@ metadata: { filter_metadata: { com.bar.foo: { baz: test_config_value }, baz: {na EXPECT_EQ("vh_bluh", vh_typed_metadata.get(baz_factory.name())->name); // Get metadata of route configuration. - const auto& config_metadata = route_entry->virtualHost().routeConfig().metadata(); - const auto& config_typed_metadata = route_entry->virtualHost().routeConfig().typedMetadata(); + const auto& config_metadata = route->virtualHost().routeConfig().metadata(); + const auto& config_typed_metadata = route->virtualHost().routeConfig().typedMetadata(); EXPECT_EQ("test_config_value", Envoy::Config::Metadata::metadataValue(&config_metadata, "com.bar.foo", "baz") @@ -8824,10 +8839,10 @@ TEST_F(RouteMatcherTest, PathSeparatedPrefixMatchRewrite) { NiceMock stream_info; Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rewrite?param=true#fragment", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/new/api?param=true#fragment", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); - EXPECT_EQ("rewrite-cluster", route->clusterName()); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/new/api?param=true#fragment", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); + EXPECT_EQ("rewrite-cluster", route_entry->clusterName()); EXPECT_EQ("/new/api?param=true#fragment", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -8836,10 +8851,11 @@ TEST_F(RouteMatcherTest, PathSeparatedPrefixMatchRewrite) { NiceMock stream_info; Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rewrite/this?param=true#fragment", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/new/api/this?param=true#fragment", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); - EXPECT_EQ("rewrite-cluster", route->clusterName()); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/new/api/this?param=true#fragment", + route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); + EXPECT_EQ("rewrite-cluster", route_entry->clusterName()); EXPECT_EQ("/new/api/this?param=true#fragment", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -9231,7 +9247,8 @@ TEST_F(RouteConfigurationV2, DuplicateUpgradeConfigs) { enabled: false )EOF"; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ(creation_status_.message(), "Duplicate upgrade WebSocket"); } @@ -9251,7 +9268,8 @@ TEST_F(RouteConfigurationV2, BadConnectConfig) { connect_config: {} enabled: false )EOF"; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ(creation_status_.message(), "Non-CONNECT upgrade type Websocket has ConnectConfig"); } @@ -9611,9 +9629,9 @@ TEST_F(RouteMatcherTest, PatternMatchRewriteSimple) { creation_status_); Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/one/two", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/rest/two/one", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/rest/two/one", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/rest/two/one", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -9646,10 +9664,10 @@ TEST_F(RouteMatcherTest, PatternMatchRewriteDoubleEqual) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/one/two/en/gb/ilp==/dGasdA/?key1=test1&key2=test2", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); EXPECT_EQ("/en/gb/ilp==/dGasdA/?key1=test1&key2=test2", - route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/en/gb/ilp==/dGasdA/?key1=test1&key2=test2", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -9682,9 +9700,9 @@ TEST_F(RouteMatcherTest, PatternMatchRewriteTripleEqualVariable) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/one/two/==na/three", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/==na/three/two", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/==na/three/two", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/==na/three/two", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -9717,9 +9735,9 @@ TEST_F(RouteMatcherTest, PatternMatchRewriteDoubleEqualVariable) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/one/two/=na/three", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/=na/three/two", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/=na/three/two", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/=na/three/two", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -9753,10 +9771,10 @@ TEST_F(RouteMatcherTest, PatternMatchRewriteDoubleEqualInWildcard) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/one/two/en/gb/ilp/dGasdA==/?key1=test1&key2=test2", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); EXPECT_EQ("/en/gb/ilp/dGasdA==/?key1=test1&key2=test2", - route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/en/gb/ilp/dGasdA==/?key1=test1&key2=test2", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -9790,17 +9808,17 @@ TEST_F(RouteMatcherTest, PatternMatchWildcardFilenameUnnamed) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/one/two/song.m3u8", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/rest/one/two", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/rest/one/two", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/rest/one/two", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); Http::TestRequestHeaderMapImpl headers_multi = genHeaders("path.prefix.com", "/rest/one/two/item/another/song.m3u8", "GET"); - const RouteEntry* route_multi = config.route(headers_multi, 0)->routeEntry(); - EXPECT_EQ("/rest/one/two", route_multi->currentUrlPathAfterRewrite(headers_multi)); - route->finalizeRequestHeaders(headers_multi, stream_info, true); + const RouteEntry* route_entry_multi = config.route(headers_multi, 0)->routeEntry(); + EXPECT_EQ("/rest/one/two", route_entry_multi->currentUrlPathAfterRewrite(headers_multi)); + route_entry->finalizeRequestHeaders(headers_multi, stream_info, true); EXPECT_EQ("/rest/one/two", headers_multi.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers_multi.get_(Http::Headers::get().Host)); } @@ -9834,9 +9852,10 @@ TEST_F(RouteMatcherTest, PatternMatchWildcardFilenameQueryParameters) { Http::TestRequestHeaderMapImpl headers = genHeaders( "path.prefix.com", "/api/cart/item/one/song.m3u8?one=0&two=1&three=2&four=3&go=ls", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/one?one=0&two=1&three=2&four=3&go=ls", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/one?one=0&two=1&three=2&four=3&go=ls", + route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/one?one=0&two=1&three=2&four=3&go=ls", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -9870,9 +9889,9 @@ TEST_F(RouteMatcherTest, PatternMatchWildcardFilename) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/one/two/song.m3u8", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/rest/one/two", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/rest/one/two", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/rest/one/two", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -9909,10 +9928,10 @@ TEST_F(RouteMatcherTest, PatternMatchWildcardComplexWildcardWithQueryParameter) "/xyzwebservices/v2/xyz/users/abc@xyz.com/carts/FL0001090004/" "entries?fields=FULL&client_type=WEB", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); EXPECT_EQ("/abc@xyz.com-FL0001090004/entries?fields=FULL&client_type=WEB", - route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/abc@xyz.com-FL0001090004/entries?fields=FULL&client_type=WEB", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); @@ -9947,9 +9966,9 @@ TEST_F(RouteMatcherTest, PatternMatchWildcardFilenameDir) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/one/two/root/sub/song.mp4", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/root/sub", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/root/sub", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/root/sub", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -9982,9 +10001,9 @@ TEST_F(RouteMatcherTest, PatternMatchRewriteSimpleTwo) { creation_status_); Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/one/two", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/two/one", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/two/one", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/two/one", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -10031,16 +10050,16 @@ TEST_F(RouteMatcherTest, PatternMatchRewriteCaseSensitive) { creation_status_); Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/one/two", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/two/one", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/two/one", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/two/one", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); headers = genHeaders("path.prefix.com", "/REST/one/two", "GET"); - route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/TEST/one", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/TEST/one", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/TEST/one", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -10138,9 +10157,9 @@ TEST_F(RouteMatcherTest, PatternMatchWildcardMiddleThreePartVariableNamed) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/one/previous/videos/three/end", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/previous/videos/three", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/previous/videos/three", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/previous/videos/three", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -10205,9 +10224,9 @@ TEST_F(RouteMatcherTest, PatternMatchWildcardUnnamedVariable) { creation_status_); Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/one/two", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/two", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/two", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/two", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -10241,9 +10260,9 @@ TEST_F(RouteMatcherTest, PatternMatchWildcardAtEndVariable) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/one/two/three/four", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/one", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/one", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/one", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -10277,9 +10296,9 @@ TEST_F(RouteMatcherTest, PatternMatchWildcardAtEndVariableNamed) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/one/two/three/four", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/two/three/four", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/two/three/four", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/two/three/four", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -10313,9 +10332,9 @@ TEST_F(RouteMatcherTest, PatternMatchWildcardMiddleVariableNamed) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/one/videos/three/end", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/videos/three", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/videos/three", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/videos/three", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -10349,9 +10368,9 @@ TEST_F(RouteMatcherTest, PatternMatchCaseSensitiveVariableNames) { Http::TestRequestHeaderMapImpl headers = genHeaders("path.prefix.com", "/rest/lower/upper/end", "GET"); - const RouteEntry* route = config.route(headers, 0)->routeEntry(); - EXPECT_EQ("/upper/lower", route->currentUrlPathAfterRewrite(headers)); - route->finalizeRequestHeaders(headers, stream_info, true); + const RouteEntry* route_entry = config.route(headers, 0)->routeEntry(); + EXPECT_EQ("/upper/lower", route_entry->currentUrlPathAfterRewrite(headers)); + route_entry->finalizeRequestHeaders(headers, stream_info, true); EXPECT_EQ("/upper/lower", headers.get_(Http::Headers::get().Path)); EXPECT_EQ("path.prefix.com", headers.get_(Http::Headers::get().Host)); } @@ -10724,7 +10743,8 @@ TEST_F(PerFilterConfigsTest, PerRouteWithUnknownFilter) { "@type": type.googleapis.com/google.protobuf.BoolValue )EOF"; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ(creation_status_.message(), "Didn't find a registered implementation for 'filter.unknown' with type URL: " "'google.protobuf.BoolValue'"); @@ -10745,7 +10765,8 @@ TEST_F(PerFilterConfigsTest, PerRouteWithHcmOptionalUnknownFilter) { factory_context_.cluster_manager_.initializeClusters({"baz"}, {}); - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); EXPECT_EQ(creation_status_.message(), "Didn't find a registered implementation for 'filter.unknown' with type URL: " "'google.protobuf.BoolValue'"); @@ -10835,7 +10856,8 @@ TEST_F(PerFilterConfigsTest, FilterConfigWithoutConfig) { is_optional: true )EOF"; - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, false, creation_status_); + TestConfigImpl give_me_a_name(parseRouteConfigurationFromYaml(yaml), factory_context_, false, + creation_status_); EXPECT_EQ(creation_status_.message(), "Empty route/virtual host per filter configuration for filter.unknown filter"); } @@ -11503,11 +11525,8 @@ TEST_F(CommonConfigImplTest, TestCommonConfig) { TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); - const auto& shared_config = - dynamic_cast(config.route(genHeaders("bat.com", "/", "GET"), 0) - ->routeEntry() - ->virtualHost() - .routeConfig()); + const auto& shared_config = dynamic_cast( + config.route(genHeaders("bat.com", "/", "GET"), 0)->virtualHost().routeConfig()); EXPECT_EQ(config.mostSpecificHeaderMutationsWins(), shared_config.mostSpecificHeaderMutationsWins()); diff --git a/test/common/router/delegating_route_impl_test.cc b/test/common/router/delegating_route_impl_test.cc index 69c93a63c329..5bd579dfa874 100644 --- a/test/common/router/delegating_route_impl_test.cc +++ b/test/common/router/delegating_route_impl_test.cc @@ -29,6 +29,7 @@ TEST(DelegatingRoute, DelegatingRouteTest) { TEST_METHOD(metadata); TEST_METHOD(typedMetadata); TEST_METHOD(routeName); + TEST_METHOD(virtualHost); std::string name; TEST_METHOD(mostSpecificPerFilterConfig, name); @@ -74,8 +75,6 @@ TEST(DelegatingRouteEntry, DelegatingRouteEntryTest) { TEST_METHOD(grpcTimeoutHeaderOffset); TEST_METHOD(maxGrpcTimeout); TEST_METHOD(grpcTimeoutOffset); - TEST_METHOD(virtualCluster, request_headers); - TEST_METHOD(virtualHost); TEST_METHOD(autoHostRewrite); TEST_METHOD(appendXfh); TEST_METHOD(metadataMatchCriteria); diff --git a/test/common/router/router_2_test.cc b/test/common/router/router_2_test.cc index bfa4f35adfeb..4925e55bf5f6 100644 --- a/test/common/router/router_2_test.cc +++ b/test/common/router/router_2_test.cc @@ -38,7 +38,7 @@ TEST_F(RouterTestSuppressEnvoyHeaders, Http1Upstream) { router_->onDestroy(); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } // Validate that we don't set x-envoy-overloaded when Envoy header suppression @@ -73,7 +73,7 @@ TEST_F(RouterTestSuppressEnvoyHeaders, EnvoyUpstreamServiceTime) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -141,7 +141,7 @@ class WatermarkTest : public RouterTestBase { router_->decodeHeaders(headers_, header_only_request); if (pool_ready) { EXPECT_EQ( - 1U, callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + 1U, callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } } void sendResponse() { @@ -385,7 +385,7 @@ TEST_F(WatermarkTest, RetryRequestNotComplete) { // This will result in retry_state_ being deleted. router_->decodeData(data, false); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // This should not trigger a retry as the retry state has been deleted. EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_.host_->outlier_detector_, @@ -435,7 +435,7 @@ TEST_F(RouterTestChildSpan, BasicFlow) { EXPECT_CALL(callbacks_, tracingConfig()).Times(2); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -486,7 +486,7 @@ TEST_F(RouterTestChildSpan, ResetFlow) { EXPECT_CALL(callbacks_, tracingConfig()).Times(2); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Upstream responds back to envoy. Http::ResponseHeaderMapPtr response_headers( @@ -540,7 +540,7 @@ TEST_F(RouterTestChildSpan, CancelFlow) { EXPECT_CALL(callbacks_, tracingConfig()).Times(2); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Destroy the router, causing the upstream request to be cancelled. // Response code on span is 0 because the upstream never sent a response. @@ -591,7 +591,7 @@ TEST_F(RouterTestChildSpan, ResetRetryFlow) { EXPECT_CALL(callbacks_, tracingConfig()).Times(2); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // The span should be annotated with the reset-related fields. EXPECT_CALL(*child_span_1, @@ -635,7 +635,7 @@ TEST_F(RouterTestChildSpan, ResetRetryFlow) { router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Upstream responds back with a normal response. Span should be annotated as usual. Http::ResponseHeaderMapPtr response_headers( @@ -684,7 +684,7 @@ TEST_F(RouterTestNoChildSpan, BasicFlow) { EXPECT_CALL(callbacks_.active_span_, injectContext(_, _)); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -891,7 +891,7 @@ TEST_F(RouterTestSupressGRPCStatsEnabled, ExcludeTimeoutHttpStats) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::CoreResponseFlag::UpstreamRequestTimeout)); @@ -909,10 +909,10 @@ TEST_F(RouterTestSupressGRPCStatsEnabled, ExcludeTimeoutHttpStats) { cm_.thread_local_cluster_.cluster_.info_->stats_store_.counter("upstream_rq_timeout") .value()); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_timeout_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_timeout_.value()); EXPECT_EQ(1UL, cm_.thread_local_cluster_.conn_pool_.host_->stats().rq_timeout_.value()); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_timeout_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_timeout_.value()); EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_.counter("upstream_rq_completed") .value()); @@ -944,7 +944,7 @@ TEST_F(RouterTestSupressGRPCStatsDisabled, IncludeHttpTimeoutStats) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::CoreResponseFlag::UpstreamRequestTimeout)); @@ -962,10 +962,10 @@ TEST_F(RouterTestSupressGRPCStatsDisabled, IncludeHttpTimeoutStats) { cm_.thread_local_cluster_.cluster_.info_->stats_store_.counter("upstream_rq_timeout") .value()); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_timeout_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_timeout_.value()); EXPECT_EQ(1UL, cm_.thread_local_cluster_.conn_pool_.host_->stats().rq_timeout_.value()); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_timeout_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_timeout_.value()); EXPECT_EQ( 1U, diff --git a/test/common/router/router_ratelimit_test.cc b/test/common/router/router_ratelimit_test.cc index 830af83db91a..9742352dd377 100644 --- a/test/common/router/router_ratelimit_test.cc +++ b/test/common/router/router_ratelimit_test.cc @@ -202,11 +202,10 @@ TEST_F(RateLimitConfiguration, TestVirtualHost) { factory_context_.cluster_manager_.initializeClusters({"www2test"}, {}); setupTest(yaml); auto route = config_->route(genHeaders("www.lyft.com", "/bar", "GET"), stream_info_, 0); - auto* route_entry = route->routeEntry(); ON_CALL(Const(stream_info_), route()).WillByDefault(testing::Return(route)); std::vector> rate_limits = - route_entry->virtualHost().rateLimitPolicy().getApplicableRateLimit(0); + route->virtualHost().rateLimitPolicy().getApplicableRateLimit(0); EXPECT_EQ(1U, rate_limits.size()); std::vector descriptors; @@ -294,7 +293,7 @@ class RateLimitPolicyEntryTest : public testing::Test { absl::Status creation_status; rate_limit_entry_ = std::make_unique( parseRateLimitFromV3Yaml(yaml), factory_context_, creation_status); - THROW_IF_NOT_OK(creation_status); + THROW_IF_NOT_OK(creation_status); // NOLINT descriptors_.clear(); local_descriptors_.clear(); stream_info_.downstream_connection_info_provider_->setRemoteAddress(default_remote_address_); @@ -318,7 +317,7 @@ class RateLimitPolicyEntryIpv6Test : public testing::Test { absl::Status creation_status; rate_limit_entry_ = std::make_unique( parseRateLimitFromV3Yaml(yaml), factory_context_, creation_status); - THROW_IF_NOT_OK(creation_status); + THROW_IF_NOT_OK(creation_status); // NOLINT descriptors_.clear(); local_descriptors_.clear(); stream_info_.downstream_connection_info_provider_->setRemoteAddress(default_remote_address_); diff --git a/test/common/router/router_test.cc b/test/common/router/router_test.cc index 1d9c93217976..1ccd9ef87620 100644 --- a/test/common/router/router_test.cc +++ b/test/common/router/router_test.cc @@ -205,9 +205,9 @@ class RouterTest : public RouterTestBase { router_->onDestroy(); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } }; @@ -326,7 +326,7 @@ TEST_F(RouterTest, RouteNotFound) { EXPECT_EQ(1UL, stats_store_.counter("test.no_route").value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ(callbacks_.details(), "route_not_found"); } @@ -365,7 +365,7 @@ TEST_F(RouterTest, ClusterNotFound) { EXPECT_EQ(1UL, stats_store_.counter("test.no_cluster").value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ(callbacks_.details(), "cluster_not_found"); } @@ -396,7 +396,7 @@ TEST_F(RouterTest, PoolFailureWithPriority) { EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Pool failure, so upstream request was not initiated. EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ( callbacks_.details(), "upstream_reset_before_response_started{remote_connection_failure|tls_version_mismatch}"); @@ -429,7 +429,7 @@ TEST_F(RouterTest, PoolFailureDueToConnectTimeout) { EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Pool failure, so upstream request was not initiated. EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ(callbacks_.details(), "upstream_reset_before_response_started{connection_timeout|connect_timeout}"); } @@ -452,7 +452,7 @@ TEST_F(RouterTest, Http1Upstream) { router_->onDestroy(); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } TEST_F(RouterTest, Http2Upstream) { @@ -471,7 +471,7 @@ TEST_F(RouterTest, Http2Upstream) { router_->onDestroy(); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } TEST_F(RouterTest, HashPolicy) { @@ -498,7 +498,7 @@ TEST_F(RouterTest, HashPolicy) { router_->onDestroy(); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } TEST_F(RouterTest, HashPolicyNoHash) { @@ -525,7 +525,7 @@ TEST_F(RouterTest, HashPolicyNoHash) { router_->onDestroy(); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } TEST_F(RouterTest, HashKeyNoHashPolicy) { @@ -737,7 +737,7 @@ TEST_F(RouterTest, CancelBeforeBoundToPool) { router_->onDestroy(); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } TEST_F(RouterTest, NoHost) { @@ -758,7 +758,7 @@ TEST_F(RouterTest, NoHost) { .value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ(callbacks_.details(), "no_healthy_upstream"); } @@ -792,7 +792,7 @@ TEST_F(RouterTest, MaintenanceMode) { .value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->load_report_stats_store_ .counter("upstream_rq_dropped") .value()); @@ -839,7 +839,7 @@ TEST_F(RouterTest, DropOverloadDropped) { .value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->load_report_stats_store_ .counter("upstream_rq_dropped") .value()); @@ -953,7 +953,7 @@ TEST_F(RouterTest, EnvoyAttemptCountInRequestUpdatedInRetries) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Initial request has 1 attempt. EXPECT_EQ(1, atoi(std::string(headers.getEnvoyAttemptCountValue()).c_str())); @@ -981,7 +981,7 @@ TEST_F(RouterTest, EnvoyAttemptCountInRequestUpdatedInRetries) { expectNewStreamWithImmediateEncoder(encoder2, &response_decoder, Http::Protocol::Http10); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // The retry should cause the header to increase to 2. EXPECT_EQ(2, atoi(std::string(headers.getEnvoyAttemptCountValue()).c_str())); @@ -1054,7 +1054,7 @@ TEST_F(RouterTest, EnvoyAttemptCountInResponsePresentWithLocalReply) { router_->decodeHeaders(headers, true); // Pool failure, so upstream request was never initiated. EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); EXPECT_EQ(callbacks_.details(), "upstream_reset_before_response_started{remote_connection_failure}"); @@ -1075,7 +1075,7 @@ TEST_F(RouterTest, EnvoyAttemptCountInResponseWithRetries) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ(1U, callbacks_.stream_info_.attemptCount().value()); // 5xx response. @@ -1093,7 +1093,7 @@ TEST_F(RouterTest, EnvoyAttemptCountInResponseWithRetries) { expectNewStreamWithImmediateEncoder(encoder2, &response_decoder, Http::Protocol::Http10); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ(2U, callbacks_.stream_info_.attemptCount().value()); // Normal response. @@ -1179,7 +1179,7 @@ TEST_F(RouterTest, AllDebugConfig) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); } @@ -1193,7 +1193,7 @@ TEST_F(RouterTest, NoRetriesOverflow) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // 5xx response. router_->retry_state_->expectHeadersRetry(); @@ -1210,7 +1210,7 @@ TEST_F(RouterTest, NoRetriesOverflow) { expectNewStreamWithImmediateEncoder(encoder2, &response_decoder, Http::Protocol::Http10); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // RetryOverflow kicks in. EXPECT_CALL(callbacks_.stream_info_, @@ -1252,7 +1252,7 @@ TEST_F(RouterTest, ResetDuringEncodeHeaders) { // The reset will be converted into a local reply. router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); router_->onDestroy(); } @@ -1269,7 +1269,7 @@ TEST_F(RouterTest, UpstreamTimeoutAllStatsEmission) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::CoreResponseFlag::UpstreamRequestTimeout)); @@ -1284,7 +1284,7 @@ TEST_F(RouterTest, UpstreamTimeoutAllStatsEmission) { cm_.thread_local_cluster_.cluster_.info_->stats_store_.counter("upstream_rq_timeout") .value()); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_timeout_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_timeout_.value()); EXPECT_EQ(1UL, cm_.thread_local_cluster_.conn_pool_.host_->stats().rq_timeout_.value()); } @@ -1301,7 +1301,7 @@ TEST_F(RouterTest, UpstreamTimeout) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::CoreResponseFlag::UpstreamRequestTimeout)); @@ -1319,7 +1319,7 @@ TEST_F(RouterTest, UpstreamTimeout) { cm_.thread_local_cluster_.cluster_.info_->stats_store_.counter("upstream_rq_timeout") .value()); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_timeout_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_timeout_.value()); EXPECT_EQ(1UL, cm_.thread_local_cluster_.conn_pool_.host_->stats().rq_timeout_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); } @@ -1341,7 +1341,7 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStat) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Global timeout budget used. EXPECT_CALL( @@ -1377,7 +1377,7 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatFailure) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Global timeout budget used. EXPECT_CALL( @@ -1411,7 +1411,7 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatOnlyGlobal) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Global timeout budget used. EXPECT_CALL( @@ -1447,7 +1447,7 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringRetries) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Per-try budget used on the first request. EXPECT_CALL(cm_.thread_local_cluster_.cluster_.info_->timeout_budget_stats_store_, @@ -1479,7 +1479,7 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringRetries) { expectPerTryTimerCreate(); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Per-try budget exhausted on the second try. EXPECT_CALL(cm_.thread_local_cluster_.cluster_.info_->timeout_budget_stats_store_, @@ -1530,7 +1530,7 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringGlobalTimeout) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Per-try budget used on the first request. EXPECT_CALL(cm_.thread_local_cluster_.cluster_.info_->timeout_budget_stats_store_, @@ -1561,7 +1561,7 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringGlobalTimeout) { expectPerTryTimerCreate(); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Global timeout was hit, fires 100. EXPECT_CALL( @@ -1609,7 +1609,7 @@ TEST_F(RouterTest, GrpcOkTrailersOnly) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "0"}}); @@ -1631,7 +1631,7 @@ TEST_F(RouterTest, GrpcAlreadyExistsTrailersOnly) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "6"}}); @@ -1653,7 +1653,7 @@ TEST_F(RouterTest, GrpcOutlierDetectionUnavailableStatusCode) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "14"}}); @@ -1676,7 +1676,7 @@ TEST_F(RouterTest, GrpcInternalTrailersOnly) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "13"}}); @@ -1699,7 +1699,7 @@ TEST_F(RouterTest, GrpcDataEndStream) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -1725,7 +1725,7 @@ TEST_F(RouterTest, GrpcReset) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -1752,7 +1752,7 @@ TEST_F(RouterTest, GrpcOk) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(callbacks_.dispatcher_, pushTrackedObject(_)); EXPECT_CALL(callbacks_.dispatcher_, popTrackedObject(_)); @@ -1783,7 +1783,7 @@ TEST_F(RouterTest, GrpcInternal) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -1810,7 +1810,7 @@ TEST_F(RouterTest, UpstreamTimeoutWithAltResponse) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::CoreResponseFlag::UpstreamRequestTimeout)); @@ -1872,12 +1872,12 @@ TEST_F(RouterTest, UpstreamPerTryIdleTimeout) { per_try_idle_timeout_ = new Event::MockTimer(&callbacks_.dispatcher_); EXPECT_CALL(*per_try_idle_timeout_, enableTimer(std::chrono::milliseconds(3000), _)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // The per try timeout timer should not be started yet. pool_callbacks->onPoolReady(encoder, cm_.thread_local_cluster_.conn_pool_.host_, upstream_stream_info_, Http::Protocol::Http10); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(encoder.stream_, resetStream(Http::StreamResetReason::LocalReset)); EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_.host_->outlier_detector_, @@ -1935,12 +1935,12 @@ TEST_F(RouterTest, UpstreamPerTryIdleTimeoutSuccess) { per_try_idle_timeout_ = new Event::MockTimer(&callbacks_.dispatcher_); EXPECT_CALL(*per_try_idle_timeout_, enableTimer(std::chrono::milliseconds(3000), _)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // The per try timeout timer should not be started yet. pool_callbacks->onPoolReady(encoder, cm_.thread_local_cluster_.conn_pool_.host_, upstream_stream_info_, Http::Protocol::Http10); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(*per_try_idle_timeout_, enableTimer(std::chrono::milliseconds(3000), _)); Http::ResponseHeaderMapPtr response_headers( @@ -1974,7 +1974,7 @@ TEST_F(RouterTest, UpstreamPerTryTimeout) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::CoreResponseFlag::UpstreamRequestTimeout)); @@ -2024,11 +2024,11 @@ TEST_F(RouterTest, UpstreamPerTryTimeoutDelayedPoolReady) { // Per try timeout starts when onPoolReady is called. expectPerTryTimerCreate(); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); pool_callbacks->onPoolReady(encoder, cm_.thread_local_cluster_.conn_pool_.host_, upstream_stream_info_, Http::Protocol::Http10); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::CoreResponseFlag::UpstreamRequestTimeout)); @@ -2078,12 +2078,12 @@ TEST_F(RouterTest, UpstreamPerTryTimeoutExcludesNewStream) { per_try_timeout_ = new Event::MockTimer(&callbacks_.dispatcher_); EXPECT_CALL(*per_try_timeout_, enableTimer(_, _)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // The per try timeout timer should not be started yet. pool_callbacks->onPoolReady(encoder, cm_.thread_local_cluster_.conn_pool_.host_, upstream_stream_info_, Http::Protocol::Http10); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(encoder.stream_, resetStream(Http::StreamResetReason::LocalReset)); EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_.host_->outlier_detector_, @@ -2140,7 +2140,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutFirstRequestSucceeds) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL( cm_.thread_local_cluster_.conn_pool_.host_->outlier_detector_, @@ -2166,7 +2166,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutFirstRequestSucceeds) { expectPerTryTimerCreate(); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ(2U, router_->upstreamRequests().size()); // We should not have updated any stats yet because no requests have been @@ -2231,7 +2231,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutResetsOnBadHeaders) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL( cm_.thread_local_cluster_.conn_pool_.host_->outlier_detector_, @@ -2256,7 +2256,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutResetsOnBadHeaders) { expectPerTryTimerCreate(); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // We should not have updated any stats yet because no requests have been // canceled @@ -2339,7 +2339,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutThirdRequestSucceeds) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); @@ -2375,7 +2375,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutThirdRequestSucceeds) { expectPerTryTimerCreate(); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -2404,7 +2404,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutThirdRequestSucceeds) { expectPerTryTimerCreate(); router_->retry_state_->callback_(); EXPECT_EQ(3U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Now write a 200 back. We expect the 2nd stream to be reset and stats to be @@ -2615,7 +2615,7 @@ TEST_F(RouterTest, RetryRequestBeforeBody) { EXPECT_CALL(encoder2, encodeHeaders(HeaderHasValueRef("myheader", "present"), false)); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Complete request. Ensure original headers are present. @@ -2669,7 +2669,7 @@ TEST_F(RouterTest, RetryRequestDuringBody) { EXPECT_CALL(encoder2, encodeData(BufferStringEqual(body1), false)); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Complete request. Ensure original headers are present. @@ -2727,7 +2727,7 @@ TEST_F(RouterTest, RetryRequestDuringBodyDataBetweenAttemptsNotEndStream) { EXPECT_CALL(encoder2, encodeData(BufferStringEqual(body1 + body2), false)); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Complete request. Ensure original headers are present. @@ -2801,7 +2801,7 @@ TEST_F(RouterTest, NormalPathUpstreamResetDuringBodyDataTransferNotBuffering) { Buffer::OwnedImpl buf1(body1); router_->decodeData(buf1, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -2847,7 +2847,7 @@ TEST_F(RouterTest, RetryRequestDuringBodyCompleteBetweenAttempts) { EXPECT_CALL(encoder2, encodeData(BufferStringEqual(body1 + body2), true)); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Send successful response, verify success. @@ -2898,7 +2898,7 @@ TEST_F(RouterTest, RetryRequestDuringBodyTrailerBetweenAttempts) { EXPECT_CALL(encoder2, encodeTrailers(HeaderMapEqualRef(&trailers))); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Send successful response, verify success. @@ -2979,7 +2979,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutGlobalTimeout) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL( cm_.thread_local_cluster_.conn_pool_.host_->outlier_detector_, @@ -3005,7 +3005,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutGlobalTimeout) { expectPerTryTimerCreate(); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -3054,7 +3054,7 @@ TEST_F(RouterTest, HedgingRetriesExhaustedBadResponse) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL( cm_.thread_local_cluster_.conn_pool_.host_->outlier_detector_, @@ -3083,7 +3083,7 @@ TEST_F(RouterTest, HedgingRetriesExhaustedBadResponse) { expectPerTryTimerCreate(); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -3142,7 +3142,7 @@ TEST_F(RouterTest, HedgingRetriesProceedAfterReset) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL( cm_.thread_local_cluster_.conn_pool_.host_->outlier_detector_, @@ -3159,7 +3159,7 @@ TEST_F(RouterTest, HedgingRetriesProceedAfterReset) { expectPerTryTimerCreate(); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -3265,7 +3265,7 @@ TEST_F(RouterTest, HedgingRetryImmediatelyReset) { EXPECT_TRUE(verifyHostUpstreamStats(1, 1)); // Pool failure for the first try, so only 1 upstream request was made. EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } TEST_F(RouterTest, RetryNoneHealthy) { @@ -3295,7 +3295,7 @@ TEST_F(RouterTest, RetryNoneHealthy) { EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Pool failure for the first try, so only 1 upstream request was made. EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } TEST_F(RouterTest, RetryUpstreamReset) { @@ -3313,7 +3313,7 @@ TEST_F(RouterTest, RetryUpstreamReset) { Buffer::OwnedImpl body("test body"); router_->decodeData(body, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(*router_->retry_state_, shouldRetryReset(Http::StreamResetReason::RemoteReset, _, _, _)) @@ -3346,7 +3346,7 @@ TEST_F(RouterTest, RetryUpstreamReset) { router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Normal response. @@ -3375,7 +3375,7 @@ TEST_F(RouterTest, RetryHttp3UpstreamReset) { Buffer::OwnedImpl body("test body"); router_->decodeData(body, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(*router_->retry_state_, shouldRetryReset(Http::StreamResetReason::RemoteReset, _, _, _)) .WillOnce(Invoke([this](const Http::StreamResetReason, RetryState::Http3Used http3_used, @@ -3409,7 +3409,7 @@ TEST_F(RouterTest, RetryHttp3UpstreamReset) { router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Normal response. @@ -3439,7 +3439,7 @@ TEST_F(RouterTest, NoRetryWithBodyLimit) { Buffer::OwnedImpl body("t"); router_->decodeData(body, false); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -3473,7 +3473,7 @@ TEST_F(RouterTest, RetryUpstreamPerTryTimeout) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); router_->retry_state_->expectResetRetry(); EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_.host_->outlier_detector_, @@ -3501,7 +3501,7 @@ TEST_F(RouterTest, RetryUpstreamPerTryTimeout) { expectPerTryTimerCreate(); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Normal response. EXPECT_CALL(*router_->retry_state_, shouldRetryHeaders(_, _, _)) @@ -3540,7 +3540,7 @@ TEST_F(RouterTest, RetryUpstreamConnectionFailure) { absl::string_view(), nullptr); // Pool failure, so no upstream request was made. EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseDecoder* response_decoder = nullptr; // We expect this reset to kick off a new request. @@ -3559,7 +3559,7 @@ TEST_F(RouterTest, RetryUpstreamConnectionFailure) { router_->retry_state_->callback_(); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Normal response. EXPECT_CALL(*router_->retry_state_, shouldRetryHeaders(_, _, _)) @@ -3585,7 +3585,7 @@ TEST_F(RouterTest, DontResetStartedResponseOnUpstreamPerTryTimeout) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Since the response is already started we don't retry. EXPECT_CALL(*router_->retry_state_, shouldRetryHeaders(_, _, _)) @@ -3605,7 +3605,7 @@ TEST_F(RouterTest, DontResetStartedResponseOnUpstreamPerTryTimeout) { .counter("upstream_rq_per_try_timeout") .value()); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } TEST_F(RouterTest, RetryUpstreamResetResponseStarted) { @@ -3619,7 +3619,7 @@ TEST_F(RouterTest, RetryUpstreamResetResponseStarted) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Since the response is already started we don't retry. EXPECT_CALL(*router_->retry_state_, shouldRetryHeaders(_, _, _)) @@ -3641,7 +3641,7 @@ TEST_F(RouterTest, RetryUpstreamResetResponseStarted) { // later reset occurs. EXPECT_TRUE(verifyHostUpstreamStats(1, 0)); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } TEST_F(RouterTest, RetryUpstreamReset1xxResponseStarted) { @@ -3655,7 +3655,7 @@ TEST_F(RouterTest, RetryUpstreamReset1xxResponseStarted) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // The 100-continue will result in resetting retry_state_, so when the stream // is reset we won't even check shouldRetryReset() (or shouldRetryHeaders()). @@ -3673,7 +3673,7 @@ TEST_F(RouterTest, RetryUpstreamReset1xxResponseStarted) { putResult(Upstream::Outlier::Result::LocalOriginConnectFailed, _)); encoder1.stream_.resetStream(Http::StreamResetReason::RemoteReset); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } TEST_F(RouterTest, RetryUpstream5xx) { @@ -3687,7 +3687,7 @@ TEST_F(RouterTest, RetryUpstream5xx) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // 5xx response. router_->retry_state_->expectHeadersRetry(); @@ -3705,7 +3705,7 @@ TEST_F(RouterTest, RetryUpstream5xx) { router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Normal response. EXPECT_CALL(*router_->retry_state_, shouldRetryHeaders(_, _, _)) @@ -3731,7 +3731,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelay) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // 5xx response. router_->retry_state_->expectHeadersRetry(); @@ -3869,7 +3869,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHost) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // 5xx response. router_->retry_state_->expectHeadersRetry(); @@ -3905,7 +3905,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHost) { EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Timeout fired so no retry was done. EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } // Retry timeout during a retry delay leading to no upstream host, as well as an alt response code. @@ -3922,7 +3922,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHostAltRespo HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // 5xx response. router_->retry_state_->expectHeadersRetry(); @@ -3956,7 +3956,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHostAltRespo EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // no retry was done. EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } TEST_F(RouterTest, RetryUpstream5xxNotComplete) { @@ -3977,7 +3977,7 @@ TEST_F(RouterTest, RetryUpstream5xxNotComplete) { Http::TestRequestTrailerMapImpl trailers{{"some", "trailer"}}; router_->decodeTrailers(trailers); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // 5xx response. router_->retry_state_->expectHeadersRetry(); @@ -3999,7 +3999,7 @@ TEST_F(RouterTest, RetryUpstream5xxNotComplete) { EXPECT_CALL(encoder2, encodeTrailers(_)); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Normal response. EXPECT_CALL(*router_->retry_state_, shouldRetryHeaders(_, _, _)) @@ -4044,7 +4044,7 @@ TEST_F(RouterTest, RetryUpstreamGrpcCancelled) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // gRPC with status "cancelled" (1) router_->retry_state_->expectHeadersRetry(); @@ -4062,7 +4062,7 @@ TEST_F(RouterTest, RetryUpstreamGrpcCancelled) { router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Normal response. EXPECT_CALL(*router_->retry_state_, shouldRetryHeaders(_, _, _)) @@ -4102,7 +4102,7 @@ TEST_F(RouterTest, RetryRespectsMaxHostSelectionCount) { Http::TestRequestTrailerMapImpl trailers{{"some", "trailer"}}; router_->decodeTrailers(trailers); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // 5xx response. router_->retry_state_->expectHeadersRetry(); @@ -4124,7 +4124,7 @@ TEST_F(RouterTest, RetryRespectsMaxHostSelectionCount) { EXPECT_CALL(encoder2, encodeTrailers(_)); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Now that we're triggered a retry, we should see the configured number of host selections. EXPECT_EQ(3, router_->hostSelectionRetryCount()); @@ -4169,7 +4169,7 @@ TEST_F(RouterTest, RetryRespectsRetryHostPredicate) { Http::TestRequestTrailerMapImpl trailers{{"some", "trailer"}}; router_->decodeTrailers(trailers); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // 5xx response. router_->retry_state_->expectHeadersRetry(); @@ -4191,7 +4191,7 @@ TEST_F(RouterTest, RetryRespectsRetryHostPredicate) { EXPECT_CALL(encoder2, encodeTrailers(_)); router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // Now that we're triggered a retry, we should see the router reject hosts. EXPECT_TRUE(router_->shouldSelectAnotherHost(host)); @@ -4646,7 +4646,7 @@ TEST_P(RouterShadowingTest, BufferingShadowWithClusterHeader) { router_->decodeTrailers(trailers); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -4684,7 +4684,7 @@ TEST_P(RouterShadowingTest, ShadowNoClusterHeaderInHeader) { Http::TestRequestTrailerMapImpl trailers{{"some", "trailer"}}; router_->decodeTrailers(trailers); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -4725,7 +4725,7 @@ TEST_P(RouterShadowingTest, ShadowClusterNameEmptyInHeader) { Http::TestRequestTrailerMapImpl trailers{{"some", "trailer"}}; router_->decodeTrailers(trailers); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -4796,7 +4796,7 @@ TEST_P(RouterShadowingTest, StreamingShadow) { EXPECT_CALL(fizz_request, captureAndSendTrailers_(Http::HeaderValueOf("some", "trailer"))); router_->decodeTrailers(trailers); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -4861,7 +4861,7 @@ TEST_P(RouterShadowingTest, BufferingShadow) { })); router_->decodeTrailers(trailers); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -4948,7 +4948,7 @@ TEST_F(RouterTest, AltStatName) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); @@ -4993,7 +4993,7 @@ TEST_F(RouterTest, Redirect) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_FALSE(callbacks_.stream_info_.attemptCount().has_value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); } @@ -5013,7 +5013,7 @@ TEST_F(RouterTest, RedirectFound) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_FALSE(callbacks_.stream_info_.attemptCount().has_value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); } @@ -5030,7 +5030,7 @@ TEST_F(RouterTest, DirectResponse) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_FALSE(callbacks_.stream_info_.attemptCount().has_value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(1UL, router_->stats().rq_direct_response_.value()); @@ -5051,7 +5051,7 @@ TEST_F(RouterTest, DirectResponseWithBody) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_FALSE(callbacks_.stream_info_.attemptCount().has_value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(1UL, router_->stats().rq_direct_response_.value()); @@ -5071,7 +5071,7 @@ TEST_F(RouterTest, DirectResponseWithLocation) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_FALSE(callbacks_.stream_info_.attemptCount().has_value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(1UL, router_->stats().rq_direct_response_.value()); @@ -5090,7 +5090,7 @@ TEST_F(RouterTest, DirectResponseWithoutLocation) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_FALSE(callbacks_.stream_info_.attemptCount().has_value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(1UL, router_->stats().rq_direct_response_.value()); @@ -5171,7 +5171,7 @@ TEST_F(RouterTest, UpstreamSSLConnection) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -5207,7 +5207,7 @@ TEST_F(RouterTest, UpstreamTimingSingleRequest) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "503"}}); @@ -5264,7 +5264,7 @@ TEST_F(RouterTest, UpstreamTimingRetry) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); test_time_.advanceTimeWait(std::chrono::milliseconds(43)); @@ -5337,7 +5337,7 @@ TEST_F(RouterTest, UpstreamTimingTimeout) { Buffer::OwnedImpl data; router_->decodeData(data, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); test_time_.advanceTimeWait(std::chrono::milliseconds(33)); @@ -5932,7 +5932,7 @@ TEST_F(RouterTest, CanaryStatusTrue) { EXPECT_CALL(callbacks_.stream_info_, setVirtualClusterName(virtual_cluster_name)); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}, @@ -5964,7 +5964,7 @@ TEST_F(RouterTest, CanaryStatusFalse) { EXPECT_CALL(callbacks_.stream_info_, setVirtualClusterName(virtual_cluster_name)); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}, @@ -6011,7 +6011,7 @@ TEST_F(RouterTest, AutoHostRewriteEnabled) { EXPECT_CALL(callbacks_.route_->route_entry_, appendXfh()).WillOnce(Return(true)); router_->decodeHeaders(incoming_headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); router_->onDestroy(); } @@ -6041,7 +6041,7 @@ TEST_F(RouterTest, AutoHostRewriteDisabled) { EXPECT_CALL(callbacks_.route_->route_entry_, autoHostRewrite()).WillOnce(Return(false)); router_->decodeHeaders(incoming_headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); router_->onDestroy(); } @@ -6138,7 +6138,7 @@ TEST_F(RouterTest, ApplicationProtocols) { router_->onDestroy(); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } // Verify that CONNECT payload is not sent upstream until :200 response headers @@ -6367,7 +6367,7 @@ TEST_F(RouterTest, ExpectedUpstreamTimeoutUpdatedDuringRetries) { HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); test_time_.advanceTimeWait(std::chrono::milliseconds(50)); @@ -6399,7 +6399,7 @@ TEST_F(RouterTest, ExpectedUpstreamTimeoutUpdatedDuringRetries) { router_->retry_state_->callback_(); EXPECT_EQ(2U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); // The retry should cause the header to increase to 2. EXPECT_EQ(2, atoi(std::string(headers.getEnvoyAttemptCountValue()).c_str())); @@ -6672,7 +6672,7 @@ TEST_F(RouterTest, OverwriteSchemeWithUpstreamTransportProtocol) { router_->onDestroy(); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } } // namespace Router diff --git a/test/common/router/router_test_base.cc b/test/common/router/router_test_base.cc index 4721d7a01e6d..d8cb0c05c689 100644 --- a/test/common/router/router_test_base.cc +++ b/test/common/router/router_test_base.cc @@ -174,9 +174,9 @@ void RouterTestBase::verifyAttemptCountInRequestBasic(bool set_include_attempt_c router_->onDestroy(); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } void RouterTestBase::verifyAttemptCountInResponseBasic(bool set_include_attempt_count_in_response, @@ -209,7 +209,7 @@ void RouterTestBase::verifyAttemptCountInResponseBasic(bool set_include_attempt_ response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 0)); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); } void RouterTestBase::sendRequest(bool end_stream) { @@ -294,7 +294,7 @@ void RouterTestBase::testAppendCluster(absl::optional clu HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -339,7 +339,7 @@ void RouterTestBase::testAppendUpstreamHost( HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(1U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); Http::ResponseHeaderMapPtr response_headers( new Http::TestResponseHeaderMapImpl{{":status", "200"}}); @@ -387,7 +387,7 @@ void RouterTestBase::testDoNotForward( HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); EXPECT_EQ(0U, - callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value()); + callbacks_.route_->virtual_host_.virtual_cluster_.stats().upstream_rq_total_.value()); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); } diff --git a/test/extensions/filters/http/cors/cors_filter_test.cc b/test/extensions/filters/http/cors/cors_filter_test.cc index aaa3f6924a12..3206df3017c1 100644 --- a/test/extensions/filters/http/cors/cors_filter_test.cc +++ b/test/extensions/filters/http/cors/cors_filter_test.cc @@ -118,8 +118,7 @@ TEST_F(CorsFilterTest, InitializeCorsPoliciesTest) { filter_.setEncoderFilterCallbacks(encoder_callbacks_); EXPECT_CALL(decoder_callbacks_.route_->route_entry_, corsPolicy()).WillOnce(Return(nullptr)); - EXPECT_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_, corsPolicy()) - .WillOnce(Return(nullptr)); + EXPECT_CALL(decoder_callbacks_.route_->virtual_host_, corsPolicy()).WillOnce(Return(nullptr)); ON_CALL(decoder_callbacks_, traversePerFilterConfig(_)) .WillByDefault( @@ -138,8 +137,7 @@ TEST_F(CorsFilterTest, InitializeCorsPoliciesTest) { EXPECT_CALL(decoder_callbacks_.route_->route_entry_, corsPolicy()) .WillOnce(Return(cors_policy_.get())); - EXPECT_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_, corsPolicy()) - .WillOnce(Return(nullptr)); + EXPECT_CALL(decoder_callbacks_.route_->virtual_host_, corsPolicy()).WillOnce(Return(nullptr)); ON_CALL(decoder_callbacks_, traversePerFilterConfig(_)) .WillByDefault( @@ -157,7 +155,7 @@ TEST_F(CorsFilterTest, InitializeCorsPoliciesTest) { filter_.setEncoderFilterCallbacks(encoder_callbacks_); EXPECT_CALL(decoder_callbacks_.route_->route_entry_, corsPolicy()).WillOnce(Return(nullptr)); - EXPECT_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_, corsPolicy()) + EXPECT_CALL(decoder_callbacks_.route_->virtual_host_, corsPolicy()) .WillOnce(Return(cors_policy_.get())); ON_CALL(decoder_callbacks_, traversePerFilterConfig(_)) @@ -721,8 +719,7 @@ TEST_F(CorsFilterTest, NoCorsEntry) { .WillByDefault(Invoke([](std::function) {})); // No cors policy in route entry or virtual host. ON_CALL(decoder_callbacks_.route_->route_entry_, corsPolicy()).WillByDefault(Return(nullptr)); - ON_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_, corsPolicy()) - .WillByDefault(Return(nullptr)); + ON_CALL(decoder_callbacks_.route_->virtual_host_, corsPolicy()).WillByDefault(Return(nullptr)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(false, isCorsRequest()); diff --git a/test/extensions/filters/http/local_ratelimit/filter_test.cc b/test/extensions/filters/http/local_ratelimit/filter_test.cc index 813496391410..4495dcaf7a6a 100644 --- a/test/extensions/filters/http/local_ratelimit/filter_test.cc +++ b/test/extensions/filters/http/local_ratelimit/filter_test.cc @@ -496,10 +496,9 @@ class DescriptorFilterTest : public FilterTest { decoder_callbacks_.route_->route_entry_.rate_limit_policy_.rate_limit_policy_entry_.clear(); decoder_callbacks_.route_->route_entry_.rate_limit_policy_.rate_limit_policy_entry_ .emplace_back(route_rate_limit_); - decoder_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_ - .rate_limit_policy_entry_.clear(); - decoder_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_ - .rate_limit_policy_entry_.emplace_back(vh_rate_limit_); + decoder_callbacks_.route_->virtual_host_.rate_limit_policy_.rate_limit_policy_entry_.clear(); + decoder_callbacks_.route_->virtual_host_.rate_limit_policy_.rate_limit_policy_entry_ + .emplace_back(vh_rate_limit_); } std::vector descriptor_{{{{"foo2", "bar2"}}}}; @@ -783,7 +782,7 @@ TEST_F(DescriptorFilterTest, NoVHRateLimitOption) { EXPECT_CALL(decoder_callbacks_.route_->route_entry_.rate_limit_policy_, empty()) .WillOnce(Return(false)); - EXPECT_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(decoder_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)) .Times(0); auto headers = Http::TestRequestHeaderMapImpl(); @@ -806,7 +805,7 @@ TEST_F(DescriptorFilterTest, OverrideVHRateLimitOptionWithRouteRateLimitSet) { EXPECT_CALL(decoder_callbacks_.route_->route_entry_.rate_limit_policy_, empty()) .WillOnce(Return(false)); - EXPECT_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(decoder_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)) .Times(0); auto headers = Http::TestRequestHeaderMapImpl(); @@ -827,7 +826,7 @@ TEST_F(DescriptorFilterTest, OverrideVHRateLimitOptionWithoutRouteRateLimit) { EXPECT_CALL(decoder_callbacks_.route_->route_entry_.rate_limit_policy_, empty()) .WillOnce(Return(true)); - EXPECT_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(decoder_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(vh_rate_limit_, populateLocalDescriptors(_, _, _, _)) @@ -847,7 +846,7 @@ TEST_F(DescriptorFilterTest, IncludeVHRateLimitOptionWithOnlyVHRateLimitSet) { EXPECT_CALL(decoder_callbacks_.route_->route_entry_, includeVirtualHostRateLimits()) .WillOnce(Return(false)); - EXPECT_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(decoder_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(vh_rate_limit_, populateLocalDescriptors(_, _, _, _)) @@ -870,7 +869,7 @@ TEST_F(DescriptorFilterTest, IncludeVHRateLimitOptionWithRouteAndVHRateLimitSet) EXPECT_CALL(decoder_callbacks_.route_->route_entry_, includeVirtualHostRateLimits()) .WillOnce(Return(false)); - EXPECT_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(decoder_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(vh_rate_limit_, populateLocalDescriptors(_, _, _, _)) @@ -893,7 +892,7 @@ TEST_F(DescriptorFilterTest, IgnoreVHRateLimitOptionWithRouteRateLimitSet) { EXPECT_CALL(decoder_callbacks_.route_->route_entry_, includeVirtualHostRateLimits()) .WillOnce(Return(false)); - EXPECT_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(decoder_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)) .Times(0); @@ -912,7 +911,7 @@ TEST_F(DescriptorFilterTest, IgnoreVHRateLimitOptionWithOutRouteRateLimit) { EXPECT_CALL(decoder_callbacks_.route_->route_entry_, includeVirtualHostRateLimits()) .WillOnce(Return(false)); - EXPECT_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(decoder_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)) .Times(0); @@ -930,7 +929,7 @@ TEST_F(DescriptorFilterTest, IncludeVirtualHostRateLimitsSetTrue) { EXPECT_CALL(decoder_callbacks_.route_->route_entry_, includeVirtualHostRateLimits()) .WillOnce(Return(true)); - EXPECT_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(decoder_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(vh_rate_limit_, populateLocalDescriptors(_, _, _, _)) diff --git a/test/extensions/filters/http/ratelimit/ratelimit_test.cc b/test/extensions/filters/http/ratelimit/ratelimit_test.cc index db63d1b5be2c..8207ba087fab 100644 --- a/test/extensions/filters/http/ratelimit/ratelimit_test.cc +++ b/test/extensions/filters/http/ratelimit/ratelimit_test.cc @@ -62,9 +62,8 @@ class HttpRateLimitFilterTest : public testing::Test { filter_callbacks_.route_->route_entry_.rate_limit_policy_.rate_limit_policy_entry_.clear(); filter_callbacks_.route_->route_entry_.rate_limit_policy_.rate_limit_policy_entry_.emplace_back( route_rate_limit_); - filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_.rate_limit_policy_entry_ - .clear(); - filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_.rate_limit_policy_entry_ + filter_callbacks_.route_->virtual_host_.rate_limit_policy_.rate_limit_policy_entry_.clear(); + filter_callbacks_.route_->virtual_host_.rate_limit_policy_.rate_limit_policy_entry_ .emplace_back(vh_rate_limit_); } @@ -223,7 +222,7 @@ TEST_F(HttpRateLimitFilterTest, OkResponse) { EXPECT_CALL(route_rate_limit_, populateDescriptors(_, _, _, _)) .WillOnce(SetArgReferee<0>(descriptor_)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(*client_, limit(_, "foo", @@ -267,7 +266,7 @@ TEST_F(HttpRateLimitFilterTest, OkResponseWithHeaders) { EXPECT_CALL(route_rate_limit_, populateDescriptors(_, _, _, _)) .WillOnce(SetArgReferee<0>(descriptor_)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(*client_, limit(_, "foo", @@ -323,7 +322,7 @@ TEST_F(HttpRateLimitFilterTest, OkResponseWithFilterHeaders) { EXPECT_CALL(route_rate_limit_, populateDescriptors(_, _, _, _)) .WillOnce(SetArgReferee<0>(descriptor_)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(*client_, limit(_, "foo", @@ -1150,7 +1149,7 @@ TEST_F(HttpRateLimitFilterTest, InternalRequestType) { EXPECT_CALL(route_rate_limit_, populateDescriptors(_, _, _, _)) .WillOnce(SetArgReferee<0>(descriptor_)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(*client_, limit(_, "foo", @@ -1193,7 +1192,7 @@ TEST_F(HttpRateLimitFilterTest, ExternalRequestType) { EXPECT_CALL(route_rate_limit_, populateDescriptors(_, _, _, _)) .WillOnce(SetArgReferee<0>(descriptor_)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(*client_, limit(_, "foo", @@ -1244,8 +1243,7 @@ TEST_F(HttpRateLimitFilterTest, DEPRECATED_FEATURE_TEST(ExcludeVirtualHost)) { EXPECT_CALL(filter_callbacks_.route_->route_entry_.rate_limit_policy_, empty()) .WillOnce(Return(false)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, - getApplicableRateLimit(0)) + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)) .Times(0); EXPECT_CALL(*client_, limit(_, "foo", @@ -1294,8 +1292,7 @@ TEST_F(HttpRateLimitFilterTest, OverrideVHRateLimitOptionWithRouteRateLimitSet) EXPECT_CALL(filter_callbacks_.route_->route_entry_.rate_limit_policy_, empty()) .WillOnce(Return(false)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, - getApplicableRateLimit(0)) + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)) .Times(0); EXPECT_CALL(*client_, limit(_, "foo", @@ -1342,7 +1339,7 @@ TEST_F(HttpRateLimitFilterTest, OverrideVHRateLimitOptionWithoutRouteRateLimit) EXPECT_CALL(filter_callbacks_.route_->route_entry_.rate_limit_policy_, empty()) .WillOnce(Return(true)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(vh_rate_limit_, populateDescriptors(_, _, _, _)) @@ -1389,7 +1386,7 @@ TEST_F(HttpRateLimitFilterTest, IncludeVHRateLimitOptionWithOnlyVHRateLimitSet) .Times(2) .WillRepeatedly(Return(&per_route_config_)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(vh_rate_limit_, populateDescriptors(_, _, _, _)) @@ -1438,7 +1435,7 @@ TEST_F(HttpRateLimitFilterTest, IncludeVHRateLimitOptionWithRouteAndVHRateLimitS .Times(2) .WillRepeatedly(Return(&per_route_config_)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)); EXPECT_CALL(vh_rate_limit_, populateDescriptors(_, _, _, _)) @@ -1487,8 +1484,7 @@ TEST_F(HttpRateLimitFilterTest, IgnoreVHRateLimitOptionWithRouteRateLimitSet) { .Times(2) .WillRepeatedly(Return(&per_route_config_)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, - getApplicableRateLimit(0)) + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)) .Times(0); EXPECT_CALL(*client_, limit(_, "foo", @@ -1531,8 +1527,7 @@ TEST_F(HttpRateLimitFilterTest, IgnoreVHRateLimitOptionWithOutRouteRateLimit) { EXPECT_CALL(*filter_callbacks_.route_, mostSpecificPerFilterConfig(_)) .WillOnce(Return(&per_route_config_)); - EXPECT_CALL(filter_callbacks_.route_->route_entry_.virtual_host_.rate_limit_policy_, - getApplicableRateLimit(0)) + EXPECT_CALL(filter_callbacks_.route_->virtual_host_.rate_limit_policy_, getApplicableRateLimit(0)) .Times(0); EXPECT_CALL(filter_callbacks_, continueDecoding()).Times(0); diff --git a/test/extensions/formatter/metadata/metadata_test.cc b/test/extensions/formatter/metadata/metadata_test.cc index 1929ec1b1096..acb03df66151 100644 --- a/test/extensions/formatter/metadata/metadata_test.cc +++ b/test/extensions/formatter/metadata/metadata_test.cc @@ -151,11 +151,8 @@ TEST_F(MetadataFormatterTest, VirtualHostMetadata) { std::shared_ptr route{new NiceMock()}; EXPECT_CALL(stream_info_, route()).WillRepeatedly(testing::Return(route)); - std::shared_ptr route_entry{new NiceMock()}; - EXPECT_CALL(*route, routeEntry()).WillRepeatedly(testing::Return(route_entry.get())); - std::shared_ptr virtual_host{new NiceMock()}; - EXPECT_CALL(*route_entry, virtualHost()).WillRepeatedly(testing::ReturnRef(*virtual_host)); + EXPECT_CALL(*route, virtualHost()).WillRepeatedly(testing::ReturnRef(*virtual_host)); EXPECT_CALL(*virtual_host, metadata()).WillRepeatedly(testing::ReturnRef(*metadata_)); EXPECT_EQ("test_value", getTestMetadataFormatter("VIRTUAL_HOST") diff --git a/test/mocks/router/mocks.cc b/test/mocks/router/mocks.cc index 8ebe043e0405..c321bfe1574f 100644 --- a/test/mocks/router/mocks.cc +++ b/test/mocks/router/mocks.cc @@ -76,6 +76,7 @@ MockVirtualHost::MockVirtualHost() { ON_CALL(*this, rateLimitPolicy()).WillByDefault(ReturnRef(rate_limit_policy_)); ON_CALL(*this, metadata()).WillByDefault(ReturnRef(metadata_)); ON_CALL(*this, typedMetadata()).WillByDefault(ReturnRef(typed_metadata_)); + ON_CALL(*this, virtualCluster(_)).WillByDefault(Return(&virtual_cluster_)); } MockVirtualHost::~MockVirtualHost() = default; @@ -106,8 +107,6 @@ MockRouteEntry::MockRouteEntry() { .WillByDefault(Return(std::numeric_limits::max())); ON_CALL(*this, shadowPolicies()).WillByDefault(ReturnRef(shadow_policies_)); ON_CALL(*this, timeout()).WillByDefault(Return(std::chrono::milliseconds(10))); - ON_CALL(*this, virtualCluster(_)).WillByDefault(Return(&virtual_cluster_)); - ON_CALL(*this, virtualHost()).WillByDefault(ReturnRef(virtual_host_)); ON_CALL(*this, includeVirtualHostRateLimits()).WillByDefault(Return(true)); ON_CALL(*this, pathMatchCriterion()).WillByDefault(ReturnRef(path_match_criterion_)); ON_CALL(*this, upgradeMap()).WillByDefault(ReturnRef(upgrade_map_)); @@ -153,6 +152,7 @@ MockRoute::MockRoute() { ON_CALL(*this, metadata()).WillByDefault(ReturnRef(metadata_)); ON_CALL(*this, typedMetadata()).WillByDefault(ReturnRef(typed_metadata_)); ON_CALL(*this, routeName()).WillByDefault(ReturnRef(route_name_)); + ON_CALL(*this, virtualHost()).WillByDefault(ReturnRef(virtual_host_)); } MockRoute::~MockRoute() = default; diff --git a/test/mocks/router/mocks.h b/test/mocks/router/mocks.h index 026c274e9b85..ca84f36654f4 100644 --- a/test/mocks/router/mocks.h +++ b/test/mocks/router/mocks.h @@ -332,6 +332,7 @@ class MockVirtualHost : public VirtualHost { (const)); MOCK_METHOD(const envoy::config::core::v3::Metadata&, metadata, (), (const)); MOCK_METHOD(const Envoy::Config::TypedMetadata&, typedMetadata, (), (const)); + MOCK_METHOD(const VirtualCluster*, virtualCluster, (const Http::HeaderMap& headers), (const)); Stats::StatName statName() const override { stat_name_ = std::make_unique(name(), *symbol_table_); @@ -345,6 +346,7 @@ class MockVirtualHost : public VirtualHost { TestCorsPolicy cors_policy_; envoy::config::core::v3::Metadata metadata_; MockRouteMetadata typed_metadata_; + TestVirtualCluster virtual_cluster_; }; class MockHashPolicy : public Http::HashPolicy { @@ -442,8 +444,6 @@ class MockRouteEntry : public RouteEntry { MOCK_METHOD(absl::optional, grpcTimeoutHeaderOffset, (), (const)); MOCK_METHOD(absl::optional, maxGrpcTimeout, (), (const)); MOCK_METHOD(absl::optional, grpcTimeoutOffset, (), (const)); - MOCK_METHOD(const VirtualCluster*, virtualCluster, (const Http::HeaderMap& headers), (const)); - MOCK_METHOD(const VirtualHost&, virtualHost, (), (const)); MOCK_METHOD(bool, autoHostRewrite, (), (const)); MOCK_METHOD(bool, appendXfh, (), (const)); MOCK_METHOD((const std::multimap&), opaqueConfig, (), (const)); @@ -461,7 +461,6 @@ class MockRouteEntry : public RouteEntry { std::string cluster_name_{"fake_cluster"}; std::multimap opaque_config_; - TestVirtualCluster virtual_cluster_; TestRetryPolicy retry_policy_; testing::NiceMock internal_redirect_policy_; PathMatcherSharedPtr path_matcher_; @@ -469,7 +468,6 @@ class MockRouteEntry : public RouteEntry { TestHedgePolicy hedge_policy_; testing::NiceMock rate_limit_policy_; std::vector shadow_policies_; - testing::NiceMock virtual_host_; MockHashPolicy hash_policy_; MockMetadataMatchCriteria metadata_matches_criteria_; MockTlsContextMatchCriteria tls_context_matches_criteria_; @@ -525,6 +523,7 @@ class MockRoute : public Route { MOCK_METHOD(const envoy::config::core::v3::Metadata&, metadata, (), (const)); MOCK_METHOD(const Envoy::Config::TypedMetadata&, typedMetadata, (), (const)); MOCK_METHOD(const std::string&, routeName, (), (const)); + MOCK_METHOD(const VirtualHost&, virtualHost, (), (const)); testing::NiceMock route_entry_; testing::NiceMock decorator_; @@ -532,6 +531,7 @@ class MockRoute : public Route { envoy::config::core::v3::Metadata metadata_; MockRouteMetadata typed_metadata_; std::string route_name_{"fake_route_name"}; + testing::NiceMock virtual_host_; }; class MockConfig : public Config { diff --git a/test/tools/router_check/router.cc b/test/tools/router_check/router.cc index 410caf6cc021..837bdd1eb956 100644 --- a/test/tools/router_check/router.cc +++ b/test/tools/router_check/router.cc @@ -332,11 +332,11 @@ bool RouterCheckTool::compareVirtualCluster( tool_config.route_ != nullptr && tool_config.route_->routeEntry() != nullptr; const bool has_virtual_cluster = has_route_entry && - tool_config.route_->routeEntry()->virtualCluster(*tool_config.request_headers_) != nullptr; + tool_config.route_->virtualHost().virtualCluster(*tool_config.request_headers_) != nullptr; std::string actual = ""; if (has_virtual_cluster) { Stats::StatName stat_name = - tool_config.route_->routeEntry()->virtualCluster(*tool_config.request_headers_)->statName(); + tool_config.route_->virtualHost().virtualCluster(*tool_config.request_headers_)->statName(); actual = tool_config.symbolTable().toString(stat_name); } const bool matches = @@ -362,7 +362,7 @@ bool RouterCheckTool::compareVirtualHost( tool_config.route_ != nullptr && tool_config.route_->routeEntry() != nullptr; std::string actual = ""; if (has_route_entry) { - Stats::StatName stat_name = tool_config.route_->routeEntry()->virtualHost().statName(); + Stats::StatName stat_name = tool_config.route_->virtualHost().statName(); actual = tool_config.symbolTable().toString(stat_name); } const bool matches = From 6fb1903cd2eef4876cb9d333792d3778948ba455 Mon Sep 17 00:00:00 2001 From: Christoph Pakulski Date: Tue, 23 Jul 2024 02:29:01 -0400 Subject: [PATCH 05/26] Lua: add option to put backpressure when script executes httpCall (#35104) Commit Message: add option to put backpressure when Lua script executes httpCall Additional Description: PR addresses a situation when upon receiving request headers, Lua script issues httpCall and backpressure should be put on the downstream client to slow down sending body, which size may exceed maximum allowed buffer size per connection. Risk Level: Low (default setting preserves previous behaviour) Testing: Added unit test Docs Changes: updated API annotation Release Notes: yes Platform Specific Features: No Fixes #10076 --------- Signed-off-by: Christoph Pakulski --- changelogs/current.yaml | 4 + source/common/runtime/runtime_features.cc | 1 + .../extensions/filters/http/lua/lua_filter.cc | 7 +- .../filters/http/lua/lua_filter_test.cc | 382 ++++++++++-------- 4 files changed, 217 insertions(+), 177 deletions(-) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 859372e2dad7..dd6474cf1ddf 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -5,6 +5,10 @@ behavior_changes: minor_behavior_changes: # *Changes that may cause incompatibilities for some users, but should not for most* +- area: lua + change: | + When Lua script executes httpCall, backpressure is exercised when receiving body from downstream client. This behavior can be reverted + by setting the runtime guard ``envoy.reloadable_features.lua_flow_control_while_http_call`` to false. bug_fixes: # *Changes expected to improve the state of the world and are unlikely to have negative effects* diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index 545e3a188929..89024047da29 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -68,6 +68,7 @@ RUNTIME_GUARD(envoy_reloadable_features_http_route_connect_proxy_by_default); RUNTIME_GUARD(envoy_reloadable_features_immediate_response_use_filter_mutation_rule); RUNTIME_GUARD(envoy_reloadable_features_jwt_authn_remove_jwt_from_query_params); RUNTIME_GUARD(envoy_reloadable_features_jwt_authn_validate_uri); +RUNTIME_GUARD(envoy_reloadable_features_lua_flow_control_while_http_call); RUNTIME_GUARD(envoy_reloadable_features_no_downgrade_to_canonical_name); RUNTIME_GUARD(envoy_reloadable_features_no_extension_lookup_by_name); RUNTIME_GUARD(envoy_reloadable_features_no_timer_based_rate_limit_token_bucket); diff --git a/source/extensions/filters/http/lua/lua_filter.cc b/source/extensions/filters/http/lua/lua_filter.cc index 298c0d56a9db..a39e3f6de7d1 100644 --- a/source/extensions/filters/http/lua/lua_filter.cc +++ b/source/extensions/filters/http/lua/lua_filter.cc @@ -278,7 +278,12 @@ Http::FilterDataStatus StreamHandleWrapper::onData(Buffer::Instance& data, bool resumeCoroutine(0, yield_callback_); } - if (state_ == State::HttpCall || state_ == State::WaitForBody) { + if (state_ == State::HttpCall) { + return (Runtime::runtimeFeatureEnabled( + "envoy.reloadable_features.lua_flow_control_while_http_call")) + ? Http::FilterDataStatus::StopIterationAndWatermark + : Http::FilterDataStatus::StopIterationAndBuffer; + } else if (state_ == State::WaitForBody) { ENVOY_LOG(trace, "buffering body"); return Http::FilterDataStatus::StopIterationAndBuffer; } else if (state_ == State::Responded) { diff --git a/test/extensions/filters/http/lua/lua_filter_test.cc b/test/extensions/filters/http/lua/lua_filter_test.cc index 706c4d334714..ab59e37483c1 100644 --- a/test/extensions/filters/http/lua/lua_filter_test.cc +++ b/test/extensions/filters/http/lua/lua_filter_test.cc @@ -846,56 +846,62 @@ TEST_F(LuaHttpFilterTest, HttpCall) { end )EOF"}; - InSequence s; - setup(SCRIPT); + for (const bool flow_control : std::vector({false, true})) { + Runtime::maybeSetRuntimeGuard("envoy.reloadable_features.lua_flow_control_while_http_call", + flow_control); + InSequence s; + setup(SCRIPT); - Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; - Http::MockAsyncClientRequest request(&cluster_manager_.thread_local_cluster_.async_client_); - Http::AsyncClient::Callbacks* callbacks; - EXPECT_CALL(cluster_manager_, getThreadLocalCluster(Eq("cluster"))); - EXPECT_CALL(cluster_manager_.thread_local_cluster_, httpAsyncClient()); - EXPECT_CALL(cluster_manager_.thread_local_cluster_.async_client_, send_(_, _, _)) - .WillOnce(Invoke( - [&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, - const Http::AsyncClient::RequestOptions& options) -> Http::AsyncClient::Request* { - const Http::TestRequestHeaderMapImpl expected_headers{ - {":method", "POST"}, - {":path", "/"}, - {":authority", "foo"}, - - {"set-cookie", "flavor=chocolate; Path=/"}, - {"set-cookie", "variant=chewy; Path=/"}, - {"content-length", "11"}}; - EXPECT_THAT(&message->headers(), HeaderMapEqualIgnoreOrder(&expected_headers)); - // The parent span always be set for lua http call. - EXPECT_NE(options.parent_span_, nullptr); - - callbacks = &cb; - return &request; - })); - - EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, - filter_->decodeHeaders(request_headers, false)); - - Buffer::OwnedImpl data("hello"); - EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data, false)); + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; + Http::MockAsyncClientRequest request(&cluster_manager_.thread_local_cluster_.async_client_); + Http::AsyncClient::Callbacks* callbacks; + EXPECT_CALL(cluster_manager_, getThreadLocalCluster(Eq("cluster"))); + EXPECT_CALL(cluster_manager_.thread_local_cluster_, httpAsyncClient()); + EXPECT_CALL(cluster_manager_.thread_local_cluster_.async_client_, send_(_, _, _)) + .WillOnce(Invoke( + [&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, + const Http::AsyncClient::RequestOptions& options) -> Http::AsyncClient::Request* { + const Http::TestRequestHeaderMapImpl expected_headers{ + {":method", "POST"}, + {":path", "/"}, + {":authority", "foo"}, + + {"set-cookie", "flavor=chocolate; Path=/"}, + {"set-cookie", "variant=chewy; Path=/"}, + {"content-length", "11"}}; + EXPECT_THAT(&message->headers(), HeaderMapEqualIgnoreOrder(&expected_headers)); + // The parent span always be set for lua http call. + EXPECT_NE(options.parent_span_, nullptr); + + callbacks = &cb; + return &request; + })); - Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); + EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, + filter_->decodeHeaders(request_headers, false)); - Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( - Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); - const char response[8] = {'r', 'e', 's', 'p', '\0', 'n', 's', 'e'}; - response_message->body().add(response, 8); - EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq(":status 200"))); - EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("8"))); - EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq(std::string("resp\0nse", 8)))); - EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("0"))); - EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("nse"))); - EXPECT_CALL(decoder_callbacks_, continueDecoding()); - callbacks->onBeforeFinalizeUpstreamSpan(child_span_, &response_message->headers()); - callbacks->onSuccess(request, std::move(response_message)); - EXPECT_EQ(0, stats_store_.counter("test.lua.errors").value()); + Buffer::OwnedImpl data("hello"); + EXPECT_EQ(flow_control ? Http::FilterDataStatus::StopIterationAndWatermark + : Http::FilterDataStatus::StopIterationAndBuffer, + filter_->decodeData(data, false)); + + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); + + Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); + const char response[8] = {'r', 'e', 's', 'p', '\0', 'n', 's', 'e'}; + response_message->body().add(response, 8); + EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq(":status 200"))); + EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("8"))); + EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq(std::string("resp\0nse", 8)))); + EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("0"))); + EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("nse"))); + EXPECT_CALL(decoder_callbacks_, continueDecoding()); + callbacks->onBeforeFinalizeUpstreamSpan(child_span_, &response_message->headers()); + callbacks->onSuccess(request, std::move(response_message)); + EXPECT_EQ(0, stats_store_.counter("test.lua.errors").value()); + } } // HTTP request flow with multiple header values for same header name. @@ -923,41 +929,47 @@ TEST_F(LuaHttpFilterTest, HttpCallWithRepeatedHeaders) { end )EOF"}; - InSequence s; - setup(SCRIPT); + for (const bool flow_control : std::vector({false, true})) { + Runtime::maybeSetRuntimeGuard("envoy.reloadable_features.lua_flow_control_while_http_call", + flow_control); + InSequence s; + setup(SCRIPT); - Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; - Http::MockAsyncClientRequest request(&cluster_manager_.thread_local_cluster_.async_client_); - Http::AsyncClient::Callbacks* callbacks; - EXPECT_CALL(cluster_manager_, getThreadLocalCluster(Eq("cluster"))); - EXPECT_CALL(cluster_manager_.thread_local_cluster_, httpAsyncClient()); - EXPECT_CALL(cluster_manager_.thread_local_cluster_.async_client_, send_(_, _, _)) - .WillOnce( - Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& cb, - const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - callbacks = &cb; - return &request; - })); + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; + Http::MockAsyncClientRequest request(&cluster_manager_.thread_local_cluster_.async_client_); + Http::AsyncClient::Callbacks* callbacks; + EXPECT_CALL(cluster_manager_, getThreadLocalCluster(Eq("cluster"))); + EXPECT_CALL(cluster_manager_.thread_local_cluster_, httpAsyncClient()); + EXPECT_CALL(cluster_manager_.thread_local_cluster_.async_client_, send_(_, _, _)) + .WillOnce( + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& cb, + const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { + callbacks = &cb; + return &request; + })); - EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, - filter_->decodeHeaders(request_headers, false)); + EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, + filter_->decodeHeaders(request_headers, false)); - Buffer::OwnedImpl data("hello"); - EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data, false)); + Buffer::OwnedImpl data("hello"); + EXPECT_EQ(flow_control ? Http::FilterDataStatus::StopIterationAndWatermark + : Http::FilterDataStatus::StopIterationAndBuffer, + filter_->decodeData(data, false)); - Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); - Http::ResponseMessagePtr response_message( - new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ - new Http::TestResponseHeaderMapImpl{{"key", "value"}, {"key", "second_value"}}})); + Http::ResponseMessagePtr response_message( + new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{"key", "value"}, {"key", "second_value"}}})); - EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("key value,second_value"))); + EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("key value,second_value"))); - EXPECT_CALL(decoder_callbacks_, continueDecoding()); - callbacks->onBeforeFinalizeUpstreamSpan(child_span_, &response_message->headers()); - callbacks->onSuccess(request, std::move(response_message)); - EXPECT_EQ(0, stats_store_.counter("test.lua.errors").value()); + EXPECT_CALL(decoder_callbacks_, continueDecoding()); + callbacks->onBeforeFinalizeUpstreamSpan(child_span_, &response_message->headers()); + callbacks->onSuccess(request, std::move(response_message)); + EXPECT_EQ(0, stats_store_.counter("test.lua.errors").value()); + } } // Basic HTTP request flow. Asynchronous flag set to false. @@ -982,47 +994,53 @@ TEST_F(LuaHttpFilterTest, HttpCallAsyncFalse) { end )EOF"}; - InSequence s; - setup(SCRIPT); - - Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; - Http::MockAsyncClientRequest request(&cluster_manager_.thread_local_cluster_.async_client_); - Http::AsyncClient::Callbacks* callbacks; - EXPECT_CALL(cluster_manager_, getThreadLocalCluster(Eq("cluster"))); - EXPECT_CALL(cluster_manager_.thread_local_cluster_, httpAsyncClient()); - EXPECT_CALL(cluster_manager_.thread_local_cluster_.async_client_, send_(_, _, _)) - .WillOnce( - Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, - const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - const Http::TestRequestHeaderMapImpl expected_headers{ - {":path", "/"}, - {":method", "POST"}, - {":authority", "foo"}, - {"set-cookie", "flavor=chocolate; Path=/"}, - {"set-cookie", "variant=chewy; Path=/"}, - {"content-length", "11"}}; - EXPECT_THAT(&message->headers(), HeaderMapEqualIgnoreOrder(&expected_headers)); - callbacks = &cb; - return &request; - })); - - EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, - filter_->decodeHeaders(request_headers, false)); + for (const bool flow_control : std::vector({false, true})) { + Runtime::maybeSetRuntimeGuard("envoy.reloadable_features.lua_flow_control_while_http_call", + flow_control); + InSequence s; + setup(SCRIPT); - Buffer::OwnedImpl data("hello"); - EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data, false)); + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; + Http::MockAsyncClientRequest request(&cluster_manager_.thread_local_cluster_.async_client_); + Http::AsyncClient::Callbacks* callbacks; + EXPECT_CALL(cluster_manager_, getThreadLocalCluster(Eq("cluster"))); + EXPECT_CALL(cluster_manager_.thread_local_cluster_, httpAsyncClient()); + EXPECT_CALL(cluster_manager_.thread_local_cluster_.async_client_, send_(_, _, _)) + .WillOnce( + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, + const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { + const Http::TestRequestHeaderMapImpl expected_headers{ + {":path", "/"}, + {":method", "POST"}, + {":authority", "foo"}, + {"set-cookie", "flavor=chocolate; Path=/"}, + {"set-cookie", "variant=chewy; Path=/"}, + {"content-length", "11"}}; + EXPECT_THAT(&message->headers(), HeaderMapEqualIgnoreOrder(&expected_headers)); + callbacks = &cb; + return &request; + })); - Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); + EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, + filter_->decodeHeaders(request_headers, false)); - Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( - Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); - response_message->body().add("response"); - EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq(":status 200"))); - EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("response"))); - EXPECT_CALL(decoder_callbacks_, continueDecoding()); - callbacks->onSuccess(request, std::move(response_message)); - EXPECT_EQ(0, stats_store_.counter("test.lua.errors").value()); + Buffer::OwnedImpl data("hello"); + EXPECT_EQ(flow_control ? Http::FilterDataStatus::StopIterationAndWatermark + : Http::FilterDataStatus::StopIterationAndBuffer, + filter_->decodeData(data, false)); + + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); + + Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); + response_message->body().add("response"); + EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq(":status 200"))); + EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("response"))); + EXPECT_CALL(decoder_callbacks_, continueDecoding()); + callbacks->onSuccess(request, std::move(response_message)); + EXPECT_EQ(0, stats_store_.counter("test.lua.errors").value()); + } } // Basic asynchronous, fire-and-forget HTTP request flow. @@ -1248,43 +1266,49 @@ TEST_F(LuaHttpFilterTest, HttpCallNoBody) { end )EOF"}; - InSequence s; - setup(SCRIPT); - - Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; - Http::MockAsyncClientRequest request(&cluster_manager_.thread_local_cluster_.async_client_); - Http::AsyncClient::Callbacks* callbacks; - EXPECT_CALL(cluster_manager_, getThreadLocalCluster(Eq("cluster"))); - EXPECT_CALL(cluster_manager_.thread_local_cluster_, httpAsyncClient()); - EXPECT_CALL(cluster_manager_.thread_local_cluster_.async_client_, send_(_, _, _)) - .WillOnce(Invoke( - [&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, - const Http::AsyncClient::RequestOptions& options) -> Http::AsyncClient::Request* { - // We are actively deferring to the parent span's sampled state. - EXPECT_FALSE(options.sampled_.has_value()); - const Http::TestRequestHeaderMapImpl expected_headers{ - {":path", "/"}, {":method", "GET"}, {":authority", "foo"}}; - EXPECT_THAT(&message->headers(), HeaderMapEqualIgnoreOrder(&expected_headers)); - callbacks = &cb; - return &request; - })); - - EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, - filter_->decodeHeaders(request_headers, false)); + for (const bool flow_control : std::vector({false, true})) { + Runtime::maybeSetRuntimeGuard("envoy.reloadable_features.lua_flow_control_while_http_call", + flow_control); + InSequence s; + setup(SCRIPT); - Buffer::OwnedImpl data("hello"); - EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data, false)); + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; + Http::MockAsyncClientRequest request(&cluster_manager_.thread_local_cluster_.async_client_); + Http::AsyncClient::Callbacks* callbacks; + EXPECT_CALL(cluster_manager_, getThreadLocalCluster(Eq("cluster"))); + EXPECT_CALL(cluster_manager_.thread_local_cluster_, httpAsyncClient()); + EXPECT_CALL(cluster_manager_.thread_local_cluster_.async_client_, send_(_, _, _)) + .WillOnce(Invoke( + [&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, + const Http::AsyncClient::RequestOptions& options) -> Http::AsyncClient::Request* { + // We are actively deferring to the parent span's sampled state. + EXPECT_FALSE(options.sampled_.has_value()); + const Http::TestRequestHeaderMapImpl expected_headers{ + {":path", "/"}, {":method", "GET"}, {":authority", "foo"}}; + EXPECT_THAT(&message->headers(), HeaderMapEqualIgnoreOrder(&expected_headers)); + callbacks = &cb; + return &request; + })); - Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); + EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, + filter_->decodeHeaders(request_headers, false)); - Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( - Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); - EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq(":status 200"))); - EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("no body"))); - EXPECT_CALL(decoder_callbacks_, continueDecoding()); - callbacks->onSuccess(request, std::move(response_message)); - EXPECT_EQ(0, stats_store_.counter("test.lua.errors").value()); + Buffer::OwnedImpl data("hello"); + EXPECT_EQ(flow_control ? Http::FilterDataStatus::StopIterationAndWatermark + : Http::FilterDataStatus::StopIterationAndBuffer, + filter_->decodeData(data, false)); + + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); + + Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); + EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq(":status 200"))); + EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("no body"))); + EXPECT_CALL(decoder_callbacks_, continueDecoding()); + callbacks->onSuccess(request, std::move(response_message)); + EXPECT_EQ(0, stats_store_.counter("test.lua.errors").value()); + } } // HTTP call followed by immediate response. @@ -1594,40 +1618,46 @@ TEST_F(LuaHttpFilterTest, HttpCallWithTimeoutAndSampledInOptions) { end )EOF"}; - InSequence s; - setup(SCRIPT); + for (const bool flow_control : std::vector({false, true})) { + Runtime::maybeSetRuntimeGuard("envoy.reloadable_features.lua_flow_control_while_http_call", + flow_control); + InSequence s; + setup(SCRIPT); - Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; - Http::MockAsyncClientRequest request(&cluster_manager_.thread_local_cluster_.async_client_); - Http::AsyncClient::Callbacks* callbacks; - EXPECT_CALL(cluster_manager_, getThreadLocalCluster(Eq("cluster"))); - EXPECT_CALL(cluster_manager_.thread_local_cluster_, httpAsyncClient()); - EXPECT_CALL(cluster_manager_.thread_local_cluster_.async_client_, send_(_, _, _)) - .WillOnce(Invoke( - [&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& cb, - const Http::AsyncClient::RequestOptions& options) -> Http::AsyncClient::Request* { - EXPECT_EQ(options.timeout->count(), 5000); - EXPECT_EQ(options.sampled_.value(), false); - EXPECT_EQ(options.send_xff, false); - callbacks = &cb; - return &request; - })); + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; + Http::MockAsyncClientRequest request(&cluster_manager_.thread_local_cluster_.async_client_); + Http::AsyncClient::Callbacks* callbacks; + EXPECT_CALL(cluster_manager_, getThreadLocalCluster(Eq("cluster"))); + EXPECT_CALL(cluster_manager_.thread_local_cluster_, httpAsyncClient()); + EXPECT_CALL(cluster_manager_.thread_local_cluster_.async_client_, send_(_, _, _)) + .WillOnce(Invoke( + [&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& cb, + const Http::AsyncClient::RequestOptions& options) -> Http::AsyncClient::Request* { + EXPECT_EQ(options.timeout->count(), 5000); + EXPECT_EQ(options.sampled_.value(), false); + EXPECT_EQ(options.send_xff, false); + callbacks = &cb; + return &request; + })); - EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, - filter_->decodeHeaders(request_headers, false)); + EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, + filter_->decodeHeaders(request_headers, false)); - Buffer::OwnedImpl data("hello"); - EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data, false)); + Buffer::OwnedImpl data("hello"); + EXPECT_EQ(flow_control ? Http::FilterDataStatus::StopIterationAndWatermark + : Http::FilterDataStatus::StopIterationAndBuffer, + filter_->decodeData(data, false)); - Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); - Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( - Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); - EXPECT_CALL(decoder_callbacks_, continueDecoding()); - callbacks->onBeforeFinalizeUpstreamSpan(child_span_, &response_message->headers()); - callbacks->onSuccess(request, std::move(response_message)); - EXPECT_EQ(0, stats_store_.counter("test.lua.errors").value()); + Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); + EXPECT_CALL(decoder_callbacks_, continueDecoding()); + callbacks->onBeforeFinalizeUpstreamSpan(child_span_, &response_message->headers()); + callbacks->onSuccess(request, std::move(response_message)); + EXPECT_EQ(0, stats_store_.counter("test.lua.errors").value()); + } } // HTTP request flow with timeout and invalid flag in options. From 7fd5a40a5860af5fa96e5ee31cc84cfa3928a8d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:06:54 +0100 Subject: [PATCH 06/26] build(deps): bump debian from `f528891` to `5f7d566` in /examples/shared/golang (#35355) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/shared/golang/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/shared/golang/Dockerfile b/examples/shared/golang/Dockerfile index 245d815e17e7..f38b74470b4c 100644 --- a/examples/shared/golang/Dockerfile +++ b/examples/shared/golang/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim@sha256:f528891ab1aa484bf7233dbcc84f3c806c3e427571d75510a9d74bb5ec535b33 AS os-base +FROM debian:bookworm-slim@sha256:5f7d5664eae4a192c2d2d6cb67fc3f3c7891a8722cd2903cc35aa649a12b0c8d AS os-base RUN rm -f /etc/apt/apt.conf.d/docker-clean \ && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' | tee /etc/apt/apt.conf.d/keep-cache From a4677e4130ba5a8efe031ef73bbdb234f28a93e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:07:14 +0100 Subject: [PATCH 07/26] build(deps): bump alpine from `b89d9c9` to `0a4eaa0` in /examples/opentelemetry (#35353) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/opentelemetry/Dockerfile-opentelemetry | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/opentelemetry/Dockerfile-opentelemetry b/examples/opentelemetry/Dockerfile-opentelemetry index 7e8ead8619bf..432b0f151160 100644 --- a/examples/opentelemetry/Dockerfile-opentelemetry +++ b/examples/opentelemetry/Dockerfile-opentelemetry @@ -1,4 +1,4 @@ -FROM alpine:3.20@sha256:b89d9c93e9ed3597455c90a0b88a8bbb5cb7188438f70953fede212a0c4394e0 AS otelc_curl +FROM alpine:3.20@sha256:0a4eaa0eecf5f8c050e5bba433f58c052be7587ee8af3e8b3910ef9ab5fbe9f5 AS otelc_curl RUN apk --update add curl FROM otel/opentelemetry-collector:latest@sha256:56b275978745d866d4e8bcb15de9e51ef259b61210b87c387bfd336a30a69acb From dd8c7275d526984b614470784aaebfb9b91a397c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:07:31 +0100 Subject: [PATCH 08/26] build(deps): bump debian from `f528891` to `5f7d566` in /examples/shared/websocket (#35350) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/shared/websocket/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/shared/websocket/Dockerfile b/examples/shared/websocket/Dockerfile index 0397e74b9a24..4f714ce9fcb7 100644 --- a/examples/shared/websocket/Dockerfile +++ b/examples/shared/websocket/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim@sha256:f528891ab1aa484bf7233dbcc84f3c806c3e427571d75510a9d74bb5ec535b33 AS websocket-base +FROM debian:bookworm-slim@sha256:5f7d5664eae4a192c2d2d6cb67fc3f3c7891a8722cd2903cc35aa649a12b0c8d AS websocket-base ENV DEBIAN_FRONTEND=noninteractive RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \ From a10abf48d00bd7d6e71c5cb7f426e764d6c0c403 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:07:43 +0100 Subject: [PATCH 09/26] build(deps): bump the examples-kafka group in /examples/kafka with 2 updates (#35349) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/kafka/Dockerfile-kafka | 2 +- examples/kafka/Dockerfile-zookeeper | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/kafka/Dockerfile-kafka b/examples/kafka/Dockerfile-kafka index 66dfa7c92c0f..08e3c37aab9e 100644 --- a/examples/kafka/Dockerfile-kafka +++ b/examples/kafka/Dockerfile-kafka @@ -1 +1 @@ -FROM confluentinc/cp-kafka:latest@sha256:29c57d630410981edb82a09806b2a7fbbcda51029e6e89283a843e64e68b29c1 +FROM confluentinc/cp-kafka:latest@sha256:161aa5a125ebf49a88732bb3f2d37aa7605d4b758434503b1472c445f3132dc9 diff --git a/examples/kafka/Dockerfile-zookeeper b/examples/kafka/Dockerfile-zookeeper index 31b23f309e9d..85eab02adeca 100644 --- a/examples/kafka/Dockerfile-zookeeper +++ b/examples/kafka/Dockerfile-zookeeper @@ -1 +1 @@ -FROM confluentinc/cp-zookeeper:latest@sha256:62208941a36aba05a1c3f8cd9ca10f6c26ab14e6d3a7ed3d70a453501973fad3 +FROM confluentinc/cp-zookeeper:latest@sha256:f89d332ecee856fe0bf2f1f8d936cb2603c3339d6417a97743d9fdac310f6656 From 64b2ec3ad643fe47858052d2cafc3ed03560d5ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:07:58 +0100 Subject: [PATCH 10/26] build(deps-dev): bump typescript from 5.5.3 to 5.5.4 in /examples/single-page-app/ui (#35352) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/single-page-app/ui/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/single-page-app/ui/yarn.lock b/examples/single-page-app/ui/yarn.lock index 772a6e549dac..40adb76db1a7 100644 --- a/examples/single-page-app/ui/yarn.lock +++ b/examples/single-page-app/ui/yarn.lock @@ -4233,9 +4233,9 @@ typed-array-length@^1.0.6: possible-typed-array-names "^1.0.0" typescript@*: - version "5.5.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.3.tgz#e1b0a3c394190838a0b168e771b0ad56a0af0faa" - integrity sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ== + version "5.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" + integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== unbox-primitive@^1.0.2: version "1.0.2" From 5809554058e2bbec216b7aff24c6f128cae40b7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:08:14 +0100 Subject: [PATCH 11/26] build(deps-dev): bump eslint-plugin-promise from 6.4.0 to 6.6.0 in /examples/single-page-app/ui (#35351) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/single-page-app/ui/package.json | 2 +- examples/single-page-app/ui/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/single-page-app/ui/package.json b/examples/single-page-app/ui/package.json index e59c3ed409fc..689265268bf5 100644 --- a/examples/single-page-app/ui/package.json +++ b/examples/single-page-app/ui/package.json @@ -30,7 +30,7 @@ "eslint-config-standard-with-typescript": "^43.0.0", "eslint-plugin-import": "^2.25.2", "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", - "eslint-plugin-promise": "^6.4.0", + "eslint-plugin-promise": "^6.6.0", "eslint-plugin-react": "^7.35.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.9", diff --git a/examples/single-page-app/ui/yarn.lock b/examples/single-page-app/ui/yarn.lock index 40adb76db1a7..401b1d183414 100644 --- a/examples/single-page-app/ui/yarn.lock +++ b/examples/single-page-app/ui/yarn.lock @@ -2506,10 +2506,10 @@ eslint-plugin-import@^2.25.2: resolve "^1.22.2" semver "^7.5.3" -eslint-plugin-promise@^6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.4.0.tgz#54926d53c79541efe9cea6ac1d823a58bbed1106" - integrity sha512-/KWWRaD3fGkVCZsdR0RU53PSthFmoHVhZl+y9+6DqeDLSikLdlUVpVEAmI6iCRR5QyOjBYBqHZV/bdv4DJ4Gtw== +eslint-plugin-promise@^6.6.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz#acd3fd7d55cead7a10f92cf698f36c0aafcd717a" + integrity sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ== eslint-plugin-react-hooks@^4.6.2: version "4.6.2" From 5d600e8df188272e6e31e253e43807f12b3cd8d6 Mon Sep 17 00:00:00 2001 From: "dependency-envoy[bot]" <148525496+dependency-envoy[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 11:13:18 +0000 Subject: [PATCH 12/26] deps/api: Bump `com_github_bufbuild_buf` -> 1.35.0 (#35358) Created by Envoy dependency bot for @phlax Fix #35356 Signed-off-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> Signed-off-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> Co-authored-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> --- api/bazel/repository_locations.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/bazel/repository_locations.bzl b/api/bazel/repository_locations.bzl index 7cddb720821a..77cd67d214fa 100644 --- a/api/bazel/repository_locations.bzl +++ b/api/bazel/repository_locations.bzl @@ -144,11 +144,11 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "buf", project_desc = "A new way of working with Protocol Buffers.", # Used for breaking change detection in API protobufs project_url = "https://buf.build", - version = "1.34.0", - sha256 = "82dcf1a5f45498b539a04d764e3cb274a13c8d94271c92508fc1624d227895ff", + version = "1.35.0", + sha256 = "a75c622b5d6fae792a0e64a04baa296681eacba7ce0c3c35d25c8b42da2f71e1", strip_prefix = "buf", urls = ["https://github.com/bufbuild/buf/releases/download/v{version}/buf-Linux-x86_64.tar.gz"], - release_date = "2024-06-21", + release_date = "2024-07-22", use_category = ["api"], license = "Apache-2.0", license_url = "https://github.com/bufbuild/buf/blob/v{version}/LICENSE", From 71af94de606a319f2350b79a38209748e5ffe1b2 Mon Sep 17 00:00:00 2001 From: "dependency-envoy[bot]" <148525496+dependency-envoy[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:31:31 +0100 Subject: [PATCH 13/26] deps: Bump `com_github_maxmind_libmaxminddb` -> 1.10.0 (#35361) Created by Envoy dependency bot for @phlax Fix #34664 Signed-off-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> Signed-off-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> Co-authored-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> --- bazel/repository_locations.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index a9f9f3036731..af5d1da07ee2 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -1533,13 +1533,13 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "maxmind_libmaxminddb", project_desc = "C library for reading MaxMind DB files", project_url = "https://github.com/maxmind/libmaxminddb", - version = "1.9.1", - sha256 = "a80682a89d915fdf60b35d316232fb04ebf36fff27fda9bd39fe8a38d3cd3f12", + version = "1.10.0", + sha256 = "5e6db72df423ae225bfe8897069f6def40faa8931f456b99d79b8b4d664c6671", strip_prefix = "libmaxminddb-{version}", urls = ["https://github.com/maxmind/libmaxminddb/releases/download/{version}/libmaxminddb-{version}.tar.gz"], use_category = ["dataplane_ext"], extensions = ["envoy.geoip_providers.maxmind"], - release_date = "2024-01-10", + release_date = "2024-06-10", cpe = "cpe:2.3:a:maxmind:libmaxminddb:*", license = "Apache-2.0", license_url = "https://github.com/maxmind/libmaxminddb/blob/{version}/LICENSE", From d568b51478ce4cf57a5b1efa7a00126dd1388279 Mon Sep 17 00:00:00 2001 From: alyssawilk Date: Tue, 23 Jul 2024 07:51:02 -0400 Subject: [PATCH 14/26] listener: removing exceptions from the filter chain manager (#35337) Risk Level: low Testing: updated tests Docs Changes: n/a Release Notes: n/a https://github.com/envoyproxy/envoy-mobile/issues/176 Signed-off-by: Alyssa Wilk --- .../filter_chain_manager_impl.cc | 180 +++++++++++------- .../filter_chain_manager_impl.h | 29 +-- .../common/listener_manager/listener_impl.cc | 4 +- .../filter_chain_benchmark_test.cc | 8 +- .../filter_chain_manager_impl_test.cc | 67 ++++--- tools/code_format/config.yaml | 1 - 6 files changed, 165 insertions(+), 124 deletions(-) diff --git a/source/common/listener_manager/filter_chain_manager_impl.cc b/source/common/listener_manager/filter_chain_manager_impl.cc index a0c29fdd6883..71b04e20082f 100644 --- a/source/common/listener_manager/filter_chain_manager_impl.cc +++ b/source/common/listener_manager/filter_chain_manager_impl.cc @@ -122,7 +122,7 @@ bool FilterChainManagerImpl::isWildcardServerName(const std::string& name) { return absl::StartsWith(name, "*."); } -void FilterChainManagerImpl::addFilterChains( +absl::Status FilterChainManagerImpl::addFilterChains( const xds::type::matcher::v3::Matcher* filter_chain_matcher, absl::Span filter_chain_span, const envoy::config::listener::v3::FilterChain* default_filter_chain, @@ -138,7 +138,7 @@ void FilterChainManagerImpl::addFilterChains( for (const auto& filter_chain : filter_chain_span) { const auto& filter_chain_match = filter_chain->filter_chain_match(); if (!filter_chain_match.address_suffix().empty() || filter_chain_match.has_suffix_len()) { - throwEnvoyExceptionOrPanic(fmt::format( + return absl::InvalidArgumentError(fmt::format( "error adding listener '{}': filter chain '{}' contains " "unimplemented fields", absl::StrJoin(addresses_, ",", Network::AddressStrFormatter()), filter_chain->name())); @@ -157,7 +157,7 @@ void FilterChainManagerImpl::addFilterChains( MessageUtil::getJsonStringFromMessageOrError(filter_chain_match, false)); #endif - throwEnvoyExceptionOrPanic(error_msg); + return absl::InvalidArgumentError(error_msg); } filter_chains.insert({filter_chain_match, filter_chain->name()}); } @@ -175,14 +175,14 @@ void FilterChainManagerImpl::addFilterChains( // If using the matcher, require usage of "name" field and skip building the index. if (filter_chain_matcher) { if (filter_chain->name().empty()) { - throwEnvoyExceptionOrPanic(fmt::format( + return absl::InvalidArgumentError(fmt::format( "error adding listener '{}': \"name\" field is required when using a listener matcher", absl::StrJoin(addresses_, ",", Network::AddressStrFormatter()))); } auto [_, inserted] = filter_chains_by_name.try_emplace(filter_chain->name(), filter_chain_impl); if (!inserted) { - throwEnvoyExceptionOrPanic(fmt::format( + return absl::InvalidArgumentError(fmt::format( "error adding listener '{}': \"name\" field is duplicated with value '{}'", absl::StrJoin(addresses_, ",", Network::AddressStrFormatter()), filter_chain->name())); } @@ -190,30 +190,38 @@ void FilterChainManagerImpl::addFilterChains( ENVOY_LOG(debug, "filter chain match in chain '{}' is ignored", filter_chain->name()); } } else { - auto createAddressVector = [](const auto& prefix_ranges) -> std::vector { + auto createAddressVector = [](const auto& prefix_ranges, + absl::Status& creation_status) -> std::vector { std::vector ips; ips.reserve(prefix_ranges.size()); for (const auto& ip : prefix_ranges) { - const auto& cidr_range = THROW_OR_RETURN_VALUE(Network::Address::CidrRange::create(ip), - Network::Address::CidrRange); - ips.push_back(cidr_range.asString()); + auto cidr_range_or_error = Network::Address::CidrRange::create(ip); + if (cidr_range_or_error.status().ok()) { + ips.push_back(cidr_range_or_error->asString()); + } else { + creation_status = cidr_range_or_error.status(); + } } return ips; }; + absl::Status creation_status = absl::OkStatus(); // Validate IP addresses. std::vector destination_ips = - createAddressVector(filter_chain_match.prefix_ranges()); + createAddressVector(filter_chain_match.prefix_ranges(), creation_status); + RETURN_IF_NOT_OK(creation_status); std::vector source_ips = - createAddressVector(filter_chain_match.source_prefix_ranges()); + createAddressVector(filter_chain_match.source_prefix_ranges(), creation_status); + RETURN_IF_NOT_OK(creation_status); std::vector direct_source_ips = - createAddressVector(filter_chain_match.direct_source_prefix_ranges()); + createAddressVector(filter_chain_match.direct_source_prefix_ranges(), creation_status); + RETURN_IF_NOT_OK(creation_status); std::vector server_names; // Reject partial wildcards, we don't match on them. for (const auto& server_name : filter_chain_match.server_names()) { if (absl::StrContains(server_name, '*') && !isWildcardServerName(server_name)) { - throwEnvoyExceptionOrPanic( + return absl::InvalidArgumentError( fmt::format("error adding listener '{}': partial wildcards are not supported in " "\"server_names\"", absl::StrJoin(addresses_, ",", Network::AddressStrFormatter()))); @@ -221,18 +229,18 @@ void FilterChainManagerImpl::addFilterChains( server_names.push_back(absl::AsciiStrToLower(server_name)); } - addFilterChainForDestinationPorts( + RETURN_IF_NOT_OK(addFilterChainForDestinationPorts( destination_ports_map_, PROTOBUF_GET_WRAPPED_OR_DEFAULT(filter_chain_match, destination_port, 0), destination_ips, server_names, filter_chain_match.transport_protocol(), filter_chain_match.application_protocols(), direct_source_ips, filter_chain_match.source_type(), source_ips, filter_chain_match.source_ports(), - filter_chain_impl); + filter_chain_impl)); } fc_contexts_[*filter_chain] = filter_chain_impl; } - convertIPsToTries(); + RETURN_IF_NOT_OK(convertIPsToTries()); copyOrRebuildDefaultFilterChain(default_filter_chain, filter_chain_factory_builder, context_creator); // Construct matcher if it is present in the listener configuration. @@ -246,6 +254,7 @@ void FilterChainManagerImpl::addFilterChains( } ENVOY_LOG(debug, "new fc_contexts has {} filter chains, including {} newly built", fc_contexts_.size(), new_filter_chain_size); + return absl::OkStatus(); } void FilterChainManagerImpl::copyOrRebuildDefaultFilterChain( @@ -281,7 +290,7 @@ void FilterChainManagerImpl::copyOrRebuildDefaultFilterChain( } } -void FilterChainManagerImpl::addFilterChainForDestinationPorts( +absl::Status FilterChainManagerImpl::addFilterChainForDestinationPorts( DestinationPortsMap& destination_ports_map, uint16_t destination_port, const std::vector& destination_ips, const absl::Span server_names, const std::string& transport_protocol, @@ -295,13 +304,13 @@ void FilterChainManagerImpl::addFilterChainForDestinationPorts( destination_ports_map[destination_port] = std::make_pair(DestinationIPsMap{}, nullptr); } - addFilterChainForDestinationIPs(destination_ports_map[destination_port].first, destination_ips, - server_names, transport_protocol, application_protocols, - direct_source_ips, source_type, source_ips, source_ports, - filter_chain); + return addFilterChainForDestinationIPs(destination_ports_map[destination_port].first, + destination_ips, server_names, transport_protocol, + application_protocols, direct_source_ips, source_type, + source_ips, source_ports, filter_chain); } -void FilterChainManagerImpl::addFilterChainForDestinationIPs( +absl::Status FilterChainManagerImpl::addFilterChainForDestinationIPs( DestinationIPsMap& destination_ips_map, const std::vector& destination_ips, const absl::Span server_names, const std::string& transport_protocol, const absl::Span application_protocols, @@ -311,19 +320,21 @@ void FilterChainManagerImpl::addFilterChainForDestinationIPs( const absl::Span source_ports, const Network::FilterChainSharedPtr& filter_chain) { if (destination_ips.empty()) { - addFilterChainForServerNames(destination_ips_map[EMPTY_STRING], server_names, - transport_protocol, application_protocols, direct_source_ips, - source_type, source_ips, source_ports, filter_chain); + RETURN_IF_NOT_OK(addFilterChainForServerNames( + destination_ips_map[EMPTY_STRING], server_names, transport_protocol, application_protocols, + direct_source_ips, source_type, source_ips, source_ports, filter_chain)); } else { for (const auto& destination_ip : destination_ips) { - addFilterChainForServerNames(destination_ips_map[destination_ip], server_names, - transport_protocol, application_protocols, direct_source_ips, - source_type, source_ips, source_ports, filter_chain); + RETURN_IF_NOT_OK( + addFilterChainForServerNames(destination_ips_map[destination_ip], server_names, + transport_protocol, application_protocols, direct_source_ips, + source_type, source_ips, source_ports, filter_chain)); } } + return absl::OkStatus(); } -void FilterChainManagerImpl::addFilterChainForServerNames( +absl::Status FilterChainManagerImpl::addFilterChainForServerNames( ServerNamesMapSharedPtr& server_names_map_ptr, const absl::Span server_names, const std::string& transport_protocol, const absl::Span application_protocols, @@ -338,26 +349,27 @@ void FilterChainManagerImpl::addFilterChainForServerNames( auto& server_names_map = *server_names_map_ptr; if (server_names.empty()) { - addFilterChainForApplicationProtocols(server_names_map[EMPTY_STRING][transport_protocol], - application_protocols, direct_source_ips, source_type, - source_ips, source_ports, filter_chain); + RETURN_IF_NOT_OK(addFilterChainForApplicationProtocols( + server_names_map[EMPTY_STRING][transport_protocol], application_protocols, + direct_source_ips, source_type, source_ips, source_ports, filter_chain)); } else { for (const auto& server_name : server_names) { if (isWildcardServerName(server_name)) { // Add mapping for the wildcard domain, i.e. ".example.com" for "*.example.com". - addFilterChainForApplicationProtocols( + RETURN_IF_NOT_OK(addFilterChainForApplicationProtocols( server_names_map[server_name.substr(1)][transport_protocol], application_protocols, - direct_source_ips, source_type, source_ips, source_ports, filter_chain); + direct_source_ips, source_type, source_ips, source_ports, filter_chain)); } else { - addFilterChainForApplicationProtocols(server_names_map[server_name][transport_protocol], - application_protocols, direct_source_ips, source_type, - source_ips, source_ports, filter_chain); + RETURN_IF_NOT_OK(addFilterChainForApplicationProtocols( + server_names_map[server_name][transport_protocol], application_protocols, + direct_source_ips, source_type, source_ips, source_ports, filter_chain)); } } } + return absl::OkStatus(); } -void FilterChainManagerImpl::addFilterChainForApplicationProtocols( +absl::Status FilterChainManagerImpl::addFilterChainForApplicationProtocols( ApplicationProtocolsMap& application_protocols_map, const absl::Span application_protocols, const std::vector& direct_source_ips, @@ -366,36 +378,39 @@ void FilterChainManagerImpl::addFilterChainForApplicationProtocols( const absl::Span source_ports, const Network::FilterChainSharedPtr& filter_chain) { if (application_protocols.empty()) { - addFilterChainForDirectSourceIPs(application_protocols_map[EMPTY_STRING].first, - direct_source_ips, source_type, source_ips, source_ports, - filter_chain); + RETURN_IF_NOT_OK(addFilterChainForDirectSourceIPs(application_protocols_map[EMPTY_STRING].first, + direct_source_ips, source_type, source_ips, + source_ports, filter_chain)); } else { for (const auto& application_protocol_ptr : application_protocols) { - addFilterChainForDirectSourceIPs(application_protocols_map[*application_protocol_ptr].first, - direct_source_ips, source_type, source_ips, source_ports, - filter_chain); + RETURN_IF_NOT_OK(addFilterChainForDirectSourceIPs( + application_protocols_map[*application_protocol_ptr].first, direct_source_ips, + source_type, source_ips, source_ports, filter_chain)); } } + return absl::OkStatus(); } -void FilterChainManagerImpl::addFilterChainForDirectSourceIPs( +absl::Status FilterChainManagerImpl::addFilterChainForDirectSourceIPs( DirectSourceIPsMap& direct_source_ips_map, const std::vector& direct_source_ips, const envoy::config::listener::v3::FilterChainMatch::ConnectionSourceType source_type, const std::vector& source_ips, const absl::Span source_ports, const Network::FilterChainSharedPtr& filter_chain) { if (direct_source_ips.empty()) { - addFilterChainForSourceTypes(direct_source_ips_map[EMPTY_STRING], source_type, source_ips, - source_ports, filter_chain); + RETURN_IF_NOT_OK(addFilterChainForSourceTypes(direct_source_ips_map[EMPTY_STRING], source_type, + source_ips, source_ports, filter_chain)); } else { for (const auto& direct_source_ip : direct_source_ips) { - addFilterChainForSourceTypes(direct_source_ips_map[direct_source_ip], source_type, source_ips, - source_ports, filter_chain); + RETURN_IF_NOT_OK(addFilterChainForSourceTypes(direct_source_ips_map[direct_source_ip], + source_type, source_ips, source_ports, + filter_chain)); } } + return absl::OkStatus(); } -void FilterChainManagerImpl::addFilterChainForSourceTypes( +absl::Status FilterChainManagerImpl::addFilterChainForSourceTypes( SourceTypesArraySharedPtr& source_types_array_ptr, const envoy::config::listener::v3::FilterChainMatch::ConnectionSourceType source_type, const std::vector& source_ips, @@ -407,30 +422,33 @@ void FilterChainManagerImpl::addFilterChainForSourceTypes( SourceTypesArray& source_types_array = *source_types_array_ptr; if (source_ips.empty()) { - addFilterChainForSourceIPs(source_types_array[source_type].first, EMPTY_STRING, source_ports, - filter_chain); + RETURN_IF_NOT_OK(addFilterChainForSourceIPs(source_types_array[source_type].first, EMPTY_STRING, + source_ports, filter_chain)); } else { for (const auto& source_ip : source_ips) { - addFilterChainForSourceIPs(source_types_array[source_type].first, source_ip, source_ports, - filter_chain); + RETURN_IF_NOT_OK(addFilterChainForSourceIPs(source_types_array[source_type].first, source_ip, + source_ports, filter_chain)); } } + return absl::OkStatus(); } -void FilterChainManagerImpl::addFilterChainForSourceIPs( +absl::Status FilterChainManagerImpl::addFilterChainForSourceIPs( SourceIPsMap& source_ips_map, const std::string& source_ip, const absl::Span source_ports, const Network::FilterChainSharedPtr& filter_chain) { if (source_ports.empty()) { - addFilterChainForSourcePorts(source_ips_map[source_ip], 0, filter_chain); + RETURN_IF_NOT_OK(addFilterChainForSourcePorts(source_ips_map[source_ip], 0, filter_chain)); } else { for (auto source_port : source_ports) { - addFilterChainForSourcePorts(source_ips_map[source_ip], source_port, filter_chain); + RETURN_IF_NOT_OK( + addFilterChainForSourcePorts(source_ips_map[source_ip], source_port, filter_chain)); } } + return absl::OkStatus(); } -void FilterChainManagerImpl::addFilterChainForSourcePorts( +absl::Status FilterChainManagerImpl::addFilterChainForSourcePorts( SourcePortsMapSharedPtr& source_ports_map_ptr, uint32_t source_port, const Network::FilterChainSharedPtr& filter_chain) { if (source_ports_map_ptr == nullptr) { @@ -442,34 +460,43 @@ void FilterChainManagerImpl::addFilterChainForSourcePorts( // If we got here and found already configured branch, then it means that this FilterChainMatch // is a duplicate, and that there is some overlap in the repeated fields with already processed // FilterChainMatches. - throwEnvoyExceptionOrPanic( + return absl::InvalidArgumentError( fmt::format("error adding listener '{}': multiple filter chains with " "overlapping matching rules are defined", absl::StrJoin(addresses_, ",", Network::AddressStrFormatter()))); } + return absl::OkStatus(); } namespace { // Template function for creating a CIDR list entry for either source or destination address. template -std::pair> makeCidrListEntry(const std::string& cidr, - const T& data) { +std::pair> +makeCidrListEntry(const std::string& cidr, const T& data, absl::Status& creation_status) { std::vector subnets; + absl::StatusOr range; if (cidr == EMPTY_STRING) { if (Network::SocketInterfaceSingleton::get().ipFamilySupported(AF_INET)) { - subnets.push_back(THROW_OR_RETURN_VALUE( - Network::Address::CidrRange::create(Network::Utility::getIpv4CidrCatchAllAddress()), - Network::Address::CidrRange)); + range = Network::Address::CidrRange::create(Network::Utility::getIpv4CidrCatchAllAddress()); + creation_status = range.status(); + if (range.status().ok()) { + subnets.push_back(*range); + } } if (Network::SocketInterfaceSingleton::get().ipFamilySupported(AF_INET6)) { - subnets.push_back(THROW_OR_RETURN_VALUE( - Network::Address::CidrRange::create(Network::Utility::getIpv6CidrCatchAllAddress()), - Network::Address::CidrRange)); + range = Network::Address::CidrRange::create(Network::Utility::getIpv6CidrCatchAllAddress()); + creation_status = range.status(); + if (range.status().ok()) { + subnets.push_back(*range); + } } } else { - subnets.push_back(THROW_OR_RETURN_VALUE(Network::Address::CidrRange::create(cidr), - Network::Address::CidrRange)); + range = Network::Address::CidrRange::create(cidr); + creation_status = range.status(); + if (range.status().ok()) { + subnets.push_back(*range); + } } return std::make_pair>(T(data), std::move(subnets)); } @@ -699,7 +726,7 @@ const Network::FilterChain* FilterChainManagerImpl::findFilterChainForSourceIpAn return nullptr; } -void FilterChainManagerImpl::convertIPsToTries() { +absl::Status FilterChainManagerImpl::convertIPsToTries() { for (auto& [destination_port, destination_ips_pair] : destination_ports_map_) { UNREFERENCED_PARAMETER(destination_port); // These variables are used as we build up the destination CIDRs used for the trie. @@ -709,7 +736,10 @@ void FilterChainManagerImpl::convertIPsToTries() { destination_ips_list.reserve(destination_ips_map.size()); for (const auto& [destination_ip, server_names_map_ptr] : destination_ips_map) { - destination_ips_list.push_back(makeCidrListEntry(destination_ip, server_names_map_ptr)); + absl::Status creation_status = absl::OkStatus(); + destination_ips_list.push_back( + makeCidrListEntry(destination_ip, server_names_map_ptr, creation_status)); + RETURN_IF_NOT_OK(creation_status); // This hugely nested for loop greatly pains me, but I'm not sure how to make it better. // We need to get access to all of the source IP strings so that we can convert them into @@ -729,7 +759,8 @@ void FilterChainManagerImpl::convertIPsToTries() { for (auto& [direct_source_ip, source_arrays_ptr] : direct_source_ips_map) { direct_source_ips_list.push_back( - makeCidrListEntry(direct_source_ip, source_arrays_ptr)); + makeCidrListEntry(direct_source_ip, source_arrays_ptr, creation_status)); + RETURN_IF_NOT_OK(creation_status); for (auto& [source_ips_map, source_ips_trie] : *source_arrays_ptr) { std::vector< @@ -738,7 +769,9 @@ void FilterChainManagerImpl::convertIPsToTries() { source_ips_list.reserve(source_ips_map.size()); for (auto& [source_ip, source_port_map_ptr] : source_ips_map) { - source_ips_list.push_back(makeCidrListEntry(source_ip, source_port_map_ptr)); + source_ips_list.push_back( + makeCidrListEntry(source_ip, source_port_map_ptr, creation_status)); + RETURN_IF_NOT_OK(creation_status); } source_ips_trie = std::make_unique(source_ips_list, true); @@ -753,6 +786,7 @@ void FilterChainManagerImpl::convertIPsToTries() { destination_ips_trie = std::make_unique(destination_ips_list, true); } + return absl::OkStatus(); } Network::DrainableFilterChainSharedPtr FilterChainManagerImpl::findExistingFilterChain( diff --git a/source/common/listener_manager/filter_chain_manager_impl.h b/source/common/listener_manager/filter_chain_manager_impl.h index 023fd754e955..46a408af4223 100644 --- a/source/common/listener_manager/filter_chain_manager_impl.h +++ b/source/common/listener_manager/filter_chain_manager_impl.h @@ -149,7 +149,7 @@ class FilterChainManagerImpl : public Network::FilterChainManager, // Add all filter chains into this manager. During the lifetime of FilterChainManagerImpl this // should be called at most once. - void addFilterChains( + absl::Status addFilterChains( const xds::type::matcher::v3::Matcher* filter_chain_matcher, absl::Span filter_chain_span, const envoy::config::listener::v3::FilterChain* default_filter_chain, @@ -170,7 +170,7 @@ class FilterChainManagerImpl : public Network::FilterChainManager, } private: - void convertIPsToTries(); + absl::Status convertIPsToTries(); const Network::FilterChain* findFilterChainUsingMatcher(const Network::ConnectionSocket& socket, const StreamInfo::StreamInfo& info) const; @@ -214,7 +214,7 @@ class FilterChainManagerImpl : public Network::FilterChainManager, using DestinationPortsMap = absl::flat_hash_map>; - void addFilterChainForDestinationPorts( + absl::Status addFilterChainForDestinationPorts( DestinationPortsMap& destination_ports_map, uint16_t destination_port, const std::vector& destination_ips, const absl::Span server_names, const std::string& transport_protocol, @@ -224,7 +224,7 @@ class FilterChainManagerImpl : public Network::FilterChainManager, const std::vector& source_ips, const absl::Span source_ports, const Network::FilterChainSharedPtr& filter_chain); - void addFilterChainForDestinationIPs( + absl::Status addFilterChainForDestinationIPs( DestinationIPsMap& destination_ips_map, const std::vector& destination_ips, const absl::Span server_names, const std::string& transport_protocol, const absl::Span application_protocols, @@ -233,7 +233,7 @@ class FilterChainManagerImpl : public Network::FilterChainManager, const std::vector& source_ips, const absl::Span source_ports, const Network::FilterChainSharedPtr& filter_chain); - void addFilterChainForServerNames( + absl::Status addFilterChainForServerNames( ServerNamesMapSharedPtr& server_names_map_ptr, const absl::Span server_names, const std::string& transport_protocol, const absl::Span application_protocols, @@ -242,7 +242,7 @@ class FilterChainManagerImpl : public Network::FilterChainManager, const std::vector& source_ips, const absl::Span source_ports, const Network::FilterChainSharedPtr& filter_chain); - void addFilterChainForApplicationProtocols( + absl::Status addFilterChainForApplicationProtocols( ApplicationProtocolsMap& application_protocol_map, const absl::Span application_protocols, const std::vector& direct_source_ips, @@ -250,24 +250,25 @@ class FilterChainManagerImpl : public Network::FilterChainManager, const std::vector& source_ips, const absl::Span source_ports, const Network::FilterChainSharedPtr& filter_chain); - void addFilterChainForDirectSourceIPs( + absl::Status addFilterChainForDirectSourceIPs( DirectSourceIPsMap& direct_source_ips_map, const std::vector& direct_source_ips, const envoy::config::listener::v3::FilterChainMatch::ConnectionSourceType source_type, const std::vector& source_ips, const absl::Span source_ports, const Network::FilterChainSharedPtr& filter_chain); - void addFilterChainForSourceTypes( + absl::Status addFilterChainForSourceTypes( SourceTypesArraySharedPtr& source_types_array_ptr, const envoy::config::listener::v3::FilterChainMatch::ConnectionSourceType source_type, const std::vector& source_ips, const absl::Span source_ports, const Network::FilterChainSharedPtr& filter_chain); - void addFilterChainForSourceIPs(SourceIPsMap& source_ips_map, const std::string& source_ip, - const absl::Span source_ports, - const Network::FilterChainSharedPtr& filter_chain); - void addFilterChainForSourcePorts(SourcePortsMapSharedPtr& source_ports_map_ptr, - uint32_t source_port, - const Network::FilterChainSharedPtr& filter_chain); + absl::Status addFilterChainForSourceIPs(SourceIPsMap& source_ips_map, + const std::string& source_ip, + const absl::Span source_ports, + const Network::FilterChainSharedPtr& filter_chain); + absl::Status addFilterChainForSourcePorts(SourcePortsMapSharedPtr& source_ports_map_ptr, + uint32_t source_port, + const Network::FilterChainSharedPtr& filter_chain); const Network::FilterChain* findFilterChainForDestinationIP(const DestinationIPsTrie& destination_ips_trie, diff --git a/source/common/listener_manager/listener_impl.cc b/source/common/listener_manager/listener_impl.cc index dde659392823..8aaa43a212c5 100644 --- a/source/common/listener_manager/listener_impl.cc +++ b/source/common/listener_manager/listener_impl.cc @@ -735,11 +735,11 @@ void ListenerImpl::validateFilterChains(const envoy::config::listener::v3::Liste void ListenerImpl::buildFilterChains(const envoy::config::listener::v3::Listener& config) { transport_factory_context_->setInitManager(*dynamic_init_manager_); ListenerFilterChainFactoryBuilder builder(*this, *transport_factory_context_); - filter_chain_manager_->addFilterChains( + THROW_IF_NOT_OK(filter_chain_manager_->addFilterChains( config.has_filter_chain_matcher() ? &config.filter_chain_matcher() : nullptr, config.filter_chains(), config.has_default_filter_chain() ? &config.default_filter_chain() : nullptr, builder, - *filter_chain_manager_); + *filter_chain_manager_)); } void ListenerImpl::buildConnectionBalancer(const envoy::config::listener::v3::Listener& config, diff --git a/test/common/listener_manager/filter_chain_benchmark_test.cc b/test/common/listener_manager/filter_chain_benchmark_test.cc index 539eb9b972ff..07f571786485 100644 --- a/test/common/listener_manager/filter_chain_benchmark_test.cc +++ b/test/common/listener_manager/filter_chain_benchmark_test.cc @@ -233,8 +233,8 @@ BENCHMARK_DEFINE_F(FilterChainBenchmarkFixture, FilterChainManagerBuildTest) for (auto _ : state) { UNREFERENCED_PARAMETER(_); FilterChainManagerImpl filter_chain_manager{addresses, factory_context, init_manager_}; - filter_chain_manager.addFilterChains(nullptr, filter_chains_, nullptr, dummy_builder_, - filter_chain_manager); + THROW_IF_NOT_OK(filter_chain_manager.addFilterChains(nullptr, filter_chains_, nullptr, + dummy_builder_, filter_chain_manager)); } } @@ -257,8 +257,8 @@ BENCHMARK_DEFINE_F(FilterChainBenchmarkFixture, FilterChainFindTest) addresses.emplace_back(std::make_shared("127.0.0.1", 1234)); FilterChainManagerImpl filter_chain_manager{addresses, factory_context, init_manager_}; - filter_chain_manager.addFilterChains(nullptr, filter_chains_, nullptr, dummy_builder_, - filter_chain_manager); + THROW_IF_NOT_OK(filter_chain_manager.addFilterChains(nullptr, filter_chains_, nullptr, + dummy_builder_, filter_chain_manager)); NiceMock stream_info; for (auto _ : state) { UNREFERENCED_PARAMETER(_); diff --git a/test/common/listener_manager/filter_chain_manager_impl_test.cc b/test/common/listener_manager/filter_chain_manager_impl_test.cc index f4cd6f118c3b..56a03483a160 100644 --- a/test/common/listener_manager/filter_chain_manager_impl_test.cc +++ b/test/common/listener_manager/filter_chain_manager_impl_test.cc @@ -106,10 +106,10 @@ class FilterChainManagerImplTest : public testing::TestWithParam { void addSingleFilterChainHelper( const envoy::config::listener::v3::FilterChain& filter_chain, const envoy::config::listener::v3::FilterChain* fallback_filter_chain = nullptr) { - filter_chain_manager_->addFilterChains( + THROW_IF_NOT_OK(filter_chain_manager_->addFilterChains( GetParam() ? &matcher_ : nullptr, std::vector{&filter_chain}, - fallback_filter_chain, filter_chain_factory_builder_, *filter_chain_manager_); + fallback_filter_chain, filter_chain_factory_builder_, *filter_chain_manager_)); } // Intermediate states. @@ -173,10 +173,12 @@ TEST_P(FilterChainManagerImplTest, FilterChainMatchNothing) { TEST_P(FilterChainManagerImplTest, FilterChainMatchCaseInSensitive) { envoy::config::listener::v3::FilterChain new_filter_chain = filter_chain_template_; new_filter_chain.mutable_filter_chain_match()->add_server_names("foo.EXAMPLE.com"); - filter_chain_manager_->addFilterChains( - GetParam() ? &matcher_ : nullptr, - std::vector{&new_filter_chain}, nullptr, - filter_chain_factory_builder_, *filter_chain_manager_); + EXPECT_TRUE(filter_chain_manager_ + ->addFilterChains(GetParam() ? &matcher_ : nullptr, + std::vector{ + &new_filter_chain}, + nullptr, filter_chain_factory_builder_, *filter_chain_manager_) + .ok()); auto filter_chain = findFilterChainHelper(10000, "127.0.0.1", "FOO.example.com", "tls", {}, "8.8.8.8", 111); EXPECT_NE(filter_chain, nullptr); @@ -221,11 +223,12 @@ TEST_P(FilterChainManagerImplTest, LookupFilterChainContextByFilterChainMessage) filter_chain_messages.push_back(std::move(new_filter_chain)); } EXPECT_CALL(filter_chain_factory_builder_, buildFilterChain(_, _)).Times(2); - filter_chain_manager_->addFilterChains( - GetParam() ? &matcher_ : nullptr, - std::vector{&filter_chain_messages[0], - &filter_chain_messages[1]}, - nullptr, filter_chain_factory_builder_, *filter_chain_manager_); + EXPECT_TRUE(filter_chain_manager_ + ->addFilterChains(GetParam() ? &matcher_ : nullptr, + std::vector{ + &filter_chain_messages[0], &filter_chain_messages[1]}, + nullptr, filter_chain_factory_builder_, *filter_chain_manager_) + .ok()); } TEST_P(FilterChainManagerImplTest, DuplicateContextsAreNotBuilt) { @@ -240,20 +243,24 @@ TEST_P(FilterChainManagerImplTest, DuplicateContextsAreNotBuilt) { } EXPECT_CALL(filter_chain_factory_builder_, buildFilterChain(_, _)); - filter_chain_manager_->addFilterChains( - GetParam() ? &matcher_ : nullptr, - std::vector{&filter_chain_messages[0]}, - nullptr, filter_chain_factory_builder_, *filter_chain_manager_); + EXPECT_TRUE(filter_chain_manager_ + ->addFilterChains(GetParam() ? &matcher_ : nullptr, + std::vector{ + &filter_chain_messages[0]}, + nullptr, filter_chain_factory_builder_, *filter_chain_manager_) + .ok()); FilterChainManagerImpl new_filter_chain_manager{addresses_, parent_context_, init_manager_, *filter_chain_manager_}; // The new filter chain manager maintains 3 filter chains, but only 2 filter chain context is // built because it reuse the filter chain context in the previous filter chain manager EXPECT_CALL(filter_chain_factory_builder_, buildFilterChain(_, _)).Times(2); - new_filter_chain_manager.addFilterChains( - GetParam() ? &matcher_ : nullptr, - std::vector{ - &filter_chain_messages[0], &filter_chain_messages[1], &filter_chain_messages[2]}, - nullptr, filter_chain_factory_builder_, new_filter_chain_manager); + EXPECT_TRUE(new_filter_chain_manager + .addFilterChains(GetParam() ? &matcher_ : nullptr, + std::vector{ + &filter_chain_messages[0], &filter_chain_messages[1], + &filter_chain_messages[2]}, + nullptr, filter_chain_factory_builder_, new_filter_chain_manager) + .ok()); } TEST_P(FilterChainManagerImplTest, CreatedFilterChainFactoryContextHasIndependentDrainClose) { @@ -291,17 +298,17 @@ TEST_P(FilterChainManagerImplTest, DuplicateFilterChainMatchFails) { new_filter_chain1.mutable_filter_chain_match()->add_server_names("example.com"); envoy::config::listener::v3::FilterChain new_filter_chain2 = new_filter_chain1; - EXPECT_THROW_WITH_MESSAGE(filter_chain_manager_->addFilterChains( - nullptr, - std::vector{ - &new_filter_chain1, &new_filter_chain2}, - nullptr, filter_chain_factory_builder_, *filter_chain_manager_), - EnvoyException, - "error adding listener '127.0.0.1:1234': filter chain 'foo' has the " - "same matching rules defined as 'foo'" + EXPECT_EQ(filter_chain_manager_ + ->addFilterChains(nullptr, + std::vector{ + &new_filter_chain1, &new_filter_chain2}, + nullptr, filter_chain_factory_builder_, *filter_chain_manager_) + .message(), + "error adding listener '127.0.0.1:1234': filter chain 'foo' has the " + "same matching rules defined as 'foo'" #ifdef ENVOY_ENABLE_YAML - ". duplicate matcher is: " - "{\"destination_port\":10000,\"server_names\":[\"example.com\"]}" + ". duplicate matcher is: " + "{\"destination_port\":10000,\"server_names\":[\"example.com\"]}" #endif ); } diff --git a/tools/code_format/config.yaml b/tools/code_format/config.yaml index b4277350d9be..e92b584d799c 100644 --- a/tools/code_format/config.yaml +++ b/tools/code_format/config.yaml @@ -100,7 +100,6 @@ paths: - source/common/router/route_config_update_receiver_impl.cc - source/common/listener_manager/listener_impl.cc - source/common/listener_manager/listener_manager_impl.cc - - source/common/listener_manager/filter_chain_manager_impl.cc - source/common/upstream/cluster_manager_impl.cc - source/common/upstream/upstream_impl.cc - source/common/network/listen_socket_impl.cc From e9da574f56026d63e087d9ed9bd3c92bfb417ae8 Mon Sep 17 00:00:00 2001 From: "dependency-envoy[bot]" <148525496+dependency-envoy[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:32:58 +0100 Subject: [PATCH 15/26] deps: Bump `io_opentelemetry_cpp` -> 1.16.1 (#35360) Created by Envoy dependency bot for @phlax Fix #35254 Signed-off-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> --------- Signed-off-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> Signed-off-by: Ryan Northey Co-authored-by: dependency-envoy[bot] <148525496+dependency-envoy[bot]@users.noreply.github.com> Co-authored-by: Ryan Northey --- bazel/io_opentelemetry_cpp.patch | 13 ------------- bazel/repositories.bzl | 6 +----- bazel/repository_locations.bzl | 6 +++--- 3 files changed, 4 insertions(+), 21 deletions(-) delete mode 100644 bazel/io_opentelemetry_cpp.patch diff --git a/bazel/io_opentelemetry_cpp.patch b/bazel/io_opentelemetry_cpp.patch deleted file mode 100644 index 6eb4cfe2a9a5..000000000000 --- a/bazel/io_opentelemetry_cpp.patch +++ /dev/null @@ -1,13 +0,0 @@ -# TODO: Remove once https://github.com/open-telemetry/opentelemetry-cpp/issues/2556 is merged - ---- a/api/include/opentelemetry/trace/span_context.h -+++ b/api/include/opentelemetry/trace/span_context.h -@@ -30,7 +30,7 @@ class SpanContext final - SpanContext(bool sampled_flag, bool is_remote) noexcept - : trace_id_(), - span_id_(), -- trace_flags_(trace::TraceFlags((uint8_t)sampled_flag)), -+ trace_flags_(trace::TraceFlags(static_cast(sampled_flag))), - is_remote_(is_remote), - trace_state_(TraceState::GetDefault()) - {} diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index e8d03de52658..f42c356932fa 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -774,11 +774,7 @@ def _io_opentracing_cpp(): ) def _io_opentelemetry_api_cpp(): - external_http_archive( - name = "io_opentelemetry_cpp", - patch_args = ["-p1"], - patches = ["@envoy//bazel:io_opentelemetry_cpp.patch"], - ) + external_http_archive(name = "io_opentelemetry_cpp") native.bind( name = "opentelemetry_api", actual = "@io_opentelemetry_cpp//api:api", diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index af5d1da07ee2..f28bd5705739 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -572,8 +572,8 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "OpenTelemetry", project_desc = "Observability framework and toolkit designed to create and manage telemetry data such as traces, metrics, and logs.", project_url = "https://opentelemetry.io", - version = "1.14.2", - sha256 = "c7e7801c9f6228751cdb9dd4724d0f04777ed53f524c8828e73bf4c9f894e0bd", + version = "1.16.1", + sha256 = "b8a78bb2a3a78133dbb08bcd04342f4b1e03cb4a19079b8416d408d905fffc37", strip_prefix = "opentelemetry-cpp-{version}", urls = ["https://github.com/open-telemetry/opentelemetry-cpp/archive/refs/tags/v{version}.tar.gz"], use_category = ["observability_ext"], @@ -582,7 +582,7 @@ REPOSITORY_LOCATIONS_SPEC = dict( "envoy.tracers.opentelemetry.samplers.always_on", "envoy.tracers.opentelemetry.samplers.dynatrace", ], - release_date = "2024-02-27", + release_date = "2024-07-17", cpe = "N/A", license = "Apache-2.0", license_url = "https://github.com/open-telemetry/opentelemetry-cpp/blob/v{version}/LICENSE", From 45bacfad74157d0e0727c784b6922eca8726ed8f Mon Sep 17 00:00:00 2001 From: code Date: Tue, 23 Jul 2024 21:34:08 +0800 Subject: [PATCH 16/26] runtime: remove envoy.reloadable_features.no_downgrade_to_canonical_name (#35331) Commit Message: runtime: remove envoy.reloadable_features.no_downgrade_to_canonical_name Additional Description: envoy.reloadable_features.no_downgrade_to_canonical_name is set to true by default at #30340 (9 mouth ago). And we just release 1.31. It's time to remove it and the legacy code path. Risk Level: low. Testing: n/a. Docs Changes: n/a. Release Notes: added. Platform Specific Features: n/a. Fixes https://github.com/envoyproxy/envoy/issues/35371 --------- Signed-off-by: wbpcode --- changelogs/current.yaml | 4 ++ .../intro/arch_overview/http/http_filters.rst | 17 ----- source/common/http/filter_manager.cc | 50 +------------- source/common/http/filter_manager.h | 7 +- source/common/runtime/runtime_features.cc | 1 - test/common/http/filter_manager_test.cc | 69 ------------------- 6 files changed, 8 insertions(+), 140 deletions(-) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index dd6474cf1ddf..4503db855258 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -18,6 +18,10 @@ bug_fixes: removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` +- area: http + change: | + Removed runtime flag ``envoy.reloadable_features.no_downgrade_to_canonical_name`` and legacy code + path. new_features: diff --git a/docs/root/intro/arch_overview/http/http_filters.rst b/docs/root/intro/arch_overview/http/http_filters.rst index 5486ff37402c..c2a0d14cc79e 100644 --- a/docs/root/intro/arch_overview/http/http_filters.rst +++ b/docs/root/intro/arch_overview/http/http_filters.rst @@ -129,23 +129,6 @@ The ``custom-filter-name-for-lua`` and ``envoy.filters.http.buffer`` will be use related per filter config. -For the first ``custom-filter-name-for-lua`` filter, if no related entry are found by -``custom-filter-name-for-lua``, we will downgrade to try the canonical filter name ``envoy.filters.http.lua``. -This downgrading is for backward compatibility and could be disabled by setting the runtime flag -``envoy.reloadable_features.no_downgrade_to_canonical_name`` to ``true`` explicitly. - - -For the second ``envoy.filters.http.buffer`` filter, if no related entry are found by -``envoy.filters.http.buffer``, we will not try to downgrade because canonical filter name is the same as -the filter config name. - - -.. warning:: - Downgrading to canonical filter name is deprecated and will be removed soon. Please ensure the - key of the per filter config map matches the filter config name exactly and don't rely on the - downgrading behavior. - - Use of per filter config map is filter specific. See the :ref:`HTTP filter documentation ` for if and how it is utilized for every filter. diff --git a/source/common/http/filter_manager.cc b/source/common/http/filter_manager.cc index d533c41af109..21efeac055a9 100644 --- a/source/common/http/filter_manager.cc +++ b/source/common/http/filter_manager.cc @@ -281,32 +281,7 @@ ActiveStreamFilterBase::mostSpecificPerFilterConfig() const { if (current_route == nullptr) { return nullptr; } - - auto* result = current_route->mostSpecificPerFilterConfig(filter_context_.config_name); - - /** - * If: - * 1. no per filter config is found for the filter config name. - * 2. filter config name is different from the filter canonical name. - * 3. downgrade feature is not disabled. - * we fallback to use the filter canonical name. - */ - if (result == nullptr && !parent_.no_downgrade_to_canonical_name_ && - filter_context_.filter_name != filter_context_.config_name) { - // Fallback to use filter canonical name. - result = current_route->mostSpecificPerFilterConfig(filter_context_.filter_name); - - if (result != nullptr) { - ENVOY_LOG_FIRST_N( - warn, 10, - "No per filter config is found by filter config name \"{}\" and fallback to use " - "filter canonical name \"{}\". This is deprecated and will be forbidden very " - "soon. Please use the filter config name to index per filter config. See " - "https://github.com/envoyproxy/envoy/issues/29461 for more detail.", - filter_context_.config_name, filter_context_.filter_name); - } - } - return result; + return current_route->mostSpecificPerFilterConfig(filter_context_.config_name); } void ActiveStreamFilterBase::traversePerFilterConfig( @@ -316,30 +291,9 @@ void ActiveStreamFilterBase::traversePerFilterConfig( return; } - bool handled = false; current_route->traversePerFilterConfig( filter_context_.config_name, - [&handled, &cb](const Router::RouteSpecificFilterConfig& config) { - handled = true; - cb(config); - }); - - if (handled || parent_.no_downgrade_to_canonical_name_ || - filter_context_.filter_name == filter_context_.config_name) { - return; - } - - current_route->traversePerFilterConfig( - filter_context_.filter_name, [&cb, this](const Router::RouteSpecificFilterConfig& config) { - ENVOY_LOG_FIRST_N( - warn, 10, - "No per filter config is found by filter config name \"{}\" and fallback to use " - "filter canonical name \"{}\". This is deprecated and will be forbidden very " - "soon. Please use the filter config name to index per filter config. See " - "https://github.com/envoyproxy/envoy/issues/29461 for more detail.", - filter_context_.config_name, filter_context_.filter_name); - cb(config); - }); + [&cb](const Router::RouteSpecificFilterConfig& config) { cb(config); }); } Http1StreamEncoderOptionsOptRef ActiveStreamFilterBase::http1StreamEncoderOptions() { diff --git a/source/common/http/filter_manager.h b/source/common/http/filter_manager.h index 2952dcc07071..ef774fc28638 100644 --- a/source/common/http/filter_manager.h +++ b/source/common/http/filter_manager.h @@ -646,9 +646,8 @@ class FilterManager : public ScopeTrackedObject, : filter_manager_callbacks_(filter_manager_callbacks), dispatcher_(dispatcher), connection_(connection), stream_id_(stream_id), account_(std::move(account)), proxy_100_continue_(proxy_100_continue), buffer_limit_(buffer_limit), - filter_chain_factory_(filter_chain_factory), - no_downgrade_to_canonical_name_(Runtime::runtimeFeatureEnabled( - "envoy.reloadable_features.no_downgrade_to_canonical_name")) {} + filter_chain_factory_(filter_chain_factory) {} + ~FilterManager() override { ASSERT(state_.destroyed_); ASSERT(state_.filter_call_state_ == 0); @@ -1084,8 +1083,6 @@ class FilterManager : public ScopeTrackedObject, // clang-format on State state_; - - const bool no_downgrade_to_canonical_name_{}; }; // The DownstreamFilterManager has explicit handling to send local replies. diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index 89024047da29..3fa0167c79db 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -69,7 +69,6 @@ RUNTIME_GUARD(envoy_reloadable_features_immediate_response_use_filter_mutation_r RUNTIME_GUARD(envoy_reloadable_features_jwt_authn_remove_jwt_from_query_params); RUNTIME_GUARD(envoy_reloadable_features_jwt_authn_validate_uri); RUNTIME_GUARD(envoy_reloadable_features_lua_flow_control_while_http_call); -RUNTIME_GUARD(envoy_reloadable_features_no_downgrade_to_canonical_name); RUNTIME_GUARD(envoy_reloadable_features_no_extension_lookup_by_name); RUNTIME_GUARD(envoy_reloadable_features_no_timer_based_rate_limit_token_bucket); RUNTIME_GUARD(envoy_reloadable_features_normalize_host_for_preresolve_dfp_dns); diff --git a/test/common/http/filter_manager_test.cc b/test/common/http/filter_manager_test.cc index 4baa901077ab..c360ed655c6a 100644 --- a/test/common/http/filter_manager_test.cc +++ b/test/common/http/filter_manager_test.cc @@ -429,76 +429,7 @@ TEST_F(FilterManagerTest, SetAndGetUpstreamOverrideHost) { filter_manager_->destroyFilters(); }; -TEST_F(FilterManagerTest, GetRouteLevelFilterConfigAndEnableDowngrade) { - TestScopedRuntime scoped_runtime; - scoped_runtime.mergeValues( - {{"envoy.reloadable_features.no_downgrade_to_canonical_name", "false"}}); - - initialize(); - - std::shared_ptr decoder_filter(new NiceMock()); - - EXPECT_CALL(filter_factory_, createFilterChain(_)) - .WillRepeatedly(Invoke([&](FilterChainManager& manager) -> bool { - auto decoder_factory = createDecoderFilterFactoryCb(decoder_filter); - manager.applyFilterFactoryCb({"custom-name", "filter-name"}, decoder_factory); - return true; - })); - filter_manager_->createFilterChain(); - - std::shared_ptr route(new NiceMock()); - auto route_config = std::make_shared(); - - NiceMock downstream_callbacks; - ON_CALL(filter_manager_callbacks_, downstreamCallbacks) - .WillByDefault(Return(OptRef{downstream_callbacks})); - ON_CALL(downstream_callbacks, route(_)).WillByDefault(Return(route)); - - // Get a valid config by the custom filter name. - EXPECT_CALL(*route, mostSpecificPerFilterConfig(testing::Eq("custom-name"))) - .WillOnce(Return(route_config.get())); - EXPECT_EQ(route_config.get(), decoder_filter->callbacks_->mostSpecificPerFilterConfig()); - - // Try again with filter name if we get nothing by the custom filter name. - EXPECT_CALL(*route, mostSpecificPerFilterConfig(testing::Eq("custom-name"))) - .WillOnce(Return(nullptr)); - EXPECT_CALL(*route, mostSpecificPerFilterConfig(testing::Eq("filter-name"))) - .WillOnce(Return(route_config.get())); - EXPECT_EQ(route_config.get(), decoder_filter->callbacks_->mostSpecificPerFilterConfig()); - - // Get a valid config by the custom filter name. - EXPECT_CALL(*route, traversePerFilterConfig(testing::Eq("custom-name"), _)) - .WillOnce(Invoke([&](const std::string&, - std::function cb) { - cb(*route_config); - })); - decoder_filter->callbacks_->traversePerFilterConfig( - [&](const Router::RouteSpecificFilterConfig& config) { - EXPECT_EQ(route_config.get(), &config); - }); - - // Try again with filter name if we get nothing by the custom filter name. - EXPECT_CALL(*route, traversePerFilterConfig(testing::Eq("custom-name"), _)) - .WillOnce(Invoke([&](const std::string&, - std::function) {})); - EXPECT_CALL(*route, traversePerFilterConfig(testing::Eq("filter-name"), _)) - .WillOnce(Invoke([&](const std::string&, - std::function cb) { - cb(*route_config); - })); - decoder_filter->callbacks_->traversePerFilterConfig( - [&](const Router::RouteSpecificFilterConfig& config) { - EXPECT_EQ(route_config.get(), &config); - }); - - filter_manager_->destroyFilters(); -}; - TEST_F(FilterManagerTest, GetRouteLevelFilterConfig) { - TestScopedRuntime scoped_runtime; - scoped_runtime.mergeValues( - {{"envoy.reloadable_features.no_downgrade_to_canonical_name", "true"}}); - initialize(); std::shared_ptr decoder_filter(new NiceMock()); From 6e7c81cb8b7220fda4551a575a81f309b9affc28 Mon Sep 17 00:00:00 2001 From: alyssawilk Date: Tue, 23 Jul 2024 09:53:03 -0400 Subject: [PATCH 17/26] cares: restoring prior defaults (#35335) This should theoretically restore the defaults changed in https://github.com/c-ares/c-ares/pull/542/files Risk Level: medium Testing: Docs Changes: n/a Release Notes: n/a fixes https://github.com/envoyproxy/envoy/issues/35117 Signed-off-by: Alyssa Wilk --- source/extensions/network/dns_resolver/cares/dns_impl.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/extensions/network/dns_resolver/cares/dns_impl.cc b/source/extensions/network/dns_resolver/cares/dns_impl.cc index d4b5fd6004bd..46986aadeb3a 100644 --- a/source/extensions/network/dns_resolver/cares/dns_impl.cc +++ b/source/extensions/network/dns_resolver/cares/dns_impl.cc @@ -100,6 +100,12 @@ DnsResolverImpl::AresOptions DnsResolverImpl::defaultAresOptions() { options.options_.udp_max_queries = udp_max_queries_; } + // This block reinstates cares defaults before https://github.com/c-ares/c-ares/pull/542 + options.optmask_ |= ARES_OPT_TIMEOUT; + options.options_.timeout = 5; + options.optmask_ |= ARES_OPT_TRIES; + options.options_.tries = 4; + return options; } From 69a9c7c7468e8484f439e302b4f0cd4f3784545e Mon Sep 17 00:00:00 2001 From: Konstantin Baidin <128369285+konstantin-baidin-y42@users.noreply.github.com> Date: Tue, 23 Jul 2024 19:00:48 +0200 Subject: [PATCH 18/26] external authz: Interpret error grpc codes of the external authz server as failure to fix failure_mode_allowed feature (#34951) Fixes #34705 Signed-off-by: konstantin-baidin-y42 --- .../filter/http/ext_authz/v2/ext_authz.proto | 5 +- .../filters/http/ext_authz/v3/ext_authz.proto | 5 +- changelogs/current.yaml | 6 ++ source/common/runtime/runtime_features.cc | 2 + .../common/ext_authz/ext_authz_grpc_impl.cc | 12 ++- .../extensions/filters/common/ext_authz/BUILD | 1 + .../ext_authz/ext_authz_grpc_impl_test.cc | 91 ++++++++++++++----- 7 files changed, 93 insertions(+), 29 deletions(-) diff --git a/api/envoy/config/filter/http/ext_authz/v2/ext_authz.proto b/api/envoy/config/filter/http/ext_authz/v2/ext_authz.proto index c79dd4a24bc9..c55938fc3cbe 100644 --- a/api/envoy/config/filter/http/ext_authz/v2/ext_authz.proto +++ b/api/envoy/config/filter/http/ext_authz/v2/ext_authz.proto @@ -40,11 +40,12 @@ message ExtAuthz { // // 1. When set to true, the filter will *accept* client request even if the communication with // the authorization service has failed, or if the authorization service has returned a HTTP 5xx - // error. + // error. In case with GRPC authorization service, only PermissionDenied (7) and Unauthenticated (16) + // status codes will *reject* client requests. And other GRPC statuses will *accept* client requests. // // 2. When set to false, ext-authz will *reject* client requests and return a *Forbidden* // response if the communication with the authorization service has failed, or if the - // authorization service has returned a HTTP 5xx error. + // authorization service has returned a HTTP 5xx error or any non-Ok GRPC status. // // Note that errors can be *always* tracked in the :ref:`stats // `. diff --git a/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto b/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto index 4b4e79ef1f9f..7619d7ba5097 100644 --- a/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto +++ b/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto @@ -56,11 +56,12 @@ message ExtAuthz { // // 1. When set to true, the filter will ``accept`` client request even if the communication with // the authorization service has failed, or if the authorization service has returned a HTTP 5xx - // error. + // error. In case with GRPC authorization service, only PermissionDenied (7) and Unauthenticated (16) + // status codes will ``reject`` client requests. And other GRPC statuses will ``accept`` client requests. // // 2. When set to false, ext-authz will ``reject`` client requests and return a ``Forbidden`` // response if the communication with the authorization service has failed, or if the - // authorization service has returned a HTTP 5xx error. + // authorization service has returned a HTTP 5xx error or any non-Ok GRPC status. // // Note that errors can be ``always`` tracked in the :ref:`stats // `. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 4503db855258..fdcb91be6d49 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -15,6 +15,12 @@ bug_fixes: - area: dns change: | The DNS filter no longer returns FORMERR if a message has an ID of 0. +- area: ext_authz + change: | + Fixed fail-open behaviour of the :ref:`failure_mode_allow config option + ` + when a grpc external authz server is used. + The behaviour can be enabled by ``envoy_reloadable_features_process_ext_authz_grpc_error_codes_as_errors``. removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index 3fa0167c79db..4fe38e851ebe 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -73,6 +73,8 @@ RUNTIME_GUARD(envoy_reloadable_features_no_extension_lookup_by_name); RUNTIME_GUARD(envoy_reloadable_features_no_timer_based_rate_limit_token_bucket); RUNTIME_GUARD(envoy_reloadable_features_normalize_host_for_preresolve_dfp_dns); RUNTIME_GUARD(envoy_reloadable_features_original_dst_rely_on_idle_timeout); +// Fixes fail-open behaviour of failure_mode_allow for external authz grpc servers. +RUNTIME_GUARD(envoy_reloadable_features_process_ext_authz_grpc_error_codes_as_errors); RUNTIME_GUARD(envoy_reloadable_features_proxy_104); RUNTIME_GUARD(envoy_reloadable_features_proxy_status_mapping_more_core_response_flags); RUNTIME_GUARD(envoy_reloadable_features_quic_fix_filter_manager_uaf); diff --git a/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.cc b/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.cc index dab5d014d109..22b72b803224 100644 --- a/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.cc +++ b/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.cc @@ -114,7 +114,11 @@ void GrpcClientImpl::onSuccess(std::unique_ptrok_response(); copyOkResponseMutations(authz_response, ok_response); } - } else { + } else if (response->status().code() == Grpc::Status::WellKnownGrpcStatus::PermissionDenied || + response->status().code() == Grpc::Status::WellKnownGrpcStatus::Unauthenticated || + !Runtime::runtimeFeatureEnabled( + "envoy.reloadable_features.process_ext_authz_grpc_error_codes_as_errors")) { + // The request was explicitly forbidden by the external authz server. span.setTag(TracingConstants::get().TraceStatus, TracingConstants::get().TraceUnauthz); authz_response->status = CheckStatus::Denied; @@ -129,6 +133,12 @@ void GrpcClientImpl::onSuccess(std::unique_ptrbody = response->denied_response().body(); } + } else { + // Unexpected response from external authz server is interpreted as failure + ENVOY_LOG(trace, "CheckRequest call failed with status: {}", + Grpc::Utility::grpcStatusToString(response->status().code())); + authz_response->status = CheckStatus::Error; + authz_response->status_code = Http::Code::Forbidden; } // OkHttpResponse.dynamic_metadata is deprecated. Until OkHttpResponse.dynamic_metadata is diff --git a/test/extensions/filters/common/ext_authz/BUILD b/test/extensions/filters/common/ext_authz/BUILD index 931e9f56d3b2..b4d802beb974 100644 --- a/test/extensions/filters/common/ext_authz/BUILD +++ b/test/extensions/filters/common/ext_authz/BUILD @@ -36,6 +36,7 @@ envoy_cc_test( "//source/extensions/filters/common/ext_authz:ext_authz_grpc_lib", "//test/extensions/filters/common/ext_authz:ext_authz_test_common", "//test/mocks/tracing:tracing_mocks", + "//test/test_common:test_runtime_lib", "@envoy_api//envoy/service/auth/v3:pkg_cc_proto", "@envoy_api//envoy/type/v3:pkg_cc_proto", ], diff --git a/test/extensions/filters/common/ext_authz/ext_authz_grpc_impl_test.cc b/test/extensions/filters/common/ext_authz/ext_authz_grpc_impl_test.cc index a7832ddeda2a..cec883ca7506 100644 --- a/test/extensions/filters/common/ext_authz/ext_authz_grpc_impl_test.cc +++ b/test/extensions/filters/common/ext_authz/ext_authz_grpc_impl_test.cc @@ -11,6 +11,7 @@ #include "test/mocks/grpc/mocks.h" #include "test/mocks/stream_info/mocks.h" #include "test/mocks/tracing/mocks.h" +#include "test/test_common/test_runtime.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -179,30 +180,6 @@ TEST_F(ExtAuthzGrpcClientTest, AuthorizationDenied) { client_->onSuccess(std::move(check_response), span_); } -// Test the client when a gRPC status code unknown is received from the authorization server. -TEST_F(ExtAuthzGrpcClientTest, AuthorizationDeniedGrpcUnknownStatus) { - initialize(); - - auto check_response = std::make_unique(); - auto status = check_response->mutable_status(); - status->set_code(Grpc::Status::WellKnownGrpcStatus::Unknown); - auto authz_response = Response{}; - authz_response.status = CheckStatus::Denied; - - envoy::service::auth::v3::CheckRequest request; - expectCallSend(request); - client_->check(request_callbacks_, request, Tracing::NullSpan::instance(), stream_info_); - - Http::TestRequestHeaderMapImpl headers; - client_->onCreateInitialMetadata(headers); - EXPECT_EQ(nullptr, headers.RequestId()); - EXPECT_CALL(span_, setTag(Eq("ext_authz_status"), Eq("ext_authz_unauthorized"))); - EXPECT_CALL(request_callbacks_, onComplete_(WhenDynamicCastTo( - AuthzResponseNoAttributes(authz_response)))); - - client_->onSuccess(std::move(check_response), span_); -} - // Test the client when a denied response with additional HTTP attributes is received. TEST_F(ExtAuthzGrpcClientTest, AuthorizationDeniedWithAllAttributes) { initialize(); @@ -437,6 +414,72 @@ TEST_F(ExtAuthzGrpcClientTest, AuthorizationOkWithAppendActions) { span_); } +// Test the client when an error code response is received. +TEST_F(ExtAuthzGrpcClientTest, AuthorizationReturnsErrorOnBadGrpcCode) { + initialize(); + + auto check_response = std::make_unique(); + auto status = check_response->mutable_status(); + + ProtobufWkt::Struct expected_dynamic_metadata; + auto* metadata_fields = expected_dynamic_metadata.mutable_fields(); + (*metadata_fields)["foo"] = ValueUtil::stringValue("ok"); + (*metadata_fields)["bar"] = ValueUtil::numberValue(1); + + // The expected dynamic metadata is set to the outer check response, hence regardless the + // check_response's http_response value (either OkHttpResponse or DeniedHttpResponse) the dynamic + // metadata is set to be equal to the check response's dynamic metadata. + check_response->mutable_dynamic_metadata()->MergeFrom(expected_dynamic_metadata); + + status->set_code(Grpc::Status::WellKnownGrpcStatus::Unavailable); + + // This is the expected authz response. + auto authz_response = Response{}; + authz_response.status = CheckStatus::Error; + + authz_response.dynamic_metadata = expected_dynamic_metadata; + + envoy::service::auth::v3::CheckRequest request; + expectCallSend(request); + client_->check(request_callbacks_, request, Tracing::NullSpan::instance(), stream_info_); + + Http::TestRequestHeaderMapImpl headers; + client_->onCreateInitialMetadata(headers); + + EXPECT_CALL(request_callbacks_, onComplete_(WhenDynamicCastTo( + AuthzResponseNoAttributes(authz_response)))); + client_->onSuccess(std::move(check_response), span_); +} + +// Test the client when an error code response is received and +// process_ext_authz_grpc_error_codes_as_errors is false. +TEST_F(ExtAuthzGrpcClientTest, AuthorizationReturnsDeniedOnUnknownGrpcCodeWhenFeatureFlagDisabled) { + TestScopedRuntime scoped_runtime; + scoped_runtime.mergeValues( + {{"envoy.reloadable_features.process_ext_authz_grpc_error_codes_as_errors", "false"}}); + + initialize(); + + auto check_response = std::make_unique(); + auto status = check_response->mutable_status(); + status->set_code(Grpc::Status::WellKnownGrpcStatus::Unknown); + auto authz_response = Response{}; + authz_response.status = CheckStatus::Denied; + + envoy::service::auth::v3::CheckRequest request; + expectCallSend(request); + client_->check(request_callbacks_, request, Tracing::NullSpan::instance(), stream_info_); + + Http::TestRequestHeaderMapImpl headers; + client_->onCreateInitialMetadata(headers); + EXPECT_EQ(nullptr, headers.RequestId()); + EXPECT_CALL(span_, setTag(Eq("ext_authz_status"), Eq("ext_authz_unauthorized"))); + EXPECT_CALL(request_callbacks_, onComplete_(WhenDynamicCastTo( + AuthzResponseNoAttributes(authz_response)))); + + client_->onSuccess(std::move(check_response), span_); +} + } // namespace ExtAuthz } // namespace Common } // namespace Filters From ff6ced12ef202a18f94186da898ea10329b618e9 Mon Sep 17 00:00:00 2001 From: "Antonio V. Leonti" <53806445+antoniovleonti@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:02:21 -0400 Subject: [PATCH 19/26] ext_authz: filter state access logging stats PREP (#34945) Adds a temporarily unused ExtAuthzLoggingInfo to store stats in filter status. Also adds a field to ext_authz config which will populate a filter_metadata field in the ExtAuthzLoggingInfo. Signed-off-by: antoniovleonti --- .../filters/http/ext_authz/v3/ext_authz.proto | 8 ++- changelogs/current.yaml | 5 ++ .../filters/http/ext_authz/ext_authz.cc | 11 +++ .../filters/http/ext_authz/ext_authz.h | 14 ++++ .../filters/http/ext_authz/ext_authz_test.cc | 68 +++++++++++++++++++ 5 files changed, 105 insertions(+), 1 deletion(-) diff --git a/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto b/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto index 7619d7ba5097..357dd5fc645a 100644 --- a/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto +++ b/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto @@ -11,6 +11,7 @@ import "envoy/type/matcher/v3/metadata.proto"; import "envoy/type/matcher/v3/string.proto"; import "envoy/type/v3/http_status.proto"; +import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; import "envoy/annotations/deprecation.proto"; @@ -29,7 +30,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // External Authorization :ref:`configuration overview `. // [#extension: envoy.filters.http.ext_authz] -// [#next-free-field: 28] +// [#next-free-field: 29] message ExtAuthz { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.http.ext_authz.v3.ExtAuthz"; @@ -291,6 +292,11 @@ message ExtAuthz { // // If unset, defaults to true. google.protobuf.BoolValue enable_dynamic_metadata_ingestion = 27; + + // Additional metadata to be added to the filter state for logging purposes. The metadata will be + // added to StreamInfo's filter state under the namespace corresponding to the ext_authz filter + // name. + google.protobuf.Struct filter_metadata = 28; } // Configuration for buffering the request data. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index fdcb91be6d49..b23e1b7bd022 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -30,5 +30,10 @@ removed_config_or_runtime: path. new_features: +- area: ext_authz + change: | + Added config field + :ref:`filter_metadata ` + for injecting arbitrary data to the filter state for logging. deprecated: diff --git a/source/extensions/filters/http/ext_authz/ext_authz.cc b/source/extensions/filters/http/ext_authz/ext_authz.cc index 470dcbd5e2fb..d301d12689c8 100644 --- a/source/extensions/filters/http/ext_authz/ext_authz.cc +++ b/source/extensions/filters/http/ext_authz/ext_authz.cc @@ -87,6 +87,8 @@ FilterConfig::FilterConfig(const envoy::extensions::filters::http::ext_authz::v3 enable_dynamic_metadata_ingestion_( PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, enable_dynamic_metadata_ingestion, true)), runtime_(factory_context.runtime()), http_context_(factory_context.httpContext()), + filter_metadata_(config.has_filter_metadata() ? absl::optional(config.filter_metadata()) + : absl::nullopt), filter_enabled_(config.has_filter_enabled() ? absl::optional( Runtime::FractionalPercent(config.filter_enabled(), runtime_)) @@ -376,6 +378,15 @@ Http::FilterMetadataStatus Filter::encodeMetadata(Http::MetadataMap&) { void Filter::setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) { decoder_callbacks_ = &callbacks; + const Envoy::StreamInfo::FilterStateSharedPtr& filter_state = + decoder_callbacks_->streamInfo().filterState(); + if (config_->filterMetadata().has_value() && + !filter_state->hasData(decoder_callbacks_->filterConfigName())) { + filter_state->setData(decoder_callbacks_->filterConfigName(), + std::make_shared(*config_->filterMetadata()), + Envoy::StreamInfo::FilterState::StateType::ReadOnly, + Envoy::StreamInfo::FilterState::LifeSpan::Request); + } } void Filter::setEncoderFilterCallbacks(Http::StreamEncoderFilterCallbacks& callbacks) { diff --git a/source/extensions/filters/http/ext_authz/ext_authz.h b/source/extensions/filters/http/ext_authz/ext_authz.h index fe1cb103789c..5e740e6dfb7d 100644 --- a/source/extensions/filters/http/ext_authz/ext_authz.h +++ b/source/extensions/filters/http/ext_authz/ext_authz.h @@ -51,6 +51,17 @@ struct ExtAuthzFilterStats { ALL_EXT_AUTHZ_FILTER_STATS(GENERATE_COUNTER_STRUCT) }; +class ExtAuthzLoggingInfo : public Envoy::StreamInfo::FilterState::Object { +public: + explicit ExtAuthzLoggingInfo(const Envoy::ProtobufWkt::Struct& filter_metadata) + : filter_metadata_(filter_metadata) {} + + const ProtobufWkt::Struct& filterMetadata() const { return filter_metadata_; } + +private: + const Envoy::ProtobufWkt::Struct filter_metadata_; +}; + /** * Configuration for the External Authorization (ext_authz) filter. */ @@ -139,6 +150,8 @@ class FilterConfig { bool includeTLSSession() const { return include_tls_session_; } const LabelsMap& destinationLabels() const { return destination_labels_; } + const absl::optional& filterMetadata() const { return filter_metadata_; } + bool chargeClusterResponseStats() const { return charge_cluster_response_stats_; } const Filters::Common::ExtAuthz::MatcherSharedPtr& allowedHeadersMatcher() const { @@ -189,6 +202,7 @@ class FilterConfig { Runtime::Loader& runtime_; Http::Context& http_context_; LabelsMap destination_labels_; + const absl::optional filter_metadata_; const absl::optional filter_enabled_; const absl::optional filter_enabled_metadata_; diff --git a/test/extensions/filters/http/ext_authz/ext_authz_test.cc b/test/extensions/filters/http/ext_authz/ext_authz_test.cc index c63186f01929..7559128d07cf 100644 --- a/test/extensions/filters/http/ext_authz/ext_authz_test.cc +++ b/test/extensions/filters/http/ext_authz/ext_authz_test.cc @@ -53,6 +53,8 @@ namespace HttpFilters { namespace ExtAuthz { namespace { +constexpr char FilterConfigName[] = "ext_authz_filter"; + template class HttpFilterTestBase : public T { public: HttpFilterTestBase() {} @@ -70,6 +72,7 @@ template class HttpFilterTestBase : public T { "ext_authz_prefix", factory_context_); client_ = new Filters::Common::ExtAuthz::MockClient(); filter_ = std::make_unique(config_, Filters::Common::ExtAuthz::ClientPtr{client_}); + ON_CALL(decoder_filter_callbacks_, filterConfigName()).WillByDefault(Return(FilterConfigName)); filter_->setDecoderFilterCallbacks(decoder_filter_callbacks_); filter_->setEncoderFilterCallbacks(encoder_filter_callbacks_); addr_ = std::make_shared("1.2.3.4", 1111); @@ -2926,6 +2929,71 @@ TEST_P(HttpFilterTestParam, ImmediateOkResponse) { EXPECT_EQ(1U, config_->stats().ok_.value()); } +TEST_F(HttpFilterTest, LoggingInfoOK) { + InSequence s; + + initialize(R"EOF( + grpc_service: + envoy_grpc: + cluster_name: "ext_authz_server" + filter_metadata: + foo: "bar" + )EOF"); + + prepareCheck(); + + Filters::Common::ExtAuthz::Response response{}; + response.status = Filters::Common::ExtAuthz::CheckStatus::OK; + + EXPECT_CALL(*client_, check(_, _, _, _)) + .WillOnce(Invoke([&](Filters::Common::ExtAuthz::RequestCallbacks& callbacks, + const envoy::service::auth::v3::CheckRequest&, Tracing::Span&, + const StreamInfo::StreamInfo&) -> void { + callbacks.onComplete(std::make_unique(response)); + })); + EXPECT_CALL(decoder_filter_callbacks_, continueDecoding()).Times(0); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); + + auto filter_state = decoder_filter_callbacks_.streamInfo().filterState(); + ASSERT_TRUE(filter_state->hasData(FilterConfigName)); + + auto logging_info = filter_state->getDataReadOnly(FilterConfigName); + ASSERT_TRUE(logging_info->filterMetadata().fields().contains("foo")); + EXPECT_EQ(logging_info->filterMetadata().fields().at("foo").string_value(), "bar"); +} + +// Test that if no filter metadata is configured, filter state is not added to stream info. +TEST_F(HttpFilterTest, LoggingInfoEmpty) { + InSequence s; + + initialize(R"EOF( + grpc_service: + envoy_grpc: + cluster_name: "ext_authz_server" + )EOF"); + + prepareCheck(); + + Filters::Common::ExtAuthz::Response response{}; + response.status = Filters::Common::ExtAuthz::CheckStatus::OK; + + EXPECT_CALL(*client_, check(_, _, _, _)) + .WillOnce(Invoke([&](Filters::Common::ExtAuthz::RequestCallbacks& callbacks, + const envoy::service::auth::v3::CheckRequest&, Tracing::Span&, + const StreamInfo::StreamInfo&) -> void { + callbacks.onComplete(std::make_unique(response)); + })); + EXPECT_CALL(decoder_filter_callbacks_, continueDecoding()).Times(0); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); + + auto filter_state = decoder_filter_callbacks_.streamInfo().filterState(); + EXPECT_FALSE(filter_state->hasData(FilterConfigName)); +} + // Test that an synchronous denied response from the authorization service passing additional HTTP // attributes to the downstream. TEST_P(HttpFilterTestParam, ImmediateDeniedResponseWithHttpAttributes) { From c3241e42bc6695b5e08a1319ad4be563cb745064 Mon Sep 17 00:00:00 2001 From: yanjunxiang-google <78807980+yanjunxiang-google@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:42:24 -0400 Subject: [PATCH 20/26] Remove runtime flag envoy_reloadable_features_dns_cache_set_first_resolve_complete (#35379) Fixes: https://github.com/envoyproxy/envoy/issues/35367 Risk Level: low Testing: n/a Docs Changes: n/a Release Notes: inline Signed-off-by: Yanjun Xiang --- changelogs/current.yaml | 3 +++ source/common/runtime/runtime_features.cc | 1 - .../common/dynamic_forward_proxy/dns_cache_impl.cc | 5 +---- .../extensions/common/dynamic_forward_proxy/dns_cache_impl.h | 4 ---- .../common/dynamic_forward_proxy/dns_cache_impl_test.cc | 4 ---- 5 files changed, 4 insertions(+), 13 deletions(-) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index b23e1b7bd022..e625fe665676 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -28,6 +28,9 @@ removed_config_or_runtime: change: | Removed runtime flag ``envoy.reloadable_features.no_downgrade_to_canonical_name`` and legacy code path. +- area: DNS + change: | + Removed ``envoy.reloadable_features.dns_cache_set_first_resolve_complete`` runtime flag and legacy code paths. new_features: - area: ext_authz diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index 4fe38e851ebe..11e4fe070f7b 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -37,7 +37,6 @@ RUNTIME_GUARD(envoy_reloadable_features_consistent_header_validation); RUNTIME_GUARD(envoy_reloadable_features_defer_processing_backedup_streams); RUNTIME_GUARD(envoy_reloadable_features_dfp_mixed_scheme); RUNTIME_GUARD(envoy_reloadable_features_disallow_quic_client_udp_mmsg); -RUNTIME_GUARD(envoy_reloadable_features_dns_cache_set_first_resolve_complete); RUNTIME_GUARD(envoy_reloadable_features_dns_details); RUNTIME_GUARD(envoy_reloadable_features_dns_nodata_noname_is_success); RUNTIME_GUARD(envoy_reloadable_features_dns_reresolve_on_eai_again); diff --git a/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc b/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc index d5c315712e15..99b7efcc5b4e 100644 --- a/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc +++ b/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc @@ -465,10 +465,7 @@ void DnsCacheImpl::finishResolve(const std::string& host, primary_host_info->host_info_->setDetails(std::string(details)); runAddUpdateCallbacks(host, primary_host_info->host_info_); - if (Runtime::runtimeFeatureEnabled( - "envoy.reloadable_features.dns_cache_set_first_resolve_complete")) { - primary_host_info->host_info_->setFirstResolveComplete(); - } + primary_host_info->host_info_->setFirstResolveComplete(); address_changed = true; stats_.host_address_changed_.inc(); } else if (current_address == nullptr) { diff --git a/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.h b/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.h index 7d6d059a2790..a521d14ec458 100644 --- a/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.h +++ b/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.h @@ -140,10 +140,6 @@ class DnsCacheImpl : public DnsCache, Logger::Loggable&& list) { absl::WriterMutexLock lock{&resolve_lock_}; - if (!(Runtime::runtimeFeatureEnabled( - "envoy.reloadable_features.dns_cache_set_first_resolve_complete"))) { - first_resolve_complete_ = true; - } address_ = address; address_list_ = std::move(list); } diff --git a/test/extensions/common/dynamic_forward_proxy/dns_cache_impl_test.cc b/test/extensions/common/dynamic_forward_proxy/dns_cache_impl_test.cc index ae2d4f2d1b9c..4e44b403ebc0 100644 --- a/test/extensions/common/dynamic_forward_proxy/dns_cache_impl_test.cc +++ b/test/extensions/common/dynamic_forward_proxy/dns_cache_impl_test.cc @@ -191,10 +191,6 @@ TEST_P(DnsCacheImplPreresolveTest, PreresolveFailure) { } TEST_F(DnsCacheImplTest, DnsFirstResolveComplete) { - // This test relies on below runtime flag to be true. - TestScopedRuntime scoped_runtime; - scoped_runtime.mergeValues( - {{"envoy.reloadable_features.dns_cache_set_first_resolve_complete", "true"}}); Network::DnsResolver::ResolveCb resolve_cb; std::string hostname = "bar.baz.com:443"; EXPECT_CALL(*resolver_, resolve("bar.baz.com", _, _)) From 226942b4858699c38605567f8d3b70927a19cc96 Mon Sep 17 00:00:00 2001 From: Arul Thileeban Sagayam Date: Tue, 23 Jul 2024 16:51:18 -0400 Subject: [PATCH 21/26] tls: add enable_client_cipher_preference option (#35106) Fixes #34604 Signed-off-by: Arul Thileeban Sagayam --- .../transport_sockets/tls/v3/tls.proto | 7 ++- changelogs/current.yaml | 5 ++ envoy/ssl/context_config.h | 5 ++ source/common/tls/context_impl.cc | 5 -- .../common/tls/server_context_config_impl.cc | 3 +- .../common/tls/server_context_config_impl.h | 2 + source/common/tls/server_context_impl.cc | 5 ++ test/common/tls/BUILD | 2 + test/common/tls/context_impl_test.cc | 51 +++++++++++++++++++ test/common/tls/handshaker_factory_test.cc | 9 +--- .../tls/integration/ssl_integration_test.cc | 38 ++++++++++++++ .../integration/ssl_integration_test_base.cc | 2 + .../integration/ssl_integration_test_base.h | 2 + test/common/tls/ssl_test_utility.h | 10 ++++ test/config/utility.cc | 5 ++ test/config/utility.h | 12 +++++ test/mocks/ssl/mocks.h | 1 + 17 files changed, 149 insertions(+), 15 deletions(-) diff --git a/api/envoy/extensions/transport_sockets/tls/v3/tls.proto b/api/envoy/extensions/transport_sockets/tls/v3/tls.proto index 9d465c973210..c22d580e6f5d 100644 --- a/api/envoy/extensions/transport_sockets/tls/v3/tls.proto +++ b/api/envoy/extensions/transport_sockets/tls/v3/tls.proto @@ -63,7 +63,7 @@ message UpstreamTlsContext { google.protobuf.BoolValue enforce_rsa_key_usage = 5; } -// [#next-free-field: 11] +// [#next-free-field: 12] message DownstreamTlsContext { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.DownstreamTlsContext"; @@ -140,6 +140,11 @@ message DownstreamTlsContext { // If the client provides SNI but no such cert matched, it will decide to full scan certificates or not based on this config. // Defaults to false. See more details in :ref:`Multiple TLS certificates `. google.protobuf.BoolValue full_scan_certs_on_sni_mismatch = 9; + + // By default, Envoy as a server uses its preferred cipher during the handshake. + // Setting this to true would allow the downstream client's preferred cipher to be used instead. + // Has no effect when using TLSv1_3. + bool prefer_client_ciphers = 11; } // TLS key log configuration. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index e625fe665676..7147c211c781 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -33,6 +33,11 @@ removed_config_or_runtime: Removed ``envoy.reloadable_features.dns_cache_set_first_resolve_complete`` runtime flag and legacy code paths. new_features: +- area: tls + change: | + Added :ref:`prefer_client_ciphers + ` + to support enabling client cipher preference instead of server's for TLS handshakes. - area: ext_authz change: | Added config field diff --git a/envoy/ssl/context_config.h b/envoy/ssl/context_config.h index 87c26f0250d0..a247c71533ad 100644 --- a/envoy/ssl/context_config.h +++ b/envoy/ssl/context_config.h @@ -199,6 +199,11 @@ class ServerContextConfig : public virtual ContextConfig { * downstream TLS handshake, false otherwise. */ virtual bool fullScanCertsOnSNIMismatch() const PURE; + + /** + * @return true if the client cipher preference is enabled, false otherwise. + */ + virtual bool preferClientCiphers() const PURE; }; using ServerContextConfigPtr = std::unique_ptr; diff --git a/source/common/tls/context_impl.cc b/source/common/tls/context_impl.cc index 29bdc17c0b6a..8e997df07399 100644 --- a/source/common/tls/context_impl.cc +++ b/source/common/tls/context_impl.cc @@ -308,11 +308,6 @@ ContextImpl::ContextImpl(Stats::Scope& scope, const Envoy::Ssl::ContextConfig& c } } - // use the server's cipher list preferences - for (auto& ctx : tls_contexts_) { - SSL_CTX_set_options(ctx.ssl_ctx_.get(), SSL_OP_CIPHER_SERVER_PREFERENCE); - } - parsed_alpn_protocols_ = parseAlpnProtocols(config.alpnProtocols(), creation_status); SET_AND_RETURN_IF_NOT_OK(creation_status, creation_status); diff --git a/source/common/tls/server_context_config_impl.cc b/source/common/tls/server_context_config_impl.cc index bfd611dbdb60..e40ebd9d15ce 100644 --- a/source/common/tls/server_context_config_impl.cc +++ b/source/common/tls/server_context_config_impl.cc @@ -123,7 +123,8 @@ ServerContextConfigImpl::ServerContextConfigImpl( disable_stateless_session_resumption_(getStatelessSessionResumptionDisabled(config)), disable_stateful_session_resumption_(config.disable_stateful_session_resumption()), full_scan_certs_on_sni_mismatch_( - PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, full_scan_certs_on_sni_mismatch, false)) { + PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, full_scan_certs_on_sni_mismatch, false)), + prefer_client_ciphers_(config.prefer_client_ciphers()) { SET_AND_RETURN_IF_NOT_OK(creation_status, creation_status); if (session_ticket_keys_provider_ != nullptr) { // Validate tls session ticket keys early to reject bad sds updates. diff --git a/source/common/tls/server_context_config_impl.h b/source/common/tls/server_context_config_impl.h index 5cacbbb0d438..b11ddba70802 100644 --- a/source/common/tls/server_context_config_impl.h +++ b/source/common/tls/server_context_config_impl.h @@ -40,6 +40,7 @@ class ServerContextConfigImpl : public ContextConfigImpl, public Envoy::Ssl::Ser } bool fullScanCertsOnSNIMismatch() const override { return full_scan_certs_on_sni_mismatch_; } + bool preferClientCiphers() const override { return prefer_client_ciphers_; } private: ServerContextConfigImpl( @@ -71,6 +72,7 @@ class ServerContextConfigImpl : public ContextConfigImpl, public Envoy::Ssl::Ser const bool disable_stateless_session_resumption_; const bool disable_stateful_session_resumption_; bool full_scan_certs_on_sni_mismatch_; + const bool prefer_client_ciphers_; }; } // namespace Tls diff --git a/source/common/tls/server_context_impl.cc b/source/common/tls/server_context_impl.cc index 00b6d7051057..b7ac27c718a6 100644 --- a/source/common/tls/server_context_impl.cc +++ b/source/common/tls/server_context_impl.cc @@ -159,6 +159,11 @@ ServerContextImpl::ServerContextImpl(Stats::Scope& scope, this); } + if (!config.preferClientCiphers()) { + // Use server cipher preference based on config. + SSL_CTX_set_options(ctx.ssl_ctx_.get(), SSL_OP_CIPHER_SERVER_PREFERENCE); + } + // If the handshaker handles session tickets natively, don't call // `SSL_CTX_set_tlsext_ticket_key_cb`. if (config.disableStatelessSessionResumption()) { diff --git a/test/common/tls/BUILD b/test/common/tls/BUILD index 464ad5b8c79f..af168e029f10 100644 --- a/test/common/tls/BUILD +++ b/test/common/tls/BUILD @@ -145,6 +145,7 @@ envoy_cc_test_library( "ssl_test_utility.h", ], deps = [ + "//source/common/tls:ssl_socket_lib", "//source/common/tls:utility_lib", "//test/test_common:environment_lib", ], @@ -197,6 +198,7 @@ envoy_cc_test( name = "handshaker_factory_test", srcs = ["handshaker_factory_test.cc"], deps = [ + ":ssl_test_utils", "//source/common/stream_info:stream_info_lib", "//source/common/tls:context_lib", "//source/common/tls:server_context_config_lib", diff --git a/test/common/tls/context_impl_test.cc b/test/common/tls/context_impl_test.cc index 04c7bfd82aca..0bbd94dbd4ae 100644 --- a/test/common/tls/context_impl_test.cc +++ b/test/common/tls/context_impl_test.cc @@ -13,6 +13,7 @@ #include "source/common/tls/context_config_impl.h" #include "source/common/tls/context_impl.h" #include "source/common/tls/server_context_config_impl.h" +#include "source/common/tls/server_ssl_socket.h" #include "source/common/tls/utility.h" #include "test/common/tls/ssl_certs_test.h" @@ -141,6 +142,56 @@ TEST_F(SslContextImplTest, TestCipherSuites) { "ciphers were rejected when tried individually: BOGUS1-SHA256, BOGUS2-SHA"); } +// Envoy's default cipher preference is server's. +TEST_F(SslContextImplTest, TestServerCipherPreference) { + const std::string yaml = R"EOF( + common_tls_context: + tls_certificates: + certificate_chain: + filename: "{{ test_rundir }}/test/common/tls/test_data/unittest_cert.pem" + private_key: + filename: "{{ test_rundir }}/test/common/tls/test_data/unittest_key.pem" + )EOF"; + + envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext tls_context; + TestUtility::loadFromYaml(TestEnvironment::substitute(yaml), tls_context); + auto cfg = ServerContextConfigImpl::create(tls_context, factory_context_).value(); + ASSERT_FALSE(cfg.get()->preferClientCiphers()); + + auto socket_factory = *Extensions::TransportSockets::Tls::ServerSslSocketFactory::create( + std::move(cfg), manager_, *store_.rootScope(), {}); + std::unique_ptr socket = + socket_factory->createDownstreamTransportSocket(); + SSL_CTX* ssl_ctx = extractSslCtx(socket.get()); + + EXPECT_TRUE(SSL_CTX_get_options(ssl_ctx) & SSL_OP_CIPHER_SERVER_PREFERENCE); +} + +TEST_F(SslContextImplTest, TestPreferClientCiphers) { + const std::string yaml = R"EOF( + common_tls_context: + tls_certificates: + certificate_chain: + filename: "{{ test_rundir }}/test/common/tls/test_data/unittest_cert.pem" + private_key: + filename: "{{ test_rundir }}/test/common/tls/test_data/unittest_key.pem" + prefer_client_ciphers: true + )EOF"; + + envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext tls_context; + TestUtility::loadFromYaml(TestEnvironment::substitute(yaml), tls_context); + auto cfg = ServerContextConfigImpl::create(tls_context, factory_context_).value(); + ASSERT_TRUE(cfg.get()->preferClientCiphers()); + + auto socket_factory = *Extensions::TransportSockets::Tls::ServerSslSocketFactory::create( + std::move(cfg), manager_, *store_.rootScope(), {}); + std::unique_ptr socket = + socket_factory->createDownstreamTransportSocket(); + SSL_CTX* ssl_ctx = extractSslCtx(socket.get()); + + EXPECT_FALSE(SSL_CTX_get_options(ssl_ctx) & SSL_OP_CIPHER_SERVER_PREFERENCE); +} + TEST_F(SslContextImplTest, TestExpiringCert) { const std::string yaml = R"EOF( common_tls_context: diff --git a/test/common/tls/handshaker_factory_test.cc b/test/common/tls/handshaker_factory_test.cc index aac0aef2b407..a22f85832321 100644 --- a/test/common/tls/handshaker_factory_test.cc +++ b/test/common/tls/handshaker_factory_test.cc @@ -11,6 +11,7 @@ #include "source/common/tls/ssl_handshaker.h" #include "source/server/process_context_impl.h" +#include "test/common/tls/ssl_test_utility.h" #include "test/mocks/network/connection.h" #include "test/mocks/server/transport_socket_factory_context.h" #include "test/test_common/registry.h" @@ -105,14 +106,6 @@ class HandshakerFactoryTest : public testing::Test { custom_handshaker->mutable_typed_config()->PackFrom(ProtobufWkt::StringValue()); } - // Helper for downcasting a socket to a test socket so we can examine its - // SSL_CTX. - SSL_CTX* extractSslCtx(Network::TransportSocket* socket) { - SslSocket* ssl_socket = dynamic_cast(socket); - SSL* ssl = ssl_socket->rawSslForTest(); - return SSL_get_SSL_CTX(ssl); - } - NiceMock server_factory_context_; Stats::IsolatedStoreImpl stats_store_; std::unique_ptr context_manager_; diff --git a/test/common/tls/integration/ssl_integration_test.cc b/test/common/tls/integration/ssl_integration_test.cc index fd2e6e844381..4ad8d5867935 100644 --- a/test/common/tls/integration/ssl_integration_test.cc +++ b/test/common/tls/integration/ssl_integration_test.cc @@ -275,6 +275,44 @@ TEST_P(SslIntegrationTest, RouterDownstreamDisconnectBeforeResponseComplete) { checkStats(); } +// Test server preference of cipher suites. Server order is ECDHE-RSA-AES128-GCM-SHA256 +// followed by ECDHE-RSA-AES256-GCM-SHA384. "ECDHE-RSA-AES128-GCM-SHA256" should be used based on +// server preference. +TEST_P(SslIntegrationTest, TestServerCipherPreference) { + server_ciphers_.push_back("ECDHE-RSA-AES128-GCM-SHA256"); + server_ciphers_.push_back("ECDHE-RSA-AES256-GCM-SHA384"); + initialize(); + codec_client_ = makeHttpConnection(makeSslClientConnection( + ClientSslTransportOptions{} + .setTlsVersion(envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_2) + .setCipherSuites({"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"}))); + auto response = + sendRequestAndWaitForResponse(default_request_headers_, 0, default_response_headers_, 0); + + const std::string counter_name = listenerStatPrefix("ssl.ciphers.ECDHE-RSA-AES128-GCM-SHA256"); + Stats::CounterSharedPtr counter = test_server_->counter(counter_name); + EXPECT_EQ(1, test_server_->counter(counter_name)->value()); +} + +// Test client preference of cipher suites. Same server preference is followed as in the previous. +// "ECDHE-RSA-AES256-GCM-SHA384" should be used based on client preference. +TEST_P(SslIntegrationTest, ClientCipherPreference) { + prefer_client_ciphers_ = true; + server_ciphers_.push_back("ECDHE-RSA-AES128-GCM-SHA256"); + server_ciphers_.push_back("ECDHE-RSA-AES256-GCM-SHA384"); + initialize(); + codec_client_ = makeHttpConnection(makeSslClientConnection( + ClientSslTransportOptions{} + .setTlsVersion(envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_2) + .setCipherSuites({"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"}))); + auto response = + sendRequestAndWaitForResponse(default_request_headers_, 0, default_response_headers_, 0); + + const std::string counter_name = listenerStatPrefix("ssl.ciphers.ECDHE-RSA-AES256-GCM-SHA384"); + Stats::CounterSharedPtr counter = test_server_->counter(counter_name); + EXPECT_EQ(1, test_server_->counter(counter_name)->value()); +} + // This test must be here vs integration_admin_test so that it tests a server with loaded certs. TEST_P(SslIntegrationTest, AdminCertEndpoint) { DISABLE_IF_ADMIN_DISABLED; // Admin functionality. diff --git a/test/common/tls/integration/ssl_integration_test_base.cc b/test/common/tls/integration/ssl_integration_test_base.cc index 2a89ffee0972..0539b833a9c2 100644 --- a/test/common/tls/integration/ssl_integration_test_base.cc +++ b/test/common/tls/integration/ssl_integration_test_base.cc @@ -10,8 +10,10 @@ void SslIntegrationTestBase::initialize() { .setEcdsaCert(server_ecdsa_cert_) .setEcdsaCertOcspStaple(server_ecdsa_cert_ocsp_staple_) .setOcspStapleRequired(ocsp_staple_required_) + .setPreferClientCiphers(prefer_client_ciphers_) .setTlsV13(server_tlsv1_3_) .setCurves(server_curves_) + .setCiphers(server_ciphers_) .setExpectClientEcdsaCert(client_ecdsa_cert_) .setTlsKeyLogFilter(keylog_local_, keylog_remote_, keylog_local_negative_, diff --git a/test/common/tls/integration/ssl_integration_test_base.h b/test/common/tls/integration/ssl_integration_test_base.h index 63366d2d1ff9..31bbda465023 100644 --- a/test/common/tls/integration/ssl_integration_test_base.h +++ b/test/common/tls/integration/ssl_integration_test_base.h @@ -31,11 +31,13 @@ class SslIntegrationTestBase : public HttpIntegrationTest { protected: bool server_tlsv1_3_{false}; std::vector server_curves_; + std::vector server_ciphers_; bool server_rsa_cert_{true}; bool server_rsa_cert_ocsp_staple_{false}; bool server_ecdsa_cert_{false}; bool server_ecdsa_cert_ocsp_staple_{false}; bool ocsp_staple_required_{false}; + bool prefer_client_ciphers_{false}; bool client_ecdsa_cert_{false}; // Set this true to debug SSL handshake issues with openssl s_client. The // verbose trace will be in the logs, openssl must be installed separately. diff --git a/test/common/tls/ssl_test_utility.h b/test/common/tls/ssl_test_utility.h index a8bf453ed50a..e437ad970b0c 100644 --- a/test/common/tls/ssl_test_utility.h +++ b/test/common/tls/ssl_test_utility.h @@ -3,6 +3,8 @@ #include #include +#include "source/common/tls/ssl_socket.h" + #include "test/test_common/environment.h" #include "gtest/gtest.h" @@ -36,6 +38,14 @@ inline bssl::UniquePtr readCertChainFromFile(const std::string& return certChain; } +// Helper for downcasting a socket to a test socket so we can examine its +// SSL_CTX. +SSL_CTX* extractSslCtx(Network::TransportSocket* socket) { + SslSocket* ssl_socket = dynamic_cast(socket); + SSL* ssl = ssl_socket->rawSslForTest(); + return SSL_get_SSL_CTX(ssl); +} + } // namespace Tls } // namespace TransportSockets } // namespace Extensions diff --git a/test/config/utility.cc b/test/config/utility.cc index ca67cec4274b..0f908a434394 100644 --- a/test/config/utility.cc +++ b/test/config/utility.cc @@ -1315,6 +1315,7 @@ void ConfigHelper::addSslConfig(const ServerSslOptions& options) { tls_context.set_ocsp_staple_policy( envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::MUST_STAPLE); } + tls_context.set_prefer_client_ciphers(options.prefer_client_ciphers_); filter_chain->mutable_transport_socket()->set_name("envoy.transport_sockets.tls"); filter_chain->mutable_transport_socket()->mutable_typed_config()->PackFrom(tls_context); } @@ -1506,6 +1507,9 @@ void ConfigHelper::initializeTls( for (const auto& curve : options.curves_) { common_tls_context.mutable_tls_params()->add_ecdh_curves(curve); } + for (const auto& cipher : options.ciphers_) { + common_tls_context.mutable_tls_params()->add_cipher_suites(cipher); + } if (options.rsa_cert_) { auto* tls_certificate = common_tls_context.add_tls_certificates(); tls_certificate->mutable_certificate_chain()->set_filename( @@ -1528,6 +1532,7 @@ void ConfigHelper::initializeTls( "test/config/integration/certs/server_ecdsa_ocsp_resp.der")); } } + if (!options.san_matchers_.empty()) { *validation_context->mutable_match_typed_subject_alt_names() = {options.san_matchers_.begin(), options.san_matchers_.end()}; diff --git a/test/config/utility.h b/test/config/utility.h index a1e5cff2bf60..c9016cb15691 100644 --- a/test/config/utility.h +++ b/test/config/utility.h @@ -70,6 +70,16 @@ class ConfigHelper { return *this; } + ServerSslOptions& setPreferClientCiphers(bool prefer_client_ciphers) { + prefer_client_ciphers_ = prefer_client_ciphers; + return *this; + } + + ServerSslOptions& setCiphers(const std::vector& ciphers) { + ciphers_ = ciphers; + return *this; + } + ServerSslOptions& setCurves(const std::vector& curves) { curves_ = curves; return *this; @@ -127,9 +137,11 @@ class ConfigHelper { bool rsa_cert_ocsp_staple_{true}; bool ecdsa_cert_{false}; bool ecdsa_cert_ocsp_staple_{false}; + bool prefer_client_ciphers_{false}; bool ocsp_staple_required_{false}; bool tlsv1_3_{false}; std::vector curves_; + std::vector ciphers_; bool expect_client_ecdsa_cert_{false}; bool keylog_local_filter_{false}; bool keylog_remote_filter_{false}; diff --git a/test/mocks/ssl/mocks.h b/test/mocks/ssl/mocks.h index 96923831725e..7a3e35a95707 100644 --- a/test/mocks/ssl/mocks.h +++ b/test/mocks/ssl/mocks.h @@ -126,6 +126,7 @@ class MockServerContextConfig : public ServerContextConfig { MOCK_METHOD(const std::string&, cipherSuites, (), (const)); MOCK_METHOD(const std::string&, ecdhCurves, (), (const)); MOCK_METHOD(const std::string&, signatureAlgorithms, (), (const)); + MOCK_METHOD(bool, preferClientCiphers, (), (const)); MOCK_METHOD(std::vector>, tlsCertificates, (), (const)); MOCK_METHOD(const CertificateValidationContextConfig*, certificateValidationContext, (), (const)); From e5fc7ecb40d810c2b8bc23db351fa75eb165865b Mon Sep 17 00:00:00 2001 From: botengyao Date: Tue, 23 Jul 2024 17:50:45 -0400 Subject: [PATCH 22/26] tls: remove runtime guard `ssl_transport_failure_reason_format` (#35389) Risk Level: low Testing: Docs Changes: Release Notes: Platform Specific Features: Fixes:#35375 --------- Signed-off-by: Boteng Yao --- changelogs/current.yaml | 3 +++ source/common/runtime/runtime_features.cc | 1 - source/common/tls/ssl_socket.cc | 11 +++----- .../tls/integration/ssl_integration_test.cc | 26 ------------------- 4 files changed, 6 insertions(+), 35 deletions(-) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 7147c211c781..6e90255923b6 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -31,6 +31,9 @@ removed_config_or_runtime: - area: DNS change: | Removed ``envoy.reloadable_features.dns_cache_set_first_resolve_complete`` runtime flag and legacy code paths. +- area: tls + change: | + Removed runtime flag ``envoy.reloadable_features.ssl_transport_failure_reason_format``. new_features: - area: tls diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index 11e4fe070f7b..67ff78d42fcc 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -90,7 +90,6 @@ RUNTIME_GUARD(envoy_reloadable_features_sanitize_te); RUNTIME_GUARD(envoy_reloadable_features_send_header_raw_value); RUNTIME_GUARD(envoy_reloadable_features_send_local_reply_when_no_buffer_and_upstream_request); RUNTIME_GUARD(envoy_reloadable_features_skip_dns_lookup_for_proxied_requests); -RUNTIME_GUARD(envoy_reloadable_features_ssl_transport_failure_reason_format); RUNTIME_GUARD(envoy_reloadable_features_stateful_session_encode_ttl_in_cookie); RUNTIME_GUARD(envoy_reloadable_features_strict_duration_validation); RUNTIME_GUARD(envoy_reloadable_features_tcp_tunneling_send_downstream_fin_on_upstream_trailers); diff --git a/source/common/tls/ssl_socket.cc b/source/common/tls/ssl_socket.cc index e731640d680e..dfbf77899ec3 100644 --- a/source/common/tls/ssl_socket.cc +++ b/source/common/tls/ssl_socket.cc @@ -6,7 +6,6 @@ #include "source/common/common/empty_string.h" #include "source/common/common/hex.h" #include "source/common/http/headers.h" -#include "source/common/runtime/runtime_features.h" #include "source/common/tls/io_handle_bio.h" #include "source/common/tls/ssl_handshaker.h" #include "source/common/tls/utility.h" @@ -210,8 +209,6 @@ PostIoAction SslSocket::doHandshake() { return info_->doHandshake(); } void SslSocket::drainErrorQueue() { bool saw_error = false; bool saw_counted_error = false; - bool new_ssl_failure_format = Runtime::runtimeFeatureEnabled( - "envoy.reloadable_features.ssl_transport_failure_reason_format"); while (uint64_t err = ERR_get_error()) { if (ERR_GET_LIB(err) == ERR_LIB_SSL) { if (ERR_GET_REASON(err) == SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE) { @@ -229,10 +226,10 @@ void SslSocket::drainErrorQueue() { saw_error = true; if (failure_reason_.empty()) { - failure_reason_ = new_ssl_failure_format ? "TLS_error:" : "TLS error:"; + failure_reason_ = "TLS_error:"; } - absl::StrAppend(&failure_reason_, new_ssl_failure_format ? "|" : " ", err, ":", + absl::StrAppend(&failure_reason_, "|", err, ":", absl::NullSafeStringView(ERR_lib_error_string(err)), ":", absl::NullSafeStringView(ERR_func_error_string(err)), ":", absl::NullSafeStringView(ERR_reason_error_string(err))); @@ -243,9 +240,7 @@ void SslSocket::drainErrorQueue() { } if (!failure_reason_.empty()) { - if (new_ssl_failure_format) { - absl::StrAppend(&failure_reason_, ":TLS_error_end"); - } + absl::StrAppend(&failure_reason_, ":TLS_error_end"); ENVOY_CONN_LOG(debug, "remote address:{},{}", callbacks_->connection(), callbacks_->connection().connectionInfoProvider().remoteAddress()->asString(), failure_reason_); diff --git a/test/common/tls/integration/ssl_integration_test.cc b/test/common/tls/integration/ssl_integration_test.cc index 4ad8d5867935..53773b7081e1 100644 --- a/test/common/tls/integration/ssl_integration_test.cc +++ b/test/common/tls/integration/ssl_integration_test.cc @@ -790,8 +790,6 @@ TEST_P(SslCertficateIntegrationTest, ServerEcdsaClientRsaOnly) { // Test the access log. TEST_P(SslCertficateIntegrationTest, ServerEcdsaClientRsaOnlyWithAccessLog) { TestScopedRuntime scoped_runtime; - scoped_runtime.mergeValues( - {{"envoy.reloadable_features.ssl_transport_failure_reason_format", "true"}}); useListenerAccessLog("DOWNSTREAM_TRANSPORT_FAILURE_REASON=%DOWNSTREAM_TRANSPORT_FAILURE_REASON% " "FILTER_CHAIN_NAME=%FILTER_CHAIN_NAME%"); server_rsa_cert_ = false; @@ -813,30 +811,6 @@ TEST_P(SslCertficateIntegrationTest, ServerEcdsaClientRsaOnlyWithAccessLog) { } } -// Server has only an ECDSA certificate, client is only RSA capable, leads to a connection fail. -TEST_P(SslCertficateIntegrationTest, ServerEcdsaClientRsaOnlyWithAccessLogOriginalFormat) { - TestScopedRuntime scoped_runtime; - scoped_runtime.mergeValues( - {{"envoy.reloadable_features.ssl_transport_failure_reason_format", "false"}}); - useListenerAccessLog("DOWNSTREAM_TRANSPORT_FAILURE_REASON=%DOWNSTREAM_TRANSPORT_FAILURE_REASON% " - "FILTER_CHAIN_NAME=%FILTER_CHAIN_NAME%"); - server_rsa_cert_ = false; - server_ecdsa_cert_ = true; - initialize(); - auto codec_client = - makeRawHttpConnection(makeSslClientConnection(rsaOnlyClientOptions()), absl::nullopt); - EXPECT_FALSE(codec_client->connected()); - - auto log_result = waitForAccessLog(listener_access_log_name_); - if (tls_version_ == envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_3) { - EXPECT_EQ(log_result, "DOWNSTREAM_TRANSPORT_FAILURE_REASON=TLS_error:_268435709:SSL_routines:" - "OPENSSL_internal:NO_COMMON_SIGNATURE_ALGORITHMS FILTER_CHAIN_NAME=-"); - } else { - EXPECT_EQ(log_result, "DOWNSTREAM_TRANSPORT_FAILURE_REASON=TLS_error:_268435640:" - "SSL_routines:OPENSSL_internal:NO_SHARED_CIPHER FILTER_CHAIN_NAME=-"); - } -} - // Server with RSA/ECDSA certificates and a client with only RSA cipher suites works. // Test empty access log with successful connection. TEST_P(SslCertficateIntegrationTest, ServerRsaEcdsaClientRsaOnlyWithAccessLog) { From e7d2b7a93670f050ace8258ca98167f5957423af Mon Sep 17 00:00:00 2001 From: Tianyu <72890320+tyxia@users.noreply.github.com> Date: Tue, 23 Jul 2024 19:25:19 -0400 Subject: [PATCH 23/26] ext_proc: flow control in observability mode (#35298) Commit Message: This PR is split from https://github.com/envoyproxy/envoy/pull/35077. The change is specifically needed for ext_proc's observability mode where the stream is deferred closed upon filter destruction (i.e., stream outlives the filter object) Risk Level: Low, existing runtime guard and observability mode only Testing: e2e test and load test Docs Changes: N/A Release Notes: N/A Platform Specific Features: N/A --------- Signed-off-by: tyxia --- .../filters/http/ext_proc/client_impl.cc | 3 +- .../filters/http/ext_proc/client_impl.h | 7 ++ .../filters/http/ext_proc/ext_proc.cc | 11 ++- .../ext_proc/ext_proc_integration_test.cc | 84 ++++++++----------- 4 files changed, 53 insertions(+), 52 deletions(-) diff --git a/source/extensions/filters/http/ext_proc/client_impl.cc b/source/extensions/filters/http/ext_proc/client_impl.cc index 8dacb7d72e0c..842d72f70288 100644 --- a/source/extensions/filters/http/ext_proc/client_impl.cc +++ b/source/extensions/filters/http/ext_proc/client_impl.cc @@ -62,7 +62,8 @@ void ExternalProcessorStreamImpl::send(envoy::service::ext_proc::v3::ProcessingR bool ExternalProcessorStreamImpl::close() { if (!stream_closed_) { ENVOY_LOG(debug, "Closing gRPC stream"); - if (grpc_side_stream_flow_control_) { + // Unregister the watermark callbacks, if any exist (e.g., filter is not destroyed yet) + if (grpc_side_stream_flow_control_ && callbacks_.has_value()) { stream_.removeWatermarkCallbacks(); } stream_.closeStream(); diff --git a/source/extensions/filters/http/ext_proc/client_impl.h b/source/extensions/filters/http/ext_proc/client_impl.h index e56def004bc0..f5677cb667cc 100644 --- a/source/extensions/filters/http/ext_proc/client_impl.h +++ b/source/extensions/filters/http/ext_proc/client_impl.h @@ -57,6 +57,12 @@ class ExternalProcessorStreamImpl : public ExternalProcessorStream, // When the filter object is being destroyed, `callbacks_` (which is a OptRef to filter object) // should be reset to avoid the dangling reference. callbacks_.reset(); + + // Unregister the watermark callbacks(if any) to prevent access of filter callbacks after + // the filter object is destroyed. + if (grpc_side_stream_flow_control_ && !stream_closed_) { + stream_.removeWatermarkCallbacks(); + } } // AsyncStreamCallbacks @@ -87,6 +93,7 @@ class ExternalProcessorStreamImpl : public ExternalProcessorStream, Grpc::AsyncStream stream_; Http::AsyncClient::ParentContext grpc_context_; bool stream_closed_ = false; + // Boolean flag initiated by runtime flag. const bool grpc_side_stream_flow_control_; }; diff --git a/source/extensions/filters/http/ext_proc/ext_proc.cc b/source/extensions/filters/http/ext_proc/ext_proc.cc index 8d4a62f0f8e3..eb89d19d1930 100644 --- a/source/extensions/filters/http/ext_proc/ext_proc.cc +++ b/source/extensions/filters/http/ext_proc/ext_proc.cc @@ -396,15 +396,18 @@ void Filter::onDestroy() { decoding_state_.stopMessageTimer(); encoding_state_.stopMessageTimer(); - if (stream_ != nullptr) { - stream_->notifyFilterDestroy(); - } - if (config_->observabilityMode()) { // In observability mode where the main stream processing and side stream processing are // asynchronous, it is possible that filter instance is destroyed before the side stream request // arrives at ext_proc server. In order to prevent the data loss in this case, side stream // closure is deferred upon filter destruction with a timer. + + // First, release the referenced filter resource. + if (stream_ != nullptr) { + stream_->notifyFilterDestroy(); + } + + // Second, perform stream deferred closure. deferredCloseStream(); } else { // Perform immediate close on the stream otherwise. diff --git a/test/extensions/filters/http/ext_proc/ext_proc_integration_test.cc b/test/extensions/filters/http/ext_proc/ext_proc_integration_test.cc index 4e5756847880..8991e848072e 100644 --- a/test/extensions/filters/http/ext_proc/ext_proc_integration_test.cc +++ b/test/extensions/filters/http/ext_proc/ext_proc_integration_test.cc @@ -647,6 +647,35 @@ class ExtProcIntegrationTest : public HttpIntegrationTest, verifyDownstreamResponse(*response, 200); } + void testSidestreamPushbackDownstream(uint32_t body_size, bool check_downstream_flow_control) { + config_helper_.setBufferLimits(1024, 1024); + + proto_config_.mutable_processing_mode()->set_request_header_mode(ProcessingMode::SKIP); + proto_config_.mutable_processing_mode()->set_request_body_mode(ProcessingMode::STREAMED); + proto_config_.mutable_processing_mode()->set_response_header_mode(ProcessingMode::SKIP); + initializeConfig(); + HttpIntegrationTest::initialize(); + + std::string body_str = std::string(body_size, 'a'); + auto response = sendDownstreamRequestWithBody(body_str, absl::nullopt); + + bool end_stream = false; + int count = 0; + while (!end_stream) { + processRequestBodyMessage( + *grpc_upstreams_[0], count == 0 ? true : false, + [&end_stream](const HttpBody& body, BodyResponse&) { + end_stream = body.end_of_stream(); + return true; + }, + check_downstream_flow_control); + count++; + } + handleUpstreamRequest(); + + verifyDownstreamResponse(*response, 200); + } + envoy::extensions::filters::http::ext_proc::v3::ExternalProcessor proto_config_{}; uint32_t max_message_timeout_ms_{0}; std::vector grpc_upstreams_; @@ -4507,32 +4536,16 @@ TEST_P(ExtProcIntegrationTest, SidestreamPushbackDownstream) { return; } - config_helper_.setBufferLimits(1024, 1024); - - proto_config_.mutable_processing_mode()->set_request_header_mode(ProcessingMode::SKIP); - proto_config_.mutable_processing_mode()->set_request_body_mode(ProcessingMode::STREAMED); - proto_config_.mutable_processing_mode()->set_response_header_mode(ProcessingMode::SKIP); - initializeConfig(); - HttpIntegrationTest::initialize(); - - std::string body_str = std::string(16 * 1024, 'a'); - auto response = sendDownstreamRequestWithBody(body_str, absl::nullopt); + testSidestreamPushbackDownstream(16 * 1024, true); +} - bool end_stream = false; - int count = 0; - while (!end_stream) { - processRequestBodyMessage( - *grpc_upstreams_[0], count == 0 ? true : false, - [&end_stream](const HttpBody& body, BodyResponse&) { - end_stream = body.end_of_stream(); - return true; - }, - /*check_downstream_flow_control=*/true); - count++; +TEST_P(ExtProcIntegrationTest, SidestreamPushbackDownstreamObservabilityMode) { + if (std::get<1>(std::get<0>(GetParam())) != Envoy::Grpc::ClientType::EnvoyGrpc) { + return; } - handleUpstreamRequest(); - verifyDownstreamResponse(*response, 200); + proto_config_.set_observability_mode(true); + testSidestreamPushbackDownstream(16 * 1024, true); } TEST_P(ExtProcIntegrationTest, SidestreamPushbackDownstreamRuntimeDisable) { @@ -4543,30 +4556,7 @@ TEST_P(ExtProcIntegrationTest, SidestreamPushbackDownstreamRuntimeDisable) { scoped_runtime_.mergeValues( {{"envoy.reloadable_features.grpc_side_stream_flow_control", "false"}}); - config_helper_.setBufferLimits(1024, 1024); - - proto_config_.mutable_processing_mode()->set_request_header_mode(ProcessingMode::SKIP); - proto_config_.mutable_processing_mode()->set_request_body_mode(ProcessingMode::STREAMED); - proto_config_.mutable_processing_mode()->set_response_header_mode(ProcessingMode::SKIP); - initializeConfig(); - HttpIntegrationTest::initialize(); - - std::string body_str = std::string(1030, 'a'); - auto response = sendDownstreamRequestWithBody(body_str, absl::nullopt); - - bool end_stream = false; - int count = 0; - while (!end_stream) { - processRequestBodyMessage(*grpc_upstreams_[0], count == 0 ? true : false, - [&end_stream](const HttpBody& body, BodyResponse&) { - end_stream = body.end_of_stream(); - return true; - }); - count++; - } - handleUpstreamRequest(); - - verifyDownstreamResponse(*response, 200); + testSidestreamPushbackDownstream(1030, false); } } // namespace Envoy From 8182418db107fb7cd6af7d92e1fa7a68b8eb97ff Mon Sep 17 00:00:00 2001 From: RenjieTang Date: Tue, 23 Jul 2024 16:36:21 -0700 Subject: [PATCH 24/26] Quiche roll 20240717144914 (#35241) https://github.com/google/quiche/compare/7880417d1..f8ca4ffbe ``` $ git log 7880417d1..f8ca4ffbe --date=short --no-merges --format="%ad %al %s" 2024-07-17 quiche-dev Make implicit `this` capture explicit 2024-07-17 danzh No public description 2024-07-17 wub Fix test ConnectionMigrationWithNonZeroConnectionIDClientIPChangedMultipleTimes. 2024-07-16 wub Deprecate gfe2_restart_flag_quic_opport_bundle_qpack_decoder_data5. 2024-07-16 birenroy Migrates all users of spdy::Http2HeaderBlock to quiche::HttpHeaderBlock. 2024-07-16 birenroy Migrates all users of spdy::Http2HeaderBlock to quiche::HttpHeaderBlock. 2024-07-16 vasilvv Fix a bug in parser where for non-normal object status, the number of bytes read was counted incorrectly. 2024-07-16 birenroy Migrates all users of spdy::Http2HeaderBlock to quiche::HttpHeaderBlock. 2024-07-15 birenroy Migrates all users of spdy::Http2HeaderBlock to quiche::HttpHeaderBlock. 2024-07-15 danzh Unhide security fix to QuicSpdyStream (cl/626052950). 2024-07-12 birenroy Migrates all users of spdy::Http2HeaderBlock to quiche::HttpHeaderBlock. 2024-07-12 awillia Fix a memory leak in InitializeAndCheckForTlsPskFailure test helper 2024-07-11 fayang Parse and log cert compression algos from CHLO. 2024-07-11 quiche-dev Modify the visitor to allow it to interact with packets written by the packet exchanger. 2024-07-11 vasilvv Implement MoQT priority calculation. ``` Signed-off-by: Renjie Tang --------- Signed-off-by: Renjie Tang --- bazel/external/quiche_stream_fix.patch | 51 -------------------------- bazel/repositories.bzl | 1 - bazel/repository_locations.bzl | 6 +-- 3 files changed, 3 insertions(+), 55 deletions(-) delete mode 100644 bazel/external/quiche_stream_fix.patch diff --git a/bazel/external/quiche_stream_fix.patch b/bazel/external/quiche_stream_fix.patch deleted file mode 100644 index ae632933ffbb..000000000000 --- a/bazel/external/quiche_stream_fix.patch +++ /dev/null @@ -1,51 +0,0 @@ -# Fix https://github.com/envoyproxy/envoy-setec/issues/1496#issuecomment-2064844217 - -diff --git a/quiche/quic/core/http/quic_spdy_stream.cc b/quiche/quic/core/http/quic_spdy_stream.cc -index 4a5c2ede2..d69895055 100644 ---- a/quiche/quic/core/http/quic_spdy_stream.cc -+++ b/quiche/quic/core/http/quic_spdy_stream.cc -@@ -1865,6 +1865,18 @@ bool QuicSpdyStream::AreHeaderFieldValuesValid( - return true; - } - -+void QuicSpdyStream::StopReading() { -+ QuicStream::StopReading(); -+ if (GetQuicReloadableFlag( -+ quic_stop_reading_also_stops_header_decompression) && -+ VersionUsesHttp3(transport_version()) && !fin_received() && -+ spdy_session_->qpack_decoder()) { -+ // Clean up Qpack decoding states. -+ spdy_session_->qpack_decoder()->OnStreamReset(id()); -+ qpack_decoded_headers_accumulator_.reset(); -+ } -+} -+ - void QuicSpdyStream::OnInvalidHeaders() { Reset(QUIC_BAD_APPLICATION_PAYLOAD); } - - void QuicSpdyStream::CloseReadSide() { -diff --git a/quiche/quic/core/http/quic_spdy_stream.h b/quiche/quic/core/http/quic_spdy_stream.h -index 10c34b10f..5c0cb0128 100644 ---- a/quiche/quic/core/http/quic_spdy_stream.h -+++ b/quiche/quic/core/http/quic_spdy_stream.h -@@ -117,6 +117,7 @@ class QUICHE_EXPORT QuicSpdyStream - - // QuicStream implementation - void OnClose() override; -+ void StopReading() override; - - // Override to maybe close the write side after writing. - void OnCanWrite() override; -diff --git a/quiche/common/quiche_feature_flags_list.h b/quiche/common/quiche_feature_flags_list.h -index 27181430f..6c790fe6d 100755 ---- a/quiche/common/quiche_feature_flags_list.h -+++ b/quiche/common/quiche_feature_flags_list.h -@@ -45,7 +45,8 @@ QUICHE_FLAG(bool, quiche_reloadable_flag_quic_pacing_remove_non_initial_burst, f - QUICHE_FLAG(bool, quiche_reloadable_flag_quic_priority_respect_incremental, false, false, "If true, respect the incremental parameter of each stream in QuicWriteBlockedList.") - QUICHE_FLAG(bool, quiche_reloadable_flag_quic_require_handshake_confirmation, true, true, "If true, require handshake confirmation for QUIC connections, functionally disabling 0-rtt handshakes.") - QUICHE_FLAG(bool, quiche_reloadable_flag_quic_send_placeholder_ticket_when_encrypt_ticket_fails, false, true, "If true, when TicketCrypter fails to encrypt a session ticket, quic::TlsServerHandshaker will send a placeholder ticket, instead of an empty one, to the client.") --QUICHE_FLAG(bool, quiche_reloadable_flag_quic_stop_reading_also_stops_header_decompression, false, false, "") -+ -+QUICHE_FLAG(bool, quiche_reloadable_flag_quic_stop_reading_also_stops_header_decompression, false, true, "If true, QUIC stream will not continue decompressing buffer headers after StopReading() called.") - QUICHE_FLAG(bool, quiche_reloadable_flag_quic_test_peer_addr_change_after_normalize, false, false, "If true, QuicConnection::ProcessValidatedPacket will use normalized address to test peer address changes.") - QUICHE_FLAG(bool, quiche_reloadable_flag_quic_testonly_default_false, false, false, "A testonly reloadable flag that will always default to false.") - QUICHE_FLAG(bool, quiche_reloadable_flag_quic_testonly_default_true, true, true, "A testonly reloadable flag that will always default to true.") diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index f42c356932fa..63f74b807b60 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -1139,7 +1139,6 @@ def _com_github_google_quiche(): patch_cmds = ["find quiche/ -type f -name \"*.bazel\" -delete"], patches = [ "@envoy//bazel/external:quiche_sequencer_fix.patch", - "@envoy//bazel/external:quiche_stream_fix.patch", ], patch_args = ["-p1"], build_file = "@envoy//bazel/external:quiche.BUILD", diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index f28bd5705739..b4d3d606a1bb 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -1191,12 +1191,12 @@ REPOSITORY_LOCATIONS_SPEC = dict( project_name = "QUICHE", project_desc = "QUICHE (QUIC, HTTP/2, Etc) is Google‘s implementation of QUIC and related protocols", project_url = "https://github.com/google/quiche", - version = "7880417d1eec571527443008ac7bad4735232a62", - sha256 = "e6b658d0c109b561c580ec66768ffdda737e6332bb195150bf1622ce6415dbf5", + version = "f8ca4ffbe5eb5c099bd11ba3e90553fa282c8421", + sha256 = "7648ede3f32bc6367a629b245d268c9be47ba05e23b4345a54152dabeba387d9", urls = ["https://github.com/google/quiche/archive/{version}.tar.gz"], strip_prefix = "quiche-{version}", use_category = ["controlplane", "dataplane_core"], - release_date = "2024-07-11", + release_date = "2024-07-17", cpe = "N/A", license = "BSD-3-Clause", license_url = "https://github.com/google/quiche/blob/{version}/LICENSE", From 5aef5d6edacdb07afb04df62e11de6597094cd1a Mon Sep 17 00:00:00 2001 From: alyssawilk Date: Tue, 23 Jul 2024 20:21:53 -0400 Subject: [PATCH 25/26] router: removing a few exceptions (#35346) Risk Level: low Testing: updated tests Docs Changes: n/a Release Notes: n/a https://github.com/envoyproxy/envoy-mobile/issues/176 Signed-off-by: Alyssa Wilk --- source/common/router/config_impl.cc | 43 +++++++++++++++++++------- source/common/router/config_impl.h | 17 +++++++--- test/common/router/config_impl_test.cc | 7 ++--- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc index 159845873a3f..51bb67a87147 100644 --- a/source/common/router/config_impl.cc +++ b/source/common/router/config_impl.cc @@ -159,14 +159,15 @@ class RouteActionValidationVisitor } }; -const envoy::config::route::v3::WeightedCluster::ClusterWeight& validateWeightedClusterSpecifier( +absl::Status validateWeightedClusterSpecifier( const envoy::config::route::v3::WeightedCluster::ClusterWeight& cluster) { if (!cluster.name().empty() && !cluster.cluster_header().empty()) { - throwEnvoyExceptionOrPanic("Only one of name or cluster_header can be specified"); + return absl::InvalidArgumentError("Only one of name or cluster_header can be specified"); } else if (cluster.name().empty() && cluster.cluster_header().empty()) { - throwEnvoyExceptionOrPanic("At least one of name or cluster_header need to be specified"); + return absl::InvalidArgumentError( + "At least one of name or cluster_header need to be specified"); } - return cluster; + return absl::OkStatus(); } // Returns a vector of header parsers, sorted by specificity. The `specificity_ascend` parameter @@ -261,13 +262,17 @@ RetryPolicyImpl::create(const envoy::config::route::v3::RetryPolicy& retry_polic ProtobufMessage::ValidationVisitor& validation_visitor, Upstream::RetryExtensionFactoryContext& factory_context, Server::Configuration::CommonFactoryContext& common_context) { - return std::unique_ptr( - new RetryPolicyImpl(retry_policy, validation_visitor, factory_context, common_context)); + absl::Status creation_status = absl::OkStatus(); + auto ret = std::unique_ptr(new RetryPolicyImpl( + retry_policy, validation_visitor, factory_context, common_context, creation_status)); + RETURN_IF_NOT_OK(creation_status); + return ret; } RetryPolicyImpl::RetryPolicyImpl(const envoy::config::route::v3::RetryPolicy& retry_policy, ProtobufMessage::ValidationVisitor& validation_visitor, Upstream::RetryExtensionFactoryContext& factory_context, - Server::Configuration::CommonFactoryContext& common_context) + Server::Configuration::CommonFactoryContext& common_context, + absl::Status& creation_status) : retriable_headers_(Http::HeaderUtility::buildHeaderMatcherVector( retry_policy.retriable_headers(), common_context)), retriable_request_headers_(Http::HeaderUtility::buildHeaderMatcherVector( @@ -332,8 +337,9 @@ RetryPolicyImpl::RetryPolicyImpl(const envoy::config::route::v3::RetryPolicy& re } if ((*max_interval_).count() < (*base_interval_).count()) { - throwEnvoyExceptionOrPanic( + creation_status = absl::InvalidArgumentError( "retry_policy.max_interval must greater than or equal to the base_interval"); + return; } } } @@ -644,8 +650,10 @@ RouteEntryImplBase::RouteEntryImplBase(const CommonVirtualHostSharedPtr& vhost, std::vector weighted_clusters; weighted_clusters.reserve(route.route().weighted_clusters().clusters().size()); for (const auto& cluster : route.route().weighted_clusters().clusters()) { - auto cluster_entry = std::make_unique( - this, runtime_key_prefix + "." + cluster.name(), factory_context, validator, cluster); + auto cluster_entry = THROW_OR_RETURN_VALUE( + WeightedClusterEntry::create(this, runtime_key_prefix + "." + cluster.name(), + factory_context, validator, cluster), + std::unique_ptr); weighted_clusters.emplace_back(std::move(cluster_entry)); total_weight += weighted_clusters.back()->clusterWeight(); if (total_weight > std::numeric_limits::max()) { @@ -1475,13 +1483,24 @@ const Envoy::Config::TypedMetadata& RouteEntryImplBase::typedMetadata() const { : DefaultRouteMetadataPack::get().typed_metadata_; } +absl::StatusOr> +RouteEntryImplBase::WeightedClusterEntry::create( + const RouteEntryImplBase* parent, const std::string& runtime_key, + Server::Configuration::ServerFactoryContext& factory_context, + ProtobufMessage::ValidationVisitor& validator, + const envoy::config::route::v3::WeightedCluster::ClusterWeight& cluster) { + RETURN_IF_NOT_OK(validateWeightedClusterSpecifier(cluster)); + return std::unique_ptr( + new WeightedClusterEntry(parent, runtime_key, factory_context, validator, cluster)); +} + RouteEntryImplBase::WeightedClusterEntry::WeightedClusterEntry( const RouteEntryImplBase* parent, const std::string& runtime_key, Server::Configuration::ServerFactoryContext& factory_context, ProtobufMessage::ValidationVisitor& validator, const envoy::config::route::v3::WeightedCluster::ClusterWeight& cluster) - : DynamicRouteEntry(parent, nullptr, validateWeightedClusterSpecifier(cluster).name()), - runtime_key_(runtime_key), loader_(factory_context.runtime()), + : DynamicRouteEntry(parent, nullptr, cluster.name()), runtime_key_(runtime_key), + loader_(factory_context.runtime()), cluster_weight_(PROTOBUF_GET_WRAPPED_REQUIRED(cluster, weight)), per_filter_configs_(THROW_OR_RETURN_VALUE( PerFilterConfigs::create(cluster.typed_per_filter_config(), factory_context, validator), diff --git a/source/common/router/config_impl.h b/source/common/router/config_impl.h index 1e5b8ebee210..2a6bfc723532 100644 --- a/source/common/router/config_impl.h +++ b/source/common/router/config_impl.h @@ -469,7 +469,8 @@ class RetryPolicyImpl : public RetryPolicy { RetryPolicyImpl(const envoy::config::route::v3::RetryPolicy& retry_policy, ProtobufMessage::ValidationVisitor& validation_visitor, Upstream::RetryExtensionFactoryContext& factory_context, - Server::Configuration::CommonFactoryContext& common_context); + Server::Configuration::CommonFactoryContext& common_context, + absl::Status& creation_status); std::chrono::milliseconds per_try_timeout_{0}; std::chrono::milliseconds per_try_idle_timeout_{0}; // We set the number of retries to 1 by default (i.e. when no route or vhost level retry policy is @@ -992,10 +993,11 @@ class RouteEntryImplBase : public RouteEntryAndRoute, */ class WeightedClusterEntry : public DynamicRouteEntry { public: - WeightedClusterEntry(const RouteEntryImplBase* parent, const std::string& rutime_key, - Server::Configuration::ServerFactoryContext& factory_context, - ProtobufMessage::ValidationVisitor& validator, - const envoy::config::route::v3::WeightedCluster::ClusterWeight& cluster); + static absl::StatusOr> + create(const RouteEntryImplBase* parent, const std::string& rutime_key, + Server::Configuration::ServerFactoryContext& factory_context, + ProtobufMessage::ValidationVisitor& validator, + const envoy::config::route::v3::WeightedCluster::ClusterWeight& cluster); uint64_t clusterWeight() const { return loader_.snapshot().getInteger(runtime_key_, cluster_weight_); @@ -1064,6 +1066,11 @@ class RouteEntryImplBase : public RouteEntryAndRoute, const Http::LowerCaseString& clusterHeaderName() const { return cluster_header_name_; } private: + WeightedClusterEntry(const RouteEntryImplBase* parent, const std::string& rutime_key, + Server::Configuration::ServerFactoryContext& factory_context, + ProtobufMessage::ValidationVisitor& validator, + const envoy::config::route::v3::WeightedCluster::ClusterWeight& cluster); + const std::string runtime_key_; Runtime::Loader& loader_; const uint64_t cluster_weight_; diff --git a/test/common/router/config_impl_test.cc b/test/common/router/config_impl_test.cc index 93bc3b972e58..b9679737b71b 100644 --- a/test/common/router/config_impl_test.cc +++ b/test/common/router/config_impl_test.cc @@ -4973,10 +4973,9 @@ TEST_F(RouteMatcherTest, InvalidRetryBackOff) { )EOF"; factory_context_.cluster_manager_.initializeClusters({"backoff"}, {}); - EXPECT_THROW_WITH_MESSAGE( - TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, - creation_status_), - EnvoyException, "retry_policy.max_interval must greater than or equal to the base_interval"); + TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true, creation_status_); + EXPECT_EQ(creation_status_.message(), + "retry_policy.max_interval must greater than or equal to the base_interval"); } TEST_F(RouteMatcherTest, RateLimitedRetryBackOff) { From 8a214e8a7104749f81cb945dc79e4a23029d6bda Mon Sep 17 00:00:00 2001 From: yanjunxiang-google <78807980+yanjunxiang-google@users.noreply.github.com> Date: Tue, 23 Jul 2024 20:55:44 -0400 Subject: [PATCH 26/26] Remove runtime flag envoy_reloadable_features_send_header_raw_value (#35388) Fixes: https://github.com/envoyproxy/envoy/issues/31982 Description: https://github.com/envoyproxy/envoy/pull/27865 added a runtime flag: "envoy.reloadable_features.send_header_value_in_bytes", which later on being changed into "envoy_reloadable_features_send_header_raw_value" by https://github.com/envoyproxy/envoy/pull/28245. It has been 6 months since the code has been exercised by default, so it's time to remove the old code path and deprecate this runtime flag. With this change, the Envoy ext_proc filter and the ext_proc server will only communicate with the ``raw_value`` field: https://github.com/envoyproxy/envoy/blob/ff6ced12ef202a18f94186da898ea10329b618e9/api/envoy/config/core/v3/base.proto#L391. Any setting in the ``value`` field from the ext_proc server will be ignored: https://github.com/envoyproxy/envoy/blob/ff6ced12ef202a18f94186da898ea10329b618e9/api/envoy/config/core/v3/base.proto#L384 All the ext_proc filter related tests are changed to set and check raw_value. --------- Signed-off-by: Yanjun Xiang --- .../ext_proc/v3/external_processor.proto | 24 +-- changelogs/current.yaml | 3 + source/common/runtime/runtime_features.cc | 1 - .../filters/http/ext_proc/mutation_utils.cc | 23 +-- test/extensions/filters/http/ext_proc/BUILD | 3 - .../http/ext_proc/ext_proc_benchmark_test.cc | 4 +- .../ext_proc/ext_proc_integration_test.cc | 141 +++++++----------- .../filters/http/ext_proc/filter_test.cc | 55 ++++--- .../http/ext_proc/mutation_utils_test.cc | 51 +++---- .../ext_proc/streaming_integration_test.cc | 3 - .../extensions/filters/http/ext_proc/utils.cc | 6 +- 11 files changed, 115 insertions(+), 199 deletions(-) diff --git a/api/envoy/service/ext_proc/v3/external_processor.proto b/api/envoy/service/ext_proc/v3/external_processor.proto index e1d698ff7295..585d0aa7bf41 100644 --- a/api/envoy/service/ext_proc/v3/external_processor.proto +++ b/api/envoy/service/ext_proc/v3/external_processor.proto @@ -206,12 +206,8 @@ message ProcessingResponse { message HttpHeaders { // The HTTP request headers. All header keys will be // lower-cased, because HTTP header keys are case-insensitive. - // The ``headers`` encoding is based on the runtime guard - // envoy_reloadable_features_send_header_raw_value setting. - // When it is true, the header value is encoded in the + // The header value is encoded in the // :ref:`raw_value ` field. - // When it is false, the header value is encoded in the - // :ref:`value ` field. config.core.v3.HeaderMap headers = 1; // [#not-implemented-hide:] @@ -235,12 +231,8 @@ message HttpBody { // This message contains the trailers. message HttpTrailers { - // The ``trailers`` encoding is based on the runtime guard - // envoy_reloadable_features_send_header_raw_value setting. - // When it is true, the header value is encoded in the + // The header value is encoded in the // :ref:`raw_value ` field. - // When it is false, the header value is encoded in the - // :ref:`value ` field. config.core.v3.HeaderMap trailers = 1; } @@ -308,12 +300,8 @@ message CommonResponse { // Add new trailers to the message. This may be used when responding to either a // HttpHeaders or HttpBody message, but only if this message is returned // along with the CONTINUE_AND_REPLACE status. - // The ``trailers`` encoding is based on the runtime guard - // envoy_reloadable_features_send_header_raw_value setting. - // When it is true, the header value is encoded in the + // The header value is encoded in the // :ref:`raw_value ` field. - // When it is false, the header value is encoded in the - // :ref:`value ` field. config.core.v3.HeaderMap trailers = 4; // Clear the route cache for the current client request. This is necessary @@ -362,12 +350,8 @@ message HeaderMutation { // Add or replace HTTP headers. Attempts to set the value of // any ``x-envoy`` header, and attempts to set the ``:method``, // ``:authority``, ``:scheme``, or ``host`` headers will be ignored. - // The ``set_headers`` encoding is based on the runtime guard - // envoy_reloadable_features_send_header_raw_value setting. - // When it is true, the header value is encoded in the + // The header value is encoded in the // :ref:`raw_value ` field. - // When it is false, the header value is encoded in the - // :ref:`value ` field. repeated config.core.v3.HeaderValueOption set_headers = 1; // Remove these HTTP headers. Attempts to remove system headers -- diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 6e90255923b6..4631f141d5d5 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -24,6 +24,9 @@ bug_fixes: removed_config_or_runtime: # *Normally occurs at the end of the* :ref:`deprecation period ` +- area: ext_proc + change: | + Removed runtime flag ``envoy_reloadable_features_send_header_raw_value`` and legacy code path. - area: http change: | Removed runtime flag ``envoy.reloadable_features.no_downgrade_to_canonical_name`` and legacy code diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index 67ff78d42fcc..c9a983327d4a 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -87,7 +87,6 @@ RUNTIME_GUARD(envoy_reloadable_features_reject_invalid_yaml); RUNTIME_GUARD(envoy_reloadable_features_report_stream_reset_error_code); RUNTIME_GUARD(envoy_reloadable_features_sanitize_http2_headers_without_nghttp2); RUNTIME_GUARD(envoy_reloadable_features_sanitize_te); -RUNTIME_GUARD(envoy_reloadable_features_send_header_raw_value); RUNTIME_GUARD(envoy_reloadable_features_send_local_reply_when_no_buffer_and_upstream_request); RUNTIME_GUARD(envoy_reloadable_features_skip_dns_lookup_for_proxied_requests); RUNTIME_GUARD(envoy_reloadable_features_stateful_session_encode_ttl_in_cookie); diff --git a/source/extensions/filters/http/ext_proc/mutation_utils.cc b/source/extensions/filters/http/ext_proc/mutation_utils.cc index ebd794aa41a9..eaaec2ad7f9a 100644 --- a/source/extensions/filters/http/ext_proc/mutation_utils.cc +++ b/source/extensions/filters/http/ext_proc/mutation_utils.cc @@ -61,12 +61,7 @@ void MutationUtils::headersToProto( if (headerCanBeForwarded(e.key().getStringView(), allowed_headers, disallowed_headers)) { auto* new_header = proto_out.add_headers(); new_header->set_key(std::string(e.key().getStringView())); - // Setting up value or raw_value field based on the runtime flag. - if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.send_header_raw_value")) { - new_header->set_raw_value(std::string(e.value().getStringView())); - } else { - new_header->set_value(MessageUtil::sanitizeUtf8String(e.value().getStringView())); - } + new_header->set_raw_value(std::string(e.value().getStringView())); } return Http::HeaderMap::Iterate::Continue; }); @@ -158,21 +153,7 @@ absl::Status MutationUtils::applyHeaderMutations(const HeaderMutation& mutation, continue; } - // Only one of value or raw_value in the HeaderValue message should be set. - if (!sh.header().value().empty() && !sh.header().raw_value().empty()) { - ENVOY_LOG(debug, "Only one of value or raw_value in the HeaderValue message should be set, " - "may not be append."); - rejected_mutations.inc(); - return absl::InvalidArgumentError( - "Only one of value or raw_value in the HeaderValue message should be set."); - } - - absl::string_view header_value; - if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.send_header_raw_value")) { - header_value = sh.header().raw_value(); - } else { - header_value = sh.header().value(); - } + const absl::string_view header_value = sh.header().raw_value(); if (!Http::HeaderUtility::headerNameIsValid(sh.header().key()) || !Http::HeaderUtility::headerValueIsValid(header_value)) { ENVOY_LOG(debug, diff --git a/test/extensions/filters/http/ext_proc/BUILD b/test/extensions/filters/http/ext_proc/BUILD index 319245ffa157..d884d35c6037 100644 --- a/test/extensions/filters/http/ext_proc/BUILD +++ b/test/extensions/filters/http/ext_proc/BUILD @@ -59,7 +59,6 @@ envoy_extension_cc_test( "//test/mocks/server:overload_manager_mocks", "//test/mocks/server:server_factory_context_mocks", "//test/proto:helloworld_proto_cc_proto", - "//test/test_common:test_runtime_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/service/ext_proc/v3:pkg_cc_proto", ], @@ -145,7 +144,6 @@ envoy_extension_cc_test( "//source/extensions/filters/http/ext_proc:mutation_utils_lib", "//test/mocks/server:server_factory_context_mocks", "//test/mocks/stats:stats_mocks", - "//test/test_common:test_runtime_lib", "//test/test_common:utility_lib", "@envoy_api//envoy/config/common/mutation_rules/v3:pkg_cc_proto", ], @@ -216,7 +214,6 @@ envoy_extension_cc_test( "//source/extensions/filters/http/ext_proc:config", "//test/common/http:common_lib", "//test/integration:http_integration_lib", - "//test/test_common:test_runtime_lib", "//test/test_common:utility_lib", "@com_google_absl//absl/strings:str_format", "@envoy_api//envoy/extensions/filters/http/ext_proc/v3:pkg_cc_proto", diff --git a/test/extensions/filters/http/ext_proc/ext_proc_benchmark_test.cc b/test/extensions/filters/http/ext_proc/ext_proc_benchmark_test.cc index d180c9c0b381..99111d739cfc 100644 --- a/test/extensions/filters/http/ext_proc/ext_proc_benchmark_test.cc +++ b/test/extensions/filters/http/ext_proc/ext_proc_benchmark_test.cc @@ -182,7 +182,7 @@ TEST_F(BenchmarkTest, AddRequestHeaderAndClose) { ->mutable_header_mutation() ->add_set_headers(); new_hdr->mutable_header()->set_key("x-envoy-benchmark"); - new_hdr->mutable_header()->set_value("true"); + new_hdr->mutable_header()->set_raw_value("true"); stream->Write(header_resp); }); initialize(); @@ -210,7 +210,7 @@ TEST_F(BenchmarkTest, AddResponseHeaderAndClose) { ->add_set_headers() ->mutable_header(); new_hdr->set_key("x-envoy-benchmark"); - new_hdr->set_value("true"); + new_hdr->set_raw_value("true"); stream->Write(response_out); }); initialize(); diff --git a/test/extensions/filters/http/ext_proc/ext_proc_integration_test.cc b/test/extensions/filters/http/ext_proc/ext_proc_integration_test.cc index 8991e848072e..9338b5d4c5f2 100644 --- a/test/extensions/filters/http/ext_proc/ext_proc_integration_test.cc +++ b/test/extensions/filters/http/ext_proc/ext_proc_integration_test.cc @@ -97,8 +97,6 @@ class ExtProcIntegrationTest : public HttpIntegrationTest, [&total_cluster_endpoints](const auto& item) { total_cluster_endpoints += item.second; }); ASSERT_EQ(total_cluster_endpoints, grpc_upstream_count_); - scoped_runtime_.mergeValues( - {{"envoy.reloadable_features.send_header_raw_value", header_raw_value_}}); scoped_runtime_.mergeValues( {{"envoy.reloadable_features.immediate_response_use_filter_mutation_rule", filter_mutation_rule_}}); @@ -555,7 +553,7 @@ class ExtProcIntegrationTest : public HttpIntegrationTest, auto* headers = mutation.add_set_headers(); auto str = absl::StrCat("x-test-header-internal-", std::to_string(i)); headers->mutable_header()->set_key(str); - headers->mutable_header()->set_value(str); + headers->mutable_header()->set_raw_value(str); } } @@ -571,7 +569,7 @@ class ExtProcIntegrationTest : public HttpIntegrationTest, auto* content_length = headers_resp.mutable_response()->mutable_header_mutation()->add_set_headers(); content_length->mutable_header()->set_key("content-length"); - content_length->mutable_header()->set_value("13"); + content_length->mutable_header()->set_raw_value("13"); return true; }); @@ -682,7 +680,6 @@ class ExtProcIntegrationTest : public HttpIntegrationTest, FakeHttpConnectionPtr processor_connection_; FakeStreamPtr processor_stream_; TestScopedRuntime scoped_runtime_; - std::string header_raw_value_{"false"}; std::string filter_mutation_rule_{"false"}; // Number of grpc upstreams in the test. int grpc_upstream_count_ = 2; @@ -941,7 +938,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeaders) { auto response_header_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* mut1 = response_header_mutation->add_set_headers(); mut1->mutable_header()->set_key("x-new-header"); - mut1->mutable_header()->set_value("new"); + mut1->mutable_header()->set_raw_value("new"); response_header_mutation->add_remove_headers("x-remove-this"); return true; }); @@ -1025,7 +1022,7 @@ TEST_P(ExtProcIntegrationTest, SetHostHeaderRoutingSucceeded) { // Set host header to match the domain of virtual host in routing configuration. auto* mut = response_header_mutation->add_set_headers(); mut->mutable_header()->set_key(":authority"); - mut->mutable_header()->set_value(vhost_domain); + mut->mutable_header()->set_raw_value(vhost_domain); // Clear the route cache to trigger the route re-pick. headers_resp.mutable_response()->set_clear_route_cache(true); @@ -1086,7 +1083,7 @@ TEST_P(ExtProcIntegrationTest, SetHostHeaderRoutingFailed) { // configuration. auto* mut1 = response_header_mutation->add_set_headers(); mut1->mutable_header()->set_key(":authority"); - mut1->mutable_header()->set_value("wrong_host"); + mut1->mutable_header()->set_raw_value("wrong_host"); // Clear the route cache to trigger the route re-pick. headers_resp.mutable_response()->set_clear_route_cache(true); @@ -1116,19 +1113,19 @@ TEST_P(ExtProcIntegrationTest, GetAndSetPathHeader) { auto response_header_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* mut1 = response_header_mutation->add_set_headers(); mut1->mutable_header()->set_key(":path"); - mut1->mutable_header()->set_value("/mutated_path/bluh"); + mut1->mutable_header()->set_raw_value("/mutated_path/bluh"); auto* mut2 = response_header_mutation->add_set_headers(); mut2->mutable_header()->set_key(":scheme"); - mut2->mutable_header()->set_value("https"); + mut2->mutable_header()->set_raw_value("https"); auto* mut3 = response_header_mutation->add_set_headers(); mut3->mutable_header()->set_key(":authority"); - mut3->mutable_header()->set_value("new_host"); + mut3->mutable_header()->set_raw_value("new_host"); auto* mut4 = response_header_mutation->add_set_headers(); mut4->mutable_header()->set_key(":method"); - mut4->mutable_header()->set_value("POST"); + mut4->mutable_header()->set_raw_value("POST"); return true; }); @@ -1170,7 +1167,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeadersWithLogging) { auto response_header_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* mut1 = response_header_mutation->add_set_headers(); mut1->mutable_header()->set_key("x-new-header"); - mut1->mutable_header()->set_value("new"); + mut1->mutable_header()->set_raw_value("new"); return true; }); @@ -1212,11 +1209,10 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeadersNonUtf8WithValueInString) { {":method", "GET"}, {"host", "host"}, {":path", "/"}, - {"x-bad-utf8", "valid_prefix!(valid_suffix"}, + {"x-bad-utf8", "valid_prefix\303(valid_suffix"}, {"x-forwarded-proto", "http"}}; for (const auto& header : headers.headers().headers()) { - EXPECT_TRUE(!header.value().empty()); - EXPECT_TRUE(header.raw_value().empty()); + EXPECT_TRUE(!header.raw_value().empty()); } EXPECT_THAT(headers.headers(), HeaderProtosEqual(expected_request_headers)); @@ -1246,8 +1242,6 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeadersNonUtf8WithValueInString) { TEST_P(ExtProcIntegrationTest, GetAndSetHeadersNonUtf8WithValueInBytes) { proto_config_.mutable_processing_mode()->set_response_header_mode(ProcessingMode::SKIP); - // Set up runtime flag to have header value encoded in raw_value. - header_raw_value_ = "true"; initializeConfig(); HttpIntegrationTest::initialize(); auto response = sendDownstreamRequest([](Http::HeaderMap& headers) { @@ -1272,7 +1266,6 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeadersNonUtf8WithValueInBytes) { {"x-bad-utf8", "valid_prefix\303(valid_suffix"}, {"x-forwarded-proto", "http"}}; for (const auto& header : headers.headers().headers()) { - EXPECT_TRUE(header.value().empty()); EXPECT_TRUE(!header.raw_value().empty()); } EXPECT_THAT(headers.headers(), HeaderProtosEqual(expected_request_headers)); @@ -1300,26 +1293,6 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeadersNonUtf8WithValueInBytes) { verifyDownstreamResponse(*response, 200); } -TEST_P(ExtProcIntegrationTest, BothValueAndValueBytesAreSetInHeaderValueWrong) { - proto_config_.mutable_processing_mode()->set_response_header_mode(ProcessingMode::SKIP); - // Set up runtime flag to have header value encoded in raw_value. - header_raw_value_ = "true"; - initializeConfig(); - HttpIntegrationTest::initialize(); - auto response = sendDownstreamRequest(absl::nullopt); - - processRequestHeadersMessage( - *grpc_upstreams_[0], true, [](const HttpHeaders&, HeadersResponse& headers_resp) { - auto response_header_mutation = headers_resp.mutable_response()->mutable_header_mutation(); - auto* mut1 = response_header_mutation->add_set_headers(); - mut1->mutable_header()->set_key("x-new-header"); - mut1->mutable_header()->set_value("foo"); - mut1->mutable_header()->set_raw_value("bar"); - return true; - }); - verifyDownstreamResponse(*response, 500); -} - // Test the filter with body buffering turned on, but sending a GET // and a response that both have no body. TEST_P(ExtProcIntegrationTest, GetBufferedButNoBodies) { @@ -1458,7 +1431,7 @@ TEST_P(ExtProcIntegrationTest, RemoveResponseContentLengthAfterBodyProcessing) { auto* content_length = headers_resp.mutable_response()->mutable_header_mutation()->add_set_headers(); content_length->mutable_header()->set_key("content-length"); - content_length->mutable_header()->set_value("13"); + content_length->mutable_header()->set_raw_value("13"); return true; }); @@ -1493,7 +1466,7 @@ TEST_P(ExtProcIntegrationTest, MismatchedContentLengthAndBodyLength) { auto* content_length = headers_resp.mutable_response()->mutable_header_mutation()->add_set_headers(); content_length->mutable_header()->set_key("content-length"); - content_length->mutable_header()->set_value(absl::StrCat(set_content_length)); + content_length->mutable_header()->set_raw_value(absl::StrCat(set_content_length)); return true; }); @@ -1524,10 +1497,10 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeadersOnResponse) { auto* response_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* add1 = response_mutation->add_set_headers(); add1->mutable_header()->set_key("x-response-processed"); - add1->mutable_header()->set_value("1"); + add1->mutable_header()->set_raw_value("1"); auto* add2 = response_mutation->add_set_headers(); add2->mutable_header()->set_key(":status"); - add2->mutable_header()->set_value("201"); + add2->mutable_header()->set_raw_value("201"); return true; }); @@ -1550,10 +1523,10 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeadersOnResponseBadStatus) { auto* response_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* add1 = response_mutation->add_set_headers(); add1->mutable_header()->set_key("x-response-processed"); - add1->mutable_header()->set_value("1"); + add1->mutable_header()->set_raw_value("1"); auto* add2 = response_mutation->add_set_headers(); add2->mutable_header()->set_key(":status"); - add2->mutable_header()->set_value("100"); + add2->mutable_header()->set_raw_value("100"); return true; }); @@ -1579,13 +1552,13 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeadersOnResponseTwoStatuses) { auto* response_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* add1 = response_mutation->add_set_headers(); add1->mutable_header()->set_key("x-response-processed"); - add1->mutable_header()->set_value("1"); + add1->mutable_header()->set_raw_value("1"); auto* add2 = response_mutation->add_set_headers(); add2->mutable_header()->set_key(":status"); - add2->mutable_header()->set_value("201"); + add2->mutable_header()->set_raw_value("201"); auto* add3 = response_mutation->add_set_headers(); add3->mutable_header()->set_key(":status"); - add3->mutable_header()->set_value("202"); + add3->mutable_header()->set_raw_value("202"); add3->mutable_append()->set_value(true); return true; }); @@ -1615,7 +1588,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeadersAndTrailersOnResponse) { auto* trailer_mut = resp.mutable_header_mutation(); auto* trailer_add = trailer_mut->add_set_headers(); trailer_add->mutable_header()->set_key("x-modified-trailers"); - trailer_add->mutable_header()->set_value("xxx"); + trailer_add->mutable_header()->set_raw_value("xxx"); return true; }); @@ -1644,7 +1617,7 @@ TEST_P(ExtProcIntegrationTest, DISABLED_GetAndSetTrailersIncorrectlyOnResponse) *grpc_upstreams_[0], false, [](const HttpTrailers&, TrailersResponse& resp) { auto* trailer_add = resp.mutable_header_mutation()->add_set_headers(); trailer_add->mutable_header()->set_key("x-modified-trailers"); - trailer_add->mutable_header()->set_value("xxx"); + trailer_add->mutable_header()->set_raw_value("xxx"); return true; }); @@ -1673,7 +1646,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetOnlyTrailersOnResponse) { auto* trailer_mut = resp.mutable_header_mutation(); auto* trailer_add = trailer_mut->add_set_headers(); trailer_add->mutable_header()->set_key("x-modified-trailers"); - trailer_add->mutable_header()->set_value("xxx"); + trailer_add->mutable_header()->set_raw_value("xxx"); return true; }); @@ -1699,7 +1672,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetBodyAndHeadersOnResponse) { auto* content_length = headers_resp.mutable_response()->mutable_header_mutation()->add_set_headers(); content_length->mutable_header()->set_key("content-length"); - content_length->mutable_header()->set_value("13"); + content_length->mutable_header()->set_raw_value("13"); return true; }); @@ -1712,7 +1685,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetBodyAndHeadersOnResponse) { auto* header_mut = body_resp.mutable_response()->mutable_header_mutation(); auto* header_add = header_mut->add_set_headers(); header_add->mutable_header()->set_key("x-testing-response-header"); - header_add->mutable_header()->set_value("Yes"); + header_add->mutable_header()->set_raw_value("Yes"); return true; }); @@ -1760,7 +1733,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetBodyAndHeadersOnResponsePartialBuffered) auto* content_length = headers_resp.mutable_response()->mutable_header_mutation()->add_set_headers(); content_length->mutable_header()->set_key("content-length"); - content_length->mutable_header()->set_value("100"); + content_length->mutable_header()->set_raw_value("100"); return true; }); // Should get just one message with the body @@ -1770,7 +1743,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetBodyAndHeadersOnResponsePartialBuffered) auto* header_mut = body_resp.mutable_response()->mutable_header_mutation(); auto* header_add = header_mut->add_set_headers(); header_add->mutable_header()->set_key("x-testing-response-header"); - header_add->mutable_header()->set_value("Yes"); + header_add->mutable_header()->set_raw_value("Yes"); return true; }); @@ -1807,7 +1780,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetBodyAndHeadersAndTrailersOnResponse) { auto* trailer_mut = resp.mutable_header_mutation(); auto* trailer_add = trailer_mut->add_set_headers(); trailer_add->mutable_header()->set_key("x-modified-trailers"); - trailer_add->mutable_header()->set_value("xxx"); + trailer_add->mutable_header()->set_raw_value("xxx"); return true; }); @@ -1870,7 +1843,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetBodyAndHeadersOnBigResponse) { auto* header_mut = body_resp.mutable_response()->mutable_header_mutation(); auto* header_add = header_mut->add_set_headers(); header_add->mutable_header()->set_key("x-testing-response-header"); - header_add->mutable_header()->set_value("Yes"); + header_add->mutable_header()->set_raw_value("Yes"); return true; }); @@ -1893,7 +1866,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetBodyOnBoth) { auto* content_length = headers_resp.mutable_response()->mutable_header_mutation()->add_set_headers(); content_length->mutable_header()->set_key("content-length"); - content_length->mutable_header()->set_value("13"); + content_length->mutable_header()->set_raw_value("13"); return true; }); @@ -1939,7 +1912,7 @@ TEST_P(ExtProcIntegrationTest, ProcessingModeResponseOnly) { auto* response_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* add1 = response_mutation->add_set_headers(); add1->mutable_header()->set_key("x-response-processed"); - add1->mutable_header()->set_value("1"); + add1->mutable_header()->set_raw_value("1"); return true; }); @@ -1962,10 +1935,10 @@ TEST_P(ExtProcIntegrationTest, GetAndRespondImmediately) { immediate.set_details("Failed because you are not authorized"); auto* hdr1 = immediate.mutable_headers()->add_set_headers(); hdr1->mutable_header()->set_key("x-failure-reason"); - hdr1->mutable_header()->set_value("testing"); + hdr1->mutable_header()->set_raw_value("testing"); auto* hdr2 = immediate.mutable_headers()->add_set_headers(); hdr2->mutable_header()->set_key("content-type"); - hdr2->mutable_header()->set_value("application/json"); + hdr2->mutable_header()->set_raw_value("application/json"); }); verifyDownstreamResponse(*response, 401); @@ -1986,10 +1959,10 @@ TEST_P(ExtProcIntegrationTest, GetAndRespondImmediatelyWithLogging) { immediate.set_details("Failed because you are not authorized"); auto* hdr1 = immediate.mutable_headers()->add_set_headers(); hdr1->mutable_header()->set_key("x-failure-reason"); - hdr1->mutable_header()->set_value("testing"); + hdr1->mutable_header()->set_raw_value("testing"); auto* hdr2 = immediate.mutable_headers()->add_set_headers(); hdr2->mutable_header()->set_key("content-type"); - hdr2->mutable_header()->set_value("application/json"); + hdr2->mutable_header()->set_raw_value("application/json"); }); verifyDownstreamResponse(*response, 401); @@ -2007,7 +1980,7 @@ TEST_P(ExtProcIntegrationTest, GetAndRespondImmediatelyWithInvalidCharacter) { immediate.mutable_status()->set_code(envoy::type::v3::StatusCode::Unauthorized); auto* hdr = immediate.mutable_headers()->add_set_headers(); hdr->mutable_header()->set_key("x-failure-reason\n"); - hdr->mutable_header()->set_value("testing"); + hdr->mutable_header()->set_raw_value("testing"); }); verifyDownstreamResponse(*response, 401); @@ -2189,7 +2162,7 @@ TEST_P(ExtProcIntegrationTest, GetAndRespondImmediatelyWithSystemHeaderMutation) auto* hdr = immediate.mutable_headers()->add_set_headers(); // Adding system header in the ext_proc response. hdr->mutable_header()->set_key(":foo"); - hdr->mutable_header()->set_value("bar"); + hdr->mutable_header()->set_raw_value("bar"); }); verifyDownstreamResponse(*response, 401); // The added system header is not sent to the client. @@ -2210,7 +2183,7 @@ TEST_P(ExtProcIntegrationTest, GetAndRespondImmediatelyWithEnvoyHeaderMutation) auto* hdr = immediate.mutable_headers()->add_set_headers(); // Adding x-envoy header is not allowed. hdr->mutable_header()->set_key("x-envoy-foo"); - hdr->mutable_header()->set_value("bar"); + hdr->mutable_header()->set_raw_value("bar"); }); verifyDownstreamResponse(*response, 401); EXPECT_THAT(response->headers(), HasNoHeader("x-envoy-foo")); @@ -2228,10 +2201,10 @@ TEST_P(ExtProcIntegrationTest, GetAndImmediateRespondMutationAllowEnvoy) { immediate.mutable_status()->set_code(envoy::type::v3::StatusCode::Unauthorized); auto* hdr = immediate.mutable_headers()->add_set_headers(); hdr->mutable_header()->set_key("x-envoy-foo"); - hdr->mutable_header()->set_value("bar"); + hdr->mutable_header()->set_raw_value("bar"); auto* hdr1 = immediate.mutable_headers()->add_set_headers(); hdr1->mutable_header()->set_key("host"); - hdr1->mutable_header()->set_value("test"); + hdr1->mutable_header()->set_raw_value("test"); }); verifyDownstreamResponse(*response, 401); @@ -2255,7 +2228,7 @@ TEST_P(ExtProcIntegrationTest, GetAndRespondImmediatelyWithDefaultHeaderMutation auto* hdr = immediate.mutable_headers()->add_set_headers(); // Adding x-envoy header is allowed since default overrides config. hdr->mutable_header()->set_key("x-envoy-foo"); - hdr->mutable_header()->set_value("bar"); + hdr->mutable_header()->set_raw_value("bar"); }); verifyDownstreamResponse(*response, 401); EXPECT_FALSE(response->headers().get(LowerCaseString("x-envoy-foo")).empty()); @@ -2276,7 +2249,7 @@ TEST_P(ExtProcIntegrationTest, GetAndIncorrectlyModifyHeaderOnBody) { EXPECT_TRUE(body.end_of_stream()); auto* mut = response.mutable_response()->mutable_header_mutation()->add_set_headers(); mut->mutable_header()->set_key(":scheme"); - mut->mutable_header()->set_value("tcp"); + mut->mutable_header()->set_raw_value("tcp"); return true; }); @@ -2298,7 +2271,7 @@ TEST_P(ExtProcIntegrationTest, GetAndIncorrectlyModifyHeaderOnBodyPartialBuffer) EXPECT_TRUE(body.end_of_stream()); auto* mut = response.mutable_response()->mutable_header_mutation()->add_set_headers(); mut->mutable_header()->set_key(":scheme"); - mut->mutable_header()->set_value("tcp"); + mut->mutable_header()->set_raw_value("tcp"); return true; }); @@ -2318,10 +2291,10 @@ TEST_P(ExtProcIntegrationTest, ConvertGetToPost) { auto* header_mut = headers_resp.mutable_response()->mutable_header_mutation(); auto* method = header_mut->add_set_headers(); method->mutable_header()->set_key(":method"); - method->mutable_header()->set_value("POST"); + method->mutable_header()->set_raw_value("POST"); auto* content_type = header_mut->add_set_headers(); content_type->mutable_header()->set_key("content-type"); - content_type->mutable_header()->set_value("text/plain"); + content_type->mutable_header()->set_raw_value("text/plain"); headers_resp.mutable_response()->mutable_body_mutation()->set_body("Hello, Server!"); // This special status tells us to replace the whole request headers_resp.mutable_response()->set_status(CommonResponse::CONTINUE_AND_REPLACE); @@ -2962,10 +2935,10 @@ TEST_P(ExtProcIntegrationTest, PerRouteGrpcService) { auto* response_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* add1 = response_mutation->add_set_headers(); add1->mutable_header()->set_key("x-response-processed"); - add1->mutable_header()->set_value("1"); + add1->mutable_header()->set_raw_value("1"); auto* add2 = response_mutation->add_set_headers(); add2->mutable_header()->set_key(":status"); - add2->mutable_header()->set_value("201"); + add2->mutable_header()->set_raw_value("201"); return true; }); verifyDownstreamResponse(*response, 201); @@ -3039,7 +3012,7 @@ TEST_P(ExtProcIntegrationTest, RequestAndResponseMessageNewTimeoutWithHeaderMuta auto response_header_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* mut1 = response_header_mutation->add_set_headers(); mut1->mutable_header()->set_key("x-new-header"); - mut1->mutable_header()->set_value("new"); + mut1->mutable_header()->set_raw_value("new"); response_header_mutation->add_remove_headers("x-remove-this"); return true; }); @@ -3403,7 +3376,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetBodyOnBothWithClearRouteCache) { auto* content_length = headers_resp.mutable_response()->mutable_header_mutation()->add_set_headers(); content_length->mutable_header()->set_key("content-length"); - content_length->mutable_header()->set_value("13"); + content_length->mutable_header()->set_raw_value("13"); headers_resp.mutable_response()->set_clear_route_cache(true); return true; }); @@ -3435,7 +3408,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetBodyOnBothWithClearRouteCache) { auto* header_mut = body_resp.mutable_response()->mutable_header_mutation(); auto* header_add = header_mut->add_set_headers(); header_add->mutable_header()->set_key("x-testing-response-header"); - header_add->mutable_header()->set_value("Yes"); + header_add->mutable_header()->set_raw_value("Yes"); body_resp.mutable_response()->set_clear_route_cache(true); return true; }); @@ -3989,7 +3962,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeadersUpstream) { auto response_header_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* mut1 = response_header_mutation->add_set_headers(); mut1->mutable_header()->set_key("x-new-header"); - mut1->mutable_header()->set_value("new"); + mut1->mutable_header()->set_raw_value("new"); response_header_mutation->add_remove_headers("x-remove-this"); return true; }); @@ -4023,7 +3996,6 @@ TEST_P(ExtProcIntegrationTest, RetryOnResponseError) { proto_config_.mutable_message_timeout()->set_seconds(5); proto_config_.mutable_max_message_timeout()->set_seconds(10); - header_raw_value_ = "true"; envoy::config::core::v3::RetryPolicy* retry_policy = proto_config_.mutable_grpc_service()->mutable_retry_policy(); retry_policy->mutable_num_retries()->set_value(1); @@ -4078,7 +4050,6 @@ TEST_P(ExtProcIntegrationTest, RetryOnDifferentHost) { proto_config_.mutable_message_timeout()->set_seconds(5); proto_config_.mutable_max_message_timeout()->set_seconds(10); - header_raw_value_ = "true"; envoy::config::core::v3::RetryPolicy* retry_policy = proto_config_.mutable_grpc_service()->mutable_retry_policy(); retry_policy->mutable_num_retries()->set_value(2); @@ -4167,7 +4138,7 @@ TEST_P(ExtProcIntegrationTest, ObservabilityModeWithHeader) { auto* response_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* add1 = response_mutation->add_set_headers(); add1->mutable_header()->set_key("x-response-processed"); - add1->mutable_header()->set_value("1"); + add1->mutable_header()->set_raw_value("1"); return true; }); @@ -4277,7 +4248,7 @@ TEST_P(ExtProcIntegrationTest, ObservabilityModeWithTrailer) { auto* trailer_mut = resp.mutable_header_mutation(); auto* trailer_add = trailer_mut->add_set_headers(); trailer_add->mutable_header()->set_key("x-modified-trailers"); - trailer_add->mutable_header()->set_value("xxx"); + trailer_add->mutable_header()->set_raw_value("xxx"); return true; }); @@ -4418,7 +4389,7 @@ TEST_P(ExtProcIntegrationTest, GetAndSetHeadersUpstreamObservabilityMode) { auto response_header_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* mut1 = response_header_mutation->add_set_headers(); mut1->mutable_header()->set_key("x-new-header"); - mut1->mutable_header()->set_value("new"); + mut1->mutable_header()->set_raw_value("new"); response_header_mutation->add_remove_headers("x-remove-this"); return true; }); @@ -4490,7 +4461,7 @@ TEST_P(ExtProcIntegrationTest, DISABLED_GetAndSetHeadersUpstreamObservabilityMod auto response_header_mutation = headers_resp.mutable_response()->mutable_header_mutation(); auto* mut1 = response_header_mutation->add_set_headers(); mut1->mutable_header()->set_key("x-new-header"); - mut1->mutable_header()->set_value("new"); + mut1->mutable_header()->set_raw_value("new"); response_header_mutation->add_remove_headers("x-remove-this"); return true; }); diff --git a/test/extensions/filters/http/ext_proc/filter_test.cc b/test/extensions/filters/http/ext_proc/filter_test.cc index 389c470e89ff..df23483ac3b1 100644 --- a/test/extensions/filters/http/ext_proc/filter_test.cc +++ b/test/extensions/filters/http/ext_proc/filter_test.cc @@ -30,7 +30,6 @@ #include "test/mocks/tracing/mocks.h" #include "test/mocks/upstream/cluster_manager.h" #include "test/test_common/printers.h" -#include "test/test_common/test_runtime.h" #include "test/test_common/utility.h" #include "gmock/gmock.h" @@ -90,7 +89,6 @@ static const std::string filter_config_name = "scooby.dooby.doo"; class HttpFilterTest : public testing::Test { protected: void initialize(std::string&& yaml, bool is_upstream_filter = false) { - scoped_runtime_.mergeValues({{"envoy.reloadable_features.send_header_raw_value", "false"}}); client_ = std::make_unique(); route_ = std::make_shared>(); EXPECT_CALL(*client_, start(_, _, _, _)).WillOnce(Invoke(this, &HttpFilterTest::doStart)); @@ -615,7 +613,6 @@ class HttpFilterTest : public testing::Test { TestResponseTrailerMapImpl response_trailers_; std::vector timers_; Event::MockTimer* deferred_close_timer_; - TestScopedRuntime scoped_runtime_; Envoy::Event::SimulatedTimeSystem* test_time_; envoy::config::core::v3::Metadata dynamic_metadata_; testing::NiceMock connection_; @@ -711,11 +708,11 @@ TEST_F(HttpFilterTest, PostAndChangeHeaders) { auto headers_mut = header_resp.mutable_response()->mutable_header_mutation(); auto add1 = headers_mut->add_set_headers(); add1->mutable_header()->set_key("x-new-header"); - add1->mutable_header()->set_value("new"); + add1->mutable_header()->set_raw_value("new"); add1->mutable_append()->set_value(false); auto add2 = headers_mut->add_set_headers(); add2->mutable_header()->set_key("x-some-other-header"); - add2->mutable_header()->set_value("no"); + add2->mutable_header()->set_raw_value("no"); add2->mutable_append()->set_value(true); *headers_mut->add_remove_headers() = "x-do-we-want-this"; }); @@ -750,7 +747,7 @@ TEST_F(HttpFilterTest, PostAndChangeHeaders) { auto* resp_headers_mut = header_resp.mutable_response()->mutable_header_mutation(); auto* resp_add1 = resp_headers_mut->add_set_headers(); resp_add1->mutable_header()->set_key("x-new-header"); - resp_add1->mutable_header()->set_value("new"); + resp_add1->mutable_header()->set_raw_value("new"); }); // We should now have changed the original header a bit @@ -801,15 +798,15 @@ TEST_F(HttpFilterTest, PostAndRespondImmediately) { auto* immediate_headers = immediate_response->mutable_headers(); auto* hdr1 = immediate_headers->add_set_headers(); hdr1->mutable_header()->set_key("content-type"); - hdr1->mutable_header()->set_value("text/plain"); + hdr1->mutable_header()->set_raw_value("text/plain"); auto* hdr2 = immediate_headers->add_set_headers(); hdr2->mutable_append()->set_value(true); hdr2->mutable_header()->set_key("x-another-thing"); - hdr2->mutable_header()->set_value("1"); + hdr2->mutable_header()->set_raw_value("1"); auto* hdr3 = immediate_headers->add_set_headers(); hdr3->mutable_append()->set_value(true); hdr3->mutable_header()->set_key("x-another-thing"); - hdr3->mutable_header()->set_value("2"); + hdr3->mutable_header()->set_raw_value("2"); stream_callbacks_->onReceiveMessage(std::move(resp1)); TestResponseHeaderMapImpl expected_response_headers{ @@ -856,7 +853,7 @@ TEST_F(HttpFilterTest, PostAndRespondImmediatelyWithDisabledConfig) { auto* immediate_headers = immediate_response->mutable_headers(); auto* hdr1 = immediate_headers->add_set_headers(); hdr1->mutable_header()->set_key("content-type"); - hdr1->mutable_header()->set_value("text/plain"); + hdr1->mutable_header()->set_raw_value("text/plain"); stream_callbacks_->onReceiveMessage(std::move(resp1)); Buffer::OwnedImpl req_data("foo"); @@ -2729,7 +2726,7 @@ TEST_F(HttpFilterTest, ClearRouteCacheHeaderMutation) { auto* resp_headers_mut = resp.mutable_response()->mutable_header_mutation(); auto* resp_add = resp_headers_mut->add_set_headers(); resp_add->mutable_header()->set_key("x-new-header"); - resp_add->mutable_header()->set_value("new"); + resp_add->mutable_header()->set_raw_value("new"); resp.mutable_response()->set_clear_route_cache(true); }); @@ -2746,7 +2743,7 @@ TEST_F(HttpFilterTest, ClearRouteCacheHeaderMutation) { auto* resp_headers_mut = resp.mutable_response()->mutable_header_mutation(); auto* resp_add = resp_headers_mut->add_set_headers(); resp_add->mutable_header()->set_key("x-new-header"); - resp_add->mutable_header()->set_value("new"); + resp_add->mutable_header()->set_raw_value("new"); resp.mutable_response()->set_clear_route_cache(true); }); @@ -2779,7 +2776,7 @@ TEST_F(HttpFilterTest, ClearRouteCacheDisabledHeaderMutation) { auto* resp_headers_mut = resp.mutable_response()->mutable_header_mutation(); auto* resp_add = resp_headers_mut->add_set_headers(); resp_add->mutable_header()->set_key("x-new-header"); - resp_add->mutable_header()->set_value("new"); + resp_add->mutable_header()->set_raw_value("new"); resp.mutable_response()->set_clear_route_cache(true); }); @@ -2796,7 +2793,7 @@ TEST_F(HttpFilterTest, ClearRouteCacheDisabledHeaderMutation) { auto* resp_headers_mut = resp.mutable_response()->mutable_header_mutation(); auto* resp_add = resp_headers_mut->add_set_headers(); resp_add->mutable_header()->set_key("x-new-header"); - resp_add->mutable_header()->set_value("new"); + resp_add->mutable_header()->set_raw_value("new"); resp.mutable_response()->set_clear_route_cache(true); }); @@ -2929,7 +2926,7 @@ TEST_F(HttpFilterTest, FilterRouteCacheActionSetToClearHeaderMutation) { auto* resp_headers_mut = resp.mutable_response()->mutable_header_mutation(); auto* resp_add = resp_headers_mut->add_set_headers(); resp_add->mutable_header()->set_key("x-new-header"); - resp_add->mutable_header()->set_value("new"); + resp_add->mutable_header()->set_raw_value("new"); }); EXPECT_EQ(FilterHeadersStatus::StopIteration, filter_->encodeHeaders(response_headers_, false)); @@ -3008,7 +3005,7 @@ TEST_F(HttpFilterTest, FilterRouteCacheActionSetToRetainWithHeaderMutation) { auto* resp_headers_mut = resp.mutable_response()->mutable_header_mutation(); auto* resp_add = resp_headers_mut->add_set_headers(); resp_add->mutable_header()->set_key("x-new-header"); - resp_add->mutable_header()->set_value("new"); + resp_add->mutable_header()->set_raw_value("new"); resp.mutable_response()->set_clear_route_cache(true); }); @@ -3036,7 +3033,7 @@ TEST_F(HttpFilterTest, FilterRouteCacheActionSetToRetainResponseNotWithHeaderMut auto* resp_headers_mut = resp.mutable_response()->mutable_header_mutation(); auto* resp_add = resp_headers_mut->add_set_headers(); resp_add->mutable_header()->set_key("x-new-header"); - resp_add->mutable_header()->set_value("new"); + resp_add->mutable_header()->set_raw_value("new"); }); EXPECT_EQ(FilterHeadersStatus::StopIteration, filter_->encodeHeaders(response_headers_, false)); @@ -3067,7 +3064,7 @@ TEST_F(HttpFilterTest, ReplaceRequest) { hdrs_resp.mutable_response()->set_status(CommonResponse::CONTINUE_AND_REPLACE); auto* hdr = hdrs_resp.mutable_response()->mutable_header_mutation()->add_set_headers(); hdr->mutable_header()->set_key(":method"); - hdr->mutable_header()->set_value("POST"); + hdr->mutable_header()->set_raw_value("POST"); hdrs_resp.mutable_response()->mutable_body_mutation()->set_body("Hello, World!"); }); @@ -3128,7 +3125,7 @@ TEST_F(HttpFilterTest, ReplaceCompleteResponseBuffered) { hdrs_resp.mutable_response()->set_status(CommonResponse::CONTINUE_AND_REPLACE); auto* hdr = hdrs_resp.mutable_response()->mutable_header_mutation()->add_set_headers(); hdr->mutable_header()->set_key("x-test-header"); - hdr->mutable_header()->set_value("true"); + hdr->mutable_header()->set_raw_value("true"); hdrs_resp.mutable_response()->mutable_body_mutation()->set_body("Hello, World!"); }); @@ -3331,7 +3328,7 @@ TEST_F(HttpFilterTest, IgnoreInvalidHeaderMutations) { auto add1 = headers_mut->add_set_headers(); // Not allowed to change the "host" header by default add1->mutable_header()->set_key("Host"); - add1->mutable_header()->set_value("wrong:1234"); + add1->mutable_header()->set_raw_value("wrong:1234"); // Not allowed to remove x-envoy headers by default. headers_mut->add_remove_headers("x-envoy-special-thing"); }); @@ -3379,7 +3376,7 @@ TEST_F(HttpFilterTest, FailOnInvalidHeaderMutations) { auto add1 = headers_mut->add_set_headers(); // Not allowed to change the "host" header by default add1->mutable_header()->set_key("Host"); - add1->mutable_header()->set_value("wrong:1234"); + add1->mutable_header()->set_raw_value("wrong:1234"); // Not allowed to remove x-envoy headers by default. headers_mut->add_remove_headers("x-envoy-special-thing"); stream_callbacks_->onReceiveMessage(std::move(resp1)); @@ -3421,10 +3418,10 @@ TEST_F(HttpFilterTest, ResponseTrailerMutationExceedSizeLimit) { // size limit 2kb. But the result header map size exceeds the count limit 2kb. auto add1 = headers_mut->add_set_headers(); add1->mutable_header()->set_key("x-new-header-0123456789"); - add1->mutable_header()->set_value("new-header-0123456789"); + add1->mutable_header()->set_raw_value("new-header-0123456789"); auto add2 = headers_mut->add_set_headers(); add2->mutable_header()->set_key("x-some-other-header-0123456789"); - add2->mutable_header()->set_value("some-new-header-0123456789"); + add2->mutable_header()->set_raw_value("some-new-header-0123456789"); }, false); filter_->onDestroy(); @@ -3987,7 +3984,7 @@ TEST_F(HttpFilterTest, ClearRouteCacheHeaderMutationUpstreamIgnored) { auto* resp_headers_mut = resp.mutable_response()->mutable_header_mutation(); auto* resp_add = resp_headers_mut->add_set_headers(); resp_add->mutable_header()->set_key("x-new-header"); - resp_add->mutable_header()->set_value("new"); + resp_add->mutable_header()->set_raw_value("new"); resp.mutable_response()->set_clear_route_cache(true); }); @@ -4030,7 +4027,7 @@ TEST_F(HttpFilterTest, PostAndRespondImmediatelyUpstream) { auto* immediate_headers = immediate_response->mutable_headers(); auto* hdr1 = immediate_headers->add_set_headers(); hdr1->mutable_header()->set_key("content-type"); - hdr1->mutable_header()->set_value("text/plain"); + hdr1->mutable_header()->set_raw_value("text/plain"); stream_callbacks_->onReceiveMessage(std::move(resp1)); TestResponseHeaderMapImpl expected_response_headers{}; // Send local reply never happened. @@ -4324,10 +4321,10 @@ TEST_F(HttpFilter2Test, LastDecodeDataCallExceedsStreamBufferLimitWouldJustRaise auto* hdr = headers_response->mutable_response()->mutable_header_mutation()->add_set_headers(); hdr->mutable_header()->set_key("foo"); - hdr->mutable_header()->set_value("gift-from-external-server"); + hdr->mutable_header()->set_raw_value("gift-from-external-server"); hdr = headers_response->mutable_response()->mutable_header_mutation()->add_set_headers(); hdr->mutable_header()->set_key(":path"); - hdr->mutable_header()->set_value("/mutated_path/bluh"); + hdr->mutable_header()->set_raw_value("/mutated_path/bluh"); HttpFilterTest::stream_callbacks_->onReceiveMessage(std::move(response)); return ::Envoy::Http::okStatus(); @@ -4429,10 +4426,10 @@ TEST_F(HttpFilter2Test, LastEncodeDataCallExceedsStreamBufferLimitWouldJustRaise auto* hdr = headers_response->mutable_response()->mutable_header_mutation()->add_set_headers(); hdr->mutable_header()->set_key("foo"); - hdr->mutable_header()->set_value("gift-from-external-server"); + hdr->mutable_header()->set_raw_value("gift-from-external-server"); hdr = headers_response->mutable_response()->mutable_header_mutation()->add_set_headers(); hdr->mutable_header()->set_key("new_response_header"); - hdr->mutable_header()->set_value("bluh"); + hdr->mutable_header()->set_raw_value("bluh"); HttpFilterTest::stream_callbacks_->onReceiveMessage(std::move(response)); return FilterHeadersStatus::StopIteration; })); diff --git a/test/extensions/filters/http/ext_proc/mutation_utils_test.cc b/test/extensions/filters/http/ext_proc/mutation_utils_test.cc index c3876ce96233..ea0efe3b6cf2 100644 --- a/test/extensions/filters/http/ext_proc/mutation_utils_test.cc +++ b/test/extensions/filters/http/ext_proc/mutation_utils_test.cc @@ -6,7 +6,6 @@ #include "test/extensions/filters/http/ext_proc/utils.h" #include "test/mocks/server/server_factory_context.h" #include "test/mocks/stats/mocks.h" -#include "test/test_common/test_runtime.h" #include "test/test_common/utility.h" #include "gtest/gtest.h" @@ -56,8 +55,6 @@ TEST_F(MutationUtilsTest, TestBuildHeaders) { } TEST_F(MutationUtilsTest, TestApplyMutations) { - TestScopedRuntime scoped_runtime; - scoped_runtime.mergeValues({{"envoy.reloadable_features.send_header_raw_value", "false"}}); Http::TestRequestHeaderMapImpl headers{ {":scheme", "https"}, {":method", "GET"}, @@ -75,27 +72,27 @@ TEST_F(MutationUtilsTest, TestApplyMutations) { auto* s = mutation.add_set_headers(); s->mutable_append()->set_value(true); s->mutable_header()->set_key("x-append-this"); - s->mutable_header()->set_value("2"); + s->mutable_header()->set_raw_value("2"); s = mutation.add_set_headers(); s->mutable_append()->set_value(true); s->mutable_header()->set_key("x-append-this"); - s->mutable_header()->set_value("3"); + s->mutable_header()->set_raw_value("3"); s = mutation.add_set_headers(); s->mutable_append()->set_value(true); s->mutable_header()->set_key("x-remove-and-append-this"); - s->mutable_header()->set_value("4"); + s->mutable_header()->set_raw_value("4"); s = mutation.add_set_headers(); s->mutable_append()->set_value(false); s->mutable_header()->set_key("x-replace-this"); - s->mutable_header()->set_value("no"); + s->mutable_header()->set_raw_value("no"); s = mutation.add_set_headers(); s->mutable_header()->set_key(":status"); - s->mutable_header()->set_value("418"); + s->mutable_header()->set_raw_value("418"); // Default of "append" is "false" and mutations // are applied in order. s = mutation.add_set_headers(); s->mutable_header()->set_key("x-replace-this"); - s->mutable_header()->set_value("nope"); + s->mutable_header()->set_raw_value("nope"); // Incomplete structures should be ignored mutation.add_set_headers(); @@ -111,31 +108,31 @@ TEST_F(MutationUtilsTest, TestApplyMutations) { // should be ignored until we explicitly allow them. s = mutation.add_set_headers(); s->mutable_header()->set_key("host"); - s->mutable_header()->set_value("invalid:123"); + s->mutable_header()->set_raw_value("invalid:123"); s = mutation.add_set_headers(); s->mutable_header()->set_key("Host"); - s->mutable_header()->set_value("invalid:456"); + s->mutable_header()->set_raw_value("invalid:456"); s = mutation.add_set_headers(); s->mutable_header()->set_key(":authority"); - s->mutable_header()->set_value("invalid:789"); + s->mutable_header()->set_raw_value("invalid:789"); s = mutation.add_set_headers(); s->mutable_header()->set_key(":method"); - s->mutable_header()->set_value("PATCH"); + s->mutable_header()->set_raw_value("PATCH"); s = mutation.add_set_headers(); s->mutable_header()->set_key(":scheme"); - s->mutable_header()->set_value("http"); + s->mutable_header()->set_raw_value("http"); s = mutation.add_set_headers(); s->mutable_header()->set_key("X-Envoy-StrangeThing"); - s->mutable_header()->set_value("Yes"); + s->mutable_header()->set_raw_value("Yes"); // Attempts to set the status header out of range should // also be ignored. s = mutation.add_set_headers(); s->mutable_header()->set_key(":status"); - s->mutable_header()->set_value("This is not even an integer"); + s->mutable_header()->set_raw_value("This is not even an integer"); s = mutation.add_set_headers(); s->mutable_header()->set_key(":status"); - s->mutable_header()->set_value("100"); + s->mutable_header()->set_raw_value("100"); // Use the default mutation rules Checker checker(HeaderMutationRules::default_instance(), regex_engine_); @@ -165,27 +162,25 @@ TEST_F(MutationUtilsTest, TestApplyMutations) { } TEST_F(MutationUtilsTest, TestNonAppendableHeaders) { - TestScopedRuntime scoped_runtime; - scoped_runtime.mergeValues({{"envoy.reloadable_features.send_header_raw_value", "false"}}); Http::TestRequestHeaderMapImpl headers; envoy::service::ext_proc::v3::HeaderMutation mutation; auto* s = mutation.add_set_headers(); s->mutable_append()->set_value(true); s->mutable_header()->set_key(":path"); - s->mutable_header()->set_value("/foo"); + s->mutable_header()->set_raw_value("/foo"); s = mutation.add_set_headers(); s->mutable_header()->set_key(":status"); - s->mutable_header()->set_value("400"); + s->mutable_header()->set_raw_value("400"); // These two should be ignored since we ignore attempts // to set multiple values for system headers. s = mutation.add_set_headers(); s->mutable_append()->set_value(true); s->mutable_header()->set_key(":path"); - s->mutable_header()->set_value("/baz"); + s->mutable_header()->set_raw_value("/baz"); s = mutation.add_set_headers(); s->mutable_append()->set_value(true); s->mutable_header()->set_key(":status"); - s->mutable_header()->set_value("401"); + s->mutable_header()->set_raw_value("401"); // Use the default mutation rules Checker checker(HeaderMutationRules::default_instance(), regex_engine_); @@ -203,8 +198,6 @@ TEST_F(MutationUtilsTest, TestNonAppendableHeaders) { } TEST_F(MutationUtilsTest, TestSetHeaderWithInvalidCharacter) { - TestScopedRuntime scoped_runtime; - scoped_runtime.mergeValues({{"envoy.reloadable_features.send_header_raw_value", "false"}}); Http::TestRequestHeaderMapImpl headers{ {":method", "GET"}, {"host", "localhost:1000"}, @@ -215,7 +208,7 @@ TEST_F(MutationUtilsTest, TestSetHeaderWithInvalidCharacter) { auto* s = mutation.add_set_headers(); // Test header key contains invalid character. s->mutable_header()->set_key("x-append-this\n"); - s->mutable_header()->set_value("value"); + s->mutable_header()->set_raw_value("value"); EXPECT_CALL(rejections, inc()); EXPECT_FALSE( MutationUtils::applyHeaderMutations(mutation, headers, false, checker, rejections).ok()); @@ -224,15 +217,13 @@ TEST_F(MutationUtilsTest, TestSetHeaderWithInvalidCharacter) { s = mutation.add_set_headers(); // Test header value contains invalid character. s->mutable_header()->set_key("x-append-this"); - s->mutable_header()->set_value("value\r"); + s->mutable_header()->set_raw_value("value\r"); EXPECT_CALL(rejections, inc()); EXPECT_FALSE( MutationUtils::applyHeaderMutations(mutation, headers, false, checker, rejections).ok()); } TEST_F(MutationUtilsTest, TestSetHeaderWithContentLength) { - TestScopedRuntime scoped_runtime; - scoped_runtime.mergeValues({{"envoy.reloadable_features.send_header_raw_value", "false"}}); Http::TestRequestHeaderMapImpl headers{ {":scheme", "https"}, {":method", "GET"}, @@ -246,7 +237,7 @@ TEST_F(MutationUtilsTest, TestSetHeaderWithContentLength) { auto* s = mutation.add_set_headers(); // Test header key contains content_length. s->mutable_header()->set_key("content-length"); - s->mutable_header()->set_value("10"); + s->mutable_header()->set_raw_value("10"); EXPECT_TRUE(MutationUtils::applyHeaderMutations(mutation, headers, false, checker, rejections, /*remove_content_length=*/true) diff --git a/test/extensions/filters/http/ext_proc/streaming_integration_test.cc b/test/extensions/filters/http/ext_proc/streaming_integration_test.cc index e8b4182ecd6f..da03a6e69f58 100644 --- a/test/extensions/filters/http/ext_proc/streaming_integration_test.cc +++ b/test/extensions/filters/http/ext_proc/streaming_integration_test.cc @@ -8,7 +8,6 @@ #include "test/extensions/filters/http/ext_proc/test_processor.h" #include "test/extensions/filters/http/ext_proc/utils.h" #include "test/integration/http_integration.h" -#include "test/test_common/test_runtime.h" #include "test/test_common/utility.h" #include "absl/strings/str_format.h" @@ -46,7 +45,6 @@ class StreamingIntegrationTest : public HttpIntegrationTest, } void initializeConfig() { - scoped_runtime_.mergeValues({{"envoy.reloadable_features.send_header_raw_value", "false"}}); skip_tag_extraction_rule_check_ = true; // This enables a built-in automatic upstream server. autonomous_upstream_ = true; @@ -148,7 +146,6 @@ class StreamingIntegrationTest : public HttpIntegrationTest, IntegrationStreamDecoderPtr client_response_; std::atomic processor_request_hash_; std::atomic processor_response_hash_; - TestScopedRuntime scoped_runtime_; }; // Ensure that the test suite is run with all combinations the Envoy and Google gRPC clients. diff --git a/test/extensions/filters/http/ext_proc/utils.cc b/test/extensions/filters/http/ext_proc/utils.cc index 35d9387c14d8..896a3515f7b4 100644 --- a/test/extensions/filters/http/ext_proc/utils.cc +++ b/test/extensions/filters/http/ext_proc/utils.cc @@ -19,11 +19,7 @@ bool ExtProcTestUtility::headerProtosEqualIgnoreOrder( Http::TestRequestHeaderMapImpl actual_headers; for (const auto& header : actual.headers()) { if (!ignoredHeaders().contains(header.key())) { - if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.send_header_raw_value")) { - actual_headers.addCopy(header.key(), header.raw_value()); - } else { - actual_headers.addCopy(header.key(), header.value()); - } + actual_headers.addCopy(header.key(), header.raw_value()); } } return TestUtility::headerMapEqualIgnoreOrder(expected, actual_headers);