From 22a229d88a1896b43d60452740f0f3e2c45a238d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Guti=C3=A9rrez=20Segal=C3=A9s?= Date: Tue, 4 Feb 2020 17:52:43 -0500 Subject: [PATCH 01/87] refactor: move aws signing bits to common/ (#9925) This was under filter/http/common/aws for historical reasons, so moving it to source/extensions/common/aws where it should live. Signed-off-by: Raul Gutierrez Segales --- CODEOWNERS | 2 +- .../{filters/http => }/common/aws/BUILD | 0 .../common/aws/credentials_provider.h | 2 -- .../common/aws/credentials_provider_impl.cc | 4 +--- .../common/aws/credentials_provider_impl.h | 4 +--- .../http => }/common/aws/region_provider.h | 2 -- .../common/aws/region_provider_impl.cc | 4 +--- .../common/aws/region_provider_impl.h | 4 +--- .../{filters/http => }/common/aws/signer.h | 3 --- .../http => }/common/aws/signer_impl.cc | 6 ++--- .../http => }/common/aws/signer_impl.h | 6 ++--- .../{filters/http => }/common/aws/utility.cc | 4 +--- .../{filters/http => }/common/aws/utility.h | 2 -- .../filters/http/aws_request_signing/BUILD | 8 +++---- .../aws_request_signing_filter.cc | 4 ++-- .../aws_request_signing_filter.h | 10 ++++----- .../http/aws_request_signing/config.cc | 12 +++++----- .../extensions/grpc_credentials/aws_iam/BUILD | 8 +++---- .../grpc_credentials/aws_iam/config.cc | 22 +++++++++---------- .../grpc_credentials/aws_iam/config.h | 7 +++--- .../{filters/http => }/common/aws/BUILD | 20 ++++++++--------- .../aws_metadata_fetcher_integration_test.cc | 4 ++-- .../aws/credentials_provider_impl_test.cc | 6 ++--- .../common/aws/credentials_provider_test.cc | 4 +--- .../{filters/http => }/common/aws/mocks.cc | 4 +--- .../{filters/http => }/common/aws/mocks.h | 6 ++--- .../common/aws/region_provider_impl_test.cc | 4 +--- .../http => }/common/aws/signer_impl_test.cc | 8 +++---- .../http => }/common/aws/utility_test.cc | 4 +--- .../aws_request_signing_filter_test.cc | 4 ++-- tools/check_format.py | 2 +- 31 files changed, 70 insertions(+), 110 deletions(-) rename source/extensions/{filters/http => }/common/aws/BUILD (100%) rename source/extensions/{filters/http => }/common/aws/credentials_provider.h (97%) rename source/extensions/{filters/http => }/common/aws/credentials_provider_impl.cc (98%) rename source/extensions/{filters/http => }/common/aws/credentials_provider_impl.h (97%) rename source/extensions/{filters/http => }/common/aws/region_provider.h (92%) rename source/extensions/{filters/http => }/common/aws/region_provider_impl.cc (85%) rename source/extensions/{filters/http => }/common/aws/region_provider_impl.h (85%) rename source/extensions/{filters/http => }/common/aws/signer.h (89%) rename source/extensions/{filters/http => }/common/aws/signer_impl.cc (97%) rename source/extensions/{filters/http => }/common/aws/signer_impl.h (94%) rename source/extensions/{filters/http => }/common/aws/utility.cc (98%) rename source/extensions/{filters/http => }/common/aws/utility.h (97%) rename test/extensions/{filters/http => }/common/aws/BUILD (72%) rename test/extensions/{filters/http => }/common/aws/aws_metadata_fetcher_integration_test.cc (98%) rename test/extensions/{filters/http => }/common/aws/credentials_provider_impl_test.cc (98%) rename test/extensions/{filters/http => }/common/aws/credentials_provider_test.cc (92%) rename test/extensions/{filters/http => }/common/aws/mocks.cc (76%) rename test/extensions/{filters/http => }/common/aws/mocks.h (85%) rename test/extensions/{filters/http => }/common/aws/region_provider_impl_test.cc (89%) rename test/extensions/{filters/http => }/common/aws/signer_impl_test.cc (96%) rename test/extensions/{filters/http => }/common/aws/utility_test.cc (97%) diff --git a/CODEOWNERS b/CODEOWNERS index c555dc3978..af0e28fdc3 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -53,7 +53,7 @@ extensions/filters/common/original_src @snowp @klarose /*/extensions/filters/http/cache @toddmgreer @jmarantz # aws_iam grpc credentials /*/extensions/grpc_credentials/aws_iam @lavignes @mattklein123 -/*/extensions/filters/http/common/aws @lavignes @mattklein123 +/*/extensions/common/aws @lavignes @mattklein123 # adaptive concurrency limit extension. /*/extensions/filters/http/adaptive_concurrency @tonya11en @mattklein123 # http inspector diff --git a/source/extensions/filters/http/common/aws/BUILD b/source/extensions/common/aws/BUILD similarity index 100% rename from source/extensions/filters/http/common/aws/BUILD rename to source/extensions/common/aws/BUILD diff --git a/source/extensions/filters/http/common/aws/credentials_provider.h b/source/extensions/common/aws/credentials_provider.h similarity index 97% rename from source/extensions/filters/http/common/aws/credentials_provider.h rename to source/extensions/common/aws/credentials_provider.h index 04ad9d8b10..ed6bb31256 100644 --- a/source/extensions/filters/http/common/aws/credentials_provider.h +++ b/source/extensions/common/aws/credentials_provider.h @@ -9,7 +9,6 @@ namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -71,6 +70,5 @@ using CredentialsProviderSharedPtr = std::shared_ptr; } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/filters/http/common/aws/credentials_provider_impl.cc b/source/extensions/common/aws/credentials_provider_impl.cc similarity index 98% rename from source/extensions/filters/http/common/aws/credentials_provider_impl.cc rename to source/extensions/common/aws/credentials_provider_impl.cc index ba2de4e510..aa367a07d0 100644 --- a/source/extensions/filters/http/common/aws/credentials_provider_impl.cc +++ b/source/extensions/common/aws/credentials_provider_impl.cc @@ -1,4 +1,4 @@ -#include "extensions/filters/http/common/aws/credentials_provider_impl.h" +#include "extensions/common/aws/credentials_provider_impl.h" #include "envoy/common/exception.h" @@ -8,7 +8,6 @@ namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -221,6 +220,5 @@ DefaultCredentialsProviderChain::DefaultCredentialsProviderChain( } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/filters/http/common/aws/credentials_provider_impl.h b/source/extensions/common/aws/credentials_provider_impl.h similarity index 97% rename from source/extensions/filters/http/common/aws/credentials_provider_impl.h rename to source/extensions/common/aws/credentials_provider_impl.h index 36a0067e59..e493ebdb74 100644 --- a/source/extensions/filters/http/common/aws/credentials_provider_impl.h +++ b/source/extensions/common/aws/credentials_provider_impl.h @@ -8,13 +8,12 @@ #include "common/common/logger.h" #include "common/common/thread.h" -#include "extensions/filters/http/common/aws/credentials_provider.h" +#include "extensions/common/aws/credentials_provider.h" #include "absl/strings/string_view.h" namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -165,6 +164,5 @@ class DefaultCredentialsProviderChain : public CredentialsProviderChain, } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/filters/http/common/aws/region_provider.h b/source/extensions/common/aws/region_provider.h similarity index 92% rename from source/extensions/filters/http/common/aws/region_provider.h rename to source/extensions/common/aws/region_provider.h index 2bd307595f..aa87f90c17 100644 --- a/source/extensions/filters/http/common/aws/region_provider.h +++ b/source/extensions/common/aws/region_provider.h @@ -6,7 +6,6 @@ namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -28,6 +27,5 @@ using RegionProviderSharedPtr = std::shared_ptr; } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/filters/http/common/aws/region_provider_impl.cc b/source/extensions/common/aws/region_provider_impl.cc similarity index 85% rename from source/extensions/filters/http/common/aws/region_provider_impl.cc rename to source/extensions/common/aws/region_provider_impl.cc index f535eaef3e..3943f45ba2 100644 --- a/source/extensions/filters/http/common/aws/region_provider_impl.cc +++ b/source/extensions/common/aws/region_provider_impl.cc @@ -1,8 +1,7 @@ -#include "extensions/filters/http/common/aws/region_provider_impl.h" +#include "extensions/common/aws/region_provider_impl.h" namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -25,6 +24,5 @@ absl::optional EnvironmentRegionProvider::getRegion() { } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/filters/http/common/aws/region_provider_impl.h b/source/extensions/common/aws/region_provider_impl.h similarity index 85% rename from source/extensions/filters/http/common/aws/region_provider_impl.h rename to source/extensions/common/aws/region_provider_impl.h index 114d1e294f..9e45823d44 100644 --- a/source/extensions/filters/http/common/aws/region_provider_impl.h +++ b/source/extensions/common/aws/region_provider_impl.h @@ -2,11 +2,10 @@ #include "common/common/logger.h" -#include "extensions/filters/http/common/aws/region_provider.h" +#include "extensions/common/aws/region_provider.h" namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -33,6 +32,5 @@ class StaticRegionProvider : public RegionProvider { } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/filters/http/common/aws/signer.h b/source/extensions/common/aws/signer.h similarity index 89% rename from source/extensions/filters/http/common/aws/signer.h rename to source/extensions/common/aws/signer.h index 9c1689323c..1673a52972 100644 --- a/source/extensions/filters/http/common/aws/signer.h +++ b/source/extensions/common/aws/signer.h @@ -5,11 +5,9 @@ namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { -// TODO(rgs): Move this to source/extensions/common. class Signer { public: virtual ~Signer() = default; @@ -34,6 +32,5 @@ using SignerPtr = std::unique_ptr; } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/filters/http/common/aws/signer_impl.cc b/source/extensions/common/aws/signer_impl.cc similarity index 97% rename from source/extensions/filters/http/common/aws/signer_impl.cc rename to source/extensions/common/aws/signer_impl.cc index ef04a489d3..e2bae8da28 100644 --- a/source/extensions/filters/http/common/aws/signer_impl.cc +++ b/source/extensions/common/aws/signer_impl.cc @@ -1,4 +1,4 @@ -#include "extensions/filters/http/common/aws/signer_impl.h" +#include "extensions/common/aws/signer_impl.h" #include "envoy/common/exception.h" @@ -8,13 +8,12 @@ #include "common/crypto/utility.h" #include "common/http/headers.h" -#include "extensions/filters/http/common/aws/utility.h" +#include "extensions/common/aws/utility.h" #include "absl/strings/str_join.h" namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -122,6 +121,5 @@ SignerImpl::createAuthorizationHeader(absl::string_view access_key_id, } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/filters/http/common/aws/signer_impl.h b/source/extensions/common/aws/signer_impl.h similarity index 94% rename from source/extensions/filters/http/common/aws/signer_impl.h rename to source/extensions/common/aws/signer_impl.h index d89c14fbf7..16064ff322 100644 --- a/source/extensions/filters/http/common/aws/signer_impl.h +++ b/source/extensions/common/aws/signer_impl.h @@ -4,12 +4,11 @@ #include "common/common/utility.h" #include "common/singleton/const_singleton.h" -#include "extensions/filters/http/common/aws/credentials_provider.h" -#include "extensions/filters/http/common/aws/signer.h" +#include "extensions/common/aws/credentials_provider.h" +#include "extensions/common/aws/signer.h" namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -82,6 +81,5 @@ class SignerImpl : public Signer, public Logger::Loggable { } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/filters/http/common/aws/utility.cc b/source/extensions/common/aws/utility.cc similarity index 98% rename from source/extensions/filters/http/common/aws/utility.cc rename to source/extensions/common/aws/utility.cc index e8d4df8ebc..e42aa60a73 100644 --- a/source/extensions/filters/http/common/aws/utility.cc +++ b/source/extensions/common/aws/utility.cc @@ -1,4 +1,4 @@ -#include "extensions/filters/http/common/aws/utility.h" +#include "extensions/common/aws/utility.h" #include "common/common/fmt.h" #include "common/common/utility.h" @@ -8,7 +8,6 @@ namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -141,6 +140,5 @@ absl::optional Utility::metadataFetcher(const std::string& host, } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/filters/http/common/aws/utility.h b/source/extensions/common/aws/utility.h similarity index 97% rename from source/extensions/filters/http/common/aws/utility.h rename to source/extensions/common/aws/utility.h index c43236ceb2..d37ef28ce2 100644 --- a/source/extensions/filters/http/common/aws/utility.h +++ b/source/extensions/common/aws/utility.h @@ -4,7 +4,6 @@ namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -59,6 +58,5 @@ class Utility { } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/source/extensions/filters/http/aws_request_signing/BUILD b/source/extensions/filters/http/aws_request_signing/BUILD index 91e8ac2d40..c723fb932b 100644 --- a/source/extensions/filters/http/aws_request_signing/BUILD +++ b/source/extensions/filters/http/aws_request_signing/BUILD @@ -18,9 +18,9 @@ envoy_cc_library( hdrs = ["aws_request_signing_filter.h"], deps = [ "//include/envoy/http:filter_interface", + "//source/extensions/common/aws:credentials_provider_impl_lib", + "//source/extensions/common/aws:signer_impl_lib", "//source/extensions/filters/http/common:pass_through_filter_lib", - "//source/extensions/filters/http/common/aws:credentials_provider_impl_lib", - "//source/extensions/filters/http/common/aws:signer_impl_lib", "@envoy_api//envoy/extensions/filters/http/aws_request_signing/v3:pkg_cc_proto", ], ) @@ -34,10 +34,10 @@ envoy_cc_extension( deps = [ ":aws_request_signing_filter_lib", "//include/envoy/registry", + "//source/extensions/common/aws:credentials_provider_impl_lib", + "//source/extensions/common/aws:signer_impl_lib", "//source/extensions/filters/http:well_known_names", "//source/extensions/filters/http/common:factory_base_lib", - "//source/extensions/filters/http/common/aws:credentials_provider_impl_lib", - "//source/extensions/filters/http/common/aws:signer_impl_lib", "@envoy_api//envoy/extensions/filters/http/aws_request_signing/v3:pkg_cc_proto", ], ) diff --git a/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.cc b/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.cc index fccc64f0b3..4ddcd094e5 100644 --- a/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.cc +++ b/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.cc @@ -7,13 +7,13 @@ namespace Extensions { namespace HttpFilters { namespace AwsRequestSigningFilter { -FilterConfigImpl::FilterConfigImpl(HttpFilters::Common::Aws::SignerPtr&& signer, +FilterConfigImpl::FilterConfigImpl(Extensions::Common::Aws::SignerPtr&& signer, const std::string& stats_prefix, Stats::Scope& scope) : signer_(std::move(signer)), stats_(Filter::generateStats(stats_prefix, scope)) {} Filter::Filter(const std::shared_ptr& config) : config_(config) {} -HttpFilters::Common::Aws::Signer& FilterConfigImpl::signer() { return *signer_; } +Extensions::Common::Aws::Signer& FilterConfigImpl::signer() { return *signer_; } FilterStats& FilterConfigImpl::stats() { return stats_; } diff --git a/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h b/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h index a557928503..6892b22b08 100644 --- a/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h +++ b/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h @@ -5,7 +5,7 @@ #include "envoy/stats/scope.h" #include "envoy/stats/stats_macros.h" -#include "extensions/filters/http/common/aws/signer.h" +#include "extensions/common/aws/signer.h" #include "extensions/filters/http/common/pass_through_filter.h" namespace Envoy { @@ -39,7 +39,7 @@ class FilterConfig { /** * @return the config's signer. */ - virtual HttpFilters::Common::Aws::Signer& signer() PURE; + virtual Extensions::Common::Aws::Signer& signer() PURE; /** * @return the filter stats. @@ -54,14 +54,14 @@ using FilterConfigSharedPtr = std::shared_ptr; */ class FilterConfigImpl : public FilterConfig { public: - FilterConfigImpl(HttpFilters::Common::Aws::SignerPtr&& signer, const std::string& stats_prefix, + FilterConfigImpl(Extensions::Common::Aws::SignerPtr&& signer, const std::string& stats_prefix, Stats::Scope& scope); - HttpFilters::Common::Aws::Signer& signer() override; + Extensions::Common::Aws::Signer& signer() override; FilterStats& stats() override; private: - HttpFilters::Common::Aws::SignerPtr signer_; + Extensions::Common::Aws::SignerPtr signer_; FilterStats stats_; }; diff --git a/source/extensions/filters/http/aws_request_signing/config.cc b/source/extensions/filters/http/aws_request_signing/config.cc index a3bee90138..1304753a53 100644 --- a/source/extensions/filters/http/aws_request_signing/config.cc +++ b/source/extensions/filters/http/aws_request_signing/config.cc @@ -4,10 +4,10 @@ #include "envoy/extensions/filters/http/aws_request_signing/v3/aws_request_signing.pb.validate.h" #include "envoy/registry/registry.h" +#include "extensions/common/aws/credentials_provider_impl.h" +#include "extensions/common/aws/signer_impl.h" +#include "extensions/common/aws/utility.h" #include "extensions/filters/http/aws_request_signing/aws_request_signing_filter.h" -#include "extensions/filters/http/common/aws/credentials_provider_impl.h" -#include "extensions/filters/http/common/aws/signer_impl.h" -#include "extensions/filters/http/common/aws/utility.h" namespace Envoy { namespace Extensions { @@ -19,9 +19,9 @@ Http::FilterFactoryCb AwsRequestSigningFilterFactory::createFilterFactoryFromPro const std::string& stats_prefix, Server::Configuration::FactoryContext& context) { auto credentials_provider = - std::make_shared( - context.api(), HttpFilters::Common::Aws::Utility::metadataFetcher); - auto signer = std::make_unique( + std::make_shared( + context.api(), Extensions::Common::Aws::Utility::metadataFetcher); + auto signer = std::make_unique( config.service_name(), config.region(), credentials_provider, context.dispatcher().timeSource()); diff --git a/source/extensions/grpc_credentials/aws_iam/BUILD b/source/extensions/grpc_credentials/aws_iam/BUILD index 9aced1ce17..2b8980e765 100644 --- a/source/extensions/grpc_credentials/aws_iam/BUILD +++ b/source/extensions/grpc_credentials/aws_iam/BUILD @@ -25,10 +25,10 @@ envoy_cc_extension( "//source/common/grpc:google_grpc_creds_lib", "//source/common/http:message_lib", "//source/common/http:utility_lib", - "//source/extensions/filters/http/common/aws:credentials_provider_impl_lib", - "//source/extensions/filters/http/common/aws:region_provider_impl_lib", - "//source/extensions/filters/http/common/aws:signer_impl_lib", - "//source/extensions/filters/http/common/aws:utility_lib", + "//source/extensions/common/aws:credentials_provider_impl_lib", + "//source/extensions/common/aws:region_provider_impl_lib", + "//source/extensions/common/aws:signer_impl_lib", + "//source/extensions/common/aws:utility_lib", "//source/extensions/grpc_credentials:well_known_names", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/config/grpc_credential/v3:pkg_cc_proto", diff --git a/source/extensions/grpc_credentials/aws_iam/config.cc b/source/extensions/grpc_credentials/aws_iam/config.cc index 4729e962cf..5f60eab146 100644 --- a/source/extensions/grpc_credentials/aws_iam/config.cc +++ b/source/extensions/grpc_credentials/aws_iam/config.cc @@ -12,10 +12,10 @@ #include "common/http/utility.h" #include "common/protobuf/message_validator_impl.h" -#include "extensions/filters/http/common/aws/credentials_provider_impl.h" -#include "extensions/filters/http/common/aws/region_provider_impl.h" -#include "extensions/filters/http/common/aws/signer_impl.h" -#include "extensions/filters/http/common/aws/utility.h" +#include "extensions/common/aws/credentials_provider_impl.h" +#include "extensions/common/aws/region_provider_impl.h" +#include "extensions/common/aws/signer_impl.h" +#include "extensions/common/aws/utility.h" namespace Envoy { namespace Extensions { @@ -45,10 +45,9 @@ std::shared_ptr AwsIamGrpcCredentialsFactory::getChann const auto& config = Envoy::MessageUtil::downcastAndValidate< const envoy::config::grpc_credential::v3::AwsIamConfig&>( *config_message, ProtobufMessage::getNullValidationVisitor()); - auto credentials_provider = - std::make_shared( - api, HttpFilters::Common::Aws::Utility::metadataFetcher); - auto signer = std::make_unique( + auto credentials_provider = std::make_shared( + api, Common::Aws::Utility::metadataFetcher); + auto signer = std::make_unique( config.service_name(), getRegion(config), credentials_provider, api.timeSource()); std::shared_ptr new_call_creds = grpc::MetadataCredentialsFromPlugin( std::make_unique(std::move(signer))); @@ -75,12 +74,11 @@ std::shared_ptr AwsIamGrpcCredentialsFactory::getChann std::string AwsIamGrpcCredentialsFactory::getRegion( const envoy::config::grpc_credential::v3::AwsIamConfig& config) { - std::unique_ptr region_provider; + std::unique_ptr region_provider; if (!config.region().empty()) { - region_provider = - std::make_unique(config.region()); + region_provider = std::make_unique(config.region()); } else { - region_provider = std::make_unique(); + region_provider = std::make_unique(); } if (!region_provider->getRegion().has_value()) { diff --git a/source/extensions/grpc_credentials/aws_iam/config.h b/source/extensions/grpc_credentials/aws_iam/config.h index cd0d6977b5..9ac68a0451 100644 --- a/source/extensions/grpc_credentials/aws_iam/config.h +++ b/source/extensions/grpc_credentials/aws_iam/config.h @@ -7,7 +7,7 @@ #include "common/http/message_impl.h" -#include "extensions/filters/http/common/aws/signer.h" +#include "extensions/common/aws/signer.h" #include "extensions/grpc_credentials/well_known_names.h" namespace Envoy { @@ -39,8 +39,7 @@ class AwsIamGrpcCredentialsFactory : public Grpc::GoogleGrpcCredentialsFactory { */ class AwsIamHeaderAuthenticator : public grpc::MetadataCredentialsPlugin { public: - AwsIamHeaderAuthenticator(HttpFilters::Common::Aws::SignerPtr signer) - : signer_(std::move(signer)) {} + AwsIamHeaderAuthenticator(Common::Aws::SignerPtr signer) : signer_(std::move(signer)) {} grpc::Status GetMetadata(grpc::string_ref, grpc::string_ref, const grpc::AuthContext&, std::multimap* metadata) override; @@ -54,7 +53,7 @@ class AwsIamHeaderAuthenticator : public grpc::MetadataCredentialsPlugin { static void signedHeadersToMetadata(const Http::HeaderMap& headers, std::multimap& metadata); - const HttpFilters::Common::Aws::SignerPtr signer_; + const Common::Aws::SignerPtr signer_; }; } // namespace AwsIam diff --git a/test/extensions/filters/http/common/aws/BUILD b/test/extensions/common/aws/BUILD similarity index 72% rename from test/extensions/filters/http/common/aws/BUILD rename to test/extensions/common/aws/BUILD index 55be6eb2a6..a6c37b7001 100644 --- a/test/extensions/filters/http/common/aws/BUILD +++ b/test/extensions/common/aws/BUILD @@ -14,8 +14,8 @@ envoy_cc_mock( srcs = ["mocks.cc"], hdrs = ["mocks.h"], deps = [ - "//source/extensions/filters/http/common/aws:credentials_provider_interface", - "//source/extensions/filters/http/common/aws:signer_interface", + "//source/extensions/common/aws:credentials_provider_interface", + "//source/extensions/common/aws:signer_interface", ], ) @@ -25,8 +25,8 @@ envoy_cc_test( deps = [ "//source/common/buffer:buffer_lib", "//source/common/http:message_lib", - "//source/extensions/filters/http/common/aws:signer_impl_lib", - "//test/extensions/filters/http/common/aws:aws_mocks", + "//source/extensions/common/aws:signer_impl_lib", + "//test/extensions/common/aws:aws_mocks", "//test/test_common:simulated_time_system_lib", "//test/test_common:utility_lib", ], @@ -36,7 +36,7 @@ envoy_cc_test( name = "utility_test", srcs = ["utility_test.cc"], deps = [ - "//source/extensions/filters/http/common/aws:utility_lib", + "//source/extensions/common/aws:utility_lib", "//test/test_common:utility_lib", ], ) @@ -45,7 +45,7 @@ envoy_cc_test( name = "region_provider_impl_test", srcs = ["region_provider_impl_test.cc"], deps = [ - "//source/extensions/filters/http/common/aws:region_provider_impl_lib", + "//source/extensions/common/aws:region_provider_impl_lib", "//test/test_common:environment_lib", ], ) @@ -54,8 +54,8 @@ envoy_cc_test( name = "credentials_provider_impl_test", srcs = ["credentials_provider_impl_test.cc"], deps = [ - "//source/extensions/filters/http/common/aws:credentials_provider_impl_lib", - "//test/extensions/filters/http/common/aws:aws_mocks", + "//source/extensions/common/aws:credentials_provider_impl_lib", + "//test/extensions/common/aws:aws_mocks", "//test/mocks/api:api_mocks", "//test/mocks/event:event_mocks", "//test/test_common:environment_lib", @@ -67,7 +67,7 @@ envoy_cc_test( name = "credentials_provider_test", srcs = ["credentials_provider_test.cc"], deps = [ - "//source/extensions/filters/http/common/aws:credentials_provider_interface", + "//source/extensions/common/aws:credentials_provider_interface", ], ) @@ -78,7 +78,7 @@ envoy_cc_test( ], deps = [ "//source/common/common:fmt_lib", - "//source/extensions/filters/http/common/aws:utility_lib", + "//source/extensions/common/aws:utility_lib", "//source/extensions/filters/http/fault:config", "//source/extensions/filters/http/fault:fault_filter_lib", "//source/extensions/filters/http/router:config", diff --git a/test/extensions/filters/http/common/aws/aws_metadata_fetcher_integration_test.cc b/test/extensions/common/aws/aws_metadata_fetcher_integration_test.cc similarity index 98% rename from test/extensions/filters/http/common/aws/aws_metadata_fetcher_integration_test.cc rename to test/extensions/common/aws/aws_metadata_fetcher_integration_test.cc index b6d1237548..41a0ebdd04 100644 --- a/test/extensions/filters/http/common/aws/aws_metadata_fetcher_integration_test.cc +++ b/test/extensions/common/aws/aws_metadata_fetcher_integration_test.cc @@ -1,6 +1,6 @@ #include "common/common/fmt.h" -#include "extensions/filters/http/common/aws/utility.h" +#include "extensions/common/aws/utility.h" #include "test/integration/integration.h" #include "test/integration/utility.h" @@ -9,7 +9,7 @@ namespace Envoy { -using Envoy::Extensions::HttpFilters::Common::Aws::Utility; +using Envoy::Extensions::Common::Aws::Utility; class AwsMetadataIntegrationTestBase : public ::testing::Test, public BaseIntegrationTest { public: diff --git a/test/extensions/filters/http/common/aws/credentials_provider_impl_test.cc b/test/extensions/common/aws/credentials_provider_impl_test.cc similarity index 98% rename from test/extensions/filters/http/common/aws/credentials_provider_impl_test.cc rename to test/extensions/common/aws/credentials_provider_impl_test.cc index 93173d7c0c..f4233b3cba 100644 --- a/test/extensions/filters/http/common/aws/credentials_provider_impl_test.cc +++ b/test/extensions/common/aws/credentials_provider_impl_test.cc @@ -1,6 +1,6 @@ -#include "extensions/filters/http/common/aws/credentials_provider_impl.h" +#include "extensions/common/aws/credentials_provider_impl.h" -#include "test/extensions/filters/http/common/aws/mocks.h" +#include "test/extensions/common/aws/mocks.h" #include "test/mocks/api/mocks.h" #include "test/mocks/event/mocks.h" #include "test/test_common/environment.h" @@ -14,7 +14,6 @@ using testing::Return; namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -444,6 +443,5 @@ TEST(CredentialsProviderChainTest, getCredentials_secondProviderReturns) { } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/test/extensions/filters/http/common/aws/credentials_provider_test.cc b/test/extensions/common/aws/credentials_provider_test.cc similarity index 92% rename from test/extensions/filters/http/common/aws/credentials_provider_test.cc rename to test/extensions/common/aws/credentials_provider_test.cc index 32c9546ed6..e2aff11b2f 100644 --- a/test/extensions/filters/http/common/aws/credentials_provider_test.cc +++ b/test/extensions/common/aws/credentials_provider_test.cc @@ -1,10 +1,9 @@ -#include "extensions/filters/http/common/aws/credentials_provider.h" +#include "extensions/common/aws/credentials_provider.h" #include "gtest/gtest.h" namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -52,6 +51,5 @@ TEST(Credentials, AllNonEmpty) { } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/test/extensions/filters/http/common/aws/mocks.cc b/test/extensions/common/aws/mocks.cc similarity index 76% rename from test/extensions/filters/http/common/aws/mocks.cc rename to test/extensions/common/aws/mocks.cc index 3e68170b4b..479ed4d446 100644 --- a/test/extensions/filters/http/common/aws/mocks.cc +++ b/test/extensions/common/aws/mocks.cc @@ -1,8 +1,7 @@ -#include "test/extensions/filters/http/common/aws/mocks.h" +#include "test/extensions/common/aws/mocks.h" namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -16,6 +15,5 @@ MockSigner::~MockSigner() = default; } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/test/extensions/filters/http/common/aws/mocks.h b/test/extensions/common/aws/mocks.h similarity index 85% rename from test/extensions/filters/http/common/aws/mocks.h rename to test/extensions/common/aws/mocks.h index 9ee9aa7b66..99048a6dec 100644 --- a/test/extensions/filters/http/common/aws/mocks.h +++ b/test/extensions/common/aws/mocks.h @@ -1,13 +1,12 @@ #pragma once -#include "extensions/filters/http/common/aws/credentials_provider.h" -#include "extensions/filters/http/common/aws/signer.h" +#include "extensions/common/aws/credentials_provider.h" +#include "extensions/common/aws/signer.h" #include "gmock/gmock.h" namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -46,6 +45,5 @@ class DummyMetadataFetcher { } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/test/extensions/filters/http/common/aws/region_provider_impl_test.cc b/test/extensions/common/aws/region_provider_impl_test.cc similarity index 89% rename from test/extensions/filters/http/common/aws/region_provider_impl_test.cc rename to test/extensions/common/aws/region_provider_impl_test.cc index 7cb14439a5..8ab7282586 100644 --- a/test/extensions/filters/http/common/aws/region_provider_impl_test.cc +++ b/test/extensions/common/aws/region_provider_impl_test.cc @@ -1,4 +1,4 @@ -#include "extensions/filters/http/common/aws/region_provider_impl.h" +#include "extensions/common/aws/region_provider_impl.h" #include "test/test_common/environment.h" @@ -6,7 +6,6 @@ namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { @@ -37,6 +36,5 @@ TEST_F(StaticRegionProviderTest, SomeRegion) { } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/test/extensions/filters/http/common/aws/signer_impl_test.cc b/test/extensions/common/aws/signer_impl_test.cc similarity index 96% rename from test/extensions/filters/http/common/aws/signer_impl_test.cc rename to test/extensions/common/aws/signer_impl_test.cc index c09a986b5f..fc93649eea 100644 --- a/test/extensions/filters/http/common/aws/signer_impl_test.cc +++ b/test/extensions/common/aws/signer_impl_test.cc @@ -1,10 +1,10 @@ #include "common/buffer/buffer_impl.h" #include "common/http/message_impl.h" -#include "extensions/filters/http/common/aws/signer_impl.h" -#include "extensions/filters/http/common/aws/utility.h" +#include "extensions/common/aws/signer_impl.h" +#include "extensions/common/aws/utility.h" -#include "test/extensions/filters/http/common/aws/mocks.h" +#include "test/extensions/common/aws/mocks.h" #include "test/test_common/simulated_time_system.h" #include "test/test_common/utility.h" @@ -13,7 +13,6 @@ using testing::Return; namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { namespace { @@ -167,6 +166,5 @@ TEST_F(SignerImplTest, SignHostHeader) { } // namespace } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/test/extensions/filters/http/common/aws/utility_test.cc b/test/extensions/common/aws/utility_test.cc similarity index 97% rename from test/extensions/filters/http/common/aws/utility_test.cc rename to test/extensions/common/aws/utility_test.cc index e472ab7439..9aaf15c900 100644 --- a/test/extensions/filters/http/common/aws/utility_test.cc +++ b/test/extensions/common/aws/utility_test.cc @@ -1,4 +1,4 @@ -#include "extensions/filters/http/common/aws/utility.h" +#include "extensions/common/aws/utility.h" #include "test/test_common/utility.h" @@ -9,7 +9,6 @@ using testing::Pair; namespace Envoy { namespace Extensions { -namespace HttpFilters { namespace Common { namespace Aws { namespace { @@ -150,6 +149,5 @@ TEST(UtilityTest, JoinCanonicalHeaderNamesWithEmptyMap) { } // namespace } // namespace Aws } // namespace Common -} // namespace HttpFilters } // namespace Extensions } // namespace Envoy diff --git a/test/extensions/filters/http/aws_request_signing/aws_request_signing_filter_test.cc b/test/extensions/filters/http/aws_request_signing/aws_request_signing_filter_test.cc index 6a1125589e..15d8b748c2 100644 --- a/test/extensions/filters/http/aws_request_signing/aws_request_signing_filter_test.cc +++ b/test/extensions/filters/http/aws_request_signing/aws_request_signing_filter_test.cc @@ -1,5 +1,5 @@ +#include "extensions/common/aws/signer.h" #include "extensions/filters/http/aws_request_signing/aws_request_signing_filter.h" -#include "extensions/filters/http/common/aws/signer.h" #include "test/mocks/http/mocks.h" @@ -22,7 +22,7 @@ class MockFilterConfig : public FilterConfig { public: MockFilterConfig() { signer_ = std::make_shared(); } - HttpFilters::Common::Aws::Signer& signer() override { return *signer_; } + Common::Aws::Signer& signer() override { return *signer_; } FilterStats& stats() override { return stats_; } std::shared_ptr signer_; diff --git a/tools/check_format.py b/tools/check_format.py index be3d137708..bc481bc67f 100755 --- a/tools/check_format.py +++ b/tools/check_format.py @@ -32,7 +32,7 @@ # definitions for real-world time, the construction of them in main(), and perf annotation. # For now it includes the validation server but that really should be injected too. REAL_TIME_WHITELIST = ("./source/common/common/utility.h", - "./source/extensions/filters/http/common/aws/utility.cc", + "./source/extensions/common/aws/utility.cc", "./source/common/event/real_time_system.cc", "./source/common/event/real_time_system.h", "./source/exe/main_common.cc", "./source/exe/main_common.h", "./source/server/config_validation/server.cc", From 963d7056ae2b27b40d3cd974cf668fe0ba791f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Guti=C3=A9rrez=20Segal=C3=A9s?= Date: Tue, 4 Feb 2020 17:53:15 -0500 Subject: [PATCH 02/87] aws_request_signing: inherit from PassThroughDecoderFilter (#9926) Signed-off-by: Raul Gutierrez Segales --- .../http/aws_request_signing/aws_request_signing_filter.h | 2 +- source/extensions/filters/http/aws_request_signing/config.cc | 2 +- test/extensions/filters/http/aws_request_signing/config_test.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h b/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h index 6892b22b08..eb0fe9f34d 100644 --- a/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h +++ b/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h @@ -68,7 +68,7 @@ class FilterConfigImpl : public FilterConfig { /** * HTTP AWS request signing auth filter. */ -class Filter : public Http::PassThroughFilter, Logger::Loggable { +class Filter : public Http::PassThroughDecoderFilter, Logger::Loggable { public: Filter(const std::shared_ptr& config); diff --git a/source/extensions/filters/http/aws_request_signing/config.cc b/source/extensions/filters/http/aws_request_signing/config.cc index 1304753a53..ababbee4f9 100644 --- a/source/extensions/filters/http/aws_request_signing/config.cc +++ b/source/extensions/filters/http/aws_request_signing/config.cc @@ -29,7 +29,7 @@ Http::FilterFactoryCb AwsRequestSigningFilterFactory::createFilterFactoryFromPro std::make_shared(std::move(signer), stats_prefix, context.scope()); return [filter_config](Http::FilterChainFactoryCallbacks& callbacks) -> void { auto filter = std::make_shared(filter_config); - callbacks.addStreamFilter(filter); + callbacks.addStreamDecoderFilter(filter); }; } diff --git a/test/extensions/filters/http/aws_request_signing/config_test.cc b/test/extensions/filters/http/aws_request_signing/config_test.cc index 3149cf3dba..424524b999 100644 --- a/test/extensions/filters/http/aws_request_signing/config_test.cc +++ b/test/extensions/filters/http/aws_request_signing/config_test.cc @@ -31,7 +31,7 @@ region: us-west-2 Http::FilterFactoryCb cb = factory.createFilterFactoryFromProto(proto_config, "stats", context); Http::MockFilterChainFactoryCallbacks filter_callbacks; - EXPECT_CALL(filter_callbacks, addStreamFilter(_)); + EXPECT_CALL(filter_callbacks, addStreamDecoderFilter(_)); cb(filter_callbacks); } From 4ea661f5f75f0c7e14d7f3ff26c0d04ad4d57468 Mon Sep 17 00:00:00 2001 From: Derek Argueta Date: Tue, 4 Feb 2020 14:54:03 -0800 Subject: [PATCH 03/87] thrift: introduce PassThroughDecoderFilter (#9902) Signed-off-by: Derek Argueta --- .../network/thrift_proxy/filters/BUILD | 8 ++ .../filters/pass_through_filter.h | 107 ++++++++++++++++++ .../thrift_proxy/filters/ratelimit/BUILD | 2 +- .../filters/ratelimit/ratelimit.cc | 16 +-- .../filters/ratelimit/ratelimit.h | 60 +--------- 5 files changed, 128 insertions(+), 65 deletions(-) create mode 100644 source/extensions/filters/network/thrift_proxy/filters/pass_through_filter.h diff --git a/source/extensions/filters/network/thrift_proxy/filters/BUILD b/source/extensions/filters/network/thrift_proxy/filters/BUILD index 1f4ebe2b5f..ba1054d990 100644 --- a/source/extensions/filters/network/thrift_proxy/filters/BUILD +++ b/source/extensions/filters/network/thrift_proxy/filters/BUILD @@ -50,3 +50,11 @@ envoy_cc_library( "//source/common/singleton:const_singleton", ], ) + +envoy_cc_library( + name = "pass_through_filter_lib", + hdrs = ["pass_through_filter.h"], + deps = [ + ":filter_interface", + ], +) diff --git a/source/extensions/filters/network/thrift_proxy/filters/pass_through_filter.h b/source/extensions/filters/network/thrift_proxy/filters/pass_through_filter.h new file mode 100644 index 0000000000..6992253a11 --- /dev/null +++ b/source/extensions/filters/network/thrift_proxy/filters/pass_through_filter.h @@ -0,0 +1,107 @@ +#pragma once + +#include "extensions/filters/network/thrift_proxy/filters/filter.h" + +#include "absl/strings/string_view.h" + +namespace Envoy { +namespace Extensions { +namespace NetworkFilters { +namespace ThriftProxy { +namespace ThriftFilters { + +/** + * Pass through Thrift decoder filter. Continue at each decoding state within the series of + * transitions. + */ +class PassThroughDecoderFilter : public DecoderFilter { +public: + // ThriftDecoderFilter + void onDestroy() override {} + + void setDecoderFilterCallbacks(DecoderFilterCallbacks& callbacks) override { + decoder_callbacks_ = &callbacks; + }; + + // Thrift Decoder State Machine + ThriftProxy::FilterStatus transportBegin(ThriftProxy::MessageMetadataSharedPtr) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus transportEnd() override { return ThriftProxy::FilterStatus::Continue; } + + ThriftProxy::FilterStatus messageBegin(ThriftProxy::MessageMetadataSharedPtr) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus messageEnd() override { return ThriftProxy::FilterStatus::Continue; } + + ThriftProxy::FilterStatus structBegin(absl::string_view) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus structEnd() override { return ThriftProxy::FilterStatus::Continue; } + + ThriftProxy::FilterStatus fieldBegin(absl::string_view, ThriftProxy::FieldType&, + int16_t&) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus fieldEnd() override { return ThriftProxy::FilterStatus::Continue; } + + ThriftProxy::FilterStatus boolValue(bool&) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus byteValue(uint8_t&) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus int16Value(int16_t&) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus int32Value(int32_t&) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus int64Value(int64_t&) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus doubleValue(double&) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus stringValue(absl::string_view) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus mapBegin(ThriftProxy::FieldType&, ThriftProxy::FieldType&, + uint32_t&) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus mapEnd() override { return ThriftProxy::FilterStatus::Continue; } + + ThriftProxy::FilterStatus listBegin(ThriftProxy::FieldType&, uint32_t&) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus listEnd() override { return ThriftProxy::FilterStatus::Continue; } + + ThriftProxy::FilterStatus setBegin(ThriftProxy::FieldType&, uint32_t&) override { + return ThriftProxy::FilterStatus::Continue; + } + + ThriftProxy::FilterStatus setEnd() override { return ThriftProxy::FilterStatus::Continue; } + +protected: + DecoderFilterCallbacks* decoder_callbacks_{}; +}; + +} // namespace ThriftFilters +} // namespace ThriftProxy +} // namespace NetworkFilters +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/filters/network/thrift_proxy/filters/ratelimit/BUILD b/source/extensions/filters/network/thrift_proxy/filters/ratelimit/BUILD index b54c2ce449..953db0fdff 100644 --- a/source/extensions/filters/network/thrift_proxy/filters/ratelimit/BUILD +++ b/source/extensions/filters/network/thrift_proxy/filters/ratelimit/BUILD @@ -21,7 +21,7 @@ envoy_cc_library( "//source/extensions/filters/common/ratelimit:ratelimit_lib", "//source/extensions/filters/common/ratelimit:stat_names_lib", "//source/extensions/filters/network/thrift_proxy:app_exception_lib", - "//source/extensions/filters/network/thrift_proxy/filters:filter_interface", + "//source/extensions/filters/network/thrift_proxy/filters:pass_through_filter_lib", "//source/extensions/filters/network/thrift_proxy/router:router_ratelimit_interface", "@envoy_api//envoy/extensions/filters/network/thrift_proxy/filters/ratelimit/v3:pkg_cc_proto", ], diff --git a/source/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit.cc b/source/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit.cc index bdcc6d73d5..621332f678 100644 --- a/source/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit.cc +++ b/source/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit.cc @@ -25,7 +25,7 @@ ThriftProxy::FilterStatus Filter::messageBegin(ThriftProxy::MessageMetadataShare } void Filter::initiateCall(const ThriftProxy::MessageMetadata& metadata) { - ThriftProxy::Router::RouteConstSharedPtr route = callbacks_->route(); + ThriftProxy::Router::RouteConstSharedPtr route = decoder_callbacks_->route(); if (!route || !route->routeEntry()) { return; } @@ -77,10 +77,11 @@ void Filter::complete(Filters::Common::RateLimit::LimitStatus status, cluster_->statsScope().counterFromStatName(stat_names.error_).inc(); if (!config_->failureModeAllow()) { state_ = State::Responded; - callbacks_->sendLocalReply( + decoder_callbacks_->sendLocalReply( ThriftProxy::AppException(ThriftProxy::AppExceptionType::InternalError, "limiter error"), false); - callbacks_->streamInfo().setResponseFlag(StreamInfo::ResponseFlag::RateLimitServiceError); + decoder_callbacks_->streamInfo().setResponseFlag( + StreamInfo::ResponseFlag::RateLimitServiceError); return; } cluster_->statsScope().counterFromStatName(stat_names.failure_mode_allowed_).inc(); @@ -89,17 +90,17 @@ void Filter::complete(Filters::Common::RateLimit::LimitStatus status, cluster_->statsScope().counterFromStatName(stat_names.over_limit_).inc(); if (config_->runtime().snapshot().featureEnabled("ratelimit.thrift_filter_enforcing", 100)) { state_ = State::Responded; - callbacks_->sendLocalReply( + decoder_callbacks_->sendLocalReply( ThriftProxy::AppException(ThriftProxy::AppExceptionType::InternalError, "over limit"), false); - callbacks_->streamInfo().setResponseFlag(StreamInfo::ResponseFlag::RateLimited); + decoder_callbacks_->streamInfo().setResponseFlag(StreamInfo::ResponseFlag::RateLimited); return; } break; } if (!initiating_call_) { - callbacks_->continueDecoding(); + decoder_callbacks_->continueDecoding(); } } @@ -117,7 +118,8 @@ void Filter::populateRateLimitDescriptors( continue; } rate_limit.populateDescriptors(*route_entry, descriptors, config_->localInfo().clusterName(), - metadata, *callbacks_->streamInfo().downstreamRemoteAddress()); + metadata, + *decoder_callbacks_->streamInfo().downstreamRemoteAddress()); } } diff --git a/source/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit.h b/source/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit.h index 7fe2889af7..1c01f8af85 100644 --- a/source/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit.h +++ b/source/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit.h @@ -13,7 +13,7 @@ #include "extensions/filters/common/ratelimit/ratelimit.h" #include "extensions/filters/common/ratelimit/stat_names.h" -#include "extensions/filters/network/thrift_proxy/filters/filter.h" +#include "extensions/filters/network/thrift_proxy/filters/pass_through_filter.h" namespace Envoy { namespace Extensions { @@ -65,69 +65,16 @@ using ConfigSharedPtr = std::shared_ptr; * error is returned and the failure_mode_deny option is enabled, an application exception is * returned. By default, errors allow the request to continue. */ -class Filter : public ThriftProxy::ThriftFilters::DecoderFilter, +class Filter : public ThriftProxy::ThriftFilters::PassThroughDecoderFilter, public Filters::Common::RateLimit::RequestCallbacks { public: Filter(ConfigSharedPtr config, Filters::Common::RateLimit::ClientPtr&& client) : config_(std::move(config)), client_(std::move(client)) {} ~Filter() override = default; - // ThriftFilters::ThriftDecoderFilter + // ThriftFilters::PassThroughDecoderFilter void onDestroy() override; - void setDecoderFilterCallbacks( - ThriftProxy::ThriftFilters::DecoderFilterCallbacks& callbacks) override { - callbacks_ = &callbacks; - }; - ThriftProxy::FilterStatus - transportBegin(NetworkFilters::ThriftProxy::MessageMetadataSharedPtr) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus transportEnd() override { return ThriftProxy::FilterStatus::Continue; } ThriftProxy::FilterStatus messageBegin(ThriftProxy::MessageMetadataSharedPtr) override; - ThriftProxy::FilterStatus messageEnd() override { return ThriftProxy::FilterStatus::Continue; } - ThriftProxy::FilterStatus structBegin(absl::string_view) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus structEnd() override { return ThriftProxy::FilterStatus::Continue; } - ThriftProxy::FilterStatus fieldBegin(absl::string_view, ThriftProxy::FieldType&, - int16_t&) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus fieldEnd() override { return ThriftProxy::FilterStatus::Continue; } - ThriftProxy::FilterStatus boolValue(bool&) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus byteValue(uint8_t&) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus int16Value(int16_t&) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus int32Value(int32_t&) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus int64Value(int64_t&) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus doubleValue(double&) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus stringValue(absl::string_view) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus mapBegin(ThriftProxy::FieldType&, ThriftProxy::FieldType&, - uint32_t&) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus mapEnd() override { return ThriftProxy::FilterStatus::Continue; } - ThriftProxy::FilterStatus listBegin(ThriftProxy::FieldType&, uint32_t&) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus listEnd() override { return ThriftProxy::FilterStatus::Continue; } - ThriftProxy::FilterStatus setBegin(ThriftProxy::FieldType&, uint32_t&) override { - return ThriftProxy::FilterStatus::Continue; - } - ThriftProxy::FilterStatus setEnd() override { return ThriftProxy::FilterStatus::Continue; } // RateLimit::RequestCallbacks void complete(Filters::Common::RateLimit::LimitStatus status, @@ -145,7 +92,6 @@ class Filter : public ThriftProxy::ThriftFilters::DecoderFilter, ConfigSharedPtr config_; Filters::Common::RateLimit::ClientPtr client_; - ThriftProxy::ThriftFilters::DecoderFilterCallbacks* callbacks_{}; State state_{State::NotStarted}; Upstream::ClusterInfoConstSharedPtr cluster_; bool initiating_call_{false}; From cb0342fe0c302f3f69a5ef18aa62f7d78da3f67b Mon Sep 17 00:00:00 2001 From: zyfjeff Date: Wed, 5 Feb 2020 06:55:35 +0800 Subject: [PATCH 04/87] try shrink heap at some key points (#9912) Signed-off-by: tianqian.zyf --- source/common/config/BUILD | 2 ++ source/common/config/grpc_mux_impl.cc | 2 ++ source/common/config/new_grpc_mux_impl.cc | 2 ++ source/common/memory/BUILD | 3 +++ source/common/memory/stats.cc | 6 ++++++ source/common/memory/stats.h | 5 +++++ source/common/memory/utils.cc | 24 +++++++++++++++++++++++ source/common/memory/utils.h | 1 + source/server/http/BUILD | 1 + source/server/http/admin.cc | 2 ++ tools/spelling_dictionary.txt | 1 + 11 files changed, 49 insertions(+) diff --git a/source/common/config/BUILD b/source/common/config/BUILD index bf9242df38..ad2db3c578 100644 --- a/source/common/config/BUILD +++ b/source/common/config/BUILD @@ -147,6 +147,7 @@ envoy_cc_library( "//include/envoy/config:subscription_interface", "//include/envoy/upstream:cluster_manager_interface", "//source/common/common:minimal_logger_lib", + "//source/common/memory:utils_lib", "//source/common/protobuf", "@envoy_api//envoy/api/v2:pkg_cc_proto", "@envoy_api//envoy/service/discovery/v3:pkg_cc_proto", @@ -177,6 +178,7 @@ envoy_cc_library( ":watch_map_lib", "//include/envoy/event:dispatcher_interface", "//include/envoy/grpc:async_client_interface", + "//source/common/memory:utils_lib", "@envoy_api//envoy/api/v2:pkg_cc_proto", "@envoy_api//envoy/service/discovery/v3:pkg_cc_proto", ], diff --git a/source/common/config/grpc_mux_impl.cc b/source/common/config/grpc_mux_impl.cc index 694dea2373..92aa93f365 100644 --- a/source/common/config/grpc_mux_impl.cc +++ b/source/common/config/grpc_mux_impl.cc @@ -6,6 +6,7 @@ #include "common/config/utility.h" #include "common/config/version_converter.h" +#include "common/memory/utils.h" #include "common/protobuf/protobuf.h" namespace Envoy { @@ -199,6 +200,7 @@ void GrpcMuxImpl::onDiscoveryResponse( // TODO(mattklein123): In the future if we start tracking per-resource versions, we // would do that tracking here. api_state_[type_url].request_.set_version_info(message->version_info()); + Memory::Utils::tryShrinkHeap(); } catch (const EnvoyException& e) { for (auto watch : api_state_[type_url].watches_) { watch->callbacks_.onConfigUpdateFailed( diff --git a/source/common/config/new_grpc_mux_impl.cc b/source/common/config/new_grpc_mux_impl.cc index 43012559bd..20fd240c9f 100644 --- a/source/common/config/new_grpc_mux_impl.cc +++ b/source/common/config/new_grpc_mux_impl.cc @@ -7,6 +7,7 @@ #include "common/common/token_bucket_impl.h" #include "common/config/utility.h" #include "common/config/version_converter.h" +#include "common/memory/utils.h" #include "common/protobuf/protobuf.h" #include "common/protobuf/utility.h" @@ -60,6 +61,7 @@ void NewGrpcMuxImpl::onDiscoveryResponse( } kickOffAck(sub->second->sub_state_.handleResponse(*message)); + Memory::Utils::tryShrinkHeap(); } void NewGrpcMuxImpl::onStreamEstablished() { diff --git a/source/common/memory/BUILD b/source/common/memory/BUILD index 83a46fa4fc..1501b81a6b 100644 --- a/source/common/memory/BUILD +++ b/source/common/memory/BUILD @@ -23,6 +23,9 @@ envoy_cc_library( srcs = ["utils.cc"], hdrs = ["utils.h"], tcmalloc_dep = 1, + deps = [ + ":stats_lib", + ], ) envoy_cc_library( diff --git a/source/common/memory/stats.cc b/source/common/memory/stats.cc index d35b2add1a..88a033ef54 100644 --- a/source/common/memory/stats.cc +++ b/source/common/memory/stats.cc @@ -42,6 +42,12 @@ uint64_t Stats::totalPageHeapUnmapped() { return value; } +uint64_t Stats::totalPhysicalBytes() { + size_t value = 0; + MallocExtension::instance()->GetNumericProperty("generic.total_physical_bytes", &value); + return value; +} + void Stats::dumpStatsToLog() { constexpr int buffer_size = 100000; auto buffer = std::make_unique(buffer_size); diff --git a/source/common/memory/stats.h b/source/common/memory/stats.h index 21b8cdd105..71bc261ae1 100644 --- a/source/common/memory/stats.h +++ b/source/common/memory/stats.h @@ -40,6 +40,11 @@ class Stats { */ static uint64_t totalPageHeapFree(); + /** + * @return uint64_t estimate of total bytes of the physical memory usage by the allocator + */ + static uint64_t totalPhysicalBytes(); + /** * Log detailed stats about current memory allocation. Intended for debugging purposes. */ diff --git a/source/common/memory/utils.cc b/source/common/memory/utils.cc index dec4a124f9..2fa9575722 100644 --- a/source/common/memory/utils.cc +++ b/source/common/memory/utils.cc @@ -1,5 +1,8 @@ #include "common/memory/utils.h" +#include "common/common/assert.h" +#include "common/memory/stats.h" + #ifdef TCMALLOC #include "gperftools/malloc_extension.h" #endif @@ -13,5 +16,26 @@ void Utils::releaseFreeMemory() { #endif } +/* + The purpose of this function is to release the cache introduced by tcmalloc, + mainly in xDS config updates, admin handler, and so on. all work on the main thread, + so the overall impact on performance is small. + Ref: https://github.com/envoyproxy/envoy/pull/9471#discussion_r363825985 +*/ +void Utils::tryShrinkHeap() { +#ifdef TCMALLOC + // TODO(zyfjeff): Make max unfreed memory byte configurable + static const uint64_t MAX_UNFREED_MEMORY_BYTE = 100 * 1024 * 1024; + auto total_physical_bytes = Stats::totalPhysicalBytes(); + auto allocated_size_by_app = Stats::totalCurrentlyAllocated(); + + ASSERT(total_physical_bytes >= allocated_size_by_app); + + if ((total_physical_bytes - allocated_size_by_app) >= MAX_UNFREED_MEMORY_BYTE) { + Utils::releaseFreeMemory(); + } +#endif +} + } // namespace Memory } // namespace Envoy diff --git a/source/common/memory/utils.h b/source/common/memory/utils.h index d6311204a2..da475f1801 100644 --- a/source/common/memory/utils.h +++ b/source/common/memory/utils.h @@ -6,6 +6,7 @@ namespace Memory { class Utils { public: static void releaseFreeMemory(); + static void tryShrinkHeap(); }; } // namespace Memory diff --git a/source/server/http/BUILD b/source/server/http/BUILD index 303ee872af..0f80988f87 100644 --- a/source/server/http/BUILD +++ b/source/server/http/BUILD @@ -48,6 +48,7 @@ envoy_cc_library( "//source/common/http:headers_lib", "//source/common/http:utility_lib", "//source/common/memory:stats_lib", + "//source/common/memory:utils_lib", "//source/common/network:connection_balancer_lib", "//source/common/network:listen_socket_lib", "//source/common/network:raw_buffer_socket_lib", diff --git a/source/server/http/admin.cc b/source/server/http/admin.cc index 4567ae5545..0b16a19678 100644 --- a/source/server/http/admin.cc +++ b/source/server/http/admin.cc @@ -46,6 +46,7 @@ #include "common/http/headers.h" #include "common/json/json_loader.h" #include "common/memory/stats.h" +#include "common/memory/utils.h" #include "common/network/listen_socket_impl.h" #include "common/network/utility.h" #include "common/profiler/profiler.h" @@ -1491,6 +1492,7 @@ Http::Code AdminImpl::runCallback(absl::string_view path_and_query, } } code = handler.handler_(path_and_query, response_headers, response, admin_stream); + Memory::Utils::tryShrinkHeap(); break; } } diff --git a/tools/spelling_dictionary.txt b/tools/spelling_dictionary.txt index fc33d74061..3982a43a63 100644 --- a/tools/spelling_dictionary.txt +++ b/tools/spelling_dictionary.txt @@ -1091,6 +1091,7 @@ unejection unescape unescaped unescaping +unfreed unhandled unicast unicode From b844788bd993b8dcfc91bb145e3ff6b475584dda Mon Sep 17 00:00:00 2001 From: yanavlasov Date: Wed, 5 Feb 2020 00:42:47 -0500 Subject: [PATCH 05/87] Fix CRLF in Request-Line (#9930) Signed-off-by: Yan Avlasov --- test/integration/idle_timeout_integration_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/idle_timeout_integration_test.cc b/test/integration/idle_timeout_integration_test.cc index 2bc8fe4f00..7607048d5e 100644 --- a/test/integration/idle_timeout_integration_test.cc +++ b/test/integration/idle_timeout_integration_test.cc @@ -325,7 +325,7 @@ TEST_P(IdleTimeoutIntegrationTest, RequestTimeoutUnconfiguredDoesNotTriggerOnBod } TEST_P(IdleTimeoutIntegrationTest, RequestTimeoutTriggersOnRawIncompleteRequestWithHeaders) { - // Omitting \r\n\n\n does not indicate incomplete request in HTTP2 + // Omitting \r\n\r\n does not indicate incomplete request in HTTP2 if (downstreamProtocol() == Envoy::Http::CodecClient::Type::HTTP2) { return; } @@ -349,7 +349,7 @@ TEST_P(IdleTimeoutIntegrationTest, RequestTimeoutDoesNotTriggerOnRawCompleteRequ fake_upstreams_[0]->set_allow_unexpected_disconnects(true); std::string raw_response; - sendRawHttpAndWaitForResponse(lookupPort("http"), "GET / HTTP/1.1\r\n\n\n", &raw_response, true); + sendRawHttpAndWaitForResponse(lookupPort("http"), "GET / HTTP/1.1\r\n\r\n", &raw_response, true); EXPECT_THAT(raw_response, testing::Not(testing::HasSubstr("request timeout"))); } From 1f3e7ddae990c215435a491d3e16f2650f4d99aa Mon Sep 17 00:00:00 2001 From: yanavlasov Date: Wed, 5 Feb 2020 00:43:15 -0500 Subject: [PATCH 06/87] Fully qualify calls to methods in the absl:: namespace. absl::string_view is an alias of std::string_view in some C++17 environments and argument dependent lookup fails to find functions in absl namespace. (#9931) Signed-off-by: Yan Avlasov --- .../filters/http/cache/http_cache_utils.cc | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/extensions/filters/http/cache/http_cache_utils.cc b/source/extensions/filters/http/cache/http_cache_utils.cc index 26e235dfdd..14d3f67d97 100644 --- a/source/extensions/filters/http/cache/http_cache_utils.cc +++ b/source/extensions/filters/http/cache/http_cache_utils.cc @@ -45,7 +45,7 @@ bool Utils::tchar(char c) { // // token = 1*tchar bool Utils::eatToken(absl::string_view& s) { - const absl::string_view::iterator token_end = c_find_if_not(s, &tchar); + const absl::string_view::iterator token_end = absl::c_find_if_not(s, &tchar); if (token_end == s.begin()) { return false; } @@ -84,7 +84,7 @@ void Utils::eatDirectiveArgument(absl::string_view& s) { // SystemTime::duration::zero(). If parsing overflows, returns // SystemTime::duration::max(). SystemTime::duration Utils::eatLeadingDuration(absl::string_view& s) { - const absl::string_view::iterator digits_end = c_find_if_not(s, &absl::ascii_isdigit); + const absl::string_view::iterator digits_end = absl::c_find_if_not(s, &absl::ascii_isdigit); const size_t digits_length = digits_end - s.begin(); if (digits_length == 0) { return SystemTime::duration::zero(); @@ -118,26 +118,26 @@ SystemTime::duration Utils::effectiveMaxAge(absl::string_view cache_control) { while (!cache_control.empty()) { // Each time through the loop, we eat one cache-directive. Each branch // either returns or completely eats a cache-directive. - if (ConsumePrefix(&cache_control, "no-cache")) { + if (absl::ConsumePrefix(&cache_control, "no-cache")) { if (eatToken(cache_control)) { // The token wasn't no-cache; it just started that way, so we must // finish eating this cache-directive. - if (ConsumePrefix(&cache_control, "=")) { + if (absl::ConsumePrefix(&cache_control, "=")) { eatDirectiveArgument(cache_control); } } else { // Found a no-cache directive, so validation is required. return SystemTime::duration::zero(); } - } else if (ConsumePrefix(&cache_control, "s-maxage=")) { + } else if (absl::ConsumePrefix(&cache_control, "s-maxage=")) { max_age = eatLeadingDuration(cache_control); found_s_maxage = true; - cache_control = StripLeadingAsciiWhitespace(cache_control); + cache_control = absl::StripLeadingAsciiWhitespace(cache_control); if (!cache_control.empty() && cache_control[0] != ',') { // Unexpected text at end of directive return SystemTime::duration::zero(); } - } else if (!found_s_maxage && ConsumePrefix(&cache_control, "max-age=")) { + } else if (!found_s_maxage && absl::ConsumePrefix(&cache_control, "max-age=")) { max_age = eatLeadingDuration(cache_control); if (!cache_control.empty() && cache_control[0] != ',') { // Unexpected text at end of directive @@ -145,7 +145,7 @@ SystemTime::duration Utils::effectiveMaxAge(absl::string_view cache_control) { } } else if (eatToken(cache_control)) { // Unknown directive--ignore. - if (ConsumePrefix(&cache_control, "=")) { + if (absl::ConsumePrefix(&cache_control, "=")) { eatDirectiveArgument(cache_control); } } else { @@ -154,8 +154,8 @@ SystemTime::duration Utils::effectiveMaxAge(absl::string_view cache_control) { } // Whichever branch we took should have consumed the entire cache-directive, // so we just need to eat the delimiter and optional whitespace. - ConsumePrefix(&cache_control, ","); - cache_control = StripLeadingAsciiWhitespace(cache_control); + absl::ConsumePrefix(&cache_control, ","); + cache_control = absl::StripLeadingAsciiWhitespace(cache_control); } return max_age; } From 2d90dd7157af272ec1fa082f4f8b58d703a58ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Guti=C3=A9rrez=20Segal=C3=A9s?= Date: Wed, 5 Feb 2020 00:43:46 -0500 Subject: [PATCH 07/87] docs: fix aws_request_signing's config example (#9932) Signed-off-by: Raul Gutierrez Segales --- .../http/http_filters/aws_request_signing_filter.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/root/configuration/http/http_filters/aws_request_signing_filter.rst b/docs/root/configuration/http/http_filters/aws_request_signing_filter.rst index 9184d31cff..4c9e097b87 100644 --- a/docs/root/configuration/http/http_filters/aws_request_signing_filter.rst +++ b/docs/root/configuration/http/http_filters/aws_request_signing_filter.rst @@ -25,6 +25,8 @@ Example filter configuration: name: envoy.filters.http.aws_request_signing typed_config: "@type": type.googleapis.com/envoy.config.filter.http.aws_request_signing.v2alpha.AwsRequestSigning + service_name: s3 + region: us-west-2 Statistics From dea4eb001f78b5beeab234c2c481fd4d28af0f3b Mon Sep 17 00:00:00 2001 From: Matt Klein Date: Wed, 5 Feb 2020 09:11:56 -0800 Subject: [PATCH 08/87] http: codec refactor part 2 (#9918) This is part 1 in a set of changes to refactor the HTTP codecs so they can emit typed request headers, request trailers, response headers, and response trailers. This will help clean up various interface inconsistencies as well as unlock a greater variety of header map improvements. Signed-off-by: Matt Klein --- include/envoy/http/api_listener.h | 9 +- include/envoy/http/codec.h | 151 +- include/envoy/http/conn_pool.h | 6 +- source/common/http/codec_client.cc | 2 +- source/common/http/codec_client.h | 10 +- source/common/http/codec_wrappers.h | 24 +- source/common/http/conn_manager_impl.cc | 8 +- source/common/http/conn_manager_impl.h | 15 +- source/common/http/conn_pool_base.cc | 12 +- source/common/http/conn_pool_base.h | 12 +- source/common/http/conn_pool_base_legacy.cc | 5 +- source/common/http/conn_pool_base_legacy.h | 6 +- source/common/http/http1/codec_impl.cc | 27 +- source/common/http/http1/codec_impl.h | 44 +- source/common/http/http1/conn_pool.cc | 12 +- source/common/http/http1/conn_pool.h | 8 +- source/common/http/http1/conn_pool_legacy.cc | 14 +- source/common/http/http1/conn_pool_legacy.h | 10 +- source/common/http/http2/codec_impl.cc | 62 +- source/common/http/http2/codec_impl.h | 63 +- source/common/http/http2/conn_pool.cc | 2 +- source/common/http/http2/conn_pool.h | 2 +- source/common/http/http2/conn_pool_legacy.cc | 4 +- source/common/http/http2/conn_pool_legacy.h | 4 +- source/common/router/router.cc | 4 +- source/common/router/router.h | 14 +- source/common/upstream/health_checker_impl.cc | 2 +- source/common/upstream/health_checker_impl.h | 20 +- .../quic_listeners/quiche/codec_impl.cc | 13 +- .../quic_listeners/quiche/codec_impl.h | 2 +- .../quiche/envoy_quic_client_stream.cc | 15 +- .../quiche/envoy_quic_client_stream.h | 15 +- .../quiche/envoy_quic_server_session.cc | 6 +- .../quiche/envoy_quic_server_session.h | 4 +- .../quiche/envoy_quic_server_stream.cc | 11 +- .../quiche/envoy_quic_server_stream.h | 8 +- .../quic_listeners/quiche/envoy_quic_stream.h | 13 +- test/common/http/async_client_impl_test.cc | 62 +- test/common/http/codec_client_test.cc | 56 +- test/common/http/codec_impl_fuzz_test.cc | 101 +- test/common/http/codec_wrappers_test.cc | 43 +- test/common/http/common.h | 4 +- .../http/conn_manager_impl_fuzz_test.cc | 4 +- test/common/http/conn_manager_impl_test.cc | 212 +-- test/common/http/http1/codec_impl_test.cc | 296 ++-- .../http/http1/conn_pool_legacy_test.cc | 110 +- test/common/http/http1/conn_pool_test.cc | 110 +- test/common/http/http2/codec_impl_test.cc | 18 +- .../http/http2/conn_pool_legacy_test.cc | 105 +- test/common/http/http2/conn_pool_test.cc | 133 +- test/common/http/http2/frame_replay.cc | 2 +- test/common/http/http2/frame_replay.h | 6 +- test/common/router/router_test.cc | 1540 +++++++++-------- .../common/router/router_upstream_log_test.cc | 16 +- .../upstream/health_checker_impl_test.cc | 8 +- .../quiche/envoy_quic_client_session_test.cc | 8 +- .../quiche/envoy_quic_client_stream_test.cc | 4 +- .../quiche/envoy_quic_server_session_test.cc | 52 +- .../quiche/envoy_quic_server_stream_test.cc | 4 +- .../api_listener_integration_test.cc | 2 +- test/integration/autonomous_upstream.cc | 6 +- test/integration/autonomous_upstream.h | 4 +- test/integration/fake_upstream.cc | 4 +- test/integration/fake_upstream.h | 15 +- test/integration/http2_integration_test.cc | 10 +- .../http2_upstream_integration_test.cc | 8 +- test/integration/http_integration.cc | 20 +- test/integration/http_integration.h | 16 +- .../http_timeout_integration_test.cc | 4 +- test/integration/integration.h | 2 +- test/integration/utility.cc | 2 +- test/integration/utility.h | 2 +- test/mocks/http/api_listener.h | 4 +- test/mocks/http/conn_pool.h | 6 +- test/mocks/http/mocks.h | 6 +- test/mocks/http/stream_decoder.cc | 29 + test/mocks/http/stream_decoder.h | 37 +- test/mocks/http/stream_encoder.cc | 29 + test/mocks/http/stream_encoder.h | 26 +- 79 files changed, 2073 insertions(+), 1692 deletions(-) diff --git a/include/envoy/http/api_listener.h b/include/envoy/http/api_listener.h index 59c83a5dd9..9c119e5c7d 100644 --- a/include/envoy/http/api_listener.h +++ b/include/envoy/http/api_listener.h @@ -20,14 +20,15 @@ class ApiListener { * response are backed by the same Stream object. * @param is_internally_created indicates if this stream was originated by a * client, or was created by Envoy, by example as part of an internal redirect. - * @return StreamDecoder& supplies the decoder callbacks to fire into for stream decoding events. + * @return RequestDecoder& supplies the decoder callbacks to fire into for stream + * decoding events. */ - virtual StreamDecoder& newStream(StreamEncoder& response_encoder, - bool is_internally_created = false) PURE; + virtual RequestDecoder& newStream(ResponseEncoder& response_encoder, + bool is_internally_created = false) PURE; }; using ApiListenerPtr = std::unique_ptr; using ApiListenerOptRef = absl::optional>; } // namespace Http -} // namespace Envoy \ No newline at end of file +} // namespace Envoy diff --git a/include/envoy/http/codec.h b/include/envoy/http/codec.h index 55841b7e14..fb7c8b5978 100644 --- a/include/envoy/http/codec.h +++ b/include/envoy/http/codec.h @@ -27,89 +27,158 @@ const char MaxResponseHeadersCountOverrideKey[] = class Stream; /** - * Encodes an HTTP stream. + * Encodes an HTTP stream. This interface contains methods common to both the request and response + * path. + * TODO(mattklein123): Consider removing the StreamEncoder interface entirely and just duplicating + * the methods in both the request/response path for simplicity. */ class StreamEncoder { public: virtual ~StreamEncoder() = default; /** - * Encode 100-Continue headers. - * @param headers supplies the 100-Continue header map to encode. + * Encode a data frame. + * @param data supplies the data to encode. The data may be moved by the encoder. + * @param end_stream supplies whether this is the last data frame. */ - virtual void encode100ContinueHeaders(const HeaderMap& headers) PURE; + virtual void encodeData(Buffer::Instance& data, bool end_stream) PURE; + + /** + * @return Stream& the backing stream. + */ + virtual Stream& getStream() PURE; + /** + * Encode metadata. + * @param metadata_map_vector is the vector of metadata maps to encode. + */ + virtual void encodeMetadata(const MetadataMapVector& metadata_map_vector) PURE; +}; + +/** + * Stream encoder used for sending a request (client to server). Virtual inheritance is required + * due to a parallel implementation split between the shared base class and the derived class. + * TODO(mattklein123): In a future change the header types will be changed to differentiate from + * the response path. + */ +class RequestEncoder : public virtual StreamEncoder { +public: /** * Encode headers, optionally indicating end of stream. Response headers must * have a valid :status set. * @param headers supplies the header map to encode. - * @param end_stream supplies whether this is a header only request/response. + * @param end_stream supplies whether this is a header only request. */ virtual void encodeHeaders(const HeaderMap& headers, bool end_stream) PURE; - /** - * Encode a data frame. - * @param data supplies the data to encode. The data may be moved by the encoder. - * @param end_stream supplies whether this is the last data frame. - */ - virtual void encodeData(Buffer::Instance& data, bool end_stream) PURE; - /** * Encode trailers. This implicitly ends the stream. * @param trailers supplies the trailers to encode. */ virtual void encodeTrailers(const HeaderMap& trailers) PURE; +}; +/** + * Stream encoder used for sending a response (server to client). Virtual inheritance is required + * due to a parallel implementation split between the shared base class and the derived class. + * TODO(mattklein123): In a future change the header types will be changed to differentiate from + * the request path. + */ +class ResponseEncoder : public virtual StreamEncoder { +public: /** - * @return Stream& the backing stream. + * Encode 100-Continue headers. + * @param headers supplies the 100-Continue header map to encode. */ - virtual Stream& getStream() PURE; + virtual void encode100ContinueHeaders(const HeaderMap& headers) PURE; /** - * Encode metadata. - * @param metadata_map_vector is the vector of metadata maps to encode. + * Encode headers, optionally indicating end of stream. Response headers must + * have a valid :status set. + * @param headers supplies the header map to encode. + * @param end_stream supplies whether this is a header only response. */ - virtual void encodeMetadata(const MetadataMapVector& metadata_map_vector) PURE; + virtual void encodeHeaders(const HeaderMap& headers, bool end_stream) PURE; + + /** + * Encode trailers. This implicitly ends the stream. + * @param trailers supplies the trailers to encode. + */ + virtual void encodeTrailers(const HeaderMap& trailers) PURE; }; /** - * Decodes an HTTP stream. These are callbacks fired into a sink. + * Decodes an HTTP stream. These are callbacks fired into a sink. This interface contains methods + * common to both the request and response path. + * TODO(mattklein123): Consider removing the StreamDecoder interface entirely and just duplicating + * the methods in both the request/response path for simplicity. */ class StreamDecoder { public: virtual ~StreamDecoder() = default; /** - * Called with decoded 100-Continue headers. - * @param headers supplies the decoded 100-Continue headers map that is moved into the callee. + * Called with a decoded data frame. + * @param data supplies the decoded data. + * @param end_stream supplies whether this is the last data frame. */ - virtual void decode100ContinueHeaders(HeaderMapPtr&& headers) PURE; + virtual void decodeData(Buffer::Instance& data, bool end_stream) PURE; /** - * Called with decoded headers, optionally indicating end of stream. - * @param headers supplies the decoded headers map that is moved into the callee. - * @param end_stream supplies whether this is a header only request/response. + * Called with decoded METADATA. + * @param decoded METADATA. */ - virtual void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) PURE; + virtual void decodeMetadata(MetadataMapPtr&& metadata_map) PURE; +}; +/** + * Stream decoder used for receiving a request (client to server). Virtual inheritance is required + * due to a parallel implementation split between the shared base class and the derived class. + * TODO(mattklein123): In a future change the header types will be changed to differentiate from + * the response path. + */ +class RequestDecoder : public virtual StreamDecoder { +public: /** - * Called with a decoded data frame. - * @param data supplies the decoded data. - * @param end_stream supplies whether this is the last data frame. + * Called with decoded headers, optionally indicating end of stream. + * @param headers supplies the decoded headers map. + * @param end_stream supplies whether this is a header only request. */ - virtual void decodeData(Buffer::Instance& data, bool end_stream) PURE; + virtual void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) PURE; /** * Called with a decoded trailers frame. This implicitly ends the stream. * @param trailers supplies the decoded trailers. */ virtual void decodeTrailers(HeaderMapPtr&& trailers) PURE; +}; +/** + * Stream decoder used for receiving a response (server to client). Virtual inheritance is required + * due to a parallel implementation split between the shared base class and the derived class. + * TODO(mattklein123): In a future change the header types will be changed to differentiate from + * the request path. + */ +class ResponseDecoder : public virtual StreamDecoder { +public: /** - * Called with decoded METADATA. - * @param decoded METADATA. + * Called with decoded 100-Continue headers. + * @param headers supplies the decoded 100-Continue headers map. */ - virtual void decodeMetadata(MetadataMapPtr&& metadata_map) PURE; + virtual void decode100ContinueHeaders(HeaderMapPtr&& headers) PURE; + + /** + * Called with decoded headers, optionally indicating end of stream. + * @param headers supplies the decoded headers map. + * @param end_stream supplies whether this is a header only response. + */ + virtual void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) PURE; + + /** + * Called with a decoded trailers frame. This implicitly ends the stream. + * @param trailers supplies the decoded trailers. + */ + virtual void decodeTrailers(HeaderMapPtr&& trailers) PURE; }; /** @@ -198,14 +267,14 @@ class Stream { */ virtual void readDisable(bool disable) PURE; - /* + /** * Return the number of bytes this stream is allowed to buffer, or 0 if there is no limit * configured. * @return uint32_t the stream's configured buffer limits. */ virtual uint32_t bufferLimit() PURE; - /* + /** * @return string_view optionally return the reason behind codec level errors. * * This information is communicated via direct accessor rather than passed with the @@ -214,7 +283,7 @@ class Stream { */ virtual absl::string_view responseDetails() { return ""; } - /* + /** * @return const Address::InstanceConstSharedPtr& the local address of the connection associated * with the stream. */ @@ -421,17 +490,17 @@ class ServerConnectionCallbacks : public virtual ConnectionCallbacks { * response are backed by the same Stream object. * @param is_internally_created indicates if this stream was originated by a * client, or was created by Envoy, by example as part of an internal redirect. - * @return StreamDecoder& supplies the decoder callbacks to fire into for stream decoding events. + * @return RequestDecoder& supplies the decoder callbacks to fire into for stream decoding + * events. */ - virtual StreamDecoder& newStream(StreamEncoder& response_encoder, - bool is_internally_created = false) PURE; + virtual RequestDecoder& newStream(ResponseEncoder& response_encoder, + bool is_internally_created = false) PURE; }; /** * A server side HTTP connection. */ class ServerConnection : public virtual Connection {}; - using ServerConnectionPtr = std::unique_ptr; /** @@ -442,9 +511,9 @@ class ClientConnection : public virtual Connection { /** * Create a new outgoing request stream. * @param response_decoder supplies the decoder callbacks to fire response events into. - * @return StreamEncoder& supplies the encoder to write the request into. + * @return RequestEncoder& supplies the encoder to write the request into. */ - virtual StreamEncoder& newStream(StreamDecoder& response_decoder) PURE; + virtual RequestEncoder& newStream(ResponseDecoder& response_decoder) PURE; }; using ClientConnectionPtr = std::unique_ptr; diff --git a/include/envoy/http/conn_pool.h b/include/envoy/http/conn_pool.h index 8ee9270e6d..1eb40df565 100644 --- a/include/envoy/http/conn_pool.h +++ b/include/envoy/http/conn_pool.h @@ -60,8 +60,7 @@ class Callbacks { * connection pools the description may be different each time this is called. * @param info supplies the stream info object associated with the upstream connection. */ - virtual void onPoolReady(Http::StreamEncoder& encoder, - Upstream::HostDescriptionConstSharedPtr host, + virtual void onPoolReady(RequestEncoder& encoder, Upstream::HostDescriptionConstSharedPtr host, const StreamInfo::StreamInfo& info) PURE; }; @@ -119,7 +118,8 @@ class Instance : public Event::DeferredDeletable { * @warning Do not call cancel() from the callbacks, as the request is implicitly canceled when * the callbacks are called. */ - virtual Cancellable* newStream(Http::StreamDecoder& response_decoder, Callbacks& callbacks) PURE; + virtual Cancellable* newStream(Http::ResponseDecoder& response_decoder, + Callbacks& callbacks) PURE; /** * @return Upstream::HostDescriptionConstSharedPtr the host for which connections are pooled. diff --git a/source/common/http/codec_client.cc b/source/common/http/codec_client.cc index 04a2ca0d7b..d4a65c5aa0 100644 --- a/source/common/http/codec_client.cc +++ b/source/common/http/codec_client.cc @@ -58,7 +58,7 @@ void CodecClient::deleteRequest(ActiveRequest& request) { } } -StreamEncoder& CodecClient::newStream(StreamDecoder& response_decoder) { +RequestEncoder& CodecClient::newStream(ResponseDecoder& response_decoder) { ActiveRequestPtr request(new ActiveRequest(*this, response_decoder)); request->encoder_ = &codec_->newStream(*request); request->encoder_->getStream().addCallbacks(*request); diff --git a/source/common/http/codec_client.h b/source/common/http/codec_client.h index ab29c15db8..63d16b93dd 100644 --- a/source/common/http/codec_client.h +++ b/source/common/http/codec_client.h @@ -100,7 +100,7 @@ class CodecClient : Logger::Loggable, * @param response_decoder supplies the decoder to use for response callbacks. * @return StreamEncoder& the encoder to use for encoding the request. */ - StreamEncoder& newStream(StreamDecoder& response_decoder); + RequestEncoder& newStream(ResponseDecoder& response_decoder); void setConnectionStats(const Network::Connection::ConnectionStats& stats) { connection_->setConnectionStats(stats); @@ -186,9 +186,9 @@ class CodecClient : Logger::Loggable, struct ActiveRequest : LinkedObject, public Event::DeferredDeletable, public StreamCallbacks, - public StreamDecoderWrapper { - ActiveRequest(CodecClient& parent, StreamDecoder& inner) - : StreamDecoderWrapper(inner), parent_(parent) {} + public ResponseDecoderWrapper { + ActiveRequest(CodecClient& parent, ResponseDecoder& inner) + : ResponseDecoderWrapper(inner), parent_(parent) {} // StreamCallbacks void onResetStream(StreamResetReason reason, absl::string_view) override { @@ -201,7 +201,7 @@ class CodecClient : Logger::Loggable, void onPreDecodeComplete() override { parent_.responseDecodeComplete(*this); } void onDecodeComplete() override {} - StreamEncoder* encoder_{}; + RequestEncoder* encoder_{}; CodecClient& parent_; }; diff --git a/source/common/http/codec_wrappers.h b/source/common/http/codec_wrappers.h index f90bf1c0c5..ec99ddd29c 100644 --- a/source/common/http/codec_wrappers.h +++ b/source/common/http/codec_wrappers.h @@ -6,11 +6,11 @@ namespace Envoy { namespace Http { /** - * Wrapper for StreamDecoder that just forwards to an "inner" decoder. + * Wrapper for ResponseDecoder that just forwards to an "inner" decoder. */ -class StreamDecoderWrapper : public StreamDecoder { +class ResponseDecoderWrapper : public ResponseDecoder { public: - // StreamDecoder + // ResponseDecoder void decode100ContinueHeaders(HeaderMapPtr&& headers) override { inner_.decode100ContinueHeaders(std::move(headers)); } @@ -50,7 +50,7 @@ class StreamDecoderWrapper : public StreamDecoder { } protected: - StreamDecoderWrapper(StreamDecoder& inner) : inner_(inner) {} + ResponseDecoderWrapper(ResponseDecoder& inner) : inner_(inner) {} /** * Consumers of the wrapper generally want to know when a decode is complete. This is called @@ -59,19 +59,15 @@ class StreamDecoderWrapper : public StreamDecoder { virtual void onPreDecodeComplete() PURE; virtual void onDecodeComplete() PURE; - StreamDecoder& inner_; + ResponseDecoder& inner_; }; /** - * Wrapper for StreamEncoder that just forwards to an "inner" encoder. + * Wrapper for RequestEncoder that just forwards to an "inner" encoder. */ -class StreamEncoderWrapper : public StreamEncoder { +class RequestEncoderWrapper : public RequestEncoder { public: - // StreamEncoder - void encode100ContinueHeaders(const HeaderMap& headers) override { - inner_.encode100ContinueHeaders(headers); - } - + // RequestEncoder void encodeHeaders(const HeaderMap& headers, bool end_stream) override { inner_.encodeHeaders(headers, end_stream); if (end_stream) { @@ -98,7 +94,7 @@ class StreamEncoderWrapper : public StreamEncoder { Stream& getStream() override { return inner_.getStream(); } protected: - StreamEncoderWrapper(StreamEncoder& inner) : inner_(inner) {} + RequestEncoderWrapper(RequestEncoder& inner) : inner_(inner) {} /** * Consumers of the wrapper generally want to know when an encode is complete. This is called at @@ -106,7 +102,7 @@ class StreamEncoderWrapper : public StreamEncoder { */ virtual void onEncodeComplete() PURE; - StreamEncoder& inner_; + RequestEncoder& inner_; }; } // namespace Http diff --git a/source/common/http/conn_manager_impl.cc b/source/common/http/conn_manager_impl.cc index 3c4956339e..947d511fd5 100644 --- a/source/common/http/conn_manager_impl.cc +++ b/source/common/http/conn_manager_impl.cc @@ -254,8 +254,8 @@ void ConnectionManagerImpl::doDeferredStreamDestroy(ActiveStream& stream) { } } -StreamDecoder& ConnectionManagerImpl::newStream(StreamEncoder& response_encoder, - bool is_internally_created) { +RequestDecoder& ConnectionManagerImpl::newStream(ResponseEncoder& response_encoder, + bool is_internally_created) { if (connection_idle_timer_) { connection_idle_timer_->disableTimer(); } @@ -2297,14 +2297,14 @@ bool ConnectionManagerImpl::ActiveStreamDecoderFilter::recreateStream() { // decoder because the decoder callbacks are complete. It would be good to // null out that pointer but should not be necessary. HeaderMapPtr request_headers(std::move(parent_.request_headers_)); - StreamEncoder* response_encoder = parent_.response_encoder_; + ResponseEncoder* response_encoder = parent_.response_encoder_; parent_.response_encoder_ = nullptr; response_encoder->getStream().removeCallbacks(parent_); // This functionally deletes the stream (via deferred delete) so do not // reference anything beyond this point. parent_.connection_manager_.doEndStream(this->parent_); - StreamDecoder& new_stream = parent_.connection_manager_.newStream(*response_encoder, true); + RequestDecoder& new_stream = parent_.connection_manager_.newStream(*response_encoder, true); // We don't need to copy over the old parent FilterState from the old StreamInfo if it did not // store any objects with a LifeSpan at or above DownstreamRequest. This is to avoid unnecessary // heap allocation. diff --git a/source/common/http/conn_manager_impl.h b/source/common/http/conn_manager_impl.h index 57a2d4209c..072215fb18 100644 --- a/source/common/http/conn_manager_impl.h +++ b/source/common/http/conn_manager_impl.h @@ -86,8 +86,8 @@ class ConnectionManagerImpl : Logger::Loggable, void onGoAway() override; // Http::ServerConnectionCallbacks - StreamDecoder& newStream(StreamEncoder& response_encoder, - bool is_internally_created = false) override; + RequestDecoder& newStream(ResponseEncoder& response_encoder, + bool is_internally_created = false) override; // Network::ConnectionCallbacks void onEvent(Network::ConnectionEvent event) override; @@ -438,7 +438,7 @@ class ConnectionManagerImpl : Logger::Loggable, struct ActiveStream : LinkedObject, public Event::DeferredDeletable, public StreamCallbacks, - public StreamDecoder, + public RequestDecoder, public FilterChainFactoryCallbacks, public Tracing::Config, public ScopeTrackedObject { @@ -504,12 +504,13 @@ class ConnectionManagerImpl : Logger::Loggable, void onBelowWriteBufferLowWatermark() override; // Http::StreamDecoder - void decode100ContinueHeaders(HeaderMapPtr&&) override { NOT_REACHED_GCOVR_EXCL_LINE; } - void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) override; void decodeData(Buffer::Instance& data, bool end_stream) override; - void decodeTrailers(HeaderMapPtr&& trailers) override; void decodeMetadata(MetadataMapPtr&&) override; + // Http::RequestDecoder + void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) override; + void decodeTrailers(HeaderMapPtr&& trailers) override; + // Http::FilterChainFactoryCallbacks void addStreamDecoderFilter(StreamDecoderFilterSharedPtr filter) override { addStreamDecoderFilterWorker(filter, false); @@ -654,7 +655,7 @@ class ConnectionManagerImpl : Logger::Loggable, Router::ScopedConfigConstSharedPtr snapped_scoped_routes_config_; Tracing::SpanPtr active_span_; const uint64_t stream_id_; - StreamEncoder* response_encoder_{}; + ResponseEncoder* response_encoder_{}; HeaderMapPtr continue_headers_; HeaderMapPtr response_headers_; Buffer::WatermarkBufferPtr buffered_response_data_; diff --git a/source/common/http/conn_pool_base.cc b/source/common/http/conn_pool_base.cc index 89e63a7d1e..da9736a4e6 100644 --- a/source/common/http/conn_pool_base.cc +++ b/source/common/http/conn_pool_base.cc @@ -54,7 +54,8 @@ void ConnPoolImplBase::tryCreateNewConnection() { } } -void ConnPoolImplBase::attachRequestToClient(ActiveClient& client, StreamDecoder& response_decoder, +void ConnPoolImplBase::attachRequestToClient(ActiveClient& client, + ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks) { ASSERT(client.state_ == ActiveClient::State::READY); @@ -65,7 +66,7 @@ void ConnPoolImplBase::attachRequestToClient(ActiveClient& client, StreamDecoder host_->cluster().stats().upstream_rq_pending_overflow_.inc(); } else { ENVOY_CONN_LOG(debug, "creating stream", *client.codec_client_); - StreamEncoder& new_encoder = client.newStreamEncoder(response_decoder); + RequestEncoder& new_encoder = client.newStreamEncoder(response_decoder); client.remaining_requests_--; if (client.remaining_requests_ == 0) { @@ -110,7 +111,7 @@ void ConnPoolImplBase::onRequestClosed(ActiveClient& client, bool delay_attachin } } -ConnectionPool::Cancellable* ConnPoolImplBase::newStream(Http::StreamDecoder& response_decoder, +ConnectionPool::Cancellable* ConnPoolImplBase::newStream(ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks) { if (!ready_clients_.empty()) { ActiveClient& client = *ready_clients_.front(); @@ -317,7 +318,7 @@ void ConnPoolImplBase::onConnectionEvent(ConnPoolImplBase::ActiveClient& client, } } -ConnPoolImplBase::PendingRequest::PendingRequest(ConnPoolImplBase& parent, StreamDecoder& decoder, +ConnPoolImplBase::PendingRequest::PendingRequest(ConnPoolImplBase& parent, ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) : parent_(parent), decoder_(decoder), callbacks_(callbacks) { parent_.host_->cluster().stats().upstream_rq_pending_total_.inc(); @@ -331,7 +332,8 @@ ConnPoolImplBase::PendingRequest::~PendingRequest() { } ConnectionPool::Cancellable* -ConnPoolImplBase::newPendingRequest(StreamDecoder& decoder, ConnectionPool::Callbacks& callbacks) { +ConnPoolImplBase::newPendingRequest(ResponseDecoder& decoder, + ConnectionPool::Callbacks& callbacks) { ENVOY_LOG(debug, "queueing request due to no available connections"); PendingRequestPtr pending_request(new PendingRequest(*this, decoder, callbacks)); pending_request->moveIntoList(std::move(pending_request), pending_requests_); diff --git a/source/common/http/conn_pool_base.h b/source/common/http/conn_pool_base.h index 3d2fea253e..a0e0671e65 100644 --- a/source/common/http/conn_pool_base.h +++ b/source/common/http/conn_pool_base.h @@ -18,7 +18,7 @@ class ConnPoolImplBase : public ConnectionPool::Instance, protected Logger::Loggable { public: // ConnectionPool::Instance - ConnectionPool::Cancellable* newStream(StreamDecoder& response_decoder, + ConnectionPool::Cancellable* newStream(ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks) override; void addDrainedCallback(DrainedCb cb) override; bool hasActiveConnections() const override; @@ -68,7 +68,7 @@ class ConnPoolImplBase : public ConnectionPool::Instance, virtual bool hasActiveRequests() const PURE; virtual bool closingWithIncompleteRequest() const PURE; - virtual StreamEncoder& newStreamEncoder(StreamDecoder& response_decoder) PURE; + virtual RequestEncoder& newStreamEncoder(ResponseDecoder& response_decoder) PURE; enum class State { CONNECTING, // Connection is not yet established. @@ -94,7 +94,7 @@ class ConnPoolImplBase : public ConnectionPool::Instance, using ActiveClientPtr = std::unique_ptr; struct PendingRequest : LinkedObject, public ConnectionPool::Cancellable { - PendingRequest(ConnPoolImplBase& parent, StreamDecoder& decoder, + PendingRequest(ConnPoolImplBase& parent, ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks); ~PendingRequest() override; @@ -102,7 +102,7 @@ class ConnPoolImplBase : public ConnectionPool::Instance, void cancel() override { parent_.onPendingRequestCancel(*this); } ConnPoolImplBase& parent_; - StreamDecoder& decoder_; + ResponseDecoder& decoder_; ConnectionPool::Callbacks& callbacks_; }; @@ -118,7 +118,7 @@ class ConnPoolImplBase : public ConnectionPool::Instance, std::list& owningList(ActiveClient::State state); // Creates a new PendingRequest and enqueues it into the request queue. - ConnectionPool::Cancellable* newPendingRequest(StreamDecoder& decoder, + ConnectionPool::Cancellable* newPendingRequest(ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks); // Removes the PendingRequest from the list of requests. Called when the PendingRequest is // cancelled, e.g. when the stream is reset before a connection has been established. @@ -140,7 +140,7 @@ class ConnPoolImplBase : public ConnectionPool::Instance, void onConnectionEvent(ActiveClient& client, Network::ConnectionEvent event); void checkForDrained(); void onUpstreamReady(); - void attachRequestToClient(ActiveClient& client, StreamDecoder& response_decoder, + void attachRequestToClient(ActiveClient& client, ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks); // Creates a new connection if allowed by resourceManager, or if created to avoid diff --git a/source/common/http/conn_pool_base_legacy.cc b/source/common/http/conn_pool_base_legacy.cc index f41e6ea67b..9476a846a3 100644 --- a/source/common/http/conn_pool_base_legacy.cc +++ b/source/common/http/conn_pool_base_legacy.cc @@ -38,7 +38,7 @@ ConnPoolImplBase::ActiveClient::ConnectionState ConnPoolImplBase::ActiveClient:: return Connected; } -ConnPoolImplBase::PendingRequest::PendingRequest(ConnPoolImplBase& parent, StreamDecoder& decoder, +ConnPoolImplBase::PendingRequest::PendingRequest(ConnPoolImplBase& parent, ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) : parent_(parent), decoder_(decoder), callbacks_(callbacks) { parent_.host_->cluster().stats().upstream_rq_pending_total_.inc(); @@ -52,7 +52,8 @@ ConnPoolImplBase::PendingRequest::~PendingRequest() { } ConnectionPool::Cancellable* -ConnPoolImplBase::newPendingRequest(StreamDecoder& decoder, ConnectionPool::Callbacks& callbacks) { +ConnPoolImplBase::newPendingRequest(ResponseDecoder& decoder, + ConnectionPool::Callbacks& callbacks) { ENVOY_LOG(debug, "queueing request due to no available connections"); PendingRequestPtr pending_request(new PendingRequest(*this, decoder, callbacks)); pending_request->moveIntoList(std::move(pending_request), pending_requests_); diff --git a/source/common/http/conn_pool_base_legacy.h b/source/common/http/conn_pool_base_legacy.h index 5a2cba3470..edcd252915 100644 --- a/source/common/http/conn_pool_base_legacy.h +++ b/source/common/http/conn_pool_base_legacy.h @@ -40,7 +40,7 @@ class ConnPoolImplBase : protected Logger::Loggable { }; struct PendingRequest : LinkedObject, public ConnectionPool::Cancellable { - PendingRequest(ConnPoolImplBase& parent, StreamDecoder& decoder, + PendingRequest(ConnPoolImplBase& parent, ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks); ~PendingRequest() override; @@ -48,14 +48,14 @@ class ConnPoolImplBase : protected Logger::Loggable { void cancel() override { parent_.onPendingRequestCancel(*this); } ConnPoolImplBase& parent_; - StreamDecoder& decoder_; + ResponseDecoder& decoder_; ConnectionPool::Callbacks& callbacks_; }; using PendingRequestPtr = std::unique_ptr; // Creates a new PendingRequest and enqueues it into the request queue. - ConnectionPool::Cancellable* newPendingRequest(StreamDecoder& decoder, + ConnectionPool::Cancellable* newPendingRequest(ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks); // Removes the PendingRequest from the list of requests. Called when the PendingRequest is // cancelled, e.g. when the stream is reset before a connection has been established. diff --git a/source/common/http/http1/codec_impl.cc b/source/common/http/http1/codec_impl.cc index 2e11ec6f33..8cb2190267 100644 --- a/source/common/http/http1/codec_impl.cc +++ b/source/common/http/http1/codec_impl.cc @@ -63,9 +63,9 @@ const std::string StreamEncoderImpl::LAST_CHUNK = "0\r\n"; StreamEncoderImpl::StreamEncoderImpl(ConnectionImpl& connection, HeaderKeyFormatter* header_key_formatter) - : connection_(connection), header_key_formatter_(header_key_formatter), chunk_encoding_(true), - processing_100_continue_(false), is_response_to_head_request_(false), - is_content_length_allowed_(true) { + : connection_(connection), chunk_encoding_(true), processing_100_continue_(false), + is_response_to_head_request_(false), is_content_length_allowed_(true), + header_key_formatter_(header_key_formatter) { if (connection_.connection().aboveHighWatermark()) { runHighWatermarkCallbacks(); } @@ -94,14 +94,14 @@ void StreamEncoderImpl::encodeFormattedHeader(absl::string_view key, absl::strin } } -void StreamEncoderImpl::encode100ContinueHeaders(const HeaderMap& headers) { +void ResponseEncoderImpl::encode100ContinueHeaders(const HeaderMap& headers) { ASSERT(headers.Status()->value() == "100"); processing_100_continue_ = true; encodeHeaders(headers, false); processing_100_continue_ = false; } -void StreamEncoderImpl::encodeHeaders(const HeaderMap& headers, bool end_stream) { +void StreamEncoderImpl::encodeHeadersBase(const HeaderMap& headers, bool end_stream) { bool saw_content_length = false; headers.iterate( [](const HeaderEntry& header, void* context) -> HeaderMap::Iterate { @@ -204,7 +204,7 @@ void StreamEncoderImpl::encodeData(Buffer::Instance& data, bool end_stream) { } } -void StreamEncoderImpl::encodeTrailers(const HeaderMap& trailers) { +void StreamEncoderImpl::encodeTrailersBase(const HeaderMap& trailers) { if (!connection_.enableTrailers()) { return endEncode(); } @@ -274,8 +274,11 @@ const Network::Address::InstanceConstSharedPtr& StreamEncoderImpl::connectionLoc static const char RESPONSE_PREFIX[] = "HTTP/1.1 "; static const char HTTP_10_RESPONSE_PREFIX[] = "HTTP/1.0 "; -void ResponseStreamEncoderImpl::encodeHeaders(const HeaderMap& headers, bool end_stream) { +void ResponseEncoderImpl::encodeHeaders(const HeaderMap& headers, bool end_stream) { started_response_ = true; + + // The contract is that client codecs must ensure that :status is present. + ASSERT(headers.Status() != nullptr); uint64_t numeric_status = Utility::getResponseStatus(headers); if (connection_.protocol() == Protocol::Http10 && connection_.supports_http_10()) { @@ -302,12 +305,12 @@ void ResponseStreamEncoderImpl::encodeHeaders(const HeaderMap& headers, bool end setIsContentLengthAllowed(true); } - StreamEncoderImpl::encodeHeaders(headers, end_stream); + encodeHeadersBase(headers, end_stream); } static const char REQUEST_POSTFIX[] = " HTTP/1.1\r\n"; -void RequestStreamEncoderImpl::encodeHeaders(const HeaderMap& headers, bool end_stream) { +void RequestEncoderImpl::encodeHeaders(const HeaderMap& headers, bool end_stream) { const HeaderEntry* method = headers.Method(); const HeaderEntry* path = headers.Path(); if (!method || !path) { @@ -322,7 +325,7 @@ void RequestStreamEncoderImpl::encodeHeaders(const HeaderMap& headers, bool end_ connection_.copyToBuffer(path->value().getStringView().data(), path->value().size()); connection_.copyToBuffer(REQUEST_POSTFIX, sizeof(REQUEST_POSTFIX) - 1); - StreamEncoderImpl::encodeHeaders(headers, end_stream); + encodeHeadersBase(headers, end_stream); } http_parser_settings ConnectionImpl::settings_{ @@ -843,7 +846,7 @@ bool ClientConnectionImpl::cannotHaveBody() { } } -StreamEncoder& ClientConnectionImpl::newStream(StreamDecoder& response_decoder) { +RequestEncoder& ClientConnectionImpl::newStream(ResponseDecoder& response_decoder) { if (resetStreamCalled()) { throw CodecClientException("cannot create new streams after calling reset"); } @@ -852,7 +855,7 @@ StreamEncoder& ClientConnectionImpl::newStream(StreamDecoder& response_decoder) // reusing this connection. This is done when the final pipeline response is received. ASSERT(connection_.readEnabled()); - request_encoder_ = std::make_unique(*this, header_key_formatter_.get()); + request_encoder_ = std::make_unique(*this, header_key_formatter_.get()); pending_responses_.emplace_back(&response_decoder); return *request_encoder_; } diff --git a/source/common/http/http1/codec_impl.h b/source/common/http/http1/codec_impl.h index 497e64c65b..4dc1744b9e 100644 --- a/source/common/http/http1/codec_impl.h +++ b/source/common/http/http1/codec_impl.h @@ -41,16 +41,13 @@ class ConnectionImpl; /** * Base class for HTTP/1.1 request and response encoders. */ -class StreamEncoderImpl : public StreamEncoder, +class StreamEncoderImpl : public virtual StreamEncoder, public Stream, Logger::Loggable, public StreamCallbackHelper { public: // Http::StreamEncoder - void encode100ContinueHeaders(const HeaderMap& headers) override; - void encodeHeaders(const HeaderMap& headers, bool end_stream) override; void encodeData(Buffer::Instance& data, bool end_stream) override; - void encodeTrailers(const HeaderMap& trailers) override; void encodeMetadata(const MetadataMapVector&) override; Stream& getStream() override { return *this; } @@ -68,12 +65,18 @@ class StreamEncoderImpl : public StreamEncoder, protected: StreamEncoderImpl(ConnectionImpl& connection, HeaderKeyFormatter* header_key_formatter); + void setIsContentLengthAllowed(bool value) { is_content_length_allowed_ = value; } + void encodeHeadersBase(const HeaderMap& headers, bool end_stream); + void encodeTrailersBase(const HeaderMap& headers); static const std::string CRLF; static const std::string LAST_CHUNK; ConnectionImpl& connection_; - void setIsContentLengthAllowed(bool value) { is_content_length_allowed_ = value; } + bool chunk_encoding_ : 1; + bool processing_100_continue_ : 1; + bool is_response_to_head_request_ : 1; + bool is_content_length_allowed_ : 1; private: /** @@ -100,25 +103,23 @@ class StreamEncoderImpl : public StreamEncoder, void encodeFormattedHeader(absl::string_view key, absl::string_view value); const HeaderKeyFormatter* const header_key_formatter_; - bool chunk_encoding_ : 1; - bool processing_100_continue_ : 1; - bool is_response_to_head_request_ : 1; - bool is_content_length_allowed_ : 1; absl::string_view details_; }; /** * HTTP/1.1 response encoder. */ -class ResponseStreamEncoderImpl : public StreamEncoderImpl { +class ResponseEncoderImpl : public StreamEncoderImpl, public ResponseEncoder { public: - ResponseStreamEncoderImpl(ConnectionImpl& connection, HeaderKeyFormatter* header_key_formatter) + ResponseEncoderImpl(ConnectionImpl& connection, HeaderKeyFormatter* header_key_formatter) : StreamEncoderImpl(connection, header_key_formatter) {} bool startedResponse() { return started_response_; } - // Http::StreamEncoder + // Http::ResponseEncoder + void encode100ContinueHeaders(const HeaderMap& headers) override; void encodeHeaders(const HeaderMap& headers, bool end_stream) override; + void encodeTrailers(const HeaderMap& trailers) override { encodeTrailersBase(trailers); } private: bool started_response_{}; @@ -127,14 +128,15 @@ class ResponseStreamEncoderImpl : public StreamEncoderImpl { /** * HTTP/1.1 request encoder. */ -class RequestStreamEncoderImpl : public StreamEncoderImpl { +class RequestEncoderImpl : public StreamEncoderImpl, public RequestEncoder { public: - RequestStreamEncoderImpl(ConnectionImpl& connection, HeaderKeyFormatter* header_key_formatter) + RequestEncoderImpl(ConnectionImpl& connection, HeaderKeyFormatter* header_key_formatter) : StreamEncoderImpl(connection, header_key_formatter) {} bool headRequest() { return head_request_; } - // Http::StreamEncoder + // Http::RequestEncoder void encodeHeaders(const HeaderMap& headers, bool end_stream) override; + void encodeTrailers(const HeaderMap& trailers) override { encodeTrailersBase(trailers); } private: bool head_request_{}; @@ -341,8 +343,8 @@ class ServerConnectionImpl : public ServerConnection, public ConnectionImpl { : response_encoder_(connection, header_key_formatter) {} HeaderString request_url_; - StreamDecoder* request_decoder_{}; - ResponseStreamEncoderImpl response_encoder_; + RequestDecoder* request_decoder_{}; + ResponseEncoderImpl response_encoder_; bool remote_complete_{}; }; @@ -384,13 +386,13 @@ class ClientConnectionImpl : public ClientConnection, public ConnectionImpl { const uint32_t max_response_headers_count); // Http::ClientConnection - StreamEncoder& newStream(StreamDecoder& response_decoder) override; + RequestEncoder& newStream(ResponseDecoder& response_decoder) override; private: struct PendingResponse { - PendingResponse(StreamDecoder* decoder) : decoder_(decoder) {} + PendingResponse(ResponseDecoder* decoder) : decoder_(decoder) {} - StreamDecoder* decoder_; + ResponseDecoder* decoder_; bool head_request_{}; }; @@ -409,7 +411,7 @@ class ClientConnectionImpl : public ClientConnection, public ConnectionImpl { void onAboveHighWatermark() override; void onBelowLowWatermark() override; - std::unique_ptr request_encoder_; + std::unique_ptr request_encoder_; std::list pending_responses_; // Set true between receiving 100-Continue headers and receiving the spurious onMessageComplete. bool ignore_message_complete_for_100_continue_{}; diff --git a/source/common/http/http1/conn_pool.cc b/source/common/http/http1/conn_pool.cc index ec2dd55870..89499113d7 100644 --- a/source/common/http/http1/conn_pool.cc +++ b/source/common/http/http1/conn_pool.cc @@ -65,11 +65,11 @@ void ConnPoolImpl::onResponseComplete(ActiveClient& client) { } } -ConnPoolImpl::StreamWrapper::StreamWrapper(StreamDecoder& response_decoder, ActiveClient& parent) - : StreamEncoderWrapper(parent.codec_client_->newStream(*this)), - StreamDecoderWrapper(response_decoder), parent_(parent) { +ConnPoolImpl::StreamWrapper::StreamWrapper(ResponseDecoder& response_decoder, ActiveClient& parent) + : RequestEncoderWrapper(parent.codec_client_->newStream(*this)), + ResponseDecoderWrapper(response_decoder), parent_(parent) { - StreamEncoderWrapper::inner_.getStream().addCallbacks(*this); + RequestEncoderWrapper::inner_.getStream().addCallbacks(*this); } ConnPoolImpl::StreamWrapper::~StreamWrapper() { @@ -99,7 +99,7 @@ void ConnPoolImpl::StreamWrapper::decodeHeaders(HeaderMapPtr&& headers, bool end close_connection_ = true; } - StreamDecoderWrapper::decodeHeaders(std::move(headers), end_stream); + ResponseDecoderWrapper::decodeHeaders(std::move(headers), end_stream); } void ConnPoolImpl::StreamWrapper::onDecodeComplete() { @@ -121,7 +121,7 @@ bool ConnPoolImpl::ActiveClient::closingWithIncompleteRequest() const { return (stream_wrapper_ != nullptr) && (!stream_wrapper_->decode_complete_); } -StreamEncoder& ConnPoolImpl::ActiveClient::newStreamEncoder(StreamDecoder& response_decoder) { +RequestEncoder& ConnPoolImpl::ActiveClient::newStreamEncoder(ResponseDecoder& response_decoder) { ASSERT(!stream_wrapper_); stream_wrapper_ = std::make_unique(response_decoder, *this); return *stream_wrapper_; diff --git a/source/common/http/http1/conn_pool.h b/source/common/http/http1/conn_pool.h index c9b013b126..4a7d7c8b70 100644 --- a/source/common/http/http1/conn_pool.h +++ b/source/common/http/http1/conn_pool.h @@ -35,10 +35,10 @@ class ConnPoolImpl : public ConnPoolImplBase { protected: struct ActiveClient; - struct StreamWrapper : public StreamEncoderWrapper, - public StreamDecoderWrapper, + struct StreamWrapper : public RequestEncoderWrapper, + public ResponseDecoderWrapper, public StreamCallbacks { - StreamWrapper(StreamDecoder& response_decoder, ActiveClient& parent); + StreamWrapper(ResponseDecoder& response_decoder, ActiveClient& parent); ~StreamWrapper() override; // StreamEncoderWrapper @@ -72,7 +72,7 @@ class ConnPoolImpl : public ConnPoolImplBase { // ConnPoolImplBase::ActiveClient bool hasActiveRequests() const override; bool closingWithIncompleteRequest() const override; - StreamEncoder& newStreamEncoder(StreamDecoder& response_decoder) override; + RequestEncoder& newStreamEncoder(ResponseDecoder& response_decoder) override; StreamWrapperPtr stream_wrapper_; }; diff --git a/source/common/http/http1/conn_pool_legacy.cc b/source/common/http/http1/conn_pool_legacy.cc index 6f85335298..9f761c768a 100644 --- a/source/common/http/http1/conn_pool_legacy.cc +++ b/source/common/http/http1/conn_pool_legacy.cc @@ -68,7 +68,7 @@ bool ConnPoolImpl::hasActiveConnections() const { return !pending_requests_.empty() || !busy_clients_.empty(); } -void ConnPoolImpl::attachRequestToClient(ActiveClient& client, StreamDecoder& response_decoder, +void ConnPoolImpl::attachRequestToClient(ActiveClient& client, ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks) { ASSERT(!client.stream_wrapper_); host_->cluster().stats().upstream_rq_total_.inc(); @@ -96,7 +96,7 @@ void ConnPoolImpl::createNewConnection() { client->moveIntoList(std::move(client), busy_clients_); } -ConnectionPool::Cancellable* ConnPoolImpl::newStream(StreamDecoder& response_decoder, +ConnectionPool::Cancellable* ConnPoolImpl::newStream(ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks) { if (!ready_clients_.empty()) { ready_clients_.front()->moveBetweenLists(ready_clients_, busy_clients_); @@ -254,11 +254,11 @@ void ConnPoolImpl::processIdleClient(ActiveClient& client, bool delay) { checkForDrained(); } -ConnPoolImpl::StreamWrapper::StreamWrapper(StreamDecoder& response_decoder, ActiveClient& parent) - : StreamEncoderWrapper(parent.codec_client_->newStream(*this)), - StreamDecoderWrapper(response_decoder), parent_(parent) { +ConnPoolImpl::StreamWrapper::StreamWrapper(ResponseDecoder& response_decoder, ActiveClient& parent) + : RequestEncoderWrapper(parent.codec_client_->newStream(*this)), + ResponseDecoderWrapper(response_decoder), parent_(parent) { - StreamEncoderWrapper::inner_.getStream().addCallbacks(*this); + RequestEncoderWrapper::inner_.getStream().addCallbacks(*this); parent_.parent_.host_->cluster().stats().upstream_rq_active_.inc(); parent_.parent_.host_->stats().rq_active_.inc(); @@ -297,7 +297,7 @@ void ConnPoolImpl::StreamWrapper::decodeHeaders(HeaderMapPtr&& headers, bool end close_connection_ = true; } - StreamDecoderWrapper::decodeHeaders(std::move(headers), end_stream); + ResponseDecoderWrapper::decodeHeaders(std::move(headers), end_stream); } void ConnPoolImpl::StreamWrapper::onDecodeComplete() { diff --git a/source/common/http/http1/conn_pool_legacy.h b/source/common/http/http1/conn_pool_legacy.h index e2f9aa0309..75065bace4 100644 --- a/source/common/http/http1/conn_pool_legacy.h +++ b/source/common/http/http1/conn_pool_legacy.h @@ -44,7 +44,7 @@ class ConnPoolImpl : public ConnectionPool::Instance, public Legacy::ConnPoolImp void addDrainedCallback(DrainedCb cb) override; void drainConnections() override; bool hasActiveConnections() const override; - ConnectionPool::Cancellable* newStream(StreamDecoder& response_decoder, + ConnectionPool::Cancellable* newStream(ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks) override; Upstream::HostDescriptionConstSharedPtr host() const override { return host_; }; @@ -54,10 +54,10 @@ class ConnPoolImpl : public ConnectionPool::Instance, public Legacy::ConnPoolImp protected: struct ActiveClient; - struct StreamWrapper : public StreamEncoderWrapper, - public StreamDecoderWrapper, + struct StreamWrapper : public RequestEncoderWrapper, + public ResponseDecoderWrapper, public StreamCallbacks { - StreamWrapper(StreamDecoder& response_decoder, ActiveClient& parent); + StreamWrapper(ResponseDecoder& response_decoder, ActiveClient& parent); ~StreamWrapper() override; // StreamEncoderWrapper @@ -108,7 +108,7 @@ class ConnPoolImpl : public ConnectionPool::Instance, public Legacy::ConnPoolImp using ActiveClientPtr = std::unique_ptr; - void attachRequestToClient(ActiveClient& client, StreamDecoder& response_decoder, + void attachRequestToClient(ActiveClient& client, ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks); virtual CodecClientPtr createCodecClient(Upstream::Host::CreateConnectionData& data) PURE; void createNewConnection(); diff --git a/source/common/http/http2/codec_impl.cc b/source/common/http/http2/codec_impl.cc index e2fb633376..1542bda34b 100644 --- a/source/common/http/http2/codec_impl.cc +++ b/source/common/http/http2/codec_impl.cc @@ -88,12 +88,12 @@ void ConnectionImpl::StreamImpl::buildHeaders(std::vector& final_hea &final_headers); } -void ConnectionImpl::StreamImpl::encode100ContinueHeaders(const HeaderMap& headers) { +void ConnectionImpl::ServerStreamImpl::encode100ContinueHeaders(const HeaderMap& headers) { ASSERT(headers.Status()->value() == "100"); encodeHeaders(headers, false); } -void ConnectionImpl::StreamImpl::encodeHeaders(const HeaderMap& headers, bool end_stream) { +void ConnectionImpl::StreamImpl::encodeHeadersBase(const HeaderMap& headers, bool end_stream) { std::vector final_headers; // This must exist outside of the scope of isUpgrade as the underlying memory is @@ -122,7 +122,7 @@ void ConnectionImpl::StreamImpl::encodeHeaders(const HeaderMap& headers, bool en parent_.sendPendingFrames(); } -void ConnectionImpl::StreamImpl::encodeTrailers(const HeaderMap& trailers) { +void ConnectionImpl::StreamImpl::encodeTrailersBase(const HeaderMap& trailers) { ASSERT(!local_end_stream_); local_end_stream_ = true; if (pending_send_data_.length() > 0) { @@ -185,9 +185,32 @@ void ConnectionImpl::StreamImpl::pendingRecvBufferLowWatermark() { readDisable(false); } -void ConnectionImpl::StreamImpl::decodeHeaders() { - maybeTransformUpgradeFromH2ToH1(); - decoder_->decodeHeaders(std::move(headers_), remote_end_stream_); +void ConnectionImpl::ClientStreamImpl::decodeHeaders() { + if (!upgrade_type_.empty() && headers_->Status()) { + Http::Utility::transformUpgradeResponseFromH2toH1(*headers_, upgrade_type_); + } + + if (headers_->Status()->value() == "100") { + ASSERT(!remote_end_stream_); + response_decoder_.decode100ContinueHeaders(std::move(headers_)); + } else { + response_decoder_.decodeHeaders(std::move(headers_), remote_end_stream_); + } +} + +void ConnectionImpl::ClientStreamImpl::decodeTrailers() { + response_decoder_.decodeTrailers(std::move(headers_)); +} + +void ConnectionImpl::ServerStreamImpl::decodeHeaders() { + if (Http::Utility::isH2UpgradeRequest(*headers_)) { + Http::Utility::transformUpgradeRequestFromH2toH1(*headers_); + } + request_decoder_->decodeHeaders(std::move(headers_), remote_end_stream_); +} + +void ConnectionImpl::ServerStreamImpl::decodeTrailers() { + request_decoder_->decodeTrailers(std::move(headers_)); } void ConnectionImpl::StreamImpl::pendingSendBufferHighWatermark() { @@ -344,7 +367,7 @@ MetadataDecoder& ConnectionImpl::StreamImpl::getMetadataDecoder() { } void ConnectionImpl::StreamImpl::onMetadataDecoded(MetadataMapPtr&& metadata_map_ptr) { - decoder_->decodeMetadata(std::move(metadata_map_ptr)); + decoder().decodeMetadata(std::move(metadata_map_ptr)); } ConnectionImpl::ConnectionImpl(Network::Connection& connection, Stats::Scope& stats, @@ -492,14 +515,7 @@ int ConnectionImpl::onFrameReceived(const nghttp2_frame* frame) { if (CodeUtility::is1xx(Http::Utility::getResponseStatus(*stream->headers_))) { stream->waiting_for_non_informational_headers_ = true; } - - if (stream->headers_->Status()->value() == "100") { - ASSERT(!stream->remote_end_stream_); - stream->decoder_->decode100ContinueHeaders(std::move(stream->headers_)); - } else { - stream->decodeHeaders(); - } - break; + FALLTHRU; } case NGHTTP2_HCAT_REQUEST: { @@ -522,7 +538,7 @@ int ConnectionImpl::onFrameReceived(const nghttp2_frame* frame) { stats_.too_many_header_frames_.inc(); throw CodecProtocolException("Unexpected 'trailers' with no end stream."); } else { - stream->decoder_->decodeTrailers(std::move(stream->headers_)); + stream->decodeTrailers(); } } else { ASSERT(!nghttp2_session_check_server_session(session_)); @@ -552,7 +568,7 @@ int ConnectionImpl::onFrameReceived(const nghttp2_frame* frame) { // It's possible that we are waiting to send a deferred reset, so only raise data if local // is not complete. if (!stream->deferred_reset_) { - stream->decoder_->decodeData(stream->pending_recv_data_, stream->remote_end_stream_); + stream->decoder().decodeData(stream->pending_recv_data_, stream->remote_end_stream_); } stream->pending_recv_data_.drain(stream->pending_recv_data_.length()); @@ -1062,17 +1078,17 @@ ClientConnectionImpl::ClientConnectionImpl(Network::Connection& connection, allow_metadata_ = http2_settings.allow_metadata_; } -Http::StreamEncoder& ClientConnectionImpl::newStream(StreamDecoder& decoder) { - StreamImplPtr stream(new ClientStreamImpl(*this, per_stream_buffer_limit_)); - stream->decoder_ = &decoder; +RequestEncoder& ClientConnectionImpl::newStream(ResponseDecoder& decoder) { + ClientStreamImplPtr stream(new ClientStreamImpl(*this, per_stream_buffer_limit_, decoder)); // If the connection is currently above the high watermark, make sure to inform the new stream. // The connection can not pass this on automatically as it has no awareness that a new stream is // created. if (connection_.aboveHighWatermark()) { stream->runHighWatermarkCallbacks(); } + ClientStreamImpl& stream_ref = *stream; stream->moveIntoList(std::move(stream), active_streams_); - return *active_streams_.front(); + return stream_ref; } int ClientConnectionImpl::onBeginHeaders(const nghttp2_frame* frame) { @@ -1131,11 +1147,11 @@ int ServerConnectionImpl::onBeginHeaders(const nghttp2_frame* frame) { return 0; } - StreamImplPtr stream(new ServerStreamImpl(*this, per_stream_buffer_limit_)); + ServerStreamImplPtr stream(new ServerStreamImpl(*this, per_stream_buffer_limit_)); if (connection_.aboveHighWatermark()) { stream->runHighWatermarkCallbacks(); } - stream->decoder_ = &callbacks_.newStream(*stream); + stream->request_decoder_ = &callbacks_.newStream(*stream); stream->stream_id_ = frame->hd.stream_id; stream->moveIntoList(std::move(stream), active_streams_); nghttp2_session_set_stream_user_data(session_, frame->hd.stream_id, diff --git a/source/common/http/http2/codec_impl.h b/source/common/http/http2/codec_impl.h index c5b8dc1ac8..e9390acd3d 100644 --- a/source/common/http/http2/codec_impl.h +++ b/source/common/http/http2/codec_impl.h @@ -140,7 +140,7 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable, public Event::DeferredDeletable, @@ -154,16 +154,16 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable& final_headers, const HeaderMap& headers); void saveHeader(HeaderString&& name, HeaderString&& value); + void encodeHeadersBase(const HeaderMap& headers, bool end_stream); virtual void submitHeaders(const std::vector& final_headers, nghttp2_data_provider* provider) PURE; + void encodeTrailersBase(const HeaderMap& headers); void submitTrailers(const HeaderMap& trailers); void submitMetadata(); + virtual StreamDecoder& decoder() PURE; // Http::StreamEncoder - void encode100ContinueHeaders(const HeaderMap& headers) override; - void encodeHeaders(const HeaderMap& headers, bool end_stream) override; void encodeData(Buffer::Instance& data, bool end_stream) override; - void encodeTrailers(const HeaderMap& trailers) override; Stream& getStream() override { return *this; } void encodeMetadata(const MetadataMapVector& metadata_map_vector) override; @@ -193,7 +193,8 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable 0; } ConnectionImpl& parent_; HeaderMapImplPtr headers_; - StreamDecoder* decoder_{}; int32_t stream_id_{-1}; uint32_t unconsumed_bytes_{0}; uint32_t read_disable_count_{0}; @@ -238,8 +237,10 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable& final_headers, @@ -248,38 +249,52 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggablevalue().getStringView()); Http::Utility::transformUpgradeRequestFromH1toH2(headers); } - void maybeTransformUpgradeFromH2ToH1() override { - if (!upgrade_type_.empty() && headers_->Status()) { - Http::Utility::transformUpgradeResponseFromH2toH1(*headers_, upgrade_type_); - } + StreamDecoder& decoder() override { return response_decoder_; } + void decodeHeaders() override; + void decodeTrailers() override; + + // RequestEncoder + void encodeHeaders(const HeaderMap& headers, bool end_stream) override { + encodeHeadersBase(headers, end_stream); } + void encodeTrailers(const HeaderMap& trailers) override { encodeTrailersBase(trailers); } + + ResponseDecoder& response_decoder_; std::string upgrade_type_; }; + using ClientStreamImplPtr = std::unique_ptr; + /** * Server side stream (response). */ - struct ServerStreamImpl : public StreamImpl { + struct ServerStreamImpl : public StreamImpl, public ResponseEncoder { using StreamImpl::StreamImpl; // StreamImpl - void encodeHeaders(const HeaderMap& headers, bool end_stream) override { - // The contract is that client codecs must ensure that :status is present. - ASSERT(headers.Status() != nullptr); - StreamImpl::encodeHeaders(headers, end_stream); - } void submitHeaders(const std::vector& final_headers, nghttp2_data_provider* provider) override; void transformUpgradeFromH1toH2(HeaderMap& headers) override { Http::Utility::transformUpgradeResponseFromH1toH2(headers); } - void maybeTransformUpgradeFromH2ToH1() override { - if (Http::Utility::isH2UpgradeRequest(*headers_)) { - Http::Utility::transformUpgradeRequestFromH2toH1(*headers_); - } + StreamDecoder& decoder() override { return *request_decoder_; } + void decodeHeaders() override; + void decodeTrailers() override; + + // ResponseEncoder + void encode100ContinueHeaders(const HeaderMap& headers) override; + void encodeHeaders(const HeaderMap& headers, bool end_stream) override { + // The contract is that client codecs must ensure that :status is present. + ASSERT(headers.Status() != nullptr); + encodeHeadersBase(headers, end_stream); } + void encodeTrailers(const HeaderMap& trailers) override { encodeTrailersBase(trailers); } + + RequestDecoder* request_decoder_{}; }; + using ServerStreamImplPtr = std::unique_ptr; + ConnectionImpl* base() { return this; } StreamImpl* getStream(int32_t stream_id); int saveHeader(const nghttp2_frame* frame, HeaderString&& name, HeaderString&& value); @@ -403,7 +418,7 @@ class ClientConnectionImpl : public ClientConnection, public ConnectionImpl { const uint32_t max_response_headers_count); // Http::ClientConnection - Http::StreamEncoder& newStream(StreamDecoder& response_decoder) override; + RequestEncoder& newStream(ResponseDecoder& response_decoder) override; private: // ConnectionImpl diff --git a/source/common/http/http2/conn_pool.cc b/source/common/http/http2/conn_pool.cc index 2fc988a8fe..090ac7d4d1 100644 --- a/source/common/http/http2/conn_pool.cc +++ b/source/common/http/http2/conn_pool.cc @@ -82,7 +82,7 @@ bool ConnPoolImpl::ActiveClient::closingWithIncompleteRequest() const { return closed_with_active_rq_; } -StreamEncoder& ConnPoolImpl::ActiveClient::newStreamEncoder(StreamDecoder& response_decoder) { +RequestEncoder& ConnPoolImpl::ActiveClient::newStreamEncoder(ResponseDecoder& response_decoder) { return codec_client_->newStream(response_decoder); } diff --git a/source/common/http/http2/conn_pool.h b/source/common/http/http2/conn_pool.h index 30685c9a37..481f4eb24a 100644 --- a/source/common/http/http2/conn_pool.h +++ b/source/common/http/http2/conn_pool.h @@ -43,7 +43,7 @@ class ConnPoolImpl : public ConnPoolImplBase { // ConnPoolImpl::ActiveClient bool hasActiveRequests() const override; bool closingWithIncompleteRequest() const override; - StreamEncoder& newStreamEncoder(StreamDecoder& response_decoder) override; + RequestEncoder& newStreamEncoder(ResponseDecoder& response_decoder) override; // CodecClientCallbacks void onStreamDestroy() override { parent().onStreamDestroy(*this); } diff --git a/source/common/http/http2/conn_pool_legacy.cc b/source/common/http/http2/conn_pool_legacy.cc index 9e4c271fd6..c949459d54 100644 --- a/source/common/http/http2/conn_pool_legacy.cc +++ b/source/common/http/http2/conn_pool_legacy.cc @@ -87,7 +87,7 @@ void ConnPoolImpl::checkForDrained() { } } -void ConnPoolImpl::newClientStream(Http::StreamDecoder& response_decoder, +void ConnPoolImpl::newClientStream(ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks) { if (!host_->cluster().resourceManager(priority_).requests().canCreate()) { ENVOY_LOG(debug, "max requests overflow"); @@ -108,7 +108,7 @@ void ConnPoolImpl::newClientStream(Http::StreamDecoder& response_decoder, } } -ConnectionPool::Cancellable* ConnPoolImpl::newStream(Http::StreamDecoder& response_decoder, +ConnectionPool::Cancellable* ConnPoolImpl::newStream(ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks) { ASSERT(drained_callbacks_.empty()); diff --git a/source/common/http/http2/conn_pool_legacy.h b/source/common/http/http2/conn_pool_legacy.h index 6fef4d989d..0ffb2e520a 100644 --- a/source/common/http/http2/conn_pool_legacy.h +++ b/source/common/http/http2/conn_pool_legacy.h @@ -36,7 +36,7 @@ class ConnPoolImpl : public ConnectionPool::Instance, public Legacy::ConnPoolImp void addDrainedCallback(DrainedCb cb) override; void drainConnections() override; bool hasActiveConnections() const override; - ConnectionPool::Cancellable* newStream(Http::StreamDecoder& response_decoder, + ConnectionPool::Cancellable* newStream(ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks) override; Upstream::HostDescriptionConstSharedPtr host() const override { return host_; }; @@ -88,7 +88,7 @@ class ConnPoolImpl : public ConnectionPool::Instance, public Legacy::ConnPoolImp void onGoAway(ActiveClient& client); void onStreamDestroy(ActiveClient& client); void onStreamReset(ActiveClient& client, Http::StreamResetReason reason); - void newClientStream(Http::StreamDecoder& response_decoder, ConnectionPool::Callbacks& callbacks); + void newClientStream(ResponseDecoder& response_decoder, ConnectionPool::Callbacks& callbacks); void onUpstreamReady(); Event::Dispatcher& dispatcher_; diff --git a/source/common/router/router.cc b/source/common/router/router.cc index 7823c3c2fc..5c54c8e290 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -1697,7 +1697,7 @@ void Filter::UpstreamRequest::onPoolFailure(Http::ConnectionPool::PoolFailureRea onResetStream(reset_reason, transport_failure_reason); } -void Filter::UpstreamRequest::onPoolReady(Http::StreamEncoder& request_encoder, +void Filter::UpstreamRequest::onPoolReady(Http::RequestEncoder& request_encoder, Upstream::HostDescriptionConstSharedPtr host, const StreamInfo::StreamInfo& info) { // This may be called under an existing ScopeTrackerScopeState but it will unwind correctly. @@ -1787,7 +1787,7 @@ ProdFilter::createRetryState(const RetryPolicy& policy, Http::HeaderMap& request priority); } -void Filter::UpstreamRequest::setRequestEncoder(Http::StreamEncoder& request_encoder) { +void Filter::UpstreamRequest::setRequestEncoder(Http::RequestEncoder& request_encoder) { request_encoder_ = &request_encoder; // Now that there is an encoder, have the connection manager inform the manager when the // downstream buffers are overrun. This may result in immediate watermark callbacks referencing diff --git a/source/common/router/router.h b/source/common/router/router.h index b21ec0b484..8674b6ac21 100644 --- a/source/common/router/router.h +++ b/source/common/router/router.h @@ -366,7 +366,7 @@ class Filter : Logger::Loggable, RetryStatePtr retry_state_; private: - struct UpstreamRequest : public Http::StreamDecoder, + struct UpstreamRequest : public Http::ResponseDecoder, public Http::StreamCallbacks, public Http::ConnectionPool::Callbacks, public LinkedObject { @@ -393,11 +393,13 @@ class Filter : Logger::Loggable, } // Http::StreamDecoder + void decodeData(Buffer::Instance& data, bool end_stream) override; + void decodeMetadata(Http::MetadataMapPtr&& metadata_map) override; + + // Http::ResponseDecoder void decode100ContinueHeaders(Http::HeaderMapPtr&& headers) override; void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; - void decodeData(Buffer::Instance& data, bool end_stream) override; void decodeTrailers(Http::HeaderMapPtr&& trailers) override; - void decodeMetadata(Http::MetadataMapPtr&& metadata_map) override; // Http::StreamCallbacks void onResetStream(Http::StreamResetReason reason, @@ -439,11 +441,11 @@ class Filter : Logger::Loggable, void onPoolFailure(Http::ConnectionPool::PoolFailureReason reason, absl::string_view transport_failure_reason, Upstream::HostDescriptionConstSharedPtr host) override; - void onPoolReady(Http::StreamEncoder& request_encoder, + void onPoolReady(Http::RequestEncoder& request_encoder, Upstream::HostDescriptionConstSharedPtr host, const StreamInfo::StreamInfo& info) override; - void setRequestEncoder(Http::StreamEncoder& request_encoder); + void setRequestEncoder(Http::RequestEncoder& request_encoder); void clearRequestEncoder(); struct DownstreamWatermarkManager : public Http::DownstreamWatermarkCallbacks { @@ -463,7 +465,7 @@ class Filter : Logger::Loggable, bool grpc_rq_success_deferred_; Event::TimerPtr per_try_timeout_; Http::ConnectionPool::Cancellable* conn_pool_stream_handle_{}; - Http::StreamEncoder* request_encoder_{}; + Http::RequestEncoder* request_encoder_{}; absl::optional deferred_reset_reason_; Buffer::WatermarkBufferPtr buffered_request_body_; Upstream::HostDescriptionConstSharedPtr upstream_host_; diff --git a/source/common/upstream/health_checker_impl.cc b/source/common/upstream/health_checker_impl.cc index e5c279cd99..74a5288867 100644 --- a/source/common/upstream/health_checker_impl.cc +++ b/source/common/upstream/health_checker_impl.cc @@ -228,7 +228,7 @@ void HttpHealthCheckerImpl::HttpActiveHealthCheckSession::onInterval() { expect_reset_ = false; } - Http::StreamEncoder* request_encoder = &client_->newStream(*this); + Http::RequestEncoder* request_encoder = &client_->newStream(*this); request_encoder->getStream().addCallbacks(*this); Http::HeaderMapImpl request_headers{ diff --git a/source/common/upstream/health_checker_impl.h b/source/common/upstream/health_checker_impl.h index 6f2b1ed229..4976f563b8 100644 --- a/source/common/upstream/health_checker_impl.h +++ b/source/common/upstream/health_checker_impl.h @@ -69,7 +69,7 @@ class HttpHealthCheckerImpl : public HealthCheckerImplBase { private: struct HttpActiveHealthCheckSession : public ActiveHealthCheckSession, - public Http::StreamDecoder, + public Http::ResponseDecoder, public Http::StreamCallbacks { HttpActiveHealthCheckSession(HttpHealthCheckerImpl& parent, const HostSharedPtr& host); ~HttpActiveHealthCheckSession() override; @@ -85,16 +85,18 @@ class HttpHealthCheckerImpl : public HealthCheckerImplBase { void onDeferredDelete() final; // Http::StreamDecoder - void decode100ContinueHeaders(Http::HeaderMapPtr&&) override {} - void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; void decodeData(Buffer::Instance&, bool end_stream) override { if (end_stream) { onResponseComplete(); } } - void decodeTrailers(Http::HeaderMapPtr&&) override { onResponseComplete(); } void decodeMetadata(Http::MetadataMapPtr&&) override {} + // Http::ResponseDecoder + void decode100ContinueHeaders(Http::HeaderMapPtr&&) override {} + void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; + void decodeTrailers(Http::HeaderMapPtr&&) override { onResponseComplete(); } + // Http::StreamCallbacks void onResetStream(Http::StreamResetReason reason, absl::string_view transport_failure_reason) override; @@ -288,7 +290,7 @@ class GrpcHealthCheckerImpl : public HealthCheckerImplBase { private: struct GrpcActiveHealthCheckSession : public ActiveHealthCheckSession, - public Http::StreamDecoder, + public Http::ResponseDecoder, public Http::StreamCallbacks { GrpcActiveHealthCheckSession(GrpcHealthCheckerImpl& parent, const HostSharedPtr& host); ~GrpcActiveHealthCheckSession() override; @@ -306,11 +308,13 @@ class GrpcHealthCheckerImpl : public HealthCheckerImplBase { void onDeferredDelete() final; // Http::StreamDecoder + void decodeData(Buffer::Instance&, bool end_stream) override; + void decodeMetadata(Http::MetadataMapPtr&&) override {} + + // Http::ResponseDecoder void decode100ContinueHeaders(Http::HeaderMapPtr&&) override {} void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; - void decodeData(Buffer::Instance&, bool end_stream) override; void decodeTrailers(Http::HeaderMapPtr&&) override; - void decodeMetadata(Http::MetadataMapPtr&&) override {} // Http::StreamCallbacks void onResetStream(Http::StreamResetReason reason, @@ -347,7 +351,7 @@ class GrpcHealthCheckerImpl : public HealthCheckerImplBase { HttpConnectionCallbackImpl http_connection_callback_impl_{*this}; GrpcHealthCheckerImpl& parent_; Http::CodecClientPtr client_; - Http::StreamEncoder* request_encoder_; + Http::RequestEncoder* request_encoder_; Grpc::Decoder decoder_; std::unique_ptr health_check_response_; // If true, stream reset was initiated by us (GrpcActiveHealthCheckSession), not by HTTP stack, diff --git a/source/extensions/quic_listeners/quiche/codec_impl.cc b/source/extensions/quic_listeners/quiche/codec_impl.cc index 49b7128aaa..fc031eb32d 100644 --- a/source/extensions/quic_listeners/quiche/codec_impl.cc +++ b/source/extensions/quic_listeners/quiche/codec_impl.cc @@ -12,6 +12,9 @@ namespace Quic { EnvoyQuicStream* quicStreamToEnvoyStream(quic::QuicStream* stream) { return dynamic_cast(stream); } +EnvoyQuicClientStream* quicStreamToEnvoyClientStream(quic::QuicStream* stream) { + return dynamic_cast(stream); +} bool QuicHttpConnectionImplBase::wantsToWrite() { return quic_session_.bytesToSend() > 0; } @@ -58,15 +61,15 @@ QuicHttpClientConnectionImpl::QuicHttpClientConnectionImpl(EnvoyQuicClientSessio session.setHttpConnectionCallbacks(callbacks); } -Http::StreamEncoder& -QuicHttpClientConnectionImpl::newStream(Http::StreamDecoder& response_decoder) { - EnvoyQuicStream* stream = - quicStreamToEnvoyStream(quic_client_session_.CreateOutgoingBidirectionalStream()); +Http::RequestEncoder& +QuicHttpClientConnectionImpl::newStream(Http::ResponseDecoder& response_decoder) { + EnvoyQuicClientStream* stream = + quicStreamToEnvoyClientStream(quic_client_session_.CreateOutgoingBidirectionalStream()); // TODO(danzh) handle stream creation failure gracefully. This can happen when // there are already 100 open streams. In such case, caller should hold back // the stream creation till an existing stream is closed. ASSERT(stream != nullptr, "Fail to create QUIC stream."); - stream->setDecoder(response_decoder); + stream->setResponseDecoder(response_decoder); if (quic_client_session_.aboveHighWatermark()) { stream->runHighWatermarkCallbacks(); } diff --git a/source/extensions/quic_listeners/quiche/codec_impl.h b/source/extensions/quic_listeners/quiche/codec_impl.h index 3fabff7c3a..732a8aa8e5 100644 --- a/source/extensions/quic_listeners/quiche/codec_impl.h +++ b/source/extensions/quic_listeners/quiche/codec_impl.h @@ -65,7 +65,7 @@ class QuicHttpClientConnectionImpl : public QuicHttpConnectionImplBase, Http::ConnectionCallbacks& callbacks); // Http::ClientConnection - Http::StreamEncoder& newStream(Http::StreamDecoder& response_decoder) override; + Http::RequestEncoder& newStream(Http::ResponseDecoder& response_decoder) override; // Http::Connection void goAway() override { NOT_REACHED_GCOVR_EXCL_LINE; } diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc index b6fed6f108..c70228d0e0 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc @@ -44,11 +44,6 @@ EnvoyQuicClientStream::EnvoyQuicClientStream(quic::PendingStream* pending, 16 * 1024, [this]() { runLowWatermarkCallbacks(); }, [this]() { runHighWatermarkCallbacks(); }) {} -void EnvoyQuicClientStream::encode100ContinueHeaders(const Http::HeaderMap& headers) { - ASSERT(headers.Status()->value() == "100"); - encodeHeaders(headers, false); -} - void EnvoyQuicClientStream::encodeHeaders(const Http::HeaderMap& headers, bool end_stream) { ENVOY_STREAM_LOG(debug, "encodeHeaders: (end_stream={}) {}.", *this, end_stream, headers); WriteHeaders(envoyHeadersToSpdyHeaderBlock(headers), end_stream, nullptr); @@ -109,9 +104,8 @@ void EnvoyQuicClientStream::OnInitialHeadersComplete(bool fin, size_t frame_len, if (rst_sent()) { return; } - ASSERT(decoder() != nullptr); ASSERT(headers_decompressed()); - decoder()->decodeHeaders(quicHeadersToEnvoyHeaders(header_list), /*end_stream=*/fin); + response_decoder_->decodeHeaders(quicHeadersToEnvoyHeaders(header_list), /*end_stream=*/fin); if (fin) { end_stream_decoded_ = true; } @@ -150,7 +144,7 @@ void EnvoyQuicClientStream::OnBodyAvailable() { // already delivered it or decodeTrailers will be called. bool skip_decoding = empty_payload_with_fin && (end_stream_decoded_ || !finished_reading); if (!skip_decoding) { - decoder()->decodeData(*buffer, finished_reading); + response_decoder_->decodeData(*buffer, finished_reading); if (finished_reading) { end_stream_decoded_ = true; } @@ -170,7 +164,7 @@ void EnvoyQuicClientStream::OnBodyAvailable() { // For Google QUIC implementation, trailers may arrived earlier and wait to // be consumed after reading all the body. Consume it here. // IETF QUIC shouldn't reach here because trailers are sent on same stream. - decoder()->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); + response_decoder_->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); MarkTrailersConsumed(); } OnFinRead(); @@ -186,8 +180,7 @@ void EnvoyQuicClientStream::OnTrailingHeadersComplete(bool fin, size_t frame_len !FinishedReadingTrailers()) { // Before QPack, trailers can arrive before body. Only decode trailers after finishing decoding // body. - ASSERT(decoder() != nullptr); - decoder()->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); + response_decoder_->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); MarkTrailersConsumed(); } } diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h index 6f99a80980..b2f420c41c 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h @@ -15,20 +15,25 @@ namespace Envoy { namespace Quic { // This class is a quic stream and also a request encoder. -class EnvoyQuicClientStream : public quic::QuicSpdyClientStream, public EnvoyQuicStream { +class EnvoyQuicClientStream : public quic::QuicSpdyClientStream, + public EnvoyQuicStream, + public Http::RequestEncoder { public: EnvoyQuicClientStream(quic::QuicStreamId id, quic::QuicSpdyClientSession* client_session, quic::StreamType type); EnvoyQuicClientStream(quic::PendingStream* pending, quic::QuicSpdyClientSession* client_session, quic::StreamType type); + void setResponseDecoder(Http::ResponseDecoder& decoder) { response_decoder_ = &decoder; } + // Http::StreamEncoder - void encode100ContinueHeaders(const Http::HeaderMap& headers) override; - void encodeHeaders(const Http::HeaderMap& headers, bool end_stream) override; void encodeData(Buffer::Instance& data, bool end_stream) override; - void encodeTrailers(const Http::HeaderMap& trailers) override; void encodeMetadata(const Http::MetadataMapVector& metadata_map_vector) override; + // Http::RequestEncoder + void encodeHeaders(const Http::HeaderMap& headers, bool end_stream) override; + void encodeTrailers(const Http::HeaderMap& trailers) override; + // Http::Stream void resetStream(Http::StreamResetReason reason) override; // quic::QuicSpdyStream @@ -54,6 +59,8 @@ class EnvoyQuicClientStream : public quic::QuicSpdyClientStream, public EnvoyQui private: QuicFilterManagerConnectionImpl* filterManagerConnection(); + + Http::ResponseDecoder* response_decoder_{nullptr}; }; } // namespace Quic diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_session.cc b/source/extensions/quic_listeners/quiche/envoy_quic_server_session.cc index d5ba4433fe..77457350d4 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_session.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_session.cc @@ -70,10 +70,10 @@ quic::QuicSpdyStream* EnvoyQuicServerSession::CreateOutgoingUnidirectionalStream NOT_REACHED_GCOVR_EXCL_LINE; } -void EnvoyQuicServerSession::setUpRequestDecoder(EnvoyQuicStream& stream) { +void EnvoyQuicServerSession::setUpRequestDecoder(EnvoyQuicServerStream& stream) { ASSERT(http_connection_callbacks_ != nullptr); - Http::StreamDecoder& decoder = http_connection_callbacks_->newStream(stream); - stream.setDecoder(decoder); + Http::RequestDecoder& decoder = http_connection_callbacks_->newStream(stream); + stream.setRequestDecoder(decoder); } void EnvoyQuicServerSession::OnConnectionClosed(const quic::QuicConnectionCloseFrame& frame, diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_session.h b/source/extensions/quic_listeners/quiche/envoy_quic_server_session.h index 0e6415e0df..50d348fb5f 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_session.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_session.h @@ -14,7 +14,7 @@ #include #include "extensions/quic_listeners/quiche/quic_filter_manager_connection_impl.h" -#include "extensions/quic_listeners/quiche/envoy_quic_stream.h" +#include "extensions/quic_listeners/quiche/envoy_quic_server_stream.h" namespace Envoy { namespace Quic { @@ -73,7 +73,7 @@ class EnvoyQuicServerSession : public quic::QuicServerSessionBase, bool hasDataToWrite() override; private: - void setUpRequestDecoder(EnvoyQuicStream& stream); + void setUpRequestDecoder(EnvoyQuicServerStream& stream); std::unique_ptr quic_connection_; // These callbacks are owned by network filters and quic session should out live diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc index ca3ff13ca4..35878eeb34 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc @@ -126,9 +126,8 @@ void EnvoyQuicServerStream::switchStreamBlockState(bool should_block) { void EnvoyQuicServerStream::OnInitialHeadersComplete(bool fin, size_t frame_len, const quic::QuicHeaderList& header_list) { quic::QuicSpdyServerStreamBase::OnInitialHeadersComplete(fin, frame_len, header_list); - ASSERT(decoder() != nullptr); ASSERT(headers_decompressed()); - decoder()->decodeHeaders(quicHeadersToEnvoyHeaders(header_list), /*end_stream=*/fin); + request_decoder_->decodeHeaders(quicHeadersToEnvoyHeaders(header_list), /*end_stream=*/fin); if (fin) { end_stream_decoded_ = true; } @@ -167,8 +166,7 @@ void EnvoyQuicServerStream::OnBodyAvailable() { // already delivered it or decodeTrailers will be called. bool skip_decoding = empty_payload_with_fin && (end_stream_decoded_ || !finished_reading); if (!skip_decoding) { - ASSERT(decoder() != nullptr); - decoder()->decodeData(*buffer, finished_reading); + request_decoder_->decodeData(*buffer, finished_reading); if (finished_reading) { end_stream_decoded_ = true; } @@ -188,7 +186,7 @@ void EnvoyQuicServerStream::OnBodyAvailable() { // For Google QUIC implementation, trailers may arrived earlier and wait to // be consumed after reading all the body. Consume it here. // IETF QUIC shouldn't reach here because trailers are sent on same stream. - decoder()->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); + request_decoder_->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); MarkTrailersConsumed(); } OnFinRead(); @@ -203,8 +201,7 @@ void EnvoyQuicServerStream::OnTrailingHeadersComplete(bool fin, size_t frame_len !FinishedReadingTrailers()) { // Before QPack trailers can arrive before body. Only decode trailers after finishing decoding // body. - ASSERT(decoder() != nullptr); - decoder()->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); + request_decoder_->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); MarkTrailersConsumed(); } } diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h index e79ac3d081..80353f2cd1 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h @@ -15,7 +15,9 @@ namespace Envoy { namespace Quic { // This class is a quic stream and also a response encoder. -class EnvoyQuicServerStream : public quic::QuicSpdyServerStreamBase, public EnvoyQuicStream { +class EnvoyQuicServerStream : public quic::QuicSpdyServerStreamBase, + public EnvoyQuicStream, + public Http::ResponseEncoder { public: EnvoyQuicServerStream(quic::QuicStreamId id, quic::QuicSpdySession* session, quic::StreamType type); @@ -23,6 +25,8 @@ class EnvoyQuicServerStream : public quic::QuicSpdyServerStreamBase, public Envo EnvoyQuicServerStream(quic::PendingStream* pending, quic::QuicSpdySession* session, quic::StreamType type); + void setRequestDecoder(Http::RequestDecoder& decoder) { request_decoder_ = &decoder; } + // Http::StreamEncoder void encode100ContinueHeaders(const Http::HeaderMap& headers) override; void encodeHeaders(const Http::HeaderMap& headers, bool end_stream) override; @@ -54,6 +58,8 @@ class EnvoyQuicServerStream : public quic::QuicSpdyServerStreamBase, public Envo private: QuicFilterManagerConnectionImpl* filterManagerConnection(); + + Http::RequestDecoder* request_decoder_{nullptr}; }; } // namespace Quic diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_stream.h b/source/extensions/quic_listeners/quiche/envoy_quic_stream.h index 157422ecc5..7171473e32 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_stream.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_stream.h @@ -12,7 +12,7 @@ namespace Envoy { namespace Quic { // Base class for EnvoyQuicServer|ClientStream. -class EnvoyQuicStream : public Http::StreamEncoder, +class EnvoyQuicStream : public virtual Http::StreamEncoder, public Http::Stream, public Http::StreamCallbackHelper, protected Logger::Loggable { @@ -80,10 +80,6 @@ class EnvoyQuicStream : public Http::StreamEncoder, return connection()->localAddress(); } - // Needs to be called during quic stream creation before the stream receives - // any headers and data. - void setDecoder(Http::StreamDecoder& decoder) { decoder_ = &decoder; } - void maybeCheckWatermark(uint64_t buffered_data_old, uint64_t buffered_data_new, QuicFilterManagerConnectionImpl& connection) { if (buffered_data_new == buffered_data_old) { @@ -106,11 +102,6 @@ class EnvoyQuicStream : public Http::StreamEncoder, virtual uint32_t streamId() PURE; virtual Network::Connection* connection() PURE; - Http::StreamDecoder* decoder() { - ASSERT(decoder_ != nullptr); - return decoder_; - } - // True once end of stream is propagated to Envoy. Envoy doesn't expect to be // notified more than once about end of stream. So once this is true, no need // to set it in the callback to Envoy stream any more. @@ -121,8 +112,6 @@ class EnvoyQuicStream : public Http::StreamEncoder, bool in_decode_data_callstack_{false}; private: - // Not owned. - Http::StreamDecoder* decoder_{nullptr}; // Keeps track of bytes buffered in the stream send buffer in QUICHE and reacts // upon crossing high and low watermarks. // Its high watermark is also the buffer limit of stream read/write filters in diff --git a/test/common/http/async_client_impl_test.cc b/test/common/http/async_client_impl_test.cc index b2e66ca010..e4a0f63231 100644 --- a/test/common/http/async_client_impl_test.cc +++ b/test/common/http/async_client_impl_test.cc @@ -71,8 +71,8 @@ class AsyncClientImplTest : public testing::Test { MockAsyncClientCallbacks callbacks_; MockAsyncClientStreamCallbacks stream_callbacks_; NiceMock cm_; - NiceMock stream_encoder_; - StreamDecoder* response_decoder_{}; + NiceMock stream_encoder_; + ResponseDecoder* response_decoder_{}; NiceMock* timer_; NiceMock dispatcher_; NiceMock runtime_; @@ -93,7 +93,7 @@ TEST_F(AsyncClientImplTest, BasicStream) { Buffer::InstancePtr body{new Buffer::OwnedImpl("test body")}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -136,7 +136,7 @@ TEST_F(AsyncClientImplTest, Basic) { Buffer::Instance& data = *message_->body(); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -172,7 +172,7 @@ TEST_F(AsyncClientImplTracingTest, Basic) { Buffer::Instance& data = *message_->body(); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -211,7 +211,7 @@ TEST_F(AsyncClientImplTracingTest, BasicNamedChildSpan) { Buffer::Instance& data = *message_->body(); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -249,7 +249,7 @@ TEST_F(AsyncClientImplTest, BasicHashPolicy) { Buffer::Instance& data = *message_->body(); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -293,7 +293,7 @@ TEST_F(AsyncClientImplTest, Retry) { Buffer::Instance& data = *message_->body(); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -313,7 +313,7 @@ TEST_F(AsyncClientImplTest, Retry) { // Retry request. EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -336,7 +336,7 @@ TEST_F(AsyncClientImplTest, RetryWithStream) { Buffer::InstancePtr body{new Buffer::OwnedImpl("test body")}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -361,7 +361,7 @@ TEST_F(AsyncClientImplTest, RetryWithStream) { // Retry request. EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -384,7 +384,7 @@ TEST_F(AsyncClientImplTest, MultipleStreams) { Buffer::InstancePtr body{new Buffer::OwnedImpl("test body")}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -405,12 +405,12 @@ TEST_F(AsyncClientImplTest, MultipleStreams) { // Start stream 2 Buffer::InstancePtr body2{new Buffer::OwnedImpl("test body")}; - NiceMock stream_encoder2; - StreamDecoder* response_decoder2{}; + NiceMock stream_encoder2; + ResponseDecoder* response_decoder2{}; MockAsyncClientStreamCallbacks stream_callbacks2; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder2, cm_.conn_pool_.host_, stream_info_); response_decoder2 = &decoder; @@ -444,7 +444,7 @@ TEST_F(AsyncClientImplTest, MultipleRequests) { Buffer::Instance& data = *message_->body(); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -459,11 +459,11 @@ TEST_F(AsyncClientImplTest, MultipleRequests) { // Send request 2. MessagePtr message2{new RequestMessageImpl()}; HttpTestUtility::addDefaultHeaders(message2->headers()); - NiceMock stream_encoder2; - StreamDecoder* response_decoder2{}; + NiceMock stream_encoder2; + ResponseDecoder* response_decoder2{}; MockAsyncClientCallbacks callbacks2; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder2, cm_.conn_pool_.host_, stream_info_); response_decoder2 = &decoder; @@ -490,7 +490,7 @@ TEST_F(AsyncClientImplTest, StreamAndRequest) { Buffer::Instance& data = *message_->body(); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -504,11 +504,11 @@ TEST_F(AsyncClientImplTest, StreamAndRequest) { // Start stream Buffer::InstancePtr body{new Buffer::OwnedImpl("test body")}; - NiceMock stream_encoder2; - StreamDecoder* response_decoder2{}; + NiceMock stream_encoder2; + ResponseDecoder* response_decoder2{}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder2, cm_.conn_pool_.host_, stream_info_); response_decoder2 = &decoder; @@ -547,7 +547,7 @@ TEST_F(AsyncClientImplTest, StreamWithTrailers) { TestHeaderMapImpl trailers{{"some", "request_trailer"}}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -580,7 +580,7 @@ TEST_F(AsyncClientImplTest, Trailers) { Buffer::Instance& data = *message_->body(); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -621,7 +621,7 @@ TEST_F(AsyncClientImplTest, LocalResetAfterStreamStart) { Buffer::InstancePtr body{new Buffer::OwnedImpl("test body")}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -656,7 +656,7 @@ TEST_F(AsyncClientImplTest, SendDataAfterRemoteClosure) { Buffer::InstancePtr body{new Buffer::OwnedImpl("test body")}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -690,7 +690,7 @@ TEST_F(AsyncClientImplTest, SendTrailersRemoteClosure) { Buffer::InstancePtr body{new Buffer::OwnedImpl("test body")}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -764,7 +764,7 @@ TEST_F(AsyncClientImplTest, RemoteResetAfterStreamStart) { Buffer::InstancePtr body{new Buffer::OwnedImpl("test body")}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -797,7 +797,7 @@ TEST_F(AsyncClientImplTest, RemoteResetAfterStreamStart) { TEST_F(AsyncClientImplTest, ResetAfterResponseStart) { EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; @@ -1135,7 +1135,7 @@ TEST_F(AsyncClientImplTest, MultipleDataStream) { Buffer::InstancePtr body2{new Buffer::OwnedImpl("test body2")}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](StreamDecoder& decoder, + .WillOnce(Invoke([&](ResponseDecoder& decoder, ConnectionPool::Callbacks& callbacks) -> ConnectionPool::Cancellable* { callbacks.onPoolReady(stream_encoder_, cm_.conn_pool_.host_, stream_info_); response_decoder_ = &decoder; diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index 8aa90954b2..e8876f8c31 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -90,15 +90,15 @@ TEST_F(CodecClientTest, NotCallDetectEarlyCloseWhenReadDiabledUsingHttp3) { } TEST_F(CodecClientTest, BasicHeaderOnlyResponse) { - Http::StreamDecoder* inner_decoder; - NiceMock inner_encoder; + ResponseDecoder* inner_decoder; + NiceMock inner_encoder; EXPECT_CALL(*codec_, newStream(_)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder) -> Http::StreamEncoder& { + .WillOnce(Invoke([&](ResponseDecoder& decoder) -> RequestEncoder& { inner_decoder = &decoder; return inner_encoder; })); - Http::MockStreamDecoder outer_decoder; + Http::MockResponseDecoder outer_decoder; client_->newStream(outer_decoder); Http::HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -107,15 +107,15 @@ TEST_F(CodecClientTest, BasicHeaderOnlyResponse) { } TEST_F(CodecClientTest, BasicResponseWithBody) { - Http::StreamDecoder* inner_decoder; - NiceMock inner_encoder; + ResponseDecoder* inner_decoder; + NiceMock inner_encoder; EXPECT_CALL(*codec_, newStream(_)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder) -> Http::StreamEncoder& { + .WillOnce(Invoke([&](ResponseDecoder& decoder) -> RequestEncoder& { inner_decoder = &decoder; return inner_encoder; })); - Http::MockStreamDecoder outer_decoder; + Http::MockResponseDecoder outer_decoder; client_->newStream(outer_decoder); Http::HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -128,15 +128,15 @@ TEST_F(CodecClientTest, BasicResponseWithBody) { } TEST_F(CodecClientTest, DisconnectBeforeHeaders) { - Http::StreamDecoder* inner_decoder; - NiceMock inner_encoder; + ResponseDecoder* inner_decoder; + NiceMock inner_encoder; EXPECT_CALL(*codec_, newStream(_)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder) -> Http::StreamEncoder& { + .WillOnce(Invoke([&](ResponseDecoder& decoder) -> RequestEncoder& { inner_decoder = &decoder; return inner_encoder; })); - Http::MockStreamDecoder outer_decoder; + Http::MockResponseDecoder outer_decoder; Http::StreamEncoder& request_encoder = client_->newStream(outer_decoder); Http::MockStreamCallbacks callbacks; request_encoder.getStream().addCallbacks(callbacks); @@ -150,15 +150,15 @@ TEST_F(CodecClientTest, DisconnectBeforeHeaders) { } TEST_F(CodecClientTest, IdleTimerWithNoActiveRequests) { - Http::StreamDecoder* inner_decoder; - NiceMock inner_encoder; + ResponseDecoder* inner_decoder; + NiceMock inner_encoder; EXPECT_CALL(*codec_, newStream(_)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder) -> Http::StreamEncoder& { + .WillOnce(Invoke([&](ResponseDecoder& decoder) -> RequestEncoder& { inner_decoder = &decoder; return inner_encoder; })); - Http::MockStreamDecoder outer_decoder; + Http::MockResponseDecoder outer_decoder; Http::StreamEncoder& request_encoder = client_->newStream(outer_decoder); Http::MockStreamCallbacks callbacks; request_encoder.getStream().addCallbacks(callbacks); @@ -182,15 +182,15 @@ TEST_F(CodecClientTest, IdleTimerWithNoActiveRequests) { } TEST_F(CodecClientTest, IdleTimerClientRemoteCloseWithActiveRequests) { - Http::StreamDecoder* inner_decoder; - NiceMock inner_encoder; + ResponseDecoder* inner_decoder; + NiceMock inner_encoder; EXPECT_CALL(*codec_, newStream(_)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder) -> Http::StreamEncoder& { + .WillOnce(Invoke([&](ResponseDecoder& decoder) -> RequestEncoder& { inner_decoder = &decoder; return inner_encoder; })); - Http::MockStreamDecoder outer_decoder; + Http::MockResponseDecoder outer_decoder; Http::StreamEncoder& request_encoder = client_->newStream(outer_decoder); Http::MockStreamCallbacks callbacks; request_encoder.getStream().addCallbacks(callbacks); @@ -206,15 +206,15 @@ TEST_F(CodecClientTest, IdleTimerClientRemoteCloseWithActiveRequests) { } TEST_F(CodecClientTest, IdleTimerClientLocalCloseWithActiveRequests) { - Http::StreamDecoder* inner_decoder; - NiceMock inner_encoder; + ResponseDecoder* inner_decoder; + NiceMock inner_encoder; EXPECT_CALL(*codec_, newStream(_)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder) -> Http::StreamEncoder& { + .WillOnce(Invoke([&](ResponseDecoder& decoder) -> RequestEncoder& { inner_decoder = &decoder; return inner_encoder; })); - Http::MockStreamDecoder outer_decoder; + Http::MockResponseDecoder outer_decoder; Http::StreamEncoder& request_encoder = client_->newStream(outer_decoder); Http::MockStreamCallbacks callbacks; request_encoder.getStream().addCallbacks(callbacks); @@ -332,9 +332,9 @@ class CodecNetworkTest : public testing::TestWithParam Http::StreamEncoder& { + .WillOnce(Invoke([&](ResponseDecoder& decoder) -> RequestEncoder& { inner_decoder = &decoder; return inner_encoder_; })); @@ -365,8 +365,8 @@ class CodecNetworkTest : public testing::TestWithParam upstream_callbacks_; Network::ClientConnection* client_connection_{}; NiceMock client_callbacks_; - NiceMock inner_encoder_; - NiceMock outer_decoder_; + NiceMock inner_encoder_; + NiceMock outer_decoder_; }; // Send a block of data from upstream, and ensure it is received by the codec. diff --git a/test/common/http/codec_impl_fuzz_test.cc b/test/common/http/codec_impl_fuzz_test.cc index ed592b66dc..428d253322 100644 --- a/test/common/http/codec_impl_fuzz_test.cc +++ b/test/common/http/codec_impl_fuzz_test.cc @@ -87,10 +87,11 @@ class HttpStream : public LinkedObject { enum class StreamState : int { PendingHeaders, PendingDataOrTrailers, Closed }; struct DirectionalState { - // The request encode and response decoder belong to the client, the - // response encoder and request decoder belong to the server. - StreamEncoder* encoder_; - NiceMock decoder_; + // TODO(mattklein123): Split this more clearly into request and response directional state. + RequestEncoder* request_encoder_; + ResponseEncoder* response_encoder_; + NiceMock response_decoder_; + NiceMock request_decoder_; NiceMock stream_callbacks_; StreamState stream_state_; bool local_closed_{false}; @@ -115,7 +116,7 @@ class HttpStream : public LinkedObject { } request_, response_; HttpStream(ClientConnection& client, const TestHeaderMapImpl& request_headers, bool end_stream) { - request_.encoder_ = &client.newStream(response_.decoder_); + request_.request_encoder_ = &client.newStream(response_.response_decoder_); ON_CALL(request_.stream_callbacks_, onResetStream(_, _)) .WillByDefault(InvokeWithoutArgs([this] { ENVOY_LOG_MISC(trace, "reset request for stream index {}", stream_index_); @@ -126,34 +127,32 @@ class HttpStream : public LinkedObject { ENVOY_LOG_MISC(trace, "reset response for stream index {}", stream_index_); resetStream(); })); - ON_CALL(request_.decoder_, decodeHeaders_(_, true)).WillByDefault(InvokeWithoutArgs([this] { - // The HTTP/1 codec needs this to cleanup any latent stream resources. - response_.encoder_->getStream().resetStream(StreamResetReason::LocalReset); - request_.closeRemote(); - })); - ON_CALL(request_.decoder_, decodeData(_, true)).WillByDefault(InvokeWithoutArgs([this] { + ON_CALL(request_.request_decoder_, decodeHeaders_(_, true)) + .WillByDefault(InvokeWithoutArgs([this] { + // The HTTP/1 codec needs this to cleanup any latent stream resources. + response_.response_encoder_->getStream().resetStream(StreamResetReason::LocalReset); + request_.closeRemote(); + })); + ON_CALL(request_.request_decoder_, decodeData(_, true)).WillByDefault(InvokeWithoutArgs([this] { // The HTTP/1 codec needs this to cleanup any latent stream resources. - response_.encoder_->getStream().resetStream(StreamResetReason::LocalReset); + response_.response_encoder_->getStream().resetStream(StreamResetReason::LocalReset); request_.closeRemote(); })); - ON_CALL(request_.decoder_, decodeTrailers_(_)).WillByDefault(InvokeWithoutArgs([this] { + ON_CALL(request_.request_decoder_, decodeTrailers_(_)).WillByDefault(InvokeWithoutArgs([this] { // The HTTP/1 codec needs this to cleanup any latent stream resources. - response_.encoder_->getStream().resetStream(StreamResetReason::LocalReset); + response_.response_encoder_->getStream().resetStream(StreamResetReason::LocalReset); request_.closeRemote(); })); - ON_CALL(response_.decoder_, decodeHeaders_(_, true)).WillByDefault(InvokeWithoutArgs([this] { - response_.closeRemote(); - })); - ON_CALL(response_.decoder_, decodeData(_, true)).WillByDefault(InvokeWithoutArgs([this] { - response_.closeRemote(); - })); - ON_CALL(response_.decoder_, decodeTrailers_(_)).WillByDefault(InvokeWithoutArgs([this] { - response_.closeRemote(); - })); + ON_CALL(response_.response_decoder_, decodeHeaders_(_, true)) + .WillByDefault(InvokeWithoutArgs([this] { response_.closeRemote(); })); + ON_CALL(response_.response_decoder_, decodeData(_, true)) + .WillByDefault(InvokeWithoutArgs([this] { response_.closeRemote(); })); + ON_CALL(response_.response_decoder_, decodeTrailers_(_)) + .WillByDefault(InvokeWithoutArgs([this] { response_.closeRemote(); })); if (!end_stream) { - request_.encoder_->getStream().addCallbacks(request_.stream_callbacks_); + request_.request_encoder_->getStream().addCallbacks(request_.stream_callbacks_); } - request_.encoder_->encodeHeaders(request_headers, end_stream); + request_.request_encoder_->encodeHeaders(request_headers, end_stream); request_.stream_state_ = end_stream ? StreamState::Closed : StreamState::PendingDataOrTrailers; response_.stream_state_ = StreamState::PendingHeaders; } @@ -176,7 +175,7 @@ class HttpStream : public LinkedObject { Http::TestHeaderMapImpl headers = fromSanitizedHeaders(directional_action.continue_headers()); headers.setReferenceKey(Headers::get().Status, "100"); - state.encoder_->encode100ContinueHeaders(headers); + state.response_encoder_->encode100ContinueHeaders(headers); } break; } @@ -186,7 +185,11 @@ class HttpStream : public LinkedObject { if (response && headers.Status() == nullptr) { headers.setReferenceKey(Headers::get().Status, "200"); } - state.encoder_->encodeHeaders(headers, end_stream); + if (response) { + state.response_encoder_->encodeHeaders(headers, end_stream); + } else { + state.request_encoder_->encodeHeaders(headers, end_stream); + } if (end_stream) { state.closeLocal(); } else { @@ -198,7 +201,11 @@ class HttpStream : public LinkedObject { case test::common::http::DirectionalAction::kData: { if (state.isLocalOpen() && state.stream_state_ == StreamState::PendingDataOrTrailers) { Buffer::OwnedImpl buf(std::string(directional_action.data() % (1024 * 1024), 'a')); - state.encoder_->encodeData(buf, end_stream); + if (response) { + state.response_encoder_->encodeData(buf, end_stream); + } else { + state.request_encoder_->encodeData(buf, end_stream); + } if (end_stream) { state.closeLocal(); } @@ -208,7 +215,11 @@ class HttpStream : public LinkedObject { case test::common::http::DirectionalAction::kDataValue: { if (state.isLocalOpen() && state.stream_state_ == StreamState::PendingDataOrTrailers) { Buffer::OwnedImpl buf(directional_action.data_value()); - state.encoder_->encodeData(buf, end_stream); + if (response) { + state.response_encoder_->encodeData(buf, end_stream); + } else { + state.request_encoder_->encodeData(buf, end_stream); + } if (end_stream) { state.closeLocal(); } @@ -217,7 +228,13 @@ class HttpStream : public LinkedObject { } case test::common::http::DirectionalAction::kTrailers: { if (state.isLocalOpen() && state.stream_state_ == StreamState::PendingDataOrTrailers) { - state.encoder_->encodeTrailers(fromSanitizedHeaders(directional_action.trailers())); + if (response) { + state.response_encoder_->encodeTrailers( + fromSanitizedHeaders(directional_action.trailers())); + } else { + state.request_encoder_->encodeTrailers( + fromSanitizedHeaders(directional_action.trailers())); + } state.stream_state_ = StreamState::Closed; state.closeLocal(); } @@ -225,7 +242,13 @@ class HttpStream : public LinkedObject { } case test::common::http::DirectionalAction::kResetStream: { if (state.stream_state_ != StreamState::Closed) { - state.encoder_->getStream().resetStream( + StreamEncoder* encoder; + if (response) { + encoder = state.response_encoder_; + } else { + encoder = state.request_encoder_; + } + encoder->getStream().resetStream( static_cast(directional_action.reset_stream())); request_.stream_state_ = response_.stream_state_ = StreamState::Closed; } @@ -242,7 +265,13 @@ class HttpStream : public LinkedObject { } else { --state.read_disable_count_; } - state.encoder_->getStream().readDisable(disable); + StreamEncoder* encoder; + if (response) { + encoder = state.response_encoder_; + } else { + encoder = state.request_encoder_; + } + encoder->getStream().readDisable(disable); } break; } @@ -401,20 +430,20 @@ void codecFuzz(const test::common::http::CodecImplFuzzTestCase& input, HttpVersi std::list pending_streams; std::list streams; // For new streams when we aren't expecting one (e.g. as a result of a mutation). - NiceMock orphan_request_decoder; + NiceMock orphan_request_decoder; ON_CALL(server_callbacks, newStream(_, _)) - .WillByDefault(Invoke([&](StreamEncoder& encoder, bool) -> StreamDecoder& { + .WillByDefault(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { if (pending_streams.empty()) { return orphan_request_decoder; } auto stream_ptr = pending_streams.front()->removeFromList(pending_streams); HttpStream* const stream = stream_ptr.get(); stream_ptr->moveIntoListBack(std::move(stream_ptr), streams); - stream->response_.encoder_ = &encoder; + stream->response_.response_encoder_ = &encoder; encoder.getStream().addCallbacks(stream->response_.stream_callbacks_); stream->stream_index_ = streams.size() - 1; - return stream->request_.decoder_; + return stream->request_.request_decoder_; })); const auto client_server_buf_drain = [&client_write_buf, &server_write_buf] { diff --git a/test/common/http/codec_wrappers_test.cc b/test/common/http/codec_wrappers_test.cc index d660c4f85f..6f690cdbb5 100644 --- a/test/common/http/codec_wrappers_test.cc +++ b/test/common/http/codec_wrappers_test.cc @@ -8,33 +8,34 @@ using testing::_; namespace Envoy { namespace Http { -class MockStreamEncoderWrapper : public StreamEncoderWrapper { +class MockRequestEncoderWrapper : public RequestEncoderWrapper { public: - MockStreamEncoderWrapper() : StreamEncoderWrapper(inner_encoder_) {} + MockRequestEncoderWrapper() : RequestEncoderWrapper(inner_encoder_) {} void onEncodeComplete() override { encode_complete_ = true; } - MockStreamEncoder& innerEncoder() { return inner_encoder_; } + MockRequestEncoder& innerEncoder() { return inner_encoder_; } bool encodeComplete() const { return encode_complete_; } private: - MockStreamEncoder inner_encoder_; + MockRequestEncoder inner_encoder_; bool encode_complete_{}; }; -TEST(StreamEncoderWrapper, HeaderOnlyEncode) { - MockStreamEncoderWrapper wrapper; +TEST(RequestEncoderWrapper, HeaderOnlyEncode) { + MockRequestEncoderWrapper wrapper; EXPECT_CALL(wrapper.innerEncoder(), encodeHeaders(_, true)); - wrapper.encodeHeaders(TestHeaderMapImpl{{":status", "200"}}, true); + wrapper.encodeHeaders( + TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}, {":authority", "foo"}}, true); EXPECT_TRUE(wrapper.encodeComplete()); } -TEST(StreamEncoderWrapper, HeaderAndBodyEncode) { - MockStreamEncoderWrapper wrapper; +TEST(RequestEncoderWrapper, HeaderAndBodyEncode) { + MockRequestEncoderWrapper wrapper; - TestHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(wrapper.innerEncoder(), encodeHeaders(_, false)); - wrapper.encodeHeaders(response_headers, false); + wrapper.encodeHeaders( + TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}, {":authority", "foo"}}, false); EXPECT_FALSE(wrapper.encodeComplete()); Buffer::OwnedImpl data; @@ -43,12 +44,12 @@ TEST(StreamEncoderWrapper, HeaderAndBodyEncode) { EXPECT_TRUE(wrapper.encodeComplete()); } -TEST(StreamEncoderWrapper, HeaderAndBodyAndTrailersEncode) { - MockStreamEncoderWrapper wrapper; +TEST(RequestEncoderWrapper, HeaderAndBodyAndTrailersEncode) { + MockRequestEncoderWrapper wrapper; - TestHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(wrapper.innerEncoder(), encodeHeaders(_, false)); - wrapper.encodeHeaders(response_headers, false); + wrapper.encodeHeaders( + TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}, {":authority", "foo"}}, false); EXPECT_FALSE(wrapper.encodeComplete()); Buffer::OwnedImpl data; @@ -61,17 +62,5 @@ TEST(StreamEncoderWrapper, HeaderAndBodyAndTrailersEncode) { EXPECT_TRUE(wrapper.encodeComplete()); } -TEST(StreamEncoderWrapper, 100ContinueHeaderEncode) { - MockStreamEncoderWrapper wrapper; - - EXPECT_CALL(wrapper.innerEncoder(), encode100ContinueHeaders(_)); - wrapper.encode100ContinueHeaders(TestHeaderMapImpl{{":status", "100"}}); - EXPECT_FALSE(wrapper.encodeComplete()); - - EXPECT_CALL(wrapper.innerEncoder(), encodeHeaders(_, true)); - wrapper.encodeHeaders(TestHeaderMapImpl{{":status", "200"}}, true); - EXPECT_TRUE(wrapper.encodeComplete()); -} - } // namespace Http } // namespace Envoy diff --git a/test/common/http/common.h b/test/common/http/common.h index d9b4f7823a..ece286f107 100644 --- a/test/common/http/common.h +++ b/test/common/http/common.h @@ -38,7 +38,7 @@ class CodecClientForTest : public Http::CodecClient { * Mock callbacks used for conn pool testing. */ struct ConnPoolCallbacks : public Http::ConnectionPool::Callbacks { - void onPoolReady(Http::StreamEncoder& encoder, Upstream::HostDescriptionConstSharedPtr host, + void onPoolReady(Http::RequestEncoder& encoder, Upstream::HostDescriptionConstSharedPtr host, const StreamInfo::StreamInfo&) override { outer_encoder_ = &encoder; host_ = host; @@ -53,7 +53,7 @@ struct ConnPoolCallbacks : public Http::ConnectionPool::Callbacks { ReadyWatcher pool_failure_; ReadyWatcher pool_ready_; - Http::StreamEncoder* outer_encoder_{}; + Http::RequestEncoder* outer_encoder_{}; Upstream::HostDescriptionConstSharedPtr host_; }; diff --git a/test/common/http/conn_manager_impl_fuzz_test.cc b/test/common/http/conn_manager_impl_fuzz_test.cc index 0318637f20..72a490308a 100644 --- a/test/common/http/conn_manager_impl_fuzz_test.cc +++ b/test/common/http/conn_manager_impl_fuzz_test.cc @@ -409,8 +409,8 @@ class FuzzStream { ConnectionManagerImpl& conn_manager_; FuzzConfig& config_; - StreamDecoder* decoder_{}; - NiceMock encoder_; + RequestDecoder* decoder_{}; + NiceMock encoder_; MockStreamDecoderFilter* decoder_filter_{}; MockStreamEncoderFilter* encoder_filter_{}; StreamState request_state_; diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc index 724779c73b..d22c3c0581 100644 --- a/test/common/http/conn_manager_impl_test.cc +++ b/test/common/http/conn_manager_impl_test.cc @@ -204,7 +204,7 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan setUpBufferLimits(); EXPECT_CALL(*codec_, dispatch(_)) .WillOnce(Invoke([&, request_with_data_and_trailers](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; if (request_with_data_and_trailers) { @@ -401,7 +401,7 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan NiceMock conn_pool_; // for websocket tests // TODO(mattklein123): Not all tests have been converted over to better setup. Convert the rest. - MockStreamEncoder response_encoder_; + MockResponseEncoder response_encoder_; std::vector decoder_filters_; std::vector encoder_filters_; }; @@ -436,8 +436,8 @@ TEST_F(HttpConnectionManagerImplTest, HeaderOnlyRequestAndResponse) { // When dispatch is called on the codec, we pretend to get a new stream and then fire a headers // only request into it. Then we respond into the filter. - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)) .Times(2) .WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { @@ -496,8 +496,8 @@ TEST_F(HttpConnectionManagerImplTest, 100ContinueResponse) { // When dispatch is called on the codec, we pretend to get a new stream and then fire a headers // only request into it. Then we respond into the filter. - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -667,7 +667,7 @@ TEST_F(HttpConnectionManagerImplTest, InvalidPathWithDualFilter) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{new TestHeaderMapImpl{ {":authority", "host"}, {":path", "http://api.lyft.com/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -704,7 +704,7 @@ TEST_F(HttpConnectionManagerImplTest, PathFailedtoSanitize) { normalize_path_ = true; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/ab%00c"}, // "%00" is not valid in path according to RFC @@ -760,7 +760,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterShouldUseSantizedPath) { EXPECT_CALL(*filter, setDecoderFilterCallbacks(_)); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{new TestHeaderMapImpl{ {":authority", "host"}, {":path", original_path}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -781,7 +781,7 @@ TEST_F(HttpConnectionManagerImplTest, RouteShouldUseSantizedPath) { const std::string normalized_path = "/z"; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{new TestHeaderMapImpl{ {":authority", "host"}, {":path", original_path}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -934,8 +934,8 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlow) { use_remote_address_ = false; EXPECT_CALL(random_, uuid()).Times(0); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1001,8 +1001,8 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecorat use_remote_address_ = false; EXPECT_CALL(random_, uuid()).Times(0); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1065,8 +1065,8 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecorat use_remote_address_ = false; EXPECT_CALL(random_, uuid()).Times(0); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1145,8 +1145,8 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecorato use_remote_address_ = false; EXPECT_CALL(random_, uuid()).Times(0); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1226,8 +1226,8 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecorato use_remote_address_ = false; EXPECT_CALL(random_, uuid()).Times(0); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1282,8 +1282,8 @@ TEST_F(HttpConnectionManagerImplTest, use_remote_address_ = false; EXPECT_CALL(random_, uuid()).Times(0); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1338,8 +1338,8 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLog) { local_address); })); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1382,8 +1382,8 @@ TEST_F(HttpConnectionManagerImplTest, TestDownstreamDisconnectAccessLog) { stream_info.hasResponseFlag(StreamInfo::ResponseFlag::DownstreamConnectionTermination)); })); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1421,8 +1421,8 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLogWithTrailers) { EXPECT_NE(nullptr, stream_info.routeEntry()); })); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1470,8 +1470,8 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLogWithInvalidRequest) { EXPECT_EQ(nullptr, stream_info.routeEntry()); })); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1509,8 +1509,8 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLogSsl) { EXPECT_NE(nullptr, stream_info.routeEntry()); })); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1552,8 +1552,8 @@ TEST_F(HttpConnectionManagerImplTest, DoNotStartSpanIfTracingIsNotEnabled) { callbacks.addStreamDecoderFilter(filter); })); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -1577,8 +1577,8 @@ TEST_F(HttpConnectionManagerImplTest, DoNotStartSpanIfTracingIsNotEnabled) { TEST_F(HttpConnectionManagerImplTest, NoPath) { setup(false, ""); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); HeaderMapPtr headers{new TestHeaderMapImpl{{":authority", "host"}, {":method", "NOT_CONNECT"}}}; @@ -1603,7 +1603,7 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutNotConfigured) { EXPECT_CALL(filter_callbacks_.connection_.dispatcher_, createTimer_(_)).Times(0); EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; @@ -1702,7 +1702,7 @@ TEST_F(HttpConnectionManagerImplTest, TestStreamIdleAccessLog) { stream_idle_timeout_ = std::chrono::milliseconds(10); setup(false, ""); - NiceMock encoder; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance&) -> void { Event::MockTimer* idle_timer = setUpTimer(); EXPECT_CALL(*idle_timer, enableTimer(std::chrono::milliseconds(10), _)); @@ -1758,7 +1758,7 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutRouteOverride) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { Event::MockTimer* idle_timer = setUpTimer(); EXPECT_CALL(*idle_timer, enableTimer(std::chrono::milliseconds(10), _)); - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; @@ -1784,7 +1784,7 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutRouteZeroOverride) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { Event::MockTimer* idle_timer = setUpTimer(); EXPECT_CALL(*idle_timer, enableTimer(std::chrono::milliseconds(10), _)); - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; @@ -1808,7 +1808,7 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutAfterDownstreamHeaders // Codec sends downstream request headers. EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); Event::MockTimer* idle_timer = setUpTimer(); HeaderMapPtr headers{ @@ -1849,7 +1849,7 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutNormalTermination) { // Codec sends downstream request headers. Event::MockTimer* idle_timer = setUpTimer(); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; @@ -1877,7 +1877,7 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutAfterDownstreamHeaders // Codec sends downstream request headers. EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); Event::MockTimer* idle_timer = setUpTimer(); HeaderMapPtr headers{ @@ -1930,7 +1930,7 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutAfterUpstreamHeaders) // Codec sends downstream request headers, upstream response headers are // encoded. EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); Event::MockTimer* idle_timer = setUpTimer(); HeaderMapPtr headers{ @@ -1979,7 +1979,7 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutAfterBidiData) { // Codec sends downstream request headers, upstream response headers are // encoded, data events happen in various directions. Event::MockTimer* idle_timer = setUpTimer(); - StreamDecoder* decoder; + RequestDecoder* decoder; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ @@ -2108,7 +2108,7 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsNotDisarmedOnIncompleteReq EXPECT_CALL(*request_timer, enableTimer(request_timeout_, _)).Times(1); EXPECT_CALL(*request_timer, disableTimer()).Times(0); - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; @@ -2130,7 +2130,7 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnCompleteRequestW Event::MockTimer* request_timer = setUpTimer(); EXPECT_CALL(*request_timer, enableTimer(request_timeout_, _)).Times(1); - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; @@ -2152,7 +2152,7 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnCompleteRequestW Event::MockTimer* request_timer = setUpTimer(); EXPECT_CALL(*request_timer, enableTimer(request_timeout_, _)).Times(1); - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "POST"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -2174,7 +2174,7 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnCompleteRequestW EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { Event::MockTimer* request_timer = setUpTimer(); EXPECT_CALL(*request_timer, enableTimer(request_timeout_, _)).Times(1); - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; @@ -2206,7 +2206,7 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnEncodeHeaders) { Event::MockTimer* request_timer = setUpTimer(); EXPECT_CALL(*request_timer, enableTimer(request_timeout_, _)).Times(1); - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; @@ -2229,7 +2229,7 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnConnectionTermin Event::MockTimer* request_timer = setUpTimer(); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; @@ -2249,8 +2249,8 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnConnectionTermin TEST_F(HttpConnectionManagerImplTest, RejectWebSocketOnNonWebSocketRoute) { setup(false, ""); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); HeaderMapPtr headers{new TestHeaderMapImpl{{":authority", "host"}, @@ -2290,7 +2290,7 @@ TEST_F(HttpConnectionManagerImplTest, FooUpgradeDrainClose) { .WillRepeatedly(Invoke( [&](HeaderMap&, bool) -> FilterHeadersStatus { return FilterHeadersStatus::Continue; })); - NiceMock encoder; + NiceMock encoder; EXPECT_CALL(encoder, encodeHeaders(_, false)) .WillOnce(Invoke([&](const HeaderMap& headers, bool) -> void { EXPECT_NE(nullptr, headers.Connection()); @@ -2309,7 +2309,7 @@ TEST_F(HttpConnectionManagerImplTest, FooUpgradeDrainClose) { // When dispatch is called on the codec, we pretend to get a new stream and then fire a headers // only request into it. Then we respond into the filter. - StreamDecoder* decoder = nullptr; + RequestDecoder* decoder = nullptr; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); @@ -2348,8 +2348,8 @@ TEST_F(HttpConnectionManagerImplTest, DrainClose) { return FilterHeadersStatus::StopIteration; })); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(encoder); HeaderMapPtr headers{ @@ -2386,7 +2386,7 @@ TEST_F(HttpConnectionManagerImplTest, ResponseBeforeRequestComplete) { setup(false, "envoy-server-test"); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -2418,7 +2418,7 @@ TEST_F(HttpConnectionManagerImplTest, DisconnectOnProxyConnectionDisconnect) { setup(false, "envoy-server-test"); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{new TestHeaderMapImpl{ {":authority", "host"}, {":path", "/"}, {":method", "GET"}, {"proxy-connection", "close"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -2461,8 +2461,8 @@ TEST_F(HttpConnectionManagerImplTest, ResponseStartBeforeRequestComplete) { .WillOnce(Return(FilterHeadersStatus::StopIteration)); // Start the request - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(encoder); HeaderMapPtr headers{ @@ -2503,7 +2503,7 @@ TEST_F(HttpConnectionManagerImplTest, DownstreamDisconnect) { InSequence s; setup(false, ""); - NiceMock encoder; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { conn_manager_->newStream(encoder); data.drain(2); @@ -2555,8 +2555,8 @@ TEST_F(HttpConnectionManagerImplTest, TestDownstreamProtocolErrorAccessLog) { EXPECT_TRUE(stream_info.hasResponseFlag(StreamInfo::ResponseFlag::DownstreamProtocolError)); })); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(encoder); throw CodecProtocolException("protocol error"); @@ -2586,8 +2586,8 @@ TEST_F(HttpConnectionManagerImplTest, TestDownstreamProtocolErrorAfterHeadersAcc EXPECT_TRUE(stream_info.hasResponseFlag(StreamInfo::ResponseFlag::DownstreamProtocolError)); })); - StreamDecoder* decoder = nullptr; - NiceMock encoder; + RequestDecoder* decoder = nullptr; + NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(encoder); @@ -2683,8 +2683,8 @@ TEST_F(HttpConnectionManagerImplTest, IdleTimeout) { callbacks.addStreamDecoderFilter(StreamDecoderFilterSharedPtr{filter}); })); - NiceMock encoder; - StreamDecoder* decoder = nullptr; + NiceMock encoder; + RequestDecoder* decoder = nullptr; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(encoder); HeaderMapPtr headers{ @@ -2752,8 +2752,8 @@ TEST_F(HttpConnectionManagerImplTest, ConnectionDuration) { callbacks.addStreamDecoderFilter(StreamDecoderFilterSharedPtr{filter}); })); - NiceMock encoder; - StreamDecoder* decoder = nullptr; + NiceMock encoder; + RequestDecoder* decoder = nullptr; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(encoder); HeaderMapPtr headers{ @@ -2795,7 +2795,7 @@ TEST_F(HttpConnectionManagerImplTest, IntermediateBufferingEarlyResponse) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -2841,7 +2841,7 @@ TEST_F(HttpConnectionManagerImplTest, DoubleBuffering) { Buffer::OwnedImpl fake_data("hello"); Buffer::OwnedImpl fake_data_copy("hello"); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -2882,7 +2882,7 @@ TEST_F(HttpConnectionManagerImplTest, ZeroByteDataFiltering) { InSequence s; setup(false, ""); - StreamDecoder* decoder = nullptr; + RequestDecoder* decoder = nullptr; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ @@ -2923,7 +2923,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddTrailersInTrailersCallback) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -3009,7 +3009,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddTrailersInDataCallbackNoTrailers) setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -3100,7 +3100,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -3181,7 +3181,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback_NoDataFram setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -3240,7 +3240,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback_ContinueAf setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -3305,7 +3305,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyDuringDecodeData) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -3373,7 +3373,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInline) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -3423,7 +3423,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterClearRouteCache) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -3545,7 +3545,7 @@ TEST_F(HttpConnectionManagerImplTest, UnderlyingConnectionWatermarksPassedOnWith // Create the stream. Defer the creation of the filter chain by not sending // complete headers. - StreamDecoder* decoder; + RequestDecoder* decoder; { setUpBufferLimits(); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { @@ -3605,7 +3605,7 @@ TEST_F(HttpConnectionManagerImplTest, UnderlyingConnectionWatermarksUnwoundWithL // Create the stream. Defer the creation of the filter chain by not sending // complete headers. - StreamDecoder* decoder; + RequestDecoder* decoder; { setUpBufferLimits(); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { @@ -3756,7 +3756,7 @@ TEST_F(HttpConnectionManagerImplTest, HitRequestBufferLimitsIntermediateFilter) setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -3860,7 +3860,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterHeadReply) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "HEAD"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -3898,7 +3898,7 @@ TEST_F(HttpConnectionManagerImplTest, ResetWithStoppedFilter) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -3942,7 +3942,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterContinueAndEndStreamHeaders) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); auto headers = std::make_unique( std::initializer_list>( {{":authority", "host"}, {":path", "/"}, {":method", "GET"}})); @@ -3982,7 +3982,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterContinueAndEndStreamData) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); auto headers = makeHeaderMap({{":authority", "host"}, {":path", "/"}, {":method", "GET"}}); decoder->decodeHeaders(std::move(headers), false); @@ -4022,7 +4022,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterContinueAndEndStreamTrailers) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); auto headers = makeHeaderMap({{":authority", "host"}, {":path", "/"}, {":method", "GET"}}); decoder->decodeHeaders(std::move(headers), false); @@ -4068,7 +4068,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyContinuation) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -4153,7 +4153,7 @@ TEST_F(HttpConnectionManagerImplTest, AddDataWithAllContinue) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -4255,7 +4255,7 @@ TEST_F(HttpConnectionManagerImplTest, AddDataWithStopAndContinue) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -4330,7 +4330,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterDirectDecodeEncodeDataNoTrailers) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -4409,7 +4409,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterDirectDecodeEncodeDataTrailers) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -4503,7 +4503,7 @@ TEST_F(HttpConnectionManagerImplTest, MultipleFilters) { setup(false, ""); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -4614,7 +4614,7 @@ TEST_F(HttpConnectionManagerImplTest, NoNewStreamWhenOverloaded) { Server::OverloadActionState::Active); EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -4648,7 +4648,7 @@ TEST_F(HttpConnectionManagerImplTest, DisableKeepAliveWhenOverloaded) { })); EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{new TestHeaderMapImpl{ {":authority", "host"}, {":path", "/"}, {":method", "GET"}, {"connection", "keep-alive"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -4767,7 +4767,7 @@ TEST_F(HttpConnectionManagerImplTest, DisableKeepAliveWhenDraining) { })); EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{new TestHeaderMapImpl{ {":authority", "host"}, {":path", "/"}, {":method", "GET"}, {"connection", "keep-alive"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -4800,7 +4800,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSessionTrace) { setupFilterChain(1, 1); // Create a new stream - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); // Send headers to that stream, and verify we both set and clear the tracked object. { @@ -4859,7 +4859,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsRouteNotFound) { .Times(2) .WillRepeatedly(Return(nullptr)); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":method", "GET"}, {":path", "/foo"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -4889,7 +4889,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsUpdate) { .WillOnce(Return(nullptr)) // refreshCachedRoute first time. .WillOnce(Return(route_config_)); // triggered by callbacks_->route(), SRDS now updated. EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":method", "GET"}, {":path", "/foo"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -4952,7 +4952,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsCrossScopeReroute) { return route_config2; })); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{new TestHeaderMapImpl{ {":authority", "host"}, {":method", "GET"}, {"scope_key", "foo"}, {":path", "/foo"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -5003,7 +5003,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsRouteFound) { scopedRouteConfigProvider()->config()->route_config_.get()), route(_, _, _)) .WillOnce(Return(route1)); - StreamDecoder* decoder = nullptr; + RequestDecoder* decoder = nullptr; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ @@ -5070,8 +5070,8 @@ TEST_F(HttpConnectionManagerImplTest, HeaderOnlyRequestAndResponseUsingHttp3) { // Pretend to get a new stream and then fire a headers only request into it. Then we respond into // the filter. - NiceMock encoder; - StreamDecoder& decoder = conn_manager_->newStream(encoder); + NiceMock encoder; + RequestDecoder& decoder = conn_manager_->newStream(encoder); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder.decodeHeaders(std::move(headers), true); @@ -5108,7 +5108,7 @@ TEST_F(HttpConnectionManagerImplTest, ConnectionFilterState) { setupFilterChain(1, 0, /* num_requests = */ 3); EXPECT_CALL(*codec_, dispatch(_)).Times(2).WillRepeatedly(Invoke([&](Buffer::Instance&) -> void { - StreamDecoder* decoder = &conn_manager_->newStream(response_encoder_); + RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); HeaderMapPtr headers{ new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); diff --git a/test/common/http/http1/codec_impl_test.cc b/test/common/http/http1/codec_impl_test.cc index d1ad84afb9..9f0fdde50e 100644 --- a/test/common/http/http1/codec_impl_test.cc +++ b/test/common/http/http1/codec_impl_test.cc @@ -71,15 +71,14 @@ class Http1ServerConnectionImplTest : public testing::Test { // Then send a response just to clean up. void sendAndValidateRequestAndSendResponse(absl::string_view raw_request, const TestHeaderMapImpl& expected_request_headers) { - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .Times(1) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); - EXPECT_CALL(decoder, decodeHeaders_(HeaderMapEqual(&expected_request_headers), true)).Times(1); + EXPECT_CALL(decoder, decodeHeaders_(HeaderMapEqual(&expected_request_headers), true)); Buffer::OwnedImpl buffer(raw_request); codec_->dispatch(buffer); EXPECT_EQ(0U, buffer.length()); @@ -107,10 +106,10 @@ void Http1ServerConnectionImplTest::expect400(Protocol p, bool allow_absolute_ur max_request_headers_kb_, max_request_headers_count_); } - Http::MockStreamDecoder decoder; - Http::StreamEncoder* response_encoder = nullptr; + MockRequestDecoder decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -136,7 +135,7 @@ void Http1ServerConnectionImplTest::expectHeadersTest(Protocol p, bool allow_abs max_request_headers_kb_, max_request_headers_count_); } - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); EXPECT_CALL(decoder, decodeHeaders_(HeaderMapEqual(&expected_headers), true)).Times(1); @@ -156,16 +155,15 @@ void Http1ServerConnectionImplTest::expectTrailersTest(bool enable_trailers) { max_request_headers_kb_, max_request_headers_count_); } - StrictMock decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce( - Invoke([&](Http::StreamEncoder&, bool) -> Http::StreamDecoder& { return decoder; })); + .WillOnce(Invoke([&](ResponseEncoder&, bool) -> RequestDecoder& { return decoder; })); EXPECT_CALL(decoder, decodeHeaders_(_, false)); if (enable_trailers) { EXPECT_CALL(decoder, decodeData(_, false)).Times(AtLeast(1)); - EXPECT_CALL(decoder, decodeTrailers_).Times(1); + EXPECT_CALL(decoder, decodeTrailers_); } else { EXPECT_CALL(decoder, decodeData(_, false)).Times(AtLeast(1)); EXPECT_CALL(decoder, decodeData(_, true)); @@ -186,10 +184,9 @@ void Http1ServerConnectionImplTest::testTrailersExceedLimit(std::string trailer_ std::make_unique(connection_, store_, callbacks_, codec_settings_, max_request_headers_kb_, max_request_headers_count_); std::string exception_reason; - NiceMock decoder; + NiceMock decoder; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce( - Invoke([&](Http::StreamEncoder&, bool) -> Http::StreamDecoder& { return decoder; })); + .WillOnce(Invoke([&](ResponseEncoder&, bool) -> RequestDecoder& { return decoder; })); if (enable_trailers) { EXPECT_CALL(decoder, decodeHeaders_(_, false)); @@ -220,10 +217,10 @@ void Http1ServerConnectionImplTest::testRequestHeadersExceedLimit(std::string he initialize(); std::string exception_reason; - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -240,10 +237,10 @@ void Http1ServerConnectionImplTest::testRequestHeadersExceedLimit(std::string he void Http1ServerConnectionImplTest::testRequestHeadersAccepted(std::string header_string) { initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -259,7 +256,7 @@ TEST_F(Http1ServerConnectionImplTest, EmptyHeader) { InSequence sequence; - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); TestHeaderMapImpl expected_headers{ @@ -280,7 +277,7 @@ TEST_F(Http1ServerConnectionImplTest, IdentityEncoding) { InSequence sequence; - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); TestHeaderMapImpl expected_headers{ @@ -299,7 +296,7 @@ TEST_F(Http1ServerConnectionImplTest, ChunkedBody) { InSequence sequence; - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); TestHeaderMapImpl expected_headers{ @@ -324,7 +321,7 @@ TEST_F(Http1ServerConnectionImplTest, IdentityAndChunkedBody) { InSequence sequence; - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); Buffer::OwnedImpl buffer("POST / HTTP/1.1\r\ntransfer-encoding: " @@ -355,7 +352,7 @@ TEST_F(Http1ServerConnectionImplTest, Http10) { InSequence sequence; - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); TestHeaderMapImpl expected_headers{{":path", "/"}, {":method", "GET"}}; @@ -387,14 +384,14 @@ TEST_F(Http1ServerConnectionImplTest, Http10Absolute) { TEST_F(Http1ServerConnectionImplTest, Http10MultipleResponses) { initialize(); - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; // Send a full HTTP/1.0 request and proxy a response. { Buffer::OwnedImpl buffer( "GET /foobar HTTP/1.0\r\nHost: www.somewhere.com\r\nconnection: keep-alive\r\n\r\n"); - Http::StreamEncoder* response_encoder = nullptr; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -416,9 +413,9 @@ TEST_F(Http1ServerConnectionImplTest, Http10MultipleResponses) { {":authority", "www.somewhere.com"}, {":path", "/foobar"}, {":method", "GET"}}; Buffer::OwnedImpl buffer("GET /foobar HTTP/1.1\r\nHost: www.somewhere.com\r\n\r\n"); - Http::StreamEncoder* response_encoder = nullptr; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -479,10 +476,9 @@ TEST_F(Http1ServerConnectionImplTest, Http11InvalidTrailerPost) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - StrictMock decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce( - Invoke([&](Http::StreamEncoder&, bool) -> Http::StreamDecoder& { return decoder; })); + .WillOnce(Invoke([&](ResponseEncoder&, bool) -> RequestDecoder& { return decoder; })); EXPECT_CALL(decoder, decodeHeaders_(_, false)); EXPECT_CALL(decoder, decodeData(_, false)).Times(AtLeast(1)); @@ -551,7 +547,7 @@ TEST_F(Http1ServerConnectionImplTest, SimpleGet) { InSequence sequence; - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); TestHeaderMapImpl expected_headers{{":path", "/"}, {":method", "GET"}}; @@ -578,7 +574,7 @@ TEST_F(Http1ServerConnectionImplTest, BadRequestNoStream) { TEST_F(Http1ServerConnectionImplTest, RejectInvalidMethod) { initialize(); - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); std::string output; @@ -595,7 +591,7 @@ TEST_F(Http1ServerConnectionImplTest, BadRequestStartedStream) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); Buffer::OwnedImpl buffer("G"); @@ -611,7 +607,7 @@ TEST_F(Http1ServerConnectionImplTest, HostHeaderTranslation) { InSequence sequence; - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); TestHeaderMapImpl expected_headers{{":authority", "hello"}, {":path", "/"}, {":method", "GET"}}; @@ -633,7 +629,7 @@ TEST_F(Http1ServerConnectionImplTest, HeaderInvalidCharsRuntimeGuard) { initialize(); - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); Buffer::OwnedImpl buffer( @@ -652,10 +648,10 @@ TEST_F(Http1ServerConnectionImplTest, HeaderInvalidCharsRejection) { initialize(); - Http::MockStreamDecoder decoder; - Http::StreamEncoder* response_encoder = nullptr; + MockRequestDecoder decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -671,10 +667,10 @@ TEST_F(Http1ServerConnectionImplTest, HeaderInvalidAuthority) { initialize(); - Http::MockStreamDecoder decoder; - Http::StreamEncoder* response_encoder = nullptr; + MockRequestDecoder decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -695,7 +691,7 @@ TEST_F(Http1ServerConnectionImplTest, HeaderEmbeddedNulRejection) { InSequence sequence; - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); Buffer::OwnedImpl buffer( @@ -714,7 +710,7 @@ TEST_F(Http1ServerConnectionImplTest, HeaderMutateEmbeddedNul) { InSequence sequence; - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); Buffer::OwnedImpl buffer( @@ -736,7 +732,7 @@ TEST_F(Http1ServerConnectionImplTest, HeaderMutateEmbeddedCRLF) { InSequence sequence; - NiceMock decoder; + NiceMock decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); Buffer::OwnedImpl buffer( @@ -754,7 +750,7 @@ TEST_F(Http1ServerConnectionImplTest, CloseDuringHeadersComplete) { InSequence sequence; - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); TestHeaderMapImpl expected_headers{{"content-length", "5"}, {":path", "/"}, {":method", "POST"}}; @@ -774,7 +770,7 @@ TEST_F(Http1ServerConnectionImplTest, PostWithContentLength) { InSequence sequence; - Http::MockStreamDecoder decoder; + MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); TestHeaderMapImpl expected_headers{{"content-length", "5"}, {":path", "/"}, {":method", "POST"}}; @@ -794,10 +790,10 @@ TEST_F(Http1ServerConnectionImplTest, PostWithContentLength) { TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponse) { initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -819,10 +815,10 @@ TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponse) { TEST_F(Http1ServerConnectionImplTest, LargeHeaderResponseEncode) { initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -845,10 +841,10 @@ TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponseTrainProperHeaders) { codec_settings_.header_key_format_ = Http1Settings::HeaderKeyFormat::ProperCase; initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -869,10 +865,10 @@ TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponseTrainProperHeaders) { TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponseWith204) { initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -892,10 +888,10 @@ TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponseWith204) { TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponseWith100Then200) { initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -922,10 +918,10 @@ TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponseWith100Then200) { TEST_F(Http1ServerConnectionImplTest, MetadataTest) { initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -944,10 +940,10 @@ TEST_F(Http1ServerConnectionImplTest, MetadataTest) { TEST_F(Http1ServerConnectionImplTest, ChunkedResponse) { initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -973,10 +969,10 @@ TEST_F(Http1ServerConnectionImplTest, ChunkedResponse) { TEST_F(Http1ServerConnectionImplTest, ChunkedResponseWithTrailers) { codec_settings_.enable_trailers_ = true; initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -1005,10 +1001,10 @@ TEST_F(Http1ServerConnectionImplTest, ChunkedResponseWithTrailers) { TEST_F(Http1ServerConnectionImplTest, ContentLengthResponse) { initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -1031,10 +1027,10 @@ TEST_F(Http1ServerConnectionImplTest, ContentLengthResponse) { TEST_F(Http1ServerConnectionImplTest, HeadRequestResponse) { initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -1054,10 +1050,10 @@ TEST_F(Http1ServerConnectionImplTest, HeadRequestResponse) { TEST_F(Http1ServerConnectionImplTest, HeadChunkedRequestResponse) { initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -1077,11 +1073,11 @@ TEST_F(Http1ServerConnectionImplTest, HeadChunkedRequestResponse) { TEST_F(Http1ServerConnectionImplTest, DoubleRequest) { initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) .Times(2) - .WillRepeatedly(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillRepeatedly(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -1144,7 +1140,7 @@ TEST_F(Http1ServerConnectionImplTest, UpgradeRequest) { initialize(); InSequence sequence; - NiceMock decoder; + NiceMock decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); EXPECT_CALL(decoder, decodeHeaders_(_, false)).Times(1); @@ -1167,7 +1163,7 @@ TEST_F(Http1ServerConnectionImplTest, UpgradeRequestWithEarlyData) { initialize(); InSequence sequence; - NiceMock decoder; + NiceMock decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); Buffer::OwnedImpl expected_data("12345abcd"); @@ -1182,7 +1178,7 @@ TEST_F(Http1ServerConnectionImplTest, UpgradeRequestWithTEChunked) { initialize(); InSequence sequence; - NiceMock decoder; + NiceMock decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); // Even with T-E chunked, the data should neither be inspected for (the not @@ -1199,7 +1195,7 @@ TEST_F(Http1ServerConnectionImplTest, UpgradeRequestWithNoBody) { initialize(); InSequence sequence; - NiceMock decoder; + NiceMock decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); // Make sure we avoid the deferred_end_stream_headers_ optimization for @@ -1216,10 +1212,10 @@ TEST_F(Http1ServerConnectionImplTest, WatermarkTest) { EXPECT_CALL(connection_, bufferLimit()).Times(1).WillOnce(Return(10)); initialize(); - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -1266,8 +1262,8 @@ class Http1ClientConnectionImplTest : public testing::Test { TEST_F(Http1ClientConnectionImplTest, SimpleGet) { initialize(); - Http::MockStreamDecoder response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + MockResponseDecoder response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); @@ -1282,8 +1278,8 @@ TEST_F(Http1ClientConnectionImplTest, SimpleGetWithHeaderCasing) { initialize(); - Http::MockStreamDecoder response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + MockResponseDecoder response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); @@ -1296,8 +1292,8 @@ TEST_F(Http1ClientConnectionImplTest, SimpleGetWithHeaderCasing) { TEST_F(Http1ClientConnectionImplTest, HostHeaderTranslate) { initialize(); - Http::MockStreamDecoder response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + MockResponseDecoder response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); @@ -1310,8 +1306,8 @@ TEST_F(Http1ClientConnectionImplTest, HostHeaderTranslate) { TEST_F(Http1ClientConnectionImplTest, Reset) { initialize(); - Http::MockStreamDecoder response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + MockResponseDecoder response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); Http::MockStreamCallbacks callbacks; request_encoder.getStream().addCallbacks(callbacks); @@ -1324,8 +1320,8 @@ TEST_F(Http1ClientConnectionImplTest, Reset) { TEST_F(Http1ClientConnectionImplTest, FlowControlReadDisabledReenable) { initialize(); - Http::MockStreamDecoder response_decoder; - Http::StreamEncoder* request_encoder = &codec_->newStream(response_decoder); + MockResponseDecoder response_decoder; + Http::RequestEncoder* request_encoder = &codec_->newStream(response_decoder); std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); @@ -1372,8 +1368,8 @@ TEST_F(Http1ClientConnectionImplTest, PrematureResponse) { TEST_F(Http1ClientConnectionImplTest, EmptyBodyResponse503) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1385,8 +1381,8 @@ TEST_F(Http1ClientConnectionImplTest, EmptyBodyResponse503) { TEST_F(Http1ClientConnectionImplTest, EmptyBodyResponse200) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1398,8 +1394,8 @@ TEST_F(Http1ClientConnectionImplTest, EmptyBodyResponse200) { TEST_F(Http1ClientConnectionImplTest, HeadRequest) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "HEAD"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1411,8 +1407,8 @@ TEST_F(Http1ClientConnectionImplTest, HeadRequest) { TEST_F(Http1ClientConnectionImplTest, 204Response) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1424,8 +1420,8 @@ TEST_F(Http1ClientConnectionImplTest, 204Response) { TEST_F(Http1ClientConnectionImplTest, 100Response) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1443,10 +1439,10 @@ TEST_F(Http1ClientConnectionImplTest, 100Response) { TEST_F(Http1ClientConnectionImplTest, BadEncodeParams) { initialize(); - NiceMock response_decoder; + NiceMock response_decoder; // Need to set :method and :path - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); EXPECT_THROW(request_encoder.encodeHeaders(TestHeaderMapImpl{{":path", "/"}}, true), CodecClientException); EXPECT_THROW(request_encoder.encodeHeaders(TestHeaderMapImpl{{":method", "GET"}}, true), @@ -1456,8 +1452,8 @@ TEST_F(Http1ClientConnectionImplTest, BadEncodeParams) { TEST_F(Http1ClientConnectionImplTest, NoContentLengthResponse) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1477,8 +1473,8 @@ TEST_F(Http1ClientConnectionImplTest, NoContentLengthResponse) { TEST_F(Http1ClientConnectionImplTest, ResponseWithTrailers) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1491,8 +1487,8 @@ TEST_F(Http1ClientConnectionImplTest, ResponseWithTrailers) { TEST_F(Http1ClientConnectionImplTest, GiantPath) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{ {":method", "GET"}, {":path", "/" + std::string(16384, 'a')}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1507,8 +1503,8 @@ TEST_F(Http1ClientConnectionImplTest, UpgradeResponse) { InSequence s; - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1538,8 +1534,8 @@ TEST_F(Http1ClientConnectionImplTest, UpgradeResponseWithEarlyData) { InSequence s; - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1558,8 +1554,8 @@ TEST_F(Http1ClientConnectionImplTest, WatermarkTest) { InSequence s; - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); Http::MockStreamCallbacks stream_callbacks; request_encoder.getStream().addCallbacks(stream_callbacks); @@ -1592,8 +1588,8 @@ TEST_F(Http1ClientConnectionImplTest, HighwatermarkMultipleResponses) { InSequence s; - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); Http::MockStreamCallbacks stream_callbacks; request_encoder.getStream().addCallbacks(stream_callbacks); @@ -1659,10 +1655,10 @@ TEST_F(Http1ServerConnectionImplTest, LargeRequestHeadersSplitRejected) { initialize(); std::string exception_reason; - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -1687,10 +1683,10 @@ TEST_F(Http1ServerConnectionImplTest, ManyRequestHeadersSplitRejected) { initialize(); std::string exception_reason; - NiceMock decoder; - Http::StreamEncoder* response_encoder = nullptr; + NiceMock decoder; + Http::ResponseEncoder* response_encoder = nullptr; EXPECT_CALL(callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamEncoder& encoder, bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder = &encoder; return decoder; })); @@ -1729,8 +1725,8 @@ TEST_F(Http1ServerConnectionImplTest, ManyRequestHeadersAccepted) { TEST_F(Http1ClientConnectionImplTest, LargeResponseHeadersRejected) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1745,8 +1741,8 @@ TEST_F(Http1ClientConnectionImplTest, LargeResponseHeadersRejected) { TEST_F(Http1ClientConnectionImplTest, LargeResponseHeadersAccepted) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1762,9 +1758,9 @@ TEST_F(Http1ClientConnectionImplTest, LargeResponseHeadersAccepted) { TEST_F(Http1ClientConnectionImplTest, LargeMethodRequestEncode) { initialize(); - NiceMock response_decoder; + NiceMock response_decoder; const std::string long_method = std::string(79 * 1024, 'a'); - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", long_method}, {":path", "/"}, {":authority", "host"}}; std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); @@ -1779,9 +1775,9 @@ TEST_F(Http1ClientConnectionImplTest, LargeMethodRequestEncode) { TEST_F(Http1ClientConnectionImplTest, LargePathRequestEncode) { initialize(); - NiceMock response_decoder; + NiceMock response_decoder; const std::string long_path = std::string(79 * 1024, '/'); - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", long_path}, {":authority", "host"}}; std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); @@ -1794,8 +1790,8 @@ TEST_F(Http1ClientConnectionImplTest, LargePathRequestEncode) { TEST_F(Http1ClientConnectionImplTest, LargeHeaderRequestEncode) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); const std::string long_header_value = std::string(79 * 1024, 'a'); TestHeaderMapImpl headers{ {":method", "GET"}, {"foo", long_header_value}, {":path", "/"}, {":authority", "host"}}; @@ -1811,8 +1807,8 @@ TEST_F(Http1ClientConnectionImplTest, LargeHeaderRequestEncode) { TEST_F(Http1ClientConnectionImplTest, ManyResponseHeadersRejected) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1828,8 +1824,8 @@ TEST_F(Http1ClientConnectionImplTest, ManyResponseHeadersAccepted) { initialize(); - NiceMock response_decoder; - Http::StreamEncoder& request_encoder = codec_->newStream(response_decoder); + NiceMock response_decoder; + Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); diff --git a/test/common/http/http1/conn_pool_legacy_test.cc b/test/common/http/http1/conn_pool_legacy_test.cc index adad3d7a83..1e25075e74 100644 --- a/test/common/http/http1/conn_pool_legacy_test.cc +++ b/test/common/http/http1/conn_pool_legacy_test.cc @@ -203,14 +203,17 @@ struct ActiveTestRequest { EXPECT_CALL(callbacks_.pool_ready_, ready()); } - void startRequest() { callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); } + void startRequest() { + callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); + } Http1ConnPoolImplLegacyTest& parent_; size_t client_index_; - NiceMock outer_decoder_; + NiceMock outer_decoder_; Http::ConnectionPool::Cancellable* handle_{}; - NiceMock request_encoder_; - Http::StreamDecoder* inner_decoder_{}; + NiceMock request_encoder_; + Http::ResponseDecoder* inner_decoder_{}; ConnPoolCallbacks callbacks_; }; @@ -269,7 +272,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, VerifyTimingStats) { * Test that buffer limits are set. */ TEST_F(Http1ConnPoolImplLegacyTest, VerifyBufferLimits) { - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); EXPECT_CALL(*cluster_, perConnectionBufferLimitBytes()).WillOnce(Return(8192)); @@ -299,7 +302,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, VerifyCancelInCallback) { handle1->cancel(); })); - NiceMock outer_decoder; + NiceMock outer_decoder; // Create the first client. conn_pool_.expectClientCreate(); handle1 = conn_pool_.newStream(outer_decoder, callbacks1); @@ -346,13 +349,13 @@ TEST_F(Http1ConnPoolImplLegacyTest, MaxPendingRequests) { EXPECT_EQ(0U, cluster_->circuit_breakers_stats_.rq_pending_open_.value()); - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock outer_decoder2; + NiceMock outer_decoder2; ConnPoolCallbacks callbacks2; EXPECT_CALL(callbacks2.pool_failure_, ready()); Http::ConnectionPool::Cancellable* handle2 = conn_pool_.newStream(outer_decoder2, callbacks2); @@ -377,7 +380,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectFailure) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); @@ -457,12 +460,12 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectTimeout) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder1; + NiceMock outer_decoder1; ConnPoolCallbacks callbacks1; conn_pool_.expectClientCreate(); EXPECT_NE(nullptr, conn_pool_.newStream(outer_decoder1, callbacks1)); - NiceMock outer_decoder2; + NiceMock outer_decoder2; ConnPoolCallbacks callbacks2; EXPECT_CALL(callbacks1.pool_failure_, ready()).WillOnce(Invoke([&]() -> void { conn_pool_.expectClientCreate(); @@ -489,7 +492,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, CancelBeforeBound) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); @@ -511,14 +514,14 @@ TEST_F(Http1ConnPoolImplLegacyTest, DisconnectWhileBound) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); @@ -545,7 +548,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, MaxConnections) { EXPECT_EQ(0U, cluster_->circuit_breakers_stats_.cx_open_.value()); // Request 1 should kick off a new connection. - NiceMock outer_decoder1; + NiceMock outer_decoder1; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder1, callbacks); @@ -553,7 +556,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, MaxConnections) { EXPECT_NE(nullptr, handle); // Request 2 should not kick off a new connection. - NiceMock outer_decoder2; + NiceMock outer_decoder2; ConnPoolCallbacks callbacks2; handle = conn_pool_.newStream(outer_decoder2, callbacks2); EXPECT_EQ(1U, cluster_->stats_.upstream_cx_overflow_.value()); @@ -562,8 +565,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, MaxConnections) { EXPECT_NE(nullptr, handle); // Connect event will bind to request 1. - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); @@ -576,12 +579,14 @@ TEST_F(Http1ConnPoolImplLegacyTest, MaxConnections) { .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks2.pool_ready_, ready()); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); Http::HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); conn_pool_.expectAndRunUpstreamReady(); - callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); @@ -601,7 +606,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseWithoutHeader) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder1; + NiceMock outer_decoder1; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder1, callbacks); @@ -609,7 +614,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseWithoutHeader) { EXPECT_NE(nullptr, handle); // Request 2 should not kick off a new connection. - NiceMock outer_decoder2; + NiceMock outer_decoder2; ConnPoolCallbacks callbacks2; handle = conn_pool_.newStream(outer_decoder2, callbacks2); EXPECT_EQ(1U, cluster_->stats_.upstream_cx_overflow_.value()); @@ -617,8 +622,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseWithoutHeader) { EXPECT_NE(nullptr, handle); // Connect event will bind to request 1. - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); @@ -628,7 +633,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseWithoutHeader) { // Finishing request 1 will schedule binding the connection to request 2. conn_pool_.expectEnableUpstreamReady(); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); Http::HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); @@ -645,7 +651,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseWithoutHeader) { EXPECT_CALL(callbacks2.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); @@ -663,21 +670,22 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseHeader) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -696,21 +704,22 @@ TEST_F(Http1ConnPoolImplLegacyTest, ProxyConnectionCloseHeader) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Response with 'proxy-connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -729,21 +738,22 @@ TEST_F(Http1ConnPoolImplLegacyTest, Http10NoConnectionKeepAlive) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(Protocol::Http10); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Response without 'connection: keep-alive' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -764,21 +774,22 @@ TEST_F(Http1ConnPoolImplLegacyTest, MaxRequestsPerConnection) { cluster_->max_requests_per_connection_ = 1; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -849,7 +860,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, DrainWhileConnecting) { InSequence s; ReadyWatcher drained; - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); @@ -869,23 +880,24 @@ TEST_F(Http1ConnPoolImplLegacyTest, DrainWhileConnecting) { TEST_F(Http1ConnPoolImplLegacyTest, RemoteCloseToCompleteResponse) { InSequence s; - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].connect_timer_, disableTimer()); EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); - inner_decoder->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, false); + inner_decoder->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); Buffer::OwnedImpl dummy_data("12345"); inner_decoder->decodeData(dummy_data, false); diff --git a/test/common/http/http1/conn_pool_test.cc b/test/common/http/http1/conn_pool_test.cc index e06808ca71..ddc8ddeb12 100644 --- a/test/common/http/http1/conn_pool_test.cc +++ b/test/common/http/http1/conn_pool_test.cc @@ -202,14 +202,17 @@ struct ActiveTestRequest { EXPECT_CALL(callbacks_.pool_ready_, ready()); } - void startRequest() { callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); } + void startRequest() { + callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); + } Http1ConnPoolImplTest& parent_; size_t client_index_; - NiceMock outer_decoder_; + NiceMock outer_decoder_; Http::ConnectionPool::Cancellable* handle_{}; - NiceMock request_encoder_; - Http::StreamDecoder* inner_decoder_{}; + NiceMock request_encoder_; + Http::ResponseDecoder* inner_decoder_{}; ConnPoolCallbacks callbacks_; }; @@ -266,7 +269,7 @@ TEST_F(Http1ConnPoolImplTest, VerifyTimingStats) { * Test that buffer limits are set. */ TEST_F(Http1ConnPoolImplTest, VerifyBufferLimits) { - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); EXPECT_CALL(*cluster_, perConnectionBufferLimitBytes()).WillOnce(Return(8192)); @@ -296,7 +299,7 @@ TEST_F(Http1ConnPoolImplTest, VerifyCancelInCallback) { handle1->cancel(); })); - NiceMock outer_decoder; + NiceMock outer_decoder; // Create the first client. conn_pool_.expectClientCreate(); handle1 = conn_pool_.newStream(outer_decoder, callbacks1); @@ -343,13 +346,13 @@ TEST_F(Http1ConnPoolImplTest, MaxPendingRequests) { EXPECT_EQ(0U, cluster_->circuit_breakers_stats_.rq_pending_open_.value()); - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock outer_decoder2; + NiceMock outer_decoder2; ConnPoolCallbacks callbacks2; EXPECT_CALL(callbacks2.pool_failure_, ready()); Http::ConnectionPool::Cancellable* handle2 = conn_pool_.newStream(outer_decoder2, callbacks2); @@ -374,7 +377,7 @@ TEST_F(Http1ConnPoolImplTest, ConnectFailure) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); @@ -454,12 +457,12 @@ TEST_F(Http1ConnPoolImplTest, ConnectTimeout) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder1; + NiceMock outer_decoder1; ConnPoolCallbacks callbacks1; conn_pool_.expectClientCreate(); EXPECT_NE(nullptr, conn_pool_.newStream(outer_decoder1, callbacks1)); - NiceMock outer_decoder2; + NiceMock outer_decoder2; ConnPoolCallbacks callbacks2; EXPECT_CALL(callbacks1.pool_failure_, ready()).WillOnce(Invoke([&]() -> void { conn_pool_.expectClientCreate(); @@ -486,7 +489,7 @@ TEST_F(Http1ConnPoolImplTest, CancelBeforeBound) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); @@ -508,14 +511,14 @@ TEST_F(Http1ConnPoolImplTest, DisconnectWhileBound) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); @@ -542,7 +545,7 @@ TEST_F(Http1ConnPoolImplTest, MaxConnections) { EXPECT_EQ(0U, cluster_->circuit_breakers_stats_.cx_open_.value()); // Request 1 should kick off a new connection. - NiceMock outer_decoder1; + NiceMock outer_decoder1; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder1, callbacks); @@ -550,7 +553,7 @@ TEST_F(Http1ConnPoolImplTest, MaxConnections) { EXPECT_NE(nullptr, handle); // Request 2 should not kick off a new connection. - NiceMock outer_decoder2; + NiceMock outer_decoder2; ConnPoolCallbacks callbacks2; handle = conn_pool_.newStream(outer_decoder2, callbacks2); EXPECT_EQ(1U, cluster_->stats_.upstream_cx_overflow_.value()); @@ -559,8 +562,8 @@ TEST_F(Http1ConnPoolImplTest, MaxConnections) { EXPECT_NE(nullptr, handle); // Connect event will bind to request 1. - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); @@ -573,12 +576,14 @@ TEST_F(Http1ConnPoolImplTest, MaxConnections) { .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks2.pool_ready_, ready()); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); Http::HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); conn_pool_.expectAndRunUpstreamReady(); - callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); @@ -598,7 +603,7 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseWithoutHeader) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder1; + NiceMock outer_decoder1; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder1, callbacks); @@ -606,7 +611,7 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseWithoutHeader) { EXPECT_NE(nullptr, handle); // Request 2 should not kick off a new connection. - NiceMock outer_decoder2; + NiceMock outer_decoder2; ConnPoolCallbacks callbacks2; handle = conn_pool_.newStream(outer_decoder2, callbacks2); EXPECT_EQ(1U, cluster_->stats_.upstream_cx_overflow_.value()); @@ -614,8 +619,8 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseWithoutHeader) { EXPECT_NE(nullptr, handle); // Connect event will bind to request 1. - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); @@ -625,7 +630,8 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseWithoutHeader) { // Finishing request 1 will schedule binding the connection to request 2. conn_pool_.expectEnableUpstreamReady(); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); Http::HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); @@ -642,7 +648,8 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseWithoutHeader) { EXPECT_CALL(callbacks2.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); @@ -660,21 +667,22 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseHeader) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -693,21 +701,22 @@ TEST_F(Http1ConnPoolImplTest, ProxyConnectionCloseHeader) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Response with 'proxy-connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -726,21 +735,22 @@ TEST_F(Http1ConnPoolImplTest, Http10NoConnectionKeepAlive) { InSequence s; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(Protocol::Http10); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Response without 'connection: keep-alive' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -761,21 +771,22 @@ TEST_F(Http1ConnPoolImplTest, MaxRequestsPerConnection) { cluster_->max_requests_per_connection_ = 1; // Request 1 should kick off a new connection. - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -846,7 +857,7 @@ TEST_F(Http1ConnPoolImplTest, DrainWhileConnecting) { InSequence s; ReadyWatcher drained; - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); @@ -865,23 +876,24 @@ TEST_F(Http1ConnPoolImplTest, DrainWhileConnecting) { TEST_F(Http1ConnPoolImplTest, RemoteCloseToCompleteResponse) { InSequence s; - NiceMock outer_decoder; + NiceMock outer_decoder; ConnPoolCallbacks callbacks; conn_pool_.expectClientCreate(); Http::ConnectionPool::Cancellable* handle = conn_pool_.newStream(outer_decoder, callbacks); EXPECT_NE(nullptr, handle); - NiceMock request_encoder; - Http::StreamDecoder* inner_decoder; + NiceMock request_encoder; + ResponseDecoder* inner_decoder; EXPECT_CALL(*conn_pool_.test_clients_[0].codec_, newStream(_)) .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks.pool_ready_, ready()); EXPECT_CALL(*conn_pool_.test_clients_[0].connect_timer_, disableTimer()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); - inner_decoder->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, false); + inner_decoder->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); Buffer::OwnedImpl dummy_data("12345"); inner_decoder->decodeData(dummy_data, false); diff --git a/test/common/http/http2/codec_impl_test.cc b/test/common/http/http2/codec_impl_test.cc index 85e95250da..9c049d2734 100644 --- a/test/common/http/http2/codec_impl_test.cc +++ b/test/common/http/http2/codec_impl_test.cc @@ -75,7 +75,7 @@ class Http2CodecImplTestFixture { setupDefaultConnectionMocks(); EXPECT_CALL(server_callbacks_, newStream(_, _)) - .WillRepeatedly(Invoke([&](StreamEncoder& encoder, bool) -> StreamDecoder& { + .WillRepeatedly(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder_ = &encoder; encoder.getStream().addCallbacks(server_stream_callbacks_); return request_decoder_; @@ -146,10 +146,10 @@ class Http2CodecImplTestFixture { MockServerConnectionCallbacks server_callbacks_; std::unique_ptr server_; ConnectionWrapper server_wrapper_; - MockStreamDecoder response_decoder_; - StreamEncoder* request_encoder_; - MockStreamDecoder request_decoder_; - StreamEncoder* response_encoder_{}; + MockResponseDecoder response_decoder_; + RequestEncoder* request_encoder_; + MockRequestDecoder request_decoder_; + ResponseEncoder* response_encoder_{}; MockStreamCallbacks server_stream_callbacks_; // Corrupt a metadata frame payload. bool corrupt_metadata_frame_ = false; @@ -741,16 +741,16 @@ TEST_P(Http2CodecImplFlowControlTest, TestFlowControlInPendingSendData) { // Now create a second stream on the connection. MockStreamDecoder response_decoder2; - StreamEncoder* request_encoder2 = &client_->newStream(response_decoder_); + RequestEncoder* request_encoder2 = &client_->newStream(response_decoder_); StreamEncoder* response_encoder2; MockStreamCallbacks server_stream_callbacks2; - MockStreamDecoder request_decoder2; + MockRequestDecoder request_decoder2; // When the server stream is created it should check the status of the // underlying connection. Pretend it is overrun. EXPECT_CALL(server_connection_, aboveHighWatermark()).WillOnce(Return(true)); EXPECT_CALL(server_stream_callbacks2, onAboveWriteBufferHighWatermark()); EXPECT_CALL(server_callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](StreamEncoder& encoder, bool) -> StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder2 = &encoder; encoder.getStream().addCallbacks(server_stream_callbacks2); return request_decoder2; @@ -937,7 +937,7 @@ TEST_P(Http2CodecImplStreamLimitTest, MaxClientStreams) { request_encoder_ = &client_->newStream(response_decoder_); setupDefaultConnectionMocks(); EXPECT_CALL(server_callbacks_, newStream(_, _)) - .WillOnce(Invoke([&](StreamEncoder& encoder, bool) -> StreamDecoder& { + .WillOnce(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { response_encoder_ = &encoder; encoder.getStream().addCallbacks(server_stream_callbacks_); return request_decoder_; diff --git a/test/common/http/http2/conn_pool_legacy_test.cc b/test/common/http/http2/conn_pool_legacy_test.cc index ffc5339e9d..1521d5d9e6 100644 --- a/test/common/http/http2/conn_pool_legacy_test.cc +++ b/test/common/http/http2/conn_pool_legacy_test.cc @@ -152,10 +152,10 @@ class ActiveTestRequest { } } - Http::MockStreamDecoder decoder_; + MockResponseDecoder decoder_; ConnPoolCallbacks callbacks_; - Http::StreamDecoder* inner_decoder_{}; - NiceMock inner_encoder_; + ResponseDecoder* inner_decoder_{}; + NiceMock inner_encoder_; }; void Http2ConnPoolImplLegacyTest::expectClientConnect(size_t index, ActiveTestRequest& r) { @@ -188,9 +188,10 @@ void Http2ConnPoolImplLegacyTest::closeClient(size_t index) { void Http2ConnPoolImplLegacyTest::completeRequest(ActiveTestRequest& r) { EXPECT_CALL(r.inner_encoder_, encodeHeaders(_, true)); - r.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r.decoder_, decodeHeaders_(_, true)); - r.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); } void Http2ConnPoolImplLegacyTest::completeRequestCloseUpstream(size_t index, ActiveTestRequest& r) { @@ -217,13 +218,15 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainConnections) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // This will move primary to draining and destroy draining. pool_.drainConnections(); @@ -256,13 +259,16 @@ TEST_F(Http2ConnPoolImplLegacyTest, PendingRequests) { // Send a request through each stream. EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r3.inner_encoder_, encodeHeaders(_, true)); - r3.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r3.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Since we now have an active connection, subsequent requests should connect immediately. ActiveTestRequest r4(*this, 0, true); @@ -362,7 +368,7 @@ TEST_F(Http2ConnPoolImplLegacyTest, PendingRequestsMaxPendingCircuitBreaker) { expectClientCreate(); ActiveTestRequest r1(*this, 0, false); - Http::MockStreamDecoder decoder; + MockResponseDecoder decoder; ConnPoolCallbacks callbacks; EXPECT_CALL(callbacks.pool_failure_, ready()); EXPECT_EQ(nullptr, pool_.newStream(decoder, callbacks)); @@ -391,9 +397,10 @@ TEST_F(Http2ConnPoolImplLegacyTest, VerifyConnectionTimingStats) { deliverHistogramToSinks(Property(&Stats::Metric::name, "upstream_cx_connect_ms"), _)); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -415,9 +422,10 @@ TEST_F(Http2ConnPoolImplLegacyTest, VerifyBufferLimits) { expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -434,15 +442,17 @@ TEST_F(Http2ConnPoolImplLegacyTest, RequestAndResponse) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); ActiveTestRequest r2(*this, 0, true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -459,7 +469,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, LocalReset) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, false)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, false); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + false); r1.callbacks_.outer_encoder_->getStream().resetStream(Http::StreamResetReason::LocalReset); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -478,7 +489,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, RemoteReset) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, false)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, false); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + false); r1.inner_encoder_.stream_.resetStream(Http::StreamResetReason::RemoteReset); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -498,7 +510,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainDisconnectWithActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); @@ -521,20 +534,22 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainDisconnectDrainingWithActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); @@ -556,27 +571,29 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainPrimary) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(drained, ready()); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); @@ -590,9 +607,10 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainPrimaryNoActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(dispatcher_, deferredDelete_(_)); expectClientCreate(); @@ -601,9 +619,10 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainPrimaryNoActiveRequest) { EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); ReadyWatcher drained; EXPECT_CALL(dispatcher_, deferredDelete_(_)); @@ -633,9 +652,10 @@ TEST_F(Http2ConnPoolImplLegacyTest, ConnectTimeout) { ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); test_clients_[1].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -658,10 +678,11 @@ TEST_F(Http2ConnPoolImplLegacyTest, MaxGlobalRequests) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); ConnPoolCallbacks callbacks; - Http::MockStreamDecoder decoder; + MockResponseDecoder decoder; EXPECT_CALL(callbacks.pool_failure_, ready()); EXPECT_EQ(nullptr, pool_.newStream(decoder, callbacks)); @@ -680,9 +701,10 @@ TEST_F(Http2ConnPoolImplLegacyTest, GoAway) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].codec_client_->raiseGoAway(); @@ -690,9 +712,10 @@ TEST_F(Http2ConnPoolImplLegacyTest, GoAway) { ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); test_clients_[1].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index 55386371c0..f6de88d185 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -152,10 +152,10 @@ class ActiveTestRequest { } } - Http::MockStreamDecoder decoder_; + MockResponseDecoder decoder_; ConnPoolCallbacks callbacks_; - Http::StreamDecoder* inner_decoder_{}; - NiceMock inner_encoder_; + ResponseDecoder* inner_decoder_{}; + NiceMock inner_encoder_; ConnectionPool::Cancellable* handle_{}; }; @@ -189,9 +189,10 @@ void Http2ConnPoolImplTest::closeClient(size_t index) { void Http2ConnPoolImplTest::completeRequest(ActiveTestRequest& r) { EXPECT_CALL(r.inner_encoder_, encodeHeaders(_, true)); - r.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r.decoder_, decodeHeaders_(_, true)); - r.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); } void Http2ConnPoolImplTest::completeRequestCloseUpstream(size_t index, ActiveTestRequest& r) { @@ -230,13 +231,14 @@ TEST_F(Http2ConnPoolImplTest, DrainConnectionReadyWithRequest) { ActiveTestRequest r(*this, 0, false); expectClientConnect(0, r); EXPECT_CALL(r.inner_encoder_, encodeHeaders(_, true)); - r.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); pool_.drainConnections(); EXPECT_CALL(r.decoder_, decodeHeaders_(_, true)); EXPECT_CALL(*this, onClientDestroy()); - r.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); } /** @@ -251,13 +253,14 @@ TEST_F(Http2ConnPoolImplTest, DrainConnectionBusy) { ActiveTestRequest r(*this, 0, false); expectClientConnect(0, r); EXPECT_CALL(r.inner_encoder_, encodeHeaders(_, true)); - r.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); pool_.drainConnections(); EXPECT_CALL(r.decoder_, decodeHeaders_(_, true)); EXPECT_CALL(*this, onClientDestroy()); - r.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); } /** @@ -296,7 +299,8 @@ TEST_F(Http2ConnPoolImplTest, DrainConnections) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // With max_streams == 1, the second request moves the first connection // to draining. @@ -304,7 +308,8 @@ TEST_F(Http2ConnPoolImplTest, DrainConnections) { ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // This will move the second connection to draining. pool_.drainConnections(); @@ -389,13 +394,16 @@ TEST_F(Http2ConnPoolImplTest, PendingRequests) { // Send a request through each stream. EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r3.inner_encoder_, encodeHeaders(_, true)); - r3.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r3.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Since we now have an active connection, subsequent requests should connect immediately. ActiveTestRequest r4(*this, 0, true); @@ -430,13 +438,16 @@ TEST_F(Http2ConnPoolImplTest, PendingRequestsNumberConnectingTotalRequestsPerCon // Send a request through each stream. EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r3.inner_encoder_, encodeHeaders(_, true)); - r3.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r3.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Clean up everything. test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -466,13 +477,16 @@ TEST_F(Http2ConnPoolImplTest, PendingRequestsNumberConnectingConcurrentRequestsP // Send a request through each stream. EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r3.inner_encoder_, encodeHeaders(_, true)); - r3.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r3.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); // Clean up everything. test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -567,7 +581,7 @@ TEST_F(Http2ConnPoolImplTest, PendingRequestsMaxPendingCircuitBreaker) { expectClientCreate(); ActiveTestRequest r1(*this, 0, false); - Http::MockStreamDecoder decoder; + MockResponseDecoder decoder; ConnPoolCallbacks callbacks; EXPECT_CALL(callbacks.pool_failure_, ready()); EXPECT_EQ(nullptr, pool_.newStream(decoder, callbacks)); @@ -596,9 +610,10 @@ TEST_F(Http2ConnPoolImplTest, VerifyConnectionTimingStats) { deliverHistogramToSinks(Property(&Stats::Metric::name, "upstream_cx_connect_ms"), _)); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(cluster_->stats_store_, deliverHistogramToSinks(Property(&Stats::Metric::name, "upstream_cx_length_ms"), _)); @@ -620,9 +635,10 @@ TEST_F(Http2ConnPoolImplTest, VerifyBufferLimits) { expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -639,16 +655,18 @@ TEST_F(Http2ConnPoolImplTest, RequestAndResponse) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_EQ(1U, cluster_->stats_.upstream_cx_active_.value()); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); ActiveTestRequest r2(*this, 0, true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -666,7 +684,8 @@ TEST_F(Http2ConnPoolImplTest, LocalReset) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, false)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, false); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + false); r1.callbacks_.outer_encoder_->getStream().resetStream(Http::StreamResetReason::LocalReset); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -686,7 +705,8 @@ TEST_F(Http2ConnPoolImplTest, RemoteReset) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, false)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, false); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + false); r1.inner_encoder_.stream_.resetStream(Http::StreamResetReason::RemoteReset); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -707,7 +727,8 @@ TEST_F(Http2ConnPoolImplTest, DrainDisconnectWithActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); @@ -732,20 +753,22 @@ TEST_F(Http2ConnPoolImplTest, DrainDisconnectDrainingWithActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); @@ -769,27 +792,29 @@ TEST_F(Http2ConnPoolImplTest, DrainPrimary) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(drained, ready()); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); @@ -805,10 +830,11 @@ TEST_F(Http2ConnPoolImplTest, DrainPrimaryNoActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); @@ -816,10 +842,11 @@ TEST_F(Http2ConnPoolImplTest, DrainPrimaryNoActiveRequest) { EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); ReadyWatcher drained; EXPECT_CALL(drained, ready()); @@ -848,9 +875,10 @@ TEST_F(Http2ConnPoolImplTest, ConnectTimeout) { ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); test_clients_[1].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -873,10 +901,11 @@ TEST_F(Http2ConnPoolImplTest, MaxGlobalRequests) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); ConnPoolCallbacks callbacks; - Http::MockStreamDecoder decoder; + MockResponseDecoder decoder; EXPECT_CALL(callbacks.pool_failure_, ready()); EXPECT_EQ(nullptr, pool_.newStream(decoder, callbacks)); @@ -895,9 +924,10 @@ TEST_F(Http2ConnPoolImplTest, GoAway) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].codec_client_->raiseGoAway(); @@ -905,9 +935,10 @@ TEST_F(Http2ConnPoolImplTest, GoAway) { ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(HeaderMapImpl{}, true); + r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, + true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new HeaderMapImpl{}}, true); + r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); test_clients_[1].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); diff --git a/test/common/http/http2/frame_replay.cc b/test/common/http/http2/frame_replay.cc index e7f846954a..fb6d5f9468 100644 --- a/test/common/http/http2/frame_replay.cc +++ b/test/common/http/http2/frame_replay.cc @@ -78,7 +78,7 @@ ClientCodecFrameInjector::ClientCodecFrameInjector() : CodecFrameInjector("serve ServerCodecFrameInjector::ServerCodecFrameInjector() : CodecFrameInjector("client") { EXPECT_CALL(server_callbacks_, newStream(_, _)) - .WillRepeatedly(Invoke([&](StreamEncoder& encoder, bool) -> StreamDecoder& { + .WillRepeatedly(Invoke([&](ResponseEncoder& encoder, bool) -> RequestDecoder& { encoder.getStream().addCallbacks(server_stream_callbacks_); return request_decoder_; })); diff --git a/test/common/http/http2/frame_replay.h b/test/common/http/http2/frame_replay.h index 4ab12bd93a..afa9c6014e 100644 --- a/test/common/http/http2/frame_replay.h +++ b/test/common/http/http2/frame_replay.h @@ -68,8 +68,8 @@ class ClientCodecFrameInjector : public CodecFrameInjector { ::testing::NiceMock client_connection_; MockConnectionCallbacks client_callbacks_; - MockStreamDecoder response_decoder_; - StreamEncoder* request_encoder_; + MockResponseDecoder response_decoder_; + RequestEncoder* request_encoder_; MockStreamCallbacks client_stream_callbacks_; }; @@ -81,7 +81,7 @@ class ServerCodecFrameInjector : public CodecFrameInjector { ::testing::NiceMock server_connection_; MockServerConnectionCallbacks server_callbacks_; - MockStreamDecoder request_decoder_; + MockRequestDecoder request_decoder_; MockStreamCallbacks server_stream_callbacks_; }; diff --git a/test/common/router/router_test.cc b/test/common/router/router_test.cc index 7f90c3af15..5dea1a9452 100644 --- a/test/common/router/router_test.cc +++ b/test/common/router/router_test.cc @@ -209,7 +209,7 @@ class RouterTestBase : public testing::Test { } EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) .WillOnce(Invoke( - [&](Http::StreamDecoder& decoder, + [&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { response_decoder_ = &decoder; EXPECT_CALL(callbacks_.dispatcher_, setTrackedObject(_)).Times(testing::AtLeast(2)); @@ -272,10 +272,10 @@ class RouterTestBase : public testing::Test { Event::MockTimer* per_try_timeout_{}; Network::Address::InstanceConstSharedPtr host_address_{ Network::Utility::resolveUrl("tcp://10.0.0.5:9211")}; - NiceMock original_encoder_; - NiceMock second_encoder_; + NiceMock original_encoder_; + NiceMock second_encoder_; NiceMock connection_; - Http::StreamDecoder* response_decoder_ = nullptr; + Http::ResponseDecoder* response_decoder_ = nullptr; Http::TestHeaderMapImpl default_request_headers_{}; Http::HeaderMapPtr redirect_headers_{ new Http::TestHeaderMapImpl{{":status", "302"}, {"location", "http://www.foo.com"}}}; @@ -499,16 +499,17 @@ TEST_F(RouterTest, HashKeyNoHashPolicy) { TEST_F(RouterTest, AddCookie) { ON_CALL(callbacks_.route_->route_entry_, hashPolicy()) .WillByDefault(Return(&callbacks_.route_->route_entry_.hash_policy_)); - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return &cancellable_; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return &cancellable_; + })); EXPECT_CALL(cm_, httpConnPoolForCluster(_, _, _, _)) .WillOnce( @@ -548,16 +549,17 @@ TEST_F(RouterTest, AddCookie) { TEST_F(RouterTest, AddCookieNoDuplicate) { ON_CALL(callbacks_.route_->route_entry_, hashPolicy()) .WillByDefault(Return(&callbacks_.route_->route_entry_.hash_policy_)); - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return &cancellable_; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return &cancellable_; + })); EXPECT_CALL(cm_, httpConnPoolForCluster(_, _, _, _)) .WillOnce( @@ -595,16 +597,17 @@ TEST_F(RouterTest, AddCookieNoDuplicate) { TEST_F(RouterTest, AddMultipleCookies) { ON_CALL(callbacks_.route_->route_entry_, hashPolicy()) .WillByDefault(Return(&callbacks_.route_->route_entry_.hash_policy_)); - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return &cancellable_; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return &cancellable_; + })); EXPECT_CALL(cm_, httpConnPoolForCluster(_, _, _, _)) .WillOnce( @@ -780,15 +783,16 @@ TEST_F(RouterTestSuppressEnvoyHeaders, MaintenanceMode) { } TEST_F(RouterTest, ResponseCodeDetailsSetByUpstream) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers; @@ -805,15 +809,16 @@ TEST_F(RouterTest, ResponseCodeDetailsSetByUpstream) { // Validate that x-envoy-upstream-service-time is added on a regular // request/response path. TEST_F(RouterTest, EnvoyUpstreamServiceTime) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers; @@ -844,15 +849,16 @@ void RouterTestBase::testAppendCluster(absl::optional clu StreamInfo::FilterState::StateType::ReadOnly, StreamInfo::FilterState::LifeSpan::FilterChain); - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers; @@ -897,15 +903,16 @@ void RouterTestBase::testAppendUpstreamHost( StreamInfo::FilterState::LifeSpan::FilterChain); cm_.conn_pool_.host_->hostname_ = "scooby.doo"; - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers; @@ -1020,15 +1027,16 @@ TEST_F(RouterTest, AllDebugConfig) { // TODO(htuch): Probably should be TEST_P with // RouterTest.EnvoyUpstreamServiceTime, this is getting verbose.. TEST_F(RouterTestSuppressEnvoyHeaders, EnvoyUpstreamServiceTime) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers; @@ -1048,15 +1056,16 @@ TEST_F(RouterTestSuppressEnvoyHeaders, EnvoyUpstreamServiceTime) { } TEST_F(RouterTest, NoRetriesOverflow) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; @@ -1072,14 +1081,15 @@ TEST_F(RouterTest, NoRetriesOverflow) { // We expect the 5xx response to kick off a new request. EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); - NiceMock encoder2; + NiceMock encoder2; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); router_.retry_state_->callback_(); // RetryOverflow kicks in. @@ -1094,15 +1104,16 @@ TEST_F(RouterTest, NoRetriesOverflow) { } TEST_F(RouterTest, ResetDuringEncodeHeaders) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(callbacks_, removeDownstreamWatermarkCallbacks(_)); EXPECT_CALL(callbacks_, addDownstreamWatermarkCallbacks(_)); @@ -1124,15 +1135,16 @@ TEST_F(RouterTest, ResetDuringEncodeHeaders) { } TEST_F(RouterTest, UpstreamTimeout) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(callbacks_.stream_info_, onUpstreamHostSelected(_)) .WillOnce(Invoke([&](const Upstream::HostDescriptionConstSharedPtr host) -> void { EXPECT_EQ(host_address_, host->address()); @@ -1168,15 +1180,16 @@ TEST_F(RouterTest, UpstreamTimeout) { // Verify the timeout budget histograms are filled out correctly when using a // global and per-try timeout in a successful request. TEST_F(RouterTest, TimeoutBudgetHistogramStat) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); expectResponseTimerCreate(); @@ -1207,15 +1220,16 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStat) { // Verify the timeout budget histograms are filled out correctly when using a // global and per-try timeout in a failed request. TEST_F(RouterTest, TimeoutBudgetHistogramStatFailure) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); expectResponseTimerCreate(); @@ -1245,15 +1259,16 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatFailure) { // Verify the timeout budget histograms are filled out correctly when only using a global timeout. TEST_F(RouterTest, TimeoutBudgetHistogramStatOnlyGlobal) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "200"}}; @@ -1281,15 +1296,16 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatOnlyGlobal) { // Verify the timeout budget histograms are filled out correctly across retries. TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringRetries) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder1 = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder1 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder1 = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder1 = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); expectResponseTimerCreate(); @@ -1322,15 +1338,16 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringRetries) { // We expect the 5xx response to kick off a new request. EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); - NiceMock encoder2; - Http::StreamDecoder* response_decoder2 = nullptr; + NiceMock encoder2; + Http::ResponseDecoder* response_decoder2 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder2 = &decoder; - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder2 = &decoder; + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); router_.retry_state_->callback_(); @@ -1369,15 +1386,16 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringRetries) { // Verify the timeout budget histograms are filled out correctly when the global timeout occurs // during a retry. TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringGlobalTimeout) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder1 = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder1 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder1 = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder1 = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); expectResponseTimerCreate(); @@ -1410,15 +1428,16 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringGlobalTimeout) { // We expect the 5xx response to kick off a new request. EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); - NiceMock encoder2; - Http::StreamDecoder* response_decoder2 = nullptr; + NiceMock encoder2; + Http::ResponseDecoder* response_decoder2 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder2 = &decoder; - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder2 = &decoder; + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); router_.retry_state_->callback_(); @@ -1457,15 +1476,16 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringGlobalTimeout) { // Validate gRPC OK response stats are sane when response is trailers only. TEST_F(RouterTest, GrpcOkTrailersOnly) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; @@ -1481,15 +1501,16 @@ TEST_F(RouterTest, GrpcOkTrailersOnly) { // Validate gRPC AlreadyExists response stats are sane when response is trailers only. TEST_F(RouterTest, GrpcAlreadyExistsTrailersOnly) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; @@ -1505,15 +1526,16 @@ TEST_F(RouterTest, GrpcAlreadyExistsTrailersOnly) { // Validate gRPC Unavailable response stats are sane when response is trailers only. TEST_F(RouterTest, GrpcOutlierDetectionUnavailableStatusCode) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; @@ -1530,15 +1552,16 @@ TEST_F(RouterTest, GrpcOutlierDetectionUnavailableStatusCode) { // Validate gRPC Internal response stats are sane when response is trailers only. TEST_F(RouterTest, GrpcInternalTrailersOnly) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; @@ -1555,15 +1578,16 @@ TEST_F(RouterTest, GrpcInternalTrailersOnly) { // Validate gRPC response stats are sane when response is ended in a DATA // frame. TEST_F(RouterTest, GrpcDataEndStream) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; @@ -1582,15 +1606,16 @@ TEST_F(RouterTest, GrpcDataEndStream) { // Validate gRPC response stats are sane when response is reset after initial // response HEADERS. TEST_F(RouterTest, GrpcReset) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; @@ -1610,15 +1635,16 @@ TEST_F(RouterTest, GrpcReset) { // Validate gRPC OK response stats are sane when response is not trailers only. TEST_F(RouterTest, GrpcOk) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; @@ -1639,15 +1665,16 @@ TEST_F(RouterTest, GrpcOk) { // Validate gRPC Internal response stats are sane when response is not trailers only. TEST_F(RouterTest, GrpcInternal) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; @@ -1664,15 +1691,16 @@ TEST_F(RouterTest, GrpcInternal) { } TEST_F(RouterTest, UpstreamTimeoutWithAltResponse) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(callbacks_.stream_info_, onUpstreamHostSelected(_)) .WillOnce(Invoke([&](const Upstream::HostDescriptionConstSharedPtr host) -> void { EXPECT_EQ(host_address_, host->address()); @@ -1707,15 +1735,16 @@ TEST_F(RouterTest, UpstreamTimeoutWithAltResponse) { // Verifies that the per try timeout is initialized once the downstream request has been read. TEST_F(RouterTest, UpstreamPerTryTimeout) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(callbacks_.stream_info_, onUpstreamHostSelected(_)) .WillOnce(Invoke([&](const Upstream::HostDescriptionConstSharedPtr host) -> void { EXPECT_EQ(host_address_, host->address()); @@ -1756,16 +1785,17 @@ TEST_F(RouterTest, UpstreamPerTryTimeout) { // Verifies that the per try timeout starts when onPoolReady is called when it occurs // after the downstream request has been read. TEST_F(RouterTest, UpstreamPerTryTimeoutDelayedPoolReady) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; Http::ConnectionPool::Callbacks* pool_callbacks; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - pool_callbacks = &callbacks; - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + pool_callbacks = &callbacks; + return nullptr; + })); Http::TestHeaderMapImpl headers{{"x-envoy-internal", "true"}, {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; @@ -1807,17 +1837,18 @@ TEST_F(RouterTest, UpstreamPerTryTimeoutDelayedPoolReady) { // Ensures that the per try callback is not set until the stream becomes available. TEST_F(RouterTest, UpstreamPerTryTimeoutExcludesNewStream) { InSequence s; - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; Http::ConnectionPool::Callbacks* pool_callbacks; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - pool_callbacks = &callbacks; - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + pool_callbacks = &callbacks; + return nullptr; + })); response_timeout_ = new Event::MockTimer(&callbacks_.dispatcher_); EXPECT_CALL(*response_timeout_, enableTimer(_, _)); @@ -1865,16 +1896,17 @@ TEST_F(RouterTest, UpstreamPerTryTimeoutExcludesNewStream) { TEST_F(RouterTest, HedgedPerTryTimeoutFirstRequestSucceeds) { enableHedgeOnPerTryTimeout(); - NiceMock encoder1; - Http::StreamDecoder* response_decoder1 = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder1 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder1 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder1 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, absl::optional(absl::nullopt))) @@ -1890,19 +1922,20 @@ TEST_F(RouterTest, HedgedPerTryTimeoutFirstRequestSucceeds) { cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginTimeout, absl::optional(504))); EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); - NiceMock encoder2; - Http::StreamDecoder* response_decoder2 = nullptr; + NiceMock encoder2; + Http::ResponseDecoder* response_decoder2 = nullptr; router_.retry_state_->expectHedgedPerTryTimeoutRetry(); per_try_timeout_->invokeCallback(); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder2 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder2 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); router_.retry_state_->callback_(); @@ -1938,16 +1971,17 @@ TEST_F(RouterTest, HedgedPerTryTimeoutFirstRequestSucceeds) { TEST_F(RouterTest, HedgedPerTryTimeoutResetsOnBadHeaders) { enableHedgeOnPerTryTimeout(); - NiceMock encoder1; - Http::StreamDecoder* response_decoder1 = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder1 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder1 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder1 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, absl::optional(absl::nullopt))) @@ -1963,19 +1997,20 @@ TEST_F(RouterTest, HedgedPerTryTimeoutResetsOnBadHeaders) { cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginTimeout, absl::optional(504))); EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); - NiceMock encoder2; - Http::StreamDecoder* response_decoder2 = nullptr; + NiceMock encoder2; + Http::ResponseDecoder* response_decoder2 = nullptr; router_.retry_state_->expectHedgedPerTryTimeoutRetry(); per_try_timeout_->invokeCallback(); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder2 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder2 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); router_.retry_state_->callback_(); @@ -2016,16 +2051,17 @@ TEST_F(RouterTest, HedgedPerTryTimeoutResetsOnBadHeaders) { TEST_F(RouterTest, HedgedPerTryTimeoutThirdRequestSucceeds) { enableHedgeOnPerTryTimeout(); - NiceMock encoder1; - Http::StreamDecoder* response_decoder1 = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder1 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder1 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder1 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); expectPerTryTimerCreate(); @@ -2047,16 +2083,17 @@ TEST_F(RouterTest, HedgedPerTryTimeoutThirdRequestSucceeds) { router_.retry_state_->expectHeadersRetry(); response_decoder1->decodeHeaders(std::move(response_headers1), true); - NiceMock encoder2; - Http::StreamDecoder* response_decoder2 = nullptr; + NiceMock encoder2; + Http::ResponseDecoder* response_decoder2 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder2 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder2 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); router_.retry_state_->callback_(); @@ -2067,16 +2104,17 @@ TEST_F(RouterTest, HedgedPerTryTimeoutThirdRequestSucceeds) { EXPECT_CALL( cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginTimeout, absl::optional(504))); - NiceMock encoder3; - Http::StreamDecoder* response_decoder3 = nullptr; + NiceMock encoder3; + Http::ResponseDecoder* response_decoder3 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder3 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder3, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder3 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder3, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(callbacks_, encodeHeaders_(_, _)).Times(0); per_try_timeout_->invokeCallback(); @@ -2109,16 +2147,17 @@ TEST_F(RouterTest, HedgedPerTryTimeoutThirdRequestSucceeds) { TEST_F(RouterTest, RetryOnlyOnceForSameUpstreamRequest) { enableHedgeOnPerTryTimeout(); - NiceMock encoder1; - Http::StreamDecoder* response_decoder1 = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder1 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder1 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder1 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, absl::optional(absl::nullopt))) @@ -2138,16 +2177,17 @@ TEST_F(RouterTest, RetryOnlyOnceForSameUpstreamRequest) { router_.retry_state_->expectHedgedPerTryTimeoutRetry(); per_try_timeout_->invokeCallback(); - NiceMock encoder2; - Http::StreamDecoder* response_decoder2 = nullptr; + NiceMock encoder2; + Http::ResponseDecoder* response_decoder2 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder2 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder2 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); router_.retry_state_->callback_(); @@ -2173,16 +2213,17 @@ TEST_F(RouterTest, RetryOnlyOnceForSameUpstreamRequest) { TEST_F(RouterTest, BadHeadersDroppedIfPreviousRetryScheduled) { enableHedgeOnPerTryTimeout(); - NiceMock encoder1; - Http::StreamDecoder* response_decoder1 = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder1 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder1 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder1 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, absl::optional(absl::nullopt))) @@ -2214,16 +2255,17 @@ TEST_F(RouterTest, BadHeadersDroppedIfPreviousRetryScheduled) { response_decoder1->decodeHeaders(std::move(response_headers1), true); // Now trigger the retry for the per try timeout earlier. - NiceMock encoder2; - Http::StreamDecoder* response_decoder2 = nullptr; + NiceMock encoder2; + Http::ResponseDecoder* response_decoder2 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder2 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder2 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); router_.retry_state_->callback_(); Http::HeaderMapPtr response_headers2(new Http::TestHeaderMapImpl{{":status", "200"}}); @@ -2238,15 +2280,16 @@ TEST_F(RouterTest, BadHeadersDroppedIfPreviousRetryScheduled) { } TEST_F(RouterTest, RetryRequestNotComplete) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::UpstreamRemoteReset)); EXPECT_CALL(callbacks_.stream_info_, onUpstreamHostSelected(_)) @@ -2271,16 +2314,17 @@ TEST_F(RouterTest, RetryRequestNotComplete) { TEST_F(RouterTest, HedgedPerTryTimeoutGlobalTimeout) { enableHedgeOnPerTryTimeout(); - NiceMock encoder1; - Http::StreamDecoder* response_decoder1 = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder1 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder1 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder1 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, absl::optional(absl::nullopt))) @@ -2300,16 +2344,17 @@ TEST_F(RouterTest, HedgedPerTryTimeoutGlobalTimeout) { router_.retry_state_->expectHedgedPerTryTimeoutRetry(); per_try_timeout_->invokeCallback(); - NiceMock encoder2; - Http::StreamDecoder* response_decoder2 = nullptr; + NiceMock encoder2; + Http::ResponseDecoder* response_decoder2 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder2 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder2 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); router_.retry_state_->callback_(); @@ -2337,16 +2382,17 @@ TEST_F(RouterTest, HedgedPerTryTimeoutGlobalTimeout) { TEST_F(RouterTest, HedgingRetriesExhaustedBadResponse) { enableHedgeOnPerTryTimeout(); - NiceMock encoder1; - Http::StreamDecoder* response_decoder1 = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder1 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder1 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder1 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, absl::optional(absl::nullopt))) @@ -2366,16 +2412,17 @@ TEST_F(RouterTest, HedgingRetriesExhaustedBadResponse) { router_.retry_state_->expectHedgedPerTryTimeoutRetry(); per_try_timeout_->invokeCallback(); - NiceMock encoder2; - Http::StreamDecoder* response_decoder2 = nullptr; + NiceMock encoder2; + Http::ResponseDecoder* response_decoder2 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder2 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder2 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, absl::optional(absl::nullopt))) @@ -2417,16 +2464,17 @@ TEST_F(RouterTest, HedgingRetriesExhaustedBadResponse) { TEST_F(RouterTest, HedgingRetriesProceedAfterReset) { enableHedgeOnPerTryTimeout(); - NiceMock encoder1; - Http::StreamDecoder* response_decoder1 = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder1 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder1 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder1 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); // First is reset EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginConnectFailed, _)) @@ -2450,16 +2498,17 @@ TEST_F(RouterTest, HedgingRetriesProceedAfterReset) { router_.retry_state_->expectHedgedPerTryTimeoutRetry(); per_try_timeout_->invokeCallback(); - NiceMock encoder2; - Http::StreamDecoder* response_decoder2 = nullptr; + NiceMock encoder2; + Http::ResponseDecoder* response_decoder2 = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder2 = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder2 = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); router_.retry_state_->callback_(); @@ -2496,16 +2545,17 @@ TEST_F(RouterTest, HedgingRetriesProceedAfterReset) { TEST_F(RouterTest, HedgingRetryImmediatelyReset) { enableHedgeOnPerTryTimeout(); - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, absl::optional(absl::nullopt))) @@ -2530,7 +2580,7 @@ TEST_F(RouterTest, HedgingRetryImmediatelyReset) { EXPECT_CALL(callbacks_, encodeHeaders_(_, _)).Times(0); per_try_timeout_->invokeCallback(); - NiceMock encoder2; + NiceMock encoder2; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) .WillOnce(Invoke([&](Http::StreamDecoder&, Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { @@ -2565,15 +2615,16 @@ TEST_F(RouterTest, HedgingRetryImmediatelyReset) { } TEST_F(RouterTest, RetryNoneHealthy) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); EXPECT_CALL(callbacks_.stream_info_, onUpstreamHostSelected(_)) @@ -2602,15 +2653,16 @@ TEST_F(RouterTest, RetryNoneHealthy) { } TEST_F(RouterTest, RetryUpstreamReset) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; @@ -2627,17 +2679,18 @@ TEST_F(RouterTest, RetryUpstreamReset) { encoder1.stream_.resetStream(Http::StreamResetReason::RemoteReset); // We expect this reset to kick off a new request. - NiceMock encoder2; + NiceMock encoder2; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, - putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, - absl::optional(absl::nullopt))); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, + putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, + absl::optional(absl::nullopt))); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); router_.retry_state_->callback_(); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -2650,15 +2703,16 @@ TEST_F(RouterTest, RetryUpstreamReset) { } TEST_F(RouterTest, NoRetryWithBodyLimit) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); // Set a per route body limit which disallows any buffering. EXPECT_CALL(callbacks_.route_->route_entry_, retryShadowBufferLimit()).WillOnce(Return(0)); @@ -2679,16 +2733,17 @@ TEST_F(RouterTest, NoRetryWithBodyLimit) { // before an upstream host has been established, then the onHostAttempted function will not be // invoked. This ensures that we're not passing a null host to the retry plugins. TEST_F(RouterTest, RetryUpstreamPerTryTimeout) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); expectResponseTimerCreate(); @@ -2705,18 +2760,19 @@ TEST_F(RouterTest, RetryUpstreamPerTryTimeout) { EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // We expect this reset to kick off a new request. - NiceMock encoder2; + NiceMock encoder2; EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, - putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, - absl::optional(absl::nullopt))); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, + putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, + absl::optional(absl::nullopt))); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); router_.retry_state_->callback_(); @@ -2751,17 +2807,18 @@ TEST_F(RouterTest, RetryUpstreamConnectionFailure) { conn_pool_callbacks->onPoolFailure(Http::ConnectionPool::PoolFailureReason::ConnectionFailure, absl::string_view(), nullptr); - Http::StreamDecoder* response_decoder = nullptr; + Http::ResponseDecoder* response_decoder = nullptr; // We expect this reset to kick off a new request. - NiceMock encoder2; + NiceMock encoder2; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); router_.retry_state_->callback_(); // Normal response. @@ -2773,15 +2830,16 @@ TEST_F(RouterTest, RetryUpstreamConnectionFailure) { } TEST_F(RouterTest, DontResetStartedResponseOnUpstreamPerTryTimeout) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectPerTryTimerCreate(); expectResponseTimerCreate(); @@ -2807,15 +2865,16 @@ TEST_F(RouterTest, DontResetStartedResponseOnUpstreamPerTryTimeout) { } TEST_F(RouterTest, RetryUpstreamResetResponseStarted) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; @@ -2839,15 +2898,16 @@ TEST_F(RouterTest, RetryUpstreamResetResponseStarted) { } TEST_F(RouterTest, RetryUpstreamReset100ContinueResponseStarted) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; @@ -2868,17 +2928,18 @@ TEST_F(RouterTest, RetryUpstreamReset100ContinueResponseStarted) { putResult(Upstream::Outlier::Result::LocalOriginConnectFailed, _)); encoder1.stream_.resetStream(Http::StreamResetReason::RemoteReset); } - -TEST_F(RouterTest, RetryUpstream5xx) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; - EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + +TEST_F(RouterTest, RetryUpstream5xx) { + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; + EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; @@ -2894,14 +2955,15 @@ TEST_F(RouterTest, RetryUpstream5xx) { // We expect the 5xx response to kick off a new request. EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); - NiceMock encoder2; + NiceMock encoder2; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); router_.retry_state_->callback_(); // Normal response. @@ -2914,15 +2976,16 @@ TEST_F(RouterTest, RetryUpstream5xx) { } TEST_F(RouterTest, RetryTimeoutDuringRetryDelay) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; @@ -2950,15 +3013,16 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelay) { } TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHost) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; @@ -2974,7 +3038,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHost) { Http::ConnectionPool::MockCancellable cancellable; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, + .WillOnce(Invoke([&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks&) -> Http::ConnectionPool::Cancellable* { response_decoder = &decoder; return &cancellable; @@ -2997,15 +3061,16 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHost) { // Retry timeout during a retry delay leading to no upstream host, as well as an alt response code. TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHostAltResponseCode) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, @@ -3023,7 +3088,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHostAltRespo Http::ConnectionPool::MockCancellable cancellable; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, + .WillOnce(Invoke([&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks&) -> Http::ConnectionPool::Cancellable* { response_decoder = &decoder; return &cancellable; @@ -3043,15 +3108,16 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHostAltRespo } TEST_F(RouterTest, RetryUpstream5xxNotComplete) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; @@ -3075,14 +3141,15 @@ TEST_F(RouterTest, RetryUpstream5xxNotComplete) { EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // We expect the 5xx response to kick off a new request. - NiceMock encoder2; + NiceMock encoder2; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); ON_CALL(callbacks_, decodingBuffer()).WillByDefault(Return(body_data.get())); EXPECT_CALL(encoder2, encodeHeaders(_, false)); EXPECT_CALL(encoder2, encodeData(_, false)); @@ -3115,15 +3182,16 @@ TEST_F(RouterTest, RetryUpstream5xxNotComplete) { // Validate gRPC Cancelled response stats are sane when retry is taking effect. TEST_F(RouterTest, RetryUpstreamGrpcCancelled) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-grpc-on", "cancelled"}, @@ -3143,14 +3211,15 @@ TEST_F(RouterTest, RetryUpstreamGrpcCancelled) { // We expect the grpc-status to result in a retried request. EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); - NiceMock encoder2; + NiceMock encoder2; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); router_.retry_state_->callback_(); // Normal response. @@ -3167,15 +3236,16 @@ TEST_F(RouterTest, RetryUpstreamGrpcCancelled) { TEST_F(RouterTest, RetryRespsectsMaxHostSelectionCount) { router_.reject_all_hosts_ = true; - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; @@ -3203,14 +3273,15 @@ TEST_F(RouterTest, RetryRespsectsMaxHostSelectionCount) { EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // We expect the 5xx response to kick off a new request. - NiceMock encoder2; + NiceMock encoder2; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); ON_CALL(callbacks_, decodingBuffer()).WillByDefault(Return(body_data.get())); EXPECT_CALL(encoder2, encodeHeaders(_, false)); EXPECT_CALL(encoder2, encodeData(_, false)); @@ -3234,15 +3305,16 @@ TEST_F(RouterTest, RetryRespsectsMaxHostSelectionCount) { TEST_F(RouterTest, RetryRespectsRetryHostPredicate) { router_.reject_all_hosts_ = true; - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; @@ -3270,14 +3342,15 @@ TEST_F(RouterTest, RetryRespectsRetryHostPredicate) { EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // We expect the 5xx response to kick off a new request. - NiceMock encoder2; + NiceMock encoder2; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); ON_CALL(callbacks_, decodingBuffer()).WillByDefault(Return(body_data.get())); EXPECT_CALL(encoder2, encodeHeaders(_, false)); EXPECT_CALL(encoder2, encodeData(_, false)); @@ -3443,15 +3516,16 @@ TEST_F(RouterTest, Shadow) { callbacks_.route_->route_entry_.shadow_policies_.push_back(std::move(policy)); ON_CALL(callbacks_, streamId()).WillByDefault(Return(43)); - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); EXPECT_CALL(runtime_.snapshot_, featureEnabled("bar", 0, 43, 10000)).WillOnce(Return(true)); @@ -3494,15 +3568,16 @@ TEST_F(RouterTest, AltStatName) { .WillOnce(Return(std::chrono::milliseconds(0))); EXPECT_CALL(callbacks_.dispatcher_, createTimer_(_)).Times(0); - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); Http::TestHeaderMapImpl headers{{"x-envoy-upstream-alt-stat-name", "alt_stat"}, {"x-envoy-internal", "true"}}; @@ -3663,8 +3738,8 @@ TEST_F(RouterTest, DirectResponseWithoutLocation) { } TEST_F(RouterTest, UpstreamSSLConnection) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; std::string session_id = "D62A523A65695219D46FE1FFE285A4C371425ACE421B110B5B8D11D3EB4D5F0B"; auto connection_info = std::make_shared>(); @@ -3673,12 +3748,13 @@ TEST_F(RouterTest, UpstreamSSLConnection) { expectResponseTimerCreate(); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); Http::TestHeaderMapImpl headers{}; HttpTestUtility::addDefaultHeaders(headers); @@ -3695,15 +3771,16 @@ TEST_F(RouterTest, UpstreamSSLConnection) { // Verify that upstream timing information is set into the StreamInfo after the upstream // request completes. TEST_F(RouterTest, UpstreamTimingSingleRequest) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); StreamInfo::StreamInfoImpl stream_info(test_time_.timeSystem()); @@ -3752,15 +3829,16 @@ TEST_F(RouterTest, UpstreamTimingSingleRequest) { // Verify that upstream timing information is set into the StreamInfo when a // retry occurs (and not before). TEST_F(RouterTest, UpstreamTimingRetry) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); StreamInfo::StreamInfoImpl stream_info(test_time_); @@ -3780,12 +3858,13 @@ TEST_F(RouterTest, UpstreamTimingRetry) { test_time_.sleep(std::chrono::milliseconds(43)); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); // Check that upstream timing is not set when a retry will occur. Http::HeaderMapPtr bad_response_headers(new Http::TestHeaderMapImpl{{":status", "503"}}); @@ -3832,15 +3911,16 @@ TEST_F(RouterTest, UpstreamTimingRetry) { // Verify that upstream timing information is set into the StreamInfo when a // global timeout occurs. TEST_F(RouterTest, UpstreamTimingTimeout) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); StreamInfo::StreamInfoImpl stream_info(test_time_); ON_CALL(callbacks_, streamInfo()).WillByDefault(ReturnRef(stream_info)); @@ -4375,15 +4455,16 @@ TEST_F(RouterTest, CanaryStatusTrue) { .WillOnce(Return(std::chrono::milliseconds(0))); EXPECT_CALL(callbacks_.dispatcher_, createTimer_(_)).Times(0); - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); Http::TestHeaderMapImpl headers{{"x-envoy-upstream-alt-stat-name", "alt_stat"}, {"x-envoy-internal", "true"}}; @@ -4408,15 +4489,16 @@ TEST_F(RouterTest, CanaryStatusFalse) { .WillOnce(Return(std::chrono::milliseconds(0))); EXPECT_CALL(callbacks_.dispatcher_, createTimer_(_)).Times(0); - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); Http::TestHeaderMapImpl headers{{"x-envoy-upstream-alt-stat-name", "alt_stat"}, {"x-envoy-internal", "true"}}; @@ -4436,7 +4518,7 @@ TEST_F(RouterTest, CanaryStatusFalse) { } TEST_F(RouterTest, AutoHostRewriteEnabled) { - NiceMock encoder; + NiceMock encoder; std::string req_host{"foo.bar.com"}; Http::TestHeaderMapImpl incoming_headers; @@ -4474,7 +4556,7 @@ TEST_F(RouterTest, AutoHostRewriteEnabled) { } TEST_F(RouterTest, AutoHostRewriteDisabled) { - NiceMock encoder; + NiceMock encoder; std::string req_host{"foo.bar.com"}; Http::TestHeaderMapImpl incoming_headers; @@ -4574,7 +4656,7 @@ class WatermarkTest : public RouterTest { EXPECT_CALL(encoder_, getStream()).WillRepeatedly(ReturnRef(stream_)); EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) .WillOnce(Invoke( - [&](Http::StreamDecoder& decoder, + [&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { response_decoder_ = &decoder; pool_callbacks_ = &callbacks; @@ -4591,10 +4673,10 @@ class WatermarkTest : public RouterTest { Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}}, true); } - NiceMock encoder_; + NiceMock encoder_; NiceMock stream_; Http::StreamCallbacks* stream_callbacks_; - Http::StreamDecoder* response_decoder_ = nullptr; + Http::ResponseDecoder* response_decoder_ = nullptr; Http::TestHeaderMapImpl headers_; Http::ConnectionPool::Callbacks* pool_callbacks_{nullptr}; }; @@ -4683,11 +4765,11 @@ TEST_F(WatermarkTest, FilterWatermarks) { TEST_F(WatermarkTest, RetryRequestNotComplete) { EXPECT_CALL(callbacks_, decoderBufferLimit()).Times(2).WillRepeatedly(Return(10)); router_.setDecoderFilterCallbacks(callbacks_); - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) .WillRepeatedly(Invoke( - [&](Http::StreamDecoder& decoder, + [&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { response_decoder = &decoder; callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); @@ -4729,17 +4811,18 @@ TEST_F(RouterTestChildSpan, BasicFlow) { .WillOnce(Return(std::chrono::milliseconds(0))); EXPECT_CALL(callbacks_.dispatcher_, createTimer_(_)).Times(0); - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; Tracing::MockSpan* child_span{new Tracing::MockSpan()}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - EXPECT_CALL(*child_span, injectContext(_)); - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + EXPECT_CALL(*child_span, injectContext(_)); + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); Http::TestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); @@ -4768,17 +4851,18 @@ TEST_F(RouterTestChildSpan, ResetFlow) { .WillOnce(Return(std::chrono::milliseconds(0))); EXPECT_CALL(callbacks_.dispatcher_, createTimer_(_)).Times(0); - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; Tracing::MockSpan* child_span{new Tracing::MockSpan()}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - EXPECT_CALL(*child_span, injectContext(_)); - callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + EXPECT_CALL(*child_span, injectContext(_)); + callbacks.onPoolReady(encoder, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); Http::TestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); @@ -4814,7 +4898,7 @@ TEST_F(RouterTestChildSpan, CancelFlow) { .WillOnce(Return(std::chrono::milliseconds(0))); EXPECT_CALL(callbacks_.dispatcher_, createTimer_(_)).Times(0); - NiceMock encoder; + NiceMock encoder; Tracing::MockSpan* child_span{new Tracing::MockSpan()}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) .WillOnce(Invoke([&](Http::StreamDecoder&, Http::ConnectionPool::Callbacks& callbacks) @@ -4851,17 +4935,18 @@ TEST_F(RouterTestChildSpan, CancelFlow) { // The first request will fail because of an upstream reset, so the span will be annotated with the // reset reason. The second request will succeed, so the span will be annotated with 200 OK. TEST_F(RouterTestChildSpan, ResetRetryFlow) { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; Tracing::MockSpan* child_span_1{new Tracing::MockSpan()}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - EXPECT_CALL(*child_span_1, injectContext(_)); - callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + EXPECT_CALL(*child_span_1, injectContext(_)); + callbacks.onPoolReady(encoder1, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); expectResponseTimerCreate(); // Upstream responds back to envoy simulating an upstream reset. @@ -4889,17 +4974,18 @@ TEST_F(RouterTestChildSpan, ResetRetryFlow) { encoder1.stream_.resetStream(Http::StreamResetReason::RemoteReset); // We expect this reset to kick off a new request. - NiceMock encoder2; + NiceMock encoder2; Tracing::MockSpan* child_span_2{new Tracing::MockSpan()}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) - .WillOnce(Invoke([&](Http::StreamDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) - -> Http::ConnectionPool::Cancellable* { - response_decoder = &decoder; - EXPECT_CALL(*child_span_2, injectContext(_)); - EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); - callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); - return nullptr; - })); + .WillOnce(Invoke( + [&](Http::ResponseDecoder& decoder, + Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { + response_decoder = &decoder; + EXPECT_CALL(*child_span_2, injectContext(_)); + EXPECT_CALL(*router_.retry_state_, onHostAttempted(_)); + callbacks.onPoolReady(encoder2, cm_.conn_pool_.host_, upstream_stream_info_); + return nullptr; + })); EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router fake_cluster egress", _)) .WillOnce(Return(child_span_2)); diff --git a/test/common/router/router_upstream_log_test.cc b/test/common/router/router_upstream_log_test.cc index 4fa5414671..ad40d7c9be 100644 --- a/test/common/router/router_upstream_log_test.cc +++ b/test/common/router/router_upstream_log_test.cc @@ -125,12 +125,12 @@ class RouterUpstreamLogTest : public testing::Test { const std::initializer_list>& request_headers_init, const std::initializer_list>& response_headers_init, const std::initializer_list>& response_trailers_init) { - NiceMock encoder; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(context_.cluster_manager_.conn_pool_, newStream(_, _)) .WillOnce(Invoke( - [&](Http::StreamDecoder& decoder, + [&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { response_decoder = &decoder; EXPECT_CALL(encoder.stream_, connectionLocalAddress()) @@ -161,12 +161,12 @@ class RouterUpstreamLogTest : public testing::Test { void run() { run(200, {}, {}, {}); } void runWithRetry() { - NiceMock encoder1; - Http::StreamDecoder* response_decoder = nullptr; + NiceMock encoder1; + Http::ResponseDecoder* response_decoder = nullptr; EXPECT_CALL(context_.cluster_manager_.conn_pool_, newStream(_, _)) .WillOnce(Invoke( - [&](Http::StreamDecoder& decoder, + [&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { response_decoder = &decoder; EXPECT_CALL(encoder1.stream_, connectionLocalAddress()) @@ -190,10 +190,10 @@ class RouterUpstreamLogTest : public testing::Test { per_try_timeout_->invokeCallback(); // We expect this reset to kick off a new request. - NiceMock encoder2; + NiceMock encoder2; EXPECT_CALL(context_.cluster_manager_.conn_pool_, newStream(_, _)) .WillOnce(Invoke( - [&](Http::StreamDecoder& decoder, + [&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* { response_decoder = &decoder; EXPECT_CALL(context_.cluster_manager_.conn_pool_.host_->outlier_detector_, diff --git a/test/common/upstream/health_checker_impl_test.cc b/test/common/upstream/health_checker_impl_test.cc index 00476d1f22..0ea1169811 100644 --- a/test/common/upstream/health_checker_impl_test.cc +++ b/test/common/upstream/health_checker_impl_test.cc @@ -117,8 +117,8 @@ class HttpHealthCheckerImplTest : public testing::Test { Http::MockClientConnection* codec_{}; Stats::IsolatedStoreImpl stats_store_; Network::MockClientConnection* client_connection_{}; - NiceMock request_encoder_; - Http::StreamDecoder* stream_response_callbacks_{}; + NiceMock request_encoder_; + Http::ResponseDecoder* stream_response_callbacks_{}; }; using TestSessionPtr = std::unique_ptr; @@ -3375,8 +3375,8 @@ class GrpcHealthCheckerImplTestBase { Http::MockClientConnection* codec_{}; Stats::IsolatedStoreImpl stats_store_; Network::MockClientConnection* client_connection_{}; - NiceMock request_encoder_; - Http::StreamDecoder* stream_response_callbacks_{}; + NiceMock request_encoder_; + Http::ResponseDecoder* stream_response_callbacks_{}; CodecClientForTest* codec_client_{}; }; diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc index 6b24baec21..463ca86cf2 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc @@ -138,7 +138,7 @@ class EnvoyQuicClientSessionTest : public testing::TestWithParam { } } - EnvoyQuicClientStream& sendGetRequest(Http::StreamDecoder& response_decoder, + EnvoyQuicClientStream& sendGetRequest(Http::ResponseDecoder& response_decoder, Http::StreamCallbacks& stream_callbacks) { auto& stream = dynamic_cast(http_connection_.newStream(response_decoder)); @@ -178,7 +178,7 @@ INSTANTIATE_TEST_SUITE_P(EnvoyQuicClientSessionTests, EnvoyQuicClientSessionTest testing::ValuesIn({true, false})); TEST_P(EnvoyQuicClientSessionTest, NewStream) { - Http::MockStreamDecoder response_decoder; + Http::MockResponseDecoder response_decoder; Http::MockStreamCallbacks stream_callbacks; EnvoyQuicClientStream& stream = sendGetRequest(response_decoder, stream_callbacks); @@ -195,7 +195,7 @@ TEST_P(EnvoyQuicClientSessionTest, NewStream) { } TEST_P(EnvoyQuicClientSessionTest, OnResetFrame) { - Http::MockStreamDecoder response_decoder; + Http::MockResponseDecoder response_decoder; Http::MockStreamCallbacks stream_callbacks; EnvoyQuicClientStream& stream = sendGetRequest(response_decoder, stream_callbacks); @@ -220,7 +220,7 @@ TEST_P(EnvoyQuicClientSessionTest, ConnectionClose) { } TEST_P(EnvoyQuicClientSessionTest, ConnectionCloseWithActiveStream) { - Http::MockStreamDecoder response_decoder; + Http::MockResponseDecoder response_decoder; Http::MockStreamCallbacks stream_callbacks; EnvoyQuicClientStream& stream = sendGetRequest(response_decoder, stream_callbacks); EXPECT_CALL(*quic_connection_, diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc index 10fa5fd7f9..308147e78c 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc @@ -42,7 +42,7 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { stream_id_(quic_version_.transport_version == quic::QUIC_VERSION_99 ? 4u : 5u), quic_stream_(new EnvoyQuicClientStream(stream_id_, &quic_session_, quic::BIDIRECTIONAL)), request_headers_{{":authority", host_}, {":method", "POST"}, {":path", "/"}} { - quic_stream_->setDecoder(stream_decoder_); + quic_stream_->setResponseDecoder(stream_decoder_); quic_stream_->addCallbacks(stream_callbacks_); quic_session_.ActivateStream(std::unique_ptr(quic_stream_)); EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _)) @@ -96,7 +96,7 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { MockEnvoyQuicClientSession quic_session_; quic::QuicStreamId stream_id_; EnvoyQuicClientStream* quic_stream_; - Http::MockStreamDecoder stream_decoder_; + Http::MockResponseDecoder stream_decoder_; Http::MockStreamCallbacks stream_callbacks_; std::string host_{"www.abc.com"}; Http::TestHeaderMapImpl request_headers_; diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc index 93c0e414de..ee7e0d4414 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc @@ -155,11 +155,11 @@ class EnvoyQuicServerSessionTest : public testing::TestWithParam { return envoy_quic_session_.initializeReadFilters(); } - quic::QuicStream* createNewStream(Http::MockStreamDecoder& request_decoder, + quic::QuicStream* createNewStream(Http::MockRequestDecoder& request_decoder, Http::MockStreamCallbacks& stream_callbacks) { EXPECT_CALL(http_connection_callbacks_, newStream(_, false)) - .WillOnce(Invoke([&request_decoder, &stream_callbacks](Http::StreamEncoder& encoder, - bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&request_decoder, &stream_callbacks](Http::ResponseEncoder& encoder, + bool) -> Http::RequestDecoder& { encoder.getStream().addCallbacks(stream_callbacks); return request_decoder; })); @@ -212,7 +212,7 @@ INSTANTIATE_TEST_SUITE_P(EnvoyQuicServerSessionTests, EnvoyQuicServerSessionTest TEST_P(EnvoyQuicServerSessionTest, NewStream) { installReadFilter(); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; EXPECT_CALL(http_connection_callbacks_, newStream(_, false)) .WillOnce(testing::ReturnRef(request_decoder)); quic::QuicStreamId stream_id = @@ -241,7 +241,7 @@ TEST_P(EnvoyQuicServerSessionTest, NewStream) { TEST_P(EnvoyQuicServerSessionTest, InvalidIncomingStreamId) { quic::SetVerbosityLogThreshold(1); installReadFilter(); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; // IETF stream 5 and G-Quic stream 2 are server initiated. quic::QuicStreamId stream_id = @@ -258,7 +258,7 @@ TEST_P(EnvoyQuicServerSessionTest, InvalidIncomingStreamId) { TEST_P(EnvoyQuicServerSessionTest, NoNewStreamForInvalidIncomingStream) { installReadFilter(); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; // IETF stream 5 and G-Quic stream 2 are server initiated. quic::QuicStreamId stream_id = @@ -274,7 +274,7 @@ TEST_P(EnvoyQuicServerSessionTest, NoNewStreamForInvalidIncomingStream) { TEST_P(EnvoyQuicServerSessionTest, OnResetFrame) { installReadFilter(); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; quic::QuicStream* stream1 = createNewStream(request_decoder, stream_callbacks); quic::QuicRstStreamFrame rst1(/*control_frame_id=*/1u, stream1->id(), @@ -291,8 +291,8 @@ TEST_P(EnvoyQuicServerSessionTest, OnResetFrame) { stream1->OnStreamReset(rst1); EXPECT_CALL(http_connection_callbacks_, newStream(_, false)) - .WillOnce(Invoke([&request_decoder, &stream_callbacks](Http::StreamEncoder& encoder, - bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&request_decoder, &stream_callbacks](Http::ResponseEncoder& encoder, + bool) -> Http::RequestDecoder& { encoder.getStream().addCallbacks(stream_callbacks); return request_decoder; })); @@ -321,7 +321,7 @@ TEST_P(EnvoyQuicServerSessionTest, ConnectionClose) { TEST_P(EnvoyQuicServerSessionTest, ConnectionCloseWithActiveStream) { installReadFilter(); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; quic::QuicStream* stream = createNewStream(request_decoder, stream_callbacks); EXPECT_CALL(*quic_connection_, @@ -336,7 +336,7 @@ TEST_P(EnvoyQuicServerSessionTest, ConnectionCloseWithActiveStream) { TEST_P(EnvoyQuicServerSessionTest, NoFlushWithDataToWrite) { installReadFilter(); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; quic::QuicStream* stream = createNewStream(request_decoder, stream_callbacks); envoy_quic_session_.MarkConnectionLevelWriteBlocked(stream->id()); @@ -353,7 +353,7 @@ TEST_P(EnvoyQuicServerSessionTest, NoFlushWithDataToWrite) { TEST_P(EnvoyQuicServerSessionTest, FlushCloseWithDataToWrite) { installReadFilter(); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; quic::QuicStream* stream = createNewStream(request_decoder, stream_callbacks); @@ -403,7 +403,7 @@ TEST_P(EnvoyQuicServerSessionTest, WriteUpdatesDelayCloseTimer) { 10 * quic::kDefaultFlowControlSendWindow); envoy_quic_session_.setDelayedCloseTimeout(std::chrono::milliseconds(100)); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; // Create a stream and write enough data to make it blocked. auto stream = @@ -498,7 +498,7 @@ TEST_P(EnvoyQuicServerSessionTest, FlushCloseNoTimeout) { envoy_quic_session_.flow_controller()->UpdateSendWindowOffset( 10 * quic::kDefaultFlowControlSendWindow); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; // Create a stream and write enough data to make it blocked. auto stream = @@ -562,7 +562,7 @@ TEST_P(EnvoyQuicServerSessionTest, FlushCloseNoTimeout) { TEST_P(EnvoyQuicServerSessionTest, FlushCloseWithTimeout) { installReadFilter(); envoy_quic_session_.setDelayedCloseTimeout(std::chrono::milliseconds(100)); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; quic::QuicStream* stream = createNewStream(request_decoder, stream_callbacks); @@ -592,7 +592,7 @@ TEST_P(EnvoyQuicServerSessionTest, FlushCloseWithTimeout) { TEST_P(EnvoyQuicServerSessionTest, FlushAndWaitForCloseWithTimeout) { installReadFilter(); envoy_quic_session_.setDelayedCloseTimeout(std::chrono::milliseconds(100)); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; quic::QuicStream* stream = createNewStream(request_decoder, stream_callbacks); @@ -624,7 +624,7 @@ TEST_P(EnvoyQuicServerSessionTest, FlushAndWaitForCloseWithTimeout) { TEST_P(EnvoyQuicServerSessionTest, FlusWriteTransitToFlushWriteWithDelay) { installReadFilter(); envoy_quic_session_.setDelayedCloseTimeout(std::chrono::milliseconds(100)); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; quic::QuicStream* stream = createNewStream(request_decoder, stream_callbacks); @@ -788,11 +788,11 @@ TEST_P(EnvoyQuicServerSessionTest, SendBufferWatermark) { envoy_quic_session_.flow_controller()->UpdateSendWindowOffset( 10 * quic::kDefaultFlowControlSendWindow); installReadFilter(); - Http::MockStreamDecoder request_decoder; + Http::MockRequestDecoder request_decoder; Http::MockStreamCallbacks stream_callbacks; EXPECT_CALL(http_connection_callbacks_, newStream(_, false)) - .WillOnce(Invoke([&request_decoder, &stream_callbacks](Http::StreamEncoder& encoder, - bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&request_decoder, &stream_callbacks](Http::ResponseEncoder& encoder, + bool) -> Http::RequestDecoder& { encoder.getStream().addCallbacks(stream_callbacks); return request_decoder; })); @@ -833,11 +833,11 @@ TEST_P(EnvoyQuicServerSessionTest, SendBufferWatermark) { // Receive another request and send back response to trigger connection level // send buffer watermark. - Http::MockStreamDecoder request_decoder2; + Http::MockRequestDecoder request_decoder2; Http::MockStreamCallbacks stream_callbacks2; EXPECT_CALL(http_connection_callbacks_, newStream(_, false)) - .WillOnce(Invoke([&request_decoder2, &stream_callbacks2](Http::StreamEncoder& encoder, - bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&request_decoder2, &stream_callbacks2](Http::ResponseEncoder& encoder, + bool) -> Http::RequestDecoder& { encoder.getStream().addCallbacks(stream_callbacks2); return request_decoder2; })); @@ -864,11 +864,11 @@ TEST_P(EnvoyQuicServerSessionTest, SendBufferWatermark) { // Receive another request, the new stream should be notified about connection // high watermark reached upon creation. - Http::MockStreamDecoder request_decoder3; + Http::MockRequestDecoder request_decoder3; Http::MockStreamCallbacks stream_callbacks3; EXPECT_CALL(http_connection_callbacks_, newStream(_, false)) - .WillOnce(Invoke([&request_decoder3, &stream_callbacks3](Http::StreamEncoder& encoder, - bool) -> Http::StreamDecoder& { + .WillOnce(Invoke([&request_decoder3, &stream_callbacks3](Http::ResponseEncoder& encoder, + bool) -> Http::RequestDecoder& { encoder.getStream().addCallbacks(stream_callbacks3); return request_decoder3; })); diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc index cc5e252ef6..46eeefa6b5 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc @@ -47,7 +47,7 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { stream_id_(VersionUsesHttp3(quic_version_.transport_version) ? 4u : 5u), quic_stream_(new EnvoyQuicServerStream(stream_id_, &quic_session_, quic::BIDIRECTIONAL)), response_headers_{{":status", "200"}} { - quic_stream_->setDecoder(stream_decoder_); + quic_stream_->setRequestDecoder(stream_decoder_); quic_stream_->addCallbacks(stream_callbacks_); quic_session_.ActivateStream(std::unique_ptr(quic_stream_)); EXPECT_CALL(quic_session_, WritevData(_, _, _, _, _)) @@ -138,7 +138,7 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { MockEnvoyQuicSession quic_session_; quic::QuicStreamId stream_id_; EnvoyQuicServerStream* quic_stream_; - Http::MockStreamDecoder stream_decoder_; + Http::MockRequestDecoder stream_decoder_; Http::MockStreamCallbacks stream_callbacks_; quic::QuicHeaderList request_headers_; Http::TestHeaderMapImpl response_headers_; diff --git a/test/integration/api_listener_integration_test.cc b/test/integration/api_listener_integration_test.cc index 7328d87ea3..ee1e2d672d 100644 --- a/test/integration/api_listener_integration_test.cc +++ b/test/integration/api_listener_integration_test.cc @@ -74,7 +74,7 @@ name: api_listener )EOF"; } - NiceMock stream_encoder_; + NiceMock stream_encoder_; }; ACTION_P(Notify, notification) { notification->Notify(); } diff --git a/test/integration/autonomous_upstream.cc b/test/integration/autonomous_upstream.cc index c96cb8d23e..28abf3d2bf 100644 --- a/test/integration/autonomous_upstream.cc +++ b/test/integration/autonomous_upstream.cc @@ -20,7 +20,7 @@ const char AutonomousStream::RESPONSE_SIZE_BYTES[] = "response_size_bytes"; const char AutonomousStream::EXPECT_REQUEST_SIZE_BYTES[] = "expect_request_size_bytes"; const char AutonomousStream::RESET_AFTER_REQUEST[] = "reset_after_request"; -AutonomousStream::AutonomousStream(FakeHttpConnection& parent, Http::StreamEncoder& encoder, +AutonomousStream::AutonomousStream(FakeHttpConnection& parent, Http::ResponseEncoder& encoder, AutonomousUpstream& upstream, bool allow_incomplete_streams) : FakeStream(parent, encoder, upstream.timeSystem()), upstream_(upstream), allow_incomplete_streams_(allow_incomplete_streams) {} @@ -69,8 +69,8 @@ AutonomousHttpConnection::AutonomousHttpConnection(SharedConnectionWrapper& shar Http::DEFAULT_MAX_REQUEST_HEADERS_KB, Http::DEFAULT_MAX_HEADERS_COUNT), upstream_(upstream) {} -Http::StreamDecoder& AutonomousHttpConnection::newStream(Http::StreamEncoder& response_encoder, - bool) { +Http::RequestDecoder& AutonomousHttpConnection::newStream(Http::ResponseEncoder& response_encoder, + bool) { auto stream = new AutonomousStream(*this, response_encoder, upstream_, upstream_.allow_incomplete_streams_); streams_.push_back(FakeStreamPtr{stream}); diff --git a/test/integration/autonomous_upstream.h b/test/integration/autonomous_upstream.h index 89161dab65..92d50c11b0 100644 --- a/test/integration/autonomous_upstream.h +++ b/test/integration/autonomous_upstream.h @@ -20,7 +20,7 @@ class AutonomousStream : public FakeStream { // sending a response. static const char RESET_AFTER_REQUEST[]; - AutonomousStream(FakeHttpConnection& parent, Http::StreamEncoder& encoder, + AutonomousStream(FakeHttpConnection& parent, Http::ResponseEncoder& encoder, AutonomousUpstream& upstream, bool allow_incomplete_streams); ~AutonomousStream() override; @@ -38,7 +38,7 @@ class AutonomousHttpConnection : public FakeHttpConnection { AutonomousHttpConnection(SharedConnectionWrapper& shared_connection, Stats::Store& store, Type type, AutonomousUpstream& upstream); - Http::StreamDecoder& newStream(Http::StreamEncoder& response_encoder, bool) override; + Http::RequestDecoder& newStream(Http::ResponseEncoder& response_encoder, bool) override; private: AutonomousUpstream& upstream_; diff --git a/test/integration/fake_upstream.cc b/test/integration/fake_upstream.cc index 1a2b7c6807..f9f6d7fb3b 100644 --- a/test/integration/fake_upstream.cc +++ b/test/integration/fake_upstream.cc @@ -38,7 +38,7 @@ using testing::AssertionResult; using testing::AssertionSuccess; namespace Envoy { -FakeStream::FakeStream(FakeHttpConnection& parent, Http::StreamEncoder& encoder, +FakeStream::FakeStream(FakeHttpConnection& parent, Http::ResponseEncoder& encoder, Event::TestTimeSystem& time_system) : parent_(parent), encoder_(encoder), time_system_(time_system) { encoder.getStream().addCallbacks(*this); @@ -261,7 +261,7 @@ AssertionResult FakeConnectionBase::enableHalfClose(bool enable, [enable](Network::Connection& connection) { connection.enableHalfClose(enable); }, timeout); } -Http::StreamDecoder& FakeHttpConnection::newStream(Http::StreamEncoder& encoder, bool) { +Http::RequestDecoder& FakeHttpConnection::newStream(Http::ResponseEncoder& encoder, bool) { Thread::LockGuard lock(lock_); new_streams_.emplace_back(new FakeStream(*this, encoder, time_system_)); connection_event_.notifyOne(); diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index c478bcbd37..47de477a7b 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -43,11 +43,11 @@ class FakeHttpConnection; /** * Provides a fake HTTP stream for integration testing. */ -class FakeStream : public Http::StreamDecoder, +class FakeStream : public Http::RequestDecoder, public Http::StreamCallbacks, Logger::Loggable { public: - FakeStream(FakeHttpConnection& parent, Http::StreamEncoder& encoder, + FakeStream(FakeHttpConnection& parent, Http::ResponseEncoder& encoder, Event::TestTimeSystem& time_system); uint64_t bodyLength() { return body_.length(); } @@ -152,12 +152,13 @@ class FakeStream : public Http::StreamDecoder, } // Http::StreamDecoder - void decode100ContinueHeaders(Http::HeaderMapPtr&&) override {} - void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; void decodeData(Buffer::Instance& data, bool end_stream) override; - void decodeTrailers(Http::HeaderMapPtr&& trailers) override; void decodeMetadata(Http::MetadataMapPtr&& metadata_map_ptr) override; + // Http::RequestDecoder + void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; + void decodeTrailers(Http::HeaderMapPtr&& trailers) override; + // Http::StreamCallbacks void onResetStream(Http::StreamResetReason reason, absl::string_view transport_failure_reason) override; @@ -178,7 +179,7 @@ class FakeStream : public Http::StreamDecoder, private: FakeHttpConnection& parent_; - Http::StreamEncoder& encoder_; + Http::ResponseEncoder& encoder_; Thread::MutexBasicLockable lock_; Thread::CondVar decoder_event_; Http::HeaderMapPtr trailers_; @@ -430,7 +431,7 @@ class FakeHttpConnection : public Http::ServerConnectionCallbacks, public FakeCo std::chrono::milliseconds timeout = TestUtility::DefaultTimeout); // Http::ServerConnectionCallbacks - Http::StreamDecoder& newStream(Http::StreamEncoder& response_encoder, bool) override; + Http::RequestDecoder& newStream(Http::ResponseEncoder& response_encoder, bool) override; void onGoAway() override { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } private: diff --git a/test/integration/http2_integration_test.cc b/test/integration/http2_integration_test.cc index c7d2548ad9..4106538809 100644 --- a/test/integration/http2_integration_test.cc +++ b/test/integration/http2_integration_test.cc @@ -884,8 +884,8 @@ TEST_P(Http2IntegrationTest, GrpcRequestTimeout) { TEST_P(Http2IntegrationTest, IdleTimeoutWithSimultaneousRequests) { FakeHttpConnectionPtr fake_upstream_connection1; FakeHttpConnectionPtr fake_upstream_connection2; - Http::StreamEncoder* encoder1; - Http::StreamEncoder* encoder2; + Http::RequestEncoder* encoder1; + Http::RequestEncoder* encoder2; FakeStreamPtr upstream_request1; FakeStreamPtr upstream_request2; int32_t request1_bytes = 1024; @@ -1018,8 +1018,8 @@ TEST_P(Http2IntegrationTest, RequestMirrorWithBody) { void Http2IntegrationTest::simultaneousRequest(int32_t request1_bytes, int32_t request2_bytes) { FakeHttpConnectionPtr fake_upstream_connection1; FakeHttpConnectionPtr fake_upstream_connection2; - Http::StreamEncoder* encoder1; - Http::StreamEncoder* encoder2; + Http::RequestEncoder* encoder1; + Http::RequestEncoder* encoder2; FakeStreamPtr upstream_request1; FakeStreamPtr upstream_request2; initialize(); @@ -1249,7 +1249,7 @@ void Http2RingHashIntegrationTest::sendMultipleRequests( std::function cb) { TestRandomGenerator rand; const uint32_t num_requests = 50; - std::vector encoders; + std::vector encoders; std::vector responses; std::vector upstream_requests; diff --git a/test/integration/http2_upstream_integration_test.cc b/test/integration/http2_upstream_integration_test.cc index 989c593331..418ad053be 100644 --- a/test/integration/http2_upstream_integration_test.cc +++ b/test/integration/http2_upstream_integration_test.cc @@ -148,7 +148,7 @@ void Http2UpstreamIntegrationTest::simultaneousRequest(uint32_t request1_bytes, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}}); - Http::StreamEncoder* encoder1 = &encoder_decoder1.first; + Http::RequestEncoder* encoder1 = &encoder_decoder1.first; auto response1 = std::move(encoder_decoder1.second); ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_)); ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request1)); @@ -159,7 +159,7 @@ void Http2UpstreamIntegrationTest::simultaneousRequest(uint32_t request1_bytes, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}}); - Http::StreamEncoder* encoder2 = &encoder_decoder2.first; + Http::RequestEncoder* encoder2 = &encoder_decoder2.first; auto response2 = std::move(encoder_decoder2.second); ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request2)); @@ -204,7 +204,7 @@ TEST_P(Http2UpstreamIntegrationTest, LargeSimultaneousRequestWithBufferLimits) { void Http2UpstreamIntegrationTest::manySimultaneousRequests(uint32_t request_bytes, uint32_t) { TestRandomGenerator rand; const uint32_t num_requests = 50; - std::vector encoders; + std::vector encoders; std::vector responses; std::vector response_bytes; autonomous_upstream_ = true; @@ -264,7 +264,7 @@ TEST_P(Http2UpstreamIntegrationTest, ManyLargeSimultaneousRequestWithRandomBacku TEST_P(Http2UpstreamIntegrationTest, UpstreamConnectionCloseWithManyStreams) { config_helper_.setBufferLimits(1024, 1024); // Set buffer limits upstream and downstream. const uint32_t num_requests = 20; - std::vector encoders; + std::vector encoders; std::vector responses; std::vector upstream_requests; initialize(); diff --git a/test/integration/http_integration.cc b/test/integration/http_integration.cc index b827486643..0ed4568767 100644 --- a/test/integration/http_integration.cc +++ b/test/integration/http_integration.cc @@ -77,7 +77,7 @@ void IntegrationCodecClient::flushWrite() { IntegrationStreamDecoderPtr IntegrationCodecClient::makeHeaderOnlyRequest(const Http::HeaderMap& headers) { auto response = std::make_unique(dispatcher_); - Http::StreamEncoder& encoder = newStream(*response); + Http::RequestEncoder& encoder = newStream(*response); encoder.getStream().addCallbacks(*response); encoder.encodeHeaders(headers, true); flushWrite(); @@ -93,7 +93,7 @@ IntegrationStreamDecoderPtr IntegrationCodecClient::makeRequestWithBody(const Http::HeaderMap& headers, const std::string& body) { auto response = std::make_unique(dispatcher_); - Http::StreamEncoder& encoder = newStream(*response); + Http::RequestEncoder& encoder = newStream(*response); encoder.getStream().addCallbacks(*response); encoder.encodeHeaders(headers, false); Buffer::OwnedImpl data(body); @@ -102,37 +102,37 @@ IntegrationCodecClient::makeRequestWithBody(const Http::HeaderMap& headers, return response; } -void IntegrationCodecClient::sendData(Http::StreamEncoder& encoder, absl::string_view data, +void IntegrationCodecClient::sendData(Http::RequestEncoder& encoder, absl::string_view data, bool end_stream) { Buffer::OwnedImpl buffer_data(data.data(), data.size()); encoder.encodeData(buffer_data, end_stream); flushWrite(); } -void IntegrationCodecClient::sendData(Http::StreamEncoder& encoder, Buffer::Instance& data, +void IntegrationCodecClient::sendData(Http::RequestEncoder& encoder, Buffer::Instance& data, bool end_stream) { encoder.encodeData(data, end_stream); flushWrite(); } -void IntegrationCodecClient::sendData(Http::StreamEncoder& encoder, uint64_t size, +void IntegrationCodecClient::sendData(Http::RequestEncoder& encoder, uint64_t size, bool end_stream) { Buffer::OwnedImpl data(std::string(size, 'a')); sendData(encoder, data, end_stream); } -void IntegrationCodecClient::sendTrailers(Http::StreamEncoder& encoder, +void IntegrationCodecClient::sendTrailers(Http::RequestEncoder& encoder, const Http::HeaderMap& trailers) { encoder.encodeTrailers(trailers); flushWrite(); } -void IntegrationCodecClient::sendReset(Http::StreamEncoder& encoder) { +void IntegrationCodecClient::sendReset(Http::RequestEncoder& encoder) { encoder.getStream().resetStream(Http::StreamResetReason::LocalReset); flushWrite(); } -void IntegrationCodecClient::sendMetadata(Http::StreamEncoder& encoder, +void IntegrationCodecClient::sendMetadata(Http::RequestEncoder& encoder, Http::MetadataMap metadata_map) { Http::MetadataMapPtr metadata_map_ptr = std::make_unique(metadata_map); Http::MetadataMapVector metadata_map_vector; @@ -141,10 +141,10 @@ void IntegrationCodecClient::sendMetadata(Http::StreamEncoder& encoder, flushWrite(); } -std::pair +std::pair IntegrationCodecClient::startRequest(const Http::HeaderMap& headers) { auto response = std::make_unique(dispatcher_); - Http::StreamEncoder& encoder = newStream(*response); + Http::RequestEncoder& encoder = newStream(*response); encoder.getStream().addCallbacks(*response); encoder.encodeHeaders(headers, false); flushWrite(); diff --git a/test/integration/http_integration.h b/test/integration/http_integration.h index 16fe8192d5..26f56b12a8 100644 --- a/test/integration/http_integration.h +++ b/test/integration/http_integration.h @@ -29,14 +29,14 @@ class IntegrationCodecClient : public Http::CodecClientProd { const std::string& body); bool sawGoAway() const { return saw_goaway_; } bool connected() const { return connected_; } - void sendData(Http::StreamEncoder& encoder, absl::string_view data, bool end_stream); - void sendData(Http::StreamEncoder& encoder, Buffer::Instance& data, bool end_stream); - void sendData(Http::StreamEncoder& encoder, uint64_t size, bool end_stream); - void sendTrailers(Http::StreamEncoder& encoder, const Http::HeaderMap& trailers); - void sendReset(Http::StreamEncoder& encoder); + void sendData(Http::RequestEncoder& encoder, absl::string_view data, bool end_stream); + void sendData(Http::RequestEncoder& encoder, Buffer::Instance& data, bool end_stream); + void sendData(Http::RequestEncoder& encoder, uint64_t size, bool end_stream); + void sendTrailers(Http::RequestEncoder& encoder, const Http::HeaderMap& trailers); + void sendReset(Http::RequestEncoder& encoder); // Intentionally makes a copy of metadata_map. - void sendMetadata(Http::StreamEncoder& encoder, Http::MetadataMap metadata_map); - std::pair + void sendMetadata(Http::RequestEncoder& encoder, Http::MetadataMap metadata_map); + std::pair startRequest(const Http::HeaderMap& headers); bool waitForDisconnect(std::chrono::milliseconds time_to_wait = std::chrono::milliseconds(0)); Network::ClientConnection* connection() const { return connection_.get(); } @@ -231,7 +231,7 @@ class HttpIntegrationTest : public BaseIntegrationTest { // A placeholder for the first request received at upstream. FakeStreamPtr upstream_request_; // A pointer to the request encoder, if used. - Http::StreamEncoder* request_encoder_{nullptr}; + Http::RequestEncoder* request_encoder_{nullptr}; // The response headers sent by sendRequestAndWaitForResponse() by default. Http::TestHeaderMapImpl default_response_headers_{{":status", "200"}}; Http::TestHeaderMapImpl default_request_headers_{ diff --git a/test/integration/http_timeout_integration_test.cc b/test/integration/http_timeout_integration_test.cc index 097c085eb1..6a9ae16ee2 100644 --- a/test/integration/http_timeout_integration_test.cc +++ b/test/integration/http_timeout_integration_test.cc @@ -185,9 +185,7 @@ TEST_P(HttpTimeoutIntegrationTest, GlobalTimeoutAfterHeadersBeforeBodyResetsUpst {":authority", "host"}, {"x-forwarded-for", "10.0.0.1"}, {"x-envoy-upstream-rq-timeout-ms", "100"}}; - std::pair encoder_decoder = - codec_client_->startRequest(request_headers); - + auto encoder_decoder = codec_client_->startRequest(request_headers); auto response = std::move(encoder_decoder.second); request_encoder_ = &encoder_decoder.first; diff --git a/test/integration/integration.h b/test/integration/integration.h index 0a04837db4..6ba287a016 100644 --- a/test/integration/integration.h +++ b/test/integration/integration.h @@ -33,7 +33,7 @@ namespace Envoy { /** * Stream decoder wrapper used during integration testing. */ -class IntegrationStreamDecoder : public Http::StreamDecoder, public Http::StreamCallbacks { +class IntegrationStreamDecoder : public Http::ResponseDecoder, public Http::StreamCallbacks { public: IntegrationStreamDecoder(Event::Dispatcher& dispatcher); diff --git a/test/integration/utility.cc b/test/integration/utility.cc index ca1f05955b..832154d754 100644 --- a/test/integration/utility.cc +++ b/test/integration/utility.cc @@ -81,7 +81,7 @@ IntegrationUtil::makeSingleRequest(const Network::Address::InstanceConstSharedPt client.close(); dispatcher->exit(); })); - Http::StreamEncoder& encoder = client.newStream(*response); + Http::RequestEncoder& encoder = client.newStream(*response); encoder.getStream().addCallbacks(*response); Http::HeaderMapImpl headers; diff --git a/test/integration/utility.h b/test/integration/utility.h index 6554234ddc..93eb3459ac 100644 --- a/test/integration/utility.h +++ b/test/integration/utility.h @@ -22,7 +22,7 @@ namespace Envoy { /** * A buffering response decoder used for testing. */ -class BufferingStreamDecoder : public Http::StreamDecoder, public Http::StreamCallbacks { +class BufferingStreamDecoder : public Http::ResponseDecoder, public Http::StreamCallbacks { public: BufferingStreamDecoder(std::function on_complete_cb) : on_complete_cb_(on_complete_cb) {} diff --git a/test/mocks/http/api_listener.h b/test/mocks/http/api_listener.h index 0032f1c71c..4ee7ed6cb2 100644 --- a/test/mocks/http/api_listener.h +++ b/test/mocks/http/api_listener.h @@ -12,8 +12,8 @@ class MockApiListener : public ApiListener { ~MockApiListener() override; // Http::ApiListener - MOCK_METHOD(StreamDecoder&, newStream, - (StreamEncoder & response_encoder, bool is_internally_created)); + MOCK_METHOD(RequestDecoder&, newStream, + (ResponseEncoder & response_encoder, bool is_internally_created)); }; } // namespace Http diff --git a/test/mocks/http/conn_pool.h b/test/mocks/http/conn_pool.h index dbae960304..f5116ae3cd 100644 --- a/test/mocks/http/conn_pool.h +++ b/test/mocks/http/conn_pool.h @@ -8,10 +8,9 @@ namespace Envoy { namespace Http { - namespace ConnectionPool { -class MockCancellable : public Cancellable { +class MockCancellable : public Cancellable { public: MockCancellable(); ~MockCancellable() override; @@ -30,8 +29,7 @@ class MockInstance : public Instance { MOCK_METHOD(void, addDrainedCallback, (DrainedCb cb)); MOCK_METHOD(void, drainConnections, ()); MOCK_METHOD(bool, hasActiveConnections, (), (const)); - MOCK_METHOD(Cancellable*, newStream, - (Http::StreamDecoder & response_decoder, Http::ConnectionPool::Callbacks& callbacks)); + MOCK_METHOD(Cancellable*, newStream, (ResponseDecoder & response_decoder, Callbacks& callbacks)); MOCK_METHOD(Upstream::HostDescriptionConstSharedPtr, host, (), (const)); std::shared_ptr> host_; diff --git a/test/mocks/http/mocks.h b/test/mocks/http/mocks.h index bca811c617..b912df6c0f 100644 --- a/test/mocks/http/mocks.h +++ b/test/mocks/http/mocks.h @@ -54,8 +54,8 @@ class MockServerConnectionCallbacks : public ServerConnectionCallbacks, ~MockServerConnectionCallbacks() override; // Http::ServerConnectionCallbacks - MOCK_METHOD(StreamDecoder&, newStream, - (StreamEncoder & response_encoder, bool is_internally_created)); + MOCK_METHOD(RequestDecoder&, newStream, + (ResponseEncoder & response_encoder, bool is_internally_created)); }; class MockStreamCallbacks : public StreamCallbacks { @@ -101,7 +101,7 @@ class MockClientConnection : public ClientConnection { MOCK_METHOD(void, onUnderlyingConnectionBelowWriteBufferLowWatermark, ()); // Http::ClientConnection - MOCK_METHOD(StreamEncoder&, newStream, (StreamDecoder & response_decoder)); + MOCK_METHOD(RequestEncoder&, newStream, (ResponseDecoder & response_decoder)); }; class MockFilterChainFactory : public FilterChainFactory { diff --git a/test/mocks/http/stream_decoder.cc b/test/mocks/http/stream_decoder.cc index 3c2c75aed3..eec3f6abbd 100644 --- a/test/mocks/http/stream_decoder.cc +++ b/test/mocks/http/stream_decoder.cc @@ -1,10 +1,39 @@ #include "test/mocks/http/stream_decoder.h" +using testing::_; +using testing::Invoke; + namespace Envoy { namespace Http { MockStreamDecoder::MockStreamDecoder() = default; MockStreamDecoder::~MockStreamDecoder() = default; +MockRequestDecoder::MockRequestDecoder() { + ON_CALL(*this, decodeHeaders_(_, _)).WillByDefault(Invoke([](HeaderMapPtr& headers, bool) { + // Check for passing response headers as request headers in a test. + // TODO(mattklein123): In future changes this will become impossible once the header/trailer + // implementation classes are split. + ASSERT(headers->Status() == nullptr); + // Check to see that method is not-null. Path can be null for CONNECT and authority can be null + // at the codec level. + ASSERT(headers->Method() != nullptr); + })); +} +MockRequestDecoder::~MockRequestDecoder() = default; + +MockResponseDecoder::MockResponseDecoder() { + ON_CALL(*this, decodeHeaders_(_, _)).WillByDefault(Invoke([](HeaderMapPtr& headers, bool) { + // Check for passing request headers as response headers in a test. + // TODO(mattklein123): In future changes this will become impossible once the header/trailer + // implementation classes are split. + ASSERT(headers->Status() != nullptr); + ASSERT(headers->Path() == nullptr); + ASSERT(headers->Method() == nullptr); + ASSERT(headers->Host() == nullptr); + })); +} +MockResponseDecoder::~MockResponseDecoder() = default; + } // namespace Http } // namespace Envoy diff --git a/test/mocks/http/stream_decoder.h b/test/mocks/http/stream_decoder.h index 4526fa2272..af18cb666d 100644 --- a/test/mocks/http/stream_decoder.h +++ b/test/mocks/http/stream_decoder.h @@ -6,11 +6,38 @@ namespace Envoy { namespace Http { -class MockStreamDecoder : public StreamDecoder { +class MockStreamDecoder : public virtual StreamDecoder { public: MockStreamDecoder(); ~MockStreamDecoder() override; + void decodeMetadata(MetadataMapPtr&& metadata_map) override { decodeMetadata_(metadata_map); } + + // Http::StreamDecoder + MOCK_METHOD(void, decodeData, (Buffer::Instance & data, bool end_stream)); + MOCK_METHOD(void, decodeMetadata_, (MetadataMapPtr & metadata_map)); +}; + +class MockRequestDecoder : public MockStreamDecoder, public RequestDecoder { +public: + MockRequestDecoder(); + ~MockRequestDecoder(); + + void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) override { + decodeHeaders_(headers, end_stream); + } + void decodeTrailers(HeaderMapPtr&& trailers) override { decodeTrailers_(trailers); } + + // Http::RequestDecoder + MOCK_METHOD(void, decodeHeaders_, (HeaderMapPtr & headers, bool end_stream)); + MOCK_METHOD(void, decodeTrailers_, (HeaderMapPtr & trailers)); +}; + +class MockResponseDecoder : public MockStreamDecoder, public ResponseDecoder { +public: + MockResponseDecoder(); + ~MockResponseDecoder(); + void decode100ContinueHeaders(HeaderMapPtr&& headers) override { decode100ContinueHeaders_(headers); } @@ -19,14 +46,10 @@ class MockStreamDecoder : public StreamDecoder { } void decodeTrailers(HeaderMapPtr&& trailers) override { decodeTrailers_(trailers); } - void decodeMetadata(MetadataMapPtr&& metadata_map) override { decodeMetadata_(metadata_map); } - - // Http::StreamDecoder - MOCK_METHOD(void, decodeHeaders_, (HeaderMapPtr & headers, bool end_stream)); + // Http::ResponseDecoder MOCK_METHOD(void, decode100ContinueHeaders_, (HeaderMapPtr & headers)); - MOCK_METHOD(void, decodeData, (Buffer::Instance & data, bool end_stream)); + MOCK_METHOD(void, decodeHeaders_, (HeaderMapPtr & headers, bool end_stream)); MOCK_METHOD(void, decodeTrailers_, (HeaderMapPtr & trailers)); - MOCK_METHOD(void, decodeMetadata_, (MetadataMapPtr & metadata_map)); }; } // namespace Http diff --git a/test/mocks/http/stream_encoder.cc b/test/mocks/http/stream_encoder.cc index 98fdec7821..d0da12b71b 100644 --- a/test/mocks/http/stream_encoder.cc +++ b/test/mocks/http/stream_encoder.cc @@ -1,5 +1,8 @@ #include "test/mocks/http/stream_encoder.h" +using testing::_; +using testing::Invoke; + namespace Envoy { namespace Http { @@ -9,5 +12,31 @@ MockStreamEncoder::MockStreamEncoder() { MockStreamEncoder::~MockStreamEncoder() = default; +MockRequestEncoder::MockRequestEncoder() { + ON_CALL(*this, encodeHeaders(_, _)).WillByDefault(Invoke([](const HeaderMap& headers, bool) { + // Check for passing response headers as request headers in a test. + // TODO(mattklein123): In future changes this will become impossible once the header/trailer + // implementation classes are split. + ASSERT(headers.Status() == nullptr); + // Check to see that method is not-null. Path can be null for CONNECT and authority can be null + // at the codec level. + ASSERT(headers.Method() != nullptr); + })); +} +MockRequestEncoder::~MockRequestEncoder() = default; + +MockResponseEncoder::MockResponseEncoder() { + ON_CALL(*this, encodeHeaders(_, _)).WillByDefault(Invoke([](const HeaderMap& headers, bool) { + // Check for passing request headers as response headers in a test. + // TODO(mattklein123): In future changes this will become impossible once the header/trailer + // implementation classes are split. + ASSERT(headers.Status() != nullptr); + ASSERT(headers.Path() == nullptr); + ASSERT(headers.Method() == nullptr); + ASSERT(headers.Host() == nullptr); + })); +} +MockResponseEncoder::~MockResponseEncoder() = default; + } // namespace Http } // namespace Envoy diff --git a/test/mocks/http/stream_encoder.h b/test/mocks/http/stream_encoder.h index a55aed27e0..2adb8d484b 100644 --- a/test/mocks/http/stream_encoder.h +++ b/test/mocks/http/stream_encoder.h @@ -9,21 +9,39 @@ namespace Envoy { namespace Http { -class MockStreamEncoder : public StreamEncoder { +class MockStreamEncoder : public virtual StreamEncoder { public: MockStreamEncoder(); ~MockStreamEncoder() override; // Http::StreamEncoder - MOCK_METHOD(void, encode100ContinueHeaders, (const HeaderMap& headers)); - MOCK_METHOD(void, encodeHeaders, (const HeaderMap& headers, bool end_stream)); MOCK_METHOD(void, encodeData, (Buffer::Instance & data, bool end_stream)); - MOCK_METHOD(void, encodeTrailers, (const HeaderMap& trailers)); MOCK_METHOD(void, encodeMetadata, (const MetadataMapVector& metadata_map_vector)); MOCK_METHOD(Stream&, getStream, ()); testing::NiceMock stream_; }; +class MockRequestEncoder : public MockStreamEncoder, public RequestEncoder { +public: + MockRequestEncoder(); + ~MockRequestEncoder(); + + // Http::RequestEncoder + MOCK_METHOD(void, encodeHeaders, (const HeaderMap& headers, bool end_stream)); + MOCK_METHOD(void, encodeTrailers, (const HeaderMap& trailers)); +}; + +class MockResponseEncoder : public MockStreamEncoder, public ResponseEncoder { +public: + MockResponseEncoder(); + ~MockResponseEncoder(); + + // Http::ResponseEncoder + MOCK_METHOD(void, encode100ContinueHeaders, (const HeaderMap& headers)); + MOCK_METHOD(void, encodeHeaders, (const HeaderMap& headers, bool end_stream)); + MOCK_METHOD(void, encodeTrailers, (const HeaderMap& trailers)); +}; + } // namespace Http } // namespace Envoy From 25ce106477428774abbbccda04d0f63bb744a305 Mon Sep 17 00:00:00 2001 From: Rama Chavali Date: Wed, 5 Feb 2020 22:54:53 +0530 Subject: [PATCH 09/87] add dns sans to rbac debug log (#9936) Signed-off-by: Rama Chavali --- .../filters/http/rbac/rbac_filter.cc | 27 ++++++++++--------- .../filters/network/rbac/rbac_filter.cc | 2 ++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/source/extensions/filters/http/rbac/rbac_filter.cc b/source/extensions/filters/http/rbac/rbac_filter.cc index 146c059bf6..861ad6dfca 100644 --- a/source/extensions/filters/http/rbac/rbac_filter.cc +++ b/source/extensions/filters/http/rbac/rbac_filter.cc @@ -54,18 +54,21 @@ RoleBasedAccessControlRouteSpecificFilterConfig::RoleBasedAccessControlRouteSpec Http::FilterHeadersStatus RoleBasedAccessControlFilter::decodeHeaders(Http::HeaderMap& headers, bool) { - ENVOY_LOG(debug, - "checking request: remoteAddress: {}, localAddress: {}, ssl: {}, headers: {}, " - "dynamicMetadata: {}", - callbacks_->connection()->remoteAddress()->asString(), - callbacks_->connection()->localAddress()->asString(), - callbacks_->connection()->ssl() - ? "uriSanPeerCertificate: " + - absl::StrJoin(callbacks_->connection()->ssl()->uriSanPeerCertificate(), ",") + - ", subjectPeerCertificate: " + - callbacks_->connection()->ssl()->subjectPeerCertificate() - : "none", - headers, callbacks_->streamInfo().dynamicMetadata().DebugString()); + ENVOY_LOG( + debug, + "checking request: remoteAddress: {}, localAddress: {}, ssl: {}, headers: {}, " + "dynamicMetadata: {}", + callbacks_->connection()->remoteAddress()->asString(), + callbacks_->connection()->localAddress()->asString(), + callbacks_->connection()->ssl() + ? "uriSanPeerCertificate: " + + absl::StrJoin(callbacks_->connection()->ssl()->uriSanPeerCertificate(), ",") + + ", dnsSanPeerCertificate: " + + absl::StrJoin(callbacks_->connection()->ssl()->dnsSansPeerCertificate(), ",") + + ", subjectPeerCertificate: " + + callbacks_->connection()->ssl()->subjectPeerCertificate() + : "none", + headers, callbacks_->streamInfo().dynamicMetadata().DebugString()); std::string effective_policy_id; const auto shadow_engine = diff --git a/source/extensions/filters/network/rbac/rbac_filter.cc b/source/extensions/filters/network/rbac/rbac_filter.cc index 320c8f8083..85cabdac77 100644 --- a/source/extensions/filters/network/rbac/rbac_filter.cc +++ b/source/extensions/filters/network/rbac/rbac_filter.cc @@ -31,6 +31,8 @@ Network::FilterStatus RoleBasedAccessControlFilter::onData(Buffer::Instance&, bo callbacks_->connection().ssl() ? "uriSanPeerCertificate: " + absl::StrJoin(callbacks_->connection().ssl()->uriSanPeerCertificate(), ",") + + ", dnsSanPeerCertificate: " + + absl::StrJoin(callbacks_->connection().ssl()->dnsSansPeerCertificate(), ",") + ", subjectPeerCertificate: " + callbacks_->connection().ssl()->subjectPeerCertificate() : "none", From 4cb10d4be429d0fcb35682a44bcd3a664ff1dbb9 Mon Sep 17 00:00:00 2001 From: Yuval Kohavi Date: Wed, 5 Feb 2020 14:36:26 -0500 Subject: [PATCH 10/87] jwt_authn: fix data race that leads to seg fault (#9884) Signed-off-by: Yuval Kohavi --- .../extensions/filters/http/jwt_authn/BUILD | 1 + .../filters/http/jwt_authn/filter_config.cc | 37 +++++++++ .../filters/http/jwt_authn/filter_config.h | 79 +++++++++++-------- .../filters/http/jwt_authn/filter_factory.cc | 2 +- .../http/jwt_authn/all_verifier_test.cc | 4 +- .../http/jwt_authn/authenticator_test.cc | 4 +- .../http/jwt_authn/filter_config_test.cc | 63 +++++++++++++-- .../filters/http/jwt_authn/filter_test.cc | 27 ++++--- .../http/jwt_authn/provider_verifier_test.cc | 7 +- test/mocks/thread_local/mocks.h | 18 ++++- 10 files changed, 183 insertions(+), 59 deletions(-) create mode 100644 source/extensions/filters/http/jwt_authn/filter_config.cc diff --git a/source/extensions/filters/http/jwt_authn/BUILD b/source/extensions/filters/http/jwt_authn/BUILD index cdfde76129..0602621c2f 100644 --- a/source/extensions/filters/http/jwt_authn/BUILD +++ b/source/extensions/filters/http/jwt_authn/BUILD @@ -107,6 +107,7 @@ envoy_cc_library( envoy_cc_library( name = "filter_config_interface", + srcs = ["filter_config.cc"], hdrs = ["filter_config.h"], deps = [ ":jwks_cache_lib", diff --git a/source/extensions/filters/http/jwt_authn/filter_config.cc b/source/extensions/filters/http/jwt_authn/filter_config.cc new file mode 100644 index 0000000000..8602362846 --- /dev/null +++ b/source/extensions/filters/http/jwt_authn/filter_config.cc @@ -0,0 +1,37 @@ +#include "extensions/filters/http/jwt_authn/filter_config.h" + +namespace Envoy { +namespace Extensions { +namespace HttpFilters { +namespace JwtAuthn { + +void FilterConfigImpl::init() { + ENVOY_LOG(debug, "Loaded JwtAuthConfig: {}", proto_config_.DebugString()); + + // Note: `this` and `context` have a a lifetime of the listener. + // That may be shorter of the tls callback if the listener is torn shortly after it is created. + // We use a shared pointer to make sure this object outlives the tls callbacks. + auto shared_this = shared_from_this(); + tls_->set([shared_this](Event::Dispatcher&) -> ThreadLocal::ThreadLocalObjectSharedPtr { + return std::make_shared(shared_this->proto_config_, shared_this->time_source_, + shared_this->api_); + }); + + for (const auto& rule : proto_config_.rules()) { + rule_pairs_.emplace_back(Matcher::create(rule), + Verifier::create(rule.requires(), proto_config_.providers(), *this)); + } + + if (proto_config_.has_filter_state_rules()) { + filter_state_name_ = proto_config_.filter_state_rules().name(); + for (const auto& it : proto_config_.filter_state_rules().requires()) { + filter_state_verifiers_.emplace( + it.first, Verifier::create(it.second, proto_config_.providers(), *this)); + } + } +} + +} // namespace JwtAuthn +} // namespace HttpFilters +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/filters/http/jwt_authn/filter_config.h b/source/extensions/filters/http/jwt_authn/filter_config.h index 1f97b3f116..6ceef09082 100644 --- a/source/extensions/filters/http/jwt_authn/filter_config.h +++ b/source/extensions/filters/http/jwt_authn/filter_config.h @@ -55,38 +55,42 @@ struct JwtAuthnFilterStats { }; /** - * The filter config object to hold config and relevant objects. + * The filter config interface. It is an interface so that we can mock it in tests. */ -class FilterConfig : public Logger::Loggable, public AuthFactory { +class FilterConfig { public: - ~FilterConfig() override = default; + virtual ~FilterConfig() = default; - FilterConfig(envoy::extensions::filters::http::jwt_authn::v3::JwtAuthentication proto_config, - const std::string& stats_prefix, Server::Configuration::FactoryContext& context) - : proto_config_(std::move(proto_config)), - stats_(generateStats(stats_prefix, context.scope())), - tls_(context.threadLocal().allocateSlot()), cm_(context.clusterManager()), - time_source_(context.dispatcher().timeSource()), api_(context.api()) { - ENVOY_LOG(info, "Loaded JwtAuthConfig: {}", proto_config_.DebugString()); - tls_->set([this](Event::Dispatcher&) -> ThreadLocal::ThreadLocalObjectSharedPtr { - return std::make_shared(proto_config_, time_source_, api_); - }); - - for (const auto& rule : proto_config_.rules()) { - rule_pairs_.emplace_back(Matcher::create(rule), - Verifier::create(rule.requires(), proto_config_.providers(), *this)); - } + virtual JwtAuthnFilterStats& stats() PURE; - if (proto_config_.has_filter_state_rules()) { - filter_state_name_ = proto_config_.filter_state_rules().name(); - for (const auto& it : proto_config_.filter_state_rules().requires()) { - filter_state_verifiers_.emplace( - it.first, Verifier::create(it.second, proto_config_.providers(), *this)); - } - } - } + virtual bool bypassCorsPreflightRequest() const PURE; - JwtAuthnFilterStats& stats() { return stats_; } + // Finds the matcher that matched the header + virtual const Verifier* findVerifier(const Http::HeaderMap& headers, + const StreamInfo::FilterState& filter_state) const PURE; +}; +using FilterConfigSharedPtr = std::shared_ptr; + +/** + * The filter config object to hold config and relevant objects. + */ +class FilterConfigImpl : public Logger::Loggable, + public FilterConfig, + public AuthFactory, + public std::enable_shared_from_this { +public: + ~FilterConfigImpl() override = default; + + // Finds the matcher that matched the header + static std::shared_ptr + create(envoy::extensions::filters::http::jwt_authn::v3::JwtAuthentication proto_config, + const std::string& stats_prefix, Server::Configuration::FactoryContext& context) { + // We can't use make_shared here because the constructor of this class is private. + std::shared_ptr ptr( + new FilterConfigImpl(proto_config, stats_prefix, context)); + ptr->init(); + return ptr; + } // Get per-thread cache object. ThreadLocalCache& getCache() const { return tls_->getTyped(); } @@ -94,9 +98,14 @@ class FilterConfig : public Logger::Loggable, public AuthFactor Upstream::ClusterManager& cm() const { return cm_; } TimeSource& timeSource() const { return time_source_; } - // Finds the matcher that matched the header + // FilterConfig + + JwtAuthnFilterStats& stats() override { return stats_; } + + bool bypassCorsPreflightRequest() const override { return proto_config_.bypass_cors_preflight(); } + virtual const Verifier* findVerifier(const Http::HeaderMap& headers, - const StreamInfo::FilterState& filter_state) const { + const StreamInfo::FilterState& filter_state) const override { for (const auto& pair : rule_pairs_) { if (pair.matcher_->matches(headers)) { return pair.verifier_.get(); @@ -123,9 +132,16 @@ class FilterConfig : public Logger::Loggable, public AuthFactor timeSource()); } - bool bypassCorsPreflightRequest() { return proto_config_.bypass_cors_preflight(); } - private: + FilterConfigImpl(envoy::extensions::filters::http::jwt_authn::v3::JwtAuthentication proto_config, + const std::string& stats_prefix, Server::Configuration::FactoryContext& context) + : proto_config_(std::move(proto_config)), + stats_(generateStats(stats_prefix, context.scope())), + tls_(context.threadLocal().allocateSlot()), cm_(context.clusterManager()), + time_source_(context.dispatcher().timeSource()), api_(context.api()) {} + + void init(); + JwtAuthnFilterStats generateStats(const std::string& prefix, Stats::Scope& scope) { const std::string final_prefix = prefix + "jwt_authn."; return {ALL_JWT_AUTHN_FILTER_STATS(POOL_COUNTER_PREFIX(scope, final_prefix))}; @@ -155,7 +171,6 @@ class FilterConfig : public Logger::Loggable, public AuthFactor TimeSource& time_source_; Api::Api& api_; }; -using FilterConfigSharedPtr = std::shared_ptr; } // namespace JwtAuthn } // namespace HttpFilters diff --git a/source/extensions/filters/http/jwt_authn/filter_factory.cc b/source/extensions/filters/http/jwt_authn/filter_factory.cc index cd9006eebf..60d938a769 100644 --- a/source/extensions/filters/http/jwt_authn/filter_factory.cc +++ b/source/extensions/filters/http/jwt_authn/filter_factory.cc @@ -45,7 +45,7 @@ FilterFactory::createFilterFactoryFromProtoTyped(const JwtAuthentication& proto_ const std::string& prefix, Server::Configuration::FactoryContext& context) { validateJwtConfig(proto_config, context.api()); - auto filter_config = std::make_shared(proto_config, prefix, context); + auto filter_config = FilterConfigImpl::create(proto_config, prefix, context); return [filter_config](Http::FilterChainFactoryCallbacks& callbacks) -> void { callbacks.addStreamDecoderFilter(std::make_shared(filter_config)); }; diff --git a/test/extensions/filters/http/jwt_authn/all_verifier_test.cc b/test/extensions/filters/http/jwt_authn/all_verifier_test.cc index 3e7c9e291b..56cbe1a60a 100644 --- a/test/extensions/filters/http/jwt_authn/all_verifier_test.cc +++ b/test/extensions/filters/http/jwt_authn/all_verifier_test.cc @@ -73,7 +73,7 @@ class AllVerifierTest : public testing::Test { } void createVerifier() { - filter_config_ = ::std::make_shared(proto_config_, "", mock_factory_ctx_); + filter_config_ = FilterConfigImpl::create(proto_config_, "", mock_factory_ctx_); verifier_ = Verifier::create(proto_config_.rules(0).requires(), proto_config_.providers(), *filter_config_); } @@ -83,7 +83,7 @@ class AllVerifierTest : public testing::Test { } JwtAuthentication proto_config_; - FilterConfigSharedPtr filter_config_; + std::shared_ptr filter_config_; VerifierConstPtr verifier_; NiceMock mock_factory_ctx_; ContextSharedPtr context_; diff --git a/test/extensions/filters/http/jwt_authn/authenticator_test.cc b/test/extensions/filters/http/jwt_authn/authenticator_test.cc index b586b09613..8fb34c4dfe 100644 --- a/test/extensions/filters/http/jwt_authn/authenticator_test.cc +++ b/test/extensions/filters/http/jwt_authn/authenticator_test.cc @@ -42,7 +42,7 @@ class AuthenticatorTest : public testing::Test { void CreateAuthenticator(::google::jwt_verify::CheckAudience* check_audience = nullptr, const absl::optional& provider = absl::make_optional(ProviderName)) { - filter_config_ = ::std::make_shared(proto_config_, "", mock_factory_ctx_); + filter_config_ = FilterConfigImpl::create(proto_config_, "", mock_factory_ctx_); raw_fetcher_ = new MockJwksFetcher; fetcher_.reset(raw_fetcher_); auth_ = Authenticator::create( @@ -77,7 +77,7 @@ class AuthenticatorTest : public testing::Test { JwtAuthentication proto_config_; ExtractorConstPtr extractor_; - FilterConfigSharedPtr filter_config_; + std::shared_ptr filter_config_; MockJwksFetcher* raw_fetcher_; JwksFetcherPtr fetcher_; AuthenticatorPtr auth_; diff --git a/test/extensions/filters/http/jwt_authn/filter_config_test.cc b/test/extensions/filters/http/jwt_authn/filter_config_test.cc index e4dd9d7ab6..1285800b35 100644 --- a/test/extensions/filters/http/jwt_authn/filter_config_test.cc +++ b/test/extensions/filters/http/jwt_authn/filter_config_test.cc @@ -12,6 +12,7 @@ #include "gtest/gtest.h" using envoy::extensions::filters::http::jwt_authn::v3::JwtAuthentication; +using testing::ReturnRef; namespace Envoy { namespace Extensions { @@ -37,17 +38,17 @@ TEST(HttpJwtAuthnFilterConfigTest, FindByMatch) { TestUtility::loadFromYaml(config, proto_config); NiceMock context; - FilterConfig filter_conf(proto_config, "", context); + auto filter_conf = FilterConfigImpl::create(proto_config, "", context); StreamInfo::FilterStateImpl filter_state(StreamInfo::FilterState::LifeSpan::FilterChain); - EXPECT_TRUE(filter_conf.findVerifier( + EXPECT_TRUE(filter_conf->findVerifier( Http::TestHeaderMapImpl{ {":method", "GET"}, {":path", "/path1"}, }, filter_state) != nullptr); - EXPECT_TRUE(filter_conf.findVerifier( + EXPECT_TRUE(filter_conf->findVerifier( Http::TestHeaderMapImpl{ {":method", "GET"}, {":path", "/path2"}, @@ -55,6 +56,52 @@ TEST(HttpJwtAuthnFilterConfigTest, FindByMatch) { filter_state) == nullptr); } +TEST(HttpJwtAuthnFilterConfigTest, VerifyTLSLifetime) { + const char config[] = R"( +providers: + provider1: + issuer: issuer1 + local_jwks: + inline_string: jwks +rules: +- match: + path: /path1 + requires: + provider_name: provider1 +)"; + + NiceMock server_context; + // Make sure that the thread callbacks are not invoked inline. + server_context.thread_local_.defer_data = true; + { + // Scope in all the things that the filter depends on, so they are destroyed as we leave the + // scope. + NiceMock context; + // The threadLocal, dispatcher and api that are used by the filter config, actually belong to + // the server factory context that who's lifetime is longer. We simulate that by returning + // their instances from outside the scope. + ON_CALL(context, dispatcher()).WillByDefault(ReturnRef(server_context.dispatcher())); + ON_CALL(context, api()).WillByDefault(ReturnRef(server_context.api())); + ON_CALL(context, threadLocal()).WillByDefault(ReturnRef(server_context.threadLocal())); + + JwtAuthentication proto_config; + TestUtility::loadFromYaml(config, proto_config); + auto filter_conf = FilterConfigImpl::create(proto_config, "", context); + } + + // Even though filter_conf is now de-allocated, using a reference to it might still work, as its + // memory was not cleared. This leads to a false positive in this test when run normally. The + // test should fail under asan if the code uses invalid reference. + + // Make sure the filter scheduled a callback + EXPECT_EQ(1, server_context.thread_local_.deferred_data_.size()); + + // Simulate a situation where the callback is called after the filter config is destroyed. + // call the tls callback. we want to make sure that it doesn't depend on objects + // that are out of scope. + EXPECT_NO_THROW(server_context.thread_local_.call()); +} + TEST(HttpJwtAuthnFilterConfigTest, FindByFilterState) { const char config[] = R"( providers: @@ -79,32 +126,32 @@ TEST(HttpJwtAuthnFilterConfigTest, FindByFilterState) { TestUtility::loadFromYaml(config, proto_config); NiceMock context; - FilterConfig filter_conf(proto_config, "", context); + auto filter_conf = FilterConfigImpl::create(proto_config, "", context); // Empty filter_state StreamInfo::FilterStateImpl filter_state1(StreamInfo::FilterState::LifeSpan::FilterChain); - EXPECT_TRUE(filter_conf.findVerifier(Http::TestHeaderMapImpl(), filter_state1) == nullptr); + EXPECT_TRUE(filter_conf->findVerifier(Http::TestHeaderMapImpl(), filter_state1) == nullptr); // Wrong selector StreamInfo::FilterStateImpl filter_state2(StreamInfo::FilterState::LifeSpan::FilterChain); filter_state2.setData( "jwt_selector", std::make_unique("wrong_selector"), StreamInfo::FilterState::StateType::ReadOnly, StreamInfo::FilterState::LifeSpan::FilterChain); - EXPECT_TRUE(filter_conf.findVerifier(Http::TestHeaderMapImpl(), filter_state2) == nullptr); + EXPECT_TRUE(filter_conf->findVerifier(Http::TestHeaderMapImpl(), filter_state2) == nullptr); // correct selector StreamInfo::FilterStateImpl filter_state3(StreamInfo::FilterState::LifeSpan::FilterChain); filter_state3.setData("jwt_selector", std::make_unique("selector1"), StreamInfo::FilterState::StateType::ReadOnly, StreamInfo::FilterState::LifeSpan::FilterChain); - EXPECT_TRUE(filter_conf.findVerifier(Http::TestHeaderMapImpl(), filter_state3) != nullptr); + EXPECT_TRUE(filter_conf->findVerifier(Http::TestHeaderMapImpl(), filter_state3) != nullptr); // correct selector StreamInfo::FilterStateImpl filter_state4(StreamInfo::FilterState::LifeSpan::FilterChain); filter_state4.setData("jwt_selector", std::make_unique("selector2"), StreamInfo::FilterState::StateType::ReadOnly, StreamInfo::FilterState::LifeSpan::FilterChain); - EXPECT_TRUE(filter_conf.findVerifier(Http::TestHeaderMapImpl(), filter_state4) != nullptr); + EXPECT_TRUE(filter_conf->findVerifier(Http::TestHeaderMapImpl(), filter_state4) != nullptr); } } // namespace diff --git a/test/extensions/filters/http/jwt_authn/filter_test.cc b/test/extensions/filters/http/jwt_authn/filter_test.cc index 173a94a6c0..bf1c799d47 100644 --- a/test/extensions/filters/http/jwt_authn/filter_test.cc +++ b/test/extensions/filters/http/jwt_authn/filter_test.cc @@ -16,6 +16,7 @@ using ::google::jwt_verify::Status; using testing::_; using testing::Invoke; using testing::Return; +using testing::ReturnRef; namespace Envoy { namespace Extensions { @@ -28,22 +29,32 @@ class MockMatcher : public Matcher { MOCK_METHOD(bool, matches, (const Http::HeaderMap& headers), (const)); }; +JwtAuthnFilterStats generateMockStats(Stats::Scope& scope) { + return {ALL_JWT_AUTHN_FILTER_STATS(POOL_COUNTER_PREFIX(scope, ""))}; +} + class MockFilterConfig : public FilterConfig { public: - MockFilterConfig( - const envoy::extensions::filters::http::jwt_authn::v3::JwtAuthentication& proto_config, - const std::string& stats_prefix, Server::Configuration::FactoryContext& context) - : FilterConfig(proto_config, stats_prefix, context) {} + MockFilterConfig() : stats_(generateMockStats(stats_store_)) { + ON_CALL(*this, bypassCorsPreflightRequest()).WillByDefault(Return(true)); + ON_CALL(*this, findVerifier(_, _)).WillByDefault(Return(nullptr)); + ON_CALL(*this, stats()).WillByDefault(ReturnRef(stats_)); + } + MOCK_METHOD(const Verifier*, findVerifier, (const Http::HeaderMap& headers, const StreamInfo::FilterState& filter_state), (const)); + MOCK_METHOD(bool, bypassCorsPreflightRequest, (), (const)); + MOCK_METHOD(JwtAuthnFilterStats&, stats, ()); + + NiceMock stats_store_; + JwtAuthnFilterStats stats_; }; class FilterTest : public testing::Test { public: void SetUp() override { - proto_config_.set_bypass_cors_preflight(true); - mock_config_ = ::std::make_shared(proto_config_, "", mock_context_); + mock_config_ = ::std::make_shared>(); mock_verifier_ = std::make_unique(); filter_ = std::make_unique(mock_config_); @@ -54,9 +65,7 @@ class FilterTest : public testing::Test { EXPECT_CALL(*mock_config_.get(), findVerifier(_, _)).WillOnce(Return(mock_verifier_.get())); } - JwtAuthentication proto_config_; - NiceMock mock_context_; - std::shared_ptr mock_config_; + std::shared_ptr> mock_config_; NiceMock filter_callbacks_; std::unique_ptr filter_; std::unique_ptr mock_verifier_; diff --git a/test/extensions/filters/http/jwt_authn/provider_verifier_test.cc b/test/extensions/filters/http/jwt_authn/provider_verifier_test.cc index 460a9ad86b..cadab1e9ac 100644 --- a/test/extensions/filters/http/jwt_authn/provider_verifier_test.cc +++ b/test/extensions/filters/http/jwt_authn/provider_verifier_test.cc @@ -34,13 +34,13 @@ ProtobufWkt::Struct getExpectedPayload(const std::string& name) { class ProviderVerifierTest : public testing::Test { public: void createVerifier() { - filter_config_ = ::std::make_shared(proto_config_, "", mock_factory_ctx_); + filter_config_ = FilterConfigImpl::create(proto_config_, "", mock_factory_ctx_); verifier_ = Verifier::create(proto_config_.rules(0).requires(), proto_config_.providers(), *filter_config_); } JwtAuthentication proto_config_; - FilterConfigSharedPtr filter_config_; + std::shared_ptr filter_config_; VerifierConstPtr verifier_; NiceMock mock_factory_ctx_; ContextSharedPtr context_; @@ -175,8 +175,7 @@ TEST_F(ProviderVerifierTest, TestRequiresNonexistentProvider) { TestUtility::loadFromYaml(ExampleConfig, proto_config_); proto_config_.mutable_rules(0)->mutable_requires()->set_provider_name("nosuchprovider"); - EXPECT_THROW(::std::make_shared(proto_config_, "", mock_factory_ctx_), - EnvoyException); + EXPECT_THROW(FilterConfigImpl::create(proto_config_, "", mock_factory_ctx_), EnvoyException); } } // namespace diff --git a/test/mocks/thread_local/mocks.h b/test/mocks/thread_local/mocks.h index a1eb3efd20..b2f3f1e13f 100644 --- a/test/mocks/thread_local/mocks.h +++ b/test/mocks/thread_local/mocks.h @@ -46,6 +46,7 @@ class MockInstance : public Instance { struct SlotImpl : public Slot { SlotImpl(MockInstance& parent, uint32_t index) : parent_(parent), index_(index) { parent_.data_.resize(index_ + 1); + parent_.deferred_data_.resize(index_ + 1); } ~SlotImpl() override { @@ -71,15 +72,30 @@ class MockInstance : public Instance { main_callback); } - void set(InitializeCb cb) override { parent_.data_[index_] = cb(parent_.dispatcher_); } + void set(InitializeCb cb) override { + if (parent_.defer_data) { + parent_.deferred_data_[index_] = cb; + } else { + parent_.data_[index_] = cb(parent_.dispatcher_); + } + } MockInstance& parent_; const uint32_t index_; }; + void call() { + for (unsigned i = 0; i < deferred_data_.size(); i++) { + data_[i] = deferred_data_[i](dispatcher_); + } + deferred_data_.clear(); + } + uint32_t current_slot_{}; testing::NiceMock dispatcher_; std::vector data_; + std::vector deferred_data_; + bool defer_data{}; bool shutdown_{}; bool registered_{true}; }; From f64ade1d90d9209982008391f337ed76e7aca3d2 Mon Sep 17 00:00:00 2001 From: Bennett Dong Date: Wed, 5 Feb 2020 13:07:10 -0800 Subject: [PATCH 11/87] sds: support generic type secret (#9858) Description: This PR adds support of generic secret type in secret manager. The goal is to enable filters to access generic secret. Risk Level: Medium Testing: Unit test, Integration test Docs Changes: Changed Release Notes: Changed Signed-off-by: bennettdong --- api/envoy/api/v2/auth/cert.proto | 8 + .../transport_sockets/tls/v3/cert.proto | 10 + docs/root/intro/version_history.rst | 1 + .../envoy/api/v2/auth/cert.proto | 8 + .../transport_sockets/tls/v3/cert.proto | 10 + include/envoy/secret/secret_manager.h | 30 +++ include/envoy/secret/secret_provider.h | 6 + source/common/secret/sds_api.h | 58 +++++ source/common/secret/secret_manager_impl.cc | 71 ++++++ source/common/secret/secret_manager_impl.h | 15 ++ source/common/secret/secret_provider_impl.cc | 6 + source/common/secret/secret_provider_impl.h | 21 ++ test/common/secret/sds_api_test.cc | 61 +++++ .../common/secret/secret_manager_impl_test.cc | 229 ++++++++++++++++++ .../tls/test_data/aes_128_key | 1 + test/integration/BUILD | 16 ++ .../sds_generic_secret_integration_test.cc | 160 ++++++++++++ test/mocks/secret/mocks.h | 7 + 18 files changed, 718 insertions(+) create mode 100644 test/extensions/transport_sockets/tls/test_data/aes_128_key create mode 100644 test/integration/sds_generic_secret_integration_test.cc diff --git a/api/envoy/api/v2/auth/cert.proto b/api/envoy/api/v2/auth/cert.proto index 8321787240..7ddc11c780 100644 --- a/api/envoy/api/v2/auth/cert.proto +++ b/api/envoy/api/v2/auth/cert.proto @@ -435,6 +435,11 @@ message DownstreamTlsContext { }]; } +message GenericSecret { + // Secret of generic type and is available to filters. + core.DataSource secret = 1 [(udpa.annotations.sensitive) = true]; +} + message SdsSecretConfig { // Name (FQDN, UUID, SPKI, SHA256, etc.) by which the secret can be uniquely referred to. // When both name and config are specified, then secret can be fetched and/or reloaded via @@ -444,6 +449,7 @@ message SdsSecretConfig { core.ConfigSource sds_config = 2; } +// [#next-free-field: 6] message Secret { // Name (FQDN, UUID, SPKI, SHA256, etc.) by which the secret can be uniquely referred to. string name = 1; @@ -454,5 +460,7 @@ message Secret { TlsSessionTicketKeys session_ticket_keys = 3; CertificateValidationContext validation_context = 4; + + GenericSecret generic_secret = 5; } } diff --git a/api/envoy/extensions/transport_sockets/tls/v3/cert.proto b/api/envoy/extensions/transport_sockets/tls/v3/cert.proto index 162cdb1d0c..123d56e306 100644 --- a/api/envoy/extensions/transport_sockets/tls/v3/cert.proto +++ b/api/envoy/extensions/transport_sockets/tls/v3/cert.proto @@ -453,6 +453,13 @@ message DownstreamTlsContext { }]; } +message GenericSecret { + option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.GenericSecret"; + + // Secret of generic type and is available to filters. + config.core.v3.DataSource secret = 1 [(udpa.annotations.sensitive) = true]; +} + message SdsSecretConfig { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.SdsSecretConfig"; @@ -464,6 +471,7 @@ message SdsSecretConfig { config.core.v3.ConfigSource sds_config = 2; } +// [#next-free-field: 6] message Secret { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.Secret"; @@ -476,5 +484,7 @@ message Secret { TlsSessionTicketKeys session_ticket_keys = 3; CertificateValidationContext validation_context = 4; + + GenericSecret generic_secret = 5; } } diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index 384931bb67..f2f60d9ecf 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -8,6 +8,7 @@ Version history * retry: added a retry predicate that :ref:`rejects hosts based on metadata. ` * router: added the ability to match a route based on whether a downstream TLS connection certificate has been :ref:`validated `. +* sds: added :ref:`GenericSecret ` to support secret of generic type. * upstream: combined HTTP/1 and HTTP/2 connection pool code. This means that circuit breaker limits for both requests and connections apply to both pool types. Also, HTTP/2 now has the option to limit concurrent requests on a connection, and allow multiple draining diff --git a/generated_api_shadow/envoy/api/v2/auth/cert.proto b/generated_api_shadow/envoy/api/v2/auth/cert.proto index 8321787240..7ddc11c780 100644 --- a/generated_api_shadow/envoy/api/v2/auth/cert.proto +++ b/generated_api_shadow/envoy/api/v2/auth/cert.proto @@ -435,6 +435,11 @@ message DownstreamTlsContext { }]; } +message GenericSecret { + // Secret of generic type and is available to filters. + core.DataSource secret = 1 [(udpa.annotations.sensitive) = true]; +} + message SdsSecretConfig { // Name (FQDN, UUID, SPKI, SHA256, etc.) by which the secret can be uniquely referred to. // When both name and config are specified, then secret can be fetched and/or reloaded via @@ -444,6 +449,7 @@ message SdsSecretConfig { core.ConfigSource sds_config = 2; } +// [#next-free-field: 6] message Secret { // Name (FQDN, UUID, SPKI, SHA256, etc.) by which the secret can be uniquely referred to. string name = 1; @@ -454,5 +460,7 @@ message Secret { TlsSessionTicketKeys session_ticket_keys = 3; CertificateValidationContext validation_context = 4; + + GenericSecret generic_secret = 5; } } diff --git a/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto b/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto index e5c53dfacb..261dd35ceb 100644 --- a/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto +++ b/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto @@ -458,6 +458,13 @@ message DownstreamTlsContext { }]; } +message GenericSecret { + option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.GenericSecret"; + + // Secret of generic type and is available to filters. + config.core.v3.DataSource secret = 1 [(udpa.annotations.sensitive) = true]; +} + message SdsSecretConfig { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.SdsSecretConfig"; @@ -469,6 +476,7 @@ message SdsSecretConfig { config.core.v3.ConfigSource sds_config = 2; } +// [#next-free-field: 6] message Secret { option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.Secret"; @@ -481,5 +489,7 @@ message Secret { TlsSessionTicketKeys session_ticket_keys = 3; CertificateValidationContext validation_context = 4; + + GenericSecret generic_secret = 5; } } diff --git a/include/envoy/secret/secret_manager.h b/include/envoy/secret/secret_manager.h index 2f4fb69534..3534e8119b 100644 --- a/include/envoy/secret/secret_manager.h +++ b/include/envoy/secret/secret_manager.h @@ -11,6 +11,7 @@ namespace Envoy { namespace Server { namespace Configuration { class TransportSocketFactoryContext; +class FactoryContext; } // namespace Configuration } // namespace Server @@ -54,6 +55,14 @@ class SecretManager { virtual TlsSessionTicketKeysConfigProviderSharedPtr findStaticTlsSessionTicketKeysContextProvider(const std::string& name) const PURE; + /** + * @param name a name of the static GenericSecretConfigProvider. + * @return the GenericSecretConfigProviderSharedPtr. Returns nullptr if the static secret is not + * found. + */ + virtual GenericSecretConfigProviderSharedPtr + findStaticGenericSecretProvider(const std::string& name) const PURE; + /** * @param tls_certificate the protobuf config of the TLS certificate. * @return a TlsCertificateConfigProviderSharedPtr created from tls_certificate. @@ -80,6 +89,13 @@ class SecretManager { const envoy::extensions::transport_sockets::tls::v3::TlsSessionTicketKeys& tls_certificate) PURE; + /** + * @param generic_secret the protobuf config of the generic secret. + * @return a GenericSecretConfigProviderSharedPtr created from tls_certificate. + */ + virtual GenericSecretConfigProviderSharedPtr createInlineGenericSecretProvider( + const envoy::extensions::transport_sockets::tls::v3::GenericSecret& generic_secret) PURE; + /** * Finds and returns a dynamic secret provider associated to SDS config. Create * a new one if such provider does not exist. @@ -125,6 +141,20 @@ class SecretManager { findOrCreateTlsSessionTicketKeysContextProvider( const envoy::config::core::v3::ConfigSource& config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) PURE; + + /** + * Finds and returns a dynamic secret provider associated to SDS config. Create a new one if such + * provider does not exist. + * + * @param config_source a protobuf message object containing a SDS config source. + * @param config_name a name that uniquely refers to the SDS config source. + * @param secret_provider_context context that provides components for creating and initializing + * secret provider. + * @return GenericSecretConfigProviderSharedPtr the dynamic generic secret provider. + */ + virtual GenericSecretConfigProviderSharedPtr findOrCreateGenericSecretProvider( + const envoy::config::core::v3::ConfigSource& config_source, const std::string& config_name, + Server::Configuration::TransportSocketFactoryContext& secret_provider_context) PURE; }; } // namespace Secret diff --git a/include/envoy/secret/secret_provider.h b/include/envoy/secret/secret_provider.h index d1d299687e..2dbc31e579 100644 --- a/include/envoy/secret/secret_provider.h +++ b/include/envoy/secret/secret_provider.h @@ -49,6 +49,8 @@ using CertificateValidationContextPtr = std::unique_ptr; using TlsSessionTicketKeysPtr = std::unique_ptr; +using GenericSecretPtr = + std::unique_ptr; using TlsCertificateConfigProvider = SecretProvider; @@ -64,5 +66,9 @@ using TlsSessionTicketKeysConfigProvider = using TlsSessionTicketKeysConfigProviderSharedPtr = std::shared_ptr; +using GenericSecretConfigProvider = + SecretProvider; +using GenericSecretConfigProviderSharedPtr = std::shared_ptr; + } // namespace Secret } // namespace Envoy diff --git a/source/common/secret/sds_api.h b/source/common/secret/sds_api.h index af2b1c3fb0..70c36f5e51 100644 --- a/source/common/secret/sds_api.h +++ b/source/common/secret/sds_api.h @@ -86,10 +86,12 @@ class SdsApi : public Config::SubscriptionCallbacks { class TlsCertificateSdsApi; class CertificateValidationContextSdsApi; class TlsSessionTicketKeysSdsApi; +class GenericSecretSdsApi; using TlsCertificateSdsApiSharedPtr = std::shared_ptr; using CertificateValidationContextSdsApiSharedPtr = std::shared_ptr; using TlsSessionTicketKeysSdsApiSharedPtr = std::shared_ptr; +using GenericSecretSdsApiSharedPtr = std::shared_ptr; /** * TlsCertificateSdsApi implementation maintains and updates dynamic TLS certificate secrets. @@ -276,5 +278,61 @@ class TlsSessionTicketKeysSdsApi : public SdsApi, public TlsSessionTicketKeysCon validation_callback_manager_; }; +/** + * GenericSecretSdsApi implementation maintains and updates dynamic generic secret. + */ +class GenericSecretSdsApi : public SdsApi, public GenericSecretConfigProvider { +public: + static GenericSecretSdsApiSharedPtr + create(Server::Configuration::TransportSocketFactoryContext& secret_provider_context, + const envoy::config::core::v3::ConfigSource& sds_config, + const std::string& sds_config_name, std::function destructor_cb) { + // We need to do this early as we invoke the subscription factory during initialization, which + // is too late to throw. + Config::Utility::checkLocalInfo("GenericSecretSdsApi", secret_provider_context.localInfo()); + return std::make_shared( + sds_config, sds_config_name, secret_provider_context.clusterManager().subscriptionFactory(), + secret_provider_context.dispatcher().timeSource(), + secret_provider_context.messageValidationVisitor(), secret_provider_context.stats(), + *secret_provider_context.initManager(), destructor_cb); + } + + GenericSecretSdsApi(const envoy::config::core::v3::ConfigSource& sds_config, + const std::string& sds_config_name, + Config::SubscriptionFactory& subscription_factory, TimeSource& time_source, + ProtobufMessage::ValidationVisitor& validation_visitor, Stats::Store& stats, + Init::Manager& init_manager, std::function destructor_cb) + : SdsApi(sds_config, sds_config_name, subscription_factory, time_source, validation_visitor, + stats, init_manager, std::move(destructor_cb)) {} + + // SecretProvider + const envoy::extensions::transport_sockets::tls::v3::GenericSecret* secret() const override { + return generic_secret.get(); + } + Common::CallbackHandle* addUpdateCallback(std::function callback) override { + return update_callback_manager_.add(callback); + } + Common::CallbackHandle* addValidationCallback( + std::function + callback) override { + return validation_callback_manager_.add(callback); + } + +protected: + void setSecret(const envoy::extensions::transport_sockets::tls::v3::Secret& secret) override { + generic_secret = std::make_unique( + secret.generic_secret()); + } + void + validateConfig(const envoy::extensions::transport_sockets::tls::v3::Secret& secret) override { + validation_callback_manager_.runCallbacks(secret.generic_secret()); + } + +private: + GenericSecretPtr generic_secret; + Common::CallbackManager + validation_callback_manager_; +}; + } // namespace Secret } // namespace Envoy diff --git a/source/common/secret/secret_manager_impl.cc b/source/common/secret/secret_manager_impl.cc index b3fe35ce07..a5fffb940b 100644 --- a/source/common/secret/secret_manager_impl.cc +++ b/source/common/secret/secret_manager_impl.cc @@ -56,6 +56,16 @@ void SecretManagerImpl::addStaticSecret( } break; } + case envoy::extensions::transport_sockets::tls::v3::Secret::TypeCase::kGenericSecret: { + auto secret_provider = + std::make_shared(secret.generic_secret()); + if (!static_generic_secret_providers_.insert(std::make_pair(secret.name(), secret_provider)) + .second) { + throw EnvoyException( + absl::StrCat("Duplicate static GenericSecret secret name ", secret.name())); + } + break; + } default: throw EnvoyException("Secret type not implemented"); } @@ -80,6 +90,12 @@ SecretManagerImpl::findStaticTlsSessionTicketKeysContextProvider(const std::stri return (secret != static_session_ticket_keys_providers_.end()) ? secret->second : nullptr; } +GenericSecretConfigProviderSharedPtr +SecretManagerImpl::findStaticGenericSecretProvider(const std::string& name) const { + auto secret = static_generic_secret_providers_.find(name); + return (secret != static_generic_secret_providers_.end()) ? secret->second : nullptr; +} + TlsCertificateConfigProviderSharedPtr SecretManagerImpl::createInlineTlsCertificateProvider( const envoy::extensions::transport_sockets::tls::v3::TlsCertificate& tls_certificate) { return std::make_shared(tls_certificate); @@ -100,9 +116,15 @@ SecretManagerImpl::createInlineTlsSessionTicketKeysProvider( return std::make_shared(tls_session_ticket_keys); } +GenericSecretConfigProviderSharedPtr SecretManagerImpl::createInlineGenericSecretProvider( + const envoy::extensions::transport_sockets::tls::v3::GenericSecret& generic_secret) { + return std::make_shared(generic_secret); +} + TlsCertificateConfigProviderSharedPtr SecretManagerImpl::findOrCreateTlsCertificateProvider( const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) { + ASSERT(secret_provider_context.initManager() != nullptr); return certificate_providers_.findOrCreate(sds_config_source, config_name, secret_provider_context); } @@ -111,6 +133,7 @@ CertificateValidationContextConfigProviderSharedPtr SecretManagerImpl::findOrCreateCertificateValidationContextProvider( const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) { + ASSERT(secret_provider_context.initManager() != nullptr); return validation_context_providers_.findOrCreate(sds_config_source, config_name, secret_provider_context); } @@ -119,10 +142,18 @@ TlsSessionTicketKeysConfigProviderSharedPtr SecretManagerImpl::findOrCreateTlsSessionTicketKeysContextProvider( const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) { + ASSERT(secret_provider_context.initManager() != nullptr); return session_ticket_keys_providers_.findOrCreate(sds_config_source, config_name, secret_provider_context); } +GenericSecretConfigProviderSharedPtr SecretManagerImpl::findOrCreateGenericSecretProvider( + const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, + Server::Configuration::TransportSocketFactoryContext& secret_provider_context) { + return generic_secret_providers_.findOrCreate(sds_config_source, config_name, + secret_provider_context); +} + ProtobufTypes::MessagePtr SecretManagerImpl::dumpSecretConfigs() { // TODO(htuch): unlike other config providers, we're recreating the original // Secrets below. This makes it hard to support API_RECOVER_ORIGINAL()-style @@ -170,6 +201,19 @@ ProtobufTypes::MessagePtr SecretManagerImpl::dumpSecretConfigs() { static_secret->mutable_secret()->PackFrom(dump_secret); } + // Handle static generic secret providers. + for (const auto& secret_iter : static_generic_secret_providers_) { + const auto& generic_secret = secret_iter.second; + auto static_secret = config_dump->mutable_static_secrets()->Add(); + static_secret->set_name(secret_iter.first); + ASSERT(generic_secret != nullptr); + envoy::extensions::transport_sockets::tls::v3::Secret dump_secret; + dump_secret.set_name(secret_iter.first); + dump_secret.mutable_generic_secret()->MergeFrom(*generic_secret->secret()); + MessageUtil::redact(dump_secret); + static_secret->mutable_secret()->PackFrom(dump_secret); + } + // Handle dynamic tls_certificate providers. const auto providers = certificate_providers_.allSecretProviders(); for (const auto& cert_secrets : providers) { @@ -247,6 +291,33 @@ ProtobufTypes::MessagePtr SecretManagerImpl::dumpSecretConfigs() { MessageUtil::redact(secret); dump_secret->mutable_secret()->PackFrom(secret); } + + // Handle dynamic generic secret providers. + const auto generic_secret_providers = generic_secret_providers_.allSecretProviders(); + for (const auto& provider : generic_secret_providers) { + const auto& secret_data = provider->secretData(); + const auto& generic_secret = provider->secret(); + envoy::admin::v3::SecretsConfigDump::DynamicSecret* dump_secret; + const bool secret_ready = generic_secret != nullptr; + if (secret_ready) { + dump_secret = config_dump->mutable_dynamic_active_secrets()->Add(); + } else { + dump_secret = config_dump->mutable_dynamic_warming_secrets()->Add(); + } + dump_secret->set_name(secret_data.resource_name_); + envoy::extensions::transport_sockets::tls::v3::Secret secret; + secret.set_name(secret_data.resource_name_); + ProtobufWkt::Timestamp last_updated_ts; + TimestampUtil::systemClockToTimestamp(secret_data.last_updated_, last_updated_ts); + dump_secret->set_version_info(secret_data.version_info_); + *dump_secret->mutable_last_updated() = last_updated_ts; + if (secret_ready) { + secret.mutable_generic_secret()->MergeFrom(*generic_secret); + } + MessageUtil::redact(secret); + dump_secret->mutable_secret()->PackFrom(secret); + } + return config_dump; } diff --git a/source/common/secret/secret_manager_impl.h b/source/common/secret/secret_manager_impl.h index d6f500978a..002bed3dec 100644 --- a/source/common/secret/secret_manager_impl.h +++ b/source/common/secret/secret_manager_impl.h @@ -31,6 +31,9 @@ class SecretManagerImpl : public SecretManager { TlsSessionTicketKeysConfigProviderSharedPtr findStaticTlsSessionTicketKeysContextProvider(const std::string& name) const override; + GenericSecretConfigProviderSharedPtr + findStaticGenericSecretProvider(const std::string& name) const override; + TlsCertificateConfigProviderSharedPtr createInlineTlsCertificateProvider( const envoy::extensions::transport_sockets::tls::v3::TlsCertificate& tls_certificate) override; @@ -44,6 +47,9 @@ class SecretManagerImpl : public SecretManager { const envoy::extensions::transport_sockets::tls::v3::TlsSessionTicketKeys& tls_session_ticket_keys) override; + GenericSecretConfigProviderSharedPtr createInlineGenericSecretProvider( + const envoy::extensions::transport_sockets::tls::v3::GenericSecret& generic_secret) override; + TlsCertificateConfigProviderSharedPtr findOrCreateTlsCertificateProvider( const envoy::config::core::v3::ConfigSource& config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) override; @@ -57,6 +63,10 @@ class SecretManagerImpl : public SecretManager { const envoy::config::core::v3::ConfigSource& config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) override; + GenericSecretConfigProviderSharedPtr findOrCreateGenericSecretProvider( + const envoy::config::core::v3::ConfigSource& config_source, const std::string& config_name, + Server::Configuration::TransportSocketFactoryContext& secret_provider_context) override; + private: ProtobufTypes::MessagePtr dumpSecretConfigs(); @@ -120,10 +130,15 @@ class SecretManagerImpl : public SecretManager { std::unordered_map static_session_ticket_keys_providers_; + // Manages pairs of secret name and GenericSecretConfigProviderSharedPtr. + std::unordered_map + static_generic_secret_providers_; + // map hash code of SDS config source and SdsApi object. DynamicSecretProviders certificate_providers_; DynamicSecretProviders validation_context_providers_; DynamicSecretProviders session_ticket_keys_providers_; + DynamicSecretProviders generic_secret_providers_; Server::ConfigTracker::EntryOwnerPtr config_tracker_entry_; }; diff --git a/source/common/secret/secret_provider_impl.cc b/source/common/secret/secret_provider_impl.cc index ba0bc0139a..0513c2180a 100644 --- a/source/common/secret/secret_provider_impl.cc +++ b/source/common/secret/secret_provider_impl.cc @@ -30,5 +30,11 @@ TlsSessionTicketKeysConfigProviderImpl::TlsSessionTicketKeysConfigProviderImpl( std::make_unique( tls_session_ticket_keys)) {} +GenericSecretConfigProviderImpl::GenericSecretConfigProviderImpl( + const envoy::extensions::transport_sockets::tls::v3::GenericSecret& generic_secret) + : generic_secret_( + std::make_unique( + generic_secret)) {} + } // namespace Secret } // namespace Envoy diff --git a/source/common/secret/secret_provider_impl.h b/source/common/secret/secret_provider_impl.h index ee2ca0d6f2..49493c7f33 100644 --- a/source/common/secret/secret_provider_impl.h +++ b/source/common/secret/secret_provider_impl.h @@ -79,5 +79,26 @@ class TlsSessionTicketKeysConfigProviderImpl : public TlsSessionTicketKeysConfig Secret::TlsSessionTicketKeysPtr tls_session_ticket_keys_; }; +class GenericSecretConfigProviderImpl : public GenericSecretConfigProvider { +public: + GenericSecretConfigProviderImpl( + const envoy::extensions::transport_sockets::tls::v3::GenericSecret& generic_secret); + + const envoy::extensions::transport_sockets::tls::v3::GenericSecret* secret() const override { + return generic_secret_.get(); + } + + Common::CallbackHandle* addValidationCallback( + std::function) + override { + return nullptr; + } + + Common::CallbackHandle* addUpdateCallback(std::function) override { return nullptr; } + +private: + Secret::GenericSecretPtr generic_secret_; +}; + } // namespace Secret } // namespace Envoy diff --git a/test/common/secret/sds_api_test.cc b/test/common/secret/sds_api_test.cc index 152b20b2c9..4a94ca7ab1 100644 --- a/test/common/secret/sds_api_test.cc +++ b/test/common/secret/sds_api_test.cc @@ -6,6 +6,7 @@ #include "envoy/service/discovery/v3/discovery.pb.h" #include "envoy/service/secret/v3/sds.pb.h" +#include "common/config/datasource.h" #include "common/secret/sds_api.h" #include "common/ssl/certificate_validation_context_config_impl.h" #include "common/ssl/tls_certificate_config_impl.h" @@ -325,6 +326,66 @@ TEST_F(SdsApiTest, DefaultCertificateValidationContextTest) { validation_handle->remove(); } +class GenericSecretValidationCallback { +public: + virtual ~GenericSecretValidationCallback() = default; + virtual void + validateGenericSecret(const envoy::extensions::transport_sockets::tls::v3::GenericSecret&) PURE; +}; + +class MockGenericSecretValidationCallback : public GenericSecretValidationCallback { +public: + MockGenericSecretValidationCallback() = default; + ~MockGenericSecretValidationCallback() override = default; + MOCK_METHOD(void, validateGenericSecret, + (const envoy::extensions::transport_sockets::tls::v3::GenericSecret&)); +}; + +// Validate that GenericSecretSdsApi updates secrets successfully if +// a good secret is passed to onConfigUpdate(). +TEST_F(SdsApiTest, GenericSecretSdsApiTest) { + NiceMock server; + envoy::config::core::v3::ConfigSource config_source; + GenericSecretSdsApi sds_api(config_source, "encryption_key", subscription_factory_, time_system_, + validation_visitor_, server.stats(), init_manager_, []() {}); + + NiceMock secret_callback; + auto handle = + sds_api.addUpdateCallback([&secret_callback]() { secret_callback.onAddOrUpdateSecret(); }); + NiceMock validation_callback; + auto validation_handle = sds_api.addValidationCallback( + [&validation_callback]( + const envoy::extensions::transport_sockets::tls::v3::GenericSecret& secret) { + validation_callback.validateGenericSecret(secret); + }); + + std::string yaml = + R"EOF( +name: "encryption_key" +generic_secret: + secret: + filename: "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/aes_128_key" +)EOF"; + envoy::extensions::transport_sockets::tls::v3::Secret typed_secret; + TestUtility::loadFromYaml(TestEnvironment::substitute(yaml), typed_secret); + Protobuf::RepeatedPtrField secret_resources; + secret_resources.Add()->PackFrom(typed_secret); + EXPECT_CALL(secret_callback, onAddOrUpdateSecret()); + EXPECT_CALL(validation_callback, validateGenericSecret(_)); + initialize(); + subscription_factory_.callbacks_->onConfigUpdate(secret_resources, ""); + + const envoy::extensions::transport_sockets::tls::v3::GenericSecret generic_secret( + *sds_api.secret()); + const std::string secret_path = + "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/aes_128_key"; + EXPECT_EQ(TestEnvironment::readFileToStringForTest(TestEnvironment::substitute(secret_path)), + Config::DataSource::read(generic_secret.secret(), true, *api_)); + + handle->remove(); + validation_handle->remove(); +} + // Validate that SdsApi throws exception if an empty secret is passed to onConfigUpdate(). TEST_F(SdsApiTest, EmptyResource) { NiceMock server; diff --git a/test/common/secret/secret_manager_impl_test.cc b/test/common/secret/secret_manager_impl_test.cc index 9687a9ccd8..7ebf6cc461 100644 --- a/test/common/secret/secret_manager_impl_test.cc +++ b/test/common/secret/secret_manager_impl_test.cc @@ -200,6 +200,51 @@ name: "abc.com" "Duplicate static TlsSessionTicketKeys secret name abc.com"); } +// Validate that secret manager adds static generic secret successfully. +TEST_F(SecretManagerImplTest, GenericSecretLoadSuccess) { + std::unique_ptr secret_manager(new SecretManagerImpl(config_tracker_)); + + envoy::extensions::transport_sockets::tls::v3::Secret secret; + const std::string yaml = + R"EOF( +name: "encryption_key" +generic_secret: + secret: + filename: "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/aes_128_key" +)EOF"; + TestUtility::loadFromYaml(TestEnvironment::substitute(yaml), secret); + secret_manager->addStaticSecret(secret); + + ASSERT_EQ(secret_manager->findStaticGenericSecretProvider("undefined"), nullptr); + ASSERT_NE(secret_manager->findStaticGenericSecretProvider("encryption_key"), nullptr); + + const envoy::extensions::transport_sockets::tls::v3::GenericSecret generic_secret( + *secret_manager->findStaticGenericSecretProvider("encryption_key")->secret()); + const std::string secret_path = + "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/aes_128_key"; + EXPECT_EQ(generic_secret.secret().filename(), TestEnvironment::substitute(secret_path)); +} + +// Validate that secret manager throws an exception when adding duplicated static generic secret. +TEST_F(SecretManagerImplTest, DuplicateGenericSecret) { + std::unique_ptr secret_manager(new SecretManagerImpl(config_tracker_)); + + envoy::extensions::transport_sockets::tls::v3::Secret secret; + const std::string yaml = + R"EOF( +name: "encryption_key" +generic_secret: + secret: + filename: "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/aes_128_key" +)EOF"; + TestUtility::loadFromYaml(TestEnvironment::substitute(yaml), secret); + secret_manager->addStaticSecret(secret); + + ASSERT_NE(secret_manager->findStaticGenericSecretProvider("encryption_key"), nullptr); + EXPECT_THROW_WITH_MESSAGE(secret_manager->addStaticSecret(secret), EnvoyException, + "Duplicate static GenericSecret secret name encryption_key"); +} + // Validate that secret manager deduplicates dynamic TLS certificate secret provider. // Regression test of https://github.com/envoyproxy/envoy/issues/5744 TEST_F(SecretManagerImplTest, DeduplicateDynamicTlsCertificateSecretProvider) { @@ -337,6 +382,52 @@ name: "abc.com" tls_config.privateKey()); } +TEST_F(SecretManagerImplTest, SdsDynamicGenericSecret) { + Server::MockInstance server; + std::unique_ptr secret_manager(new SecretManagerImpl(config_tracker_)); + envoy::config::core::v3::ConfigSource config_source; + + NiceMock secret_context; + NiceMock dispatcher; + NiceMock validation_visitor; + Stats::IsolatedStoreImpl stats; + NiceMock init_manager; + NiceMock local_info; + Init::TargetHandlePtr init_target_handle; + NiceMock init_watcher; + + EXPECT_CALL(secret_context, dispatcher()).WillOnce(ReturnRef(dispatcher)); + EXPECT_CALL(secret_context, messageValidationVisitor()).WillOnce(ReturnRef(validation_visitor)); + EXPECT_CALL(secret_context, stats()).WillOnce(ReturnRef(stats)); + EXPECT_CALL(secret_context, initManager()).WillRepeatedly(Return(&init_manager)); + EXPECT_CALL(secret_context, localInfo()).WillOnce(ReturnRef(local_info)); + EXPECT_CALL(init_manager, add(_)) + .WillOnce(Invoke([&init_target_handle](const Init::Target& target) { + init_target_handle = target.createHandle("test"); + })); + + auto secret_provider = secret_manager->findOrCreateGenericSecretProvider( + config_source, "encryption_key", secret_context); + + const std::string yaml = R"EOF( +name: "encryption_key" +generic_secret: + secret: + inline_string: "DUMMY_AES_128_KEY" +)EOF"; + envoy::extensions::transport_sockets::tls::v3::Secret typed_secret; + TestUtility::loadFromYaml(TestEnvironment::substitute(yaml), typed_secret); + Protobuf::RepeatedPtrField secret_resources; + secret_resources.Add()->PackFrom(typed_secret); + init_target_handle->initialize(init_watcher); + secret_context.cluster_manager_.subscription_factory_.callbacks_->onConfigUpdate(secret_resources, + ""); + + const envoy::extensions::transport_sockets::tls::v3::GenericSecret generic_secret( + *secret_provider->secret()); + EXPECT_EQ("DUMMY_AES_128_KEY", generic_secret.secret().inline_string()); +} + TEST_F(SecretManagerImplTest, ConfigDumpHandler) { Server::MockInstance server; auto secret_manager = std::make_unique(config_tracker_); @@ -519,6 +610,80 @@ name: "abc.com.stek" - inline_bytes: "W3JlZGFjdGVkXQ==" )EOF"; checkConfigDump(TestEnvironment::substitute(updated_once_more_config_dump)); + + // Add a dynamic generic secret provider. + time_system_.setSystemTime(std::chrono::milliseconds(1234567900000)); + auto generic_secret_provider = secret_manager->findOrCreateGenericSecretProvider( + config_source, "signing_key", secret_context); + + const std::string generic_secret_yaml = R"EOF( +name: "signing_key" +generic_secret: + secret: + inline_string: "DUMMY_ECDSA_KEY" +)EOF"; + TestUtility::loadFromYaml(TestEnvironment::substitute(generic_secret_yaml), typed_secret); + secret_resources.Clear(); + secret_resources.Add()->PackFrom(typed_secret); + init_target_handle->initialize(init_watcher); + secret_context.cluster_manager_.subscription_factory_.callbacks_->onConfigUpdate( + secret_resources, "signing-key-v1"); + + const envoy::extensions::transport_sockets::tls::v3::GenericSecret generic_secret( + *generic_secret_provider->secret()); + EXPECT_EQ("DUMMY_ECDSA_KEY", generic_secret.secret().inline_string()); + + const std::string config_dump_with_generic_secret = R"EOF( +dynamic_active_secrets: +- name: "abc.com" + version_info: "keycert-v1" + last_updated: + seconds: 1234567891 + nanos: 234000000 + secret: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret + name: "abc.com" + tls_certificate: + certificate_chain: + inline_string: "DUMMY_INLINE_BYTES_FOR_CERT_CHAIN" + private_key: + inline_string: "[redacted]" + password: + inline_string: "[redacted]" +- name: "abc.com.validation" + version_info: "validation-context-v1" + last_updated: + seconds: 1234567899 + secret: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret + name: "abc.com.validation" + validation_context: + trusted_ca: + inline_string: "DUMMY_INLINE_STRING_TRUSTED_CA" +- name: "abc.com.stek" + version_info: "stek-context-v1" + last_updated: + seconds: 1234567899 + secret: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret + name: "abc.com.stek" + session_ticket_keys: + keys: + - filename: "[redacted]" + - inline_string: "[redacted]" + - inline_bytes: "W3JlZGFjdGVkXQ==" +- name: "signing_key" + version_info: "signing-key-v1" + last_updated: + seconds: 1234567900 + secret: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret + name: "signing_key" + generic_secret: + secret: + inline_string: "[redacted]" +)EOF"; + checkConfigDump(TestEnvironment::substitute(config_dump_with_generic_secret)); } TEST_F(SecretManagerImplTest, ConfigDumpHandlerWarmingSecrets) { @@ -614,6 +779,44 @@ TEST_F(SecretManagerImplTest, ConfigDumpHandlerWarmingSecrets) { name: "abc.com.stek" )EOF"; checkConfigDump(updated_once_more_config_dump); + + time_system_.setSystemTime(std::chrono::milliseconds(1234567900000)); + auto generic_secret_provider = secret_manager->findOrCreateGenericSecretProvider( + config_source, "signing_key", secret_context); + init_target_handle->initialize(init_watcher); + const std::string config_dump_with_generic_secret = R"EOF( +dynamic_warming_secrets: +- name: "abc.com" + version_info: "uninitialized" + last_updated: + seconds: 1234567891 + nanos: 234000000 + secret: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret + name: "abc.com" +- name: "abc.com.validation" + version_info: "uninitialized" + last_updated: + seconds: 1234567899 + secret: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret + name: "abc.com.validation" +- name: "abc.com.stek" + version_info: "uninitialized" + last_updated: + seconds: 1234567899 + secret: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret + name: "abc.com.stek" +- name: "signing_key" + version_info: "uninitialized" + last_updated: + seconds: 1234567900 + secret: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret + name: "signing_key" +)EOF"; + checkConfigDump(config_dump_with_generic_secret); } TEST_F(SecretManagerImplTest, ConfigDumpHandlerStaticSecrets) { @@ -784,6 +987,32 @@ name: "abc.com.stek" checkConfigDump(TestEnvironment::substitute(expected_config_dump)); } +TEST_F(SecretManagerImplTest, ConfigDumpHandlerStaticGenericSecret) { + auto secret_manager = std::make_unique(config_tracker_); + + const std::string yaml = R"EOF( +name: "signing_key" +generic_secret: + secret: + inline_bytes: "DUMMY_ECDSA_KEY" +)EOF"; + envoy::extensions::transport_sockets::tls::v3::Secret typed_secret; + TestUtility::loadFromYaml(TestEnvironment::substitute(yaml), typed_secret); + secret_manager->addStaticSecret(typed_secret); + + const std::string expected_config_dump = R"EOF( +static_secrets: +- name: "signing_key" + secret: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret + name: "signing_key" + generic_secret: + secret: + inline_bytes: "W3JlZGFjdGVkXQ==" +)EOF"; + checkConfigDump(TestEnvironment::substitute(expected_config_dump)); +} + } // namespace } // namespace Secret } // namespace Envoy diff --git a/test/extensions/transport_sockets/tls/test_data/aes_128_key b/test/extensions/transport_sockets/tls/test_data/aes_128_key new file mode 100644 index 0000000000..c598788262 --- /dev/null +++ b/test/extensions/transport_sockets/tls/test_data/aes_128_key @@ -0,0 +1 @@ +�J��wsXyP�\;��� \ No newline at end of file diff --git a/test/integration/BUILD b/test/integration/BUILD index 23fba9512b..fa47c26579 100644 --- a/test/integration/BUILD +++ b/test/integration/BUILD @@ -829,6 +829,22 @@ envoy_cc_test( ], ) +envoy_cc_test( + name = "sds_generic_secret_integration_test", + srcs = [ + "sds_generic_secret_integration_test.cc", + ], + deps = [ + ":http_integration_lib", + "//include/envoy/registry", + "//source/common/grpc:common_lib", + "//test/test_common:utility_lib", + "@envoy_api//envoy/api/v2:pkg_cc_proto", + "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + ], +) + envoy_cc_test( name = "tcp_proxy_integration_test", srcs = [ diff --git a/test/integration/sds_generic_secret_integration_test.cc b/test/integration/sds_generic_secret_integration_test.cc new file mode 100644 index 0000000000..4342e3b288 --- /dev/null +++ b/test/integration/sds_generic_secret_integration_test.cc @@ -0,0 +1,160 @@ +#include + +#include "envoy/api/v2/discovery.pb.h" +#include "envoy/config/bootstrap/v3/bootstrap.pb.h" +#include "envoy/config/core/v3/grpc_service.pb.h" +#include "envoy/http/filter.h" +#include "envoy/registry/registry.h" +#include "envoy/secret/secret_provider.h" + +#include "common/config/datasource.h" +#include "common/grpc/common.h" + +#include "test/extensions/filters/http/common/empty_http_filter_config.h" +#include "test/integration/http_integration.h" +#include "test/integration/utility.h" +#include "test/test_common/utility.h" + +namespace Envoy { + +// The filter fetches a generic secret from secret manager and attaches it to a header for +// validation. +class SdsGenericSecretTestFilter : public Http::StreamDecoderFilter { +public: + SdsGenericSecretTestFilter(Api::Api& api, + Secret::GenericSecretConfigProviderSharedPtr config_provider) + : api_(api), config_provider_(config_provider) {} + + // Http::StreamFilterBase + void onDestroy() override{}; + + // Http::StreamDecoderFilter + Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool) override { + headers.addCopy(Http::LowerCaseString("secret"), + Config::DataSource::read(config_provider_->secret()->secret(), true, api_)); + return Http::FilterHeadersStatus::Continue; + } + + Http::FilterDataStatus decodeData(Buffer::Instance&, bool) override { + return Http::FilterDataStatus::Continue; + } + + Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + return Http::FilterTrailersStatus::Continue; + } + + void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override { + decoder_callbacks_ = &callbacks; + } + +private: + Api::Api& api_; + Secret::GenericSecretConfigProviderSharedPtr config_provider_; + Http::StreamDecoderFilterCallbacks* decoder_callbacks_; +}; + +class SdsGenericSecretTestFilterConfig + : public Extensions::HttpFilters::Common::EmptyHttpFilterConfig { +public: + SdsGenericSecretTestFilterConfig() + : Extensions::HttpFilters::Common::EmptyHttpFilterConfig("sds-generic-secret-test") { + auto* api_config_source = config_source_.mutable_api_config_source(); + api_config_source->set_api_type(envoy::config::core::v3::ApiConfigSource::GRPC); + auto* grpc_service = api_config_source->add_grpc_services(); + grpc_service->mutable_envoy_grpc()->set_cluster_name("sds_cluster"); + } + + Http::FilterFactoryCb + createFilter(const std::string&, + Server::Configuration::FactoryContext& factory_context) override { + auto secret_provider = + factory_context.clusterManager() + .clusterManagerFactory() + .secretManager() + .findOrCreateGenericSecretProvider(config_source_, "encryption_key", + factory_context.getTransportSocketFactoryContext()); + return + [&factory_context, secret_provider](Http::FilterChainFactoryCallbacks& callbacks) -> void { + callbacks.addStreamDecoderFilter(std::make_shared<::Envoy::SdsGenericSecretTestFilter>( + factory_context.api(), secret_provider)); + }; + } + +private: + envoy::config::core::v3::ConfigSource config_source_; +}; + +static Registry::RegisterFactory + register_; + +class SdsGenericSecretIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, + public HttpIntegrationTest { +public: + SdsGenericSecretIntegrationTest() + : HttpIntegrationTest(Http::CodecClient::Type::HTTP1, ipVersion()) {} + + void initialize() override { + config_helper_.addConfigModifier([](envoy::config::bootstrap::v3::Bootstrap& bootstrap) { + auto* sds_cluster = bootstrap.mutable_static_resources()->add_clusters(); + sds_cluster->MergeFrom(bootstrap.static_resources().clusters()[0]); + sds_cluster->set_name("sds_cluster"); + sds_cluster->mutable_http2_protocol_options(); + }); + + config_helper_.addFilter("{ name: sds-generic-secret-test }"); + + create_xds_upstream_ = true; + HttpIntegrationTest::initialize(); + } + + void TearDown() override { + cleanUpXdsConnection(); + cleanupUpstreamAndDownstream(); + codec_client_.reset(); + } + + void createSdsStream() { + createXdsConnection(); + AssertionResult result = xds_connection_->waitForNewStream(*dispatcher_, xds_stream_); + RELEASE_ASSERT(result, result.message()); + xds_stream_->startGrpcStream(); + } + + void sendSecret() { + envoy::extensions::transport_sockets::tls::v3::Secret secret; + secret.set_name("encryption_key"); + auto* generic_secret = secret.mutable_generic_secret(); + generic_secret->mutable_secret()->set_inline_string("DUMMY_AES_128_KEY"); + API_NO_BOOST(envoy::api::v2::DiscoveryResponse) discovery_response; + discovery_response.set_version_info("0"); + discovery_response.set_type_url(Config::TypeUrl::get().Secret); + discovery_response.add_resources()->PackFrom(API_DOWNGRADE(secret)); + xds_stream_->sendGrpcMessage(discovery_response); + } +}; + +INSTANTIATE_TEST_SUITE_P(IpVersions, SdsGenericSecretIntegrationTest, + GRPC_CLIENT_INTEGRATION_PARAMS); + +// A test that an SDS generic secret can be successfully fetched by a filter. +TEST_P(SdsGenericSecretIntegrationTest, FilterFetchSuccess) { + on_server_init_function_ = [this]() { + createSdsStream(); + sendSecret(); + }; + initialize(); + + codec_client_ = makeHttpConnection((lookupPort("http"))); + Http::TestHeaderMapImpl request_headers{ + {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}; + sendRequestAndWaitForResponse(request_headers, 0, default_response_headers_, 0); + + EXPECT_TRUE(upstream_request_->complete()); + EXPECT_EQ(0U, upstream_request_->bodyLength()); + EXPECT_EQ( + "DUMMY_AES_128_KEY", + upstream_request_->headers().get(Http::LowerCaseString("secret"))->value().getStringView()); +} + +} // namespace Envoy diff --git a/test/mocks/secret/mocks.h b/test/mocks/secret/mocks.h index 819fdf294a..d415fcfd4f 100644 --- a/test/mocks/secret/mocks.h +++ b/test/mocks/secret/mocks.h @@ -26,6 +26,8 @@ class MockSecretManager : public SecretManager { findStaticCertificateValidationContextProvider, (const std::string& name), (const)); MOCK_METHOD(TlsSessionTicketKeysConfigProviderSharedPtr, findStaticTlsSessionTicketKeysContextProvider, (const std::string& name), (const)); + MOCK_METHOD(GenericSecretConfigProviderSharedPtr, findStaticGenericSecretProvider, + (const std::string& name), (const)); MOCK_METHOD( TlsCertificateConfigProviderSharedPtr, createInlineTlsCertificateProvider, (const envoy::extensions::transport_sockets::tls::v3::TlsCertificate& tls_certificate)); @@ -36,6 +38,8 @@ class MockSecretManager : public SecretManager { MOCK_METHOD(TlsSessionTicketKeysConfigProviderSharedPtr, createInlineTlsSessionTicketKeysProvider, (const envoy::extensions::transport_sockets::tls::v3::TlsSessionTicketKeys& tls_session_ticket_keys)); + MOCK_METHOD(GenericSecretConfigProviderSharedPtr, createInlineGenericSecretProvider, + (const envoy::extensions::transport_sockets::tls::v3::GenericSecret& generic_secret)); MOCK_METHOD(TlsCertificateConfigProviderSharedPtr, findOrCreateTlsCertificateProvider, (const envoy::config::core::v3::ConfigSource&, const std::string&, Server::Configuration::TransportSocketFactoryContext&)); @@ -48,6 +52,9 @@ class MockSecretManager : public SecretManager { findOrCreateTlsSessionTicketKeysContextProvider, (const envoy::config::core::v3::ConfigSource&, const std::string&, Server::Configuration::TransportSocketFactoryContext&)); + MOCK_METHOD(GenericSecretConfigProviderSharedPtr, findOrCreateGenericSecretProvider, + (const envoy::config::core::v3::ConfigSource&, const std::string&, + Server::Configuration::TransportSocketFactoryContext&)); }; class MockSecretCallbacks : public SecretCallbacks { From d9a33764b5a625877687842c50a2260a433fabae Mon Sep 17 00:00:00 2001 From: Michael Rebello Date: Wed, 5 Feb 2020 14:40:18 -0800 Subject: [PATCH 12/87] gzip: add force load factory declaration (#9942) Adds a force load factory declaration so that this filter can be force-loaded by Envoy Mobile. Risk Level: Low Testing: Done locally, and CI Docs Changes: None Release Notes: None Signed-off-by: Michael Rebello --- source/extensions/filters/http/gzip/config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/extensions/filters/http/gzip/config.h b/source/extensions/filters/http/gzip/config.h index 989352d84f..b91f556994 100644 --- a/source/extensions/filters/http/gzip/config.h +++ b/source/extensions/filters/http/gzip/config.h @@ -26,6 +26,8 @@ class GzipFilterFactory Server::Configuration::FactoryContext& context) override; }; +DECLARE_FACTORY(GzipFilterFactory); + } // namespace Gzip } // namespace HttpFilters } // namespace Extensions From aedd8e3440f027fde56121bfed32c979d857566f Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Wed, 5 Feb 2020 15:21:07 -0800 Subject: [PATCH 13/87] docs: introduce Stable Releases. (#9919) Originally discussed and approved in: https://bit.ly/envoy-stable-releases Fixes #7915. Signed-off-by: Piotr Sikora --- CONTRIBUTING.md | 12 --------- GOVERNANCE.md | 11 ++++---- RELEASES.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 17 deletions(-) create mode 100644 RELEASES.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3c9c9e39fe..33e4ec1dc9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,18 +69,6 @@ versioning guidelines: it is expected the multi-phase warn-by-default/fail-by-default is sufficient to warn users to move away from deprecated features. -# Release cadence - -* Currently we are targeting approximately quarterly official releases. We may change this based - on customer demand. -* In general, master is assumed to be release candidate quality at all times for documented - features. For undocumented or clearly under development features, use caution or ask about - current status when running master. Lyft runs master in production, typically deploying every - few days. -* Note that we currently do not provide binary packages (RPM, etc.). Organizations are expected to - build Envoy from source. This may change in the future if we get resources for maintaining - packages. - # Submitting a PR * Fork the repo. diff --git a/GOVERNANCE.md b/GOVERNANCE.md index d782d34a16..0df8070ee7 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -70,16 +70,15 @@ or you can subscribe to the iCal feed [here](https://app.opsgenie.com/webcal/get ## Cutting a release -* We do releases approximately every 3 months as described in the - [release cadence documentation](CONTRIBUTING.md#release-cadence). -* Decide on the somewhat arbitrary time that a release will occur. +* We do releases every 3 months, at the end of each quarter, as described in the + [release schedule](RELEASES.md#release-schedule). * Take a look at open issues tagged with the current release, by [searching](https://github.com/envoyproxy/envoy/issues) for "is:open is:issue milestone:[current milestone]" and either hold off until they are fixed or bump them to the next milestone. * Begin marshalling the ongoing PR flow in this repo. Ask maintainers to hold off merging any - particularly risky PRs until after the release is tagged. This is because we currently don't use - release branches and assume that master is RC quality at all times. + particularly risky PRs until after the release is tagged. This is because we aim for master to be + at release candidate quality at all times. * Do a final check of the [release notes](docs/root/intro/version_history.rst) and make any needed corrections. * Switch the [VERSION](VERSION) from a "dev" variant to a final variant. E.g., "1.6.0-dev" to @@ -90,6 +89,8 @@ or you can subscribe to the iCal feed [here](https://app.opsgenie.com/webcal/get * Create a [tagged release](https://github.com/envoyproxy/envoy/releases). The release should start with "v" and be followed by the version number. E.g., "v1.6.0". **This must match the [VERSION](VERSION).** +* Create a branch from the tagged release, e.g. "release/v1.6". It will be used for the + [stable releases](RELEASES.md#stable-releases). * Monitor the CircleCI tag build to make sure that the final docker images get pushed along with the final docs. The final documentation will end up in the [envoyproxy.github.io repository](https://github.com/envoyproxy/envoyproxy.github.io/tree/master/docs/envoy). diff --git a/RELEASES.md b/RELEASES.md new file mode 100644 index 0000000000..d76b3fe798 --- /dev/null +++ b/RELEASES.md @@ -0,0 +1,70 @@ +# Release Process + +## Active development + +Active development is happening on the `master` branch, and a new version is released from it +at the end of each quarter. + +## Stable releases + +Stable releases of Envoy include: + +* Extended maintenance window (any version released in the last 12 months). +* Security fixes backported from the `master` branch (including those deemed not worthy + of creating a CVE). +* Stability fixes backported from the `master` branch (anything that can result in a crash, + including crashes triggered by a trusted control plane). +* Bugfixes, deemed worthwhile by the maintainers of stable releases. + +### Hand-off + +Hand-off to the maintainers of stable releases happens after Envoy maintainers release a new +version from the `master` branch by creating a `vX.Y.0` tag and a corresponding `release/vX.Y` +branch, with merge permissions given to the release manager of stable releases, and CI configured +to execute tests on it. + +### Security releases + +Critical security fixes are owned by the Envoy security team, which provides fixes for the +`master` branch, and the latest release branch. Once those fixes are ready, the maintainers +of stable releases backport them to the remaining supported stable releases. + +### Backports + +All other security and reliability fixes can be nominated for backporting to stable releases +by Envoy maintainers, Envoy security team, the change author, or members of the Envoy community +by adding the `backport/review` or `backport/approved` label (this can be done using [repokitteh]'s +`/backport` command). Changes nominated by the change author and/or members of the Envoy community +are evaluated for backporting on a case-by-case basis, and require approval from either the release +manager of stable release, Envoy maintainers, or Envoy security team. Once approved, those fixes +are backported from the `master` branch to all supported stable branches by the maintainers of +stable releases. New stable versions from non-critical security fixes are released on a regular +schedule, initially aiming for the bi-weekly releases. + +### Release management + +Release managers of stable releases are responsible for approving and merging backports, tagging +stable releases and sending announcements about them. This role is rotating on a quarterly basis. + +| Quarter | Release manager | +|:-------:|:----------------------------:| +| 2020 Q1 | Piotr Sikora ([PiotrSikora]) | + +## Release schedule + +In order to accommodate downstream projects, new Envoy releases are produced on a fixed release +schedule (at the end of each quarter), with an acceptable delay of up to 2 weeks, with a hard +deadline of 3 weeks. + +| Version | Expected | Actual | Difference | End of Life | +|:-------:|:----------:|:----------:|:----------:|:-----------:| +| 1.12.0 | 2019/09/30 | 2019/10/31 | +31 days | 2020/10/31 | +| 1.13.0 | 2019/12/31 | 2020/01/20 | +20 days | 2021/01/20 | +| 1.14.0 | 2020/03/31 | | | | +| 1.15.0 | 2020/06/30 | | | | +| 1.16.0 | 2020/09/30 | | | | +| 1.17.0 | 2020/12/31 | | | | + + +[repokitteh]: https://github.com/repokitteh +[PiotrSikora]: https://github.com/PiotrSikora From a8a43cb2ef1cca5430d44fa5ae4d56b64940fc62 Mon Sep 17 00:00:00 2001 From: Jose Ulises Nino Rivera Date: Wed, 5 Feb 2020 16:30:48 -0800 Subject: [PATCH 14/87] dns: destroy/reinitialize c-ares channel on ARES_ECONNREFUSED (#9899) Description: this PR adds logic to the DnsResolverImpl to destroy and re-initialize its c-ares channel under certain circumstances. A better option would require work in c-ares https://github.com/c-ares/c-ares/issues/301. Risk Level: med changes in low-level DNS resolution. Testing: unit tests Fixes #4543 Signed-off-by: Jose Nino --- source/common/network/dns_impl.cc | 48 ++++++++++++++---- source/common/network/dns_impl.h | 19 +++++-- test/common/network/dns_impl_test.cc | 74 ++++++++++++++++++++++++++-- tools/spelling_dictionary.txt | 2 + 4 files changed, 125 insertions(+), 18 deletions(-) diff --git a/source/common/network/dns_impl.cc b/source/common/network/dns_impl.cc index c134872b71..505b1bea7d 100644 --- a/source/common/network/dns_impl.cc +++ b/source/common/network/dns_impl.cc @@ -24,16 +24,11 @@ DnsResolverImpl::DnsResolverImpl( const std::vector& resolvers, const bool use_tcp_for_dns_lookups) : dispatcher_(dispatcher), - timer_(dispatcher.createTimer([this] { onEventCallback(ARES_SOCKET_BAD, 0); })) { - ares_options options{}; - int optmask = 0; + timer_(dispatcher.createTimer([this] { onEventCallback(ARES_SOCKET_BAD, 0); })), + use_tcp_for_dns_lookups_(use_tcp_for_dns_lookups) { - if (use_tcp_for_dns_lookups) { - optmask |= ARES_OPT_FLAGS; - options.flags |= ARES_FLAG_USEVC; - } - - initializeChannel(&options, optmask); + AresOptions options = defaultAresOptions(); + initializeChannel(&options.options_, options.optmask_); if (!resolvers.empty()) { std::vector resolver_addrs; @@ -65,6 +60,17 @@ DnsResolverImpl::~DnsResolverImpl() { ares_destroy(channel_); } +DnsResolverImpl::AresOptions DnsResolverImpl::defaultAresOptions() { + AresOptions options{}; + + if (use_tcp_for_dns_lookups_) { + options.optmask_ |= ARES_OPT_FLAGS; + options.options_.flags |= ARES_FLAG_USEVC; + } + + return options; +} + void DnsResolverImpl::initializeChannel(ares_options* options, int optmask) { options->sock_state_cb = [](void* arg, int fd, int read, int write) { static_cast(arg)->onAresSocketStateChange(fd, read, write); @@ -83,6 +89,19 @@ void DnsResolverImpl::PendingResolution::onAresGetAddrInfoCallback(int status, i } if (!fallback_if_failed_) { completed_ = true; + + // If c-ares returns ARES_ECONNREFUSED and there is no fallback we assume that the channel_ is + // broken. Mark the channel dirty so that it is destroyed and reinitialized on a subsequent call + // to DnsResolver::resolve(). The optimal solution would be for c-ares to reinitialize the + // channel, and not have Envoy track side effects. + // context: https://github.com/envoyproxy/envoy/issues/4543 and + // https://github.com/c-ares/c-ares/issues/301. + // + // The channel cannot be destroyed and reinitialized here because that leads to a c-ares + // segfault. + if (status == ARES_ECONNREFUSED) { + parent_.dirty_channel_ = true; + } } std::list address_list; @@ -203,8 +222,17 @@ ActiveDnsQuery* DnsResolverImpl::resolve(const std::string& dns_name, // TODO(hennna): Add DNS caching which will allow testing the edge case of a // failed initial call to getHostByName followed by a synchronous IPv4 // resolution. + + // @see DnsResolverImpl::PendingResolution::onAresGetAddrInfoCallback for why this is done. + if (dirty_channel_) { + dirty_channel_ = false; + ares_destroy(channel_); + + AresOptions options = defaultAresOptions(); + initializeChannel(&options.options_, options.optmask_); + } std::unique_ptr pending_resolution( - new PendingResolution(callback, dispatcher_, channel_, dns_name)); + new PendingResolution(*this, callback, dispatcher_, channel_, dns_name)); if (dns_lookup_family == DnsLookupFamily::Auto) { pending_resolution->fallback_if_failed_ = true; } diff --git a/source/common/network/dns_impl.h b/source/common/network/dns_impl.h index cecad8a2e7..79a140dea6 100644 --- a/source/common/network/dns_impl.h +++ b/source/common/network/dns_impl.h @@ -39,9 +39,10 @@ class DnsResolverImpl : public DnsResolver, protected Logger::Loggable events_; }; diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index 84b1415144..65bc03c10d 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -55,9 +55,9 @@ enum class RecordType { A, AAAA }; class TestDnsServerQuery { public: TestDnsServerQuery(ConnectionPtr connection, const HostMap& hosts_a, const HostMap& hosts_aaaa, - const CNameMap& cnames, const std::chrono::seconds& record_ttl) + const CNameMap& cnames, const std::chrono::seconds& record_ttl, bool refused) : connection_(std::move(connection)), hosts_a_(hosts_a), hosts_aaaa_(hosts_aaaa), - cnames_(cnames), record_ttl_(record_ttl) { + cnames_(cnames), record_ttl_(record_ttl), refused_(refused) { connection_->addReadFilter(Network::ReadFilterSharedPtr{new ReadFilter(*this)}); } @@ -171,7 +171,11 @@ class TestDnsServerQuery { memcpy(response_base, request, response_base_len); DNS_HEADER_SET_QR(response_base, 1); DNS_HEADER_SET_AA(response_base, 0); - DNS_HEADER_SET_RCODE(response_base, answer_size > 0 ? NOERROR : NXDOMAIN); + if (parent_.refused_) { + DNS_HEADER_SET_RCODE(response_base, REFUSED); + } else { + DNS_HEADER_SET_RCODE(response_base, answer_size > 0 ? NOERROR : NXDOMAIN); + } DNS_HEADER_SET_ANCOUNT(response_base, answer_size); DNS_HEADER_SET_NSCOUNT(response_base, 0); DNS_HEADER_SET_ARCOUNT(response_base, 0); @@ -253,6 +257,7 @@ class TestDnsServerQuery { const HostMap& hosts_aaaa_; const CNameMap& cnames_; const std::chrono::seconds& record_ttl_; + bool refused_{}; }; class TestDnsServer : public ListenerCallbacks { @@ -263,7 +268,7 @@ class TestDnsServer : public ListenerCallbacks { Network::ConnectionPtr new_connection = dispatcher_.createServerConnection( std::move(socket), Network::Test::createRawBufferSocket()); TestDnsServerQuery* query = new TestDnsServerQuery(std::move(new_connection), hosts_a_, - hosts_aaaa_, cnames_, record_ttl_); + hosts_aaaa_, cnames_, record_ttl_, refused_); queries_.emplace_back(query); } @@ -280,6 +285,7 @@ class TestDnsServer : public ListenerCallbacks { } void setRecordTtl(const std::chrono::seconds& ttl) { record_ttl_ = ttl; } + void setRefused(bool refused) { refused_ = refused; } private: Event::Dispatcher& dispatcher_; @@ -288,6 +294,7 @@ class TestDnsServer : public ListenerCallbacks { HostMap hosts_aaaa_; CNameMap cnames_; std::chrono::seconds record_ttl_; + bool refused_{}; // All queries are tracked so we can do resource reclamation when the test is // over. std::vector> queries_; @@ -300,6 +307,7 @@ class DnsResolverImplPeer { DnsResolverImplPeer(DnsResolverImpl* resolver) : resolver_(resolver) {} ares_channel channel() const { return resolver_->channel_; } + bool isChannelDirty() const { return resolver_->dirty_channel_; } const std::unordered_map& events() { return resolver_->events_; } // Reset the channel state for a DnsResolverImpl such that it will only use // TCP and optionally has a zero timeout (for validating timeout behavior). @@ -582,6 +590,64 @@ TEST_P(DnsImplTest, CallbackException) { "unknown"); } +// Validate that the c-ares channel is destroyed and re-initialized when c-ares returns +// ARES_ECONNREFUSED as its callback status. +TEST_P(DnsImplTest, DestroyChannelOnRefused) { + ASSERT_FALSE(peer_->isChannelDirty()); + server_->addHosts("some.good.domain", {"201.134.56.7"}, RecordType::A); + server_->setRefused(true); + + std::list address_list; + EXPECT_NE(nullptr, resolver_->resolve("", DnsLookupFamily::V4Only, + [&](std::list&& results) -> void { + address_list = getAddressList(results); + dispatcher_->exit(); + })); + + dispatcher_->run(Event::Dispatcher::RunType::Block); + // The c-ares channel should be dirty because the TestDnsServer replied with return code REFUSED; + // This test, and the way the TestDnsServerQuery is setup, relies on the fact that Envoy's + // c-ares channel is configured **without** the ARES_FLAG_NOCHECKRESP flag. This causes c-ares to + // discard packets with REFUSED, and thus Envoy receives ARES_ECONNREFUSED due to the code here: + // https://github.com/c-ares/c-ares/blob/d7e070e7283f822b1d2787903cce3615536c5610/ares_process.c#L654 + // If that flag needs to be set, or c-ares changes its handling this test will need to be updated + // to create another condition where c-ares invokes onAresGetAddrInfoCallback with status == + // ARES_ECONNREFUSED. + EXPECT_TRUE(peer_->isChannelDirty()); + EXPECT_TRUE(address_list.empty()); + + server_->setRefused(false); + + // Resolve will destroy the original channel and create a new one. + EXPECT_NE(nullptr, resolver_->resolve("some.good.domain", DnsLookupFamily::V4Only, + [&](std::list&& results) -> void { + address_list = getAddressList(results); + dispatcher_->exit(); + })); + + dispatcher_->run(Event::Dispatcher::RunType::Block); + // However, the fresh channel initialized by production code does not point to the TestDnsServer. + // This means that resolution will return ARES_ENOTFOUND. This should not dirty the channel. + EXPECT_FALSE(peer_->isChannelDirty()); + EXPECT_TRUE(address_list.empty()); + + // Reset the channel to point to the TestDnsServer, and make sure resolution is healthy. + if (tcp_only()) { + peer_->resetChannelTcpOnly(zero_timeout()); + } + ares_set_servers_ports_csv(peer_->channel(), socket_->localAddress()->asString().c_str()); + + EXPECT_NE(nullptr, resolver_->resolve("some.good.domain", DnsLookupFamily::Auto, + [&](std::list&& results) -> void { + address_list = getAddressList(results); + dispatcher_->exit(); + })); + + dispatcher_->run(Event::Dispatcher::RunType::Block); + EXPECT_FALSE(peer_->isChannelDirty()); + EXPECT_TRUE(hasAddress(address_list, "201.134.56.7")); +} + TEST_P(DnsImplTest, DnsIpAddressVersion) { std::list address_list; server_->addHosts("some.good.domain", {"1.2.3.4"}, RecordType::A); diff --git a/tools/spelling_dictionary.txt b/tools/spelling_dictionary.txt index 3982a43a63..08c43ebb70 100644 --- a/tools/spelling_dictionary.txt +++ b/tools/spelling_dictionary.txt @@ -76,6 +76,7 @@ EDESTRUCTION EDF EINVAL ELB +ENOTFOUND ENOTSUP ENV EOF @@ -181,6 +182,7 @@ NDEBUG NEXTHDR NGHTTP NOAUTH +NOCHECKRESP NODELAY NOLINT NOLINTNEXTLINE From ea7ab31d64a59fb18e46f71a296b68ce0e527e28 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Wed, 5 Feb 2020 21:03:01 -0800 Subject: [PATCH 15/87] tls: update BoringSSL to 08a0b210 (3987). (#9943) Signed-off-by: Piotr Sikora --- bazel/repository_locations.bzl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 33dad22963..06368be355 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -27,15 +27,15 @@ REPOSITORY_LOCATIONS = dict( urls = ["https://github.com/envoyproxy/envoy-build-tools/archive/0a98f4bd8b3eeeaa11a10f6a4fe5c59e7c2e16df.tar.gz"], ), boringssl = dict( - sha256 = "3eea198c8e3f587ffc8ea6acf87d7575f571bbe6dd88ec90405e236303f3dc01", - strip_prefix = "boringssl-65e0aad1b721a5aa67f2a8041cf48f691139bb9f", + sha256 = "3edf2c38687956f632ba4e0784f999ac2f66feb6c0db8d82b9f8f75d3a9ffae6", + strip_prefix = "boringssl-08a0b21059e432352a93c427f1d66bb524ad40ae", # To update BoringSSL, which tracks Chromium releases: - # 1. Open https://omahaproxy.appspot.com/ and note of linux/beta release. + # 1. Open https://omahaproxy.appspot.com/ and note of linux/stable release. # 2. Open https://chromium.googlesource.com/chromium/src/+/refs/tags//DEPS and note . # 3. Find a commit in BoringSSL's "master-with-bazel" branch that merges . # - # chromium-79.0.3945.16 (BETA) - urls = ["https://github.com/google/boringssl/archive/65e0aad1b721a5aa67f2a8041cf48f691139bb9f.tar.gz"], + # chromium-80.0.3987.87 + urls = ["https://github.com/google/boringssl/archive/08a0b21059e432352a93c427f1d66bb524ad40ae.tar.gz"], ), boringssl_fips = dict( sha256 = "b12ad676ee533824f698741bd127f6fbc82c46344398a6d78d25e62c6c418c73", From 9cc7a5caf2961947d6c5eea18a1afbbbc13af82b Mon Sep 17 00:00:00 2001 From: Stephan Zuercher Date: Wed, 5 Feb 2020 21:04:22 -0800 Subject: [PATCH 16/87] access_loggers: use new-style names (#9921) Modifies the well-known-names of the built-in access loggers to use the same name as the extension build system. Risk Level: low, previous name is still accepted Testing: existing tests Docs Changes: updated names Release Notes: updated Deprecated: old names are logged as deprecated Signed-off-by: Stephan Zuercher --- api/envoy/config/accesslog/v2/als.proto | 4 +- api/envoy/config/accesslog/v2/file.proto | 2 +- api/envoy/config/accesslog/v3/accesslog.proto | 12 +- .../filter/accesslog/v2/accesslog.proto | 12 +- .../access_loggers/file/v3/file.proto | 2 +- .../access_loggers/grpc/v3/als.proto | 4 +- configs/envoy_double_proxy_v2.template.yaml | 2 +- configs/envoy_front_proxy_v2.template.yaml | 2 +- .../envoy_service_to_service_v2.template.yaml | 12 +- .../grpc_http1_reverse_bridge_filter.rst | 2 +- docs/root/intro/deprecated.rst | 10 ++ docs/root/intro/version_history.rst | 4 +- examples/cors/backend/front-envoy.yaml | 2 +- examples/cors/frontend/front-envoy.yaml | 2 +- examples/csrf/crosssite/front-envoy.yaml | 2 +- examples/csrf/samesite/front-envoy.yaml | 2 +- examples/fault-injection/envoy.yaml | 2 +- examples/grpc-bridge/client/envoy-proxy.yaml | 2 +- examples/grpc-bridge/server/envoy-proxy.yaml | 2 +- .../envoy/config/accesslog/v2/als.proto | 4 +- .../envoy/config/accesslog/v2/file.proto | 2 +- .../envoy/config/accesslog/v3/accesslog.proto | 12 +- .../filter/accesslog/v2/accesslog.proto | 12 +- .../access_loggers/file/v3/file.proto | 2 +- .../access_loggers/grpc/v3/als.proto | 4 +- .../extensions/access_loggers/file/config.cc | 3 +- .../access_loggers/grpc/http_config.cc | 3 +- .../access_loggers/grpc/tcp_config.cc | 3 +- .../access_loggers/well_known_names.h | 6 +- test/common/access_log/BUILD | 2 + .../common/access_log/access_log_impl_test.cc | 123 +++++++++++------- .../common/router/router_upstream_log_test.cc | 4 +- test/config/integration/server.yaml | 2 +- test/config/utility.cc | 2 +- .../http_grpc_access_log_integration_test.cc | 2 +- .../tcp_grpc_access_log_integration_test.cc | 2 +- .../http_connection_manager/config_test.cc | 6 +- .../http2_upstream_integration_test.cc | 4 +- .../integration/tcp_proxy_integration_test.cc | 2 +- 39 files changed, 165 insertions(+), 117 deletions(-) diff --git a/api/envoy/config/accesslog/v2/als.proto b/api/envoy/config/accesslog/v2/als.proto index 1b949238a5..2486ffb81e 100644 --- a/api/envoy/config/accesslog/v2/als.proto +++ b/api/envoy/config/accesslog/v2/als.proto @@ -17,7 +17,7 @@ option (udpa.annotations.file_migrate).move_to_package = "envoy.extensions.acces // [#protodoc-title: gRPC Access Log Service (ALS)] -// Configuration for the built-in *envoy.http_grpc_access_log* +// Configuration for the built-in *envoy.access_loggers.http_grpc* // :ref:`AccessLog `. This configuration will // populate :ref:`StreamAccessLogsMessage.http_logs // `. @@ -38,7 +38,7 @@ message HttpGrpcAccessLogConfig { repeated string additional_response_trailers_to_log = 4; } -// Configuration for the built-in *envoy.tcp_grpc_access_log* type. This configuration will +// Configuration for the built-in *envoy.access_loggers.tcp_grpc* type. This configuration will // populate *StreamAccessLogsMessage.tcp_logs*. // [#extension: envoy.access_loggers.tcp_grpc] message TcpGrpcAccessLogConfig { diff --git a/api/envoy/config/accesslog/v2/file.proto b/api/envoy/config/accesslog/v2/file.proto index b64b0c4b92..395c396d70 100644 --- a/api/envoy/config/accesslog/v2/file.proto +++ b/api/envoy/config/accesslog/v2/file.proto @@ -16,7 +16,7 @@ option (udpa.annotations.file_migrate).move_to_package = "envoy.extensions.acces // [#extension: envoy.access_loggers.file] // Custom configuration for an :ref:`AccessLog ` -// that writes log entries directly to a file. Configures the built-in *envoy.file_access_log* +// that writes log entries directly to a file. Configures the built-in *envoy.access_loggers.file* // AccessLog. message FileAccessLog { // A path to a local file to which to write the access log entries. diff --git a/api/envoy/config/accesslog/v3/accesslog.proto b/api/envoy/config/accesslog/v3/accesslog.proto index 59c2511039..8bfc999f08 100644 --- a/api/envoy/config/accesslog/v3/accesslog.proto +++ b/api/envoy/config/accesslog/v3/accesslog.proto @@ -30,9 +30,9 @@ message AccessLog { // The name of the access log implementation to instantiate. The name must // match a statically registered access log. Current built-in loggers include: // - // #. "envoy.file_access_log" - // #. "envoy.http_grpc_access_log" - // #. "envoy.tcp_grpc_access_log" + // #. "envoy.access_loggers.file" + // #. "envoy.access_loggers.http_grpc" + // #. "envoy.access_loggers.tcp_grpc" string name = 1; // Filter which is used to determine if the access log needs to be written. @@ -41,11 +41,11 @@ message AccessLog { // Custom configuration that depends on the access log being instantiated. Built-in // configurations include: // - // #. "envoy.file_access_log": :ref:`FileAccessLog + // #. "envoy.access_loggers.file": :ref:`FileAccessLog // ` - // #. "envoy.http_grpc_access_log": :ref:`HttpGrpcAccessLogConfig + // #. "envoy.access_loggers.http_grpc": :ref:`HttpGrpcAccessLogConfig // ` - // #. "envoy.tcp_grpc_access_log": :ref:`TcpGrpcAccessLogConfig + // #. "envoy.access_loggers.tcp_grpc": :ref:`TcpGrpcAccessLogConfig // ` oneof config_type { google.protobuf.Any typed_config = 4; diff --git a/api/envoy/config/filter/accesslog/v2/accesslog.proto b/api/envoy/config/filter/accesslog/v2/accesslog.proto index 7839489731..8a525dee91 100644 --- a/api/envoy/config/filter/accesslog/v2/accesslog.proto +++ b/api/envoy/config/filter/accesslog/v2/accesslog.proto @@ -23,9 +23,9 @@ message AccessLog { // The name of the access log implementation to instantiate. The name must // match a statically registered access log. Current built-in loggers include: // - // #. "envoy.file_access_log" - // #. "envoy.http_grpc_access_log" - // #. "envoy.tcp_grpc_access_log" + // #. "envoy.access_loggers.file" + // #. "envoy.access_loggers.http_grpc" + // #. "envoy.access_loggers.tcp_grpc" string name = 1; // Filter which is used to determine if the access log needs to be written. @@ -34,11 +34,11 @@ message AccessLog { // Custom configuration that depends on the access log being instantiated. Built-in // configurations include: // - // #. "envoy.file_access_log": :ref:`FileAccessLog + // #. "envoy.access_loggers.file": :ref:`FileAccessLog // ` - // #. "envoy.http_grpc_access_log": :ref:`HttpGrpcAccessLogConfig + // #. "envoy.access_loggers.http_grpc": :ref:`HttpGrpcAccessLogConfig // ` - // #. "envoy.tcp_grpc_access_log": :ref:`TcpGrpcAccessLogConfig + // #. "envoy.access_loggers.tcp_grpc": :ref:`TcpGrpcAccessLogConfig // ` oneof config_type { google.protobuf.Struct config = 3 [deprecated = true]; diff --git a/api/envoy/extensions/access_loggers/file/v3/file.proto b/api/envoy/extensions/access_loggers/file/v3/file.proto index 8bd6f99efc..1bcf1afd94 100644 --- a/api/envoy/extensions/access_loggers/file/v3/file.proto +++ b/api/envoy/extensions/access_loggers/file/v3/file.proto @@ -16,7 +16,7 @@ option java_multiple_files = true; // [#extension: envoy.access_loggers.file] // Custom configuration for an :ref:`AccessLog ` -// that writes log entries directly to a file. Configures the built-in *envoy.file_access_log* +// that writes log entries directly to a file. Configures the built-in *envoy.access_loggers.file* // AccessLog. message FileAccessLog { option (udpa.annotations.versioning).previous_message_type = diff --git a/api/envoy/extensions/access_loggers/grpc/v3/als.proto b/api/envoy/extensions/access_loggers/grpc/v3/als.proto index f9d32a75c7..7e059bb55c 100644 --- a/api/envoy/extensions/access_loggers/grpc/v3/als.proto +++ b/api/envoy/extensions/access_loggers/grpc/v3/als.proto @@ -17,7 +17,7 @@ option java_multiple_files = true; // [#protodoc-title: gRPC Access Log Service (ALS)] -// Configuration for the built-in *envoy.http_grpc_access_log* +// Configuration for the built-in *envoy.access_loggers.http_grpc* // :ref:`AccessLog `. This configuration will // populate :ref:`StreamAccessLogsMessage.http_logs // `. @@ -41,7 +41,7 @@ message HttpGrpcAccessLogConfig { repeated string additional_response_trailers_to_log = 4; } -// Configuration for the built-in *envoy.tcp_grpc_access_log* type. This configuration will +// Configuration for the built-in *envoy.access_loggers.tcp_grpc* type. This configuration will // populate *StreamAccessLogsMessage.tcp_logs*. // [#extension: envoy.access_loggers.tcp_grpc] message TcpGrpcAccessLogConfig { diff --git a/configs/envoy_double_proxy_v2.template.yaml b/configs/envoy_double_proxy_v2.template.yaml index 60b938e6a9..9b880b53c8 100644 --- a/configs/envoy_double_proxy_v2.template.yaml +++ b/configs/envoy_double_proxy_v2.template.yaml @@ -63,7 +63,7 @@ common_http_protocol_options: idle_timeout: 840s access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file filter: or_filter: filters: diff --git a/configs/envoy_front_proxy_v2.template.yaml b/configs/envoy_front_proxy_v2.template.yaml index ae61071985..c50b9adb78 100644 --- a/configs/envoy_front_proxy_v2.template.yaml +++ b/configs/envoy_front_proxy_v2.template.yaml @@ -73,7 +73,7 @@ common_http_protocol_options: idle_timeout: 840s access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file filter: or_filter: filters: diff --git a/configs/envoy_service_to_service_v2.template.yaml b/configs/envoy_service_to_service_v2.template.yaml index c58416f1e2..3e1c893c42 100644 --- a/configs/envoy_service_to_service_v2.template.yaml +++ b/configs/envoy_service_to_service_v2.template.yaml @@ -48,14 +48,14 @@ - name: envoy.router typed_config: {} access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file filter: not_health_check_filter: {} typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/var/log/envoy/ingress_http.log" {{ access_log_helper.ingress_full()|indent(10)}} - - name: envoy.file_access_log + - name: envoy.access_loggers.file filter: and_filter: filters: @@ -84,7 +84,7 @@ "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/var/log/envoy/ingress_http_error.log" {{ access_log_helper.ingress_sampled_log()|indent(10)}} - - name: envoy.file_access_log + - name: envoy.access_loggers.file filter: and_filter: filters: @@ -131,7 +131,7 @@ static_resources: common_http_protocol_options: idle_timeout: 840s access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file filter: or_filter: filters: @@ -192,7 +192,7 @@ static_resources: common_http_protocol_options: idle_timeout: 840s access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file filter: or_filter: filters: @@ -270,7 +270,7 @@ static_resources: - name: envoy.router typed_config: {} access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file filter: or_filter: filters: diff --git a/docs/root/configuration/http/http_filters/grpc_http1_reverse_bridge_filter.rst b/docs/root/configuration/http/http_filters/grpc_http1_reverse_bridge_filter.rst index 21ac6b6ce6..baebebfb92 100644 --- a/docs/root/configuration/http/http_filters/grpc_http1_reverse_bridge_filter.rst +++ b/docs/root/configuration/http/http_filters/grpc_http1_reverse_bridge_filter.rst @@ -63,7 +63,7 @@ How to disable HTTP/1.1 reverse bridge filter per route typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/stdout diff --git a/docs/root/intro/deprecated.rst b/docs/root/intro/deprecated.rst index c591472974..87849c6da7 100644 --- a/docs/root/intro/deprecated.rst +++ b/docs/root/intro/deprecated.rst @@ -15,6 +15,16 @@ Deprecated items below are listed in chronological order. * The previous behavior for upstream connection pool circuit breaking described `here `_ has been deprecated in favor of the new behavior described :ref:`here `. +* Access Logger names have been deprecated in favor of the extension name from the envoy build + system. + + .. csv-table:: + :header: Canonical Names, Deprecated Names + :widths: 1, 1 + + envoy.access_loggers.file, envoy.file_access_log + envoy.access_loggers.http_grpc, envoy.http_grpc_access_log + envoy.access_loggers.tcp_grpc, envoy.tcp_grpc_access_log 1.13.0 (January 20, 2020) ========================= diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index f2f60d9ecf..1d918da540 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -3,6 +3,8 @@ Version history 1.14.0 (Pending) ================ +* access loggers: access logger extensions use the "envoy.access_loggers" name space. A mapping + of extension names is available in the :ref:`deprecated ` documentation. * config: use type URL to select an extension whenever the config type URL (or its previous versions) uniquely identify a typed extension, see :ref:`extension configuration `. * http: fixing a bug in HTTP/1.0 responses where Connection: keep-alive was not appended for connections which were kept alive. * retry: added a retry predicate that :ref:`rejects hosts based on metadata. ` @@ -17,7 +19,7 @@ Version history "envoy.reloadable_features.new_http2_connection_pool_behavior" and then re-configure your clusters or restart Envoy. The behavior will not switch until the connection pools are recreated. The new circuit breaker behavior is described :ref:`here `. -* upstream: changed load distribution algorithm when all priorities enter :ref:`panic mode`. +* upstream: changed load distribution algorithm when all priorities enter :ref:`panic mode`. 1.13.0 (January 20, 2020) ========================= diff --git a/examples/cors/backend/front-envoy.yaml b/examples/cors/backend/front-envoy.yaml index b98d210758..ee1e4a55d3 100644 --- a/examples/cors/backend/front-envoy.yaml +++ b/examples/cors/backend/front-envoy.yaml @@ -12,7 +12,7 @@ static_resources: codec_type: auto stat_prefix: ingress_http access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/var/log/access.log" diff --git a/examples/cors/frontend/front-envoy.yaml b/examples/cors/frontend/front-envoy.yaml index c2379d5efc..54aa839d91 100644 --- a/examples/cors/frontend/front-envoy.yaml +++ b/examples/cors/frontend/front-envoy.yaml @@ -12,7 +12,7 @@ static_resources: codec_type: auto stat_prefix: ingress_http access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/var/log/access.log" diff --git a/examples/csrf/crosssite/front-envoy.yaml b/examples/csrf/crosssite/front-envoy.yaml index 23b14510e9..45c7c4d017 100644 --- a/examples/csrf/crosssite/front-envoy.yaml +++ b/examples/csrf/crosssite/front-envoy.yaml @@ -12,7 +12,7 @@ static_resources: codec_type: auto stat_prefix: ingress_http access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/var/log/access.log" diff --git a/examples/csrf/samesite/front-envoy.yaml b/examples/csrf/samesite/front-envoy.yaml index ed82deeb22..f91ed4c1e2 100644 --- a/examples/csrf/samesite/front-envoy.yaml +++ b/examples/csrf/samesite/front-envoy.yaml @@ -12,7 +12,7 @@ static_resources: codec_type: auto stat_prefix: ingress_http access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/var/log/access.log" diff --git a/examples/fault-injection/envoy.yaml b/examples/fault-injection/envoy.yaml index 3c42501078..6d6d592548 100644 --- a/examples/fault-injection/envoy.yaml +++ b/examples/fault-injection/envoy.yaml @@ -12,7 +12,7 @@ static_resources: codec_type: auto stat_prefix: ingress_http access_log: - name: envoy.file_access_log + name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/stdout diff --git a/examples/grpc-bridge/client/envoy-proxy.yaml b/examples/grpc-bridge/client/envoy-proxy.yaml index ca798eb7eb..99ff531717 100644 --- a/examples/grpc-bridge/client/envoy-proxy.yaml +++ b/examples/grpc-bridge/client/envoy-proxy.yaml @@ -12,7 +12,7 @@ static_resources: codec_type: auto add_user_agent: true access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/dev/stdout" diff --git a/examples/grpc-bridge/server/envoy-proxy.yaml b/examples/grpc-bridge/server/envoy-proxy.yaml index de25aa91f8..6bce532b46 100644 --- a/examples/grpc-bridge/server/envoy-proxy.yaml +++ b/examples/grpc-bridge/server/envoy-proxy.yaml @@ -12,7 +12,7 @@ static_resources: codec_type: auto stat_prefix: ingress_http access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/dev/stdout" diff --git a/generated_api_shadow/envoy/config/accesslog/v2/als.proto b/generated_api_shadow/envoy/config/accesslog/v2/als.proto index 1b949238a5..2486ffb81e 100644 --- a/generated_api_shadow/envoy/config/accesslog/v2/als.proto +++ b/generated_api_shadow/envoy/config/accesslog/v2/als.proto @@ -17,7 +17,7 @@ option (udpa.annotations.file_migrate).move_to_package = "envoy.extensions.acces // [#protodoc-title: gRPC Access Log Service (ALS)] -// Configuration for the built-in *envoy.http_grpc_access_log* +// Configuration for the built-in *envoy.access_loggers.http_grpc* // :ref:`AccessLog `. This configuration will // populate :ref:`StreamAccessLogsMessage.http_logs // `. @@ -38,7 +38,7 @@ message HttpGrpcAccessLogConfig { repeated string additional_response_trailers_to_log = 4; } -// Configuration for the built-in *envoy.tcp_grpc_access_log* type. This configuration will +// Configuration for the built-in *envoy.access_loggers.tcp_grpc* type. This configuration will // populate *StreamAccessLogsMessage.tcp_logs*. // [#extension: envoy.access_loggers.tcp_grpc] message TcpGrpcAccessLogConfig { diff --git a/generated_api_shadow/envoy/config/accesslog/v2/file.proto b/generated_api_shadow/envoy/config/accesslog/v2/file.proto index b64b0c4b92..395c396d70 100644 --- a/generated_api_shadow/envoy/config/accesslog/v2/file.proto +++ b/generated_api_shadow/envoy/config/accesslog/v2/file.proto @@ -16,7 +16,7 @@ option (udpa.annotations.file_migrate).move_to_package = "envoy.extensions.acces // [#extension: envoy.access_loggers.file] // Custom configuration for an :ref:`AccessLog ` -// that writes log entries directly to a file. Configures the built-in *envoy.file_access_log* +// that writes log entries directly to a file. Configures the built-in *envoy.access_loggers.file* // AccessLog. message FileAccessLog { // A path to a local file to which to write the access log entries. diff --git a/generated_api_shadow/envoy/config/accesslog/v3/accesslog.proto b/generated_api_shadow/envoy/config/accesslog/v3/accesslog.proto index e87b551e23..42398bfbbd 100644 --- a/generated_api_shadow/envoy/config/accesslog/v3/accesslog.proto +++ b/generated_api_shadow/envoy/config/accesslog/v3/accesslog.proto @@ -26,9 +26,9 @@ message AccessLog { // The name of the access log implementation to instantiate. The name must // match a statically registered access log. Current built-in loggers include: // - // #. "envoy.file_access_log" - // #. "envoy.http_grpc_access_log" - // #. "envoy.tcp_grpc_access_log" + // #. "envoy.access_loggers.file" + // #. "envoy.access_loggers.http_grpc" + // #. "envoy.access_loggers.tcp_grpc" string name = 1; // Filter which is used to determine if the access log needs to be written. @@ -37,11 +37,11 @@ message AccessLog { // Custom configuration that depends on the access log being instantiated. Built-in // configurations include: // - // #. "envoy.file_access_log": :ref:`FileAccessLog + // #. "envoy.access_loggers.file": :ref:`FileAccessLog // ` - // #. "envoy.http_grpc_access_log": :ref:`HttpGrpcAccessLogConfig + // #. "envoy.access_loggers.http_grpc": :ref:`HttpGrpcAccessLogConfig // ` - // #. "envoy.tcp_grpc_access_log": :ref:`TcpGrpcAccessLogConfig + // #. "envoy.access_loggers.tcp_grpc": :ref:`TcpGrpcAccessLogConfig // ` oneof config_type { google.protobuf.Struct hidden_envoy_deprecated_config = 3 [deprecated = true]; diff --git a/generated_api_shadow/envoy/config/filter/accesslog/v2/accesslog.proto b/generated_api_shadow/envoy/config/filter/accesslog/v2/accesslog.proto index 7839489731..8a525dee91 100644 --- a/generated_api_shadow/envoy/config/filter/accesslog/v2/accesslog.proto +++ b/generated_api_shadow/envoy/config/filter/accesslog/v2/accesslog.proto @@ -23,9 +23,9 @@ message AccessLog { // The name of the access log implementation to instantiate. The name must // match a statically registered access log. Current built-in loggers include: // - // #. "envoy.file_access_log" - // #. "envoy.http_grpc_access_log" - // #. "envoy.tcp_grpc_access_log" + // #. "envoy.access_loggers.file" + // #. "envoy.access_loggers.http_grpc" + // #. "envoy.access_loggers.tcp_grpc" string name = 1; // Filter which is used to determine if the access log needs to be written. @@ -34,11 +34,11 @@ message AccessLog { // Custom configuration that depends on the access log being instantiated. Built-in // configurations include: // - // #. "envoy.file_access_log": :ref:`FileAccessLog + // #. "envoy.access_loggers.file": :ref:`FileAccessLog // ` - // #. "envoy.http_grpc_access_log": :ref:`HttpGrpcAccessLogConfig + // #. "envoy.access_loggers.http_grpc": :ref:`HttpGrpcAccessLogConfig // ` - // #. "envoy.tcp_grpc_access_log": :ref:`TcpGrpcAccessLogConfig + // #. "envoy.access_loggers.tcp_grpc": :ref:`TcpGrpcAccessLogConfig // ` oneof config_type { google.protobuf.Struct config = 3 [deprecated = true]; diff --git a/generated_api_shadow/envoy/extensions/access_loggers/file/v3/file.proto b/generated_api_shadow/envoy/extensions/access_loggers/file/v3/file.proto index 8bd6f99efc..1bcf1afd94 100644 --- a/generated_api_shadow/envoy/extensions/access_loggers/file/v3/file.proto +++ b/generated_api_shadow/envoy/extensions/access_loggers/file/v3/file.proto @@ -16,7 +16,7 @@ option java_multiple_files = true; // [#extension: envoy.access_loggers.file] // Custom configuration for an :ref:`AccessLog ` -// that writes log entries directly to a file. Configures the built-in *envoy.file_access_log* +// that writes log entries directly to a file. Configures the built-in *envoy.access_loggers.file* // AccessLog. message FileAccessLog { option (udpa.annotations.versioning).previous_message_type = diff --git a/generated_api_shadow/envoy/extensions/access_loggers/grpc/v3/als.proto b/generated_api_shadow/envoy/extensions/access_loggers/grpc/v3/als.proto index f9d32a75c7..7e059bb55c 100644 --- a/generated_api_shadow/envoy/extensions/access_loggers/grpc/v3/als.proto +++ b/generated_api_shadow/envoy/extensions/access_loggers/grpc/v3/als.proto @@ -17,7 +17,7 @@ option java_multiple_files = true; // [#protodoc-title: gRPC Access Log Service (ALS)] -// Configuration for the built-in *envoy.http_grpc_access_log* +// Configuration for the built-in *envoy.access_loggers.http_grpc* // :ref:`AccessLog `. This configuration will // populate :ref:`StreamAccessLogsMessage.http_logs // `. @@ -41,7 +41,7 @@ message HttpGrpcAccessLogConfig { repeated string additional_response_trailers_to_log = 4; } -// Configuration for the built-in *envoy.tcp_grpc_access_log* type. This configuration will +// Configuration for the built-in *envoy.access_loggers.tcp_grpc* type. This configuration will // populate *StreamAccessLogsMessage.tcp_logs*. // [#extension: envoy.access_loggers.tcp_grpc] message TcpGrpcAccessLogConfig { diff --git a/source/extensions/access_loggers/file/config.cc b/source/extensions/access_loggers/file/config.cc index 9d58ba10d8..dca4268868 100644 --- a/source/extensions/access_loggers/file/config.cc +++ b/source/extensions/access_loggers/file/config.cc @@ -81,7 +81,8 @@ FileAccessLogFactory::convertJsonFormatToMap(ProtobufWkt::Struct json_format) { /** * Static registration for the file access log. @see RegisterFactory. */ -REGISTER_FACTORY(FileAccessLogFactory, Server::Configuration::AccessLogInstanceFactory); +REGISTER_FACTORY(FileAccessLogFactory, + Server::Configuration::AccessLogInstanceFactory){"envoy.file_access_log"}; } // namespace File } // namespace AccessLoggers diff --git a/source/extensions/access_loggers/grpc/http_config.cc b/source/extensions/access_loggers/grpc/http_config.cc index 0351d0b8ac..6655c9f615 100644 --- a/source/extensions/access_loggers/grpc/http_config.cc +++ b/source/extensions/access_loggers/grpc/http_config.cc @@ -44,7 +44,8 @@ std::string HttpGrpcAccessLogFactory::name() const { return AccessLogNames::get( /** * Static registration for the HTTP gRPC access log. @see RegisterFactory. */ -REGISTER_FACTORY(HttpGrpcAccessLogFactory, Server::Configuration::AccessLogInstanceFactory); +REGISTER_FACTORY(HttpGrpcAccessLogFactory, + Server::Configuration::AccessLogInstanceFactory){"envoy.http_grpc_access_log"}; } // namespace HttpGrpc } // namespace AccessLoggers diff --git a/source/extensions/access_loggers/grpc/tcp_config.cc b/source/extensions/access_loggers/grpc/tcp_config.cc index acdf897c0e..80d985dce2 100644 --- a/source/extensions/access_loggers/grpc/tcp_config.cc +++ b/source/extensions/access_loggers/grpc/tcp_config.cc @@ -43,7 +43,8 @@ std::string TcpGrpcAccessLogFactory::name() const { return AccessLogNames::get() /** * Static registration for the TCP gRPC access log. @see RegisterFactory. */ -REGISTER_FACTORY(TcpGrpcAccessLogFactory, Server::Configuration::AccessLogInstanceFactory); +REGISTER_FACTORY(TcpGrpcAccessLogFactory, + Server::Configuration::AccessLogInstanceFactory){"envoy.tcp_grpc_access_log"}; } // namespace TcpGrpc } // namespace AccessLoggers diff --git a/source/extensions/access_loggers/well_known_names.h b/source/extensions/access_loggers/well_known_names.h index dc55f536bf..56aca60de3 100644 --- a/source/extensions/access_loggers/well_known_names.h +++ b/source/extensions/access_loggers/well_known_names.h @@ -15,11 +15,11 @@ namespace AccessLoggers { class AccessLogNameValues { public: // File access log - const std::string File = "envoy.file_access_log"; + const std::string File = "envoy.access_loggers.file"; // HTTP gRPC access log - const std::string HttpGrpc = "envoy.http_grpc_access_log"; + const std::string HttpGrpc = "envoy.access_loggers.http_grpc"; // TCP gRPC access log - const std::string TcpGrpc = "envoy.tcp_grpc_access_log"; + const std::string TcpGrpc = "envoy.access_loggers.tcp_grpc"; }; using AccessLogNames = ConstSingleton; diff --git a/test/common/access_log/BUILD b/test/common/access_log/BUILD index c320b3c4d0..8fdc442375 100644 --- a/test/common/access_log/BUILD +++ b/test/common/access_log/BUILD @@ -53,6 +53,8 @@ envoy_cc_test( deps = [ "//source/common/access_log:access_log_lib", "//source/extensions/access_loggers/file:config", + "//source/extensions/access_loggers/grpc:http_config", + "//source/extensions/access_loggers/grpc:tcp_config", "//test/common/stream_info:test_util", "//test/common/upstream:utility_lib", "//test/mocks/access_log:access_log_mocks", diff --git a/test/common/access_log/access_log_impl_test.cc b/test/common/access_log/access_log_impl_test.cc index 6db216d4a4..4e31029700 100644 --- a/test/common/access_log/access_log_impl_test.cc +++ b/test/common/access_log/access_log_impl_test.cc @@ -9,6 +9,7 @@ #include "envoy/upstream/upstream.h" #include "common/access_log/access_log_impl.h" +#include "common/config/utility.h" #include "common/protobuf/message_validator_impl.h" #include "common/runtime/runtime_impl.h" #include "common/runtime/uuid_util.h" @@ -65,7 +66,7 @@ class AccessLogImplTest : public testing::Test { TEST_F(AccessLogImplTest, LogMoreData) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -88,7 +89,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, DownstreamDisconnect) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -110,7 +111,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, RouteName) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -137,7 +138,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, EnvoyUpstreamServiceTime) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -156,7 +157,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, NoFilter) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -176,7 +177,7 @@ TEST_F(AccessLogImplTest, UpstreamHost) { stream_info_.upstream_host_ = Upstream::makeTestHostDescription(cluster, "tcp://10.0.0.5:1234"); const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -193,7 +194,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, WithFilterMiss) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: or_filter: filters: @@ -225,7 +226,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, WithFilterHit) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: or_filter: filters: @@ -268,7 +269,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, RuntimeFilter) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: runtime_filter: runtime_key: access_log.test_key @@ -307,7 +308,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, RuntimeFilterV2) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: runtime_filter: runtime_key: access_log.test_key @@ -349,7 +350,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, RuntimeFilterV2IndependentRandomness) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: runtime_filter: runtime_key: access_log.test_key @@ -383,7 +384,7 @@ TEST_F(AccessLogImplTest, PathRewrite) { request_headers_ = {{":method", "GET"}, {":path", "/foo"}, {"x-envoy-original-path", "/bar"}}; const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -400,7 +401,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, HealthCheckTrue) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: not_health_check_filter: {} typed_config: @@ -419,7 +420,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, HealthCheckFalse) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: not_health_check_filter: {} typed_config: @@ -446,7 +447,7 @@ TEST_F(AccessLogImplTest, RequestTracing) { UuidUtils::setTraceableUuid(sample_tracing_guid, UuidTraceStatus::Sampled); const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: traceable_filter: {} typed_config: @@ -480,7 +481,7 @@ TEST(AccessLogImplTestCtor, FiltersMissingInOrAndFilter) { { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: or_filter: {} typed_config: @@ -494,7 +495,7 @@ name: envoy.file_access_log { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: and_filter: {} typed_config: @@ -509,7 +510,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, AndFilter) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: and_filter: filters: @@ -545,7 +546,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, OrFilter) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: or_filter: filters: @@ -580,7 +581,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, MultipleOperators) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: and_filter: filters: @@ -691,7 +692,7 @@ TEST(AccessLogFilterTest, StatusCodeWithRuntimeKey) { TEST_F(AccessLogImplTest, StatusCodeLessThan) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: status_code_filter: comparison: @@ -719,7 +720,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, HeaderPresence) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: header_filter: header: @@ -741,7 +742,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, HeaderExactMatch) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: header_filter: header: @@ -770,7 +771,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, HeaderRegexMatch) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: header_filter: header: @@ -805,7 +806,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, HeaderRangeMatch) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: header_filter: header: @@ -850,7 +851,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, ResponseFlagFilterAnyFlag) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: response_flag_filter: {} typed_config: @@ -870,7 +871,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, ResponseFlagFilterSpecificFlag) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: response_flag_filter: flags: @@ -896,7 +897,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, ResponseFlagFilterSeveralFlags) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: response_flag_filter: flags: @@ -923,7 +924,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, ResponseFlagFilterAllFlagsInPGV) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: response_flag_filter: flags: @@ -945,7 +946,7 @@ name: envoy.file_access_log - URX - SI - IH - - DPE + - DPE typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -988,7 +989,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, ResponseFlagFilterUnsupportedFlag) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: response_flag_filter: flags: @@ -1006,7 +1007,7 @@ name: envoy.file_access_log "[\"embedded message failed validation\"] | caused by " "ResponseFlagFilterValidationError.Flags[i]: [\"value must be in list \" [\"LH\" \"UH\" " "\"UT\" \"LR\" \"UR\" \"UF\" \"UC\" \"UO\" \"NR\" \"DI\" \"FI\" \"RL\" \"UAEX\" \"RLSE\" " - "\"DC\" \"URX\" \"SI\" \"IH\" \"DPE\"]]): name: \"envoy.file_access_log\"\nfilter {\n " + "\"DC\" \"URX\" \"SI\" \"IH\" \"DPE\"]]): name: \"envoy.access_loggers.file\"\nfilter {\n " "response_flag_filter {\n flags: \"UnsupportedFlag\"\n }\n}\ntyped_config {\n " "[type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog] {\n path: \"/dev/null\"\n " "}\n}\n"); @@ -1014,7 +1015,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, ValidateTypedConfig) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: response_flag_filter: flags: @@ -1032,7 +1033,7 @@ name: envoy.file_access_log "[\"embedded message failed validation\"] | caused by " "ResponseFlagFilterValidationError.Flags[i]: [\"value must be in list \" [\"LH\" \"UH\" " "\"UT\" \"LR\" \"UR\" \"UF\" \"UC\" \"UO\" \"NR\" \"DI\" \"FI\" \"RL\" \"UAEX\" \"RLSE\" " - "\"DC\" \"URX\" \"SI\" \"IH\" \"DPE\"]]): name: \"envoy.file_access_log\"\nfilter {\n " + "\"DC\" \"URX\" \"SI\" \"IH\" \"DPE\"]]): name: \"envoy.access_loggers.file\"\nfilter {\n " "response_flag_filter {\n flags: \"UnsupportedFlag\"\n }\n}\ntyped_config {\n " "[type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog] {\n path: \"/dev/null\"\n " "}\n}\n"); @@ -1040,7 +1041,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, GrpcStatusFilterValues) { const std::string yaml_template = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: grpc_status_filter: statuses: @@ -1071,7 +1072,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, GrpcStatusFilterUnsupportedValue) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: grpc_status_filter: statuses: @@ -1087,7 +1088,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, GrpcStatusFilterBlock) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: grpc_status_filter: statuses: @@ -1108,7 +1109,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, GrpcStatusFilterHttpCodes) { const std::string yaml_template = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: grpc_status_filter: statuses: @@ -1140,7 +1141,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, GrpcStatusFilterNoCode) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: grpc_status_filter: statuses: @@ -1159,7 +1160,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, GrpcStatusFilterExclude) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: grpc_status_filter: exclude: true @@ -1184,7 +1185,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, GrpcStatusFilterExcludeFalse) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: grpc_status_filter: exclude: false @@ -1206,7 +1207,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, GrpcStatusFilterHeader) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: grpc_status_filter: statuses: @@ -1250,7 +1251,7 @@ TEST_F(AccessLogImplTest, TestHeaderFilterPresence) { Registry::RegisterFactory registered; const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: extension_filter: name: test_header_filter @@ -1326,7 +1327,7 @@ TEST_F(AccessLogImplTest, SampleExtensionFilter) { Registry::RegisterFactory registered; const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: extension_filter: name: sample_extension_filter @@ -1354,7 +1355,7 @@ name: envoy.file_access_log TEST_F(AccessLogImplTest, UnregisteredExtensionFilter) { { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: extension_filter: name: unregistered_extension_filter @@ -1373,7 +1374,7 @@ name: envoy.file_access_log { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file filter: extension_filter: name: bar @@ -1387,6 +1388,36 @@ name: envoy.file_access_log } } +// Test that the deprecated extension names still function. +TEST_F(AccessLogImplTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + { + envoy::config::accesslog::v3::AccessLog config; + config.set_name("envoy.file_access_log"); + + EXPECT_NO_THROW( + Config::Utility::getAndCheckFactory( + config)); + } + + { + envoy::config::accesslog::v3::AccessLog config; + config.set_name("envoy.http_grpc_access_log"); + + EXPECT_NO_THROW( + Config::Utility::getAndCheckFactory( + config)); + } + + { + envoy::config::accesslog::v3::AccessLog config; + config.set_name("envoy.tcp_grpc_access_log"); + + EXPECT_NO_THROW( + Config::Utility::getAndCheckFactory( + config)); + } +} + } // namespace } // namespace AccessLog } // namespace Envoy diff --git a/test/common/router/router_upstream_log_test.cc b/test/common/router/router_upstream_log_test.cc index ad40d7c9be..0e2fa80922 100644 --- a/test/common/router/router_upstream_log_test.cc +++ b/test/common/router/router_upstream_log_test.cc @@ -38,7 +38,7 @@ namespace { absl::optional testUpstreamLog() { // Custom format without timestamps or durations. const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog format: "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL% %RESPONSE_CODE% @@ -280,7 +280,7 @@ TEST_F(RouterUpstreamLogTest, LogHeaders) { // Test timestamps and durations are emitted. TEST_F(RouterUpstreamLogTest, LogTimestampsAndDurations) { const std::string yaml = R"EOF( -name: envoy.file_access_log +name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog format: "[%START_TIME%] %REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL% diff --git a/test/config/integration/server.yaml b/test/config/integration/server.yaml index 15456cc95b..78551fe8a1 100644 --- a/test/config/integration/server.yaml +++ b/test/config/integration/server.yaml @@ -50,7 +50,7 @@ static_resources: typed_config: "@type": type.googleapis.com/envoy.config.filter.http.router.v2.Router access_log: - - name: envoy.file_access_log + - name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null diff --git a/test/config/utility.cc b/test/config/utility.cc index e4514f59e1..4c9a0f2b89 100644 --- a/test/config/utility.cc +++ b/test/config/utility.cc @@ -117,7 +117,7 @@ const std::string ConfigHelper::HTTP_PROXY_CONFIG = BASE_CONFIG + R"EOF( name: envoy.router codec_type: HTTP1 access_log: - name: envoy.file_access_log + name: envoy.access_loggers.file filter: not_health_check_filter: {} typed_config: diff --git a/test/extensions/access_loggers/grpc/http_grpc_access_log_integration_test.cc b/test/extensions/access_loggers/grpc/http_grpc_access_log_integration_test.cc index 2d329b1384..dfd048e506 100644 --- a/test/extensions/access_loggers/grpc/http_grpc_access_log_integration_test.cc +++ b/test/extensions/access_loggers/grpc/http_grpc_access_log_integration_test.cc @@ -43,7 +43,7 @@ class AccessLogIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm) { auto* access_log = hcm.add_access_log(); - access_log->set_name("envoy.http_grpc_access_log"); + access_log->set_name("envoy.access_loggers.http_grpc"); envoy::extensions::access_loggers::grpc::v3::HttpGrpcAccessLogConfig config; auto* common_config = config.mutable_common_config(); diff --git a/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc b/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc index fa7936b7f1..ac006cff1b 100644 --- a/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc +++ b/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc @@ -60,7 +60,7 @@ class TcpGrpcAccessLogIntegrationTest : public Grpc::GrpcClientIntegrationParamT MessageUtil::anyConvert( *config_blob); auto* access_log = tcp_proxy_config.add_access_log(); - access_log->set_name("envoy.tcp_grpc_access_log"); + access_log->set_name("envoy.access_loggers.tcp_grpc"); envoy::extensions::access_loggers::grpc::v3::TcpGrpcAccessLogConfig access_log_config; auto* common_config = access_log_config.mutable_common_config(); common_config->set_log_name("foo"); diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index 1b26306abc..4012048958 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -877,7 +877,7 @@ stat_prefix: my_stat_prefix - name: envoy.http_dynamo_filter config: {} access_log: -- name: envoy.file_access_log +- name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/dev/null" @@ -906,7 +906,7 @@ stat_prefix: my_stat_prefix - name: envoy.http_dynamo_filter typed_config: {} access_log: -- name: envoy.file_access_log +- name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/dev/null" @@ -936,7 +936,7 @@ stat_prefix: my_stat_prefix - name: envoy.http_dynamo_filter typed_config: {} access_log: -- name: envoy.file_access_log +- name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/dev/null" diff --git a/test/integration/http2_upstream_integration_test.cc b/test/integration/http2_upstream_integration_test.cc index 418ad053be..1285ffb6c9 100644 --- a/test/integration/http2_upstream_integration_test.cc +++ b/test/integration/http2_upstream_integration_test.cc @@ -330,7 +330,7 @@ name: envoy.router typed_config: "@type": type.googleapis.com/envoy.config.filter.http.router.v2.Router upstream_log: - name: envoy.file_access_log + name: envoy.access_loggers.file filter: not_health_check_filter: {} typed_config: @@ -455,7 +455,7 @@ name: envoy.router typed_config: "@type": type.googleapis.com/envoy.config.filter.http.router.v2.Router upstream_log: - name: envoy.http_grpc_access_log + name: envoy.access_loggers.http_grpc filter: not_health_check_filter: {} typed_config: diff --git a/test/integration/tcp_proxy_integration_test.cc b/test/integration/tcp_proxy_integration_test.cc index a7c6b424d8..6520ed2a97 100644 --- a/test/integration/tcp_proxy_integration_test.cc +++ b/test/integration/tcp_proxy_integration_test.cc @@ -248,7 +248,7 @@ TEST_P(TcpProxyIntegrationTest, AccessLog) { envoy::config::filter::network::tcp_proxy::v2::TcpProxy)>(*config_blob); auto* access_log = tcp_proxy_config.add_access_log(); - access_log->set_name("envoy.file_access_log"); + access_log->set_name("envoy.access_loggers.file"); envoy::extensions::access_loggers::file::v3::FileAccessLog access_log_config; access_log_config.set_path(access_log_path); access_log_config.set_format( From 8c2d8f19c5611d1da306de36d9935584aabe9745 Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Wed, 5 Feb 2020 21:06:31 -0800 Subject: [PATCH 17/87] transport socket: hash SAN transport socket options (#9901) Signed-off-by: Lizan Zhou --- .../network/transport_socket_options_impl.cc | 6 +++++ .../upstream/cluster_manager_impl_test.cc | 22 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/source/common/network/transport_socket_options_impl.cc b/source/common/network/transport_socket_options_impl.cc index fed22159d0..f9419f016b 100644 --- a/source/common/network/transport_socket_options_impl.cc +++ b/source/common/network/transport_socket_options_impl.cc @@ -17,6 +17,12 @@ void TransportSocketOptionsImpl::hashKey(std::vector& key) const { pushScalarToByteVector(StringUtil::CaseInsensitiveHash()(override_server_name_.value()), key); } + if (!override_verify_san_list_.empty()) { + for (const auto& san : override_verify_san_list_) { + pushScalarToByteVector(StringUtil::CaseInsensitiveHash()(san), key); + } + } + if (!override_alpn_list_.empty()) { for (const auto& protocol : override_alpn_list_) { pushScalarToByteVector(StringUtil::CaseInsensitiveHash()(protocol), key); diff --git a/test/common/upstream/cluster_manager_impl_test.cc b/test/common/upstream/cluster_manager_impl_test.cc index 7619c13afa..3c84c25d55 100644 --- a/test/common/upstream/cluster_manager_impl_test.cc +++ b/test/common/upstream/cluster_manager_impl_test.cc @@ -1833,6 +1833,16 @@ TEST_F(ClusterManagerImplTest, DynamicHostRemoveWithTls) { ON_CALL(example_com_context, upstreamTransportSocketOptions()) .WillByDefault(Return(std::make_shared("example.com"))); + NiceMock example_com_context_with_san; + ON_CALL(example_com_context_with_san, upstreamTransportSocketOptions()) + .WillByDefault(Return(std::make_shared( + "example.com", std::vector{"example.com"}))); + + NiceMock example_com_context_with_san2; + ON_CALL(example_com_context_with_san2, upstreamTransportSocketOptions()) + .WillByDefault(Return(std::make_shared( + "example.com", std::vector{"example.net"}))); + NiceMock ibm_com_context; ON_CALL(ibm_com_context, upstreamTransportSocketOptions()) .WillByDefault(Return(std::make_shared("ibm.com"))); @@ -1896,7 +1906,7 @@ TEST_F(ClusterManagerImplTest, DynamicHostRemoveWithTls) { EXPECT_CALL(*cp1_high, addDrainedCallback(_)).WillOnce(SaveArg<0>(&drained_cb_high)); EXPECT_CALL(factory_, allocateTcpConnPool_(_)) - .Times(8) + .Times(10) .WillRepeatedly(ReturnNew()); // This should provide us a CP for each of the above hosts, and for different SNIs @@ -2000,6 +2010,12 @@ TEST_F(ClusterManagerImplTest, DynamicHostRemoveWithTls) { Tcp::ConnectionPool::MockInstance* tcp3_example_com = dynamic_cast(cluster_manager_->tcpConnPoolForCluster( "cluster_1", ResourcePriority::Default, &example_com_context)); + Tcp::ConnectionPool::MockInstance* tcp3_example_com_with_san = + dynamic_cast(cluster_manager_->tcpConnPoolForCluster( + "cluster_1", ResourcePriority::Default, &example_com_context_with_san)); + Tcp::ConnectionPool::MockInstance* tcp3_example_com_with_san2 = + dynamic_cast(cluster_manager_->tcpConnPoolForCluster( + "cluster_1", ResourcePriority::Default, &example_com_context_with_san2)); Tcp::ConnectionPool::MockInstance* tcp3_ibm_com = dynamic_cast(cluster_manager_->tcpConnPoolForCluster( "cluster_1", ResourcePriority::Default, &ibm_com_context)); @@ -2010,6 +2026,10 @@ TEST_F(ClusterManagerImplTest, DynamicHostRemoveWithTls) { EXPECT_EQ(tcp2_example_com, tcp3_example_com); EXPECT_EQ(tcp2_ibm_com, tcp3_ibm_com); + EXPECT_NE(tcp3_example_com, tcp3_example_com_with_san); + EXPECT_NE(tcp3_example_com, tcp3_example_com_with_san2); + EXPECT_NE(tcp3_example_com_with_san, tcp3_example_com_with_san2); + // Now add and remove a host that we never have a conn pool to. This should not lead to any // drain callbacks, etc. dns_timer_->invokeCallback(); From 58c71def4bcbf9947c4c9dd8dd81e924c63fd995 Mon Sep 17 00:00:00 2001 From: Matt Klein Date: Thu, 6 Feb 2020 09:01:16 -0800 Subject: [PATCH 18/87] statsd: do not use connect() to send datagrams (#9898) This allows stats to work if the server is not yet listening. As part of this change also clean up some UDP tests to use a common synchronous helper. Fixes https://github.com/envoyproxy/envoy/issues/8911 Signed-off-by: Matt Klein --- .../stat_sinks/common/statsd/statsd.cc | 26 ++--- .../stat_sinks/common/statsd/statsd.h | 47 ++++---- test/common/network/udp_listener_impl_test.cc | 103 +++--------------- .../udp_proxy/udp_proxy_integration_test.cc | 39 +------ .../common/statsd/udp_statsd_test.cc | 92 ++++++++++------ test/test_common/network_utility.cc | 22 ++++ test/test_common/network_utility.h | 20 ++++ 7 files changed, 157 insertions(+), 192 deletions(-) diff --git a/source/extensions/stat_sinks/common/statsd/statsd.cc b/source/extensions/stat_sinks/common/statsd/statsd.cc index 8146f8c93d..5782935fb7 100644 --- a/source/extensions/stat_sinks/common/statsd/statsd.cc +++ b/source/extensions/stat_sinks/common/statsd/statsd.cc @@ -15,6 +15,7 @@ #include "common/common/fmt.h" #include "common/common/utility.h" #include "common/config/utility.h" +#include "common/network/utility.h" #include "common/stats/symbol_table_impl.h" #include "absl/strings/str_join.h" @@ -25,22 +26,15 @@ namespace StatSinks { namespace Common { namespace Statsd { -Writer::Writer(Network::Address::InstanceConstSharedPtr address) - : io_handle_(address->socket(Network::Address::SocketType::Datagram)) { - ASSERT(io_handle_->fd() != -1); +UdpStatsdSink::WriterImpl::WriterImpl(UdpStatsdSink& parent) + : parent_(parent), + io_handle_(parent_.server_address_->socket(Network::Address::SocketType::Datagram)) {} - const Api::SysCallIntResult result = address->connect(io_handle_->fd()); - ASSERT(result.rc_ != -1); -} - -Writer::~Writer() { - if (io_handle_->isOpen()) { - RELEASE_ASSERT(io_handle_->close().err_ == nullptr, ""); - } -} - -void Writer::write(const std::string& message) { - ::send(io_handle_->fd(), message.c_str(), message.size(), MSG_DONTWAIT); +void UdpStatsdSink::WriterImpl::write(const std::string& message) { + // TODO(mattklein123): We can avoid this const_cast pattern by having a constant variant of + // RawSlice. This can be fixed elsewhere as well. + Buffer::RawSlice slice{const_cast(message.c_str()), message.size()}; + Network::Utility::writeToSocket(*io_handle_, &slice, 1, nullptr, *parent_.server_address_); } UdpStatsdSink::UdpStatsdSink(ThreadLocal::SlotAllocator& tls, @@ -49,7 +43,7 @@ UdpStatsdSink::UdpStatsdSink(ThreadLocal::SlotAllocator& tls, : tls_(tls.allocateSlot()), server_address_(std::move(address)), use_tag_(use_tag), prefix_(prefix.empty() ? Statsd::getDefaultPrefix() : prefix) { tls_->set([this](Event::Dispatcher&) -> ThreadLocal::ThreadLocalObjectSharedPtr { - return std::make_shared(this->server_address_); + return std::make_shared(*this); }); } diff --git a/source/extensions/stat_sinks/common/statsd/statsd.h b/source/extensions/stat_sinks/common/statsd/statsd.h index fa41cba5a9..41218ace19 100644 --- a/source/extensions/stat_sinks/common/statsd/statsd.h +++ b/source/extensions/stat_sinks/common/statsd/statsd.h @@ -23,29 +23,19 @@ namespace Statsd { static const std::string& getDefaultPrefix() { CONSTRUCT_ON_FIRST_USE(std::string, "envoy"); } -/** - * This is a simple UDP localhost writer for statsd messages. - */ -class Writer : public ThreadLocal::ThreadLocalObject { -public: - Writer(Network::Address::InstanceConstSharedPtr address); - // For testing. - Writer() : io_handle_(std::make_unique()) {} - ~Writer() override; - - virtual void write(const std::string& message); - // Called in unit test to validate address. - int getFdForTests() const { return io_handle_->fd(); } - -private: - Network::IoHandlePtr io_handle_; -}; - /** * Implementation of Sink that writes to a UDP statsd address. */ class UdpStatsdSink : public Stats::Sink { public: + /** + * Base interface for writing UDP datagrams. + */ + class Writer : public ThreadLocal::ThreadLocalObject { + public: + virtual void write(const std::string& message) PURE; + }; + UdpStatsdSink(ThreadLocal::SlotAllocator& tls, Network::Address::InstanceConstSharedPtr address, const bool use_tag, const std::string& prefix = getDefaultPrefix()); // For testing. @@ -61,17 +51,30 @@ class UdpStatsdSink : public Stats::Sink { void flush(Stats::MetricSnapshot& snapshot) override; void onHistogramComplete(const Stats::Histogram& histogram, uint64_t value) override; - // Called in unit test to validate writer construction and address. - int getFdForTests() { return tls_->getTyped().getFdForTests(); } bool getUseTagForTest() { return use_tag_; } const std::string& getPrefix() { return prefix_; } private: + /** + * This is a simple UDP localhost writer for statsd messages. + */ + class WriterImpl : public Writer { + public: + WriterImpl(UdpStatsdSink& parent); + + // Writer + void write(const std::string& message) override; + + private: + UdpStatsdSink& parent_; + const Network::IoHandlePtr io_handle_; + }; + const std::string getName(const Stats::Metric& metric) const; const std::string buildTagStr(const std::vector& tags) const; - ThreadLocal::SlotPtr tls_; - Network::Address::InstanceConstSharedPtr server_address_; + const ThreadLocal::SlotPtr tls_; + const Network::Address::InstanceConstSharedPtr server_address_; const bool use_tag_; // Prefix for all flushed stats. const std::string prefix_; diff --git a/test/common/network/udp_listener_impl_test.cc b/test/common/network/udp_listener_impl_test.cc index 7682aa27cc..1bdd6790e1 100644 --- a/test/common/network/udp_listener_impl_test.cc +++ b/test/common/network/udp_listener_impl_test.cc @@ -68,11 +68,6 @@ class UdpListenerImplTest : public ListenerImplTestBase { bind); } - SocketPtr createClientSocket(bool bind) { - return std::make_unique>>( - Network::Test::getCanonicalLoopbackAddress(version_), nullptr, bind); - } - // Validates receive data, source/destination address and received time. void validateRecvCallbackParams(const UdpRecvData& data) { ASSERT_NE(data.addresses_.local_, nullptr); @@ -83,7 +78,7 @@ class UdpListenerImplTest : public ListenerImplTestBase { EXPECT_EQ(data.addresses_.local_->asString(), send_to_addr_->asString()); EXPECT_EQ(data.addresses_.peer_->ip()->addressAsString(), - client_socket_->localAddress()->ip()->addressAsString()); + client_.localAddress()->ip()->addressAsString()); EXPECT_EQ(*data.addresses_.local_, *send_to_addr_); EXPECT_EQ(time_system_.monotonicTime(), data.receive_time_); @@ -92,7 +87,7 @@ class UdpListenerImplTest : public ListenerImplTestBase { } SocketSharedPtr server_socket_; - SocketPtr client_socket_; + Network::Test::UdpSyncPeer client_{GetParam()}; Address::InstanceConstSharedPtr send_to_addr_; MockUdpListenerCallbacks listener_callbacks_; std::unique_ptr listener_; @@ -130,24 +125,11 @@ TEST_P(UdpListenerImplTest, UdpSetListeningSocketOptionsSuccess) { * Tests UDP listener for actual destination and data. */ TEST_P(UdpListenerImplTest, UseActualDstUdp) { - // Setup client socket. - client_socket_ = createClientSocket(false); - // We send 2 packets const std::string first("first"); - const void* void_pointer = static_cast(first.c_str()); - Buffer::RawSlice first_slice{const_cast(void_pointer), first.length()}; + client_.write(first, *send_to_addr_); const std::string second("second"); - void_pointer = static_cast(second.c_str()); - Buffer::RawSlice second_slice{const_cast(void_pointer), second.length()}; - - auto send_rc = Network::Utility::writeToSocket(client_socket_->ioHandle(), &first_slice, 1, - nullptr, *send_to_addr_); - ASSERT_EQ(send_rc.rc_, first.length()); - - send_rc = Network::Utility::writeToSocket(client_socket_->ioHandle(), &second_slice, 1, nullptr, - *send_to_addr_); - ASSERT_EQ(send_rc.rc_, second.length()); + client_.write(second, *send_to_addr_); EXPECT_CALL(listener_callbacks_, onReadReady()); EXPECT_CALL(listener_callbacks_, onData(_)) @@ -176,24 +158,11 @@ TEST_P(UdpListenerImplTest, UseActualDstUdp) { * Tests UDP listener for read and write callbacks with actual data. */ TEST_P(UdpListenerImplTest, UdpEcho) { - // Setup client socket. - client_socket_ = createClientSocket(false); - // We send 2 packets and expect it to echo. const std::string first("first"); - const void* void_pointer = static_cast(first.c_str()); - Buffer::RawSlice first_slice{const_cast(void_pointer), first.length()}; + client_.write(first, *send_to_addr_); const std::string second("second"); - void_pointer = static_cast(second.c_str()); - Buffer::RawSlice second_slice{const_cast(void_pointer), second.length()}; - - auto send_rc = Network::Utility::writeToSocket(client_socket_->ioHandle(), &first_slice, 1, - nullptr, *send_to_addr_); - ASSERT_EQ(send_rc.rc_, first.length()); - - send_rc = Network::Utility::writeToSocket(client_socket_->ioHandle(), &second_slice, 1, nullptr, - *send_to_addr_); - ASSERT_EQ(send_rc.rc_, second.length()); + client_.write(second, *send_to_addr_); // For unit test purposes, we assume that the data was received in order. Address::InstanceConstSharedPtr test_peer_address; @@ -231,9 +200,10 @@ TEST_P(UdpListenerImplTest, UdpEcho) { const void* void_data = static_cast(data.c_str() + total_sent); Buffer::RawSlice slice{const_cast(void_data), data_size - total_sent}; + Api::IoCallUint64Result send_rc = Api::ioCallUint64ResultNoError(); do { - auto send_rc = Network::Utility::writeToSocket(const_cast(&socket)->ioHandle(), - &slice, 1, nullptr, *test_peer_address); + send_rc = Network::Utility::writeToSocket(const_cast(&socket)->ioHandle(), &slice, + 1, nullptr, *test_peer_address); if (send_rc.ok()) { total_sent += send_rc.rc_; @@ -264,29 +234,15 @@ TEST_P(UdpListenerImplTest, UdpListenerEnableDisable) { auto const* server_ip = server_socket_->localAddress()->ip(); ASSERT_NE(server_ip, nullptr); - // Setup client socket. - client_socket_ = createClientSocket(false); - // We first disable the listener and then send two packets. // - With the listener disabled, we expect that none of the callbacks will be // called. // - When the listener is enabled back, we expect the callbacks to be called + listener_->disable(); const std::string first("first"); - const void* void_pointer = static_cast(first.c_str()); - Buffer::RawSlice first_slice{const_cast(void_pointer), first.length()}; + client_.write(first, *send_to_addr_); const std::string second("second"); - void_pointer = static_cast(second.c_str()); - Buffer::RawSlice second_slice{const_cast(void_pointer), second.length()}; - - listener_->disable(); - - auto send_rc = Network::Utility::writeToSocket(client_socket_->ioHandle(), &first_slice, 1, - nullptr, *send_to_addr_); - ASSERT_EQ(send_rc.rc_, first.length()); - - send_rc = Network::Utility::writeToSocket(client_socket_->ioHandle(), &second_slice, 1, nullptr, - *send_to_addr_); - ASSERT_EQ(send_rc.rc_, second.length()); + client_.write(second, *send_to_addr_); EXPECT_CALL(listener_callbacks_, onReadReady()).Times(0); EXPECT_CALL(listener_callbacks_, onData(_)).Times(0); @@ -324,17 +280,10 @@ TEST_P(UdpListenerImplTest, UdpListenerRecvMsgError) { auto const* server_ip = server_socket_->localAddress()->ip(); ASSERT_NE(server_ip, nullptr); - client_socket_ = createClientSocket(false); - // When the `receive` system call returns an error, we expect the `onReceiveError` // callback called with `SyscallError` parameter. const std::string first("first"); - const void* void_pointer = static_cast(first.c_str()); - Buffer::RawSlice first_slice{const_cast(void_pointer), first.length()}; - - auto send_rc = Network::Utility::writeToSocket(client_socket_->ioHandle(), &first_slice, 1, - nullptr, *send_to_addr_); - ASSERT_EQ(send_rc.rc_, first.length()); + client_.write(first, *send_to_addr_); EXPECT_CALL(listener_callbacks_, onData(_)).Times(0); @@ -364,10 +313,6 @@ TEST_P(UdpListenerImplTest, UdpListenerRecvMsgError) { * address. */ TEST_P(UdpListenerImplTest, SendData) { - // Setup client socket. - client_socket_ = createClientSocket(true); - ASSERT_NE(client_socket_, nullptr); - const std::string payload("hello world"); Buffer::InstancePtr buffer(new Buffer::OwnedImpl()); buffer->add(payload); @@ -398,32 +343,16 @@ TEST_P(UdpListenerImplTest, SendData) { server_socket_->localAddress()->ip()->port())); } - UdpSendData send_data{send_from_addr->ip(), *client_socket_->localAddress(), *buffer}; + UdpSendData send_data{send_from_addr->ip(), *client_.localAddress(), *buffer}; auto send_result = listener_->send(send_data); EXPECT_TRUE(send_result.ok()) << "send() failed : " << send_result.err_->getErrorDetails(); const uint64_t bytes_to_read = payload.length(); - uint64_t bytes_read = 0; - int retry = 0; UdpRecvData data; - - do { - Api::IoCallUint64Result result = Network::Test::readFromSocket( - client_socket_->ioHandle(), *client_socket_->localAddress(), data); - - bytes_read = result.rc_; - if (bytes_read >= bytes_to_read || retry == 10 || - result.err_->getErrorCode() != Api::IoError::IoErrorCode::Again) { - break; - } - - retry++; - absl::SleepFor(absl::Milliseconds(10)); - ASSERT(bytes_read == 0); - } while (true); - EXPECT_EQ(bytes_to_read, bytes_read); + client_.recv(data); + EXPECT_EQ(bytes_to_read, data.buffer_->length()); EXPECT_EQ(send_from_addr->asString(), data.addresses_.peer_->asString()); EXPECT_EQ(data.buffer_->toString(), payload); } diff --git a/test/extensions/filters/udp/udp_proxy/udp_proxy_integration_test.cc b/test/extensions/filters/udp/udp_proxy/udp_proxy_integration_test.cc index 1fc8b543ec..830a8a5831 100644 --- a/test/extensions/filters/udp/udp_proxy/udp_proxy_integration_test.cc +++ b/test/extensions/filters/udp/udp_proxy/udp_proxy_integration_test.cc @@ -1,40 +1,11 @@ #include "envoy/config/bootstrap/v3/bootstrap.pb.h" #include "test/integration/integration.h" +#include "test/test_common/network_utility.h" namespace Envoy { namespace { -/** - * A synchronous UDP client used for testing. - */ -class UdpSyncClient { -public: - UdpSyncClient(Network::Address::IpVersion version) - : socket_(std::make_unique( - Network::Test::getCanonicalLoopbackAddress(version), nullptr, true)) { - // TODO(mattklein123): Right now all sockets are non-blocking. Move this non-blocking - // modification black to the abstraction layer so it will work for multiple platforms. - RELEASE_ASSERT(fcntl(socket_->ioHandle().fd(), F_SETFL, 0) != -1, ""); - } - - void write(const std::string& buffer, const Network::Address::Instance& peer) { - const auto rc = Network::Utility::writeToSocket(socket_->ioHandle(), Buffer::OwnedImpl(buffer), - nullptr, peer); - ASSERT_EQ(rc.rc_, buffer.length()); - } - - void recv(Network::UdpRecvData& datagram) { - datagram = Network::UdpRecvData(); - const auto rc = - Network::Test::readFromSocket(socket_->ioHandle(), *socket_->localAddress(), datagram); - ASSERT_TRUE(rc.ok()); - } - -private: - const Network::SocketPtr socket_; -}; - class UdpProxyIntegrationTest : public testing::TestWithParam, public BaseIntegrationTest { public: @@ -83,7 +54,7 @@ class UdpProxyIntegrationTest : public testing::TestWithParam( + TestEnvironment::unixDomainSocketPath("udstest.1.sock")); + NiceMock tls_; + NiceMock snapshot; + UdpStatsdSink sink(tls_, uds_address, false); + + NiceMock counter; + counter.name_ = "test_counter"; + counter.used_ = true; + counter.latch_ = 1; + snapshot.counters_.push_back({1, counter}); + + // Flush before the server is running. This will fail. + sink.flush(snapshot); + + // Start the server. + // TODO(mattklein123): Right now all sockets are non-blocking. Move this non-blocking + // modification back to the abstraction layer so it will work for multiple platforms. Additionally + // this uses low level networking calls because our abstractions in this area only work for IP + // sockets. Revisit this also. + auto io_handle = uds_address->socket(Network::Address::SocketType::Datagram); + RELEASE_ASSERT(fcntl(io_handle->fd(), F_SETFL, 0) != -1, ""); + uds_address->bind(io_handle->fd()); + + // Do the flush which should have somewhere to write now. + sink.flush(snapshot); + Buffer::OwnedImpl receive_buffer; + receive_buffer.read(*io_handle, 32); + EXPECT_EQ("envoy.test_counter:1|c", receive_buffer.toString()); +} + class UdpStatsdSinkTest : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P(IpVersions, UdpStatsdSinkTest, testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), @@ -39,15 +72,10 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, UdpStatsdSinkTest, TEST_P(UdpStatsdSinkTest, InitWithIpAddress) { NiceMock tls_; - NiceMock snapshot; // UDP statsd server address. - Network::Address::InstanceConstSharedPtr server_address = - Network::Utility::parseInternetAddressAndPort( - fmt::format("{}:8125", Network::Test::getLoopbackAddressUrlString(GetParam()))); - UdpStatsdSink sink(tls_, server_address, false); - int fd = sink.getFdForTests(); - EXPECT_NE(fd, -1); - - // Check that fd has not changed. + NiceMock snapshot; + Network::Test::UdpSyncPeer server(GetParam()); + UdpStatsdSink sink(tls_, server.localAddress(), false); + NiceMock counter; counter.name_ = "test_counter"; counter.used_ = true; @@ -61,18 +89,20 @@ TEST_P(UdpStatsdSinkTest, InitWithIpAddress) { snapshot.gauges_.push_back(gauge); sink.flush(snapshot); + Network::UdpRecvData data; + server.recv(data); + EXPECT_EQ("envoy.test_counter:1|c", data.buffer_->toString()); + Network::UdpRecvData data2; + server.recv(data2); + EXPECT_EQ("envoy.test_gauge:1|g", data2.buffer_->toString()); NiceMock timer; timer.name_ = "test_timer"; sink.onHistogramComplete(timer, 5); + Network::UdpRecvData data3; + server.recv(data3); + EXPECT_EQ("envoy.test_timer:5|ms", data3.buffer_->toString()); - EXPECT_EQ(fd, sink.getFdForTests()); - - if (GetParam() == Network::Address::IpVersion::v4) { - EXPECT_EQ("127.0.0.1:8125", Network::Address::peerAddressFromFd(fd)->asString()); - } else { - EXPECT_EQ("[::1]:8125", Network::Address::peerAddressFromFd(fd)->asString()); - } tls_.shutdownThread(); } @@ -84,15 +114,9 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, UdpStatsdSinkWithTagsTest, TEST_P(UdpStatsdSinkWithTagsTest, InitWithIpAddress) { NiceMock tls_; NiceMock snapshot; - // UDP statsd server address. - Network::Address::InstanceConstSharedPtr server_address = - Network::Utility::parseInternetAddressAndPort( - fmt::format("{}:8125", Network::Test::getLoopbackAddressUrlString(GetParam()))); - UdpStatsdSink sink(tls_, server_address, true); - int fd = sink.getFdForTests(); - EXPECT_NE(fd, -1); - - // Check that fd has not changed. + Network::Test::UdpSyncPeer server(GetParam()); + UdpStatsdSink sink(tls_, server.localAddress(), true); + std::vector tags = {Stats::Tag{"node", "test"}}; NiceMock counter; counter.name_ = "test_counter"; @@ -109,19 +133,21 @@ TEST_P(UdpStatsdSinkWithTagsTest, InitWithIpAddress) { snapshot.gauges_.push_back(gauge); sink.flush(snapshot); + Network::UdpRecvData data; + server.recv(data); + EXPECT_EQ("envoy.test_counter:1|c|#node:test", data.buffer_->toString()); + Network::UdpRecvData data2; + server.recv(data2); + EXPECT_EQ("envoy.test_gauge:1|g|#node:test", data2.buffer_->toString()); NiceMock timer; timer.name_ = "test_timer"; timer.setTags(tags); sink.onHistogramComplete(timer, 5); + Network::UdpRecvData data3; + server.recv(data3); + EXPECT_EQ("envoy.test_timer:5|ms|#node:test", data3.buffer_->toString()); - EXPECT_EQ(fd, sink.getFdForTests()); - - if (GetParam() == Network::Address::IpVersion::v4) { - EXPECT_EQ("127.0.0.1:8125", Network::Address::peerAddressFromFd(fd)->asString()); - } else { - EXPECT_EQ("[::1]:8125", Network::Address::peerAddressFromFd(fd)->asString()); - } tls_.shutdownThread(); } diff --git a/test/test_common/network_utility.cc b/test/test_common/network_utility.cc index 207925f1ca..1bf6535846 100644 --- a/test/test_common/network_utility.cc +++ b/test/test_common/network_utility.cc @@ -8,6 +8,7 @@ #include "common/common/assert.h" #include "common/common/fmt.h" #include "common/network/address_impl.h" +#include "common/network/listen_socket_impl.h" #include "common/network/raw_buffer_socket.h" #include "common/network/utility.h" #include "common/runtime/runtime_impl.h" @@ -214,6 +215,27 @@ Api::IoCallUint64Result readFromSocket(IoHandle& handle, const Address::Instance MonotonicTime(std::chrono::seconds(0)), nullptr); } +UdpSyncPeer::UdpSyncPeer(Network::Address::IpVersion version) + : socket_( + std::make_unique(getCanonicalLoopbackAddress(version), nullptr, true)) { + // TODO(mattklein123): Right now all sockets are non-blocking. Move this non-blocking + // modification back to the abstraction layer so it will work for multiple platforms. + RELEASE_ASSERT(fcntl(socket_->ioHandle().fd(), F_SETFL, 0) != -1, ""); +} + +void UdpSyncPeer::write(const std::string& buffer, const Network::Address::Instance& peer) { + const auto rc = Network::Utility::writeToSocket(socket_->ioHandle(), Buffer::OwnedImpl(buffer), + nullptr, peer); + ASSERT_EQ(rc.rc_, buffer.length()); +} + +void UdpSyncPeer::recv(Network::UdpRecvData& datagram) { + datagram = Network::UdpRecvData(); + const auto rc = + Network::Test::readFromSocket(socket_->ioHandle(), *socket_->localAddress(), datagram); + ASSERT_TRUE(rc.ok()); +} + } // namespace Test } // namespace Network } // namespace Envoy diff --git a/test/test_common/network_utility.h b/test/test_common/network_utility.h index a3410bf700..d3e155fb94 100644 --- a/test/test_common/network_utility.h +++ b/test/test_common/network_utility.h @@ -168,6 +168,26 @@ const FilterChainSharedPtr createEmptyFilterChainWithRawBufferSockets(); Api::IoCallUint64Result readFromSocket(IoHandle& handle, const Address::Instance& local_address, UdpRecvData& data); +/** + * A synchronous UDP peer that can be used for testing. + */ +class UdpSyncPeer { +public: + UdpSyncPeer(Network::Address::IpVersion version); + + // Writer a datagram to a remote peer. + void write(const std::string& buffer, const Network::Address::Instance& peer); + + // Receive a datagram. + void recv(Network::UdpRecvData& datagram); + + // Return the local peer's socket address. + const Network::Address::InstanceConstSharedPtr& localAddress() { return socket_->localAddress(); } + +private: + const Network::SocketPtr socket_; +}; + } // namespace Test } // namespace Network } // namespace Envoy From 8f174ab84d21c36a927f7adf2f7c1e4d4ad20122 Mon Sep 17 00:00:00 2001 From: Pengyuan Bian Date: Thu, 6 Feb 2020 09:15:12 -0800 Subject: [PATCH 19/87] Allow set sts as call credential for opencensus tracer stub (#9877) Signed-off-by: Pengyuan Bian --- api/envoy/config/trace/v2/trace.proto | 7 +++- api/envoy/config/trace/v3/trace.proto | 7 +++- docs/root/intro/version_history.rst | 3 +- .../envoy/config/trace/v2/trace.proto | 7 +++- .../envoy/config/trace/v3/trace.proto | 7 +++- source/common/grpc/BUILD | 4 +++ .../common/grpc/google_async_client_impl.cc | 3 +- source/common/grpc/google_async_client_impl.h | 3 -- source/common/grpc/google_grpc_creds_impl.cc | 20 ----------- source/common/grpc/google_grpc_utils.cc | 33 +++++++++++++++++++ source/common/grpc/google_grpc_utils.h | 11 +++++++ source/extensions/tracers/opencensus/BUILD | 1 + .../extensions/tracers/opencensus/config.cc | 3 +- .../opencensus/opencensus_tracer_impl.cc | 18 +++++++++- .../opencensus/opencensus_tracer_impl.h | 3 +- .../tracers/opencensus/tracer_test.cc | 9 +++-- tools/spelling_dictionary.txt | 1 + 17 files changed, 104 insertions(+), 36 deletions(-) diff --git a/api/envoy/config/trace/v2/trace.proto b/api/envoy/config/trace/v2/trace.proto index edb5dbce54..4d87a03429 100644 --- a/api/envoy/config/trace/v2/trace.proto +++ b/api/envoy/config/trace/v2/trace.proto @@ -142,7 +142,7 @@ message DatadogConfig { } // Configuration for the OpenCensus tracer. -// [#next-free-field: 13] +// [#next-free-field: 14] // [#extension: envoy.tracers.opencensus] message OpenCensusConfig { enum TraceContext { @@ -184,6 +184,11 @@ message OpenCensusConfig { // https://github.com/grpc/grpc/blob/master/doc/naming.md string stackdriver_address = 10; + // (optional) The gRPC server that hosts Stackdriver tracing service. Only + // Google gRPC is supported. If :ref:`target_uri ` + // is not provided, the default production Stackdriver address will be used. + api.v2.core.GrpcService stackdriver_grpc_service = 13; + // Enables the Zipkin exporter if set to true. The url and service name must // also be set. bool zipkin_exporter_enabled = 5; diff --git a/api/envoy/config/trace/v3/trace.proto b/api/envoy/config/trace/v3/trace.proto index f2c5442e23..ec5ac0a511 100644 --- a/api/envoy/config/trace/v3/trace.proto +++ b/api/envoy/config/trace/v3/trace.proto @@ -162,7 +162,7 @@ message DatadogConfig { } // Configuration for the OpenCensus tracer. -// [#next-free-field: 13] +// [#next-free-field: 14] // [#extension: envoy.tracers.opencensus] message OpenCensusConfig { option (udpa.annotations.versioning).previous_message_type = @@ -207,6 +207,11 @@ message OpenCensusConfig { // https://github.com/grpc/grpc/blob/master/doc/naming.md string stackdriver_address = 10; + // (optional) The gRPC server that hosts Stackdriver tracing service. Only + // Google gRPC is supported. If :ref:`target_uri ` + // is not provided, the default production Stackdriver address will be used. + core.v3.GrpcService stackdriver_grpc_service = 13; + // Enables the Zipkin exporter if set to true. The url and service name must // also be set. bool zipkin_exporter_enabled = 5; diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index 1d918da540..186ba2de61 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -11,6 +11,7 @@ Version history * router: added the ability to match a route based on whether a downstream TLS connection certificate has been :ref:`validated `. * sds: added :ref:`GenericSecret ` to support secret of generic type. +* tracing: added gRPC service configuration to the OpenCensus Stackdriver tracer. * upstream: combined HTTP/1 and HTTP/2 connection pool code. This means that circuit breaker limits for both requests and connections apply to both pool types. Also, HTTP/2 now has the option to limit concurrent requests on a connection, and allow multiple draining @@ -19,7 +20,7 @@ Version history "envoy.reloadable_features.new_http2_connection_pool_behavior" and then re-configure your clusters or restart Envoy. The behavior will not switch until the connection pools are recreated. The new circuit breaker behavior is described :ref:`here `. -* upstream: changed load distribution algorithm when all priorities enter :ref:`panic mode`. +* upstream: changed load distribution algorithm when all priorities enter :ref:`panic mode`. 1.13.0 (January 20, 2020) ========================= diff --git a/generated_api_shadow/envoy/config/trace/v2/trace.proto b/generated_api_shadow/envoy/config/trace/v2/trace.proto index edb5dbce54..4d87a03429 100644 --- a/generated_api_shadow/envoy/config/trace/v2/trace.proto +++ b/generated_api_shadow/envoy/config/trace/v2/trace.proto @@ -142,7 +142,7 @@ message DatadogConfig { } // Configuration for the OpenCensus tracer. -// [#next-free-field: 13] +// [#next-free-field: 14] // [#extension: envoy.tracers.opencensus] message OpenCensusConfig { enum TraceContext { @@ -184,6 +184,11 @@ message OpenCensusConfig { // https://github.com/grpc/grpc/blob/master/doc/naming.md string stackdriver_address = 10; + // (optional) The gRPC server that hosts Stackdriver tracing service. Only + // Google gRPC is supported. If :ref:`target_uri ` + // is not provided, the default production Stackdriver address will be used. + api.v2.core.GrpcService stackdriver_grpc_service = 13; + // Enables the Zipkin exporter if set to true. The url and service name must // also be set. bool zipkin_exporter_enabled = 5; diff --git a/generated_api_shadow/envoy/config/trace/v3/trace.proto b/generated_api_shadow/envoy/config/trace/v3/trace.proto index 09f182c03b..03eb068ab3 100644 --- a/generated_api_shadow/envoy/config/trace/v3/trace.proto +++ b/generated_api_shadow/envoy/config/trace/v3/trace.proto @@ -160,7 +160,7 @@ message DatadogConfig { } // Configuration for the OpenCensus tracer. -// [#next-free-field: 13] +// [#next-free-field: 14] // [#extension: envoy.tracers.opencensus] message OpenCensusConfig { option (udpa.annotations.versioning).previous_message_type = @@ -205,6 +205,11 @@ message OpenCensusConfig { // https://github.com/grpc/grpc/blob/master/doc/naming.md string stackdriver_address = 10; + // (optional) The gRPC server that hosts Stackdriver tracing service. Only + // Google gRPC is supported. If :ref:`target_uri ` + // is not provided, the default production Stackdriver address will be used. + core.v3.GrpcService stackdriver_grpc_service = 13; + // Enables the Zipkin exporter if set to true. The url and service name must // also be set. bool zipkin_exporter_enabled = 5; diff --git a/source/common/grpc/BUILD b/source/common/grpc/BUILD index 70c9db57d3..051d088129 100644 --- a/source/common/grpc/BUILD +++ b/source/common/grpc/BUILD @@ -124,6 +124,9 @@ envoy_cc_library( "grpc", ], deps = [ + ":google_grpc_creds_lib", + "//include/envoy/api:api_interface", + "//include/envoy/registry", "//source/common/buffer:buffer_lib", "//source/common/common:assert_lib", "//source/common/common:empty_string", @@ -131,6 +134,7 @@ envoy_cc_library( "//source/common/common:macros", "//source/common/common:utility_lib", "//source/common/grpc:status_lib", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) diff --git a/source/common/grpc/google_async_client_impl.cc b/source/common/grpc/google_async_client_impl.cc index 8e7c2d0b85..cd212c0f1d 100644 --- a/source/common/grpc/google_async_client_impl.cc +++ b/source/common/grpc/google_async_client_impl.cc @@ -80,8 +80,7 @@ GoogleAsyncClientImpl::GoogleAsyncClientImpl(Event::Dispatcher& dispatcher, // smart enough to do connection pooling and reuse with identical channel args, so this should // have comparable overhead to what we are doing in Grpc::AsyncClientImpl, i.e. no expensive // new connection implied. - std::shared_ptr creds = getGoogleGrpcChannelCredentials(config, api); - std::shared_ptr channel = CreateChannel(config.google_grpc().target_uri(), creds); + std::shared_ptr channel = GoogleGrpcUtils::createChannel(config, api); stub_ = stub_factory.createStub(channel); // Initialize client stats. stats_.streams_total_ = &scope_->counter("streams_total"); diff --git a/source/common/grpc/google_async_client_impl.h b/source/common/grpc/google_async_client_impl.h index 35628e1b73..3d1fb58ae8 100644 --- a/source/common/grpc/google_async_client_impl.h +++ b/source/common/grpc/google_async_client_impl.h @@ -184,9 +184,6 @@ class GoogleAsyncClientImpl final : public RawAsyncClient, Logger::Loggable - createChannel(const envoy::config::core::v3::GrpcService::GoogleGrpc& config); - Event::Dispatcher& dispatcher_; GoogleAsyncClientThreadLocal& tls_; // This is shared with child streams, so that they can cleanup independent of diff --git a/source/common/grpc/google_grpc_creds_impl.cc b/source/common/grpc/google_grpc_creds_impl.cc index aa2f9b6289..b534c2eebd 100644 --- a/source/common/grpc/google_grpc_creds_impl.cc +++ b/source/common/grpc/google_grpc_creds_impl.cc @@ -152,25 +152,5 @@ class DefaultGoogleGrpcCredentialsFactory : public GoogleGrpcCredentialsFactory */ REGISTER_FACTORY(DefaultGoogleGrpcCredentialsFactory, GoogleGrpcCredentialsFactory); -std::shared_ptr -getGoogleGrpcChannelCredentials(const envoy::config::core::v3::GrpcService& grpc_service, - Api::Api& api) { - GoogleGrpcCredentialsFactory* credentials_factory = nullptr; - const std::string& google_grpc_credentials_factory_name = - grpc_service.google_grpc().credentials_factory_name(); - if (google_grpc_credentials_factory_name.empty()) { - credentials_factory = Registry::FactoryRegistry::getFactory( - "envoy.grpc_credentials.default"); - } else { - credentials_factory = Registry::FactoryRegistry::getFactory( - google_grpc_credentials_factory_name); - } - if (credentials_factory == nullptr) { - throw EnvoyException(absl::StrCat("Unknown google grpc credentials factory: ", - google_grpc_credentials_factory_name)); - } - return credentials_factory->getChannelCredentials(grpc_service, api); -} - } // namespace Grpc } // namespace Envoy diff --git a/source/common/grpc/google_grpc_utils.cc b/source/common/grpc/google_grpc_utils.cc index 9465df31e3..383f814916 100644 --- a/source/common/grpc/google_grpc_utils.cc +++ b/source/common/grpc/google_grpc_utils.cc @@ -5,6 +5,9 @@ #include #include +#include "envoy/grpc/google_grpc_creds.h" +#include "envoy/registry/registry.h" + #include "common/buffer/buffer_impl.h" #include "common/common/assert.h" #include "common/common/empty_string.h" @@ -19,6 +22,30 @@ namespace Envoy { namespace Grpc { +namespace { + +std::shared_ptr +getGoogleGrpcChannelCredentials(const envoy::config::core::v3::GrpcService& grpc_service, + Api::Api& api) { + GoogleGrpcCredentialsFactory* credentials_factory = nullptr; + const std::string& google_grpc_credentials_factory_name = + grpc_service.google_grpc().credentials_factory_name(); + if (google_grpc_credentials_factory_name.empty()) { + credentials_factory = Registry::FactoryRegistry::getFactory( + "envoy.grpc_credentials.default"); + } else { + credentials_factory = Registry::FactoryRegistry::getFactory( + google_grpc_credentials_factory_name); + } + if (credentials_factory == nullptr) { + throw EnvoyException(absl::StrCat("Unknown google grpc credentials factory: ", + google_grpc_credentials_factory_name)); + } + return credentials_factory->getChannelCredentials(grpc_service, api); +} + +} // namespace + struct BufferInstanceContainer { BufferInstanceContainer(int ref_count, Buffer::InstancePtr&& buffer) : ref_count_(ref_count), buffer_(std::move(buffer)) {} @@ -93,5 +120,11 @@ Buffer::InstancePtr GoogleGrpcUtils::makeBufferInstance(const grpc::ByteBuffer& return buffer; } +std::shared_ptr +GoogleGrpcUtils::createChannel(const envoy::config::core::v3::GrpcService& config, Api::Api& api) { + std::shared_ptr creds = getGoogleGrpcChannelCredentials(config, api); + return CreateChannel(config.google_grpc().target_uri(), creds); +} + } // namespace Grpc } // namespace Envoy diff --git a/source/common/grpc/google_grpc_utils.h b/source/common/grpc/google_grpc_utils.h index 476aeaa3ee..03e7c6f618 100644 --- a/source/common/grpc/google_grpc_utils.h +++ b/source/common/grpc/google_grpc_utils.h @@ -3,8 +3,10 @@ #include #include +#include "envoy/api/api.h" #include "envoy/buffer/buffer.h" #include "envoy/common/platform.h" +#include "envoy/config/core/v3/grpc_service.pb.h" #include "grpcpp/grpcpp.h" @@ -28,6 +30,15 @@ class GoogleGrpcUtils { * owning the corresponding grpc::Slice(s) or nullptr if the grpc::ByteBuffer is bad. */ static Buffer::InstancePtr makeBufferInstance(const grpc::ByteBuffer& buffer); + + /** + * Build gRPC channel based on the given GrpcService configuration. + * @param config Google gRPC config. + * @param api reference to the Api object + * @return static std::shared_ptr a gRPC channel. + */ + static std::shared_ptr + createChannel(const envoy::config::core::v3::GrpcService& config, Api::Api& api); }; } // namespace Grpc diff --git a/source/extensions/tracers/opencensus/BUILD b/source/extensions/tracers/opencensus/BUILD index 356b8530ea..0956ae5cce 100644 --- a/source/extensions/tracers/opencensus/BUILD +++ b/source/extensions/tracers/opencensus/BUILD @@ -42,6 +42,7 @@ envoy_cc_library( ], deps = [ "//source/common/config:utility_lib", + "//source/common/grpc:google_async_client_lib", "//source/common/tracing:http_tracer_lib", "@envoy_api//envoy/config/trace/v3:pkg_cc_proto", ], diff --git a/source/extensions/tracers/opencensus/config.cc b/source/extensions/tracers/opencensus/config.cc index 5f9902f990..537e2db13b 100644 --- a/source/extensions/tracers/opencensus/config.cc +++ b/source/extensions/tracers/opencensus/config.cc @@ -18,7 +18,8 @@ OpenCensusTracerFactory::OpenCensusTracerFactory() : FactoryBase(TracerNames::ge Tracing::HttpTracerPtr OpenCensusTracerFactory::createHttpTracerTyped( const envoy::config::trace::v3::OpenCensusConfig& proto_config, Server::Instance& server) { - Tracing::DriverPtr driver = std::make_unique(proto_config, server.localInfo()); + Tracing::DriverPtr driver = + std::make_unique(proto_config, server.localInfo(), server.api()); return std::make_unique(std::move(driver), server.localInfo()); } diff --git a/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc b/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc index 839939638d..2b4fd1f3a7 100644 --- a/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc +++ b/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc @@ -6,6 +6,7 @@ #include "envoy/http/header_map.h" #include "common/common/base64.h" +#include "common/grpc/google_grpc_utils.h" #include "absl/strings/str_cat.h" #include "google/devtools/cloudtrace/v2/tracing.grpc.pb.h" @@ -28,6 +29,8 @@ namespace Extensions { namespace Tracers { namespace OpenCensus { +constexpr char GoogleStackdriverTraceAddress[] = "cloudtrace.googleapis.com"; + namespace { class ConstantValues { @@ -236,7 +239,7 @@ void Span::setSampled(bool sampled) { span_.AddAnnotation("setSampled", {{"sampl } // namespace Driver::Driver(const envoy::config::trace::v3::OpenCensusConfig& oc_config, - const LocalInfo::LocalInfo& localinfo) + const LocalInfo::LocalInfo& localinfo, Api::Api& api) : oc_config_(oc_config), local_info_(localinfo) { if (oc_config.has_trace_config()) { applyTraceConfig(oc_config.trace_config()); @@ -251,6 +254,19 @@ Driver::Driver(const envoy::config::trace::v3::OpenCensusConfig& oc_config, auto channel = grpc::CreateChannel(oc_config.stackdriver_address(), grpc::InsecureChannelCredentials()); opts.trace_service_stub = ::google::devtools::cloudtrace::v2::TraceService::NewStub(channel); + } else if (oc_config.has_stackdriver_grpc_service()) { + if (!oc_config.stackdriver_grpc_service().has_google_grpc()) { + throw EnvoyException("Opencensus stackdriver tracer only support GoogleGrpc."); + } + envoy::config::core::v3::GrpcService stackdriver_service = + oc_config.stackdriver_grpc_service(); + if (stackdriver_service.google_grpc().target_uri().empty()) { + // If stackdriver server address is not provided, the default production stackdriver + // address will be used. + stackdriver_service.mutable_google_grpc()->set_target_uri(GoogleStackdriverTraceAddress); + } + auto channel = Envoy::Grpc::GoogleGrpcUtils::createChannel(stackdriver_service, api); + opts.trace_service_stub = ::google::devtools::cloudtrace::v2::TraceService::NewStub(channel); } ::opencensus::exporters::trace::StackdriverExporter::Register(std::move(opts)); } diff --git a/source/extensions/tracers/opencensus/opencensus_tracer_impl.h b/source/extensions/tracers/opencensus/opencensus_tracer_impl.h index af2aec7a98..6e67900986 100644 --- a/source/extensions/tracers/opencensus/opencensus_tracer_impl.h +++ b/source/extensions/tracers/opencensus/opencensus_tracer_impl.h @@ -1,5 +1,6 @@ #pragma once +#include "envoy/api/api.h" #include "envoy/config/trace/v3/trace.pb.h" #include "envoy/local_info/local_info.h" #include "envoy/tracing/http_tracer.h" @@ -17,7 +18,7 @@ namespace OpenCensus { class Driver : public Tracing::Driver, Logger::Loggable { public: Driver(const envoy::config::trace::v3::OpenCensusConfig& oc_config, - const LocalInfo::LocalInfo& localinfo); + const LocalInfo::LocalInfo& localinfo, Api::Api& api); /** * Implements the abstract Driver's startSpan operation. diff --git a/test/extensions/tracers/opencensus/tracer_test.cc b/test/extensions/tracers/opencensus/tracer_test.cc index c5f990315f..4ac8102db2 100644 --- a/test/extensions/tracers/opencensus/tracer_test.cc +++ b/test/extensions/tracers/opencensus/tracer_test.cc @@ -103,7 +103,8 @@ TEST(OpenCensusTracerTest, Span) { registerSpanCatcher(); OpenCensusConfig oc_config; NiceMock local_info; - std::unique_ptr driver(new OpenCensus::Driver(oc_config, local_info)); + std::unique_ptr driver( + new OpenCensus::Driver(oc_config, local_info, *Api::createApiForTest())); NiceMock config; Http::TestHeaderMapImpl request_headers{ @@ -192,7 +193,8 @@ void testIncomingHeaders( oc_config.add_outgoing_trace_context(OpenCensusConfig::TRACE_CONTEXT); oc_config.add_outgoing_trace_context(OpenCensusConfig::GRPC_TRACE_BIN); oc_config.add_outgoing_trace_context(OpenCensusConfig::CLOUD_TRACE_CONTEXT); - std::unique_ptr driver(new OpenCensus::Driver(oc_config, local_info)); + std::unique_ptr driver( + new OpenCensus::Driver(oc_config, local_info, *Api::createApiForTest())); NiceMock config; Http::TestHeaderMapImpl request_headers{ {":path", "/"}, @@ -279,7 +281,8 @@ namespace { int SamplerTestHelper(const OpenCensusConfig& oc_config) { registerSpanCatcher(); NiceMock local_info; - std::unique_ptr driver(new OpenCensus::Driver(oc_config, local_info)); + std::unique_ptr driver( + new OpenCensus::Driver(oc_config, local_info, *Api::createApiForTest())); auto span = ::opencensus::trace::Span::StartSpan("test_span"); span.End(); // Retrieve SpanData from the OpenCensus trace exporter. diff --git a/tools/spelling_dictionary.txt b/tools/spelling_dictionary.txt index 08c43ebb70..71cccbc862 100644 --- a/tools/spelling_dictionary.txt +++ b/tools/spelling_dictionary.txt @@ -278,6 +278,7 @@ SSL STDSTRING STL STRLEN +STS SVG TBD TCLAP From 4300ad4544b500982d39fd0ddf83f38b40b80828 Mon Sep 17 00:00:00 2001 From: rulex123 <29862113+rulex123@users.noreply.github.com> Date: Thu, 6 Feb 2020 20:24:07 +0100 Subject: [PATCH 20/87] Log: allow "-l warn" and protect against invalid arg values (#9938) * Allow -l warn to configure log level on startup, and protect against invalid values for log level. Signed-off-by: Erica Manno --- source/server/options_impl.cc | 62 ++++++++++++++++++++------------ source/server/options_impl.h | 2 ++ test/server/options_impl_test.cc | 29 ++++++++++++++- 3 files changed, 70 insertions(+), 23 deletions(-) diff --git a/source/server/options_impl.cc b/source/server/options_impl.cc index 39bf5e40df..723ef5a4b7 100644 --- a/source/server/options_impl.cc +++ b/source/server/options_impl.cc @@ -16,6 +16,7 @@ #include "server/options_impl_platform.h" #include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" #include "spdlog/spdlog.h" #include "tclap/CmdLine.h" @@ -39,10 +40,7 @@ OptionsImpl::OptionsImpl(std::vector args, const HotRestartVersionCb& hot_restart_version_cb, spdlog::level::level_enum default_log_level) : signal_handling_enabled_(true) { - std::string log_levels_string = "Log levels: "; - for (auto level_string_view : spdlog::level::level_string_views) { - log_levels_string += fmt::format("[{}]", level_string_view); - } + std::string log_levels_string = fmt::format("Log levels: {}", allowedLogLevels()); log_levels_string += fmt::format("\nDefault is [{}]", spdlog::level::level_string_views[default_log_level]); @@ -161,11 +159,10 @@ OptionsImpl::OptionsImpl(std::vector args, fake_symbol_table_enabled_ = use_fake_symbol_table.getValue(); cpuset_threads_ = cpuset_threads.getValue(); - log_level_ = default_log_level; - for (size_t i = 0; i < ARRAY_SIZE(spdlog::level::level_string_views); i++) { - if (log_level.getValue() == spdlog::level::level_string_views[i]) { - log_level_ = static_cast(i); - } + if (log_level.isSet()) { + log_level_ = parseAndValidateLogLevel(log_level.getValue()); + } else { + log_level_ = default_log_level; } log_format_ = log_format.getValue(); @@ -239,6 +236,38 @@ OptionsImpl::OptionsImpl(std::vector args, } } +spdlog::level::level_enum OptionsImpl::parseAndValidateLogLevel(absl::string_view log_level) { + if (log_level == "warn") { + return spdlog::level::level_enum::warn; + } + + size_t level_to_use = std::numeric_limits::max(); + for (size_t i = 0; i < ARRAY_SIZE(spdlog::level::level_string_views); i++) { + spdlog::string_view_t spd_log_level = spdlog::level::level_string_views[i]; + if (log_level == absl::string_view(spd_log_level.data(), spd_log_level.size())) { + level_to_use = i; + break; + } + } + + if (level_to_use == std::numeric_limits::max()) { + logError(fmt::format("error: invalid log level specified '{}'", log_level)); + } + return static_cast(level_to_use); +} + +std::string OptionsImpl::allowedLogLevels() { + std::string allowed_log_levels; + for (auto level_string_view : spdlog::level::level_string_views) { + if (level_string_view == spdlog::level::to_string_view(spdlog::level::warn)) { + allowed_log_levels += fmt::format("[{}|warn]", level_string_view); + } else { + allowed_log_levels += fmt::format("[{}]", level_string_view); + } + } + return allowed_log_levels; +} + void OptionsImpl::parseComponentLogLevels(const std::string& component_log_levels) { if (component_log_levels.empty()) { return; @@ -251,23 +280,12 @@ void OptionsImpl::parseComponentLogLevels(const std::string& component_log_level logError(fmt::format("error: component log level not correctly specified '{}'", level)); } std::string log_name = log_name_level[0]; - std::string log_level = log_name_level[1]; - size_t level_to_use = std::numeric_limits::max(); - for (size_t i = 0; i < ARRAY_SIZE(spdlog::level::level_string_views); i++) { - if (log_level == spdlog::level::level_string_views[i]) { - level_to_use = i; - break; - } - } - if (level_to_use == std::numeric_limits::max()) { - logError(fmt::format("error: invalid log level specified '{}'", log_level)); - } + spdlog::level::level_enum log_level = parseAndValidateLogLevel(log_name_level[1]); Logger::Logger* logger_to_change = Logger::Registry::logger(log_name); if (!logger_to_change) { logError(fmt::format("error: invalid component specified '{}'", log_name)); } - component_log_levels_.push_back( - std::make_pair(log_name, static_cast(level_to_use))); + component_log_levels_.push_back(std::make_pair(log_name, log_level)); } } diff --git a/source/server/options_impl.h b/source/server/options_impl.h index 49993e9d98..b8f3e64695 100644 --- a/source/server/options_impl.h +++ b/source/server/options_impl.h @@ -146,9 +146,11 @@ class OptionsImpl : public Server::Options, protected Logger::Loggable&); + static std::string allowedLogLevels(); private: void logError(const std::string& error) const; + spdlog::level::level_enum parseAndValidateLogLevel(absl::string_view log_level); uint64_t base_id_; uint32_t concurrency_; diff --git a/test/server/options_impl_test.cc b/test/server/options_impl_test.cc index 99da33dc7c..276a99747c 100644 --- a/test/server/options_impl_test.cc +++ b/test/server/options_impl_test.cc @@ -223,6 +223,7 @@ TEST_F(OptionsImplTest, DefaultParams) { EXPECT_EQ("", options->adminAddressPath()); EXPECT_EQ(Network::Address::IpVersion::v4, options->localAddressIpVersion()); EXPECT_EQ(Server::Mode::Serve, options->mode()); + EXPECT_EQ(spdlog::level::warn, options->logLevel()); EXPECT_FALSE(options->hotRestartDisabled()); EXPECT_FALSE(options->cpusetThreadsEnabled()); @@ -305,12 +306,18 @@ TEST_F(OptionsImplTest, InvalidComponent) { "error: invalid component specified 'blah'"); } -TEST_F(OptionsImplTest, InvalidLogLevel) { +TEST_F(OptionsImplTest, InvalidComponentLogLevel) { std::unique_ptr options = createOptionsImpl("envoy --mode init_only"); EXPECT_THROW_WITH_REGEX(options->parseComponentLogLevels("upstream:blah,connection:trace"), MalformedArgvException, "error: invalid log level specified 'blah'"); } +TEST_F(OptionsImplTest, ComponentLogLevelContainsBlank) { + std::unique_ptr options = createOptionsImpl("envoy --mode init_only"); + EXPECT_THROW_WITH_REGEX(options->parseComponentLogLevels("upstream:,connection:trace"), + MalformedArgvException, "error: invalid log level specified ''"); +} + TEST_F(OptionsImplTest, InvalidComponentLogLevelStructure) { std::unique_ptr options = createOptionsImpl("envoy --mode init_only"); EXPECT_THROW_WITH_REGEX(options->parseComponentLogLevels("upstream:foo:bar"), @@ -324,6 +331,26 @@ TEST_F(OptionsImplTest, IncompleteComponentLogLevel) { "component log level not correctly specified 'upstream'"); } +TEST_F(OptionsImplTest, InvalidLogLevel) { + EXPECT_THROW_WITH_REGEX(createOptionsImpl("envoy -l blah"), MalformedArgvException, + "error: invalid log level specified 'blah'"); +} + +TEST_F(OptionsImplTest, ValidLogLevel) { + std::unique_ptr options = createOptionsImpl("envoy -l critical"); + EXPECT_EQ(spdlog::level::level_enum::critical, options->logLevel()); +} + +TEST_F(OptionsImplTest, WarnIsValidLogLevel) { + std::unique_ptr options = createOptionsImpl("envoy -l warn"); + EXPECT_EQ(spdlog::level::level_enum::warn, options->logLevel()); +} + +TEST_F(OptionsImplTest, AllowedLogLevels) { + EXPECT_EQ("[trace][debug][info][warning|warn][error][critical][off]", + OptionsImpl::allowedLogLevels()); +} + // Test that the test constructor comes up with the same default values as the main constructor. TEST_F(OptionsImplTest, SaneTestConstructor) { std::unique_ptr regular_options_impl(createOptionsImpl("envoy")); From e176b307bd2ab475574fc7c4b0f92e8575129573 Mon Sep 17 00:00:00 2001 From: danzh Date: Fri, 7 Feb 2020 10:49:33 -0500 Subject: [PATCH 21/87] quiche: add multi-worker support for QUIC via BPF (#9424) Signed-off-by: Dan Zhang --- include/envoy/network/connection_handler.h | 2 +- include/envoy/network/listener.h | 2 +- .../envoy/server/active_udp_listener_config.h | 4 +- source/common/network/socket_option_impl.h | 7 + .../quiche/active_quic_listener.cc | 110 ++++++++++++- .../quiche/active_quic_listener.h | 35 ++-- .../quiche/active_quic_listener_config.cc | 5 +- .../quiche/active_quic_listener_config.h | 2 +- .../quiche/envoy_quic_client_connection.cc | 10 ++ .../quiche/envoy_quic_client_connection.h | 3 + .../quiche/envoy_quic_connection.h | 4 + .../quiche/envoy_quic_dispatcher.cc | 12 +- .../quiche/envoy_quic_dispatcher.h | 6 +- .../server/active_raw_udp_listener_config.cc | 4 +- .../server/active_raw_udp_listener_config.h | 4 +- source/server/http/admin.h | 2 +- source/server/listener_impl.cc | 2 +- source/server/listener_impl.h | 2 +- .../proxy_protocol/proxy_protocol_test.cc | 4 +- .../active_quic_listener_config_test.cc | 2 +- .../quiche/active_quic_listener_test.cc | 16 +- .../quiche/envoy_quic_dispatcher_test.cc | 8 +- .../quic_listeners/quiche/integration/BUILD | 1 + .../integration/quic_http_integration_test.cc | 151 +++++++++++++++++- test/integration/integration.cc | 2 +- test/mocks/network/mocks.h | 2 +- test/server/connection_handler_test.cc | 4 +- tools/spelling_dictionary.txt | 8 + 28 files changed, 358 insertions(+), 56 deletions(-) diff --git a/include/envoy/network/connection_handler.h b/include/envoy/network/connection_handler.h index 956568bf2f..9687cadbd3 100644 --- a/include/envoy/network/connection_handler.h +++ b/include/envoy/network/connection_handler.h @@ -125,7 +125,7 @@ class ActiveUdpListenerFactory { */ virtual ConnectionHandler::ActiveListenerPtr createActiveUdpListener(ConnectionHandler& parent, Event::Dispatcher& disptacher, - Network::ListenerConfig& config) const PURE; + Network::ListenerConfig& config) PURE; /** * @return true if the UDP passing through listener doesn't form stateful connections. diff --git a/include/envoy/network/listener.h b/include/envoy/network/listener.h index 4aed7d2b5f..f5a85b56be 100644 --- a/include/envoy/network/listener.h +++ b/include/envoy/network/listener.h @@ -130,7 +130,7 @@ class ListenerConfig { * @return factory pointer if listening on UDP socket, otherwise return * nullptr. */ - virtual const ActiveUdpListenerFactory* udpListenerFactory() PURE; + virtual ActiveUdpListenerFactory* udpListenerFactory() PURE; /** * @return traffic direction of the listener. diff --git a/include/envoy/server/active_udp_listener_config.h b/include/envoy/server/active_udp_listener_config.h index e268fc16b5..52846679a5 100644 --- a/include/envoy/server/active_udp_listener_config.h +++ b/include/envoy/server/active_udp_listener_config.h @@ -20,9 +20,11 @@ class ActiveUdpListenerConfigFactory : public Config::UntypedFactory { /** * Create an ActiveUdpListenerFactory object according to given message. + * @param message specifies QUIC protocol options in a protobuf. + * @param concurrency is the number of listeners instances to be created. */ virtual Network::ActiveUdpListenerFactoryPtr - createActiveUdpListenerFactory(const Protobuf::Message& message) PURE; + createActiveUdpListenerFactory(const Protobuf::Message& message, uint32_t concurrency) PURE; std::string category() const override { return "envoy.udp_listeners"; } }; diff --git a/source/common/network/socket_option_impl.h b/source/common/network/socket_option_impl.h index d8a047acb0..95338adf6f 100644 --- a/source/common/network/socket_option_impl.h +++ b/source/common/network/socket_option_impl.h @@ -98,6 +98,13 @@ static_assert(IP_RECVDSTADDR == IP_SENDSRCADDR); // receiving destination address. #define ENVOY_SELF_IPV6_ADDR ENVOY_MAKE_SOCKET_OPTION_NAME(IPPROTO_IPV6, IPV6_RECVPKTINFO) +#ifdef SO_ATTACH_REUSEPORT_CBPF +#define ENVOY_ATTACH_REUSEPORT_CBPF \ + ENVOY_MAKE_SOCKET_OPTION_NAME(SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF) +#else +#define ENVOY_ATTACH_REUSEPORT_CBPF Network::SocketOptionName() +#endif + class SocketOptionImpl : public Socket::Option, Logger::Loggable { public: SocketOptionImpl(envoy::config::core::v3::SocketOption::SocketState in_state, diff --git a/source/extensions/quic_listeners/quiche/active_quic_listener.cc b/source/extensions/quic_listeners/quiche/active_quic_listener.cc index f278e2cd73..b79ef84e3e 100644 --- a/source/extensions/quic_listeners/quiche/active_quic_listener.cc +++ b/source/extensions/quic_listeners/quiche/active_quic_listener.cc @@ -1,5 +1,11 @@ #include "extensions/quic_listeners/quiche/active_quic_listener.h" +#if defined(__linux__) +#include +#endif + +#include + #include "extensions/quic_listeners/quiche/envoy_quic_alarm_factory.h" #include "extensions/quic_listeners/quiche/envoy_quic_connection_helper.h" #include "extensions/quic_listeners/quiche/envoy_quic_dispatcher.h" @@ -13,19 +19,32 @@ namespace Quic { ActiveQuicListener::ActiveQuicListener(Event::Dispatcher& dispatcher, Network::ConnectionHandler& parent, Network::ListenerConfig& listener_config, - const quic::QuicConfig& quic_config) + const quic::QuicConfig& quic_config, + Network::Socket::OptionsSharedPtr options) : ActiveQuicListener(dispatcher, parent, listener_config.listenSocketFactory().getListenSocket(), listener_config, - quic_config) {} + quic_config, std::move(options)) {} ActiveQuicListener::ActiveQuicListener(Event::Dispatcher& dispatcher, Network::ConnectionHandler& parent, Network::SocketSharedPtr listen_socket, Network::ListenerConfig& listener_config, - const quic::QuicConfig& quic_config) + const quic::QuicConfig& quic_config, + Network::Socket::OptionsSharedPtr options) : Server::ConnectionHandlerImpl::ActiveListenerImplBase(parent, listener_config), dispatcher_(dispatcher), version_manager_(quic::CurrentSupportedVersions()), listen_socket_(*listen_socket) { + if (options != nullptr) { + const bool ok = Network::Socket::applyOptions( + options, listen_socket_, envoy::config::core::v3::SocketOption::STATE_BOUND); + if (!ok) { + ENVOY_LOG(warn, "Failed to apply socket options to socket {} on listener {} after binding", + listen_socket_.ioHandle().fd(), listener_config.name()); + throw EnvoyException("Failed to apply socket options."); + } + listen_socket_.addOptions(options); + } + udp_listener_ = dispatcher_.createUdpListener(std::move(listen_socket), *this); quic::QuicRandom* const random = quic::QuicRandom::GetInstance(); random->RandBytes(random_seed_, sizeof(random_seed_)); @@ -41,7 +60,7 @@ ActiveQuicListener::ActiveQuicListener(Event::Dispatcher& dispatcher, quic_dispatcher_ = std::make_unique( crypto_config_.get(), quic_config, &version_manager_, std::move(connection_helper), std::move(alarm_factory), quic::kQuicDefaultConnectionIdLength, parent, config_, stats_, - dispatcher, listen_socket_); + per_worker_stats_, dispatcher, listen_socket_); quic_dispatcher_->InitializeWithWriter(new EnvoyQuicPacketWriter(listen_socket_)); } @@ -82,5 +101,88 @@ void ActiveQuicListener::onWriteReady(const Network::Socket& /*socket*/) { quic_dispatcher_->OnCanWrite(); } +ActiveQuicListenerFactory::ActiveQuicListenerFactory( + const envoy::config::listener::v3::QuicProtocolOptions& config, uint32_t concurrency) + : concurrency_(concurrency) { + uint64_t idle_network_timeout_ms = + config.has_idle_timeout() ? DurationUtil::durationToMilliseconds(config.idle_timeout()) + : 300000; + quic_config_.SetIdleNetworkTimeout( + quic::QuicTime::Delta::FromMilliseconds(idle_network_timeout_ms), + quic::QuicTime::Delta::FromMilliseconds(idle_network_timeout_ms)); + int32_t max_time_before_crypto_handshake_ms = + config.has_crypto_handshake_timeout() + ? DurationUtil::durationToMilliseconds(config.crypto_handshake_timeout()) + : 20000; + quic_config_.set_max_time_before_crypto_handshake( + quic::QuicTime::Delta::FromMilliseconds(max_time_before_crypto_handshake_ms)); + int32_t max_streams = PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, max_concurrent_streams, 100); + quic_config_.SetMaxIncomingBidirectionalStreamsToSend(max_streams); + quic_config_.SetMaxIncomingUnidirectionalStreamsToSend(max_streams); +} + +Network::ConnectionHandler::ActiveListenerPtr +ActiveQuicListenerFactory::createActiveUdpListener(Network::ConnectionHandler& parent, + Event::Dispatcher& disptacher, + Network::ListenerConfig& config) { + std::unique_ptr options = std::make_unique(); +#if defined(SO_ATTACH_REUSEPORT_CBPF) && defined(__linux__) + // This BPF filter reads the 1st word of QUIC connection id in the UDP payload and mods it by the + // number of workers to get the socket index in the SO_REUSEPORT socket groups. QUIC packets + // should be at least 9 bytes, with the 1st byte indicating one of the below QUIC packet headers: + // 1) IETF QUIC long header: most significant bit is 1. The connection id starts from the 7th + // byte. + // 2) IETF QUIC short header: most significant bit is 0. The connection id starts from 2nd + // byte. + // 3) Google QUIC header: most significant bit is 0. The connection id starts from 2nd + // byte. + // Any packet that doesn't belong to any of the three packet header types are dispatched + // based on 5-tuple source/destination addresses. + std::vector filter = { + {0x80, 0, 0, 0000000000}, // ld len + {0x35, 0, 9, 0x00000009}, // jlt #0x9, packet_too_short + {0x30, 0, 0, 0000000000}, // ldb [0] + {0x54, 0, 0, 0x00000080}, // and #0x80 + {0x15, 0, 2, 0000000000}, // jne #0, ietf_long_header + {0x20, 0, 0, 0x00000001}, // ld [1] + {0x05, 0, 0, 0x00000005}, // ja return + {0x80, 0, 0, 0000000000}, // ietf_long_header: ld len + {0x35, 0, 2, 0x0000000e}, // jlt #0xe, packet_too_short + {0x20, 0, 0, 0x00000006}, // ld [6] + {0x05, 0, 0, 0x00000001}, // ja return + {0x20, 0, 0, // packet_too_short: ld rxhash + static_cast(SKF_AD_OFF + SKF_AD_RXHASH)}, + {0x94, 0, 0, concurrency_}, // return: mod #socket_count + {0x16, 0, 0, 0000000000}, // ret a + }; + sock_fprog prog; + // This option only needs to be applied once to any one of the sockets in SO_REUSEPORT socket + // group. One of the listener will be created with this socket option. + absl::call_once(install_bpf_once_, [&]() { + if (concurrency_ > 1) { + prog.len = filter.size(); + prog.filter = filter.data(); + options->push_back(std::make_shared( + envoy::config::core::v3::SocketOption::STATE_BOUND, ENVOY_ATTACH_REUSEPORT_CBPF, + absl::string_view(reinterpret_cast(&prog), sizeof(prog)))); + } + }); +#else + if (concurrency_ > 1) { +#ifdef __APPLE__ + // Not support multiple listeners in Mac OS unless someone cares. This is because SO_REUSEPORT + // doesn't behave as expected in Mac OS.(#8794) + ENVOY_LOG(error, "Because SO_REUSEPORT doesn't guarantee stable hashing from network 5 tuple " + "to socket in Mac OS. QUIC connection is not stable with concurrency > 1"); +#else + ENVOY_LOG(warn, "BPF filter is not supported on this platform. QUIC won't support connection " + "migration and NAT port rebinding."); +#endif + } +#endif + return std::make_unique(disptacher, parent, config, quic_config_, + std::move(options)); +} + } // namespace Quic } // namespace Envoy diff --git a/source/extensions/quic_listeners/quiche/active_quic_listener.h b/source/extensions/quic_listeners/quiche/active_quic_listener.h index 93c3ef4405..09d314abe1 100644 --- a/source/extensions/quic_listeners/quiche/active_quic_listener.h +++ b/source/extensions/quic_listeners/quiche/active_quic_listener.h @@ -4,6 +4,7 @@ #include "envoy/network/connection_handler.h" #include "envoy/network/listener.h" +#include "common/network/socket_option_impl.h" #include "common/protobuf/utility.h" #include "server/connection_handler_impl.h" @@ -23,11 +24,13 @@ class ActiveQuicListener : public Network::UdpListenerCallbacks, static const size_t kNumSessionsToCreatePerLoop = 16; ActiveQuicListener(Event::Dispatcher& dispatcher, Network::ConnectionHandler& parent, - Network::ListenerConfig& listener_config, const quic::QuicConfig& quic_config); + Network::ListenerConfig& listener_config, const quic::QuicConfig& quic_config, + Network::Socket::OptionsSharedPtr options); ActiveQuicListener(Event::Dispatcher& dispatcher, Network::ConnectionHandler& parent, Network::SocketSharedPtr listen_socket, - Network::ListenerConfig& listener_config, const quic::QuicConfig& quic_config); + Network::ListenerConfig& listener_config, const quic::QuicConfig& quic_config, + Network::Socket::OptionsSharedPtr options); ~ActiveQuicListener() override; @@ -61,38 +64,24 @@ class ActiveQuicListener : public Network::UdpListenerCallbacks, using ActiveQuicListenerPtr = std::unique_ptr; // A factory to create ActiveQuicListener based on given config. -class ActiveQuicListenerFactory : public Network::ActiveUdpListenerFactory { +class ActiveQuicListenerFactory : public Network::ActiveUdpListenerFactory, + Logger::Loggable { public: - ActiveQuicListenerFactory(const envoy::config::listener::v3::QuicProtocolOptions& config) { - uint64_t idle_network_timeout_ms = - config.has_idle_timeout() ? DurationUtil::durationToMilliseconds(config.idle_timeout()) - : 300000; - quic_config_.SetIdleNetworkTimeout( - quic::QuicTime::Delta::FromMilliseconds(idle_network_timeout_ms), - quic::QuicTime::Delta::FromMilliseconds(idle_network_timeout_ms)); - int32_t max_time_before_crypto_handshake_ms = - config.has_crypto_handshake_timeout() - ? DurationUtil::durationToMilliseconds(config.crypto_handshake_timeout()) - : 20000; - quic_config_.set_max_time_before_crypto_handshake( - quic::QuicTime::Delta::FromMilliseconds(max_time_before_crypto_handshake_ms)); - int32_t max_streams = PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, max_concurrent_streams, 100); - quic_config_.SetMaxIncomingBidirectionalStreamsToSend(max_streams); - quic_config_.SetMaxIncomingUnidirectionalStreamsToSend(max_streams); - } + ActiveQuicListenerFactory(const envoy::config::listener::v3::QuicProtocolOptions& config, + uint32_t concurrency); // Network::ActiveUdpListenerFactory. Network::ConnectionHandler::ActiveListenerPtr createActiveUdpListener(Network::ConnectionHandler& parent, Event::Dispatcher& disptacher, - Network::ListenerConfig& config) const override { - return std::make_unique(disptacher, parent, config, quic_config_); - } + Network::ListenerConfig& config) override; bool isTransportConnectionless() const override { return false; } private: friend class ActiveQuicListenerFactoryPeer; quic::QuicConfig quic_config_; + const uint32_t concurrency_; + absl::once_flag install_bpf_once_; }; } // namespace Quic diff --git a/source/extensions/quic_listeners/quiche/active_quic_listener_config.cc b/source/extensions/quic_listeners/quiche/active_quic_listener_config.cc index b92ede2f7a..f0ddcf7809 100644 --- a/source/extensions/quic_listeners/quiche/active_quic_listener_config.cc +++ b/source/extensions/quic_listeners/quiche/active_quic_listener_config.cc @@ -12,9 +12,10 @@ ProtobufTypes::MessagePtr ActiveQuicListenerConfigFactory::createEmptyConfigProt } Network::ActiveUdpListenerFactoryPtr -ActiveQuicListenerConfigFactory::createActiveUdpListenerFactory(const Protobuf::Message& message) { +ActiveQuicListenerConfigFactory::createActiveUdpListenerFactory(const Protobuf::Message& message, + uint32_t concurrency) { auto& config = dynamic_cast(message); - return std::make_unique(config); + return std::make_unique(config, concurrency); } std::string ActiveQuicListenerConfigFactory::name() const { return QuicListenerName; } diff --git a/source/extensions/quic_listeners/quiche/active_quic_listener_config.h b/source/extensions/quic_listeners/quiche/active_quic_listener_config.h index f63e655d25..c8b370d8d4 100644 --- a/source/extensions/quic_listeners/quiche/active_quic_listener_config.h +++ b/source/extensions/quic_listeners/quiche/active_quic_listener_config.h @@ -16,7 +16,7 @@ class ActiveQuicListenerConfigFactory : public Server::ActiveUdpListenerConfigFa ProtobufTypes::MessagePtr createEmptyConfigProto() override; Network::ActiveUdpListenerFactoryPtr - createActiveUdpListenerFactory(const Protobuf::Message&) override; + createActiveUdpListenerFactory(const Protobuf::Message&, uint32_t concurrency) override; std::string name() const override; }; diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.cc b/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.cc index ff462568d6..c287c8e3eb 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.cc @@ -1,5 +1,7 @@ #include "extensions/quic_listeners/quiche/envoy_quic_client_connection.h" +#include + #include "envoy/config/core/v3/base.pb.h" #include "common/network/listen_socket_impl.h" @@ -92,6 +94,14 @@ void EnvoyQuicClientConnection::setUpConnectionSocket() { } } +void EnvoyQuicClientConnection::switchConnectionSocket( + Network::ConnectionSocketPtr&& connection_socket) { + auto writer = std::make_unique(*connection_socket); + setConnectionSocket(std::move(connection_socket)); + setUpConnectionSocket(); + SetQuicPacketWriter(writer.release(), true); +} + void EnvoyQuicClientConnection::onFileEvent(uint32_t events) { ENVOY_CONN_LOG(trace, "socket event: {}", *this, events); ASSERT(events & (Event::FileReadyType::Read | Event::FileReadyType::Write)); diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.h b/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.h index 8ee2f22dad..48406debe5 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_connection.h @@ -40,6 +40,9 @@ class EnvoyQuicClientConnection : public EnvoyQuicConnection, public Network::Ud // Register file event and apply socket options. void setUpConnectionSocket(); + // Switch underlying socket with the given one. This is used in connection migration. + void switchConnectionSocket(Network::ConnectionSocketPtr&& connection_socket); + private: EnvoyQuicClientConnection(const quic::QuicConnectionId& server_connection_id, quic::QuicConnectionHelperInterface& helper, diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_connection.h b/source/extensions/quic_listeners/quiche/envoy_quic_connection.h index dbc73e9057..51aebb2dd0 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_connection.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_connection.h @@ -54,6 +54,10 @@ class EnvoyQuicConnection : public quic::QuicConnection, return *envoy_connection_; } + void setConnectionSocket(Network::ConnectionSocketPtr&& connection_socket) { + connection_socket_ = std::move(connection_socket); + } + private: // TODO(danzh): populate stats. std::unique_ptr connection_stats_; diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.cc b/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.cc index 1c295dfd88..85da3fcbb7 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.cc @@ -13,12 +13,14 @@ EnvoyQuicDispatcher::EnvoyQuicDispatcher( std::unique_ptr alarm_factory, uint8_t expected_server_connection_id_length, Network::ConnectionHandler& connection_handler, Network::ListenerConfig& listener_config, Server::ListenerStats& listener_stats, - Event::Dispatcher& dispatcher, Network::Socket& listen_socket) + Server::PerHandlerListenerStats& per_worker_stats, Event::Dispatcher& dispatcher, + Network::Socket& listen_socket) : quic::QuicDispatcher(&quic_config, crypto_config, version_manager, std::move(helper), std::make_unique(), std::move(alarm_factory), expected_server_connection_id_length), connection_handler_(connection_handler), listener_config_(listener_config), - listener_stats_(listener_stats), dispatcher_(dispatcher), listen_socket_(listen_socket) { + listener_stats_(listener_stats), per_worker_stats_(per_worker_stats), dispatcher_(dispatcher), + listen_socket_(listen_socket) { // Set send buffer twice of max flow control window to ensure that stream send // buffer always takes all the data. // The max amount of data buffered is the per-stream high watermark + the max @@ -37,6 +39,8 @@ void EnvoyQuicDispatcher::OnConnectionClosed(quic::QuicConnectionId connection_i const std::string& error_details, quic::ConnectionCloseSource source) { quic::QuicDispatcher::OnConnectionClosed(connection_id, error, error_details, source); + listener_stats_.downstream_cx_active_.dec(); + per_worker_stats_.downstream_cx_active_.dec(); connection_handler_.decNumConnections(); } @@ -59,6 +63,10 @@ std::unique_ptr EnvoyQuicDispatcher::CreateQuicSession( // thing to pay attention is that if the retrieval fails, connection needs to // be closed, and it should be added to time wait list instead of session map. connection_handler_.incNumConnections(); + listener_stats_.downstream_cx_active_.inc(); + listener_stats_.downstream_cx_total_.inc(); + per_worker_stats_.downstream_cx_active_.inc(); + per_worker_stats_.downstream_cx_total_.inc(); return quic_session; } diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.h b/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.h index d1441622e3..9bd3cd7076 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_dispatcher.h @@ -48,8 +48,9 @@ class EnvoyQuicDispatcher : public quic::QuicDispatcher { uint8_t expected_server_connection_id_length, Network::ConnectionHandler& connection_handler, Network::ListenerConfig& listener_config, - Server::ListenerStats& listener_stats, Event::Dispatcher& dispatcher, - Network::Socket& listen_socket); + Server::ListenerStats& listener_stats, + Server::PerHandlerListenerStats& per_worker_stats, + Event::Dispatcher& dispatcher, Network::Socket& listen_socket); void OnConnectionClosed(quic::QuicConnectionId connection_id, quic::QuicErrorCode error, const std::string& error_details, @@ -72,6 +73,7 @@ class EnvoyQuicDispatcher : public quic::QuicDispatcher { Network::ConnectionHandler& connection_handler_; Network::ListenerConfig& listener_config_; Server::ListenerStats& listener_stats_; + Server::PerHandlerListenerStats& per_worker_stats_; Event::Dispatcher& dispatcher_; Network::Socket& listen_socket_; }; diff --git a/source/server/active_raw_udp_listener_config.cc b/source/server/active_raw_udp_listener_config.cc index 49350fb9f7..eb24251021 100644 --- a/source/server/active_raw_udp_listener_config.cc +++ b/source/server/active_raw_udp_listener_config.cc @@ -14,7 +14,7 @@ namespace Server { Network::ConnectionHandler::ActiveListenerPtr ActiveRawUdpListenerFactory::createActiveUdpListener(Network::ConnectionHandler& parent, Event::Dispatcher& dispatcher, - Network::ListenerConfig& config) const { + Network::ListenerConfig& config) { return std::make_unique(parent, dispatcher, config); } @@ -24,7 +24,7 @@ ProtobufTypes::MessagePtr ActiveRawUdpListenerConfigFactory::createEmptyConfigPr Network::ActiveUdpListenerFactoryPtr ActiveRawUdpListenerConfigFactory::createActiveUdpListenerFactory( - const Protobuf::Message& /*message*/) { + const Protobuf::Message& /*message*/, uint32_t /*concurrency*/) { return std::make_unique(); } diff --git a/source/server/active_raw_udp_listener_config.h b/source/server/active_raw_udp_listener_config.h index 337709bd29..da0216301d 100644 --- a/source/server/active_raw_udp_listener_config.h +++ b/source/server/active_raw_udp_listener_config.h @@ -11,7 +11,7 @@ class ActiveRawUdpListenerFactory : public Network::ActiveUdpListenerFactory { public: Network::ConnectionHandler::ActiveListenerPtr createActiveUdpListener(Network::ConnectionHandler& parent, Event::Dispatcher& disptacher, - Network::ListenerConfig& config) const override; + Network::ListenerConfig& config) override; bool isTransportConnectionless() const override { return true; } }; @@ -24,7 +24,7 @@ class ActiveRawUdpListenerConfigFactory : public ActiveUdpListenerConfigFactory ProtobufTypes::MessagePtr createEmptyConfigProto() override; Network::ActiveUdpListenerFactoryPtr - createActiveUdpListenerFactory(const Protobuf::Message&) override; + createActiveUdpListenerFactory(const Protobuf::Message&, uint32_t concurrency) override; std::string name() const override; }; diff --git a/source/server/http/admin.h b/source/server/http/admin.h index fac51b4b23..b29dd23420 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -391,7 +391,7 @@ class AdminImpl : public Admin, Stats::Scope& listenerScope() override { return *scope_; } uint64_t listenerTag() const override { return 0; } const std::string& name() const override { return name_; } - const Network::ActiveUdpListenerFactory* udpListenerFactory() override { + Network::ActiveUdpListenerFactory* udpListenerFactory() override { NOT_REACHED_GCOVR_EXCL_LINE; } envoy::config::core::v3::TrafficDirection direction() const override { diff --git a/source/server/listener_impl.cc b/source/server/listener_impl.cc index ac4a7f7dda..5b6380066b 100644 --- a/source/server/listener_impl.cc +++ b/source/server/listener_impl.cc @@ -180,7 +180,7 @@ ListenerImpl::ListenerImpl(const envoy::config::listener::v3::Listener& config, udp_config.udp_listener_name()); ProtobufTypes::MessagePtr message = Config::Utility::translateToFactoryConfig(udp_config, validation_visitor_, config_factory); - udp_listener_factory_ = config_factory.createActiveUdpListenerFactory(*message); + udp_listener_factory_ = config_factory.createActiveUdpListenerFactory(*message, concurrency); } if (!config.listener_filters().empty()) { diff --git a/source/server/listener_impl.h b/source/server/listener_impl.h index 2cd623b24b..a45bf23a74 100644 --- a/source/server/listener_impl.h +++ b/source/server/listener_impl.h @@ -146,7 +146,7 @@ class ListenerImpl : public Network::ListenerConfig, Stats::Scope& listenerScope() override { return *listener_scope_; } uint64_t listenerTag() const override { return listener_tag_; } const std::string& name() const override { return name_; } - const Network::ActiveUdpListenerFactory* udpListenerFactory() override { + Network::ActiveUdpListenerFactory* udpListenerFactory() override { return udp_listener_factory_.get(); } Network::ConnectionBalancer& connectionBalancer() override { return *connection_balancer_; } diff --git a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc index 060e9c26f6..5abfba8043 100644 --- a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc +++ b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc @@ -82,7 +82,7 @@ class ProxyProtocolTest : public testing::TestWithParam(*listener_factory)); diff --git a/test/extensions/quic_listeners/quiche/active_quic_listener_test.cc b/test/extensions/quic_listeners/quiche/active_quic_listener_test.cc index 47932955ac..23402e197e 100644 --- a/test/extensions/quic_listeners/quiche/active_quic_listener_test.cc +++ b/test/extensions/quic_listeners/quiche/active_quic_listener_test.cc @@ -1,3 +1,5 @@ +#include + #pragma GCC diagnostic push // QUICHE allows unused parameters. #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -64,7 +66,7 @@ class ActiveQuicListenerTest : public testing::TestWithParamaddOptions(Network::SocketOptionFactory::buildRxQueueOverFlowOptions()); quic_listener_ = std::make_unique( - *dispatcher_, connection_handler_, listen_socket_, listener_config_, quic_config_); + *dispatcher_, connection_handler_, listen_socket_, listener_config_, quic_config_, nullptr); simulated_time_system_.sleep(std::chrono::milliseconds(100)); } @@ -213,6 +215,18 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, ActiveQuicListenerTest, testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), TestUtility::ipTestParamsToString); +TEST_P(ActiveQuicListenerTest, FailSocketOptionUponCreation) { + auto option = std::make_unique(); + EXPECT_CALL(*option, setOption(_, envoy::config::core::v3::SocketOption::STATE_BOUND)) + .WillOnce(Return(false)); + auto options = std::make_shared>(); + options->emplace_back(std::move(option)); + EXPECT_THROW_WITH_REGEX(std::make_unique(*dispatcher_, connection_handler_, + listen_socket_, listener_config_, + quic_config_, options), + EnvoyException, "Failed to apply socket options."); +} + TEST_P(ActiveQuicListenerTest, ReceiveFullQuicCHLO) { ConfigureMocks(/* connection_count = */ 1); SendFullCHLO(quic::test::TestConnectionId(1)); diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_dispatcher_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_dispatcher_test.cc index 61816e0b69..2c35203638 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_dispatcher_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_dispatcher_test.cc @@ -61,13 +61,16 @@ class EnvoyQuicDispatcherTest : public testing::TestWithParam(*dispatcher_), std::make_unique(*dispatcher_, *connection_helper_.GetClock()), quic::kQuicDefaultConnectionIdLength, connection_handler_, listener_config_, - listener_stats_, *dispatcher_, *listen_socket_), + listener_stats_, per_worker_stats_, *dispatcher_, *listen_socket_), connection_id_(quic::test::TestConnectionId(1)) { auto writer = new testing::NiceMock(); envoy_quic_dispatcher_.InitializeWithWriter(writer); @@ -139,6 +142,7 @@ class EnvoyQuicDispatcherTest : public testing::TestWithParam listener_config_; Server::ListenerStats listener_stats_; + Server::PerHandlerListenerStats per_worker_stats_; Server::ConnectionHandlerImpl connection_handler_; EnvoyQuicDispatcher envoy_quic_dispatcher_; const quic::QuicConnectionId connection_id_; @@ -323,6 +327,8 @@ TEST_P(EnvoyQuicDispatcherTest, CloseConnectionDueToMissingFilterChain) { EXPECT_EQ(0u, connection_handler_.numConnections()); EXPECT_TRUE(quic::test::QuicDispatcherPeer::GetTimeWaitListManager(&envoy_quic_dispatcher_) ->IsConnectionIdInTimeWait(connection_id_)); + EXPECT_EQ(1u, listener_stats_.downstream_cx_total_.value()); + EXPECT_EQ(0u, listener_stats_.downstream_cx_active_.value()); EXPECT_EQ(1u, listener_stats_.no_filter_chain_match_.value()); } diff --git a/test/extensions/quic_listeners/quiche/integration/BUILD b/test/extensions/quic_listeners/quiche/integration/BUILD index b9230fcdc0..50e556dd84 100644 --- a/test/extensions/quic_listeners/quiche/integration/BUILD +++ b/test/extensions/quic_listeners/quiche/integration/BUILD @@ -22,6 +22,7 @@ envoy_cc_test( "//source/extensions/quic_listeners/quiche:envoy_quic_connection_helper_lib", "//source/extensions/quic_listeners/quiche:envoy_quic_proof_verifier_lib", "//source/extensions/quic_listeners/quiche:quic_transport_socket_factory_lib", + "//test/extensions/quic_listeners/quiche:quic_test_utils_for_envoy_lib", "//test/integration:http_integration_lib", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", diff --git a/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc b/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc index 3974b5178d..e5adae7e5d 100644 --- a/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc +++ b/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc @@ -1,3 +1,5 @@ +#include + #include "envoy/config/bootstrap/v3/bootstrap.pb.h" #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h" #include "envoy/extensions/transport_sockets/tls/v3/cert.pb.h" @@ -14,6 +16,7 @@ #include "quiche/quic/core/http/quic_client_push_promise_index.h" #include "quiche/quic/core/quic_utils.h" +#include "quiche/quic/test_tools/quic_test_utils.h" #pragma GCC diagnostic pop @@ -23,6 +26,7 @@ #include "extensions/quic_listeners/quiche/envoy_quic_connection_helper.h" #include "extensions/quic_listeners/quiche/envoy_quic_alarm_factory.h" #include "extensions/quic_listeners/quiche/envoy_quic_packet_writer.h" +#include "extensions/quic_listeners/quiche/envoy_quic_utils.h" namespace Envoy { namespace Quic { @@ -49,7 +53,7 @@ class QuicHttpIntegrationTest : public testing::TestWithParam( - getNextServerDesignatedConnectionId(), server_addr, conn_helper_, alarm_factory_, + getNextServerDesignatedConnectionId(), server_addr_, conn_helper_, alarm_factory_, quic::ParsedQuicVersionVector{supported_versions_[0]}, local_addr, *dispatcher_, nullptr); + quic_connection_ = connection.get(); auto session = std::make_unique( quic_config_, supported_versions_, std::move(connection), server_id_, &crypto_config_, &push_promise_index_, *dispatcher_, 0); @@ -95,13 +100,15 @@ class QuicHttpIntegrationTest : public testing::TestWithParammutable_listeners(0)->mutable_filter_chains(0); auto* transport_socket = filter_chain->mutable_transport_socket(); transport_socket->mutable_typed_config()->PackFrom(tls_context); + + bootstrap.mutable_static_resources()->mutable_listeners(0)->set_reuse_port(set_reuse_port_); }); config_helper_.addConfigModifier( [](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& @@ -123,6 +130,9 @@ class QuicHttpIntegrationTest : public testing::TestWithParam codec_clients; + quic::QuicCryptoClientConfig::CachedState* cached = crypto_config_.LookupOrCreate(server_id_); + for (size_t i = 1; i <= concurrency_; ++i) { + // The BPF filter looks at the 1st word of connection id in the packet + // header. And currently all QUIC versions support 8 bytes connection id. So + // create connections with the first 4 bytes of connection id different from each + // other so they should be evenly distributed. + cached->add_server_designated_connection_id(quic::test::TestConnectionId(i << 32)); + codec_clients.push_back(makeHttpConnection(lookupPort("http"))); + } + if (GetParam() == Network::Address::IpVersion::v4) { + test_server_->waitForCounterEq("listener.0.0.0.0_0.downstream_cx_total", 8u); + } else { + test_server_->waitForCounterEq("listener.[__]_0.downstream_cx_total", 8u); + } + for (size_t i = 0; i < concurrency_; ++i) { + if (GetParam() == Network::Address::IpVersion::v4) { + test_server_->waitForGaugeEq( + fmt::format("listener.0.0.0.0_0.worker_{}.downstream_cx_active", i), 1u); + test_server_->waitForCounterEq( + fmt::format("listener.0.0.0.0_0.worker_{}.downstream_cx_total", i), 1u); + } else { + test_server_->waitForGaugeEq(fmt::format("listener.[__]_0.worker_{}.downstream_cx_active", i), + 1u); + test_server_->waitForCounterEq( + fmt::format("listener.[__]_0.worker_{}.downstream_cx_total", i), 1u); + } + } + for (size_t i = 0; i < concurrency_; ++i) { + codec_clients[i]->close(); + } +#endif +} + +#ifndef __APPLE__ +TEST_P(QuicHttpIntegrationTest, MultipleQuicListenersNoBPF) { + concurrency_ = 8; + set_reuse_port_ = true; + initialize(); +#ifdef SO_ATTACH_REUSEPORT_CBPF +#define SO_ATTACH_REUSEPORT_CBPF_TMP SO_ATTACH_REUSEPORT_CBPF +#undef SO_ATTACH_REUSEPORT_CBPF +#endif + std::vector codec_clients; + quic::QuicCryptoClientConfig::CachedState* cached = crypto_config_.LookupOrCreate(server_id_); + for (size_t i = 1; i <= concurrency_; ++i) { + // The BPF filter looks at the 1st byte of connection id in the packet + // header. And currently all QUIC versions support 8 bytes connection id. So + // create connections with the first 4 bytes of connection id different from each + // other so they should be evenly distributed. + cached->add_server_designated_connection_id(quic::test::TestConnectionId(i << 32)); + codec_clients.push_back(makeHttpConnection(lookupPort("http"))); + } + if (GetParam() == Network::Address::IpVersion::v4) { + test_server_->waitForCounterEq("listener.0.0.0.0_0.downstream_cx_total", 8u); + } else { + test_server_->waitForCounterEq("listener.[__]_0.downstream_cx_total", 8u); + } + // Even without BPF support, these connections should more or less distributed + // across different workers. + for (size_t i = 0; i < concurrency_; ++i) { + if (GetParam() == Network::Address::IpVersion::v4) { + EXPECT_LT( + test_server_->gauge(fmt::format("listener.0.0.0.0_0.worker_{}.downstream_cx_active", i)) + ->value(), + 8u); + EXPECT_LT( + test_server_->counter(fmt::format("listener.0.0.0.0_0.worker_{}.downstream_cx_total", i)) + ->value(), + 8u); + } else { + EXPECT_LT( + test_server_->gauge(fmt::format("listener.[__]_0.worker_{}.downstream_cx_active", i)) + ->value(), + 8u); + EXPECT_LT( + test_server_->counter(fmt::format("listener.[__]_0.worker_{}.downstream_cx_total", i)) + ->value(), + 8u); + } + } + for (size_t i = 0; i < concurrency_; ++i) { + codec_clients[i]->close(); + } +#ifdef SO_ATTACH_REUSEPORT_CBPF_TMP +#define SO_ATTACH_REUSEPORT_CBPF SO_ATTACH_REUSEPORT_CBPF_TMP +#endif +} +#endif + +#if defined(SO_ATTACH_REUSEPORT_CBPF) && defined(__linux__) +TEST_P(QuicHttpIntegrationTest, ConnectionMigration) { + concurrency_ = 2; + set_reuse_port_ = true; + initialize(); + uint32_t old_port = lookupPort("http"); + codec_client_ = makeHttpConnection(old_port); + auto encoder_decoder = + codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); + request_encoder_ = &encoder_decoder.first; + auto response = std::move(encoder_decoder.second); + + codec_client_->sendData(*request_encoder_, 1024u, false); + + // Change to a new port by switching socket, and connection should still continue. + Network::Address::InstanceConstSharedPtr local_addr = + Network::Test::getCanonicalLoopbackAddress(version_); + quic_connection_->switchConnectionSocket( + createConnectionSocket(server_addr_, local_addr, nullptr)); + EXPECT_NE(old_port, local_addr->ip()->port()); + // Send the rest data. + codec_client_->sendData(*request_encoder_, 1024u, true); + waitForNextUpstreamRequest(0, TestUtility::DefaultTimeout); + // Send response headers, and end_stream if there is no response body. + const Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + size_t response_size{5u}; + upstream_request_->encodeHeaders(response_headers, false); + upstream_request_->encodeData(response_size, true); + response->waitForEndStream(); + verifyResponse(std::move(response), "200", response_headers, std::string(response_size, 'a')); + + EXPECT_TRUE(upstream_request_->complete()); + EXPECT_EQ(1024u * 2, upstream_request_->bodyLength()); + cleanupUpstreamAndDownstream(); +} +#endif + } // namespace Quic } // namespace Envoy diff --git a/test/integration/integration.cc b/test/integration/integration.cc index 2cebafe2a1..f25cdeeb56 100644 --- a/test/integration/integration.cc +++ b/test/integration/integration.cc @@ -447,7 +447,7 @@ void BaseIntegrationTest::createGeneratedApiTestServer(const std::string& bootst const char* success = "listener_manager.listener_create_success"; const char* rejected = "listener_manager.lds.update_rejected"; while ((test_server_->counter(success) == nullptr || - test_server_->counter(success)->value() == 0) && + test_server_->counter(success)->value() < concurrency_) && (!allow_lds_rejection || test_server_->counter(rejected) == nullptr || test_server_->counter(rejected)->value() == 0)) { if (time_system_.monotonicTime() >= end_time) { diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index bf7133007b..d63cedfad6 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -312,7 +312,7 @@ class MockListenerConfig : public ListenerConfig { MOCK_METHOD(Stats::Scope&, listenerScope, ()); MOCK_METHOD(uint64_t, listenerTag, (), (const)); MOCK_METHOD(const std::string&, name, (), (const)); - MOCK_METHOD(const Network::ActiveUdpListenerFactory*, udpListenerFactory, ()); + MOCK_METHOD(Network::ActiveUdpListenerFactory*, udpListenerFactory, ()); MOCK_METHOD(ConnectionBalancer&, connectionBalancer, ()); envoy::config::core::v3::TrafficDirection direction() const override { diff --git a/test/server/connection_handler_test.cc b/test/server/connection_handler_test.cc index ec4fcf68b5..08ae4e2048 100644 --- a/test/server/connection_handler_test.cc +++ b/test/server/connection_handler_test.cc @@ -62,7 +62,7 @@ class ConnectionHandlerTest : public testing::Test, protected Logger::Loggable(listener_name) - .createActiveUdpListenerFactory(dummy); + .createActiveUdpListenerFactory(dummy, /*concurrency=*/1); ON_CALL(*socket_, socketType()).WillByDefault(Return(socket_type)); } @@ -84,7 +84,7 @@ class ConnectionHandlerTest : public testing::Test, protected Logger::Loggable Date: Fri, 7 Feb 2020 08:10:33 -0800 Subject: [PATCH 22/87] adaptive concurrency: Fix min_concurrency behavior when gradient shrinks (#9947) The min_concurrency setting dicated the concurrency limit when in a min_rtt calculation window. However, if the gradient caused the concurrency limit to shrink, it was possible for the limit to drop below this configured minimum. This patch fixes this behavior so that the calculated concurrency limit is always >= the configured minimum. In addition, a minor change to the stat indicating whether the min_rtt calculation window is active. When active, the stat was being set to the concurrency limit; however, according to the documentation this should be either 0 or 1. This patch also fixes this behavior. Signed-off-by: Tony Allen --- docs/root/intro/version_history.rst | 2 ++ .../gradient_controller.cc | 11 +++---- .../gradient_controller_test.cc | 29 +++++++++++-------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index 186ba2de61..2db820f293 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -5,6 +5,8 @@ Version history ================ * access loggers: access logger extensions use the "envoy.access_loggers" name space. A mapping of extension names is available in the :ref:`deprecated ` documentation. +* adaptive concurrency: fixed bug that allowed concurrency limits to drop below the configured + minimum. * config: use type URL to select an extension whenever the config type URL (or its previous versions) uniquely identify a typed extension, see :ref:`extension configuration `. * http: fixing a bug in HTTP/1.0 responses where Connection: keep-alive was not appended for connections which were kept alive. * retry: added a retry predicate that :ref:`rejects hosts based on metadata. ` diff --git a/source/extensions/filters/http/adaptive_concurrency/concurrency_controller/gradient_controller.cc b/source/extensions/filters/http/adaptive_concurrency/concurrency_controller/gradient_controller.cc index 11c8fc844c..e975e9b592 100644 --- a/source/extensions/filters/http/adaptive_concurrency/concurrency_controller/gradient_controller.cc +++ b/source/extensions/filters/http/adaptive_concurrency/concurrency_controller/gradient_controller.cc @@ -48,8 +48,8 @@ GradientController::GradientController(GradientControllerConfig config, const std::string& stats_prefix, Stats::Scope& scope, Runtime::RandomGenerator& random) : config_(std::move(config)), dispatcher_(dispatcher), scope_(scope), - stats_(generateStats(scope_, stats_prefix)), random_(random), deferred_limit_value_(1), - num_rq_outstanding_(0), concurrency_limit_(config_.minConcurrency()), + stats_(generateStats(scope_, stats_prefix)), random_(random), num_rq_outstanding_(0), + concurrency_limit_(config_.minConcurrency()), latency_sample_hist_(hist_fast_alloc(), hist_free) { min_rtt_calc_timer_ = dispatcher_.createTimer([this]() -> void { enterMinRTTSamplingWindow(); }); @@ -83,7 +83,7 @@ GradientControllerStats GradientController::generateStats(Stats::Scope& scope, void GradientController::enterMinRTTSamplingWindow() { absl::MutexLock ml(&sample_mutation_mtx_); - stats_.min_rtt_calculation_active_.set(config_.minConcurrency()); + stats_.min_rtt_calculation_active_.set(1); // Set the minRTT flag to indicate we're gathering samples to update the value. This will // prevent the sample window from resetting until enough requests are gathered to complete the @@ -162,9 +162,10 @@ uint32_t GradientController::calculateNewLimit() { stats_.burst_queue_size_.set(burst_headroom); // The final concurrency value factors in the burst headroom and must be clamped to keep the value - // in the range [1, configured_max]. + // in the range [configured_min, configured_max]. const uint32_t new_limit = limit + burst_headroom; - return std::max(1, std::min(config_.maxConcurrencyLimit(), new_limit)); + return std::max(config_.minConcurrency(), + std::min(config_.maxConcurrencyLimit(), new_limit)); } RequestForwardingAction GradientController::forwardingDecision() { diff --git a/test/extensions/filters/http/adaptive_concurrency/concurrency_controller/gradient_controller_test.cc b/test/extensions/filters/http/adaptive_concurrency/concurrency_controller/gradient_controller_test.cc index f354c57622..a7e02b3a8e 100644 --- a/test/extensions/filters/http/adaptive_concurrency/concurrency_controller/gradient_controller_test.cc +++ b/test/extensions/filters/http/adaptive_concurrency/concurrency_controller/gradient_controller_test.cc @@ -219,29 +219,32 @@ TEST_F(GradientControllerTest, MinRTTLogicTest) { value: 0.0 interval: 30s request_count: 50 - min_concurrency: 1 + min_concurrency: 7 )EOF"; auto controller = makeController(yaml); const auto min_rtt = std::chrono::milliseconds(13); - // The controller should be measuring minRTT upon creation, so the concurrency window is 1 (the + // The controller should be measuring minRTT upon creation, so the concurrency window is 7 (the // min concurrency). EXPECT_EQ( 1, stats_.gauge("test_prefix.min_rtt_calculation_active", Stats::Gauge::ImportMode::Accumulate) .value()); - EXPECT_EQ(controller->concurrencyLimit(), 1); - tryForward(controller, true); + EXPECT_EQ(controller->concurrencyLimit(), 7); + for (int i = 0; i < 7; ++i) { + tryForward(controller, true); + } tryForward(controller, false); tryForward(controller, false); - controller->recordLatencySample(min_rtt); + for (int i = 0; i < 7; ++i) { + controller->recordLatencySample(min_rtt); + } - // 49 more requests should cause the minRTT to be done calculating. - for (int i = 0; i < 49; ++i) { - EXPECT_EQ(controller->concurrencyLimit(), 1); + // 43 more requests should cause the minRTT to be done calculating. + for (int i = 0; i < 43; ++i) { + EXPECT_EQ(controller->concurrencyLimit(), 7); tryForward(controller, true); - tryForward(controller, false); controller->recordLatencySample(min_rtt); } @@ -356,10 +359,11 @@ TEST_F(GradientControllerTest, ConcurrencyLimitBehaviorTestBasic) { request_count: 5 buffer: value: 10 + min_concurrency: 7 )EOF"; auto controller = makeController(yaml); - EXPECT_EQ(controller->concurrencyLimit(), 3); + EXPECT_EQ(controller->concurrencyLimit(), 7); // Force a minRTT of 5ms. advancePastMinRTTStage(controller, yaml, std::chrono::milliseconds(5)); @@ -370,8 +374,8 @@ TEST_F(GradientControllerTest, ConcurrencyLimitBehaviorTestBasic) { // the max gradient. time_system_.sleep(std::chrono::milliseconds(101)); dispatcher_->run(Event::Dispatcher::RunType::Block); - EXPECT_GE(controller->concurrencyLimit(), 3); - EXPECT_LE(controller->concurrencyLimit() / 3.0, 2.0); + EXPECT_GE(controller->concurrencyLimit(), 7); + EXPECT_LE(controller->concurrencyLimit() / 7.0, 2.0); // Make it seem as if the recorded latencies are consistently lower than the measured minRTT. // Ensure that it grows. @@ -398,6 +402,7 @@ TEST_F(GradientControllerTest, ConcurrencyLimitBehaviorTestBasic) { time_system_.sleep(std::chrono::milliseconds(101)); dispatcher_->run(Event::Dispatcher::RunType::Block); EXPECT_LT(controller->concurrencyLimit(), last_concurrency); + EXPECT_GE(controller->concurrencyLimit(), 7); } } From 6d69def257c0bc820223b335cfaa7dac2bbbfee1 Mon Sep 17 00:00:00 2001 From: alyssawilk Date: Fri, 7 Feb 2020 11:12:16 -0500 Subject: [PATCH 23/87] http: fixing a bug where responseDataTooLarge skipped HCM work (#9923) Signed-off-by: Alyssa Wilk --- source/common/http/conn_manager_impl.cc | 72 ++++++++++--------- source/common/http/conn_manager_impl.h | 16 ++++- test/common/http/conn_manager_impl_test.cc | 12 ++-- test/integration/protocol_integration_test.cc | 3 + 4 files changed, 65 insertions(+), 38 deletions(-) diff --git a/source/common/http/conn_manager_impl.cc b/source/common/http/conn_manager_impl.cc index 947d511fd5..966efb6306 100644 --- a/source/common/http/conn_manager_impl.cc +++ b/source/common/http/conn_manager_impl.cc @@ -1524,6 +1524,23 @@ void ConnectionManagerImpl::ActiveStream::encodeHeaders(ActiveStreamEncoderFilte } } + const bool modified_end_stream = + encoding_headers_only_ || (end_stream && continue_data_entry == encoder_filters_.end()); + encodeHeadersInternal(headers, modified_end_stream); + + if (continue_data_entry != encoder_filters_.end() && !modified_end_stream) { + // We use the continueEncoding() code since it will correctly handle not calling + // encodeHeaders() again. Fake setting StopSingleIteration since the continueEncoding() code + // expects it. + ASSERT(buffered_response_data_); + (*continue_data_entry)->iteration_state_ = + ActiveStreamFilterBase::IterationState::StopSingleIteration; + (*continue_data_entry)->continueEncoding(); + } +} + +void ConnectionManagerImpl::ActiveStream::encodeHeadersInternal(HeaderMap& headers, + bool end_stream) { // Base headers. connection_manager_.config_.dateProvider().setDateHeader(headers); // Following setReference() is safe because serverName() is constant for the life of the listener. @@ -1622,29 +1639,12 @@ void ConnectionManagerImpl::ActiveStream::encodeHeaders(ActiveStreamEncoderFilte chargeStats(headers); - ENVOY_STREAM_LOG(debug, "encoding headers via codec (end_stream={}):\n{}", *this, - encoding_headers_only_ || - (end_stream && continue_data_entry == encoder_filters_.end()), - headers); + ENVOY_STREAM_LOG(debug, "encoding headers via codec (end_stream={}):\n{}", *this, end_stream); // Now actually encode via the codec. stream_info_.onFirstDownstreamTxByteSent(); - response_encoder_->encodeHeaders( - headers, - encoding_headers_only_ || (end_stream && continue_data_entry == encoder_filters_.end())); - if (continue_data_entry != encoder_filters_.end()) { - // We use the continueEncoding() code since it will correctly handle not calling - // encodeHeaders() again. Fake setting StopSingleIteration since the continueEncoding() code - // expects it. - ASSERT(buffered_response_data_); - (*continue_data_entry)->iteration_state_ = - ActiveStreamFilterBase::IterationState::StopSingleIteration; - (*continue_data_entry)->continueEncoding(); - } else { - // End encoding if this is a header only response, either due to a filter converting it to one - // or due to the upstream returning headers only. - maybeEndEncode(encoding_headers_only_ || end_stream); - } + response_encoder_->encodeHeaders(headers, end_stream); + maybeEndEncode(end_stream); } void ConnectionManagerImpl::ActiveStream::encodeMetadata(ActiveStreamEncoderFilter* filter, @@ -1772,22 +1772,27 @@ void ConnectionManagerImpl::ActiveStream::encodeData( } } - ENVOY_STREAM_LOG(trace, "encoding data via codec (size={} end_stream={})", *this, data.length(), - end_stream); - - stream_info_.addBytesSent(data.length()); + const bool modified_end_stream = end_stream && trailers_added_entry == encoder_filters_.end(); + encodeDataInternal(data, modified_end_stream); // If trailers were adding during encodeData we need to trigger decodeTrailers in order // to allow filters to process the trailers. if (trailers_added_entry != encoder_filters_.end()) { - response_encoder_->encodeData(data, false); encodeTrailers(trailers_added_entry->get(), *response_trailers_); - } else { - response_encoder_->encodeData(data, end_stream); - maybeEndEncode(end_stream); } } +void ConnectionManagerImpl::ActiveStream::encodeDataInternal(Buffer::Instance& data, + bool end_stream) { + ASSERT(!encoding_headers_only_); + ENVOY_STREAM_LOG(trace, "encoding data via codec (size={} end_stream={})", *this, data.length(), + end_stream); + + stream_info_.addBytesSent(data.length()); + response_encoder_->encodeData(data, end_stream); + maybeEndEncode(end_stream); +} + void ConnectionManagerImpl::ActiveStream::encodeTrailers(ActiveStreamEncoderFilter* filter, HeaderMap& trailers) { resetIdleTimer(); @@ -2398,17 +2403,18 @@ void ConnectionManagerImpl::ActiveStreamEncoderFilter::responseDataTooLarge() { parent_.stream_info_.setResponseCodeDetails( StreamInfo::ResponseCodeDetails::get().RequestHeadersTooLarge); + // This does not call the standard sendLocalReply because if there is already response data + // we do not want to pass a second set of response headers through the filter chain. + // Instead, call the encodeHeadersInternal / encodeDataInternal helpers + // directly, which maximizes shared code with the normal response path. Http::Utility::sendLocalReply( Grpc::Common::hasGrpcContentType(*parent_.request_headers_), [&](HeaderMapPtr&& response_headers, bool end_stream) -> void { - parent_.chargeStats(*response_headers); parent_.response_headers_ = std::move(response_headers); - parent_.response_encoder_->encodeHeaders(*parent_.response_headers_, end_stream); - parent_.state_.local_complete_ = end_stream; + parent_.encodeHeadersInternal(*parent_.response_headers_, end_stream); }, [&](Buffer::Instance& data, bool end_stream) -> void { - parent_.response_encoder_->encodeData(data, end_stream); - parent_.state_.local_complete_ = end_stream; + parent_.encodeDataInternal(data, end_stream); }, parent_.state_.destroyed_, Http::Code::InternalServerError, CodeUtility::toString(Http::Code::InternalServerError), absl::nullopt, diff --git a/source/common/http/conn_manager_impl.h b/source/common/http/conn_manager_impl.h index 072215fb18..961632a6f0 100644 --- a/source/common/http/conn_manager_impl.h +++ b/source/common/http/conn_manager_impl.h @@ -480,13 +480,27 @@ class ConnectionManagerImpl : Logger::Loggable, const absl::optional grpc_status, absl::string_view details); void encode100ContinueHeaders(ActiveStreamEncoderFilter* filter, HeaderMap& headers); + // As with most of the encode functions, this runs encodeHeaders on various + // filters before calling encodeHeadersInternal which does final header munging and passes the + // headers to the encoder. void encodeHeaders(ActiveStreamEncoderFilter* filter, HeaderMap& headers, bool end_stream); // Sends data through encoding filter chains. filter_iteration_start_state indicates which - // filter to start the iteration with. + // filter to start the iteration with, and finally calls encodeDataInternal + // to update stats, do end stream bookkeeping, and send the data to encoder. void encodeData(ActiveStreamEncoderFilter* filter, Buffer::Instance& data, bool end_stream, FilterIterationStartState filter_iteration_start_state); void encodeTrailers(ActiveStreamEncoderFilter* filter, HeaderMap& trailers); void encodeMetadata(ActiveStreamEncoderFilter* filter, MetadataMapPtr&& metadata_map_ptr); + + // This is a helper function for encodeHeaders and responseDataTooLarge which allows for shared + // code for the two headers encoding paths. It does header munging, updates timing stats, and + // sends the headers to the encoder. + void encodeHeadersInternal(HeaderMap& headers, bool end_stream); + // This is a helper function for encodeData and responseDataTooLarge which allows for shared + // code for the two data encoding paths. It does stats updates and tracks potential end of + // stream. + void encodeDataInternal(Buffer::Instance& data, bool end_stream); + void maybeEndEncode(bool end_stream); // Returns true if new metadata is decoded. Otherwise, returns false. bool processNewlyAddedMetadata(); diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc index d22c3c0581..2c26582175 100644 --- a/test/common/http/conn_manager_impl_test.cc +++ b/test/common/http/conn_manager_impl_test.cc @@ -3808,16 +3808,20 @@ TEST_F(HttpConnectionManagerImplTest, HitResponseBufferLimitsBeforeHeaders) { // StopIterationAndBuffer, which will trigger an early response. expectOnDestroy(); - Http::TestHeaderMapImpl expected_response_headers{ - {":status", "500"}, {"content-length", "21"}, {"content-type", "text/plain"}}; Buffer::OwnedImpl fake_response("A long enough string to go over watermarks"); // Fake response starts doing through the filter. EXPECT_CALL(*encoder_filters_[1], encodeData(_, false)) .WillOnce(Return(FilterDataStatus::StopIterationAndBuffer)); std::string response_body; // The 500 goes directly to the encoder. - EXPECT_CALL(response_encoder_, - encodeHeaders(HeaderMapEqualRef(&expected_response_headers), false)); + EXPECT_CALL(response_encoder_, encodeHeaders(_, false)) + .WillOnce(Invoke([&](const HeaderMap& headers, bool) -> FilterHeadersStatus { + // Make sure this is a 500 + EXPECT_EQ("500", headers.Status()->value().getStringView()); + // Make sure Envoy standard sanitization has been applied. + EXPECT_TRUE(headers.Date() != nullptr); + return FilterHeadersStatus::Continue; + })); EXPECT_CALL(response_encoder_, encodeData(_, true)).WillOnce(AddBufferToString(&response_body)); decoder_filters_[0]->callbacks_->encodeData(fake_response, false); EXPECT_EQ("Internal Server Error", response_body); diff --git a/test/integration/protocol_integration_test.cc b/test/integration/protocol_integration_test.cc index 5f87953192..45b3055c23 100644 --- a/test/integration/protocol_integration_test.cc +++ b/test/integration/protocol_integration_test.cc @@ -580,6 +580,9 @@ TEST_P(ProtocolIntegrationTest, HittingEncoderFilterLimit) { response->waitForEndStream(); EXPECT_TRUE(response->complete()); EXPECT_EQ("500", response->headers().Status()->value().getStringView()); + // Regression test https://github.com/envoyproxy/envoy/issues/9881 by making + // sure this path does standard HCM header transformations. + EXPECT_TRUE(response->headers().Date() != nullptr); EXPECT_THAT(waitForAccessLog(access_log_name_), HasSubstr("500")); test_server_->waitForCounterEq("http.config_test.downstream_rq_5xx", 1); } From 40efc227ca89ed583e3ec4b77463fe704f51ab6f Mon Sep 17 00:00:00 2001 From: Jose Ulises Nino Rivera Date: Fri, 7 Feb 2020 11:26:31 -0800 Subject: [PATCH 24/87] metrics service: force link v2 config (#9875) Description: force link the v2 proto for metrics service config. Needed in some linking scenarios. Related to #9639. Risk Level: low Testing: on an iOS build of Envoy Mobile. Signed-off-by: Jose Nino --- source/extensions/stat_sinks/metrics_service/BUILD | 2 ++ .../grpc_metrics_proto_descriptors.cc | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/source/extensions/stat_sinks/metrics_service/BUILD b/source/extensions/stat_sinks/metrics_service/BUILD index 3ef7e3898c..c26135a750 100644 --- a/source/extensions/stat_sinks/metrics_service/BUILD +++ b/source/extensions/stat_sinks/metrics_service/BUILD @@ -32,7 +32,9 @@ envoy_cc_library( hdrs = ["grpc_metrics_proto_descriptors.h"], deps = [ "//source/common/common:assert_lib", + "//source/common/config:api_version_lib", "//source/common/protobuf", + "@envoy_api//envoy/config/metrics/v2:pkg_cc_proto", "@envoy_api//envoy/service/metrics/v2:pkg_cc_proto", ], ) diff --git a/source/extensions/stat_sinks/metrics_service/grpc_metrics_proto_descriptors.cc b/source/extensions/stat_sinks/metrics_service/grpc_metrics_proto_descriptors.cc index 73fe36e4a7..16793caef4 100644 --- a/source/extensions/stat_sinks/metrics_service/grpc_metrics_proto_descriptors.cc +++ b/source/extensions/stat_sinks/metrics_service/grpc_metrics_proto_descriptors.cc @@ -1,9 +1,11 @@ #include "extensions/stat_sinks/metrics_service/grpc_metrics_proto_descriptors.h" +#include "envoy/config/metrics/v2/metrics_service.pb.h" #include "envoy/service/metrics/v2/metrics_service.pb.h" #include "common/common/assert.h" #include "common/common/fmt.h" +#include "common/config/api_version.h" #include "common/protobuf/protobuf.h" namespace Envoy { @@ -13,12 +15,22 @@ namespace MetricsService { void validateProtoDescriptors() { // https://github.com/envoyproxy/envoy/issues/9639 - const envoy::service::metrics::v2::StreamMetricsMessage _dummy_v2; + const API_NO_BOOST(envoy::service::metrics::v2::StreamMetricsMessage) _dummy_service_v2; + // https://github.com/envoyproxy/envoy/pull/9618 made it necessary to register the previous + // version's config descriptor by calling ApiTypeOracle::getEarlierVersionDescriptor which has an + // assertion for nullptr types. + const API_NO_BOOST(envoy::config::metrics::v2::MetricsServiceConfig) _dummy_config_v2; const auto method = "envoy.service.metrics.v2.MetricsService.StreamMetrics"; RELEASE_ASSERT(Protobuf::DescriptorPool::generated_pool()->FindMethodByName(method) != nullptr, ""); + + const auto config = "envoy.config.metrics.v2.MetricsServiceConfig"; + + // Keeping this as an ASSERT because ApiTypeOracle::getEarlierVersionDescriptor also has an + // ASSERT. + ASSERT(Protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(config) != nullptr, ""); }; } // namespace MetricsService } // namespace StatSinks From 7801d058b2d3d9fc91cd8730cdbba0f76f88a0ee Mon Sep 17 00:00:00 2001 From: Sunjay Bhatia Date: Fri, 7 Feb 2020 14:59:14 -0500 Subject: [PATCH 25/87] Fix assorted breakages and Windows compilation changes (#9966) Signed-off-by: William A Rowe Jr Signed-off-by: Yechiel Kalmenson Signed-off-by: Sunjay Bhatia --- bazel/boringssl_static.patch | 16 ++++++++++ bazel/envoy_test.bzl | 3 +- bazel/repository_locations.bzl | 7 +++-- source/common/api/BUILD | 31 ++++++++++--------- .../api/{ => posix}/os_sys_calls_impl.cc | 4 +-- .../api/{ => posix}/os_sys_calls_impl.h | 0 .../os_sys_calls_impl_hot_restart.cc | 4 +-- .../os_sys_calls_impl_hot_restart.h | 0 .../{ => posix}/os_sys_calls_impl_linux.cc | 4 +-- .../api/{ => posix}/os_sys_calls_impl_linux.h | 0 source/common/common/win32/thread_impl.h | 3 ++ test/extensions/common/aws/mocks.h | 1 + test/tools/router_check/BUILD | 1 + test/tools/router_check/router_check.cc | 5 +++ tools/spelling_dictionary.txt | 2 ++ 15 files changed, 57 insertions(+), 24 deletions(-) rename source/common/api/{ => posix}/os_sys_calls_impl.cc (100%) rename source/common/api/{ => posix}/os_sys_calls_impl.h (100%) rename source/common/api/{ => posix}/os_sys_calls_impl_hot_restart.cc (100%) rename source/common/api/{ => posix}/os_sys_calls_impl_hot_restart.h (100%) rename source/common/api/{ => posix}/os_sys_calls_impl_linux.cc (100%) rename source/common/api/{ => posix}/os_sys_calls_impl_linux.h (100%) diff --git a/bazel/boringssl_static.patch b/bazel/boringssl_static.patch index 4360d06a3c..dd2a72847a 100644 --- a/bazel/boringssl_static.patch +++ b/bazel/boringssl_static.patch @@ -10,3 +10,19 @@ index d7c731bf6..315cdeca0 100644 ], "//conditions:default": ["-DOPENSSL_NO_ASM"], }) +@@ -141,6 +142,7 @@ cc_library( + ":windows_x86_64": ["-defaultlib:advapi32.lib"], + "//conditions:default": ["-lpthread"], + }), ++ linkstatic = True, + visibility = ["//visibility:public"], + ) + +@@ -150,6 +152,7 @@ cc_library( + hdrs = ssl_headers, + copts = boringssl_copts_cxx, + includes = ["src/include"], ++ linkstatic = True, + visibility = ["//visibility:public"], + deps = [ + ":crypto", diff --git a/bazel/envoy_test.bzl b/bazel/envoy_test.bzl index 3807d52fcd..17d67ff060 100644 --- a/bazel/envoy_test.bzl +++ b/bazel/envoy_test.bzl @@ -106,9 +106,10 @@ def envoy_cc_fuzz_test( linkstatic = 1, args = ["$(locations %s)" % corpus_name], data = [corpus_name], - # No fuzzing on macOS. + # No fuzzing on macOS or Windows deps = select({ "@envoy//bazel:apple": [repository + "//test:dummy_main"], + "@envoy//bazel:windows_x86_64": [repository + "//test:dummy_main"], "//conditions:default": [ ":" + test_lib_name, repository + "//test/fuzz:main", diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 06368be355..7fab9e774e 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -196,9 +196,10 @@ REPOSITORY_LOCATIONS = dict( urls = ["https://github.com/pallets/markupsafe/archive/1.1.1.tar.gz"], ), com_github_tencent_rapidjson = dict( - sha256 = "bf7ced29704a1e696fbccf2a2b4ea068e7774fa37f6d7dd4039d0787f8bed98e", - strip_prefix = "rapidjson-1.1.0", - urls = ["https://github.com/Tencent/rapidjson/archive/v1.1.0.tar.gz"], + sha256 = "a2faafbc402394df0fa94602df4b5e4befd734aad6bb55dfef46f62fcaf1090b", + strip_prefix = "rapidjson-dfbe1db9da455552f7a9ad5d2aea17dd9d832ac1", + # Changes through 2019-12-02 + urls = ["https://github.com/Tencent/rapidjson/archive/dfbe1db9da455552f7a9ad5d2aea17dd9d832ac1.tar.gz"], ), com_github_twitter_common_lang = dict( sha256 = "56d1d266fd4767941d11c27061a57bc1266a3342e551bde3780f9e9eb5ad0ed1", diff --git a/source/common/api/BUILD b/source/common/api/BUILD index b8b60aab61..f10bdc078d 100644 --- a/source/common/api/BUILD +++ b/source/common/api/BUILD @@ -22,20 +22,23 @@ envoy_cc_library( envoy_cc_library( name = "os_sys_calls_lib", - srcs = ["os_sys_calls_impl.cc"] + select({ - "//bazel:linux_x86_64": ["os_sys_calls_impl_linux.cc"], - "//bazel:linux_aarch64": ["os_sys_calls_impl_linux.cc"], - "//bazel:linux_ppc": ["os_sys_calls_impl_linux.cc"], - "//bazel:linux_mips64": ["os_sys_calls_impl_linux.cc"], - "//conditions:default": [], - }) + envoy_select_hot_restart(["os_sys_calls_impl_hot_restart.cc"]), - hdrs = ["os_sys_calls_impl.h"] + select({ - "//bazel:linux_x86_64": ["os_sys_calls_impl_linux.h"], - "//bazel:linux_aarch64": ["os_sys_calls_impl_linux.h"], - "//bazel:linux_ppc": ["os_sys_calls_impl_linux.h"], - "//bazel:linux_mips64": ["os_sys_calls_impl_linux.h"], - "//conditions:default": [], - }) + envoy_select_hot_restart(["os_sys_calls_impl_hot_restart.h"]), + srcs = select({ + "//bazel:linux": [ + "posix/os_sys_calls_impl.cc", + "posix/os_sys_calls_impl_linux.cc", + ], + "//conditions:default": ["posix/os_sys_calls_impl.cc"], + }) + envoy_select_hot_restart(["posix/os_sys_calls_impl_hot_restart.cc"]), + hdrs = select({ + "//bazel:linux": [ + "posix/os_sys_calls_impl.h", + "posix/os_sys_calls_impl_linux.h", + ], + "//conditions:default": ["posix/os_sys_calls_impl.h"], + }) + envoy_select_hot_restart(["posix/os_sys_calls_impl_hot_restart.h"]), + strip_include_prefix = select({ + "//conditions:default": "posix", + }), deps = [ "//include/envoy/api:os_sys_calls_interface", "//source/common/singleton:threadsafe_singleton", diff --git a/source/common/api/os_sys_calls_impl.cc b/source/common/api/posix/os_sys_calls_impl.cc similarity index 100% rename from source/common/api/os_sys_calls_impl.cc rename to source/common/api/posix/os_sys_calls_impl.cc index 5f13d7839a..a75df5a029 100644 --- a/source/common/api/os_sys_calls_impl.cc +++ b/source/common/api/posix/os_sys_calls_impl.cc @@ -1,5 +1,3 @@ -#include "common/api/os_sys_calls_impl.h" - #include #include #include @@ -7,6 +5,8 @@ #include #include +#include "common/api/os_sys_calls_impl.h" + namespace Envoy { namespace Api { diff --git a/source/common/api/os_sys_calls_impl.h b/source/common/api/posix/os_sys_calls_impl.h similarity index 100% rename from source/common/api/os_sys_calls_impl.h rename to source/common/api/posix/os_sys_calls_impl.h diff --git a/source/common/api/os_sys_calls_impl_hot_restart.cc b/source/common/api/posix/os_sys_calls_impl_hot_restart.cc similarity index 100% rename from source/common/api/os_sys_calls_impl_hot_restart.cc rename to source/common/api/posix/os_sys_calls_impl_hot_restart.cc index 1df6bc57f9..7f9d6e0ffd 100644 --- a/source/common/api/os_sys_calls_impl_hot_restart.cc +++ b/source/common/api/posix/os_sys_calls_impl_hot_restart.cc @@ -1,7 +1,7 @@ -#include "common/api/os_sys_calls_impl_hot_restart.h" - #include +#include "common/api/os_sys_calls_impl_hot_restart.h" + namespace Envoy { namespace Api { diff --git a/source/common/api/os_sys_calls_impl_hot_restart.h b/source/common/api/posix/os_sys_calls_impl_hot_restart.h similarity index 100% rename from source/common/api/os_sys_calls_impl_hot_restart.h rename to source/common/api/posix/os_sys_calls_impl_hot_restart.h diff --git a/source/common/api/os_sys_calls_impl_linux.cc b/source/common/api/posix/os_sys_calls_impl_linux.cc similarity index 100% rename from source/common/api/os_sys_calls_impl_linux.cc rename to source/common/api/posix/os_sys_calls_impl_linux.cc index 9b2d213c08..1eece81f78 100644 --- a/source/common/api/os_sys_calls_impl_linux.cc +++ b/source/common/api/posix/os_sys_calls_impl_linux.cc @@ -2,12 +2,12 @@ #error "Linux platform file is part of non-Linux build." #endif -#include "common/api/os_sys_calls_impl_linux.h" - #include #include +#include "common/api/os_sys_calls_impl_linux.h" + namespace Envoy { namespace Api { diff --git a/source/common/api/os_sys_calls_impl_linux.h b/source/common/api/posix/os_sys_calls_impl_linux.h similarity index 100% rename from source/common/api/os_sys_calls_impl_linux.h rename to source/common/api/posix/os_sys_calls_impl_linux.h diff --git a/source/common/common/win32/thread_impl.h b/source/common/common/win32/thread_impl.h index 76d61a4599..8b5d0fe37e 100644 --- a/source/common/common/win32/thread_impl.h +++ b/source/common/common/win32/thread_impl.h @@ -20,6 +20,9 @@ class ThreadImplWin32 : public Thread { // Thread::Thread void join() override; + // Needed for WatcherImpl for the QueueUserAPC callback context + HANDLE handle() const { return thread_handle_; } + private: std::function thread_routine_; HANDLE thread_handle_; diff --git a/test/extensions/common/aws/mocks.h b/test/extensions/common/aws/mocks.h index 99048a6dec..8e483ebe13 100644 --- a/test/extensions/common/aws/mocks.h +++ b/test/extensions/common/aws/mocks.h @@ -24,6 +24,7 @@ class MockSigner : public Signer { ~MockSigner() override; MOCK_METHOD(void, sign, (Http::Message&, bool)); + MOCK_METHOD(void, sign, (Http::HeaderMap&)); }; class MockMetadataFetcher { diff --git a/test/tools/router_check/BUILD b/test/tools/router_check/BUILD index a5294f90c8..337c4855af 100644 --- a/test/tools/router_check/BUILD +++ b/test/tools/router_check/BUILD @@ -34,6 +34,7 @@ envoy_cc_test_library( "//source/common/json:json_loader_lib", "//source/common/router:config_lib", "//source/common/stats:stats_lib", + "//source/exe:platform_impl_lib", "//test/mocks/server:server_mocks", "//test/test_common:printers_lib", "//test/test_common:utility_lib", diff --git a/test/tools/router_check/router_check.cc b/test/tools/router_check/router_check.cc index 1792af5c5b..1f0a11e166 100644 --- a/test/tools/router_check/router_check.cc +++ b/test/tools/router_check/router_check.cc @@ -2,12 +2,17 @@ #include #include +#include "exe/platform_impl.h" + #include "test/tools/router_check/router.h" int main(int argc, char* argv[]) { Envoy::Options options(argc, argv); const bool enforce_coverage = options.failUnder() != 0.0; + // We need this to ensure WSAStartup is called on Windows + Envoy::PlatformImpl platform_impl_; + try { Envoy::RouterCheckTool checktool = options.isProto() ? Envoy::RouterCheckTool::create(options.configPath(), diff --git a/tools/spelling_dictionary.txt b/tools/spelling_dictionary.txt index c6e048073d..7a6919881a 100644 --- a/tools/spelling_dictionary.txt +++ b/tools/spelling_dictionary.txt @@ -9,6 +9,7 @@ AFAICT ALPN ALS AMZ +APC API ASAN ASCII @@ -323,6 +324,7 @@ WIP WKT WRR WS +WSA Welford's Wi XDS From db3db000beef9d378aa82118205a3324186c64ca Mon Sep 17 00:00:00 2001 From: danzh Date: Fri, 7 Feb 2020 16:46:50 -0500 Subject: [PATCH 26/87] network: Add new interface TransportSocketCallbacks::flushWriteBuffer() (#9944) Signed-off-by: Dan Zhang --- include/envoy/network/transport_socket.h | 6 +++++ source/common/network/connection_impl.cc | 11 ++++++--- source/common/network/connection_impl.h | 1 + .../alts/noop_transport_socket_callbacks.h | 1 + test/common/network/connection_impl_test.cc | 24 +++++++++++++++++++ .../noop_transport_socket_callbacks_test.cc | 5 ++++ test/mocks/network/mocks.h | 1 + 7 files changed, 46 insertions(+), 3 deletions(-) diff --git a/include/envoy/network/transport_socket.h b/include/envoy/network/transport_socket.h index abf2351e8b..e303248fd4 100644 --- a/include/envoy/network/transport_socket.h +++ b/include/envoy/network/transport_socket.h @@ -83,6 +83,12 @@ class TransportSocketCallbacks { * @param event supplies the connection event */ virtual void raiseEvent(ConnectionEvent event) PURE; + + /** + * If the callbacks' write buffer is not empty, try to drain the buffer. + * As of 2/20, used by Google. + */ + virtual void flushWriteBuffer() PURE; }; /** diff --git a/source/common/network/connection_impl.cc b/source/common/network/connection_impl.cc index 5e9b57a899..91a6446a31 100644 --- a/source/common/network/connection_impl.cc +++ b/source/common/network/connection_impl.cc @@ -353,9 +353,8 @@ void ConnectionImpl::raiseEvent(ConnectionEvent event) { // where no check of the write buffer is made. Provide an opportunity to flush // here. If connection write is not ready, this is harmless. We should only do // this if we're still open (the above callbacks may have closed). - if (state() == State::Open && event == ConnectionEvent::Connected && - write_buffer_->length() > 0) { - onWriteReady(); + if (event == ConnectionEvent::Connected) { + flushWriteBuffer(); } } @@ -652,6 +651,12 @@ absl::string_view ConnectionImpl::transportFailureReason() const { return transport_socket_->failureReason(); } +void ConnectionImpl::flushWriteBuffer() { + if (state() == State::Open && write_buffer_->length() > 0) { + onWriteReady(); + } +} + ClientConnectionImpl::ClientConnectionImpl( Event::Dispatcher& dispatcher, const Address::InstanceConstSharedPtr& remote_address, const Network::Address::InstanceConstSharedPtr& source_address, diff --git a/source/common/network/connection_impl.h b/source/common/network/connection_impl.h index 90a114b318..450efa869e 100644 --- a/source/common/network/connection_impl.h +++ b/source/common/network/connection_impl.h @@ -112,6 +112,7 @@ class ConnectionImpl : public ConnectionImplBase, public TransportSocketCallback // fair sharing of CPU resources, the underlying event loop does not make any fairness guarantees. // Reconsider how to make fairness happen. void setReadBufferReady() override { file_event_->activate(Event::FileReadyType::Read); } + void flushWriteBuffer() override; // Obtain global next connection ID. This should only be used in tests. static uint64_t nextGlobalIdForTest() { return next_global_id_; } diff --git a/source/extensions/transport_sockets/alts/noop_transport_socket_callbacks.h b/source/extensions/transport_sockets/alts/noop_transport_socket_callbacks.h index 5c897ece01..d317b1db79 100644 --- a/source/extensions/transport_sockets/alts/noop_transport_socket_callbacks.h +++ b/source/extensions/transport_sockets/alts/noop_transport_socket_callbacks.h @@ -27,6 +27,7 @@ class NoOpTransportSocketCallbacks : public Network::TransportSocketCallbacks { */ void setReadBufferReady() override {} void raiseEvent(Network::ConnectionEvent) override {} + void flushWriteBuffer() override {} private: Network::TransportSocketCallbacks& parent_; diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index b13f057cc5..a068c30cf2 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -1789,6 +1789,30 @@ TEST_F(MockTransportConnectionImplTest, WriteReadyOnConnected) { .WillOnce(Return(IoResult{PostIoAction::KeepOpen, 0, true})); } +// Test the interface used by external consumers. +TEST_F(MockTransportConnectionImplTest, FlushWriteBuffer) { + InSequence s; + + // Queue up some data in write buffer. + const std::string val("some data"); + Buffer::OwnedImpl buffer(val); + EXPECT_CALL(*file_event_, activate(Event::FileReadyType::Write)).WillOnce(Invoke(file_ready_cb_)); + EXPECT_CALL(*transport_socket_, doWrite(BufferStringEqual(val), false)) + .WillOnce(Return(IoResult{PostIoAction::KeepOpen, 0, false})); + connection_->write(buffer, false); + + // A read event triggers underlying socket to ask for more data. + EXPECT_CALL(*transport_socket_, doRead(_)).WillOnce(InvokeWithoutArgs([this] { + transport_socket_callbacks_->flushWriteBuffer(); + return IoResult{PostIoAction::KeepOpen, 0, false}; + })); + EXPECT_CALL(*transport_socket_, doWrite(BufferStringEqual(val), false)) + .WillOnce(Return(IoResult{PostIoAction::KeepOpen, 0, false})); + file_ready_cb_(Event::FileReadyType::Read); + EXPECT_CALL(*transport_socket_, doWrite(_, true)) + .WillOnce(Return(IoResult{PostIoAction::KeepOpen, 0, true})); +} + // Fixture for validating behavior after a connection is closed. class PostCloseConnectionImplTest : public MockTransportConnectionImplTest { protected: diff --git a/test/extensions/transport_sockets/alts/noop_transport_socket_callbacks_test.cc b/test/extensions/transport_sockets/alts/noop_transport_socket_callbacks_test.cc index 507448d70d..fe5c5971da 100644 --- a/test/extensions/transport_sockets/alts/noop_transport_socket_callbacks_test.cc +++ b/test/extensions/transport_sockets/alts/noop_transport_socket_callbacks_test.cc @@ -26,13 +26,16 @@ class TestTransportSocketCallbacks : public Network::TransportSocketCallbacks { bool shouldDrainReadBuffer() override { return false; } void setReadBufferReady() override { set_read_buffer_ready_ = true; } void raiseEvent(Network::ConnectionEvent) override { event_raised_ = true; } + void flushWriteBuffer() override { write_buffer_flushed_ = true; } bool event_raised() const { return event_raised_; } bool set_read_buffer_ready() const { return set_read_buffer_ready_; } + bool write_buffer_flushed() const { return write_buffer_flushed_; } private: bool event_raised_{false}; bool set_read_buffer_ready_{false}; + bool write_buffer_flushed_{false}; Network::IoHandlePtr io_handle_; Network::Connection& connection_; }; @@ -56,6 +59,8 @@ TEST_F(NoOpTransportSocketCallbacksTest, TestAllCallbacks) { EXPECT_FALSE(wrapper_callbacks_.set_read_buffer_ready()); wrapped_callbacks_.raiseEvent(Network::ConnectionEvent::Connected); EXPECT_FALSE(wrapper_callbacks_.event_raised()); + wrapped_callbacks_.flushWriteBuffer(); + EXPECT_FALSE(wrapper_callbacks_.write_buffer_flushed()); } } // namespace diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index d63cedfad6..897434dbc6 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -404,6 +404,7 @@ class MockTransportSocketCallbacks : public TransportSocketCallbacks { MOCK_METHOD(bool, shouldDrainReadBuffer, ()); MOCK_METHOD(void, setReadBufferReady, ()); MOCK_METHOD(void, raiseEvent, (ConnectionEvent)); + MOCK_METHOD(void, flushWriteBuffer, ()); testing::NiceMock connection_; }; From efd5d299265fa561b00271a1ce6ef3abf1bed239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Guti=C3=A9rrez=20Segal=C3=A9s?= Date: Fri, 7 Feb 2020 18:19:28 -0500 Subject: [PATCH 27/87] thrift_proxy: add stats docs for the router filter (#9969) Signed-off-by: Raul Gutierrez Segales --- .../thrift_filters/router_filter.rst | 14 ++++++++++++++ docs/root/intro/version_history.rst | 1 + 2 files changed, 15 insertions(+) diff --git a/docs/root/configuration/other_protocols/thrift_filters/router_filter.rst b/docs/root/configuration/other_protocols/thrift_filters/router_filter.rst index 4bafe36a85..c9ced73dd5 100644 --- a/docs/root/configuration/other_protocols/thrift_filters/router_filter.rst +++ b/docs/root/configuration/other_protocols/thrift_filters/router_filter.rst @@ -9,3 +9,17 @@ scenarios. The filter's main job is to follow the instructions specified in the * :ref:`v2 API reference ` * This filter should be configured with the name *envoy.filters.thrift.router*. + +Statistics +---------- + +The filter outputs statistics in the *thrift..* namespace. + +.. csv-table:: + :header: Name, Type, Description + :widths: 1, 1, 2 + + route_missing, Counter, Total requests with no route found. + unknown_cluster, Counter, Total requests with a route that has an unknown cluster. + upstream_rq_maintenance_mode, Counter, Total requests with a destination cluster in maintenance mode. + no_healthy_upstream, Counter, Total requests with no healthy upstream endpoints available. diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index 2db820f293..83b6e91b16 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -13,6 +13,7 @@ Version history * router: added the ability to match a route based on whether a downstream TLS connection certificate has been :ref:`validated `. * sds: added :ref:`GenericSecret ` to support secret of generic type. +* thrift_proxy: add router filter stats to docs. * tracing: added gRPC service configuration to the OpenCensus Stackdriver tracer. * upstream: combined HTTP/1 and HTTP/2 connection pool code. This means that circuit breaker limits for both requests and connections apply to both pool types. Also, HTTP/2 now has From 210915157ebf74817ff7437a2d6aeed4021c84b2 Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Fri, 7 Feb 2020 15:20:24 -0800 Subject: [PATCH 28/87] router: allow overridding SAN from host/authority (#9863) Signed-off-by: Lizan Zhou --- api/envoy/api/v2/core/protocol.proto | 6 ++ api/envoy/config/core/v3/protocol.proto | 6 ++ docs/root/faq/configuration/sni.rst | 15 ++++- docs/root/intro/version_history.rst | 1 + .../envoy/api/v2/core/protocol.proto | 6 ++ .../envoy/config/core/v3/protocol.proto | 6 ++ source/common/network/BUILD | 11 ++++ .../network/transport_socket_options_impl.cc | 12 +++- .../network/upstream_subject_alt_names.cc | 12 ++++ .../network/upstream_subject_alt_names.h | 24 ++++++++ source/common/router/router.cc | 17 ++++-- .../clusters/dynamic_forward_proxy/cluster.cc | 24 +++++--- test/common/router/router_test.cc | 27 +++++++- .../dynamic_forward_proxy/cluster_test.cc | 61 +++++++++++++++++-- 14 files changed, 205 insertions(+), 23 deletions(-) create mode 100644 source/common/network/upstream_subject_alt_names.cc create mode 100644 source/common/network/upstream_subject_alt_names.h diff --git a/api/envoy/api/v2/core/protocol.proto b/api/envoy/api/v2/core/protocol.proto index 322add56ed..53b6ae8746 100644 --- a/api/envoy/api/v2/core/protocol.proto +++ b/api/envoy/api/v2/core/protocol.proto @@ -24,6 +24,12 @@ message UpstreamHttpProtocolOptions { // upstream connections based on the downstream HTTP host/authority header, as seen by the // :ref:`router filter `. bool auto_sni = 1; + + // Automatic validate upstream presented certificate for new upstream connections based on the + // downstream HTTP host/authority header, as seen by the + // :ref:`router filter `. + // This field is intended to set with `auto_sni` field. + bool auto_san_validation = 2; } message HttpProtocolOptions { diff --git a/api/envoy/config/core/v3/protocol.proto b/api/envoy/config/core/v3/protocol.proto index 77e7359fca..b3263a1fdd 100644 --- a/api/envoy/config/core/v3/protocol.proto +++ b/api/envoy/config/core/v3/protocol.proto @@ -29,6 +29,12 @@ message UpstreamHttpProtocolOptions { // upstream connections based on the downstream HTTP host/authority header, as seen by the // :ref:`router filter `. bool auto_sni = 1; + + // Automatic validate upstream presented certificate for new upstream connections based on the + // downstream HTTP host/authority header, as seen by the + // :ref:`router filter `. + // This field is intended to set with `auto_sni` field. + bool auto_san_validation = 2; } message HttpProtocolOptions { diff --git a/docs/root/faq/configuration/sni.rst b/docs/root/faq/configuration/sni.rst index 2498f5d997..0eb1b5027e 100644 --- a/docs/root/faq/configuration/sni.rst +++ b/docs/root/faq/configuration/sni.rst @@ -1,7 +1,7 @@ .. _faq_how_to_setup_sni: -How do I configure SNI? -======================= +How do I configure SNI for listeners? +===================================== `SNI `_ is only supported in the :ref:`v2 configuration/API `. @@ -65,3 +65,14 @@ The following is a YAML example of the above requirement. routes: - match: { prefix: "/" } route: { cluster: service_foo } + + +How do I configure SNI for clusters? +==================================== + +For clusters, a fixed SNI can be set in `UpstreamTlsContext `_. +To derive SNI from HTTP `host` or `:authority` header, turn on +`auto_sni `_ to override the fixed SNI in +`UpstreamTlsContext`. If upstream will present certificates with the hostname in SAN, turn on +`auto_san_validation `_ too. +It still needs a trust CA in validation context in `UpstreamTlsContext` for trust anchor. diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index 83b6e91b16..39b6a2b4f7 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -10,6 +10,7 @@ Version history * config: use type URL to select an extension whenever the config type URL (or its previous versions) uniquely identify a typed extension, see :ref:`extension configuration `. * http: fixing a bug in HTTP/1.0 responses where Connection: keep-alive was not appended for connections which were kept alive. * retry: added a retry predicate that :ref:`rejects hosts based on metadata. ` +* router: added :ref:`auto_san_validation ` to support overrriding SAN validation to transport socket for new upstream connections based on the downstream HTTP host/authority header. * router: added the ability to match a route based on whether a downstream TLS connection certificate has been :ref:`validated `. * sds: added :ref:`GenericSecret ` to support secret of generic type. diff --git a/generated_api_shadow/envoy/api/v2/core/protocol.proto b/generated_api_shadow/envoy/api/v2/core/protocol.proto index 322add56ed..53b6ae8746 100644 --- a/generated_api_shadow/envoy/api/v2/core/protocol.proto +++ b/generated_api_shadow/envoy/api/v2/core/protocol.proto @@ -24,6 +24,12 @@ message UpstreamHttpProtocolOptions { // upstream connections based on the downstream HTTP host/authority header, as seen by the // :ref:`router filter `. bool auto_sni = 1; + + // Automatic validate upstream presented certificate for new upstream connections based on the + // downstream HTTP host/authority header, as seen by the + // :ref:`router filter `. + // This field is intended to set with `auto_sni` field. + bool auto_san_validation = 2; } message HttpProtocolOptions { diff --git a/generated_api_shadow/envoy/config/core/v3/protocol.proto b/generated_api_shadow/envoy/config/core/v3/protocol.proto index 77e7359fca..b3263a1fdd 100644 --- a/generated_api_shadow/envoy/config/core/v3/protocol.proto +++ b/generated_api_shadow/envoy/config/core/v3/protocol.proto @@ -29,6 +29,12 @@ message UpstreamHttpProtocolOptions { // upstream connections based on the downstream HTTP host/authority header, as seen by the // :ref:`router filter `. bool auto_sni = 1; + + // Automatic validate upstream presented certificate for new upstream connections based on the + // downstream HTTP host/authority header, as seen by the + // :ref:`router filter `. + // This field is intended to set with `auto_sni` field. + bool auto_san_validation = 2; } message HttpProtocolOptions { diff --git a/source/common/network/BUILD b/source/common/network/BUILD index bf78cc5ed2..e8e7e9c6b6 100644 --- a/source/common/network/BUILD +++ b/source/common/network/BUILD @@ -316,6 +316,7 @@ envoy_cc_library( deps = [ ":application_protocol_lib", ":upstream_server_name_lib", + ":upstream_subject_alt_names_lib", "//include/envoy/network:transport_socket_interface", "//include/envoy/stream_info:filter_state_interface", "//source/common/common:scalar_to_byte_vector_lib", @@ -332,3 +333,13 @@ envoy_cc_library( "//source/common/common:macros", ], ) + +envoy_cc_library( + name = "upstream_subject_alt_names_lib", + srcs = ["upstream_subject_alt_names.cc"], + hdrs = ["upstream_subject_alt_names.h"], + deps = [ + "//include/envoy/stream_info:filter_state_interface", + "//source/common/common:macros", + ], +) diff --git a/source/common/network/transport_socket_options_impl.cc b/source/common/network/transport_socket_options_impl.cc index f9419f016b..4e88d9812e 100644 --- a/source/common/network/transport_socket_options_impl.cc +++ b/source/common/network/transport_socket_options_impl.cc @@ -9,6 +9,7 @@ #include "common/common/utility.h" #include "common/network/application_protocol.h" #include "common/network/upstream_server_name.h" +#include "common/network/upstream_subject_alt_names.h" namespace Envoy { namespace Network { @@ -34,6 +35,8 @@ TransportSocketOptionsSharedPtr TransportSocketOptionsUtility::fromFilterState(const StreamInfo::FilterState& filter_state) { absl::string_view server_name; std::vector application_protocols; + std::vector subject_alt_names; + bool needs_transport_socket_options = false; if (filter_state.hasData(UpstreamServerName::key())) { const auto& upstream_server_name = @@ -49,9 +52,16 @@ TransportSocketOptionsUtility::fromFilterState(const StreamInfo::FilterState& fi needs_transport_socket_options = true; } + if (filter_state.hasData(UpstreamSubjectAltNames::key())) { + const auto& upstream_subject_alt_names = + filter_state.getDataReadOnly(UpstreamSubjectAltNames::key()); + subject_alt_names = upstream_subject_alt_names.value(); + needs_transport_socket_options = true; + } + if (needs_transport_socket_options) { return std::make_shared( - server_name, std::vector{}, std::move(application_protocols)); + server_name, std::move(subject_alt_names), std::move(application_protocols)); } else { return nullptr; } diff --git a/source/common/network/upstream_subject_alt_names.cc b/source/common/network/upstream_subject_alt_names.cc new file mode 100644 index 0000000000..341f47e454 --- /dev/null +++ b/source/common/network/upstream_subject_alt_names.cc @@ -0,0 +1,12 @@ +#include "common/network/upstream_subject_alt_names.h" + +#include "common/common/macros.h" + +namespace Envoy { +namespace Network { + +const std::string& UpstreamSubjectAltNames::key() { + CONSTRUCT_ON_FIRST_USE(std::string, "envoy.network.upstream_subject_alt_names"); +} +} // namespace Network +} // namespace Envoy diff --git a/source/common/network/upstream_subject_alt_names.h b/source/common/network/upstream_subject_alt_names.h new file mode 100644 index 0000000000..a7ed779055 --- /dev/null +++ b/source/common/network/upstream_subject_alt_names.h @@ -0,0 +1,24 @@ +#pragma once + +#include "envoy/stream_info/filter_state.h" + +namespace Envoy { +namespace Network { + +/** + * SANs to validate certificate to set in the upstream connection. Filters can use this one to + * override the SAN in TLS context. + */ +class UpstreamSubjectAltNames : public StreamInfo::FilterState::Object { +public: + explicit UpstreamSubjectAltNames(const std::vector& upstream_subject_alt_names) + : upstream_subject_alt_names_(upstream_subject_alt_names) {} + const std::vector& value() const { return upstream_subject_alt_names_; } + static const std::string& key(); + +private: + const std::vector upstream_subject_alt_names_; +}; + +} // namespace Network +} // namespace Envoy diff --git a/source/common/router/router.cc b/source/common/router/router.cc index 5c54c8e290..f21f585043 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -28,6 +28,7 @@ #include "common/network/application_protocol.h" #include "common/network/transport_socket_options_impl.h" #include "common/network/upstream_server_name.h" +#include "common/network/upstream_subject_alt_names.h" #include "common/router/config_impl.h" #include "common/router/debug_config.h" #include "common/router/retry_state_impl.h" @@ -519,19 +520,23 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::HeaderMap& headers, bool e // Fetch a connection pool for the upstream cluster. const auto& upstream_http_protocol_options = cluster_->upstreamHttpProtocolOptions(); - if (upstream_http_protocol_options.has_value() && - upstream_http_protocol_options.value().auto_sni()) { + if (upstream_http_protocol_options.has_value()) { const auto parsed_authority = Http::Utility::parseAuthority(headers.Host()->value().getStringView()); - if (!parsed_authority.is_ip_address_) { - // TODO: Add SAN verification here and use it from dynamic_forward_proxy - // Update filter state with the host/authority to use for setting SNI in the transport - // socket options. This is referenced during the getConnPool() call below. + if (!parsed_authority.is_ip_address_ && upstream_http_protocol_options.value().auto_sni()) { callbacks_->streamInfo().filterState()->setData( Network::UpstreamServerName::key(), std::make_unique(parsed_authority.host_), StreamInfo::FilterState::StateType::Mutable); } + + if (upstream_http_protocol_options.value().auto_san_validation()) { + callbacks_->streamInfo().filterState()->setData( + Network::UpstreamSubjectAltNames::key(), + std::make_unique( + std::vector{std::string(parsed_authority.host_)}), + StreamInfo::FilterState::StateType::Mutable); + } } auto conn_pool = getConnPool(); diff --git a/source/extensions/clusters/dynamic_forward_proxy/cluster.cc b/source/extensions/clusters/dynamic_forward_proxy/cluster.cc index 5d68e16029..d928a7010c 100644 --- a/source/extensions/clusters/dynamic_forward_proxy/cluster.cc +++ b/source/extensions/clusters/dynamic_forward_proxy/cluster.cc @@ -100,13 +100,6 @@ void Cluster::addOrUpdateWorker( ENVOY_LOG(debug, "adding new dfproxy cluster host '{}'", host); - // Create an override transport socket options that automatically provides both SNI as well as - // SAN verification for the resolved host if the cluster has been configured with TLS. - Network::TransportSocketOptionsSharedPtr transport_socket_options = - std::make_shared( - !host_info->isIpAddress() ? host_info->resolvedHost() : "", - std::vector{host_info->resolvedHost()}); - if (new_host_map == nullptr) { new_host_map = std::make_shared(*current_map); } @@ -114,7 +107,7 @@ void Cluster::addOrUpdateWorker( new_host_map->try_emplace(host, host_info, std::make_shared( info(), host, host_info->address(), dummy_locality_lb_endpoint_, - dummy_lb_endpoint_, transport_socket_options)); + dummy_lb_endpoint_, nullptr)); if (hosts_added == nullptr) { hosts_added = std::make_unique(); } @@ -195,8 +188,21 @@ ClusterFactory::createClusterWithConfig( Stats::ScopePtr&& stats_scope) { Extensions::Common::DynamicForwardProxy::DnsCacheManagerFactoryImpl cache_manager_factory( context.singletonManager(), context.dispatcher(), context.tls(), context.stats()); + envoy::config::cluster::v3::Cluster cluster_config = cluster; + if (cluster_config.has_upstream_http_protocol_options()) { + if (!cluster_config.upstream_http_protocol_options().auto_sni() || + !cluster_config.upstream_http_protocol_options().auto_san_validation()) { + throw EnvoyException( + "dynamic_forward_proxy cluster must have auto_sni and auto_san_validation true when " + "configured with upstream_http_protocol_options"); + } + } else { + cluster_config.mutable_upstream_http_protocol_options()->set_auto_sni(true); + cluster_config.mutable_upstream_http_protocol_options()->set_auto_san_validation(true); + } + auto new_cluster = std::make_shared( - cluster, proto_config, context.runtime(), cache_manager_factory, context.localInfo(), + cluster_config, proto_config, context.runtime(), cache_manager_factory, context.localInfo(), socket_factory_context, std::move(stats_scope), context.addedViaApi()); auto lb = std::make_unique(*new_cluster); return std::make_pair(new_cluster, std::move(lb)); diff --git a/test/common/router/router_test.cc b/test/common/router/router_test.cc index 5dea1a9452..fc02dbe2e5 100644 --- a/test/common/router/router_test.cc +++ b/test/common/router/router_test.cc @@ -14,6 +14,7 @@ #include "common/network/application_protocol.h" #include "common/network/socket_option_factory.h" #include "common/network/upstream_server_name.h" +#include "common/network/upstream_subject_alt_names.h" #include "common/network/utility.h" #include "common/router/config_impl.h" #include "common/router/debug_config.h" @@ -296,7 +297,7 @@ class RouterTestSuppressEnvoyHeaders : public RouterTestBase { : RouterTestBase(false, true, Protobuf::RepeatedPtrField{}) {} }; -TEST_F(RouterTest, UpdateFilterState) { +TEST_F(RouterTest, UpdateServerNameFilterState) { NiceMock stream_info; auto dummy_option = absl::make_optional(); dummy_option.value().set_auto_sni(true); @@ -323,6 +324,30 @@ TEST_F(RouterTest, UpdateFilterState) { EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); } +TEST_F(RouterTest, UpdateSubjectAltNamesFilterState) { + NiceMock stream_info; + auto dummy_option = absl::make_optional(); + dummy_option.value().set_auto_san_validation(true); + ON_CALL(*cm_.thread_local_cluster_.cluster_.info_, upstreamHttpProtocolOptions()) + .WillByDefault(ReturnRef(dummy_option)); + ON_CALL(callbacks_.stream_info_, filterState()) + .WillByDefault(ReturnRef(stream_info.filterState())); + EXPECT_CALL(cm_.conn_pool_, newStream(_, _)).WillOnce(Return(&cancellable_)); + expectResponseTimerCreate(); + + Http::TestHeaderMapImpl headers; + + HttpTestUtility::addDefaultHeaders(headers); + router_.decodeHeaders(headers, true); + EXPECT_EQ("host", stream_info.filterState() + ->getDataReadOnly( + Network::UpstreamSubjectAltNames::key()) + .value()[0]); + EXPECT_CALL(cancellable_, cancel()); + router_.onDestroy(); + EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); +} + TEST_F(RouterTest, RouteNotFound) { EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::NoRouteFound)); diff --git a/test/extensions/clusters/dynamic_forward_proxy/cluster_test.cc b/test/extensions/clusters/dynamic_forward_proxy/cluster_test.cc index dc96d404c7..a492f4e710 100644 --- a/test/extensions/clusters/dynamic_forward_proxy/cluster_test.cc +++ b/test/extensions/clusters/dynamic_forward_proxy/cluster_test.cc @@ -3,6 +3,7 @@ #include "envoy/extensions/clusters/dynamic_forward_proxy/v3/cluster.pb.validate.h" #include "common/singleton/manager_impl.h" +#include "common/upstream/cluster_factory_impl.h" #include "extensions/clusters/dynamic_forward_proxy/cluster.h" @@ -196,8 +197,41 @@ TEST_F(ClusterTest, PopulatedCache) { EXPECT_EQ(2UL, cluster_->prioritySet().hostSetsPerPriority()[0]->hosts().size()); } +class ClusterFactoryTest : public testing::Test { +protected: + void createCluster(const std::string& yaml_config) { + envoy::config::cluster::v3::Cluster cluster_config = + Upstream::parseClusterFromV2Yaml(yaml_config); + Upstream::ClusterFactoryContextImpl cluster_factory_context( + cm_, stats_store_, tls_, nullptr, ssl_context_manager_, runtime_, random_, dispatcher_, + log_manager_, local_info_, admin_, singleton_manager_, nullptr, true, validation_visitor_, + *api_); + std::unique_ptr cluster_factory = std::make_unique(); + + std::tie(cluster_, thread_aware_lb_) = + cluster_factory->create(cluster_config, cluster_factory_context); + } + +private: + Stats::IsolatedStoreImpl stats_store_; + NiceMock ssl_context_manager_; + NiceMock cm_; + NiceMock random_; + NiceMock tls_; + NiceMock runtime_; + NiceMock dispatcher_; + NiceMock local_info_; + NiceMock log_manager_; + NiceMock admin_; + Singleton::ManagerImpl singleton_manager_{Thread::threadFactoryForTest()}; + NiceMock validation_visitor_; + Api::ApiPtr api_{Api::createApiForTest(stats_store_)}; + Upstream::ClusterSharedPtr cluster_; + Upstream::ThreadAwareLoadBalancerPtr thread_aware_lb_; +}; + // Verify that using 'sni' causes a failure. -TEST_F(ClusterTest, DEPRECATED_FEATURE_TEST(InvalidSNI)) { +TEST_F(ClusterFactoryTest, DEPRECATED_FEATURE_TEST(InvalidSNI)) { const std::string yaml_config = TestEnvironment::substitute(R"EOF( name: name connect_timeout: 0.25s @@ -216,12 +250,12 @@ connect_timeout: 0.25s )EOF"); EXPECT_THROW_WITH_MESSAGE( - initialize(yaml_config, true), EnvoyException, + createCluster(yaml_config), EnvoyException, "dynamic_forward_proxy cluster cannot configure 'sni' or 'verify_subject_alt_name'"); } // Verify that using 'verify_subject_alt_name' causes a failure. -TEST_F(ClusterTest, DEPRECATED_FEATURE_TEST(InvalidVerifySubjectAltName)) { +TEST_F(ClusterFactoryTest, DEPRECATED_FEATURE_TEST(InvalidVerifySubjectAltName)) { const std::string yaml_config = TestEnvironment::substitute(R"EOF( name: name connect_timeout: 0.25s @@ -240,10 +274,29 @@ connect_timeout: 0.25s )EOF"); EXPECT_THROW_WITH_MESSAGE( - initialize(yaml_config, true), EnvoyException, + createCluster(yaml_config), EnvoyException, "dynamic_forward_proxy cluster cannot configure 'sni' or 'verify_subject_alt_name'"); } +TEST_F(ClusterFactoryTest, InvalidUpstreamHttpProtocolOptions) { + const std::string yaml_config = TestEnvironment::substitute(R"EOF( +name: name +connect_timeout: 0.25s +cluster_type: + name: envoy.clusters.dynamic_forward_proxy + typed_config: + "@type": type.googleapis.com/envoy.config.cluster.dynamic_forward_proxy.v2alpha.ClusterConfig + dns_cache_config: + name: foo +upstream_http_protocol_options: {} +)EOF"); + + EXPECT_THROW_WITH_MESSAGE( + createCluster(yaml_config), EnvoyException, + "dynamic_forward_proxy cluster must have auto_sni and auto_san_validation true when " + "configured with upstream_http_protocol_options"); +} + } // namespace DynamicForwardProxy } // namespace Clusters } // namespace Extensions From 77678438d9499bdfd32f0cbe7d2042e72fde4319 Mon Sep 17 00:00:00 2001 From: toddmgreer Date: Fri, 7 Feb 2020 16:09:07 -0800 Subject: [PATCH 29/87] filter: Add CacheFilter config API (#9960) Signed-off-by: Todd Greer --- api/BUILD | 2 + api/docs/BUILD | 1 + .../config/filter/http/cache/v2alpha/BUILD | 13 +++ .../filter/http/cache/v2alpha/cache.proto | 77 +++++++++++++++++ .../filters/http/cache/v3alpha/BUILD | 14 ++++ .../filters/http/cache/v3alpha/cache.proto | 82 +++++++++++++++++++ .../http/http_filters/http_filters.rst | 6 ++ .../config/filter/http/cache/v2alpha/BUILD | 13 +++ .../filter/http/cache/v2alpha/cache.proto | 77 +++++++++++++++++ .../filters/http/cache/v3alpha/BUILD | 14 ++++ .../filters/http/cache/v3alpha/cache.proto | 82 +++++++++++++++++++ source/extensions/extensions_build_config.bzl | 1 + source/extensions/filters/http/cache/BUILD | 7 ++ 13 files changed, 389 insertions(+) create mode 100644 api/envoy/config/filter/http/cache/v2alpha/BUILD create mode 100644 api/envoy/config/filter/http/cache/v2alpha/cache.proto create mode 100644 api/envoy/extensions/filters/http/cache/v3alpha/BUILD create mode 100644 api/envoy/extensions/filters/http/cache/v3alpha/cache.proto create mode 100644 generated_api_shadow/envoy/config/filter/http/cache/v2alpha/BUILD create mode 100644 generated_api_shadow/envoy/config/filter/http/cache/v2alpha/cache.proto create mode 100644 generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/BUILD create mode 100644 generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/cache.proto diff --git a/api/BUILD b/api/BUILD index ce152527b5..17520935be 100644 --- a/api/BUILD +++ b/api/BUILD @@ -30,6 +30,7 @@ proto_library( "//envoy/config/filter/http/adaptive_concurrency/v2alpha:pkg", "//envoy/config/filter/http/aws_request_signing/v2alpha:pkg", "//envoy/config/filter/http/buffer/v2:pkg", + "//envoy/config/filter/http/cache/v2alpha:pkg", "//envoy/config/filter/http/cors/v2:pkg", "//envoy/config/filter/http/csrf/v2:pkg", "//envoy/config/filter/http/dynamic_forward_proxy/v2alpha:pkg", @@ -159,6 +160,7 @@ proto_library( "//envoy/extensions/filters/http/adaptive_concurrency/v3:pkg", "//envoy/extensions/filters/http/aws_request_signing/v3:pkg", "//envoy/extensions/filters/http/buffer/v3:pkg", + "//envoy/extensions/filters/http/cache/v3alpha:pkg", "//envoy/extensions/filters/http/cors/v3:pkg", "//envoy/extensions/filters/http/csrf/v3:pkg", "//envoy/extensions/filters/http/dynamic_forward_proxy/v3:pkg", diff --git a/api/docs/BUILD b/api/docs/BUILD index e281752886..da6e0524aa 100644 --- a/api/docs/BUILD +++ b/api/docs/BUILD @@ -36,6 +36,7 @@ proto_library( "//envoy/config/filter/http/adaptive_concurrency/v2alpha:pkg", "//envoy/config/filter/http/aws_request_signing/v2alpha:pkg", "//envoy/config/filter/http/buffer/v2:pkg", + "//envoy/config/filter/http/cache/v2alpha:pkg", "//envoy/config/filter/http/cors/v2:pkg", "//envoy/config/filter/http/csrf/v2:pkg", "//envoy/config/filter/http/dynamic_forward_proxy/v2alpha:pkg", diff --git a/api/envoy/config/filter/http/cache/v2alpha/BUILD b/api/envoy/config/filter/http/cache/v2alpha/BUILD new file mode 100644 index 0000000000..87746bf482 --- /dev/null +++ b/api/envoy/config/filter/http/cache/v2alpha/BUILD @@ -0,0 +1,13 @@ +# DO NOT EDIT. This file is generated by tools/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/api/v2/route:pkg", + "//envoy/type/matcher:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/api/envoy/config/filter/http/cache/v2alpha/cache.proto b/api/envoy/config/filter/http/cache/v2alpha/cache.proto new file mode 100644 index 0000000000..6d1cf5d2a7 --- /dev/null +++ b/api/envoy/config/filter/http/cache/v2alpha/cache.proto @@ -0,0 +1,77 @@ +syntax = "proto3"; + +package envoy.config.filter.http.cache.v2alpha; + +import "envoy/api/v2/route/route_components.proto"; +import "envoy/type/matcher/string.proto"; + +import "google/protobuf/any.proto"; + +import "udpa/annotations/migrate.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.config.filter.http.cache.v2alpha"; +option java_outer_classname = "CacheProto"; +option java_multiple_files = true; +option (udpa.annotations.file_migrate).move_to_package = + "envoy.extensions.filters.http.cache.v3alpha"; + +// [#protodoc-title: HTTP Cache Filter] +// [#extension: envoy.filters.http.cache] + +message CacheConfig { + // [#not-implemented-hide:] + // Modifies cache key creation by restricting which parts of the URL are included. + message KeyCreatorParams { + // If true, exclude the URL scheme from the cache key. Set to true if your origins always + // produce the same response for http and https requests. + bool exclude_scheme = 1; + + // If true, exclude the host from the cache key. Set to true if your origins' responses don't + // ever depend on host. + bool exclude_host = 2; + + // If *query_parameters_included* is nonempty, only query parameters matched + // by one or more of its matchers are included in the cache key. Any other + // query params will not affect cache lookup. + repeated api.v2.route.QueryParameterMatcher query_parameters_included = 3; + + // If *query_parameters_excluded* is nonempty, query parameters matched by one + // or more of its matchers are excluded from the cache key (even if also + // matched by *query_parameters_included*), and will not affect cache lookup. + repeated api.v2.route.QueryParameterMatcher query_parameters_excluded = 4; + } + + // Config specific to the cache storage implementation. + google.protobuf.Any typed_config = 1 [(validate.rules).any = {required: true}]; + + // [#not-implemented-hide:] + // + // + // List of allowed *Vary* headers. + // + // The *vary* response header holds a list of header names that affect the + // contents of a response, as described by + // https://httpwg.org/specs/rfc7234.html#caching.negotiated.responses. + // + // During insertion, *allowed_vary_headers* acts as a whitelist: if a + // response's *vary* header mentions any header names that aren't in + // *allowed_vary_headers*, that response will not be cached. + // + // During lookup, *allowed_vary_headers* controls what request headers will be + // sent to the cache storage implementation. + repeated type.matcher.StringMatcher allowed_vary_headers = 2; + + // [#not-implemented-hide:] + // + // + // Modifies cache key creation by restricting which parts of the URL are included. + KeyCreatorParams key_creator_params = 3; + + // [#not-implemented-hide:] + // + // + // Max body size the cache filter will insert into a cache. 0 means unlimited (though the cache + // storage implementation may have its own limit beyond which it will reject insertions). + uint32 max_body_bytes = 4; +} diff --git a/api/envoy/extensions/filters/http/cache/v3alpha/BUILD b/api/envoy/extensions/filters/http/cache/v3alpha/BUILD new file mode 100644 index 0000000000..3296466ffb --- /dev/null +++ b/api/envoy/extensions/filters/http/cache/v3alpha/BUILD @@ -0,0 +1,14 @@ +# DO NOT EDIT. This file is generated by tools/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/config/filter/http/cache/v2alpha:pkg", + "//envoy/config/route/v3:pkg", + "//envoy/type/matcher/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/api/envoy/extensions/filters/http/cache/v3alpha/cache.proto b/api/envoy/extensions/filters/http/cache/v3alpha/cache.proto new file mode 100644 index 0000000000..ad74fe7e0e --- /dev/null +++ b/api/envoy/extensions/filters/http/cache/v3alpha/cache.proto @@ -0,0 +1,82 @@ +syntax = "proto3"; + +package envoy.extensions.filters.http.cache.v3alpha; + +import "envoy/config/route/v3/route_components.proto"; +import "envoy/type/matcher/v3/string.proto"; + +import "google/protobuf/any.proto"; + +import "udpa/annotations/versioning.proto"; + +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.http.cache.v3alpha"; +option java_outer_classname = "CacheProto"; +option java_multiple_files = true; + +// [#protodoc-title: HTTP Cache Filter] +// [#extension: envoy.filters.http.cache] + +message CacheConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.config.filter.http.cache.v2alpha.CacheConfig"; + + // [#not-implemented-hide:] + // Modifies cache key creation by restricting which parts of the URL are included. + message KeyCreatorParams { + option (udpa.annotations.versioning).previous_message_type = + "envoy.config.filter.http.cache.v2alpha.CacheConfig.KeyCreatorParams"; + + // If true, exclude the URL scheme from the cache key. Set to true if your origins always + // produce the same response for http and https requests. + bool exclude_scheme = 1; + + // If true, exclude the host from the cache key. Set to true if your origins' responses don't + // ever depend on host. + bool exclude_host = 2; + + // If *query_parameters_included* is nonempty, only query parameters matched + // by one or more of its matchers are included in the cache key. Any other + // query params will not affect cache lookup. + repeated config.route.v3.QueryParameterMatcher query_parameters_included = 3; + + // If *query_parameters_excluded* is nonempty, query parameters matched by one + // or more of its matchers are excluded from the cache key (even if also + // matched by *query_parameters_included*), and will not affect cache lookup. + repeated config.route.v3.QueryParameterMatcher query_parameters_excluded = 4; + } + + // Config specific to the cache storage implementation. + google.protobuf.Any typed_config = 1 [(validate.rules).any = {required: true}]; + + // [#not-implemented-hide:] + // + // + // List of allowed *Vary* headers. + // + // The *vary* response header holds a list of header names that affect the + // contents of a response, as described by + // https://httpwg.org/specs/rfc7234.html#caching.negotiated.responses. + // + // During insertion, *allowed_vary_headers* acts as a whitelist: if a + // response's *vary* header mentions any header names that aren't in + // *allowed_vary_headers*, that response will not be cached. + // + // During lookup, *allowed_vary_headers* controls what request headers will be + // sent to the cache storage implementation. + repeated type.matcher.v3.StringMatcher allowed_vary_headers = 2; + + // [#not-implemented-hide:] + // + // + // Modifies cache key creation by restricting which parts of the URL are included. + KeyCreatorParams key_creator_params = 3; + + // [#not-implemented-hide:] + // + // + // Max body size the cache filter will insert into a cache. 0 means unlimited (though the cache + // storage implementation may have its own limit beyond which it will reject insertions). + uint32 max_body_bytes = 4; +} diff --git a/docs/root/configuration/http/http_filters/http_filters.rst b/docs/root/configuration/http/http_filters/http_filters.rst index e5614e643c..f70580ee4e 100644 --- a/docs/root/configuration/http/http_filters/http_filters.rst +++ b/docs/root/configuration/http/http_filters/http_filters.rst @@ -33,3 +33,9 @@ HTTP filters router_filter squash_filter tap_filter + +.. TODO(toddmgreer): Remove this hack and add user-visible CacheFilter docs when CacheFilter is production-ready. +.. toctree:: + :hidden: + + ../../../api-v3/extensions/filters/http/cache/v3alpha/cache.proto diff --git a/generated_api_shadow/envoy/config/filter/http/cache/v2alpha/BUILD b/generated_api_shadow/envoy/config/filter/http/cache/v2alpha/BUILD new file mode 100644 index 0000000000..87746bf482 --- /dev/null +++ b/generated_api_shadow/envoy/config/filter/http/cache/v2alpha/BUILD @@ -0,0 +1,13 @@ +# DO NOT EDIT. This file is generated by tools/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/api/v2/route:pkg", + "//envoy/type/matcher:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/generated_api_shadow/envoy/config/filter/http/cache/v2alpha/cache.proto b/generated_api_shadow/envoy/config/filter/http/cache/v2alpha/cache.proto new file mode 100644 index 0000000000..6d1cf5d2a7 --- /dev/null +++ b/generated_api_shadow/envoy/config/filter/http/cache/v2alpha/cache.proto @@ -0,0 +1,77 @@ +syntax = "proto3"; + +package envoy.config.filter.http.cache.v2alpha; + +import "envoy/api/v2/route/route_components.proto"; +import "envoy/type/matcher/string.proto"; + +import "google/protobuf/any.proto"; + +import "udpa/annotations/migrate.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.config.filter.http.cache.v2alpha"; +option java_outer_classname = "CacheProto"; +option java_multiple_files = true; +option (udpa.annotations.file_migrate).move_to_package = + "envoy.extensions.filters.http.cache.v3alpha"; + +// [#protodoc-title: HTTP Cache Filter] +// [#extension: envoy.filters.http.cache] + +message CacheConfig { + // [#not-implemented-hide:] + // Modifies cache key creation by restricting which parts of the URL are included. + message KeyCreatorParams { + // If true, exclude the URL scheme from the cache key. Set to true if your origins always + // produce the same response for http and https requests. + bool exclude_scheme = 1; + + // If true, exclude the host from the cache key. Set to true if your origins' responses don't + // ever depend on host. + bool exclude_host = 2; + + // If *query_parameters_included* is nonempty, only query parameters matched + // by one or more of its matchers are included in the cache key. Any other + // query params will not affect cache lookup. + repeated api.v2.route.QueryParameterMatcher query_parameters_included = 3; + + // If *query_parameters_excluded* is nonempty, query parameters matched by one + // or more of its matchers are excluded from the cache key (even if also + // matched by *query_parameters_included*), and will not affect cache lookup. + repeated api.v2.route.QueryParameterMatcher query_parameters_excluded = 4; + } + + // Config specific to the cache storage implementation. + google.protobuf.Any typed_config = 1 [(validate.rules).any = {required: true}]; + + // [#not-implemented-hide:] + // + // + // List of allowed *Vary* headers. + // + // The *vary* response header holds a list of header names that affect the + // contents of a response, as described by + // https://httpwg.org/specs/rfc7234.html#caching.negotiated.responses. + // + // During insertion, *allowed_vary_headers* acts as a whitelist: if a + // response's *vary* header mentions any header names that aren't in + // *allowed_vary_headers*, that response will not be cached. + // + // During lookup, *allowed_vary_headers* controls what request headers will be + // sent to the cache storage implementation. + repeated type.matcher.StringMatcher allowed_vary_headers = 2; + + // [#not-implemented-hide:] + // + // + // Modifies cache key creation by restricting which parts of the URL are included. + KeyCreatorParams key_creator_params = 3; + + // [#not-implemented-hide:] + // + // + // Max body size the cache filter will insert into a cache. 0 means unlimited (though the cache + // storage implementation may have its own limit beyond which it will reject insertions). + uint32 max_body_bytes = 4; +} diff --git a/generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/BUILD b/generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/BUILD new file mode 100644 index 0000000000..3296466ffb --- /dev/null +++ b/generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/BUILD @@ -0,0 +1,14 @@ +# DO NOT EDIT. This file is generated by tools/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/config/filter/http/cache/v2alpha:pkg", + "//envoy/config/route/v3:pkg", + "//envoy/type/matcher/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + ], +) diff --git a/generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/cache.proto b/generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/cache.proto new file mode 100644 index 0000000000..ad74fe7e0e --- /dev/null +++ b/generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/cache.proto @@ -0,0 +1,82 @@ +syntax = "proto3"; + +package envoy.extensions.filters.http.cache.v3alpha; + +import "envoy/config/route/v3/route_components.proto"; +import "envoy/type/matcher/v3/string.proto"; + +import "google/protobuf/any.proto"; + +import "udpa/annotations/versioning.proto"; + +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.http.cache.v3alpha"; +option java_outer_classname = "CacheProto"; +option java_multiple_files = true; + +// [#protodoc-title: HTTP Cache Filter] +// [#extension: envoy.filters.http.cache] + +message CacheConfig { + option (udpa.annotations.versioning).previous_message_type = + "envoy.config.filter.http.cache.v2alpha.CacheConfig"; + + // [#not-implemented-hide:] + // Modifies cache key creation by restricting which parts of the URL are included. + message KeyCreatorParams { + option (udpa.annotations.versioning).previous_message_type = + "envoy.config.filter.http.cache.v2alpha.CacheConfig.KeyCreatorParams"; + + // If true, exclude the URL scheme from the cache key. Set to true if your origins always + // produce the same response for http and https requests. + bool exclude_scheme = 1; + + // If true, exclude the host from the cache key. Set to true if your origins' responses don't + // ever depend on host. + bool exclude_host = 2; + + // If *query_parameters_included* is nonempty, only query parameters matched + // by one or more of its matchers are included in the cache key. Any other + // query params will not affect cache lookup. + repeated config.route.v3.QueryParameterMatcher query_parameters_included = 3; + + // If *query_parameters_excluded* is nonempty, query parameters matched by one + // or more of its matchers are excluded from the cache key (even if also + // matched by *query_parameters_included*), and will not affect cache lookup. + repeated config.route.v3.QueryParameterMatcher query_parameters_excluded = 4; + } + + // Config specific to the cache storage implementation. + google.protobuf.Any typed_config = 1 [(validate.rules).any = {required: true}]; + + // [#not-implemented-hide:] + // + // + // List of allowed *Vary* headers. + // + // The *vary* response header holds a list of header names that affect the + // contents of a response, as described by + // https://httpwg.org/specs/rfc7234.html#caching.negotiated.responses. + // + // During insertion, *allowed_vary_headers* acts as a whitelist: if a + // response's *vary* header mentions any header names that aren't in + // *allowed_vary_headers*, that response will not be cached. + // + // During lookup, *allowed_vary_headers* controls what request headers will be + // sent to the cache storage implementation. + repeated type.matcher.v3.StringMatcher allowed_vary_headers = 2; + + // [#not-implemented-hide:] + // + // + // Modifies cache key creation by restricting which parts of the URL are included. + KeyCreatorParams key_creator_params = 3; + + // [#not-implemented-hide:] + // + // + // Max body size the cache filter will insert into a cache. 0 means unlimited (though the cache + // storage implementation may have its own limit beyond which it will reject insertions). + uint32 max_body_bytes = 4; +} diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index 8d63b0b237..1dddce3adb 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -36,6 +36,7 @@ EXTENSIONS = { "envoy.filters.http.adaptive_concurrency": "//source/extensions/filters/http/adaptive_concurrency:config", "envoy.filters.http.aws_request_signing": "//source/extensions/filters/http/aws_request_signing:config", "envoy.filters.http.buffer": "//source/extensions/filters/http/buffer:config", + "envoy.filters.http.cache": "//source/extensions/filters/http/cache:config", "envoy.filters.http.cors": "//source/extensions/filters/http/cors:config", "envoy.filters.http.csrf": "//source/extensions/filters/http/csrf:config", "envoy.filters.http.dynamic_forward_proxy": "//source/extensions/filters/http/dynamic_forward_proxy:config", diff --git a/source/extensions/filters/http/cache/BUILD b/source/extensions/filters/http/cache/BUILD index 327fc73eb0..52d3661f44 100644 --- a/source/extensions/filters/http/cache/BUILD +++ b/source/extensions/filters/http/cache/BUILD @@ -4,6 +4,7 @@ licenses(["notice"]) # Apache 2 load( "//bazel:envoy_build_system.bzl", + "envoy_cc_extension", "envoy_cc_library", "envoy_package", ) @@ -19,3 +20,9 @@ envoy_cc_library( "//include/envoy/http:header_map_interface", ], ) + +envoy_cc_extension( + name = "config", + security_posture = "robust_to_untrusted_downstream_and_upstream", + status = "wip", +) From 858b527474a60d8e58ddbbdbae5e91bdf261415e Mon Sep 17 00:00:00 2001 From: Gary Brown Date: Sat, 8 Feb 2020 00:43:35 +0000 Subject: [PATCH 30/87] =?UTF-8?q?tracing:=20Add=20decorator=20propagate=20?= =?UTF-8?q?field=20to=20enable=20passing=20the=20operatio=E2=80=A6=20(#988?= =?UTF-8?q?2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gary Brown --- api/envoy/api/v2/route/route_components.proto | 3 + .../config/route/v3/route_components.proto | 3 + .../envoy/api/v2/route/route_components.proto | 3 + .../config/route/v3/route_components.proto | 3 + include/envoy/router/router.h | 7 + source/common/http/conn_manager_impl.cc | 81 ++++----- source/common/http/conn_manager_impl.h | 33 ++-- source/common/router/config_impl.cc | 5 +- source/common/router/config_impl.h | 4 + test/common/http/conn_manager_impl_test.cc | 157 +++++++++++++++++- test/common/router/config_impl_test.cc | 2 + test/mocks/router/mocks.cc | 1 + test/mocks/router/mocks.h | 1 + 13 files changed, 247 insertions(+), 56 deletions(-) diff --git a/api/envoy/api/v2/route/route_components.proto b/api/envoy/api/v2/route/route_components.proto index 14b4dffc3a..f5e6bae79a 100644 --- a/api/envoy/api/v2/route/route_components.proto +++ b/api/envoy/api/v2/route/route_components.proto @@ -1124,6 +1124,9 @@ message Decorator { // by the :ref:`x-envoy-decorator-operation // ` header. string operation = 1 [(validate.rules).string = {min_bytes: 1}]; + + // Whether the decorated details should be propagated to the other party. The default is true. + google.protobuf.BoolValue propagate = 2; } message Tracing { diff --git a/api/envoy/config/route/v3/route_components.proto b/api/envoy/config/route/v3/route_components.proto index 2ac0c34af4..2fde356ea6 100644 --- a/api/envoy/config/route/v3/route_components.proto +++ b/api/envoy/config/route/v3/route_components.proto @@ -1113,6 +1113,9 @@ message Decorator { // by the :ref:`x-envoy-decorator-operation // ` header. string operation = 1 [(validate.rules).string = {min_bytes: 1}]; + + // Whether the decorated details should be propagated to the other party. The default is true. + google.protobuf.BoolValue propagate = 2; } message Tracing { diff --git a/generated_api_shadow/envoy/api/v2/route/route_components.proto b/generated_api_shadow/envoy/api/v2/route/route_components.proto index 14b4dffc3a..f5e6bae79a 100644 --- a/generated_api_shadow/envoy/api/v2/route/route_components.proto +++ b/generated_api_shadow/envoy/api/v2/route/route_components.proto @@ -1124,6 +1124,9 @@ message Decorator { // by the :ref:`x-envoy-decorator-operation // ` header. string operation = 1 [(validate.rules).string = {min_bytes: 1}]; + + // Whether the decorated details should be propagated to the other party. The default is true. + google.protobuf.BoolValue propagate = 2; } message Tracing { diff --git a/generated_api_shadow/envoy/config/route/v3/route_components.proto b/generated_api_shadow/envoy/config/route/v3/route_components.proto index 45c2727f30..68a4c600ae 100644 --- a/generated_api_shadow/envoy/config/route/v3/route_components.proto +++ b/generated_api_shadow/envoy/config/route/v3/route_components.proto @@ -1190,6 +1190,9 @@ message Decorator { // by the :ref:`x-envoy-decorator-operation // ` header. string operation = 1 [(validate.rules).string = {min_bytes: 1}]; + + // Whether the decorated details should be propagated to the other party. The default is true. + google.protobuf.BoolValue propagate = 2; } message Tracing { diff --git a/include/envoy/router/router.h b/include/envoy/router/router.h index d7a2a4db18..0822eb12d8 100644 --- a/include/envoy/router/router.h +++ b/include/envoy/router/router.h @@ -816,6 +816,13 @@ class Decorator { * @return the operation name */ virtual const std::string& getOperation() const PURE; + + /** + * This method returns whether the decorator information + * should be propagated to other services. + * @return whether to propagate + */ + virtual bool propagate() const PURE; }; using DecoratorConstPtr = std::unique_ptr; diff --git a/source/common/http/conn_manager_impl.cc b/source/common/http/conn_manager_impl.cc index 966efb6306..0827e0022e 100644 --- a/source/common/http/conn_manager_impl.cc +++ b/source/common/http/conn_manager_impl.cc @@ -629,7 +629,7 @@ void ConnectionManagerImpl::ActiveStream::onIdleTimeout() { stream_info_.setResponseFlag(StreamInfo::ResponseFlag::StreamIdleTimeout); sendLocalReply(request_headers_ != nullptr && Grpc::Common::hasGrpcContentType(*request_headers_), - Http::Code::RequestTimeout, "stream timeout", nullptr, is_head_request_, + Http::Code::RequestTimeout, "stream timeout", nullptr, state_.is_head_request_, absl::nullopt, StreamInfo::ResponseCodeDetails::get().StreamIdleTimeout); } } @@ -637,7 +637,7 @@ void ConnectionManagerImpl::ActiveStream::onIdleTimeout() { void ConnectionManagerImpl::ActiveStream::onRequestTimeout() { connection_manager_.stats_.named_.downstream_rq_timeout_.inc(); sendLocalReply(request_headers_ != nullptr && Grpc::Common::hasGrpcContentType(*request_headers_), - Http::Code::RequestTimeout, "request timeout", nullptr, is_head_request_, + Http::Code::RequestTimeout, "request timeout", nullptr, state_.is_head_request_, absl::nullopt, StreamInfo::ResponseCodeDetails::get().RequestOverallTimeout); } @@ -725,7 +725,7 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers, if (Http::Headers::get().MethodValues.Head == request_headers_->Method()->value().getStringView()) { - is_head_request_ = true; + state_.is_head_request_ = true; } ENVOY_STREAM_LOG(debug, "request headers complete (end_stream={}):\n{}", *this, end_stream, *request_headers_); @@ -743,8 +743,9 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers, state_.created_filter_chain_ = true; connection_manager_.stats_.named_.downstream_rq_overload_close_.inc(); sendLocalReply(Grpc::Common::hasGrpcContentType(*request_headers_), - Http::Code::ServiceUnavailable, "envoy overloaded", nullptr, is_head_request_, - absl::nullopt, StreamInfo::ResponseCodeDetails::get().Overload); + Http::Code::ServiceUnavailable, "envoy overloaded", nullptr, + state_.is_head_request_, absl::nullopt, + StreamInfo::ResponseCodeDetails::get().Overload); return; } @@ -772,8 +773,8 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers, stream_info_.protocol(protocol); if (!connection_manager_.config_.http1Settings().accept_http_10_) { // Send "Upgrade Required" if HTTP/1.0 support is not explicitly configured on. - sendLocalReply(false, Code::UpgradeRequired, "", nullptr, is_head_request_, absl::nullopt, - StreamInfo::ResponseCodeDetails::get().LowVersion); + sendLocalReply(false, Code::UpgradeRequired, "", nullptr, state_.is_head_request_, + absl::nullopt, StreamInfo::ResponseCodeDetails::get().LowVersion); return; } else { // HTTP/1.0 defaults to single-use connections. Make sure the connection @@ -796,7 +797,7 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers, } else { // Require host header. For HTTP/1.1 Host has already been translated to :authority. sendLocalReply(Grpc::Common::hasGrpcContentType(*request_headers_), Code::BadRequest, "", - nullptr, is_head_request_, absl::nullopt, + nullptr, state_.is_head_request_, absl::nullopt, StreamInfo::ResponseCodeDetails::get().MissingHost); return; } @@ -816,7 +817,7 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers, request_headers_->Path() && !request_headers_->Path()->value().getStringView().empty(); connection_manager_.stats_.named_.downstream_rq_non_relative_path_.inc(); sendLocalReply(Grpc::Common::hasGrpcContentType(*request_headers_), Code::NotFound, "", nullptr, - is_head_request_, absl::nullopt, + state_.is_head_request_, absl::nullopt, has_path ? StreamInfo::ResponseCodeDetails::get().AbsolutePath : StreamInfo::ResponseCodeDetails::get().MissingPath); return; @@ -826,7 +827,7 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers, if (!ConnectionManagerUtility::maybeNormalizePath(*request_headers_, connection_manager_.config_)) { sendLocalReply(Grpc::Common::hasGrpcContentType(*request_headers_), Code::BadRequest, "", - nullptr, is_head_request_, absl::nullopt, + nullptr, state_.is_head_request_, absl::nullopt, StreamInfo::ResponseCodeDetails::get().PathNormalizationFailed); return; } @@ -875,7 +876,7 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers, // Do not allow upgrades if the route does not support it. connection_manager_.stats_.named_.downstream_rq_ws_on_non_ws_route_.inc(); sendLocalReply(Grpc::Common::hasGrpcContentType(*request_headers_), Code::Forbidden, "", - nullptr, is_head_request_, absl::nullopt, + nullptr, state_.is_head_request_, absl::nullopt, StreamInfo::ResponseCodeDetails::get().UpgradeFailed); return; } @@ -931,19 +932,24 @@ void ConnectionManagerImpl::ActiveStream::traceRequest() { // If a decorator has been defined, apply it to the active span. if (hasCachedRoute() && cached_route_.value()->decorator()) { - cached_route_.value()->decorator()->apply(*active_span_); + const Router::Decorator* decorator = cached_route_.value()->decorator(); + + decorator->apply(*active_span_); + + state_.decorated_propagate_ = decorator->propagate(); // Cache decorated operation. - if (!cached_route_.value()->decorator()->getOperation().empty()) { - decorated_operation_ = &cached_route_.value()->decorator()->getOperation(); + if (!decorator->getOperation().empty()) { + decorated_operation_ = &decorator->getOperation(); } } if (connection_manager_.config_.tracingConfig()->operation_name_ == Tracing::OperationName::Egress) { - // For egress (outbound) requests, pass the decorator's operation name (if defined) - // as a request header to enable the receiving service to use it in its server span. - if (decorated_operation_) { + // For egress (outbound) requests, pass the decorator's operation name (if defined and + // propagation enabled) as a request header to enable the receiving service to use it in its + // server span. + if (decorated_operation_ && state_.decorated_propagate_) { request_headers_->setEnvoyDecoratorOperation(*decorated_operation_); } } else { @@ -975,8 +981,8 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(ActiveStreamDecoderFilte for (; entry != decoder_filters_.end(); entry++) { ASSERT(!(state_.filter_call_state_ & FilterCallState::DecodeHeaders)); state_.filter_call_state_ |= FilterCallState::DecodeHeaders; - (*entry)->end_stream_ = - decoding_headers_only_ || (end_stream && continue_data_entry == decoder_filters_.end()); + (*entry)->end_stream_ = state_.decoding_headers_only_ || + (end_stream && continue_data_entry == decoder_filters_.end()); FilterHeadersStatus status = (*entry)->decodeHeaders(headers, (*entry)->end_stream_); ASSERT(!(status == FilterHeadersStatus::ContinueAndEndStream && (*entry)->end_stream_)); @@ -998,7 +1004,7 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(ActiveStreamDecoderFilte } (*entry)->decode_headers_called_ = true; - if (!(*entry)->commonHandleAfterHeadersCallback(status, decoding_headers_only_) && + if (!(*entry)->commonHandleAfterHeadersCallback(status, state_.decoding_headers_only_) && std::next(entry) != decoder_filters_.end()) { // Stop iteration IFF this is not the last filter. If it is the last filter, continue with // processing since we need to handle the case where a terminal filter wants to buffer, but @@ -1045,7 +1051,7 @@ void ConnectionManagerImpl::ActiveStream::decodeData( resetIdleTimer(); // If we previously decided to decode only the headers, do nothing here. - if (decoding_headers_only_) { + if (state_.decoding_headers_only_) { return; } @@ -1199,7 +1205,7 @@ void ConnectionManagerImpl::ActiveStream::decodeTrailers(HeaderMapPtr&& trailers void ConnectionManagerImpl::ActiveStream::decodeTrailers(ActiveStreamDecoderFilter* filter, HeaderMap& trailers) { // If we previously decided to decode only the headers, do nothing here. - if (decoding_headers_only_) { + if (state_.decoding_headers_only_) { return; } @@ -1446,7 +1452,7 @@ void ConnectionManagerImpl::ActiveStream::encode100ContinueHeaders( resetIdleTimer(); ASSERT(connection_manager_.config_.proxy100Continue()); // Make sure commonContinue continues encode100ContinueHeaders. - has_continue_headers_ = true; + state_.has_continue_headers_ = true; // Similar to the block in encodeHeaders, run encode100ContinueHeaders on each // filter. This is simpler than that case because 100 continue implies no @@ -1493,8 +1499,8 @@ void ConnectionManagerImpl::ActiveStream::encodeHeaders(ActiveStreamEncoderFilte for (; entry != encoder_filters_.end(); entry++) { ASSERT(!(state_.filter_call_state_ & FilterCallState::EncodeHeaders)); state_.filter_call_state_ |= FilterCallState::EncodeHeaders; - (*entry)->end_stream_ = - encoding_headers_only_ || (end_stream && continue_data_entry == encoder_filters_.end()); + (*entry)->end_stream_ = state_.encoding_headers_only_ || + (end_stream && continue_data_entry == encoder_filters_.end()); FilterHeadersStatus status = (*entry)->handle_->encodeHeaders(headers, (*entry)->end_stream_); if ((*entry)->end_stream_) { (*entry)->handle_->encodeComplete(); @@ -1505,11 +1511,11 @@ void ConnectionManagerImpl::ActiveStream::encodeHeaders(ActiveStreamEncoderFilte (*entry)->encode_headers_called_ = true; const auto continue_iteration = - (*entry)->commonHandleAfterHeadersCallback(status, encoding_headers_only_); + (*entry)->commonHandleAfterHeadersCallback(status, state_.encoding_headers_only_); // If we're encoding a headers only response, then mark the local as complete. This ensures // that we don't attempt to reset the downstream request in doEndStream. - if (encoding_headers_only_) { + if (state_.encoding_headers_only_) { state_.local_complete_ = true; } @@ -1524,8 +1530,8 @@ void ConnectionManagerImpl::ActiveStream::encodeHeaders(ActiveStreamEncoderFilte } } - const bool modified_end_stream = - encoding_headers_only_ || (end_stream && continue_data_entry == encoder_filters_.end()); + const bool modified_end_stream = state_.encoding_headers_only_ || + (end_stream && continue_data_entry == encoder_filters_.end()); encodeHeadersInternal(headers, modified_end_stream); if (continue_data_entry != encoder_filters_.end() && !modified_end_stream) { @@ -1616,9 +1622,10 @@ void ConnectionManagerImpl::ActiveStream::encodeHeadersInternal(HeaderMap& heade if (connection_manager_.config_.tracingConfig()->operation_name_ == Tracing::OperationName::Ingress) { // For ingress (inbound) responses, if the request headers do not include a - // decorator operation (override), then pass the decorator's operation name (if defined) + // decorator operation (override), and the decorated operation should be + // propagated, then pass the decorator's operation name (if defined) // as a response header to enable the client service to use it in its client span. - if (decorated_operation_) { + if (decorated_operation_ && state_.decorated_propagate_) { headers.setEnvoyDecoratorOperation(*decorated_operation_); } } else if (connection_manager_.config_.tracingConfig()->operation_name_ == @@ -1718,7 +1725,7 @@ void ConnectionManagerImpl::ActiveStream::encodeData( resetIdleTimer(); // If we previously decided to encode only the headers, do nothing here. - if (encoding_headers_only_) { + if (state_.encoding_headers_only_) { return; } @@ -1784,7 +1791,7 @@ void ConnectionManagerImpl::ActiveStream::encodeData( void ConnectionManagerImpl::ActiveStream::encodeDataInternal(Buffer::Instance& data, bool end_stream) { - ASSERT(!encoding_headers_only_); + ASSERT(!state_.encoding_headers_only_); ENVOY_STREAM_LOG(trace, "encoding data via codec (size={} end_stream={})", *this, data.length(), end_stream); @@ -1798,7 +1805,7 @@ void ConnectionManagerImpl::ActiveStream::encodeTrailers(ActiveStreamEncoderFilt resetIdleTimer(); // If we previously decided to encode only the headers, do nothing here. - if (encoding_headers_only_) { + if (state_.encoding_headers_only_) { return; } @@ -1978,7 +1985,7 @@ void ConnectionManagerImpl::ActiveStreamFilterBase::commonContinue() { allowIteration(); // Only resume with do100ContinueHeaders() if we've actually seen a 100-Continue. - if (parent_.has_continue_headers_ && !continue_headers_continued_) { + if (parent_.state_.has_continue_headers_ && !continue_headers_continued_) { continue_headers_continued_ = true; do100ContinueHeaders(); // If the response headers have not yet come in, don't continue on with @@ -2011,7 +2018,7 @@ void ConnectionManagerImpl::ActiveStreamFilterBase::commonContinue() { bool ConnectionManagerImpl::ActiveStreamFilterBase::commonHandleAfter100ContinueHeadersCallback( FilterHeadersStatus status) { - ASSERT(parent_.has_continue_headers_); + ASSERT(parent_.state_.has_continue_headers_); ASSERT(!continue_headers_continued_); ASSERT(canIterate()); @@ -2418,7 +2425,7 @@ void ConnectionManagerImpl::ActiveStreamEncoderFilter::responseDataTooLarge() { }, parent_.state_.destroyed_, Http::Code::InternalServerError, CodeUtility::toString(Http::Code::InternalServerError), absl::nullopt, - parent_.is_head_request_); + parent_.state_.is_head_request_); parent_.maybeEndEncode(parent_.state_.local_complete_); } else { ENVOY_STREAM_LOG( diff --git a/source/common/http/conn_manager_impl.h b/source/common/http/conn_manager_impl.h index 961632a6f0..b1d2ad22bd 100644 --- a/source/common/http/conn_manager_impl.h +++ b/source/common/http/conn_manager_impl.h @@ -282,8 +282,8 @@ class ConnectionManagerImpl : Logger::Loggable, const absl::optional grpc_status, absl::string_view details) override { parent_.stream_info_.setResponseCodeDetails(details); - parent_.sendLocalReply(is_grpc_request_, code, body, modify_headers, parent_.is_head_request_, - grpc_status, details); + parent_.sendLocalReply(is_grpc_request_, code, body, modify_headers, + parent_.state_.is_head_request_, grpc_status, details); } void encode100ContinueHeaders(HeaderMapPtr&& headers) override; void encodeHeaders(HeaderMapPtr&& headers, bool end_stream) override; @@ -548,8 +548,9 @@ class ConnectionManagerImpl : Logger::Loggable, void dumpState(std::ostream& os, int indent_level = 0) const override { const char* spaces = spacesForLevel(indent_level); os << spaces << "ActiveStream " << this << DUMP_MEMBER(stream_id_) - << DUMP_MEMBER(has_continue_headers_) << DUMP_MEMBER(is_head_request_) - << DUMP_MEMBER(decoding_headers_only_) << DUMP_MEMBER(encoding_headers_only_) << "\n"; + << DUMP_MEMBER(state_.has_continue_headers_) << DUMP_MEMBER(state_.is_head_request_) + << DUMP_MEMBER(state_.decoding_headers_only_) << DUMP_MEMBER(state_.encoding_headers_only_) + << "\n"; DUMP_DETAILS(request_headers_); DUMP_DETAILS(request_trailers_); @@ -604,7 +605,8 @@ class ConnectionManagerImpl : Logger::Loggable, State() : remote_complete_(false), local_complete_(false), codec_saw_local_complete_(false), saw_connection_close_(false), successful_upgrade_(false), created_filter_chain_(false), - is_internally_created_(false) {} + is_internally_created_(false), decorated_propagate_(true), has_continue_headers_(false), + is_head_request_(false), decoding_headers_only_(false), encoding_headers_only_(false) {} uint32_t filter_call_state_{0}; // The following 3 members are booleans rather than part of the space-saving bitfield as they @@ -627,6 +629,18 @@ class ConnectionManagerImpl : Logger::Loggable, // internal redirects or other streams created via recreateStream(). bool is_internally_created_ : 1; + bool decorated_propagate_ : 1; + // By default, we will assume there are no 100-Continue headers. If encode100ContinueHeaders + // is ever called, this is set to true so commonContinue resumes processing the 100-Continue. + bool has_continue_headers_ : 1; + bool is_head_request_ : 1; + // Whether a filter has indicated that the request should be treated as a headers only + // request. + bool decoding_headers_only_; + // Whether a filter has indicated that the response should be treated as a headers only + // response. + bool encoding_headers_only_; + // Used to track which filter is the latest filter that has received data. ActiveStreamEncoderFilter* latest_data_encoding_filter_{}; ActiveStreamDecoderFilter* latest_data_decoding_filter_{}; @@ -698,15 +712,6 @@ class ConnectionManagerImpl : Logger::Loggable, uint32_t buffer_limit_{0}; uint32_t high_watermark_count_{0}; const std::string* decorated_operation_{nullptr}; - // By default, we will assume there are no 100-Continue headers. If encode100ContinueHeaders - // is ever called, this is set to true so commonContinue resumes processing the 100-Continue. - bool has_continue_headers_{}; - bool is_head_request_{}; - // Whether a filter has indicated that the request should be treated as a headers only request. - bool decoding_headers_only_{}; - // Whether a filter has indicated that the response should be treated as a headers only - // response. - bool encoding_headers_only_{}; Network::Socket::OptionsSharedPtr upstream_options_; std::unique_ptr route_config_update_requester_; std::unique_ptr tracing_custom_tags_{nullptr}; diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc index 4f9a73c0e4..a3913d96c7 100644 --- a/source/common/router/config_impl.cc +++ b/source/common/router/config_impl.cc @@ -188,7 +188,8 @@ ShadowPolicyImpl::ShadowPolicyImpl(const RequestMirrorPolicy& config) { } DecoratorImpl::DecoratorImpl(const envoy::config::route::v3::Decorator& decorator) - : operation_(decorator.operation()) {} + : operation_(decorator.operation()), + propagate_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(decorator, propagate, true)) {} void DecoratorImpl::apply(Tracing::Span& span) const { if (!operation_.empty()) { @@ -198,6 +199,8 @@ void DecoratorImpl::apply(Tracing::Span& span) const { const std::string& DecoratorImpl::getOperation() const { return operation_; } +bool DecoratorImpl::propagate() const { return propagate_; } + RouteTracingImpl::RouteTracingImpl(const envoy::config::route::v3::Tracing& tracing) { if (!tracing.has_client_sampling()) { client_sampling_.set_numerator(100); diff --git a/source/common/router/config_impl.h b/source/common/router/config_impl.h index 7d04e40059..69f482b546 100644 --- a/source/common/router/config_impl.h +++ b/source/common/router/config_impl.h @@ -336,8 +336,12 @@ class DecoratorImpl : public Decorator { // Decorator::getOperation const std::string& getOperation() const override; + // Decorator::getOperation + bool propagate() const override; + private: const std::string operation_; + const bool propagate_; }; /** diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc index 2c26582175..c2db560ffb 100644 --- a/test/common/http/conn_manager_impl_test.cc +++ b/test/common/http/conn_manager_impl_test.cc @@ -978,10 +978,11 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecorat return span; })); route_config_provider_.route_config_->route_->decorator_.operation_ = "testOp"; - EXPECT_CALL(*route_config_provider_.route_config_->route_, decorator()).Times(4); + EXPECT_CALL(*route_config_provider_.route_config_->route_, decorator()).Times(2); EXPECT_CALL(route_config_provider_.route_config_->route_->decorator_, apply(_)) .WillOnce(Invoke( [&](const Tracing::Span& apply_to_span) -> void { EXPECT_EQ(span, &apply_to_span); })); + EXPECT_EQ(true, route_config_provider_.route_config_->route_->decorator_.propagate()); EXPECT_CALL(*span, finishSpan()); EXPECT_CALL(*span, setTag(_, _)).Times(testing::AnyNumber()); EXPECT_CALL( @@ -1029,6 +1030,72 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecorat conn_manager_->onData(fake_input, false); } +TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecoratorPropagateFalse) { + setup(false, ""); + + auto* span = new NiceMock(); + EXPECT_CALL(tracer_, startSpan_(_, _, _, _)) + .WillOnce( + Invoke([&](const Tracing::Config& config, const HeaderMap&, const StreamInfo::StreamInfo&, + const Tracing::Decision) -> Tracing::Span* { + EXPECT_EQ(Tracing::OperationName::Ingress, config.operationName()); + + return span; + })); + route_config_provider_.route_config_->route_->decorator_.operation_ = "testOp"; + ON_CALL(route_config_provider_.route_config_->route_->decorator_, propagate()) + .WillByDefault(Return(false)); + EXPECT_CALL(*route_config_provider_.route_config_->route_, decorator()).Times(2); + EXPECT_CALL(route_config_provider_.route_config_->route_->decorator_, apply(_)) + .WillOnce(Invoke( + [&](const Tracing::Span& apply_to_span) -> void { EXPECT_EQ(span, &apply_to_span); })); + EXPECT_CALL(*span, finishSpan()); + EXPECT_CALL(*span, setTag(_, _)).Times(testing::AnyNumber()); + EXPECT_CALL( + runtime_.snapshot_, + featureEnabled("tracing.global_enabled", An(), _)) + .WillOnce(Return(true)); + EXPECT_CALL(*span, setOperation(_)).Times(0); + + std::shared_ptr filter(new NiceMock()); + + EXPECT_CALL(filter_factory_, createFilterChain(_)) + .WillRepeatedly(Invoke([&](FilterChainFactoryCallbacks& callbacks) -> void { + callbacks.addStreamDecoderFilter(filter); + })); + + // Treat request as internal, otherwise x-request-id header will be overwritten. + use_remote_address_ = false; + EXPECT_CALL(random_, uuid()).Times(0); + + RequestDecoder* decoder = nullptr; + NiceMock encoder; + EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { + decoder = &conn_manager_->newStream(encoder); + + HeaderMapPtr headers{ + new TestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + decoder->decodeHeaders(std::move(headers), true); + + HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + filter->callbacks_->encodeHeaders(std::move(response_headers), true); + filter->callbacks_->activeSpan().setTag("service-cluster", "scoobydoo"); + data.drain(4); + })); + + // Verify decorator operation response header has NOT been defined (i.e. not propagated). + EXPECT_CALL(encoder, encodeHeaders(_, true)) + .WillOnce(Invoke([](const HeaderMap& headers, bool) -> void { + EXPECT_EQ(nullptr, headers.EnvoyDecoratorOperation()); + })); + + Buffer::OwnedImpl fake_input("1234"); + conn_manager_->onData(fake_input, false); +} + TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecoratorOverrideOp) { setup(false, ""); @@ -1042,7 +1109,7 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecorat return span; })); route_config_provider_.route_config_->route_->decorator_.operation_ = "initOp"; - EXPECT_CALL(*route_config_provider_.route_config_->route_, decorator()).Times(4); + EXPECT_CALL(*route_config_provider_.route_config_->route_, decorator()).Times(2); EXPECT_CALL(route_config_provider_.route_config_->route_->decorator_, apply(_)) .WillOnce(Invoke( [&](const Tracing::Span& apply_to_span) -> void { EXPECT_EQ(span, &apply_to_span); })); @@ -1122,10 +1189,11 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecorato return span; })); route_config_provider_.route_config_->route_->decorator_.operation_ = "testOp"; - EXPECT_CALL(*route_config_provider_.route_config_->route_, decorator()).Times(4); + EXPECT_CALL(*route_config_provider_.route_config_->route_, decorator()).Times(2); EXPECT_CALL(route_config_provider_.route_config_->route_->decorator_, apply(_)) .WillOnce(Invoke( [&](const Tracing::Span& apply_to_span) -> void { EXPECT_EQ(span, &apply_to_span); })); + EXPECT_EQ(true, route_config_provider_.route_config_->route_->decorator_.propagate()); EXPECT_CALL(*span, finishSpan()); EXPECT_CALL(*span, setTag(_, _)).Times(testing::AnyNumber()); EXPECT_CALL( @@ -1176,6 +1244,87 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecorato conn_manager_->onData(fake_input, false); } +TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecoratorPropagateFalse) { + setup(false, ""); + envoy::type::v3::FractionalPercent percent1; + percent1.set_numerator(100); + envoy::type::v3::FractionalPercent percent2; + percent2.set_numerator(10000); + percent2.set_denominator(envoy::type::v3::FractionalPercent::TEN_THOUSAND); + tracing_config_ = std::make_unique( + TracingConnectionManagerConfig{Tracing::OperationName::Egress, + {{":method", requestHeaderCustomTag(":method")}}, + percent1, + percent2, + percent1, + false, + 256}); + + auto* span = new NiceMock(); + EXPECT_CALL(tracer_, startSpan_(_, _, _, _)) + .WillOnce( + Invoke([&](const Tracing::Config& config, const HeaderMap&, const StreamInfo::StreamInfo&, + const Tracing::Decision) -> Tracing::Span* { + EXPECT_EQ(Tracing::OperationName::Egress, config.operationName()); + + return span; + })); + route_config_provider_.route_config_->route_->decorator_.operation_ = "testOp"; + ON_CALL(route_config_provider_.route_config_->route_->decorator_, propagate()) + .WillByDefault(Return(false)); + EXPECT_CALL(*route_config_provider_.route_config_->route_, decorator()).Times(2); + EXPECT_CALL(route_config_provider_.route_config_->route_->decorator_, apply(_)) + .WillOnce(Invoke( + [&](const Tracing::Span& apply_to_span) -> void { EXPECT_EQ(span, &apply_to_span); })); + EXPECT_CALL(*span, finishSpan()); + EXPECT_CALL(*span, setTag(_, _)).Times(testing::AnyNumber()); + EXPECT_CALL( + runtime_.snapshot_, + featureEnabled("tracing.global_enabled", An(), _)) + .WillOnce(Return(true)); + EXPECT_CALL(*span, setOperation(_)).Times(0); + + std::shared_ptr filter(new NiceMock()); + + EXPECT_CALL(filter_factory_, createFilterChain(_)) + .WillRepeatedly(Invoke([&](FilterChainFactoryCallbacks& callbacks) -> void { + callbacks.addStreamDecoderFilter(filter); + })); + + // Treat request as internal, otherwise x-request-id header will be overwritten. + use_remote_address_ = false; + EXPECT_CALL(random_, uuid()).Times(0); + + RequestDecoder* decoder = nullptr; + NiceMock encoder; + EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { + decoder = &conn_manager_->newStream(encoder); + + HeaderMapPtr headers{ + new TestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + decoder->decodeHeaders(std::move(headers), true); + + HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + filter->callbacks_->encodeHeaders(std::move(response_headers), true); + filter->callbacks_->activeSpan().setTag("service-cluster", "scoobydoo"); + + data.drain(4); + })); + + // Verify that decorator operation has NOT been set as request header (propagate is false) + EXPECT_CALL(*filter, decodeHeaders(_, true)) + .WillOnce(Invoke([](HeaderMap& headers, bool) -> FilterHeadersStatus { + EXPECT_EQ(nullptr, headers.EnvoyDecoratorOperation()); + return FilterHeadersStatus::StopIteration; + })); + + Buffer::OwnedImpl fake_input("1234"); + conn_manager_->onData(fake_input, false); +} + TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecoratorOverrideOp) { setup(false, ""); envoy::type::v3::FractionalPercent percent1; @@ -1202,7 +1351,7 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecorato return span; })); route_config_provider_.route_config_->route_->decorator_.operation_ = "initOp"; - EXPECT_CALL(*route_config_provider_.route_config_->route_, decorator()).Times(4); + EXPECT_CALL(*route_config_provider_.route_config_->route_, decorator()).Times(2); EXPECT_CALL(route_config_provider_.route_config_->route_->decorator_, apply(_)) .WillOnce(Invoke( [&](const Tracing::Span& apply_to_span) -> void { EXPECT_EQ(span, &apply_to_span); })); diff --git a/test/common/router/config_impl_test.cc b/test/common/router/config_impl_test.cc index 8bfff452da..cbbe09b060 100644 --- a/test/common/router/config_impl_test.cc +++ b/test/common/router/config_impl_test.cc @@ -4990,6 +4990,7 @@ TEST_F(RouteMatcherTest, Decorator) { cluster: foo decorator: operation: myFoo + propagate: false - match: prefix: "/bar" route: @@ -5004,6 +5005,7 @@ TEST_F(RouteMatcherTest, Decorator) { Tracing::MockSpan span; EXPECT_CALL(span, setOperation(Eq("myFoo"))); route->decorator()->apply(span); + EXPECT_EQ(false, route->decorator()->propagate()); } { Http::TestHeaderMapImpl headers = genHeaders("www.lyft.com", "/bar", "GET"); diff --git a/test/mocks/router/mocks.cc b/test/mocks/router/mocks.cc index 21edb27ffa..5f4f8d487c 100644 --- a/test/mocks/router/mocks.cc +++ b/test/mocks/router/mocks.cc @@ -112,6 +112,7 @@ MockConfig::~MockConfig() = default; MockDecorator::MockDecorator() { ON_CALL(*this, getOperation()).WillByDefault(ReturnRef(operation_)); + ON_CALL(*this, propagate()).WillByDefault(Return(true)); } MockDecorator::~MockDecorator() = default; diff --git a/test/mocks/router/mocks.h b/test/mocks/router/mocks.h index db5a33795a..a75e91a9fc 100644 --- a/test/mocks/router/mocks.h +++ b/test/mocks/router/mocks.h @@ -371,6 +371,7 @@ class MockDecorator : public Decorator { // Router::Decorator MOCK_METHOD(const std::string&, getOperation, (), (const)); + MOCK_METHOD(bool, propagate, (), (const)); MOCK_METHOD(void, apply, (Tracing::Span & span), (const)); std::string operation_{"fake_operation"}; From bbdc33e53723dc02b6d51bb0f329c5b369adfe03 Mon Sep 17 00:00:00 2001 From: toddmgreer Date: Fri, 7 Feb 2020 16:43:58 -0800 Subject: [PATCH 31/87] filter: Add HttpCache interface and helpers (#9878) Signed-off-by: Todd Greer --- source/common/http/headers.h | 1 + source/extensions/filters/http/cache/BUILD | 24 ++ .../filters/http/cache/http_cache.cc | 160 +++++++++ .../filters/http/cache/http_cache.h | 322 ++++++++++++++++++ .../extensions/filters/http/cache/key.proto | 16 + test/extensions/filters/http/cache/BUILD | 11 + .../filters/http/cache/http_cache_test.cc | 256 ++++++++++++++ tools/spelling_dictionary.txt | 5 + 8 files changed, 795 insertions(+) create mode 100644 source/extensions/filters/http/cache/http_cache.cc create mode 100644 source/extensions/filters/http/cache/http_cache.h create mode 100644 source/extensions/filters/http/cache/key.proto create mode 100644 test/extensions/filters/http/cache/http_cache_test.cc diff --git a/source/common/http/headers.h b/source/common/http/headers.h index 1c0ffc6ed2..868845ef02 100644 --- a/source/common/http/headers.h +++ b/source/common/http/headers.h @@ -117,6 +117,7 @@ class HeaderValues { const LowerCaseString EnvoyDecoratorOperation{absl::StrCat(prefix(), "-decorator-operation")}; const LowerCaseString Etag{"etag"}; const LowerCaseString Expect{"expect"}; + const LowerCaseString Expires{"expires"}; const LowerCaseString ForwardedClientCert{"x-forwarded-client-cert"}; const LowerCaseString ForwardedFor{"x-forwarded-for"}; const LowerCaseString ForwardedHost{"x-forwarded-host"}; diff --git a/source/extensions/filters/http/cache/BUILD b/source/extensions/filters/http/cache/BUILD index 52d3661f44..3bfa5e87a5 100644 --- a/source/extensions/filters/http/cache/BUILD +++ b/source/extensions/filters/http/cache/BUILD @@ -7,10 +7,34 @@ load( "envoy_cc_extension", "envoy_cc_library", "envoy_package", + "envoy_proto_library", ) envoy_package() +envoy_proto_library( + name = "key", + srcs = ["key.proto"], +) + +envoy_cc_library( + name = "http_cache_lib", + srcs = ["http_cache.cc"], + hdrs = ["http_cache.h"], + deps = [ + ":http_cache_utils_lib", + ":key_cc_proto", + "//include/envoy/buffer:buffer_interface", + "//include/envoy/common:time_interface", + "//include/envoy/config:typed_config_interface", + "//include/envoy/http:codes_interface", + "//include/envoy/http:header_map_interface", + "//source/common/common:assert_lib", + "//source/common/http:headers_lib", + "//source/common/protobuf:utility_lib", + ], +) + envoy_cc_library( name = "http_cache_utils_lib", srcs = ["http_cache_utils.cc"], diff --git a/source/extensions/filters/http/cache/http_cache.cc b/source/extensions/filters/http/cache/http_cache.cc new file mode 100644 index 0000000000..45a91f56c8 --- /dev/null +++ b/source/extensions/filters/http/cache/http_cache.cc @@ -0,0 +1,160 @@ +#include "extensions/filters/http/cache/http_cache.h" + +#include +#include + +#include "envoy/http/codes.h" + +#include "common/http/headers.h" +#include "common/protobuf/utility.h" + +#include "extensions/filters/http/cache/http_cache_utils.h" + +#include "absl/time/time.h" + +namespace Envoy { +namespace Extensions { +namespace HttpFilters { +namespace Cache { + +std::ostream& operator<<(std::ostream& os, CacheEntryStatus status) { + switch (status) { + case CacheEntryStatus::Ok: + return os << "Ok"; + case CacheEntryStatus::Unusable: + return os << "Unusable"; + case CacheEntryStatus::RequiresValidation: + return os << "RequiresValidation"; + case CacheEntryStatus::FoundNotModified: + return os << "FoundNotModified"; + case CacheEntryStatus::UnsatisfiableRange: + return os << "UnsatisfiableRange"; + } + NOT_REACHED_GCOVR_EXCL_LINE; +} + +std::ostream& operator<<(std::ostream& os, const AdjustedByteRange& range) { + return os << "[" << range.begin() << "," << range.end() << ")"; +} + +LookupRequest::LookupRequest(const Http::HeaderMap& request_headers, SystemTime timestamp) + : timestamp_(timestamp), + request_cache_control_(request_headers.CacheControl() == nullptr + ? "" + : request_headers.CacheControl()->value().getStringView()) { + // These ASSERTs check prerequisites. A request without these headers can't be looked up in cache; + // CacheFilter doesn't create LookupRequests for such requests. + ASSERT(request_headers.Path(), "Can't form cache lookup key for malformed Http::HeaderMap " + "with null Path."); + ASSERT(request_headers.ForwardedProto(), + "Can't form cache lookup key for malformed Http::HeaderMap with null ForwardedProto."); + ASSERT(request_headers.Host(), "Can't form cache lookup key for malformed Http::HeaderMap " + "with null Host."); + const Http::HeaderString& forwarded_proto = request_headers.ForwardedProto()->value(); + const auto& scheme_values = Http::Headers::get().SchemeValues; + ASSERT(forwarded_proto == scheme_values.Http || forwarded_proto == scheme_values.Https); + // TODO(toddmgreer): Let config determine whether to include forwarded_proto, host, and + // query params. + // TODO(toddmgreer): get cluster name. + // TODO(toddmgreer): Parse Range header into request_range_spec_, and handle the resultant + // vector in CacheFilter::onOkHeaders. + key_.set_cluster_name("cluster_name_goes_here"); + key_.set_host(std::string(request_headers.Host()->value().getStringView())); + key_.set_path(std::string(request_headers.Path()->value().getStringView())); + key_.set_clear_http(forwarded_proto == scheme_values.Http); +} + +// Unless this API is still alpha, calls to stableHashKey() must always return +// the same result, or a way must be provided to deal with a complete cache +// flush. localHashKey however, can be changed at will. +size_t stableHashKey(const Key& key) { return MessageUtil::hash(key); } +size_t localHashKey(const Key& key) { return stableHashKey(key); } + +// Returns true if response_headers is fresh. +bool LookupRequest::isFresh(const Http::HeaderMap& response_headers) const { + if (!response_headers.Date()) { + return false; + } + const Http::HeaderEntry* cache_control_header = response_headers.CacheControl(); + if (cache_control_header) { + const SystemTime::duration effective_max_age = + Utils::effectiveMaxAge(cache_control_header->value().getStringView()); + return timestamp_ - Utils::httpTime(response_headers.Date()) < effective_max_age; + } + // We didn't find a cache-control header with enough info to determine + // freshness, so fall back to the expires header. + return timestamp_ <= Utils::httpTime(response_headers.get(Http::Headers::get().Expires)); +} + +LookupResult LookupRequest::makeLookupResult(Http::HeaderMapPtr&& response_headers, + uint64_t content_length) const { + // TODO(toddmgreer): Implement all HTTP caching semantics. + ASSERT(response_headers); + LookupResult result; + result.cache_entry_status_ = + isFresh(*response_headers) ? CacheEntryStatus::Ok : CacheEntryStatus::RequiresValidation; + result.headers_ = std::move(response_headers); + result.content_length_ = content_length; + if (!adjustByteRangeSet(result.response_ranges_, request_range_spec_, content_length)) { + result.headers_->setStatus(static_cast(Http::Code::RangeNotSatisfiable)); + } + result.has_trailers_ = false; + return result; +} + +bool adjustByteRangeSet(std::vector& response_ranges, + const std::vector& request_range_spec, + uint64_t content_length) { + if (request_range_spec.empty()) { + // No range header, so the request can proceed. + return true; + } + + if (content_length == 0) { + // There is a range header, but it's unsatisfiable. + return false; + } + + for (const RawByteRange& spec : request_range_spec) { + if (spec.isSuffix()) { + // spec is a suffix-byte-range-spec + if (spec.suffixLength() == 0) { + // This range is unsatisfiable, so skip it. + continue; + } + if (spec.suffixLength() >= content_length) { + // All bytes are being requested, so we may as well send a '200 + // OK' response. + response_ranges.clear(); + return true; + } + response_ranges.emplace_back(content_length - spec.suffixLength(), content_length); + } else { + // spec is a byte-range-spec + if (spec.firstBytePos() >= content_length) { + // This range is unsatisfiable, so skip it. + continue; + } + if (spec.lastBytePos() >= content_length - 1) { + if (spec.firstBytePos() == 0) { + // All bytes are being requested, so we may as well send a '200 + // OK' response. + response_ranges.clear(); + return true; + } + response_ranges.emplace_back(spec.firstBytePos(), content_length); + } else { + response_ranges.emplace_back(spec.firstBytePos(), spec.lastBytePos() + 1); + } + } + } + if (response_ranges.empty()) { + // All ranges were unsatisfiable. + return false; + } + return true; +} +} // namespace Cache +} // namespace HttpFilters +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/filters/http/cache/http_cache.h b/source/extensions/filters/http/cache/http_cache.h new file mode 100644 index 0000000000..46a02884eb --- /dev/null +++ b/source/extensions/filters/http/cache/http_cache.h @@ -0,0 +1,322 @@ +#pragma once + +#include +#include +#include + +#include "envoy/buffer/buffer.h" +#include "envoy/common/time.h" +#include "envoy/config/typed_config.h" +#include "envoy/http/header_map.h" + +#include "common/common/assert.h" + +#include "source/extensions/filters/http/cache/key.pb.h" + +#include "absl/strings/string_view.h" + +namespace Envoy { +namespace Extensions { +namespace HttpFilters { +namespace Cache { +// Whether a given cache entry is good for the current request. +enum class CacheEntryStatus { + // This entry is fresh, and an appropriate response to the request. + Ok, + // No usable entry was found. If this was generated for a cache entry, the + // cache should delete that entry. + Unusable, + // This entry is stale, but appropriate for validating + RequiresValidation, + // This entry is fresh, and an appropriate basis for a 304 Not Modified + // response. + FoundNotModified, + // This entry is fresh, but can't satisfy the requested range(s). + UnsatisfiableRange, +}; + +std::ostream& operator<<(std::ostream& os, CacheEntryStatus status); + +// Byte range from an HTTP request. +class RawByteRange { +public: + // - If first==UINT64_MAX, construct a RawByteRange requesting the final last body bytes. + // - Otherwise, construct a RawByteRange requesting the [first,last] body bytes. + // Prereq: first == UINT64_MAX || first <= last + // Invariant: isSuffix() || firstBytePos() <= lastBytePos + // Examples: RawByteRange(0,4) requests the first 5 bytes. + // RawByteRange(UINT64_MAX,4) requests the last 4 bytes. + RawByteRange(uint64_t first, uint64_t last) : first_byte_pos_(first), last_byte_pos_(last) { + ASSERT(isSuffix() || first <= last, "Illegal byte range."); + } + bool isSuffix() const { return first_byte_pos_ == UINT64_MAX; } + uint64_t firstBytePos() const { + ASSERT(!isSuffix()); + return first_byte_pos_; + } + uint64_t lastBytePos() const { + ASSERT(!isSuffix()); + return last_byte_pos_; + } + uint64_t suffixLength() const { + ASSERT(isSuffix()); + return last_byte_pos_; + } + +private: + const uint64_t first_byte_pos_; + const uint64_t last_byte_pos_; +}; + +// Byte range from an HTTP request, adjusted for a known response body size, and converted from an +// HTTP-style closed interval to a C++ style half-open interval. +class AdjustedByteRange { +public: + // Construct an AdjustedByteRange representing the [first,last) bytes in the + // response body. Prereq: first <= last Invariant: begin() <= end() + // Example: AdjustedByteRange(0,4) represents the first 4 bytes. + AdjustedByteRange(uint64_t first, uint64_t last) : first_(first), last_(last) { + ASSERT(first < last, "Illegal byte range."); + } + uint64_t begin() const { return first_; } + // Unlike RawByteRange, end() is one past the index of the last offset. + uint64_t end() const { return last_; } + uint64_t length() const { return last_ - first_; } + void trimFront(uint64_t n) { + ASSERT(n <= length(), "Attempt to trim too much from range."); + first_ += n; + } + +private: + uint64_t first_; + const uint64_t last_; +}; + +inline bool operator==(const AdjustedByteRange& lhs, const AdjustedByteRange& rhs) { + return lhs.begin() == rhs.begin() && lhs.end() == rhs.end(); +} + +std::ostream& operator<<(std::ostream& os, const AdjustedByteRange& range); + +// Adjusts request_range_spec to fit a cached response of size content_length, putting the results +// in response_ranges. Returns true if response_ranges is satisfiable (empty is considered +// satisfiable, as it denotes the entire body). +// TODO(toddmgreer): Merge/reorder ranges where appropriate. +bool adjustByteRangeSet(std::vector& response_ranges, + const std::vector& request_range_spec, + uint64_t content_length); + +// Result of a lookup operation, including cached headers and information needed +// to serve a response based on it, or to attempt to validate. +struct LookupResult { + // If cache_entry_status_ == Unusable, none of the other members are + // meaningful. + CacheEntryStatus cache_entry_status_ = CacheEntryStatus::Unusable; + + // Headers of the cached response. + Http::HeaderMapPtr headers_; + + // Size of the full response body. Cache filter will generate a content-length + // header with this value, replacing any preexisting content-length header. + // (This lets us dechunk responses as we insert them, then later serve them + // with a content-length header.) + uint64_t content_length_; + + // Represents the subset of the cached response body that should be served to + // the client. If response_ranges.empty(), the entire body should be served. + // Otherwise, each Range in response_ranges specifies an exact set of bytes to + // serve from the cached response's body. All byte positions in + // response_ranges must be in the range [0,content_length). Caches should + // ensure that they can efficiently serve these ranges, and may merge and/or + // reorder ranges as appropriate, or may clear() response_ranges entirely. + std::vector response_ranges_; + + // TODO(toddmgreer): Implement trailer support. + // True if the cached response has trailers. + bool has_trailers_ = false; +}; + +// Produces a hash of key that is consistent across restarts, architectures, +// builds, and configurations. Caches that store persistent entries based on a +// 64-bit hash should (but are not required to) use stableHashKey. Once this API +// leaves alpha, any improvements to stableHashKey that would change its output +// for existing callers is a breaking change. +// +// For non-persistent storage, use MessageUtil, which has no long-term stability +// guarantees. +// +// When providing a cached response, Caches must ensure that the keys (and not +// just their hashes) match. +// +// TODO(toddmgreer): Ensure that stability guarantees above are accurate. +size_t stableHashKey(const Key& key); + +// LookupRequest holds everything about a request that's needed to look for a +// response in a cache, to evaluate whether an entry from a cache is usable, and +// to determine what ranges are needed. +class LookupRequest { +public: + using HeaderVector = std::vector; + + // Prereq: request_headers's Path(), Scheme(), and Host() are non-null. + LookupRequest(const Http::HeaderMap& request_headers, SystemTime timestamp); + + // Caches may modify the key according to local needs, though care must be + // taken to ensure that meaningfully distinct responses have distinct keys. + const Key& key() const { return key_; } + Key& key() { return key_; } + + // Returns the subset of this request's headers that are listed in + // envoy::config::filter::http::cache::v3::CacheConfig::allowed_vary_headers. If a cache + // storage implementation forwards lookup requests to a remote cache server that supports *vary* + // headers, that server may need to see these headers. For local implementations, it may be + // simpler to instead call makeLookupResult with each potential response. + HeaderVector& vary_headers() { return vary_headers_; } + const HeaderVector& vary_headers() const { return vary_headers_; } + + // Time when this LookupRequest was created (in response to an HTTP request). + SystemTime timestamp() const { return timestamp_; } + + // WARNING: Incomplete--do not use in production (yet). + // Returns a LookupResult suitable for sending to the cache filter's + // LookupHeadersCallback. Specifically, + // - LookupResult::cache_entry_status_ is set according to HTTP cache + // validation logic. + // - LookupResult::headers takes ownership of response_headers. + // - LookupResult::content_length == content_length. + // - LookupResult::response_ranges entries are satisfiable (as documented + // there). + LookupResult makeLookupResult(Http::HeaderMapPtr&& response_headers, + uint64_t content_length) const; + +private: + bool isFresh(const Http::HeaderMap& response_headers) const; + + Key key_; + std::vector request_range_spec_; + SystemTime timestamp_; + HeaderVector vary_headers_; + const std::string request_cache_control_; +}; + +// Statically known information about a cache. +struct CacheInfo { + absl::string_view name_; + bool supports_range_requests_ = false; +}; + +using LookupBodyCallback = std::function; +using LookupHeadersCallback = std::function; +using LookupTrailersCallback = std::function; +using InsertCallback = std::function; + +// Manages the lifetime of an insertion. +class InsertContext { +public: + // Accepts response_headers for caching. Only called once. + virtual void insertHeaders(const Http::HeaderMap& response_headers, bool end_stream) PURE; + + // The insertion is streamed into the cache in chunks whose size is determined + // by the client, but with a pace determined by the cache. To avoid streaming + // data into cache too fast for the cache to handle, clients should wait for + // the cache to call ready_for_next_chunk() before streaming the next chunk. + // + // The client can abort the streaming insertion by dropping the + // InsertContextPtr. A cache can abort the insertion by passing 'false' into + // ready_for_next_chunk. + virtual void insertBody(const Buffer::Instance& chunk, InsertCallback ready_for_next_chunk, + bool end_stream) PURE; + + // Inserts trailers into the cache. + virtual void insertTrailers(const Http::HeaderMap& trailers) PURE; + + virtual ~InsertContext() = default; +}; +using InsertContextPtr = std::unique_ptr; + +// Lookup context manages the lifetime of a lookup, helping clients to pull data +// from the cache at a pace that works for them. At any time a client can abort +// an in-progress lookup by simply dropping the LookupContextPtr. +class LookupContext { +public: + virtual ~LookupContext() = default; + + // Get the headers from the cache. It is a programming error to call this + // twice. + virtual void getHeaders(LookupHeadersCallback&& cb) PURE; + + // Reads the next chunk from the cache, calling cb when the chunk is ready. + // + // The cache must call cb with a range of bytes starting at range.start() and + // ending at or before range.end(). Caller is responsible for tracking what + // ranges have been received, what to request next, and when to stop. A cache + // can report an error, and cause the response to be aborted, by calling cb + // with nullptr. + // + // If a cache happens to load data in chunks of a set size, it may be + // efficient to respond with fewer than the requested number of bytes. For + // example, assuming a 23 byte full-bodied response from a cache that reads in + // absurdly small 10 byte chunks: + // + // getBody requests bytes 0-23 .......... callback with bytes 0-9 + // getBody requests bytes 10-23 .......... callback with bytes 10-19 + // getBody requests bytes 20-23 .......... callback with bytes 20-23 + virtual void getBody(const AdjustedByteRange& range, LookupBodyCallback&& cb) PURE; + + // Get the trailers from the cache. Only called if LookupResult::has_trailers + // == true. + virtual void getTrailers(LookupTrailersCallback&& cb) PURE; +}; +using LookupContextPtr = std::unique_ptr; + +// Implement this interface to provide a cache implementation for use by +// CacheFilter. +class HttpCache { +public: + // Returns a LookupContextPtr to manage the state of a cache lookup. On a cache + // miss, the returned LookupContext will be given to the insert call (if any). + virtual LookupContextPtr makeLookupContext(LookupRequest&& request) PURE; + + // Returns an InsertContextPtr to manage the state of a cache insertion. + // Responses with a chunked transfer-encoding must be dechunked before + // insertion. + virtual InsertContextPtr makeInsertContext(LookupContextPtr&& lookup_context) PURE; + + // Precondition: lookup_context represents a prior cache lookup that required + // validation. + // + // Update the headers of that cache entry to match response_headers. The cache + // entry's body and trailers (if any) will not be modified. + // + // This is called when an expired cache entry is successfully validated, to + // update the cache entry. + virtual void updateHeaders(LookupContextPtr&& lookup_context, + Http::HeaderMapPtr&& response_headers) PURE; + + // Returns statically known information about a cache. + virtual CacheInfo cacheInfo() const PURE; + + virtual ~HttpCache() = default; +}; + +// Factory interface for cache implementations to implement and register. +class HttpCacheFactory : public Config::TypedFactory { +public: + // name should be in reverse DNS format, though this is not enforced. + explicit HttpCacheFactory(std::string name) : name_(std::move(name)) {} + std::string name() const override { return name_; } + std::string category() const override { return "http_cache_factory"; } + + // Returns an HttpCache that will remain valid indefinitely (at least as long + // as the calling CacheFilter). + virtual HttpCache& getCache() PURE; + virtual ~HttpCacheFactory() = default; + +private: + const std::string name_; +}; +using HttpCacheFactoryPtr = std::unique_ptr; +} // namespace Cache +} // namespace HttpFilters +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/filters/http/cache/key.proto b/source/extensions/filters/http/cache/key.proto new file mode 100644 index 0000000000..e81a1b71cd --- /dev/null +++ b/source/extensions/filters/http/cache/key.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package Envoy.Extensions.HttpFilters.Cache; + +// Cache key for lookups and inserts. +message Key { + string cluster_name = 1; + string host = 2; + string path = 3; + string query = 4; + // True for http://, false for https://. + bool clear_http = 5; + // Cache implementations can store arbitrary content in these fields; never set by cache filter. + repeated bytes custom_fields = 6; + repeated int64 custom_ints = 7; +}; diff --git a/test/extensions/filters/http/cache/BUILD b/test/extensions/filters/http/cache/BUILD index 449518f7ba..cc18f260aa 100644 --- a/test/extensions/filters/http/cache/BUILD +++ b/test/extensions/filters/http/cache/BUILD @@ -15,3 +15,14 @@ envoy_cc_test( "//test/test_common:utility_lib", ], ) + +envoy_cc_test( + name = "http_cache_test", + srcs = ["http_cache_test.cc"], + deps = [ + "//source/extensions/filters/http/cache:http_cache_lib", + "//test/mocks/http:http_mocks", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:utility_lib", + ], +) diff --git a/test/extensions/filters/http/cache/http_cache_test.cc b/test/extensions/filters/http/cache/http_cache_test.cc new file mode 100644 index 0000000000..5eee698cf0 --- /dev/null +++ b/test/extensions/filters/http/cache/http_cache_test.cc @@ -0,0 +1,256 @@ +#include "extensions/filters/http/cache/http_cache.h" + +#include "test/mocks/http/mocks.h" +#include "test/test_common/simulated_time_system.h" +#include "test/test_common/utility.h" + +#include "gtest/gtest.h" + +using testing::ContainerEq; +using testing::TestWithParam; +using testing::ValuesIn; + +namespace Envoy { +namespace Extensions { +namespace HttpFilters { +namespace Cache { +TEST(RawByteRangeTest, IsSuffix) { + auto r = RawByteRange(UINT64_MAX, 4); + ASSERT_TRUE(r.isSuffix()); +} + +TEST(RawByteRangeTest, IsNotSuffix) { + auto r = RawByteRange(3, 4); + ASSERT_FALSE(r.isSuffix()); +} + +TEST(RawByteRangeTest, FirstBytePos) { + auto r = RawByteRange(3, 4); + ASSERT_EQ(3, r.firstBytePos()); +} + +TEST(RawByteRangeTest, LastBytePos) { + auto r = RawByteRange(3, 4); + ASSERT_EQ(4, r.lastBytePos()); +} + +TEST(RawByteRangeTest, SuffixLength) { + auto r = RawByteRange(UINT64_MAX, 4); + ASSERT_EQ(4, r.suffixLength()); +} + +TEST(AdjustedByteRangeTest, Length) { + auto a = AdjustedByteRange(3, 6); + ASSERT_EQ(3, a.length()); +} + +TEST(AdjustedByteRangeTest, TrimFront) { + auto a = AdjustedByteRange(3, 6); + a.trimFront(2); + ASSERT_EQ(5, a.begin()); +} + +TEST(AdjustedByteRangeTest, MaxLength) { + auto a = AdjustedByteRange(0, UINT64_MAX); + ASSERT_EQ(UINT64_MAX, a.length()); +} + +TEST(AdjustedByteRangeTest, MaxTrim) { + auto a = AdjustedByteRange(0, UINT64_MAX); + a.trimFront(UINT64_MAX); + ASSERT_EQ(0, a.length()); +} + +class LookupRequestTest : public testing::Test { +protected: + Event::SimulatedTimeSystem time_source_; + SystemTime current_time_ = time_source_.systemTime(); + DateFormatter formatter_{"%a, %d %b %Y %H:%M:%S GMT"}; + Http::TestHeaderMapImpl request_headers_{ + {":path", "/"}, {"x-forwarded-proto", "https"}, {":authority", "example.com"}}; +}; + +LookupResult makeLookupResult(const LookupRequest& lookup_request, + const Http::TestHeaderMapImpl& response_headers, + uint64_t content_length = 0) { + return lookup_request.makeLookupResult( + std::make_unique(response_headers), content_length); +} + +TEST_F(LookupRequestTest, MakeLookupResultNoBody) { + const LookupRequest lookup_request(request_headers_, current_time_); + const Http::TestHeaderMapImpl response_headers( + {{"date", formatter_.fromTime(current_time_)}, {"cache-control", "public, max-age=3600"}}); + const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); + ASSERT_EQ(CacheEntryStatus::Ok, lookup_response.cache_entry_status_); + ASSERT_TRUE(lookup_response.headers_); + EXPECT_THAT(*lookup_response.headers_, Http::IsSupersetOfHeaders(response_headers)); + EXPECT_EQ(lookup_response.content_length_, 0); + EXPECT_TRUE(lookup_response.response_ranges_.empty()); + EXPECT_FALSE(lookup_response.has_trailers_); +} + +TEST_F(LookupRequestTest, MakeLookupResultBody) { + const LookupRequest lookup_request(request_headers_, current_time_); + const Http::TestHeaderMapImpl response_headers( + {{"date", formatter_.fromTime(current_time_)}, {"cache-control", "public, max-age=3600"}}); + const uint64_t content_length = 5; + const LookupResult lookup_response = + makeLookupResult(lookup_request, response_headers, content_length); + ASSERT_EQ(CacheEntryStatus::Ok, lookup_response.cache_entry_status_); + ASSERT_TRUE(lookup_response.headers_); + EXPECT_THAT(*lookup_response.headers_, Http::IsSupersetOfHeaders(response_headers)); + EXPECT_EQ(lookup_response.content_length_, content_length); + EXPECT_TRUE(lookup_response.response_ranges_.empty()); + EXPECT_FALSE(lookup_response.has_trailers_); +} + +TEST_F(LookupRequestTest, MakeLookupResultNoDate) { + const LookupRequest lookup_request(request_headers_, current_time_); + const Http::TestHeaderMapImpl response_headers({{"cache-control", "public, max-age=3600"}}); + const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); + EXPECT_EQ(CacheEntryStatus::RequiresValidation, lookup_response.cache_entry_status_); + ASSERT_TRUE(lookup_response.headers_); + EXPECT_THAT(*lookup_response.headers_, Http::IsSupersetOfHeaders(response_headers)); + EXPECT_EQ(lookup_response.content_length_, 0); + EXPECT_TRUE(lookup_response.response_ranges_.empty()); + EXPECT_FALSE(lookup_response.has_trailers_); +} + +TEST_F(LookupRequestTest, PrivateResponse) { + const LookupRequest lookup_request(request_headers_, current_time_); + const Http::TestHeaderMapImpl response_headers({{"age", "2"}, + {"cache-control", "private, max-age=3600"}, + {"date", formatter_.fromTime(current_time_)}}); + const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); + + // We must make sure at cache insertion time, private responses must not be + // inserted. However, if the insertion did happen, it would be served at the + // time of lookup. (Nothing should rely on this.) + ASSERT_EQ(CacheEntryStatus::Ok, lookup_response.cache_entry_status_); + ASSERT_TRUE(lookup_response.headers_); + EXPECT_THAT(*lookup_response.headers_, Http::IsSupersetOfHeaders(response_headers)); + EXPECT_EQ(lookup_response.content_length_, 0); + EXPECT_TRUE(lookup_response.response_ranges_.empty()); + EXPECT_FALSE(lookup_response.has_trailers_); +} + +TEST_F(LookupRequestTest, Expired) { + const LookupRequest lookup_request(request_headers_, current_time_); + const Http::TestHeaderMapImpl response_headers( + {{"cache-control", "public, max-age=3600"}, {"date", "Thu, 01 Jan 2019 00:00:00 GMT"}}); + const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); + + EXPECT_EQ(CacheEntryStatus::RequiresValidation, lookup_response.cache_entry_status_); + ASSERT_TRUE(lookup_response.headers_); + EXPECT_THAT(*lookup_response.headers_, Http::IsSupersetOfHeaders(response_headers)); + EXPECT_EQ(lookup_response.content_length_, 0); + EXPECT_TRUE(lookup_response.response_ranges_.empty()); + EXPECT_FALSE(lookup_response.has_trailers_); +} + +TEST_F(LookupRequestTest, ExpiredViaFallbackheader) { + const LookupRequest lookup_request(request_headers_, current_time_); + const Http::TestHeaderMapImpl response_headers( + {{"expires", formatter_.fromTime(current_time_ - std::chrono::seconds(5))}, + {"date", formatter_.fromTime(current_time_)}}); + const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); + + EXPECT_EQ(CacheEntryStatus::RequiresValidation, lookup_response.cache_entry_status_); +} + +TEST_F(LookupRequestTest, NotExpiredViaFallbackheader) { + const LookupRequest lookup_request(request_headers_, current_time_); + const Http::TestHeaderMapImpl response_headers( + {{"expires", formatter_.fromTime(current_time_ + std::chrono::seconds(5))}, + {"date", formatter_.fromTime(current_time_)}}); + const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); + EXPECT_EQ(CacheEntryStatus::Ok, lookup_response.cache_entry_status_); +} + +TEST_F(LookupRequestTest, FullRange) { + request_headers_.addCopy("Range", "0-99"); + const LookupRequest lookup_request(request_headers_, current_time_); + const Http::TestHeaderMapImpl response_headers({{"date", formatter_.fromTime(current_time_)}, + {"cache-control", "public, max-age=3600"}, + {"content-length", "4"}}); + const uint64_t content_length = 4; + const LookupResult lookup_response = + makeLookupResult(lookup_request, response_headers, content_length); + ASSERT_EQ(CacheEntryStatus::Ok, lookup_response.cache_entry_status_); + ASSERT_TRUE(lookup_response.headers_); + EXPECT_THAT(*lookup_response.headers_, Http::IsSupersetOfHeaders(response_headers)); + EXPECT_EQ(lookup_response.content_length_, 4); + EXPECT_TRUE(lookup_response.response_ranges_.empty()); + EXPECT_FALSE(lookup_response.has_trailers_); +} + +struct AdjustByteRangeParams { + std::vector request; + std::vector result; + uint64_t content_length; +}; + +AdjustByteRangeParams satisfiable_ranges[] = + // request, result, content_length + { + // Various ways to request the full body. Full responses are signaled by empty result + // vectors. + {{{0, 3}}, {}, 4}, // byte-range-spec, exact + {{{UINT64_MAX, 4}}, {}, 4}, // suffix-byte-range-spec, exact + {{{0, 99}}, {}, 4}, // byte-range-spec, overlong + {{{0, UINT64_MAX}}, {}, 4}, // byte-range-spec, overlong + {{{UINT64_MAX, 5}}, {}, 4}, // suffix-byte-range-spec, overlong + {{{UINT64_MAX, UINT64_MAX - 1}}, {}, 4}, // suffix-byte-range-spec, overlong + {{{UINT64_MAX, UINT64_MAX}}, {}, 4}, // suffix-byte-range-spec, overlong + + // Single bytes + {{{0, 0}}, {{0, 1}}, 4}, + {{{1, 1}}, {{1, 2}}, 4}, + {{{3, 3}}, {{3, 4}}, 4}, + {{{UINT64_MAX, 1}}, {{3, 4}}, 4}, + + // Multiple bytes, starting in the middle + {{{1, 2}}, {{1, 3}}, 4}, // fully in the middle + {{{1, 3}}, {{1, 4}}, 4}, // to the end + {{{2, 21}}, {{2, 4}}, 4}, // overlong + {{{1, UINT64_MAX}}, {{1, 4}}, 4}}; // overlong +// TODO(toddmgreer): Before enabling support for multi-range requests, test it. + +class AdjustByteRangeTest : public TestWithParam {}; + +TEST_P(AdjustByteRangeTest, All) { + std::vector result; + ASSERT_TRUE(adjustByteRangeSet(result, GetParam().request, GetParam().content_length)); + EXPECT_THAT(result, ContainerEq(GetParam().result)); +} + +INSTANTIATE_TEST_SUITE_P(AdjustByteRangeTest, AdjustByteRangeTest, ValuesIn(satisfiable_ranges)); + +class AdjustByteRangeUnsatisfiableTest : public TestWithParam> {}; + +std::vector unsatisfiable_ranges[] = { + {{4, 5}}, + {{4, 9}}, + {{7, UINT64_MAX}}, + {{UINT64_MAX, 0}}, +}; + +TEST_P(AdjustByteRangeUnsatisfiableTest, All) { + std::vector result; + ASSERT_FALSE(adjustByteRangeSet(result, GetParam(), 3)); +} + +INSTANTIATE_TEST_SUITE_P(AdjustByteRangeUnsatisfiableTest, AdjustByteRangeUnsatisfiableTest, + ValuesIn(unsatisfiable_ranges)); + +TEST(AdjustByteRange, NoRangeRequest) { + std::vector result; + ASSERT_TRUE(adjustByteRangeSet(result, {}, 8)); + EXPECT_THAT(result, ContainerEq(std::vector{})); +} + +} // namespace Cache +} // namespace HttpFilters +} // namespace Extensions +} // namespace Envoy diff --git a/tools/spelling_dictionary.txt b/tools/spelling_dictionary.txt index 7a6919881a..c7b0ed68c9 100644 --- a/tools/spelling_dictionary.txt +++ b/tools/spelling_dictionary.txt @@ -219,6 +219,7 @@ PostCBs PREBIND PRNG PROT +Prereq QUIC QoS RAII @@ -484,6 +485,8 @@ deallocated deallocating deallocation dec +dechunk +dechunked dechunking decl decls @@ -950,6 +953,7 @@ rxhash sandboxed sanitization sanitizer +satisfiable scalability sched schemas @@ -1130,6 +1134,7 @@ unreferenced unregister unregisters unresolvable +unsatisfiable unserializable unsetenv unsubscription From 9105aead0f5c89419bd2aca789b3738967c0baa1 Mon Sep 17 00:00:00 2001 From: Jose Ulises Nino Rivera Date: Fri, 7 Feb 2020 17:38:11 -0800 Subject: [PATCH 32/87] api listener: add shutdown method and call during server termination (#9959) Description: this PR adds a shutdown method to the ApiListener and calls it where appropriate during server termination. Previously there would be a crash due to use after free of objects in thread local storage by streams in the ApiListener. Funny enough the flakes reported in #9746 happened due to this. Risk Level: low Testing: new unit and integration test. Without appropriate termination the new integration test repros the stacktrace reported in #9746. Signed-off-by: Jose Nino --- include/envoy/server/api_listener.h | 7 +++ source/server/api_listener_impl.cc | 14 ++++++ source/server/api_listener_impl.h | 10 +++- source/server/server.cc | 7 +++ .../api_listener_integration_test.cc | 32 ++++++++++++- test/server/BUILD | 1 + test/server/api_listener_test.cc | 46 ++++++++++++++++++- 7 files changed, 113 insertions(+), 4 deletions(-) diff --git a/include/envoy/server/api_listener.h b/include/envoy/server/api_listener.h index da5937f5d6..d07dd2ec8f 100644 --- a/include/envoy/server/api_listener.h +++ b/include/envoy/server/api_listener.h @@ -21,6 +21,13 @@ class ApiListener { */ virtual absl::string_view name() const PURE; + /** + * Shutdown the ApiListener. This is an interrupt, not a drain. In other words, calling this + * function results in termination of all active streams vs. draining where no new streams are + * allowed, but already existing streams are allowed to finish. + */ + virtual void shutdown() PURE; + /** * @return the Type of the ApiListener. */ diff --git a/source/server/api_listener_impl.cc b/source/server/api_listener_impl.cc index f990254683..107afabcad 100644 --- a/source/server/api_listener_impl.cc +++ b/source/server/api_listener_impl.cc @@ -25,6 +25,13 @@ ApiListenerImplBase::ApiListenerImplBase(const envoy::config::listener::v3::List factory_context_(parent_.server_, config_, *this, *global_scope_, *listener_scope_), read_callbacks_(SyntheticReadCallbacks(*this)) {} +void ApiListenerImplBase::SyntheticReadCallbacks::SyntheticConnection::raiseConnectionEvent( + Network::ConnectionEvent event) { + for (Network::ConnectionCallbacks* callback : callbacks_) { + callback->onEvent(event); + } +} + HttpApiListener::HttpApiListener(const envoy::config::listener::v3::Listener& config, ListenerManagerImpl& parent, const std::string& name) : ApiListenerImplBase(config, parent, name) { @@ -44,5 +51,12 @@ Http::ApiListenerOptRef HttpApiListener::http() { return Http::ApiListenerOptRef(std::ref(*http_connection_manager_)); } +void HttpApiListener::shutdown() { + // The Http::ConnectionManagerImpl is a callback target for the read_callback_.connection_. By + // raising connection closure, Http::ConnectionManagerImpl::onEvent is fired. In that case the + // Http::ConnectionManagerImpl will reset any ActiveStreams it has. + read_callbacks_.connection_.raiseConnectionEvent(Network::ConnectionEvent::RemoteClose); +} + } // namespace Server } // namespace Envoy diff --git a/source/server/api_listener_impl.h b/source/server/api_listener_impl.h index 3b5dfdcded..9227f21810 100644 --- a/source/server/api_listener_impl.h +++ b/source/server/api_listener_impl.h @@ -75,6 +75,8 @@ class ApiListenerImplBase : public ApiListener, : parent_(parent), stream_info_(parent_.parent_.factory_context_.timeSource()), options_(std::make_shared>()) {} + void raiseConnectionEvent(Network::ConnectionEvent event); + // Network::FilterManager void addWriteFilter(Network::WriteFilterSharedPtr) override { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; @@ -84,7 +86,9 @@ class ApiListenerImplBase : public ApiListener, bool initializeReadFilters() override { return true; } // Network::Connection - void addConnectionCallbacks(Network::ConnectionCallbacks&) override {} + void addConnectionCallbacks(Network::ConnectionCallbacks& cb) override { + callbacks_.push_back(&cb); + } void addBytesSentCallback(Network::Connection::BytesSentCb) override { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } @@ -129,6 +133,7 @@ class ApiListenerImplBase : public ApiListener, SyntheticReadCallbacks& parent_; StreamInfo::StreamInfoImpl stream_info_; Network::ConnectionSocket::OptionsSharedPtr options_; + std::list callbacks_; }; ApiListenerImplBase& parent_; @@ -157,6 +162,9 @@ class HttpApiListener : public ApiListenerImplBase { // ApiListener ApiListener::Type type() const override { return ApiListener::Type::HttpApiListener; } Http::ApiListenerOptRef http() override; + void shutdown() override; + + Network::ReadFilterCallbacks& readCallbacksForTest() { return read_callbacks_; } private: // Need to store the factory due to the shared_ptrs that need to be kept alive: date provider, diff --git a/source/server/server.cc b/source/server/server.cc index 32d38f7916..024e7c5d23 100644 --- a/source/server/server.cc +++ b/source/server/server.cc @@ -578,6 +578,13 @@ void InstanceImpl::terminate() { // Shutdown all the workers now that the main dispatch loop is done. if (listener_manager_ != nullptr) { + // Also shutdown the listener manager's ApiListener, if there is one, which runs on the main + // thread. This needs to happen ahead of calling thread_local_.shutdown() below to prevent any + // objects in the ApiListener destructor to reference any objects in thread local storage. + if (listener_manager_->apiListener().has_value()) { + listener_manager_->apiListener()->get().shutdown(); + } + listener_manager_->stopWorkers(); } diff --git a/test/integration/api_listener_integration_test.cc b/test/integration/api_listener_integration_test.cc index ee1e2d672d..1a9e04ef07 100644 --- a/test/integration/api_listener_integration_test.cc +++ b/test/integration/api_listener_integration_test.cc @@ -30,7 +30,6 @@ class ApiListenerIntegrationTest : public BaseIntegrationTest, bootstrap.mutable_static_resources()->add_listeners()->MergeFrom( Server::parseListenerFromV2Yaml(api_listener_config())); }); - BaseIntegrationTest::initialize(); } void TearDown() override { @@ -84,6 +83,7 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, ApiListenerIntegrationTest, TestUtility::ipTestParamsToString); TEST_P(ApiListenerIntegrationTest, Basic) { + BaseIntegrationTest::initialize(); absl::Notification done; test_server_->server().dispatcher().post([this, &done]() -> void { ASSERT_TRUE(test_server_->server().listenerManager().apiListener().has_value()); @@ -111,5 +111,33 @@ TEST_P(ApiListenerIntegrationTest, Basic) { ASSERT_TRUE(done.WaitForNotificationWithTimeout(absl::Seconds(1))); } +TEST_P(ApiListenerIntegrationTest, DestroyWithActiveStreams) { + autonomous_allow_incomplete_streams_ = true; + BaseIntegrationTest::initialize(); + absl::Notification done; + + test_server_->server().dispatcher().post([this, &done]() -> void { + ASSERT_TRUE(test_server_->server().listenerManager().apiListener().has_value()); + ASSERT_EQ("api_listener", test_server_->server().listenerManager().apiListener()->get().name()); + ASSERT_TRUE(test_server_->server().listenerManager().apiListener()->get().http().has_value()); + auto& http_api_listener = + test_server_->server().listenerManager().apiListener()->get().http()->get(); + + ON_CALL(stream_encoder_, getStream()).WillByDefault(ReturnRef(stream_encoder_.stream_)); + auto& stream_decoder = http_api_listener.newStream(stream_encoder_); + + // Send a headers-only request + stream_decoder.decodeHeaders( + Http::HeaderMapPtr(new Http::TestHeaderMapImpl{ + {":method", "GET"}, {":path", "/api"}, {":scheme", "http"}, {":authority", "host"}}), + false); + + done.Notify(); + }); + ASSERT_TRUE(done.WaitForNotificationWithTimeout(absl::Seconds(1))); + // The server should shutdown the ApiListener at the right time during server termination such + // that no crashes occur if termination happens when the ApiListener still has ongoing streams. +} + } // namespace -} // namespace Envoy \ No newline at end of file +} // namespace Envoy diff --git a/test/server/BUILD b/test/server/BUILD index 400c4b80fa..358ec82456 100644 --- a/test/server/BUILD +++ b/test/server/BUILD @@ -23,6 +23,7 @@ envoy_cc_test( ":utility_lib", "//source/server:api_listener_lib", "//source/server:listener_lib", + "//test/mocks/network:network_mocks", "//test/mocks/server:server_mocks", "//test/test_common:utility_lib", "@envoy_api//envoy/config/listener/v3:pkg_cc_proto", diff --git a/test/server/api_listener_test.cc b/test/server/api_listener_test.cc index ccf9c643ee..f229823c59 100644 --- a/test/server/api_listener_test.cc +++ b/test/server/api_listener_test.cc @@ -5,6 +5,7 @@ #include "server/api_listener_impl.h" #include "server/listener_manager_impl.h" +#include "test/mocks/network/mocks.h" #include "test/mocks/server/mocks.h" #include "test/server/utility.h" #include "test/test_common/utility.h" @@ -87,5 +88,48 @@ name: test_api_listener "eds_cluster_config {\n eds_config {\n path: \"eds path\"\n }\n }\n}\n"); } +TEST_F(ApiListenerTest, HttpApiListenerShutdown) { + const std::string yaml = R"EOF( +name: test_api_listener +address: + socket_address: + address: 127.0.0.1 + port_value: 1234 +api_listener: + api_listener: + "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager + stat_prefix: hcm + route_config: + name: api_router + virtual_hosts: + - name: api + domains: + - "*" + routes: + - match: + prefix: "/" + route: + cluster: dynamic_forward_proxy_cluster + )EOF"; + + const envoy::config::listener::v3::Listener config = parseListenerFromV2Yaml(yaml); + + auto http_api_listener = HttpApiListener(config, *listener_manager_, config.name()); + + ASSERT_EQ("test_api_listener", http_api_listener.name()); + ASSERT_EQ(ApiListener::Type::HttpApiListener, http_api_listener.type()); + ASSERT_TRUE(http_api_listener.http().has_value()); + + Network::MockConnectionCallbacks network_connection_callbacks; + // TODO(junr03): potentially figure out a way of unit testing this behavior without exposing a + // ForTest function. + http_api_listener.readCallbacksForTest().connection().addConnectionCallbacks( + network_connection_callbacks); + + EXPECT_CALL(network_connection_callbacks, onEvent(Network::ConnectionEvent::RemoteClose)); + // Shutting down the ApiListener should raise an event on all connection callback targets. + http_api_listener.shutdown(); +} + } // namespace Server -} // namespace Envoy \ No newline at end of file +} // namespace Envoy From d1db56424d39f10715f81d17d80079a22040abbf Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Sun, 9 Feb 2020 11:47:41 -0800 Subject: [PATCH 33/87] wasm: support precompiled modules in V8-based runtime. (#9691) Signed-off-by: Piotr Sikora --- bazel/external/wee8.BUILD | 6 +- source/extensions/common/wasm/null/null_vm.cc | 5 + source/extensions/common/wasm/null/null_vm.h | 1 + source/extensions/common/wasm/v8/v8.cc | 124 +++++++-- source/extensions/common/wasm/wasm_vm.h | 6 + .../common/wasm/test_data/test_rust.rs | 4 + .../common/wasm/test_data/test_rust.wasm | Bin 1068 -> 5546 bytes test/extensions/common/wasm/wasm_vm_test.cc | 38 ++- test/tools/wee8_compile/BUILD | 21 ++ test/tools/wee8_compile/wee8_compile.cc | 239 ++++++++++++++++++ tools/spelling_dictionary.txt | 2 + 11 files changed, 416 insertions(+), 30 deletions(-) create mode 100644 test/tools/wee8_compile/BUILD create mode 100644 test/tools/wee8_compile/wee8_compile.cc diff --git a/bazel/external/wee8.BUILD b/bazel/external/wee8.BUILD index 4794b9e8f6..c6e64f43bc 100644 --- a/bazel/external/wee8.BUILD +++ b/bazel/external/wee8.BUILD @@ -8,9 +8,13 @@ cc_library( "libwee8.a", ], hdrs = [ + "wee8/include/v8-version.h", "wee8/third_party/wasm-api/wasm.hh", ], - includes = ["wee8/third_party"], + includes = [ + "wee8/include", + "wee8/third_party", + ], visibility = ["//visibility:public"], ) diff --git a/source/extensions/common/wasm/null/null_vm.cc b/source/extensions/common/wasm/null/null_vm.cc index d2cb16b994..abd4418fc7 100644 --- a/source/extensions/common/wasm/null/null_vm.cc +++ b/source/extensions/common/wasm/null/null_vm.cc @@ -82,6 +82,11 @@ absl::string_view NullVm::getCustomSection(absl::string_view /* name */) { return {}; } +absl::string_view NullVm::getPrecompiledSectionName() { + // Return nothing: there is no WASM file. + return {}; +} + } // namespace Null } // namespace Wasm } // namespace Common diff --git a/source/extensions/common/wasm/null/null_vm.h b/source/extensions/common/wasm/null/null_vm.h index 82da033019..e0cf345c51 100644 --- a/source/extensions/common/wasm/null/null_vm.h +++ b/source/extensions/common/wasm/null/null_vm.h @@ -38,6 +38,7 @@ struct NullVm : public WasmVmBase { bool setWord(uint64_t pointer, Word data) override; bool getWord(uint64_t pointer, Word* data) override; absl::string_view getCustomSection(absl::string_view name) override; + absl::string_view getPrecompiledSectionName() override; #define _FORWARD_GET_FUNCTION(_T) \ void getFunction(absl::string_view function_name, _T* f) override { \ diff --git a/source/extensions/common/wasm/v8/v8.cc b/source/extensions/common/wasm/v8/v8.cc index bd158874ba..5bd2c1f57b 100644 --- a/source/extensions/common/wasm/v8/v8.cc +++ b/source/extensions/common/wasm/v8/v8.cc @@ -11,6 +11,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/strings/match.h" +#include "v8-version.h" #include "wasm-api/wasm.hh" namespace Envoy { @@ -43,6 +44,7 @@ class V8 : public WasmVmBase { bool load(const std::string& code, bool allow_precompiled) override; absl::string_view getCustomSection(absl::string_view name) override; + absl::string_view getPrecompiledSectionName() override; void link(absl::string_view debug_name) override; Cloneable cloneable() override { return Cloneable::CompiledBytecode; } @@ -70,6 +72,8 @@ class V8 : public WasmVmBase { #undef _GET_MODULE_FUNCTION private: + wasm::vec getStrippedSource(); + template void registerHostFunctionImpl(absl::string_view module_name, absl::string_view function_name, void (*function)(void*, Args...)); @@ -239,14 +243,46 @@ template constexpr T convertValTypesToArgsTuple(const U // V8 implementation. -bool V8::load(const std::string& code, bool /* allow_precompiled */) { +bool V8::load(const std::string& code, bool allow_precompiled) { ENVOY_LOG(trace, "load()"); store_ = wasm::Store::make(engine()); + // Wasm file header is 8 bytes (magic number + version). + static const uint8_t magic_number[4] = {0x00, 0x61, 0x73, 0x6d}; + if (code.size() < 8 || ::memcmp(code.data(), magic_number, 4) != 0) { + return false; + } + source_ = wasm::vec::make_uninitialized(code.size()); ::memcpy(source_.get(), code.data(), code.size()); - module_ = wasm::Module::make(store_.get(), source_); + if (allow_precompiled) { + const auto section_name = getPrecompiledSectionName(); + if (!section_name.empty()) { + const auto precompiled = getCustomSection(section_name); + if (!precompiled.empty()) { + auto vec = wasm::vec::make_uninitialized(precompiled.size()); + ::memcpy(vec.get(), precompiled.data(), precompiled.size()); + + // TODO(PiotrSikora): fuzz loading of precompiled Wasm modules. + // See: https://github.com/envoyproxy/envoy/issues/9731 + module_ = wasm::Module::deserialize(store_.get(), vec); + if (!module_) { + // Precompiled module that cannot be loaded is considered a hard error, + // so don't fallback to compiling the bytecode. + return false; + } + } + } + } + + if (!module_) { + // TODO(PiotrSikora): fuzz loading of Wasm modules. + // See: https://github.com/envoyproxy/envoy/issues/9731 + const auto stripped_source = getStrippedSource(); + module_ = wasm::Module::make(store_.get(), stripped_source ? stripped_source : source_); + } + if (module_) { shared_module_ = module_->share(); } @@ -266,39 +302,95 @@ WasmVmPtr V8::clone() { return clone; } +// Get Wasm module without Custom Sections to save some memory in workers. +wasm::vec V8::getStrippedSource() { + ENVOY_LOG(trace, "getStrippedSource()"); + ASSERT(source_.get() != nullptr); + + std::vector stripped; + + const byte_t* pos = source_.get() + 8 /* Wasm header */; + const byte_t* end = source_.get() + source_.size(); + while (pos < end) { + const auto section_start = pos; + if (pos + 1 > end) { + return wasm::vec::invalid(); + } + const auto section_type = *pos++; + const auto section_len = parseVarint(pos, end); + if (section_len == static_cast(-1) || pos + section_len > end) { + return wasm::vec::invalid(); + } + pos += section_len; + if (section_type == 0 /* custom section */) { + if (stripped.empty()) { + const byte_t* start = source_.get(); + stripped.insert(stripped.end(), start, section_start); + } + } else if (!stripped.empty()) { + stripped.insert(stripped.end(), section_start, pos /* section end */); + } + } + + // No custom sections found, use the original source. + if (stripped.empty()) { + return wasm::vec::invalid(); + } + + // Return stripped source, without custom sections. + return wasm::vec::make(stripped.size(), stripped.data()); +} + absl::string_view V8::getCustomSection(absl::string_view name) { ENVOY_LOG(trace, "getCustomSection(\"{}\")", name); ASSERT(source_.get() != nullptr); + const byte_t* pos = source_.get() + 8 /* Wasm header */; const byte_t* end = source_.get() + source_.size(); - const byte_t* pos = source_.get() + 8; // skip header while (pos < end) { if (pos + 1 > end) { throw WasmVmException("Failed to parse corrupted WASM module"); } - auto type = *pos++; - auto rest = parseVarint(pos, end); - if (pos + rest > end) { + const auto section_type = *pos++; + const auto section_len = parseVarint(pos, end); + if (section_len == static_cast(-1) || pos + section_len > end) { throw WasmVmException("Failed to parse corrupted WASM module"); } - if (type == 0 /* custom section */) { - auto start = pos; - auto len = parseVarint(pos, end); - if (pos + len > end) { + if (section_type == 0 /* custom section */) { + const auto section_data_start = pos; + const auto section_name_len = parseVarint(pos, end); + if (section_name_len == static_cast(-1) || pos + section_name_len > end) { throw WasmVmException("Failed to parse corrupted WASM module"); } - pos += len; - rest -= (pos - start); - if (len == name.size() && ::memcmp(pos - len, name.data(), len) == 0) { - ENVOY_LOG(trace, "getCustomSection(\"{}\") found, size: {}", name, rest); - return {pos, rest}; + if (section_name_len == name.size() && ::memcmp(pos, name.data(), section_name_len) == 0) { + pos += section_name_len; + ENVOY_LOG(trace, "getCustomSection(\"{}\") found, size: {}", name, + section_data_start + section_len - pos); + return {pos, static_cast(section_data_start + section_len - pos)}; } + pos = section_data_start + section_len; + } else { + pos += section_len; } - pos += rest; } return ""; } +#if defined(__linux__) && defined(__x86_64__) +#define WEE8_WASM_PRECOMPILE_PLATFORM "linux_x86_64" +#endif + +absl::string_view V8::getPrecompiledSectionName() { +#ifndef WEE8_WASM_PRECOMPILE_PLATFORM + return ""; +#else + static const auto name = + absl::StrCat("precompiled_v8_v", V8_MAJOR_VERSION, ".", V8_MINOR_VERSION, ".", + V8_BUILD_NUMBER, ".", V8_PATCH_LEVEL, "_", WEE8_WASM_PRECOMPILE_PLATFORM); + return name; +#endif +} + void V8::link(absl::string_view debug_name) { ENVOY_LOG(trace, "link(\"{}\")", debug_name); ASSERT(module_ != nullptr); diff --git a/source/extensions/common/wasm/wasm_vm.h b/source/extensions/common/wasm/wasm_vm.h index 95b43aee47..3506eaaa09 100644 --- a/source/extensions/common/wasm/wasm_vm.h +++ b/source/extensions/common/wasm/wasm_vm.h @@ -235,6 +235,12 @@ class WasmVm : public Logger::Loggable { */ virtual absl::string_view getCustomSection(absl::string_view name) PURE; + /** + * Get the name of the custom section that contains precompiled module. + * @return the name of the custom section that contains precompiled module. + */ + virtual absl::string_view getPrecompiledSectionName() PURE; + /** * Get typed function exported by the WASM module. */ diff --git a/test/extensions/common/wasm/test_data/test_rust.rs b/test/extensions/common/wasm/test_data/test_rust.rs index 304161e506..7509a6913d 100644 --- a/test/extensions/common/wasm/test_data/test_rust.rs +++ b/test/extensions/common/wasm/test_data/test_rust.rs @@ -1,5 +1,9 @@ +// TODO(PiotrSikora): build test data with Bazel rules. +// See: https://github.com/envoyproxy/envoy/issues/9733 +// // Build using: // $ rustc -C lto -C opt-level=3 -C panic=abort -C link-arg=-S -C link-arg=-zstack-size=32768 --crate-type cdylib --target wasm32-unknown-unknown test_rust.rs +// $ ../../../../../bazel-bin/test/tools/wee8_compile/wee8_compile_tool test_rust.wasm test_rust.wasm // Import functions exported from the host environment. extern "C" { diff --git a/test/extensions/common/wasm/test_data/test_rust.wasm b/test/extensions/common/wasm/test_data/test_rust.wasm index e7b1ce902a1b2870a23fd05ae63d89a101760051..6af3c924447fee846b852a9347cdfeda4f2786d5 100755 GIT binary patch literal 5546 zcmeGfZEO_Bb!PT#pV>2e;)1dHD2q*msfCU0!)G`ev0$4uoT2%!TQxFwYu`d`>^ti| zC{7dZ$T^NKizBP*M}G7N>Yu9WkE&JGI4!D3P~%pq)HG6CH)$fLD(X4VmI$I0NJZb< zojIFp)$~7L3ogf6e>KqJ)-LOBt$V zvrNtq?Z(+6s?go#W9C>qF~P{Ha5!qDjIbGtN>mPqzib-g;Xxy5O3XDr4Ep4<(e%*C z3F48G=`m6zMTbw3)n&$DJdq+wrJE9s%B;e@YC&495N-bKvsvQJWwTjAJeEZFl-A)!5-G9ByFOaIlVPnGi0Z zvUZ09BJ^+-@#Y=1pt+mUOg&JbOg&jAZMD0qwBHqwyntwcxl~C76&nGOc2)yO(rQN9 z8G#=2KIg3T$kH<2lXZ+Q!*HTUWjN8TGH@{LsvTBj8Vta;yi?BfF0h~P0;W?w9qjOI zfyoWb?R^0S*Q-=z+nGBcxt$&fNJOQ=i;T!sWdF-I-d(u!yUBC!6B(jSWR1bAoyo#vA3sjcKGV!9Xfzgd@s*(|vjmQt<611xd_$rMlvUc9~eXVu@ zu~@2-c%O9^l_wb^b~+U(B@Q5F@C_NGqh?f%934*$$76f;q+?%67~>7wBWgUR8fxT7 zJZ47JQ^si8B%v%JJupXsuK~X1L^_!oYTjkG7=hipJN&JKM!OmH8@mGL?v~>LV{o^> zZP#vpz~9k&JP_?@P9}z$M~4T8;t8{P%os|{4Gs8)rO*lYU|F{ojZ26>}U;aCts`I zHl8qt;$!2(;KJ~!4)|-@+2n6+Z)#}`j}FJur^BZ^+QaSs*DJ__3gXm<2NmQ&1^K_N zASvm+i1$WsDL{|R%wVO*@6Iy7 z5dls8>wVkRT^rWnD$wcb~D@Vo328u*y@&M>)6-X?Fr z-vsyZWj^6ejs;zci${~sTgBzq6csLYmc_Q@}KpjEXf9Vtj*WadpqAh=* zpSwooMsPcPuX6`(;n-6`3%v51he0#PapbF zw_q%IQ^}=ZFl2RZc0*nlbPVc%z3K-QAq=4&yrty2?FBqR9V6#QBJYuw7jwH3I;W;f zglhowbuBEmuN11KLvuetgN@jMtFAtDd>vG>t?>PjPSRh{RO5BJ;~azN$q++X4#*oY zn-Q=wBZ#O7x)fujK~U{><)#=#bOBm|z@u;Xg>u!VmNp^iQhZ;^X9G{I`{V~}Y7G1E z%*>!J+{Ah80PJ#5(IP>YVxfE=mluZMyP*_><@|ywgK=B?e_Ti#VFWV4hUJS4HoO1I zX)GNG5xXTs(4`oaAY|?K9^WFltB~OQJ<<#l@qT@7D|BYPu+C4h?7y-XdIhwe7b1MO z*w$RR2{%E3mmw@c@L2h|Vz z{;3a5dpErKjC9a&?~uev#(YM2$U#KVrC8Xaa=Dd|h~o4{Htnjl_q%k8abgwEfp73t zvK$M#6pNeaJeL#CHGE>0f=~`A1W$l7^}6-89^9r(?FB*m!H(|+yK@LSZEt;i-QM8r z`79hCyxLy50KMhM2lMaB+jw&H{D8O>@D{=oG_Y{xd(P7pqkb=GSAArp918r{=>y5Y zIVwLn2lEgfbr8XgA_%$^i%3LlsiiCvPU37E6`f)6xBpsT7q9>>dx@7M)PhqG?k%gD O`q%olyBno-8~+V0rl^4c literal 1068 zcmY*X%Wl(95S^Lp6t_1aUKCV7NVkPWBGl3cje!-n5(tT>Sg}i-7O1z`2tmL!IX& zGtl1-{=%`F?%dD}qj*BF&}?>tG-#TzD^NC@k4!LXwu8h7az;H4ESCo3&fWwnA{h_i zxajuwp;`*sQJjJ|?;>cFv>+D_ooW^Ir-NrXc+c}Z2apq_Oye@rHT%_2qdaF>PXv)k4{QKMkE1#eZrdr`!4vIG31 z5wmklaiX`kg6F5DVjI_cW!cjT73jr&oxm5a{Zps1FF@g+3s?fWrhu~!ZLs&+PJvV) z$Ap=9Ix}BCVqPbAnXHkwEG)pX!`m(PH8hBg^?Pg7AWz{A`ox-Ye6hrUdZ|BcQNkBB zCde0R%B#Njwg{G>zIQrpzNPb3~aTbZs=&x&BbWiz7{9%+3ytld}OqXoZ(aA6Qrpb zj#8CIir?{G*QoYHJuz{Vnj~$;<0R!_?)#D#bBb#__n&-ceiTRDamU07xq~3w9S6Gx zod-M(WtKW7NlbUOJ;9Q7?3~?L+q%5Au4;|V?MvGmX3JNb>l;^A*RQN@Zq { public: + WasmVmTest() : scope_(Stats::ScopeSharedPtr(stats_store.createScope("wasm."))) {} + void SetUp() override { g_host_functions = new MockHostFunctions(); } void TearDown() override { delete g_host_functions; } + +protected: + Stats::IsolatedStoreImpl stats_store; + Stats::ScopeSharedPtr scope_; }; -TEST_F(WasmVmTest, V8BadCode) { +INSTANTIATE_TEST_SUITE_P(AllowPrecompiled, WasmVmTest, testing::Values(false, true)); + +TEST_P(WasmVmTest, V8BadCode) { auto wasm_vm = createWasmVm("envoy.wasm.runtime.v8", scope_); ASSERT_TRUE(wasm_vm != nullptr); - EXPECT_FALSE(wasm_vm->load("bad code", false)); + EXPECT_FALSE(wasm_vm->load("bad code", GetParam())); } -TEST_F(WasmVmTest, V8Code) { +TEST_P(WasmVmTest, V8Code) { auto wasm_vm = createWasmVm("envoy.wasm.runtime.v8", scope_); ASSERT_TRUE(wasm_vm != nullptr); EXPECT_TRUE(wasm_vm->runtime() == "envoy.wasm.runtime.v8"); auto code = TestEnvironment::readFileToStringForTest(TestEnvironment::substitute( "{{ test_rundir }}/test/extensions/common/wasm/test_data/test_rust.wasm")); - EXPECT_TRUE(wasm_vm->load(code, false)); + EXPECT_TRUE(wasm_vm->load(code, GetParam())); + // Sanity checks for the expected test file. + if (!wasm_vm->getPrecompiledSectionName().empty()) { + EXPECT_TRUE(!wasm_vm->getCustomSection(wasm_vm->getPrecompiledSectionName()).empty()); + } EXPECT_THAT(wasm_vm->getCustomSection("producers"), HasSubstr("rustc")); EXPECT_TRUE(wasm_vm->getCustomSection("emscripten_metadata").empty()); @@ -154,13 +166,13 @@ TEST_F(WasmVmTest, V8Code) { EXPECT_TRUE(wasm_vm->clone() != nullptr); } -TEST_F(WasmVmTest, V8BadHostFunctions) { +TEST_P(WasmVmTest, V8BadHostFunctions) { auto wasm_vm = createWasmVm("envoy.wasm.runtime.v8", scope_); ASSERT_TRUE(wasm_vm != nullptr); auto code = TestEnvironment::readFileToStringForTest(TestEnvironment::substitute( "{{ test_rundir }}/test/extensions/common/wasm/test_data/test_rust.wasm")); - EXPECT_TRUE(wasm_vm->load(code, false)); + EXPECT_TRUE(wasm_vm->load(code, GetParam())); wasm_vm->registerCallback("env", "random", &random, CONVERT_FUNCTION_WORD_TO_UINT32(random)); EXPECT_THROW_WITH_MESSAGE(wasm_vm->link("test"), WasmVmException, @@ -182,13 +194,13 @@ TEST_F(WasmVmTest, V8BadHostFunctions) { "want: i32 -> void, but host exports: f64 -> f64"); } -TEST_F(WasmVmTest, V8BadModuleFunctions) { +TEST_P(WasmVmTest, V8BadModuleFunctions) { auto wasm_vm = createWasmVm("envoy.wasm.runtime.v8", scope_); ASSERT_TRUE(wasm_vm != nullptr); auto code = TestEnvironment::readFileToStringForTest(TestEnvironment::substitute( "{{ test_rundir }}/test/extensions/common/wasm/test_data/test_rust.wasm")); - EXPECT_TRUE(wasm_vm->load(code, false)); + EXPECT_TRUE(wasm_vm->load(code, GetParam())); wasm_vm->registerCallback("env", "pong", &pong, CONVERT_FUNCTION_WORD_TO_UINT32(pong)); wasm_vm->registerCallback("env", "random", &random, CONVERT_FUNCTION_WORD_TO_UINT32(random)); @@ -210,13 +222,13 @@ TEST_F(WasmVmTest, V8BadModuleFunctions) { "Bad function signature for: sum"); } -TEST_F(WasmVmTest, V8FunctionCalls) { +TEST_P(WasmVmTest, V8FunctionCalls) { auto wasm_vm = createWasmVm("envoy.wasm.runtime.v8", scope_); ASSERT_TRUE(wasm_vm != nullptr); auto code = TestEnvironment::readFileToStringForTest(TestEnvironment::substitute( "{{ test_rundir }}/test/extensions/common/wasm/test_data/test_rust.wasm")); - EXPECT_TRUE(wasm_vm->load(code, false)); + EXPECT_TRUE(wasm_vm->load(code, GetParam())); wasm_vm->registerCallback("env", "pong", &pong, CONVERT_FUNCTION_WORD_TO_UINT32(pong)); wasm_vm->registerCallback("env", "random", &random, CONVERT_FUNCTION_WORD_TO_UINT32(random)); @@ -248,13 +260,13 @@ TEST_F(WasmVmTest, V8FunctionCalls) { "Function: abort failed: Uncaught RuntimeError: unreachable"); } -TEST_F(WasmVmTest, V8Memory) { +TEST_P(WasmVmTest, V8Memory) { auto wasm_vm = createWasmVm("envoy.wasm.runtime.v8", scope_); ASSERT_TRUE(wasm_vm != nullptr); auto code = TestEnvironment::readFileToStringForTest(TestEnvironment::substitute( "{{ test_rundir }}/test/extensions/common/wasm/test_data/test_rust.wasm")); - EXPECT_TRUE(wasm_vm->load(code, false)); + EXPECT_TRUE(wasm_vm->load(code, GetParam())); wasm_vm->registerCallback("env", "pong", &pong, CONVERT_FUNCTION_WORD_TO_UINT32(pong)); wasm_vm->registerCallback("env", "random", &random, CONVERT_FUNCTION_WORD_TO_UINT32(random)); diff --git a/test/tools/wee8_compile/BUILD b/test/tools/wee8_compile/BUILD new file mode 100644 index 0000000000..9c363c7d92 --- /dev/null +++ b/test/tools/wee8_compile/BUILD @@ -0,0 +1,21 @@ +licenses(["notice"]) # Apache 2 + +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_test_binary", + "envoy_cc_test_library", + "envoy_package", +) + +envoy_package() + +envoy_cc_test_binary( + name = "wee8_compile_tool", + deps = [":wee8_compile_lib"], +) + +envoy_cc_test_library( + name = "wee8_compile_lib", + srcs = ["wee8_compile.cc"], + external_deps = ["wee8"], +) diff --git a/test/tools/wee8_compile/wee8_compile.cc b/test/tools/wee8_compile/wee8_compile.cc new file mode 100644 index 0000000000..499311b541 --- /dev/null +++ b/test/tools/wee8_compile/wee8_compile.cc @@ -0,0 +1,239 @@ +/* + * A tool to precompile Wasm modules. + * + * This is accomplished by loading and instantiating the Wasm module, serializing + * the V8 Isolate containing compiled code, and saving it in Wasm module's Custom + * Section under the "precompiled_v8_v_" name. + * + * Such precompiled Wasm module can be deserialized and loaded by V8, without the + * need to compile Wasm bytecode each time it's loaded. + */ + +// NOLINT(namespace-envoy) + +#include + +#include +#include +#include +#include + +#include "v8-version.h" +#include "wasm-api/wasm.hh" + +uint32_t InvalidVarint = ~uint32_t{0}; + +uint32_t parseVarint(const byte_t** pos, const byte_t* end) { + uint32_t n = 0; + uint32_t shift = 0; + byte_t b; + + do { + if (*pos >= end) { + return InvalidVarint; + } + b = **pos; + (*pos)++; + n += (b & 0x7f) << shift; + shift += 7; + } while ((b & 0x80) != 0); + + return n; +} + +wasm::vec getVarint(uint32_t value) { + byte_t bytes[5]; + int pos = 0; + + while (value >= 0x80) { + bytes[pos++] = static_cast(0x80 | (value & 0x7f)); + value >>= 7; + } + bytes[pos++] = static_cast(value & 0x7f); + + auto vec = wasm::vec::make_uninitialized(pos); + ::memcpy(vec.get(), bytes, pos); + + return vec; +} + +wasm::vec readWasmModule(const char* path, const std::string& name) { + // Open binary file. + auto file = std::ifstream(path, std::ios::binary); + file.seekg(0, std::ios_base::end); + const auto size = file.tellg(); + file.seekg(0); + auto content = wasm::vec::make_uninitialized(size); + file.read(content.get(), size); + file.close(); + + if (file.fail()) { + std::cerr << "ERROR: Failed to read the input file from: " << path << std::endl; + return wasm::vec::invalid(); + } + + // Wasm header is 8 bytes (magic number + version). + const uint8_t magic_number[4] = {0x00, 0x61, 0x73, 0x6d}; + if (size < 8 || ::memcmp(content.get(), magic_number, 4) != 0) { + std::cerr << "ERROR: Failed to parse corrupted Wasm module from: " << path << std::endl; + return wasm::vec::invalid(); + } + + // Parse Custom Sections to see if precompiled module already exists. + const byte_t* pos = content.get() + 8 /* Wasm header */; + const byte_t* end = content.get() + content.size(); + while (pos < end) { + const byte_t section_type = *pos++; + const uint32_t section_len = parseVarint(&pos, end); + if (section_len == InvalidVarint || section_len > static_cast(end - pos)) { + std::cerr << "ERROR: Failed to parse corrupted Wasm module from: " << path << std::endl; + return wasm::vec::invalid(); + } + if (section_type == 0 /* Custom Section */) { + const byte_t* section_data_start = pos; + const uint32_t section_name_len = parseVarint(&pos, end); + if (section_name_len == InvalidVarint || section_name_len > static_cast(end - pos)) { + std::cerr << "ERROR: Failed to parse corrupted Wasm module from: " << path << std::endl; + return wasm::vec::invalid(); + } + if (section_name_len == name.size() && ::memcmp(pos, name.data(), section_name_len) == 0) { + std::cerr << "ERROR: Wasm module: " << path << " already contains precompiled module." + << std::endl; + return wasm::vec::invalid(); + } + pos = section_data_start + section_len; + } else { + pos += section_len; + } + } + + return content; +} + +wasm::vec stripWasmModule(const wasm::vec& module) { + std::vector stripped; + + const byte_t* pos = module.get(); + const byte_t* end = module.get() + module.size(); + + // Copy Wasm header. + stripped.insert(stripped.end(), pos, pos + 8); + pos += 8; + + while (pos < end) { + const byte_t* section_start = pos; + const byte_t section_type = *pos++; + const uint32_t section_len = parseVarint(&pos, end); + if (section_len == InvalidVarint || section_len > static_cast(end - pos)) { + std::cerr << "ERROR: Failed to parse corrupted Wasm module." << std::endl; + return wasm::vec::invalid(); + } + if (section_type != 0 /* Custom Section */) { + stripped.insert(stripped.end(), section_start, pos + section_len); + } + pos += section_len; + } + + return wasm::vec::make(stripped.size(), stripped.data()); +} + +wasm::vec serializeWasmModule(const char* path, const wasm::vec& content) { + const auto engine = wasm::Engine::make(); + if (engine == nullptr) { + std::cerr << "ERROR: Failed to start V8." << std::endl; + return wasm::vec::invalid(); + } + + const auto store = wasm::Store::make(engine.get()); + if (store == nullptr) { + std::cerr << "ERROR: Failed to create V8 isolate." << std::endl; + return wasm::vec::invalid(); + } + + const auto module = wasm::Module::make(store.get(), content); + if (module == nullptr) { + std::cerr << "ERROR: Failed to instantiate WebAssembly module from: " << path << std::endl; + return wasm::vec::invalid(); + } + + // TODO(PiotrSikora): figure out how to wait until the backgrounded (optimized) compilation is + // finished, or ideally, how to run the optimized synchronous compilation right away. + sleep(3); + + return module->serialize(); +} + +bool writeWasmModule(const char* path, const wasm::vec& module, size_t stripped_module_size, + const std::string& section_name, const wasm::vec& serialized) { + auto file = std::fstream(path, std::ios::out | std::ios::binary); + file.write(module.get(), module.size()); + const char section_type = '\0'; // Custom Section + file.write(§ion_type, 1); + const wasm::vec section_name_len = getVarint(static_cast(section_name.size())); + const wasm::vec section_size = getVarint( + static_cast(section_name_len.size() + section_name.size() + serialized.size())); + file.write(section_size.get(), section_size.size()); + file.write(section_name_len.get(), section_name_len.size()); + file.write(section_name.data(), section_name.size()); + file.write(serialized.get(), serialized.size()); + file.close(); + + if (file.fail()) { + std::cerr << "ERROR: Failed to write the output file to: " << path << std::endl; + return false; + } + + const size_t total_size = module.size() + 1 + section_size.size() + section_name_len.size() + + section_name.size() + serialized.size(); + std::cout << "Written " << total_size << " bytes (bytecode: " << stripped_module_size << " bytes," + << " precompiled: " << serialized.size() << " bytes)." << std::endl; + return true; +} + +#if defined(__linux__) && defined(__x86_64__) +#define WEE8_WASM_PRECOMPILE_PLATFORM "linux_x86_64" +#endif + +#ifndef WEE8_WASM_PRECOMPILE_PLATFORM + +int main(int, char**) { + std::cerr << "Unsupported platform." << std::endl; + return EXIT_FAILURE; +} + +#else + +int main(int argc, char* argv[]) { + if (argc != 3) { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + return EXIT_FAILURE; + } + + const std::string section_name = + "precompiled_v8_v" + std::to_string(V8_MAJOR_VERSION) + "." + + std::to_string(V8_MINOR_VERSION) + "." + std::to_string(V8_BUILD_NUMBER) + "." + + std::to_string(V8_PATCH_LEVEL) + "_" + WEE8_WASM_PRECOMPILE_PLATFORM; + + const wasm::vec module = readWasmModule(argv[1], section_name); + if (!module) { + return EXIT_FAILURE; + } + + const wasm::vec stripped_module = stripWasmModule(module); + if (!stripped_module) { + return EXIT_FAILURE; + } + + const wasm::vec serialized = serializeWasmModule(argv[1], stripped_module); + if (!serialized) { + return EXIT_FAILURE; + } + + if (!writeWasmModule(argv[2], module, stripped_module.size(), section_name, serialized)) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +#endif diff --git a/tools/spelling_dictionary.txt b/tools/spelling_dictionary.txt index c7b0ed68c9..217468c6db 100644 --- a/tools/spelling_dictionary.txt +++ b/tools/spelling_dictionary.txt @@ -381,6 +381,7 @@ authz autoscale backend backends +backgrounded backoff backpressure backticks @@ -837,6 +838,7 @@ preallocate preallocating preallocation precalculated +precompile precompiled precompute precomputed From 4d6a60c843aeb384e25ecf7f5f87c37d69020bf8 Mon Sep 17 00:00:00 2001 From: Bennett Dong Date: Mon, 10 Feb 2020 09:22:00 -0800 Subject: [PATCH 34/87] Remove unnecessary code introduced by 9858 (#9982) Signed-off-by: bennettdong --- include/envoy/secret/secret_manager.h | 1 - source/common/secret/secret_manager_impl.cc | 3 --- 2 files changed, 4 deletions(-) diff --git a/include/envoy/secret/secret_manager.h b/include/envoy/secret/secret_manager.h index 3534e8119b..666ce32524 100644 --- a/include/envoy/secret/secret_manager.h +++ b/include/envoy/secret/secret_manager.h @@ -11,7 +11,6 @@ namespace Envoy { namespace Server { namespace Configuration { class TransportSocketFactoryContext; -class FactoryContext; } // namespace Configuration } // namespace Server diff --git a/source/common/secret/secret_manager_impl.cc b/source/common/secret/secret_manager_impl.cc index a5fffb940b..f99a1205ca 100644 --- a/source/common/secret/secret_manager_impl.cc +++ b/source/common/secret/secret_manager_impl.cc @@ -124,7 +124,6 @@ GenericSecretConfigProviderSharedPtr SecretManagerImpl::createInlineGenericSecre TlsCertificateConfigProviderSharedPtr SecretManagerImpl::findOrCreateTlsCertificateProvider( const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) { - ASSERT(secret_provider_context.initManager() != nullptr); return certificate_providers_.findOrCreate(sds_config_source, config_name, secret_provider_context); } @@ -133,7 +132,6 @@ CertificateValidationContextConfigProviderSharedPtr SecretManagerImpl::findOrCreateCertificateValidationContextProvider( const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) { - ASSERT(secret_provider_context.initManager() != nullptr); return validation_context_providers_.findOrCreate(sds_config_source, config_name, secret_provider_context); } @@ -142,7 +140,6 @@ TlsSessionTicketKeysConfigProviderSharedPtr SecretManagerImpl::findOrCreateTlsSessionTicketKeysContextProvider( const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) { - ASSERT(secret_provider_context.initManager() != nullptr); return session_ticket_keys_providers_.findOrCreate(sds_config_source, config_name, secret_provider_context); } From f103f90b05b5437112f5a7f728807f4ada5bcbb1 Mon Sep 17 00:00:00 2001 From: Michael Rebello Date: Mon, 10 Feb 2020 10:09:57 -0800 Subject: [PATCH 35/87] config: remove ApiTypeOracle assert (#9973) This assert currently validates that the return value is non-null. However, call sites actually [guard against `nullptr`](https://github.com/envoyproxy/envoy/pull/9618/files#diff-17967d56376bf9821edb17b67b8a7e63R228-R230) and treat it as a valid codepath. In Envoy Mobile, we're hitting this assert because we use the v3 configuration and don't include all the v2 protos when building the library. Removing the v2 fallback protos in this scenario can be a valid optimization. Given the above example and the fact that callers explicitly guard against `nullptr`, this assert should be removed and this codepath considered valid. Signed-off-by: Michael Rebello --- source/common/config/BUILD | 3 +-- source/common/config/api_type_oracle.cc | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/source/common/config/BUILD b/source/common/config/BUILD index ad2db3c578..03e57b8c67 100644 --- a/source/common/config/BUILD +++ b/source/common/config/BUILD @@ -13,8 +13,6 @@ envoy_cc_library( srcs = ["api_type_oracle.cc"], hdrs = ["api_type_oracle.h"], deps = [ - "//source/common/common:assert_lib", - "//source/common/common:logger_lib", "//source/common/protobuf", "@com_github_cncf_udpa//udpa/annotations:pkg_cc_proto", ], @@ -354,6 +352,7 @@ envoy_cc_library( hdrs = ["version_converter.h"], deps = [ ":api_type_oracle_lib", + "//source/common/common:assert_lib", "//source/common/protobuf", "//source/common/protobuf:well_known_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", diff --git a/source/common/config/api_type_oracle.cc b/source/common/config/api_type_oracle.cc index 2706c4af2a..8e89254b7c 100644 --- a/source/common/config/api_type_oracle.cc +++ b/source/common/config/api_type_oracle.cc @@ -1,8 +1,5 @@ #include "common/config/api_type_oracle.h" -#include "common/common/assert.h" -#include "common/common/logger.h" - #include "udpa/annotations/versioning.pb.h" namespace Envoy { @@ -20,7 +17,6 @@ ApiTypeOracle::getEarlierVersionDescriptor(const std::string& message_type) { const Protobuf::Descriptor* earlier_desc = Protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName( desc->options().GetExtension(udpa::annotations::versioning).previous_message_type()); - ASSERT(earlier_desc != nullptr); return earlier_desc; } From f75d47e72034f5db7aceeb3aad02ad1f57b34d8d Mon Sep 17 00:00:00 2001 From: toddmgreer Date: Mon, 10 Feb 2020 10:13:04 -0800 Subject: [PATCH 36/87] filter: Add .md docs (#9972) Signed-off-by: Todd Greer --- .../docs/filters/http/cache/cache_filter.md | 41 +++++++++++++++ .../filters/http/cache/cache_filter_flow.png | Bin 0 -> 90750 bytes .../http/cache/cache_filter_plugins.md | 48 ++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 source/docs/filters/http/cache/cache_filter.md create mode 100644 source/docs/filters/http/cache/cache_filter_flow.png create mode 100644 source/docs/filters/http/cache/cache_filter_plugins.md diff --git a/source/docs/filters/http/cache/cache_filter.md b/source/docs/filters/http/cache/cache_filter.md new file mode 100644 index 0000000000..71d48a1ca3 --- /dev/null +++ b/source/docs/filters/http/cache/cache_filter.md @@ -0,0 +1,41 @@ +### HTTP Cache Filter +Work in Progress--not ready for deployment + +HTTP caching can improve system throughput, latency, and network/backend load +levels when the same content is requested multiple times. Caching is +particularly valuable for edge proxies and browser-based traffic, which +typically include many cacheable static resources, but it can be useful any time +there is enough repeatedly served cacheable content. + +## Configuration +CacheFilter is configured with +envoy.config.filter.http.cache.v2alpha.CacheConfig. The only required +configuration field is typed_config. The type of this message will select what +HttpCache plugin to use, and will be passed to the selected plugin. HttpCache +plugins are located in subdirectories of +source/extensions/filters/http/cache. Specifying a message of type +envoy.source.extensions.filters.http.cache.SimpleHttpCacheConfig will select a +proof-of-concept implementation included in the Envoy source. More +implementations can be provided by implementing +Envoy::Extensions::HttpFilters::Cache::HttpCache. To write a cache storage +implementation, see ![Writing Cache Filter +Implementations](cache_filter_plugins.md). + +TODO(toddmgreer) Describe other fields as they get implemented. +The remaining configuration fields control caching behavior and limits. By +default, this filter will cache almost all responses that are considered +cacheable by ![RFC7234](https://httpwg.org/specs/rfc7234.html), with handling +of conditional (![RFC7232](https://httpwg.org/specs/rfc7232.html)), and *range* +[RFC7233](https://httpwg.org/specs/rfc7233.html) requests. Those RFC define +which request methods and response codes are cacheable, subject to the +cache-related headers they also define: *cache-control*, *range*, *if-match*, +*if-none-match*, *if-modified-since*, *if-unmodified-since*, *if-range*, *authorization*, +*date*, *age*, *expires*, and *vary*. Responses with a *vary* header will only be cached +if the named headers are listed in *allowed_vary_headers*. + +## Status + * ready for developers to write cache storage plugins; please contribute them + to the Envoy repository if possible. + * ready for contributions to help finish its implementation of HTTP caching + semantics. + * *not* ready for actual use. Please see TODOs in the code. diff --git a/source/docs/filters/http/cache/cache_filter_flow.png b/source/docs/filters/http/cache/cache_filter_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..d1d254c5d9947f2c5482fda1706870da69d3bb31 GIT binary patch literal 90750 zcmeFZc|6o_+c$0tWgW?qY{MW~LPfG>$e1KWmMl?7l7x&s``9yO52cYTS)xd`kR@Bj zz8gYgo3S$t&*^(z*Zti0^}Vk9xv%HB_lm}$8!eriHb^y3IW$NLRl@QGn7ebf6-BwNkX+6 zUgwm1V@suAuifq7Z*SNb9!V{t13%(M!<>8^4Gm(X_dO<=j6WSo-53pdDReQsyv8m6 zi@w5}cLw?f9v#b{OzST8^#v@|+Fu)3&YMqYq^4%nprT=aMnxw?^>2SFLyK=*8Nkc` z-P?bBLj%pIO#Sb_{MT{m5DmC{SSpj|pPnZ44E>tz&p#sclb0F}cX6(4nm9F6EG3*dc_~1u=s2=Jg6n71l)Lf2J* zXxp473Q%^)v{`}?4WtB`#)MR0hwON|z~TEBq4iJc*da?5uKn#tg`oBsG&EovJb^t! z^JMbE8&Nv2L=CtQ)O(-^0;xvwQeWZFfWw2bOdo+kU+h9qLR5hd8HJ!tIW!Qt48sT* zI|Pj$-*AG%i8plW;=z~VUrQwN0ULkBD=fgMA;d?6Mz7>*z@r_EY>&d}pjn=jlaTJO zFCmXb!IwlOB4>1{An~_#&_GKqVN_6CUr8W1Z-OZeBoO`EvQ`JaE@MY`3PA;d9F4U7 z0`}XlM95Si72QXmXr9bt|Gh-+z6`fG@N!)W(LARU09o17#7T=k^m$z9nK`ZJ{9$Z5p5LqC32j7^ehZ7+=>EaWh$hxb~{?5uOt*vKnf9T0LgihTOFH z*LvFAC*`=i&K>Z5D22=Vwwn*{Z{|CGIG^~t-L0q}QCoX?SJ3s1O!cU=uFv91$fr;E zN@Urbc$c-&ce&tC7(7Dy8*^ve>kMm7B=4_0yY%7RfSL#Y(spX;yMU766P3$x z=@(>HZRPyFUV+vJs2ei%{cJj4dmy*6J>E1eFSw6eub2vGP`y?z_&WK%!|iuU z5Il9CER1puw*aFcaUBhJD5LZX8=@5Pz5Vr}S(~Z++i=utzvtMmh}F7wXH+saU%b${ zQrsN|RpBX&;yKvL)=J$R{b{ggr?glhMLGp5zQ(#JZT`+rX_g{dt>XJe`h|O!&~U7y zmuu$1G@8=m`_}mu8lCu>N$o=nT1nK`rP>rHE9xvoz+?8-YOe(v&+|b7#P?KMzIay% zAXrZ3n%y_AFj5o?PW_!G9}p170ol*kn)qP(uI@fg5&}7c);9(c)@-IC%eEYJ*m|Yq zr4(zP))%Y$Oy8_(dT@r|Ry20~Kxy}Z-*!It{Nh?sw>@7$fzRmE^L~rJ3Ct)6gvo1# zwzOlpc&*jkBgMt8NpKDLtZum(z_sm1hYlcN+pP^6QXv5oBUk-=EkTD*SOSf zgm#FF9vh?Ps8rdmF=kx7t&ZN}>lsK%m}pzD(UogZ+l@O$6waN7+><&T z3S4JFPDhqH6e>m@-Tn5B3!_3G;fFpOQ=9oV=o)29o&LFYNb~)Tl*vnas}slKRJj!? zXT*Y*e@H!*vV4Ue6khZcOh++AwS2mv#ZX?vz1EDTg6VobtC$A4z`-qL!iIQPN%cxtpTZ znz(_J9y^ZdU1OqBDN4$F0d9_AnTxd&FW1Tzlk}8x4NaI29ym4umCunlODjW)EF)fN zTH3utKju?cofN%oF!xT`b|>wPg9++-dAMlT)5j0{de5t$-Y6^F2sY&3II)I8d=2xT z^!Dd@=g&qKiGQFIvb$MS?=h-aBSRR9F}+K!9hpg1U7L!)_{KU&^K+5)`j%&L%v)Xx zd(W_*y^|GeH9bA=8stBeYFY1@{_;Er9O!$5cF5YaZ*Of5y`|lG#J)hllkNR#s8r6X z=lg@N{-~xvhdQsP$(d?bJa43<>S`#%A44>_2q_Jz19)v>1#C>UHe6Ll`A?(k5$3KpH`X526L8G zwn6ckv9-Ty2l`n@3TsHIoyQHnS`hc^L&;s*15%AA*LqO`N%jwY+Kkt;nhQUCaH))x z`Lbxve-PEil{jSKJ9O-GzD$DEcJilB(_^;=DxGAy1-mNr1b61O$=`}h)?;RI(H==3 zu#}A2n$9nisi78@kjB3JjH=K5R(B(;0wyC%`j_J@k+&aJ8WnB7ujT03YDP>2Ol!_9 zq_A1O)9=4+W@72~VRNT_M|nf`Ou_B;xmIVM0YS^zFJQK8)ot^`ge8ZCC$iW?F0}vy zze#yj3i$scskGYD$|SBT$EC#N)PWlDBxN9@&0(c^eTgQ?epGg}%UQhDn&(RB?%fGD zqbuzd*wfIedk1H1q~>Ni`)IFDxcOXnj=0WWV?AV!Ss)p*RQg#@!4gKoS8!)U`OPl5 zJV$RAJL1bV&hOlj6+2h}E|wVll4 z`+U5Cs!8#6BFBa@k@H>oZlzT|(M{#?s(#_!_pC(1WbE(G>2G~6M7=bAv86D)QQLF= zUCopM$#~{-eIanuv)+q~T8%z}kr;j_7r!xJe2JA!@YPtud1+YHtsQ|+@-?j+9ThI` zENU;MExqF|>UZ&%R$k_(i*=bA6ZX3qAc#2No_bR4KkS%GGD8UL1?b_1SroP}BZ`=V zkH}`Pgn#C^7*He^g%>;nwOGPkFHhp#rtQ52M;(36pt7&wP5;B;!A}0xC!T#7qGnm` zof>gM-y52!ga@t9w?au>cV{1ZKc3ph52`4%lz90KPt*Id-iTmi|sU#*!ThWuR5u(K+k4rTVt2NgmbrzSD}e@fVGi50VUtcWH|) zwnX5K63T4>in(Z#XVw+N=}pd+xwc@pfE;tFZ6BN>)aBSsf&7*#Vo*d=ga=GdoVqF!WdqbqH4=y26 zC;hg4YHBz|FYG51`&?75zzc-Voq*uyO{}2Riz`mDi+!ZoE*Zf=%WB_Izv_k=R{xGL z<@E}r`+7thOuO0w2EDdBV(dL4JSQtvjhYWmY&Cc#2poj_?3cDPs{Xb5>wzM&y^smP z>Z)lmz7GXHE~Tk8yKQamc-X+a@W_Y4fu*w8r{234$zu~qZ1bmj#5V^ukcqmx{QhtJ z590F6IzJ|qjemqaIn`$aSwZ_0z9CXpS3_q61>F6%vlkZl4m?xTRzIECS|Fk}z0G|( z64nc4EnYLp)I8PH8?{}__MW}e)qQ@TiKTy5AFgB&UTq`dH?_b`Xc4r?V;L~Z8c@H> zPnoNCTF0?TC()>F4m~Ub{;s zubfVDsuhv3XfgA+3WeU-Xdc|2*cjd5+O+X%e#8Ac3t7~6CZp{0BexgE>#rz{##<+i+qW) z9cOQDISIN+Kvk?(8?H^5crTVXqAC`{-)Goa^2<$QD$%4He(Jqzo}Z6sP)5$#3t2}n z%66I#HTZwuVz9nJ!9|`=-n*}3k{0X zgw_jQ;QR7mI4(3e^M=pa`D%IJ?bB~zXqWNY6aKSoAKT33nMWdi+$>U&*wp`;S!@!{ z@TDdt0KOgQ5V(Ex4kfC7_NQPf`7OVbRoC9xuk+hac_bE%cg>g&^x)@mlrK6wI(Xe+ zO&{e*Hkyb=WLNPsYP=!`>EjzTS>1Nikw+NBKH7bsen#ObHRQy zYR@<^iL{0O{?ftDI6S+ayFu)F!~BZpTZgk|aAOgvgZ9$dJ&G}Z$;1p7WPhS!bccUuYHIol*b+HPQGI@K*y=Mt{TUNSNnfq+`+LW1~dZe z?b}GrDSX>pjbB`_mu8+fdNh%!Xr9N-KY9DbOnAU&0{xiVd@>JT z{vP61yJaTHUrv1Iy%T=$_TbV|KRT1a`RcC(Zn(iOo_+69YG27_`kH&F6$0X16 z(zD0!^lT*k&UYCy?Hby$piCLyA=Q~xs&1BE{aP?7NyrL@ZU4${?HxaU-^K4tKA3ZH z2sk`)UkS12vs7026xA1bJ8E~_=DgR1`e19XhLIRUA9&+>b7Wggzjc&~CdF31&3KA|)YshHw7G_}b=Owr!bI zIDFgXz8`&gQi^x~TVkJ|DIDedYga@aPGV^D(W!z(ujREhM~A9>9b{9e>N4^;u$8-O zcs3V}=1)RhC~1xnux6<&FPx6zMaETTO5B1Q#XN1^5b6?=77+_I87uyP`>nF!T_ql> z&b~pY_ve@mEV*=zLXu);!;SI!-dto0%h}%!#y5B}UaQIuXK2fKxP9p_H z3v0JHMmBV{+>0FZz6JTa)(r~Mc_Lu}AeZvXt1-(i>V8#k**6k;X!^-{*}NV{Z+3;Q z%_tt*ZWErZFkwe#EZvov{Y^0K5J^DauQ}h4$sl{gRlSHvd$#bv=QZJ5Z4zUQvWn0e zcQr%&a&tz!-0xz!&FE8tR*ApVIR(x&KBB~;c_v20PC)jfcirZBZKhcR#8GCLBv+IW z(SK`xeEv zu|RE)ytxIPauT=7duw1SH@S6u_N_sMdmeP^=Jz&)rs!Hk= zpsY&sm;F|JrWLE!7ejU*m8O0k_RYOu<+;NgL0jt;ueSSPCb-8$-OG9GVNbTVrZcGx8wfL9AoM*<{eENqmY7uDNZb9*g+MWKmuP)Vjn`6$ZV_SAFBGAeEro@Fy56e@> zKQDMQmHOw+obKqNflhhDRhY(buP@51XfelKRJjnzpR`S^ZB`Pn-r4`wc8WfRMGOMT z;B`5DgTJP0z5R$fY6HJ}Q=Mx4YUcqfTZ78o?t!A%!II}hLElG~KelVW-vt>&qv$k8 z+@(GCu4(-VbsrT%$M-Y_sO{+34V3pRD?Y8C455{s4eJnOPLrwazSE1>jAtNNdE-w{ z3%vK5oDpw64G&?-Qom!xif_Qw(SCjqvsyeT1yyk#5?rvds*rB#6B+P< zIcx!5C_;pFra8Yp#IXANFBz@Gj^4Xyym~7xI&WD94wnjOK6ednYPu7VzgwJioaNF( zt90?MSEQ@lNGi5TmF%xb2!3IgX#k2PPsI=p_Ek(@MUNN{Qif@JlS0hSXHbkfBp-ZS z>6Me^^}ae-USBFvwSIaQl$>(T<)Tq0?8R1Ua`PmoWL1TBO7nz4-;=XUqaX@im6j#& zK5dLd15h-W&1ZzEpsw(yFVoY@SP?F^UI%FcXF!CRNTU$}(`#x8f%{_ZW67{T6L zTX+b=cOMm3XVuA>2Js)l&_}wS@6o7*Ch~SSH=#`vzW8;7JiHGZ;D*H244fQZigzMF zif-2!Xu_bI+bsd>xC5)(0o!xN!wWr%qi!y8&@BCcGBi3yJpqj-#BDrOL5<8nryOc) zZ8h8bl0F*EutNqGY8&7o&H4gvs0()&E3lx@QSR{5`(2r~=2~DckZ9u0Z-$?J`y3nD zyjB?m-rpG;iv#{9ci$h{ONvV2n*6VYN+c2@*ILmyV15&`HM#omn!4y_fp47j{FQc7 z?_LUgMFBdBDoWXUVPDk!K~Uhe&$zW)@Hg+2WWEaq;Ts(#NjA~mxCc9v`r1`8t>KxQ zJG3^X<)#oD$mHoCRt}4rsch;on;R-)0lf?Sl)%rNB=rU>ikW`klkoM)*UD0cRaT&I zF?ftjs9@;q!#iqcY#2&+km`Pxp0Mb53FPr;BxPo!Ny>6;8EJe?`t=ib%@K?Nyr@iu z5d<>SCS0*|<>ARLmG{f+RgRfSm#*G~n?Cz;U}9a|mz3^i)v*yxIN+koz~32BdB8AB z7Jw{I`2Sd*;l1$tEvverqF~xW@|R{bT2ABkA_VVm>-h84@L(0DmT#}Q%YZYlVS+c~ zgpoDb&Jf>WSbe3XSmYMG(Lbq64~|mKwY%r1@WDIn?q8z0*I_ijc>*FEP(N%Q@L|Da zUs2*><_M_c`R~C7Mp`~fny@^n+QT>J$OQ2G_8?qYu8xl-<0H*@zN-1AWS|btbNA<3 zKmAS`NujkWtJ&Y~%ICVEx?bWQ;r@HUasW0Efj+3*ogZFvTxeOHZa-ii9E8#VM4@tG z9I5{Fpe}%`vH3ME#8peuDz)Uh*qH?{qNQ-~qtApNmpqb@cE77bswR$sZ{H~D^{wtpi#&e{i`P*k+P9jPj@r$9969xag94k$>p zzseDy{h&7*ZJ3z@oS9_jT6!1Rjs&Pq19y+qNXq_ThhjPzpnjfs1o z^F-dcaDO(-7AzoZCMM;XgcF-pj(4*q&Lb6?VvzFz2darH0%`;vD_Co2dKj2_33XDSnmlQg{h-Zf6uP(~keJe7!zHbdjLkT|(f*5I$Txl5yg>H~+`;g*h2twRY({BMJmR8wnJ6 zc{^{^m~@?Xf08dU8@3c{<3ek&yQ$H=@N|!JxaZmYO;6?#gGgzehtH+1j7B`f=M6Ew zkm@K-SUoA){G0W+zL=^+eyw|(-~|KC&0Y@|6e0UW#?(#js*8FWqW*pZ%uifJ$=~vRu)4)~ zLAT&6`S=0Peh(*Pe7C;MJ2kD|_-bBYkr`^Ka=>{9S*UEg{dEzPV&%t!8>^~Uvf6xT zug^8$-lPWFhIOWFO*~ek*bxpklk$^(og>ocXY+P`inEb@xW--Rwz$8fJilRjtis^7 z-VUar}bw;m*htZZ_k?jBC}Py$f&$+4zDe(YHSN?4Yrya zwDT3YktuiA49|O9#wmB+viX&wi|#zpRG>Rra_Ydh~vpH8zuuL&d_7n7_e1H!hzq6; z5&o398QL~I_$$}t^Gs=08UC}z!#i)0=9D?a+0jYJ9Qz$;i>#_cSvxuH3r`M{T}o z^NHTdJ4-wE@y*FvW^bo3B3|{@+Qh`XKDXRmVRiKShRVq3)?iKTN^<{=H!@J$DNk+y zicl&9ANjfOyE3V@#MU%6KiekU+sa3-(E6im&su_6)TuX9&DgH1INSfkcSwzOtG-`5 z_mof2vvM9?ZR6IwdFQ7hTA+8wu~7ZqHI&EbIp#{|wLQ)*{vS_U6*7X zs~<%JQc%TnvMXf62=u(e=kLMe5+#q{@*ndmo;zg{u5N9$Fe`g2pxgU%pms=Y!8}Fo z-NDyuQ49xiBqv?VB8J5AkWV#ia8OfM+0w7ougj#&pUAt=HLmf~2T>tVxMc-TEjln&tD@o8;)ycb^KkNT0du(lO? zAYm@%qn@sJtSORlfOpMOO&Wq%TYPKY-+MJG`zUJWid7A3C-LlS7==|bsOu9Ml z_teZ_ZyWeNLo99ek zMx20HUH;e>+xE+GMREAfOlY~l-mI+2{0TuySJ3MSu&2eK%TMy>dFvxPD@OJYx)HV3 z@jXkAPFPKR`7T+xz3Sw#*P0|<^?4(!Y2lJ*z~b=gIKzU>?G^GhqO2i*$ABk!ZmWip z=iT*aVc}Dz3bAsaj%=LjGHjoYKIUF{EC)VUM0nl-$V*--f9+t;C+rKtqiuz8RKB~QonZ1Wz{#C z{fXb_7={G$`?Wz}j+F%!Ct0rYiAB}I&FUn`+CC_CF}2ZBc|Yu6=~xBY=H10 zlt`rjZF=!Q1lly97cmNW0JrYlw}o_jJUIjD9u>)2P!AvVOJaIysTn!1P(kF>vOx}6tI$Kv0NZ~r&cOc>5&GU68t>~ zq-WlP@}3(aEDR-gn=BYYq2we5Xsiez;7r4Fs~GQ{fv(oW&-savs1aY0-tkykGMCEA zWhxr8gsK7&m=fbvoyihR>`V8T*k=8wlG(z~U)2R5l+AGiFjc76k`ZGd zfgSZ8>!PO|X6DvIU6pKp*8wgyd-4?%HJr{5Fu#(yfT@+W+#nVlGHTMP3$4Wg`%8U2 zo(c+`21YD@?V9ErVdybEG5tUdd%%%NfrUKA04j^97DD?dAa`(RU?V%hSmi4M0h(~Q z${D@S;0gD;VikaucY^`z&u@T_^*SD^g9_Adhw)j}2XJ_kDqzmIJ~?)b1!8zz-ticn zJeYcmlyJz4Xz;_ldXjn?;0shxWA|%RknW4C+e}dCl$qg2RY1J)dHU)oHRD;4AholZ z;Q4DQTNby$`khy3JRf-|^?o3_Md{*^&@i-wM9R4%G$|0^6YY-*zq$v$-Fp3oAq`jq zI`-TwH}KjS-)zkefpkS;mVlJQrPEg#HSU}P%2CA{fsbz}jC4H(Ym`#%6?YOy%mzHe zt5-pnwcwmDucp!jwgU~wBN_3cKz!XWOe6>3xQIT}J&}GKkn3Vq_Jh!9)UB5f4ZtKa z_#MFdwF7EhyExFf@2u*;EfMIG4rbRFu(ew%0>G30qq37B@n)A9#Sd9`@-K~EJ_D1Z zhUfi$MFq`r`?bOihc}jH-SYubZZ0Yvr(x&Or-Ep*olXEB_qK1ATB6bZv(Dphb>R0# zY1tvX;yJH>vO|u*UcA!~QUHV6IW8-;0`W0#uvv6KGe?DPXwQMybdk7PAt*HC1Z)IM zqRgQ=1+WSgpucI?0Fg;9)2r)K9~y0;pk?v)aPG^3Xms?8o7eB7(Lor*O`+$!hb}9T zy&iGMjbetKfB`n4E>*mwGO&u@r@Z!#Kp-mx5Zm(#Q9Rn zLvCnRrdQh5d%!)~q5_7}dRpQf9In}lJE{F0(C87}VH4aNjM^oqJI5_*k&qP?1Y7*N9wH!B zsA)73`Ul;r5!hkl^;APZi;J%78nS~x+!7zBG6k|8?$nTuY-QNp2QjhW-@F#e}ogJ}*tJ*qBaMs{u?c9Fw3a1j^*A;Pfvm!v~yq%TUjibKNE zdn?ALVM~&Zw-Ifklb?FIfQAviDIM=#faOM#J*OMLBD_nn zU&EaC^>IC-l(JioX4sn-f(l%3%lkj+0ye6w+o*oO{BI>T*+5e2G8E6UBZfvW+ zNWZmmLn?Dv9$v~RK;89kk2|q{d91=7y*+r)4Ntt)Ja|e z64Tb!edvY9hy}#3C8qYS6zq{KK>$<8YFGVhs$B@GCPu&rS?)s#Q`CNsg0J_lB#(&G zx1_!LDhY+oEwYcC{lmQI|K7a7X82<-2cFUn`TlJIrh2yhDo^iVnjX1Sl+B{{Vp!Nh z>AhkjB?sN1QqgJ+%#4PI?`>QhZ0UT~zBv8RozvYaI?^4*kGGAV^Bx=%FXReod<*kC zv)5j#u;S_B6=XmnzP$)*T$YJA1sL zP0@E;HmvM>>E)_(jitghocn&`SA7QWabJO7ZHmHq0UP}lA0BA{H{!sj`+zH_0$`%W1ww4kVyxA|KF$ zYN^6AweTc3yxj)pC{L#h_T6vBb4i3(8lBLrAUscXKu~CqgT!`)*>eU1jC&)`gK2n( z0|cehm?OG$F-u0)b30JfCCkfSVonvN2K?5Z1&*OXjiuv3^|=NgqeTfq^3l?Lb3`0- zseIl|Y4NI%Mx@-nXFd6eWbA)c53d6kk`VES_Gugm4IV@{WtRS#QPBjPyoryC5O5x%X?jr}ObD&A;_U z6`kAXNzt+V^-Zs0y*v<}CxyhM&iHfu3ZG!LwV8@JO9_jcAA~+kz4+*!gUc)Sb1Q2$vX3Ci)vjnO|p@-O~^Ll`%Nfxu5&-e=@5(Dt;5P?J=@{6O; zfO4;a1baJiQc3zS<}ThmXF?5y&PtAbKgR`-0pJY&mqP3l8ip_ve1;m<9u9xxR3X#crL;5+nt+k%jgiQ%;l(!6Euqa+cLL&t_Od@KPX{R?D|(Am2*3Fu^39t(lL zo<;y*=#)rnDRd8Twe4FqfjG}EH)z5+Q%zHk1Tr6j1zj3p5X}w`DaeaHF2II^x7wpc z;qVNv)6zf@j=b5b>@DF`NQKqbBk@>R9WJ^|CD+-N&NQ_|$^VrqKTSiT{VC4zci(W) zgvSOq&Oo6@btHL#kJID^8PYp#pfc%?y_cMTq-GA!76uNL%65_Cek58?!^oxUPU(+R zrChd`|7#Gg^{5dv>$FfFlQ0w`VqhW+h4LdGoCI)GlL#j8Pk)RwBDa}n)bZ?o6B^wj z=Oirl{}IESO$93=a6=M6oZOTphp+4qO8ZFF6##fE82+i_{I9`tfYg36%)S7`b+xq& zr+f(Hi+xyy4%jdEM%DkcrQ82CcpeQ5>UH=_Jt~Od1N+?}(BD&EyFfG)0f>?MPlyrN z%fA560a9BJ+&SE=T~%|#Aeksk5iT?YhRnOg_9ta4{A=+1?V-sCX9LLiGIhxRGZUn{ ztE$7N7f9@Lm|FY?#Q3+64p!#B0?+U0(D~g_1J9pTAb$A_k_jh!v=b*7+(e=M`&_6l z`d@z*wCjD3&C&YhHvmo)Z0XMIR1d zmoN+Q=0BWeI`!Yr^6UaHxcu*I2Q+z9;#UQkL#__Vg(Rne`N>mmqna^?JNNQfPm$dTc& zl4K_+bojf#Ij6mj_&HGyy;sQ6^V_4 za5qtYDMuHCN&k<=PIQH1MU$4Obi%qSLiUBbdGMGUY)RM=d3aL620=`8UkX`K7j9g( z@LU)6!{9@6SS1L&0IjF>ViQ$A zL$I=;+ATOcxuG8wmjJ64W5yov_|H)fFV|%d z3&_>U&m4@#-8_&IJ=4y~YECN%yh+W*vBA0i+1SRCC_xLee+B0$I;MqlsNa}Su-SWo zW-LGGzz-`Xxue+S6QOES-ZCs%_C}c%+C05q3*(T(MmX^Xe~!3^jV?R*87^zK%Trqz zi>9SQR;Dz+V5On+d!+fWmnGM?U7t&ENq8o>CyQ>y=w09GEk}Mt%iY|1@gnH`j_F%X zxq(yPLE!k{!ZPpt2V6cm*A5K9wx5^B)$i~9i3T6UhWgH%>#E-ZFjxnqx1*{2*@6f` zW`mu~VID@G*NfToTZzBYHfj|mNj*EiTA+MnszL3%E0R3I&%`WmrG`bF`%m8O)9AY+FS0FGkJizW)qCkzr>8RE@X_~j zBj4&9r@kTiRiYXcm}HXf?I_GE$+hdaX3U2#tV%^ZKzx6#Dl=-|WtH2thlW6ELAA{^ z?51VU)h;#)R-pM7USDu7)J|=G3pBdphq&qSWgrsWkBL3*pbJ)6YkOKI2F-H?J&|)* zm(Yw?26?3>-8(>)Qrc=i8pS{iousaE5JB;3fHu_Wx)PiDTDzdkmH{>-jchYXjq`2n zcQj*{GHGJnA(|Z`pz>9dQ~+ROoK~+o_nr1+mk_T9^KpoOeppf#iVJ=s zU~MDUSvv$4o-~Gvi*pS(Q|?NX^kh~zO`jeNq`^#Vg@UA4HU-)V;2sDFe|D9iOF|J) zq1uWLo!@?m)dvgsKxk2XW1Om6L3}<<#5=DxNq5w{@mb#hP)efk`0h6amOOnvRksHD zZ^#RIW>i+Gc-6C2blJ*P2EmH?>tYx{_n4mAx)Eg%ZYF4Kxu2pqx{isOC%qo=aY6Am zoX3ZcSCyLMreZEqz7oSJ+^O~N#y?e^Yp8Eb)4CPDRYxi~M(nt5oeDVvt&;j)bZny_ zUNbz&-t^qXCURIt$HzV#Gf@Q3W0|vcgx4L|-21rWNCo-bk11=9*&%M@)ZW9sV5SjT ze-Fm4BH^eW?ON4uP6w1kCMJ3|W>t3o$1$32j?Wkl#((|X)!tSSY^(2atKIo_qu%8f zY0{&#_@b?`B@9|+(P%K7-$09!Wg{7a?s@i!@t%4Y5^43w#KZGo&QxQ33f`Z?wv0&y zM{7gt(=Ob)a&^z@2i}h9(Lh%aBPmU?O7Zedc=C&YIWwkl+4=)#8@!!tAD;SPOmsP8ffhF1$ED4FcF=n|&w1$sjZT?YMTBMX>%U zP=eK`uFd@6b1MY)OwoNW9BUFreNY^@mxocQ*w`6w{>FEXT#O=7^(!2$y4sKi^==KH z@HONIY(D7bJM_M#2kJtIgCI(z8DM%;8Q*A{ z0o=3MM@MZD?vGktOrQ8+x> zg+uM08wY5#&AsiN!#vVnGu=rBRDNtr=yFhMP}|7IxnyO4YLsdJD4M^BL_2=htZtjp zbt~1YDEn)Lxd-HMSO>kB9`Jv%+H}7Os8{MVM;t#4?^ID)Af18(NOT;Z`oIPbH?KmY z|B_CyL!zdehf2XA%w(3W_xVt0)>*^*@!*?LbS(rh=sExwzRC=sd1G-(0tE3Kwu_(^ z#cQBvkOTy*^v(5C24C*Mr($ox;T+LM@?ij?%g|6WUX22uo8Qaz9Hz^wR+bX2`r>d? z7vyv4)bp7k;3E$6mmOfELzAvDqyL2Y{!;%wuK#)`^5?tf;N>UR1JNz269IXI0 zVnp=+X%ga014wn2MI0QU2%s3co$xL$?djQGwm>;B-aTFoz}b7R&i^Tv!JzU?QICa+ z@6$}guM5E&vo7AyJPGE0?o@8}ZSeZY%fS6Syb)d@F^U2138r)nv@n{$!=km}ff*c1 z*Ko8Dh-!zGmyHPYM;k$~gShD6`jK;{sgM{<5Iq_9M!b{t}jt`^qe*vCX`q1P;53+rl3K2ak#pdqdtBCufH%6 z)UN*|3(ERy{&tKV(k*d%@UT|Q@caw>37FU~-5vmNbel1$VTZ-%OCSa~9+nBBq&BXl zJ)4LvDaSsbhp&M{(vA+#$l`~F62fKY23}iW$7!bywfSG`0nlDMQTI14z(4K>{7=I1 z_x*rmh^An&0a&G-cAvrzI`Chqyi+GZY9H@<@F&He75SI?0soUr|9z|L|0RGD z2o6^kUe&ojVs-bh5kbr|Y{QJ6xJnJ}n!F)&1%G2!&wR17$6gO_Dq$$^iPvE1i>`03+XZJyPHi)MO0 z!w&TR_y8k}VKUh5txoY3?hth>MzUEu(ka^_$3G_F>Cw61hJURF+H3Q zOjQGS5yQ&5E^Ss9MaciK?Bf)f;_7~$+O zY9a(?L|lHt3I}EbmVQ{B2Th7$9aSg#HzaKY@z{(yx2?NR-t;)826C^>^Rkb$sMIZb z{_=!%HAEVnOtamn;-Tvf{~2}|E=Di@b9HOOQS=R57y${wsPKmg1TI|E>z1Zl|K&B# zf$}^oe=z&~{qcIdiKf)vnY|~UghU0T3AaV$Cx>{5Y;*llF}G7!E+b?aKfYBa)?lRg z`V-yFw%;t2n-0oIRil@fWfRJ3MWZ5mYz^isPC>KoPFlzSIs}NbJ-KucIsU?4Z@5lQ)<7UTyN1=;(NSGtCNu+1wM(Rm5o&sU-u?KU$F|hZsAmPe_TV zT*8aQtS!S@6;7y(d~3V1e9|@@4)-;}m5N&4xYWA!v*ulPLoR*}G&ULeaYVFUj=4PJhb&yI|6ps$mU> ze<#S9rZg%_H1kRj8{s=Ect0*3ek<0$^e$9df}|VNxVWf5?&~5$ znBmKCg}6PGYNg%E37>&(C9SUwM_93bL=K8iwUAr_l4g9t-3pzoB`k-%^9q-L5(hDm z-)ZQ_4b|8w7{*HA0(w17*jGhFWoZi+OxB4Hz7umCk`cJFQ0zXP3@Iy5S`QXt?_`@% zS*t_BQ=#=YrmKqG8-4W7vB`Fj_+%dOmy}_>3LUgjaghUk{&>H0RjAwvg&2T0 zq0(L0PoTm(h5aae2$op>Ls1-fIyrRu_h9P@g2@AKDq@UuwbVCxn;Q_k9k+jaPLkv3 zIbFIomRgo+oVi^_IzELlBX=dC*f2XOc6;NEzmE=ubVg+Yav^g)gRLlGeaV~}WSG;W z_h;Mc(;f*(5>9-Q9|=(vt~#AVED7K)B$$M3Qow~Qs=;f#;Dr5j6)2bfM@qooI%5+0 za8X(}9}%2&w_s1N|Ey?FVx^YzP(|;vGRUNQL8F z`~T?<{|hOAk;Y1GDqA6k?Q|3x{Y*E05y141$kxbb|Hp9yVe(uYyUgr>yT^#;Y>fqK z{`&IJJQ4ALOA>kYOiYjl7m&yd8z}S+5Iy9Myf?b|QUeCfqtO=*M8979EB!=HceUX;xUkEQ*YLOa33_um9KAsh&|9iX(r1%SYAOWp=OZbH59SB_w z%#i`!2xWXS|Cby@brsy=p?jV4HmJ)U`fYjOWP*S$mks~5`uiP6oj>IJcaWDl9y)Xw z$C5B7sQ(YN8VFq~G>e11Z$V|KK%NGw{qb;r%fP_Kx_RRsAX-3s^xg_RKLV7%5O*CWvHp1r>YR@m#WD-0MU{~5_9QfP9(V_7;kmAYF6@G|}d5&wtz(|*{{ z`XA=ce`Ds4h83Nfu%jx%;C<+Z72-D1+qC|Aa|Ak5Px(5I`e+ftn4Jf3lr$%Pi-4Wf zWcH^@)E~(OCwpvmkamNN)^HG7La6nejV*955%I2<>4E>^6}2&C{DDQ*d=bn%=(Cq!Ex52>1PQ27%OSQ zbMqJ0G6ZeRh4^&^glvNQjis&IdgL`Kcvt){Gxk2nB@tU`1d$b~l&GtG3l{~We07a! zMh+X}K4TIQ6sW)th1DA~@mc?P?5{6>#_wfMCRjDfo0K9xBxa8>{M0aJ@ zIUUTt1fdnwr2JE`iipZ6Y=Ca1QsWx9TH$3`Db`xg``_p{wpNmk6UFBmp42t>VG5mv zp{#5hi!!a0-WyY!m}SU(L0;MK?O;*jPH_shOIKM7r+FSyk}6u>=X#s5N)zV>Gb=Rm zfft-6C}L_P2$q=sr1gu42_}pAT)8vlW3{ElDc7f*b=3MKHq1g?}DNN zMcV@Bw?AVAk;D1jy~)|UTql!yJJ*EvD~9b8xL9kC+2XC=ys``0T>#V^C%SQQJ?~oV z90LTO!ue=!EU4i9HC1C=_ycJD$M4STpYo?`Ff}5M&WNNw|3{FL2gysvj5m{+#x5PG2gxy$*=!q!G@T1-xb2;4(Xrb&>4p)-<&*a6D95IwHbY@{S1eDS zn@C*&*J3?j2M``))g?1GalQLhianv)ch)^mz28ho^(FWG|Yh)pE$TLSVb`6tmyy$C2Gs@18o-lV+@OU<&83*vy(p4{i$!U`Iim(pR z`L8Cp0ZGyDo_UlDCoocQh0!1QNlxT%EI)vI%q}alHq#P`VKL&>bT&Wn-^yU2naf08 z$izP80xR^+^_Aof$!e9U0UJW_mO0PUhq43)O`%tU$GnEZlPrv&Q)w7q1wR9Di^vbu zg=QDn(tv5|O8;3t>=$ACHF60w%Rj@xS?QL`do$}xl=lph!Xpd9UKK+IJiCNcDIML$#SsB%0HLfHlqnN zc0~Yfdq}x#MR}M5^84xKFV#Fy+ebGI8idb!fcJAnI>|KSA>D09s%kG&NF(wBy!2ar zUDZdi49g?Bm6vgj_>SZLF?Qe#Jd?`bTT6MAN*m_+m`f&mmn@iIAA(DPF zdmT}9zf4XCzAY^{?$c1Te2#&59M21@Ixn&i*Vr4R1;5H7eZl~cc|cj2`}X<6BJ)Lc zP_%`HaoB-$?E-M+&hHc4V(kKx#8ni~N6OoaO4eTwwK3+I+}ter9`~WTre`&XmZtQO zbO7@!96O{aN`GPP)cT`@Ng`i6y!`U)`9od2SDv1ch`XN2t1pvV?k$C5Q! zCZou{mWD9)o!@(|zUTbD*K*Ev&i%W8_x-!?$NA@)OU!3^FR%A&c|M=7e!b_%!>wt9 zvET3Xde}0D*mHn2@dNgcRw+6YqZ7qEEc?z=(Mz-)x31Dsgs(XTgI&~}=2WR` z^IB!z%4IqigiYW3XQtwR;d0s!v2Cf3Jj-vE>K9(I^k>>wBgfyRS80r+-K zAFzfuNqnOazf`al?k1lF0O8-}PXW+|BhFl`{4snlrONVhyWx{wguMuv`+$${bG!@O z?i{&&e{HQM>EzhwCss!QB8{~g?PrdV{{C|J(AJtyxAG2!*ux;^F%t02@h!ZTizIgA z0^X;W+>5N->8M>(j4!!~QOO(;>5?N5>vs@C8l=cW+rxvB5Jm3md+uW^(GBan2BaRG zy`JZQ%FYEVwZ)2>W@+XAsU2Q|Ql@!Rh5C!If!Woh=T3ccBDhIIUy+!}J+4^pHMU}V zu859Pr_7r&%)T|_b~((-+++4nRqcFp$iWXVuUDH_katAA4%c2QaUYZS@PV0{5>92%VWcrm7*6T ztJGzzky~i4I65g+^IZ3Jm)D@O?vB#opm?H9rh5xF^)mwwb^2sZkHAw9)-RwN8!zyA z;4Kxmit!_XHG@LezK)D=?{ZmlxkWA8pnP$YrI#W@3f5#QCa_C8>PAy<+}AI@%~q39 zBFTfVB@txYeDq&CiOsFY;ZFlu%kv9cKV4omdEnao9+pj2yrgPxg7|dD8kVd{b&gSu z>F56tD*h}60F=LmI2Cvf`EQV}{~0R2hEOXB|AZY7!t?PMH1?5{d~%y*?EhTI0CSd% zgDC@WeuBZtgMQSQ?v2_3B~3rD^BI15_3*48P=q;%bfJOycXnR|>olymIqdiF_1}V# zX!qCVJIxm=eNP|%@4@U}KH*>T7ybi~`aOT)|Dyn@|6kNAwuE5Xam&#Zo#S4;F?Ufu zrl{=j^3iTYwINCM?FFtRZv#>XVwQ)DW2W(WjE_WBrn}}{)c}6Ej!gNk1jzP3J2Rxx z6OJ{4U)GKUNq=lTk{5D0{UCrCmON?}s0N3_ca_9%XVgHlH3ujXFh@BnqSlUF;M>ia zRrgUReZZw6fY-`ahFf+)5o4BTUG=RT*Wm|}c3s#51! zIE!zSE5e+owfKTpb!Fho2US&gQH{!Cyzkqp#&+TrWV_tKh68`7CH+2}|6YY%55ylv zfDF3{PJy5N_^`;&IsrmBW?30kh1#@vF{lTCT;xkQxwuWO6Yb_)AM|1M#V2p1DYhNg z@JPYy^iJo9c3@uN4TC&(rFhIm1c)a2(1CX(-#VwEb6X)RMDV#k}sSTGo zJ)u~?a>Me=ZF>#)j*h>AL@1CHE>7oi2T(d7I4lejdltIuQXGKo13WXOwX=U``*W{2+N25D$fYk*Osn#_V_ajx$3L4f#$d6V zGqUo^6JxkJ9&)mSQf+hhmh2$n$6>J?U-!5t2OGlcbJce?wTRdg&PJ|A4q*dZ@BABK z4I@|CxxHn$B3(Q+o?46<9wi( zo-H>gC=hh`*o?apQi3X*0);9U*q0^sj>QsxLr8^74mBw11E^t({hIY4GU1;cFGIG?su;) zuRd2+_yFN~=9@(4;}Ln&r2BBdM8fwjDxQEmigHB zX6_Zb6&d2BlrD+$i8BiQh#Y>=dq{Mpcz^-S)E{Adf7o|Iu%i;SlKMv1F{(}MV|J%r z(5$IGV;A;W$tGHJamP+pi@VNh&7e=5rA7sRk*ofh2u`+O8#d}Lm{`u0kxyzUK4-yP z%Q4A#ySQWN0YBzda6B5*^Ef_zd4+0prT^$X{z(yEFUR6*p?PB#PT}}!Md4Gdd{30K z^$SXRT2oK&J!#S4zN*r|Om{mZGQRH_#RQ9`_tPb?fsG+(n@qbOf&_sE@^XfnC`j^n zB$QeNs3MOg^_xll=x3>Z+^BFMkXoQx{;#;}uh^}VwCA9@`h&+n>TdG=KLn0+{=|%q zZi0vyvZ);LGy1U?Zbj2ctCAw5FWpML1CAc2)hZiVScYuR4SJd-kbV?HbEKuM0v-u} zulIdx1Z*WyO z#j4azd`f^y8IY6#e`!K-u^x++Te@a)9g8JhQ1|4CIs*Pyp@Iij0^&An_iF>=kV1(& zj@we6GPF;GJEYDMv;s0Yy2n!gA)M*A)uV^-|8l-*f%E58;0=QG`LE(RX^TX#Q!!^*`+1|FC=i-)8r|#=iW3s5;L^ z?Wpoh%nz;6&#S~lrJ85!AN&;;SVmPkF_q-Yw!vHwiv7;Addi#uD%R4P zO=fv^0i63!_v`JnL#Uhtq1Gvf%ePJfPL$Z;oKJml$}Q9g4uDPqYJd|S0Jr*xL?REN zcxWNVsN9?T7S=uf*QKtJba7mg{#W&xp-R~aXTSv|$k*Jce5tG6`@w%&Q*Y}*q2htW zOx|Ar0uMPxpE~i47xqnRgX7X^X!PxC3{3P;-CNg!F4F%Se+@{-Pd_mwg<#*G7YL;F zy8>Jp1{A!b96<4CQ(*kSawWgfwHLx-A3Avk#EJ1)MBwBbvVim~Buzs(-2wc*o>i`; zLmAobxF~Kb^WQAt1?t}>QlFXQ%;TtEB{-10!FUd8%K0u}&PBU;gwQiXbv4hmNCt9% zo*cRs3&8k=TB#id_|98Y{D|r++Gqcbo77VV80X$?Utr@ZNFf@oY$_`q`67b{r1f~g za0S+#9p_fX?p8sWL@W9e{{Z3>l@w~-S((41T)8!_l$I3Lm`Jj{{!+W~{aQ1I^rsq6` zjaT1JuWEz!LuFs)o7cmBaNvev)=|l(NGaB|{xiG5q9iHa)kH05Q5+tP+DyS)X(yZp zNl@dtt_>`f3z6IM90v19mb(&k`5U-t0zZ~w!m1_=;}Rir=Djf91|^av@#K4lK?T}) z(Z)>HfB_#Sy_)C(Ey}^aK-@e>u0`C8y^y}&g%_5^B$Yi4g-YLhF=)gB{rW8~PU+U) zPLDKpKY;E^LF^EEo*hTYq<2ZRfQa+@vOdlpMpj1=amz6#eSlFSyFI9rdL-649M5?% z%M%SFr%;(M&+)~GSw8X|;pZNeJKDHYQ>+c6t;MntuRps9qI_U``%qJAGDf7~=ciZN z6!b}4ID5XZ?LBxYO>z3q@B zvn{2z7JpN@6A+$cP-*s`?nOk>D>`*bo~+}I+f!Dq8eH3hk#C^Nn7xu~zr2`M6kAYK zC~+K!TH=19u-4n(6sPXt{hcvl7FS64V4KUgniz|97*P7u0&JO1L zQAAtG4rP8Hz`<>X8{0p^19c3f7c2KW)UF{K%2mR$a%wA%jHql{_t9sUVwYRb|KfW$PoZ~q z)w80$Hy~=g8XoV+q|gIN213p@a$lBtzVt5g5M<;&ZaHFSa+ORlm#uFvf2Hp;k-^kP z5uZ49kQ`;Q3TWTyzU?kPvn}o`DmxX?wV2u2;cZK;Lejhoil_e^uWn>yWb1w?@?OZj zwvH>Fg3-DQWju@f1_MT?4!*kkPJiS;eZbwliFJjGSCC;7=;+m}D6Vv0;pK#%wN8nL z=b4w_3#MnbdEaLNVSzKtOD&&8-dL>@p?XoUQz!y}`5@((B3}W4w`7 zLCL1-gJvZ8E7~_ZEgbefrU?ss|KKM_C|$TH%?oQ@N%r@Nq-vRPNFJnyVvxf$@&Gjb z-JOQs_pIM1z{~o)Su)+LzDbG7-6C(Ehk}w8oyX_8E}goYJ>n;G8UijHQJ7A;xoN^F z3G_$5$DQPA&yxDkIWMmXYkN?7Ccm%(6FnGNxaI(@d;l9k`t$ zgaV(;e*I;k*3eEgX4;Bta#O%-iIUzg7u110(J~_K?7Pw&t{@~b*jsj=m)PHE{RB<(t9WbY?4klQ=y6bMJn9MEi$}|_FV8D1~yz90O{T?+% z;2L*V!19$<*Zqa5glioKpkm_(^!p0{bMl@9aTT;TYG>3{N~Z;f&(Sw(oQI&m4sPSC z6)-DL7nO9RPq&?gj%9NAT)1&MRc8LxJlD%jN{o>rYK4b{9(fs|_$4*O|3h5f&@dA+-|4LAEx+^C zbE}_yPvi&v)7pwMq=U3U|G826XNK&Asuf}9rQwX7)w#$r&2>|!;{}if+Sh_t2_f$U zITMBH*`by*zKIX-TMV$vq}CY^u5&&VUkZsJy2#9M>dHy)I?YU_?voKUE3MTo!cs1= zPkn}shvGz@omn=^nb(JCEika^tjeQS;6s8eLQg8o3SJ+DvY#k0g*_cK{sdSz!dcJ?#I9Uy}tovrSH3F9r||eh1hXAM6b7Y<*xIEfshCOyWu>>=zT{YbT?xXJGXM zbaGv5lJmoD!%tO$^gUV$@ee(Z)bhIw*Ni0{e)3cwHqK@(`=qw0L%{6aSa7$nUf3{k zB>6>=8c=W4+1!a}gMp;Sj>1yiNPX302t;v4_>5=vXM_TGeeO|0NV-7WDYLFI1SKi% z26T)bUwd)w5;MBOaZhglN(H?#GO$*-?4|Mbo|N}hsah(5GZc4-8QU1D0v)%2A1Fh; zHhnlzcDC^Q(gV7wFK^mS4GGnm!mz~EYWfsq}hgZ)fw*uod_Xg ziNdJ+&#j(2*OjD76E}(#}x8gLalL+$4=Y#bx zc!Y-Yf7vZ12<%!83LX^-=-J7tX@eOejTA6%8+Y^$n(2>cZdrD*L5EB4w06Hwv`>l? zS8#i`x4w<7!O6a|udM=YFG7wKoLe;J>8Lm@ea9*WpgwcA5C$m%hb{&x%!9&HTWs2*TRSHj1Z}F9?6~iqk08dY@~Sj7G0H&KbrwkQfdZd@DM& zkP~0yk2O+xlR<<+*%0CmhAdFO80Gsc&wwY~*vP83&PcCmjKtKFPNhx-SD^JMvuwkz zUF^`*yBj=L=8M1+#$$_c#v#qnlDcUiJTlNG#Nad>(>IE`3ADf>RBu|=sr)m#Cq&!yeYt3G0|3}1x? zKR+Tjn{P{5r{H`;k23OeyY{EHCnjty`#JYKDO1J>)P7YJ_ZxbQrF>a2<{wV%!U`=( z=Qv4OGWQOyd(Q-K{V3LIZy0aen`@92=JetW4=uZkK}75kjMv>W!wehOr*_4AxQb^& zAhk1!#LicSk`i~`KkPCs-kz$rXrA3n|D+&xoBq50sokaCILn)$Emv}vUaL43tA3P& zz=_3<(!=B+n$JKgyS|lgIg>UEsD|?{zOkDZUPE@r+|#+{rJ!VrTz~4VGwt;;llYn< zS(Zw%eQ4ACMjXa8I6n3WzF+8+-1Fs2`^>BQj&V1C_x_=9om4C6`EaUXe^M^rK#Yue z-gnenLrDw*TZVG36<&*rSY1h}(f%}ham1mj<`i@+xV$VMbK(0e2fI|nkf~h%lv25Z zZ|Ll2?$jS!^61z?7Rsb!3QiE#nfxpv03GL`Y34V&y=4&XD&|(uPYL|wzSj7eCi|w4 z@u>p-ECsbs-Y&z5!e=X3H(XPa^05x5zKx`)dCmmPl%9PrJkvP8@HJMdMY{}#5i(JA z{~Y=_E|h3{UX+nDjd6^=w#m%X^E%kec^q24+gAN$ZR^CMBgQKL_n=i|{vl;)e!9Sq%jlMBMWl-Y0DfF7t$GMH zHhiJ3pO!rZTI8z2>i*8^-ugbIxv+1Zyp&+>)J+Hl>twlxPrRo9l(xIL;I zimuop@Xsfn29)?=Avo-ZhRew7skbWW{7!?b|6ozjLW3fVMK0!*7Zv<|(Qjd$2Yf1h z$=U$dO>|E(0rC;A?uB7^&z}bWPM!==>jjV~qsZerXeytu%Inn*RmV>JBt1Z;Av}X_ zs{DFY<#Z}l?E|aa#9W>r%rYz_A0!E4p_nv$F5CBRUp0?1{F+*&s^8|z3?2}&D?PjZ zHVQoLJCIAWrScF>0S~bkT(_!o-z@lM6-Y09VcUQXs35~2p3PdkFw11GN@hP{5a`-+ zoc}x@b~zvW#rTngoFI*D$20xPT(XcLj3)ai6e=an2E_DUo=tE*Nb?Sij6aY73;|f? zV?YA%AT_855`bM`;#9Auj_|->X>2;oz&}0F86gRj6uyE-2#YcSzkbm1Lt^VO_L=4I zH>xxR1#%fltF5g95aH+4&)oF8OjXXh1$00xz&DzJOy7R+GY!it3uo}z6+I;h^i-^x zVyH?vPl_kBAeSGpLBssq!5p-U&+B@Ec9Vc8W&%>GPz>Nj(C}wx0J%FhL`?o=o)h~G zkhB1+dkl>GS)kI#K!s!hmA)6?-NPc}YL!5KR50}vSlMF9r_o^Dw1JzP;C&0O{VB1} zdX*6>)K2YdA7LTM$ss@h@cL8DN*cdg;9=hZCA}sv4j};0Km&e0$aAgfJNSIT zM??c9H)05X5V#SORZ9|(z7d3-IIu*;5m^ntSUm}a0@=d1R9!pD`X7elH5LLCeFVTO z=>j1=Hc&%73xxDksbhQE-6sH$R1M^$LH^W2N_H3s>BWJYoWJq_Y^s+Ri@Sdu|8?YG0{H}sQ zad>!+st~Drfy_Yb4_4g2HHojWx0u?g>NctFk^P{{>n9-oM}@J~O@Ijax5H5ggBe|c zWS;=9B=+?Bb)dAEu@9MZ0_=VZ=gE!3FxaB;!Xz~zHTDAolopM^+q{FkqSjt}+O><# z0qNqK-5e0Np^4lF24(U(RaY?ME{P373s&6kCvly>(Mnw=5AV%z{_P8#+mVu5h;YtS`Iq3%1Zn^+k5xJ`d|ZCL4W_2 zf84niSWvO_)*vafPcHAr<@1qqaJyza^Lhm|;JaXf)wRB&sxPXv;sseC)UEZqsqGSl ziJSxZneD1MR@3Ba?{NVf=)-yf#~eMG$Es*8zf_B>iSilVUa!X~2$GX=5kDq7Vx|q% zWs>lULhpgBUJabQK<=Y?mFCO_?nYMrYm4A}9GW^=V?e4V^)cDCqn}RN9b0=kS(`0{ z=oBSi!|ld#4H}Zf;VDWaa}p6K(_F#j_rw$jkT#CE-HaygbZ^CrMyAf71(ma)azS1G7}Z|w){^KVyyi(DM~`>p>+OL#RD+pXSzm2?qaEu3db=?Tfg z*fbySo|8Xw#{B%rtLxyC1HBzR=MeR0c|u-m17VeW7z^-axZF-Yi-Nkinkf z>Db?IeaZzUr4t-ke`RNuLm_+1`%rFC&c>(_wbzjX){3a%EXQvpD&yTa`;Sg5S!KVh z|Du7eS}#CU$hezWI|`!aO(}yLaBnqI6WqJ%@^CgN9m5=e{qu{_(*-1+5FE;ohlOhS z|6q9<59;6G86r5IK`GE#7%wz#Zs5EwW)oxX$FpXCK2GeEx@zHB9jq@7gBd97B2NDG znmW6$NUzBlu_Ju*^M)%*=Yws1?m2=-z18)SQ1moKKST7xYb)kRuwJY<{@P|RT(;FO z3c?qlWV9-$m*!CFlcf&{slr^|ifwu59Afni(k@vutVV%qg4q9+%i%-DX?LR^ltf{i zBcs5_%Co-h`^0D6; zf}J!x+$t}<^~_RTxb@OO9&Cyg%)&C&2f00nq4r4!WrU(csE#J}1W9zyy*RCk{M4_w zsn74XrnZ;^*#nEyC;|!&|7+G#AhcoCDB}UgI}CRDDCD*vIQ>oEsb?Ml&w0py;%&-N zDJ1DL@M=5W)i*<-V$FdIb>b^WILE!t^B3Qf-IEai>Kb3OqFSWF7 zjw~xvzSY$eW{4k<_>x$3dQRnm3i8-HHH08=I!?eqMWYn_Pbp9hbfZ4>4AVy+-~#(E zutZ-rL`u+%zdR-sq_5g;5<>s4P6t4Fv$1F?W3l7!+kjHSS)i1_PW3LRYB_e`9JU2Y z33JqfcP~f!&LvRJnc#)(H}9>e#akXkN~!{6-|Nh0)G+$5miqs;L-wC~N=DFkC!PTq zO{3fr*V|q!_9YOIy9cJsuLZ~g|JD}VQu)2nMDE947Xvaqjo;rdaUzkE#pA71ImL#) z1)w-wNG)eWuL*+r%S%YHtOYV5?E`~AgPE2K$lm?car#d^r9zm$*m8BC-*TjH0WbkAAKn05+eBQp!v~ac63Qxo#2`eD=6`V#Z>iAU zxs?irXQ|!ulNlc@11Jo}Q5`uh?%xjwaOeLWN4gF~M-WxDJaFx|mad6ASCE?GXeS`j z4aLxcLHVuw|F@GbQ>C#Aelyp|`8oiJT)uU}&q+<@;g?*S+Q(QU&OVGN(B!`(KNSZA ziaHg%gX&zt_APCT?{@>;0g7Z-OPD}t6$w_or!7CQz82TWiMEA+7LgTE$IAi)tzljv z5C#HA5dVgf`ffBu}9srkUJm(2~$eA#PeS>>djoO zifrd?>n4MUTBai8qyW{)c0C51_^YE)!mv3Z zG8s1~O1_2Sk8&o%4-M<(=rK-j;PFQ^Ji_qBsLf=&@3Ney0SbUx%MYfZrQ3}S73rW| znxEtkZ6S^3_5r4M%oXHhM0x^9;ygoTxD9F{8zWdRFR{D?Ctt?+WGBJqP6&2F9dP-A zP#(L?<$IbWJNV8TbAMK=92gooZ65{zynoLvEbem@DmF10`NajDvcMr&tYRwn_n544WBL}QJ$#HaD17%$0NLX+3*tbhciwAM*fD=7A5E6?0H*B z&jq}5xwehh*7V98ca}*+M9M>@uwm`-S%jq&jPvC9eC zp7Bx3MyTUDxdt^!Z~qHt|I0LfKl}|j+ya906AzCctY#S zHPep0nmqlHaQKiCNrhEBQp0IOdnO^CpQDF)VhcAI@4BGQ+cL9ouX$JYd)?ErZxyOY z%wR%mAL4Ys_^!@b^55ecXEaKYBWmfC*H9jZeRu5(Pr*-bfq$ppdJ!(qYu7DvVQ0(6 zBu!BrS7G*2{1D;oG%s#9m!HP~IeFJwl?ZgMp8h!P$_6b`UY9uR_W{_Kb2^l;DoN0Y zu!1F34r9Lc<{>lcDn6JJibzo>P|W%7>8L#s>^1Kq2F_~p1`ft=!ApGQ8F!R(Ol zj0AMG#m;zaZ+>kjvNqPYj{!Osdzu(Kxh@yH9gR27yd(^hlU`kAR$L2*9~c%T&sx9v zdR3I4>`S`aoi-aC*f@5e<%LQhhvyY5k-36_mvTJGZTHG?+j;JN5?tOG*A&lR7QWAzu3*a|`XLHc z5a-N+ijTdkWPw`c&if#woNUu}lJSjU*7ivHN?1$$#KM>2XN&kj+;?=Im5?dn@%xE) z8_uah?%L6fx=FPy#Vt=0DpS`oYf4*coh+msh;WIYVPT%DlT&I#zA$XCwl`Bjwq>`f zMBsSbauM9dOCc;X{$6O`CI2Z+>r>{M*OsR0kG{8P_0N*$O7Z|m2IIsokh%Wzyj-{d zY&$QHpJVr%E65M@ZcXhR_R!ltT*jZIpp&ujWRUf?&h_nZYrWLCGb6KU7t`Dk0b4Vz zU*A~tjiK}7^RSc$htqhw4259%xHC1WautfHFFj#1u{^0PmFoj@R+;p9D$Q9-&fdzgSgZnyl<{YW-OrZmCvU5`aiJ(QcKAj&J9oH4$wAd3oK70>MiPtF;6JaS_$=dr7N z#1sKXAiWeAQe?FpWfNrQ>wMMbh-0Ay)@&3(CC;<4*3A=Gu=0CU-XfU%wydWwC6yM=%w5{ z@wwq=u=aD z_fS76U7$0Te`NQ`h{i^BMqQ9+sRp+%Bi&T%g~nW-RCw!%rFq`coFGYZ*DQLBWZO~h zEz{5dN{SkUo6V+-i53f!^so6x+0QD>H;j~S6 zQjBWOK)WtXA1`Pw&%^IrJ2g8^u&5WjN$7tkwrRTSy6xi%>PfZ>528hi?Y~G*jO1QT zu3C*d(|d=#v#8~(j5JXRU`*cBnQF?hZ!&*fzI1MCiI}He&Cn4Udm{?~05p#~9Drnt_zrv-jTId?>ZwV>xbUmG(z zbb%p-7gm3CB1h1l$g#(M!DkMhz+>=LE;|vBJcW*;YbkvvHV76HHNT)Y++8bd!ui_Fj!C|x6Fpo#^bS^B4*R` z2V{i>A_z$OCmy zICzKW3g=eJy`_n_dldNUuhp3f3O(>jRrU0IVpxjF4Q(N29JrUXDkQjVHI&gdrTlCr z!yo$|wA)PuVv}e4WPhB4Sp-q6PtwE!|LuC}D2E$b6L=>_&6{J2>Cz~+e|17@RUV#TG9{d6jRbE>AVp=n@0!FI&-7a@dK z%_GAUj7>;c-D|yv;2f(w4PYmEr)o~u@6Dkp!W#Xix8+1H7#6TEgzR%#x^%RS<9NY7 z%JbYg&|{{m3|=m>N9a(z+PGnR6um?#UzFy^?-gXLw1DwXN&l!Uvos<|*)J_{z`~s= zS|>V#S}MQdiKvBhNB4~Hb1O_=626|S$31QB-t|7U1_RJ~|MaX7hK2Q;vJh+sM%GQ3 z*MIC!qZ{4X)hbH955$E88RWa{buMR#z`Q;_zxSw?V{QIJ>WwW2W$uqs_({NXpOIgy zscxJ#Wx|lAOhpn+>4lCkYflMa*h1r*Y86_atorPJ+q~{OF-Ko}@KM?ld&H{bh}q#W zEARD}hWFN0A!$0JY$95%H=$$VN4&J(bC7_yk-V9xVIJEj!hVDf?s#u(A{H9a5!NFB zYRN9c{PbL*v?F)NZkT+-jN1nHh$s-cCI*76JUD|4x!2o6vy9}*%@v$K(|kQn_AqJ- z%$khwEl@2yv3Tk5RK4#LAxW>Kt4^h=_MJ{&TvP%_ijWHzU$Wcn7LOc57ZpBQ&VjUy z&Kh3xX)?{PV78@7|nSJ26HeT zMj|i18u9^|$pI@(Mj+>)`^TWB&UpY}EhXLbf(Hf736z6mp5H_gTp?m!xqjKmUW>jwfMS%2wEvhR9S%hDxYM$^8hUqIH zJZz+Q1_)q3I21;E22^3hx*DOY>NEpKp@N*>K#aVP#uV-VJW~6jUDwZhyg)Z^n2&st z?=4C^0mMQH=@?sTUx;wZ0+3271X3pcW4b?+ADQMX&m=*VN?6+4^Nhsa;t2zUHR?-0 zs*?k5@3(|C>E+52?6U*no8|H}$BwD~s+MgOVx{ibC5pK9O#oz=eoLlTj$ z0LC~qb`Ym+3K^lJwn_4NJZ-A4MP4_2J4HkbkoC#$eAPgnApjwNouuP*?#sBid9-ut z^}QE}+1kufkj|zt%`ibC=|eshQAwz5yb3}4XsJ?>Oo$dwYV|+E>b}_mFYHp=T0Uq@ z2TxH380=02xdOBkBj+T!WPcghiwXRA0lJ`x;*WJ6*q;Z39lFdp!-i}$!cPq`!z_k3 zve#I?P{|3G$k*0Hz$IN#X{A-b%p`>e-wcN6jO+9_oOP z{a?Z?>R6x)hA20kJ*mnh4UfO&D>9>WM9IUrd_nSSoDYoriafBDWjGYPEdZ~+Ns5He z3X&sJT31=&DLSNR-1d9{d9-yX(NTpeEgFv>QS->f)2VH`C>^SFV_$~EK&7cHDPaM3BX=yJ3j?TsC&Qv6?4}2D3g>o@=oUpES;zx(iLhiL7_`+((+I0jKFZ+iOxzX0>jsQM%%Lu!o&te$2sRZE4-7$J;M0n zAnddv!!o0r!tC24%Sl&gu98 zl!xg|1wc)e3$bwtlACbaeB?~j(;M0P@rqT+_yPC=0Bh^SIJ=|LZiw$D2Yd0s6p}Wr z`z#zOQ6)R$1Ft%OW1GMPq)x3-W#}f~Bd8-dXB$+S&QUy6dc;P4jSHoy18b&vPt%&Y zqp7_;>sb0grBRGkV{L<(+*FHNOgJtL+<9f|t005oO6z0U0Z1Zo4wa04Q1F_nfm(Vm zz(NcQNoqD=IdKk_4>8Xm;jB8nf!cCYvEn2S%rnGmb>{;naKM) z?b7Z6_!gm7Q}AlNhQScUHV$a)?i8TZSX%_RF#cLrKj0SvPCF_RX5%=>Y#&0xX_Qq0 z%Wj=Yta-fl&|}1FVX-83JU@>)RTF2(k*w(5J-13gysLlL%Kf4|oyZQC=X|09*@%9a0 zqu}yFNBeVGAC9Ao0qJN{PvIfp@Ook0yZkA2-6K}{(WO0Oc@p2PRZJ&e*$>JTzeJB zEpP0D^z7J$K-z*tvzE99?R+`WU88Jtv!KbdmSev}#U7@Ae9Q^j-!#DJ{g7YP4lodqxw=ZBIHP*Z71%2n&WNhqO(3}!j9}HN&C0t zv<*VY-0j#n9y8rh3nj|i#&$u}jY=z|k<7E)gTeQ-mr{>ZE~^IxTi%ikhvq`T|gGPf*!yEGL42g@%8W5dT@GvUZ^N z1Mib2>)?v2Is9&9b?b&dV;1KnLiM{$&zVM*?nd9*&e@a4)vY+!U(=@D8&ziW-ts3R zDSgaZMcDNl{R&-krDYE5LI>l&6{_p}@GgCf!1Di4)Rgp+019pD1s5nE_HnXfE|SUz+?1V%6=S(d&N0{!OKSXmjd zuY1wAaUbs;+m)9~5m?A}p1?M#>cyum&7K;GUEXna$evgxCg)~NHjaF=gWgu{j4gXo zQWhjZ+=#<%!7J{LIYyT}JTrAf2nGuxMS$q`2V}cFQHAQwJ0GXvqnZXtQkE(eZOA4W zp2t(D1$F!;v40ikn`S^2dz}4H`DGc;hKCcKd8QgS zvJG|DbFP~YZG<{&2O8>@pgZ0N*LDoT>U;evK}4^jTDHE;Qs7+l#j(mvX+m7;A;Z7; z%IA^DeJ--U0zp%HvTlOTX%4&pN@=h03V;$VDp3JY;k#gYIZqbbf+|c~Nw+m53~-Uf z7%Wfr0X|l9Xu_6F9r{YM{(Q%gj zsDde;TGVffjt8AkbwMXoVbH_nmNN)O2B;`T&ZSg%>U303iMGW?7U6)!=kmc^69XQHgIeFW%w}8Gz`tPuN?(F%=Dnx8 zmwA}M_mgk1pp3zoz5z|}!~rPtOBgpA9aNW*#{uk~b>YQ3vV)#<0{9k*cx zb@KlAuDkV7!P{my=BGd#JuTrC7V{jmQI;vfC#iY7!2^N%(N6JA;y$3bny7(nL?Jea zGkx&WZ+R@+;t#-Y-XyL0FNdDr1)$w`YSebW$WhSE{ZC*KcLR&_u~N}^qIzXKKEQK2 ztt|xNCc(430ky00+NC z&0Iz{s=ud)&!*KBDSB@n8WiLZf+mjBzg67w$5*MzRN&oEl`rt-tIjQ^ES;j{O~%SZ zK3GIj>4ibLw{C%W&=;>$JLT6}wVB@nCkm~_I$`cMjz$Yt+|Oz8?cKN;ua`A@a0<5^ zzAWBCp+ouXQkKOF_F??+o^X4g;j|$$Tv-MI(KMRJaTB`GTCzF%F7L~BOQ`UWa6isMZCI5{B}- zPxq1$o1px?c^Da3CUHYV>q+EOXAnMV#GrM)-}E{ZaPaZO;!<|>@->tqYUHD2N137X zdi-GTnXd8T!-;Pqu$UOYO@8ysdJ-J{j#HO`{*QVg^!NyMrq^6-{vhiq*H;BjsycWYFdx}q%@ ziC{T|*7vF@iAn9rYS{QaDoUW>)vh=`c=HZizVa>b9o2S)$bqPJqZ<-p8~Oz~<(?+; zq($F${@9q0axQ7$yS~E~Ln2|Wn$W{QeE^p)@FNM)k!RtEJ0PR)B zf&3#

SB&-eh_n{U$!PMjR%@SQB%m%Pel>>9=?_#sG7nm(H2&Jr};s{$C;vQ=Jtu5&m6q-tGu^V?6+s1X@o!u`lYUu zj7jBK@efm+AjeTtk@gT!)clI6`0(FR5FC$!Ff^7?;jV)*nH6dkzuZw`JF+)$tN=;z z3u`-rmxk5HY)rT?D=tejnK|B~AAh5UG>Tf6Mt3_nZr7Y1SFqM-4IsIOxTZPrFNPum zzXoMu4W*sSEZ4V#)-p|*!1i4XDcKqGNKhWX{)$r_y-=!kIj|gbEgUAQz7Ug`RLla{d*&?f1yZj>{jsC z%?7YlAFUsdlS8daPI?1U-ThL_A1R$0_ope-H0F=VoF{J(Ky~i;x_W!o`VU&}$?w4) zZZ^#dxcq1XQ%qGrlad~Rt)A}2rY(rzxGyQra2agmlpq?X_{-P5Alwcczo2wX9E>tE zBah4zF3&vD(O~4Jd{-8Uw+koVx&M5@8g*p8vGUxm>&;wXSg*aFJs@{H`~vrlY5lX= zroJZ@o8zcX9c|o$GLSGY(kCS8M_{SG*%Sb_O*)PX0Av{z^R$v+H*=UfW4){7U_Btv zSx{Qds)!z6{f-EBCAwdv?$++q~85lUQSsGV9C#zOzJ5#BxGng8~9K4M0C$3vY)y&AwCn~Hx zfV3S%b1pcw<JfQn-0h zpNRBASy~yk@UmkO#oa|G-|KPqhKCCl5E65apvA3^bN}){`?yAsYxBvmrEpMK9|6dF zkXWee`%@Z2-!-WY{a6LP=UJx503q*o*zRj6RPxKw-us_T?rx~-hC4dS@WW#@dHoTK)ZFOEPDR zz`C^f8gPFRd@f4OP6{9!wF`;)y2!>K*R+Fp&!6-IIXu%tT(PT^NcIzl?H)fu*Q_@f zJQ&u>#A1EFnwk2ziRYAdgSxQnjaM$z%pKrYVitMkEEi}2*K?*&6X1&L z_h#xx+-)YlK0bZ)*+fs+>G3Qw8~6@Wv;Z&xw4EnwpC0_}?0ds91bGspHe^MO79myw z00wvfeiU35Z_A>N}b;H=oq0(e}f}Vb+YQ#WWe5G`>^e zPmd)EfXGvqmM``g@I%hh;vW1A?bkfQ7c}}j2pA8*<7qr^PdKfKPHEqKxj|}n**}#CB;w}CChF!xUxaH&9}PK0JVtu2 zZ%(%*smT;h?Zm4Cm&H`wL!UUc+n3k966sTFIvi(z=L`SMgub2a+vLrw=DK7b*U*A5 z&b6u0Qm%??Rz8*^2YV%JkfanKw2pJ?5>|*>9K&((wo2Y}4jpir^P08d9&yXc6-1vU zr>Cx^=$XfoPo%WjyT8E)sr8FGe)pNn<@f%IPg|&U3#}LuEn2E|)9Cg!C-%jsNvb`x zXa73V8*ZjUa)G-PaJiUrKfMcelSb`|cL}G(+`a9_i`reY-yq-_vvZY?%xr8QAis{a zL3tPwr_7^Evf<{+9(RdTit*0ssO+fa;#8t{$E%SQw$!W3UULdJdEbuBC{{HYR&ep{ zd@RfT(X|xjyS8F{tk(S6-e>q}($a<%Vio}?Hwwc`8`+4PK=6hz<}jEwU$)c1cy8q2m~6xkHV(8Nh9h(V#B=%shKmH?L>f%A3i_ z14f6%3CUsqeY6IwMlRk~rfL+o;RmU5(Eq~rBd;LOGh|WUQp#rg8vAc~XhN(|t(OV} z;uVW7yOZxKky0${iqvHA6*#a5YJEI$H^AqOYqA(-Xwh$<5o934jxlsxPCpCwk#6$! zQmSgvlYQ>qKU1%%y+F(_l2ykJkhqFC6o;Seqx}i!|KC9u{14~zKb+5h#QD_oTnfbb z@R9v-HRYC+k*H-&6w$ictsLL0;W3`*a@gA|W<991)iVifFDmn80_@7hj*e4&Km|-} zrh6Wco*V!@{O`|oE z#a;>d^wHs9``X->EC7wlrIjE2Bms5h@aOY_u)dR@ z{C*jf0SS|KOa-ydhX7R7*#m`+b&l+G;*Tn+#V6sdzo(YCOU6S}Ke*l_LLG z*wp!CTcx3i%eEYLhlLGeXdKZDfk>&IGvmcXp#oqS{o<~f{1Ye08Who-?Cyw|NZNeW z^|0ga1gMG-*&6aZ2hsA6;2e^Hx8?QAKMx17l2y&$jY|=gIVSd_yvi4^c_mho4i<@&i^cOD-2DjD^yy=3p%==)cSYSP&UI=34$(bV&I*!AHVR~@nqZVW>q zF5AL!Qr7zuocSFmL&h{);mEOFw;C(2#D}%FOq>Wwv*V|h7-=b*jt7jD{K!M}O+fLU z`yoJ^^`x$iqZ~7)>kDB{vpLVOMIDkt<0+@W1tz>MoO}_`2zI!e9s#GloAb9oQ-$H> z#_HG9HcqWJtY<%$UQvXPahIm7;>JuEQYF<|HHi7UO^DCQ(fJ$X*IorRr=8C-Q`ZVjj73BMMcb(suoCJ#=DN>!N8gY@L_cP4;1R z$FvHYD!>f=n}>bu_{pdm|ZTgHlvv!K#YW4FIiP8d`(hfT;YU2*u9^np{JDG#iTvVRI1~VKY!JZrJ((`3_=~Iin_l`KQdRs1f%qQ;;{U}`=tntIescZSwC^^@yNBi- zu``=o94}NBdz!~YSG3}T3b=?l0~lg4r6|Yq7#S3ZT;D)RUcfA)nr`GY%IgB^$)N7A z9+dmU#~w2Qj1`KX1M_@yLy^4(6f%C>6sl~_%{v*fY`D?*BZZZ}y#$W+-7xz&BM3zP zl6J>wtfB*;-RFGZ$T-Ah>NWNxxN9S7O(|>S+eq0PMI}6a5m`3oviONNFVy^ru4|Of63pP%7z_1W`mXqfToDc@d3y8 z5Y`Fqg-J+JV5QPZX^d$%+<5i(VfDc6T%;Y97h`fTES?cXLQn$ie@M#mK@kaad(g8eyri99?ZM~V3<@$3we%3 zj@e7IedXc$a6hyD^Z}9kb6QTUt5>%{WvAK*?HUfE*>Pw#ymn?ibe|O^&T#T7Z=eR4 zV!rqFc}d|*rWyoE_ zk)&x|NY=9eKrZhK54}}2xSEvW#_lnSOc(oCGMRvWEBfxd!0s6WmHR4){j9uUWwGcy zW0n1~yykpj39cOvQYT&KEQvj-K%a8&H?cnVR}%38w#hN3fsTmYgc_u163nT~CRC2? zvR_PaPmI^yk(Q|xv$VFi_l)jIh<1dg7gjPlroqB$nT4(48Hj!@%=ggNfmh2rPy6j~ zvvvCT=~QLk%*%RR2~`20L=MblTlv>({jg(A1cl0xLwD1~OoMF1P1{M!;PuN04aeEH zQnjG~^JMWpTi-E519dP4N+#wTKtII5p{XqQQxIiwQHkGUewhJCWHoceiWRBUnmhojc0BpyN5` zrrO%oee1<%msYRt0PHO`Ge+Ul{!pKbAu zU)gj5(_@(+YY0Sg!q?+K@yyZ5R-PXI4(&D`!5S@IuWmL>x@~8BFe)n@`tvp7-~1Dq4c9Q3$PSvnI;fSAJ*Pb#Q(b+O-Vs?IB9czldoAH?sfTK zz=UEqqFdb!aehXL;0&}9w*Eg-Ib=?H@kr4z=dvy_c zi;mv%@T;nBJ04`^XKj_)pbd8I#p;F(F7yFD7@>YG`)WBo+yyAr9l<~#=2+rNPDP3|kOcrEn ziAmC;k}F9tV0>aXTC3syY);!`Z1L+Fq|I9pDL0r*sct`YM+~g%KnG16iyB}$_~#2O z$<(56yPttmF0#M_*fbG4S73YJ-s`p-gLa0NePk5=VY>TKgic(mr%C8Q71&g)nM3bc zC$(KyvEo;--d3)V!VUXk#)6UKmR9O4WFt^wwdZtmg>Y7Az9QnoomWV=hykL$6{9=MHx`e zMGNU#q6!$sdu`0raJog`Nu)h~1JF@AAx0HO@Lmsl`rK)8fEoH2=y_dfV*pxqaqDJ$ zR`0>yop#q&9_g|S$3vS);+@ZUZFns_QVn7=EGR!h+uDrFM`Qi%L>BzqN#f&n6|u01 z-9A2A@_;wBaefla7xy1_%K?VY?1P)QQ}za21Hd0h(Q86(W2pv%6+ti3e?)8$sDR_W zqdf8aphRuHr~N5K1GI%ma9b@xsDx|}*%Q9Hm9w1e)L@_&6Q{>v(0{Ji5ONbDxHUa= zjzaB4F%PO>y!KjKEHXtdX>pMaJYM}zQMx~BupN7rzw@#;B19R=zk8dZ?-afE^1KuY!v&dA zFe3wbWDgeK3ICw{_vAJ(wv3H@eA*plV@h5Y@z2}A@lxGhfv014{YbOvrkJ1&RFjJK z1pd$3+K0VALZM^+6QV83$SbE>-o@@Ke>oZ$dg`yn231fe?xOi6?(cFv5nS%AiAE=Y z{OvyEuiQjHfqWNZ87WUkOKI=$!u(82d+yrO!Qo%_%BwwrtC)%{R{Adp4^IUvz=dNy z9)O-N_|Vu;EOlHm>IwdT!)tWv7d|5rr{aAl#0tuNDQe$~01xXDLT}&1wx9Sb=}Zm; z^5uCGCq@-@xMOnQ^JeZPfUQTLYLZ<)knjhz5Y#GSUH6ZUnrixd$2BfstVvULl@-mm zc3;s15*=*JcxJ8jsHa#S>hv50stg;8J)96Inz-kq(R46zbZ}gW@>2*Ye?n6(|4GJcP#X}O|21IB!J&l(}A z|JZcQX=maLNP+D+h@Dv{0A&~c`8Ve(rk}!JwO6Eu%-9=LWv>M%f-;IP?$y>i{yP)r znqam)S^KOPF~!AXmEV(i^2V;|gS^+v+&qdx>x_BFmnnIz0A0>ZHF7j|HFfs`xp~;g z@Uc8QGe3qJ!x6Q7pdYu{jFNoxMtf%?Qf2=G>NuOvfxooJg{^oiJmPNR{_3>-paJ zFC{%(nTMI$bR0DGe|-6!mX*>6USB$^Es#P!8UPak`R32>_zPzcR;qpjj9N*5jdKQSV@liAUHTsd3M8`r zL<;!+Jjl0}1=*O%!*Boot@|Jnf#Q|}l$oh|VuZnz;87R)r74X;5a1KujS>?j^zgmq zY;xiyUt-AX$y6xTZGTqrcN*$H6rTT69@hU9_5HtE)MucIj^CnF5?e}pqz*dyqOuw$ z8xNF6H2M)RP*y}kC+-=Px1mx$p0+eE-oyuS85&%1Q`vu#cajKb1}7W{@986YG=NXE zzn2K}m+n_#|5CB_{RfEDO{`rg9++!YYzBeKn}pe-)G4cTh_T1-^{Fkqdyc@0q*_qF*+ zERU@KB2Z<^2re$yKMXS!J^Fw*J%=(Ig+O8kWaqx2nrdZC8W^!;%YPG2{xhX7!?lbH z&}nJVr)cvLVTGAA@RhxX+Ex^nHD0|0WLb{M{9G7n6#qp`Bv=X1SpAW^3c_4%edZP_ zU>pJoXy@TBW9xXzcibdrCEO?h9I&N|{JAA;f-rXJ%@sDNh=LL!15hdqkHF1GNe|p^ zLE_QdX7!PIzDjmA5I-|iV8vzD7!<0)vEh(@)gLd0I z2U5JGSb&;q$e`@A0}~pG^4KQ8hL){|Ex1#I%sYVe-7ZA2aD(RD$<5M;nB=da@@>Zo=0=0zNpj>X9f3nHuK3e|R{1mE@skD=@-B z)yRVRfR#inF8;S}@#zO{b5;H=@!6gN#RCB1i8)84@yJyC@o`L^y^4><{FiJcpW8-{ zpBIf-v4^z7b>?%e`BePITVBvW^dGq|+&}Gi+!i~)O;X-qlPp+cbxz1ZZjBp~z0sRs z1q$Vg8+bCQr!sakkn+&nI9W+2OPX5Q)=)bIkO8KLh^Wy3bL!&57k=_cn1nQ77hdMX2%?%U zU?>sgh*6a{ln}GxDf2YV4qF*GE@K+ zbg&TM)cZ&1CLoZ!crFsDUnoSK0s+Qkpi6x_Aw)UtYP zEdP{KG|xh`M_pfWT(SQ(#`#TTUI>rB=95VIP|m@op(#h(QFP>h9-cfkzqtoa>T-V8)UpwdQco!B-26tO^59-XZGPR!7gqs94?@aBAHI89bHd8C!u`ox zv9;Cj!oZ*_h~vx!$wjL(pkqmV34#a&Gu-!yS@0eMd6g~XyzPAa@cSMntz-E!aU9+< ziyi}4jR!BM`qLW?_wRiE%%nBLS@we&PMjtZaE)8e&Y0)^t*Mu)Br18>H?i+)3?IBq z112cxx3v(NdmmN?1*#Mq#(f8Vvf-N-f@)5&DlZQJENatqZ6E@mI_M)1gyqF(Vf60n zZmsS45uX!q*g=lW6eE!f=bp@Y+PMG<$t1yPP^1N)bO9RSuQHz$j#QA|4K&^T6$cnx zj3n+Cr2zZm{q<#y85Brsg8BQu)+z)`{z6Im?l6;%*E=)>PQpWDPV30^9^o}_`GurFdIt!YB1(cIw#=L*6QbDZ!DR2JNf<*v#%^Q%I6gS zmHp&E$;Y&3o8n0UPfZ&dZA=qzo1z1m-X8SinuEC>E5F;aDv~fO3ehW z(7L@cx10|&9}F}X7y)p>yfNPQC)Z)7ShV2Y#H;o&1*0}oe$!hcM~7}G-tYXdj+1e| z>|_vyrc=|;_mDb~7PFra?Ud(S~tBB?2=_u_R_RK5hd-^jkKqRsc zdiH3vnascK9kQZg;sTEK5x$$^GZX&)W$i1;gMn8NVVi!(pWTPP<-`0N<~KA{>fx4N zUOn?=0~5Vwdi{z%k~`O}0uu>`Uj*p(d+VIZ#(1Bkqq?~O&Y|hAFu^O&{(uRBAR43+ z^)u;jG;&p7E6cBx`xk^D9-v1AG3fnQ_j?wByFr|x_>Up1pHYF6&y`Op!9Xq$nLuXQ z0W7U|?A0OjKvMo%VvEjg+s8SeVNI@Wi*FHx=qhqG{IjbK5GLIDkAz<2zm((-?WkN-bO&i^Di|4EW_ zZgWnD9iZi+hre&CU^zM`*pHO@ud_>VA04FWuI>KO!0Sih85ZLkMUZ9{0nE;`?S?g% zf1%6%2%tl+-@Uu=JRB*S2uLf$Kyi*TV1(^d+7D1~mFN-I=|`}C@t8bl5CO(F==@@9 zi^bErcn^&Hf_r-R1DgTtnBP&k#^2wAUSa(?h6op4L>OYfK97k!iVh-3IYw?K2mg*E zrWW&S6?6x%Gv5)k-+ByAmTdlvdC2d#u1E3*YGohgv^-Y1{tKvOJ`88+BXNvmW?rmP z{mZ-omHm=DW1vwvHyg3d^>lijWO3ZjNC+iCy z%JnY}e2f?XA^xvzE2Rt|{B56|C?$?jahHM|MBVre_P zUUf&%(z5>GB|UxQgCbX*7iiGyFNc{*_s_E*iAc=^3%odKO;H z1%#iUY`+@&wV06WfSd4G65?WpFi*PevL38=_gMbhQuu>WKP@Vbuv*LO1$l++j*`AD z?az2s(=6j&WaoLp7;a%Kr`G8aJtL;|)}Jp!Et71s3|U|S$w zqQLz9K?nT`QShLZuHP<GTS4K!p(XT0E*6ZH;0%M?y~bKz&^pKPHBA z+dAHT>!T2;GNeHyCv6sQx@CV^jjDn^_TJpHC6uddhh7DPo}!^zE)0wd97TEYsbvAe z;Y{m?AhGv8BA)Z*i}a|TO2A?%z9AU~GH-K_W-*%p-TpUOwuUY3p%z}UU_IBbGKr{@9A9`rqdt`_}nA$!EDW;aigY$5c7SF8ccUQgieDh_0g z84;^KDjdU!*+KDVcjp_xpsq73)DX#u=^>Q*XEC zmy!MuaqYe(I?Agr@>=dijt?Y+G!Wd%T+3axiwb86sktrnK9HQ%Jd00{BSVr5lOZ|r zkt{hHsj)8T&dAEDwa+r@oPDe6xn+D%>efA&b=n;NY`m4AO=^cW=*=6v!m*Zf#HX(A zYp3LB0N)&);DheZE){MmqM^A`9|QVtvtK75hS*4}%wt3N2hP;} zk0<(Qa@$D>?uc`c$G%$*&D+sl<0*4Cwr`Tq9@X}aN!#|lO=pMt&ybB>VY_uQa*vA0 z{^K_CU34=SwCZiEpzQ#{|516w*ATCUi;X!9WJdM52kB7RP6c7ouWM{0_4*MyzH&Ea zL(m1ZkVa3BNaT3jL9hhmIdXxdiZxyy4TX}%3!GK}KMiERP3^0{H2Mt-VDS4e1yUKu zoU%op9O^MHOq5;V0Nb(c*jsy2t|G+b&iDY{4z9Gqs#3xSRuIAF+jbs7>Ylxq!xr-!8DdVcoHEI1c~1kWH)-x=r(7mp*a;JP z?#Hn@V?@0&B-*s$hGxNh9=aoTPqxP&niJe~`+=35N#O;k>vS@*7egyHB%AKa5~qIf z=&*>c+Fa4c&g!9+r%f?3No!%R$HwGoBh1}0Y`fx-b6hB8Yl)4>1FJx#?uAXtOv+p` zQS*$i9}X`!d1=%j4H_~8lq30|wCn?|HihzSm)5^tJc$pIhflKH{B7`BnwP(vr6&Hd zG3V5+!A!;EFcD(sEg*fkaQ(jPxY(_nm+A#H5sBp)SwZq`o8SEkNm9^WU=@}xO`v){8N8dH%lxV^_^Mo| z!RIw2ctYlcwlQeuBU<_EcV^&l_VXSpOvLpXvUaIypG~5 z9EhLuWr+mD&>5ta(7*FNcv~F0#+F1urprwSObd^)H}2{DDP-$~ z6lr}hrg|vGr~dq8K7*;IJF`DE7)SapRhBiRg2153-3~7ix$8;=VNx}XcM`^>z7*_% zT}Fm{a8fSvJ!y4}m2Z2#QCrjpma)45?9|t@XN}x!A12*d2y~Eb@qdxi_KJ(67av!k z>o3!b0gE(MCip`#=VSl?^X%D?qAu>y(9nb1GU1*&syRg9MH156Y;&?`s3rfWBTbNZ z4Zcr|J$?m5SSY2YO?=GCGg6YBj{8(A1u4=LU@|^I-xWVR0Gn>|{NOPdC_W(=C;(Ve z?1O73r}s@bvLsckTSwNi`TodKK}rzG2dspAXE-3)xL^ShWL*xhyAH=xLD=wYAvBat`f9QvNrAc@EDfdFA=!3#aDTmXdTHFhynkgXW(YpgGtY7v3&iUloj z`+#%bcYXbk$OyE=SWg@Po0^i9xdQfYH3}?ZJIn%7kpdcV*+qhO8!jd@*yk*>{wmP4 z5JL6=HNjvD0&zB={QhsBu|FQq3nJrfQ|{m>=L#j172$&=VU~8MX~c>kv-dGRA0WEf zdyfI@tlHDTH)}efmMPxGn?-!!@i;#{o)$F7n06Lp0}IWdtUrhgHjw;$eZ)9cDq_S>f@wi- zHNV+SFt`Hi`Ri(Eu$V3W7J}fPd9B8u)Qn(TN}L-O1)~c-2>Wqv085fghr5m{Xpz^0 zZB!OEzyO}wty!N-jujuAKHW`quvVU5_b94B`@LD7La@z(64xhe@i;C4F%I=rDhBUU z?)rXd^bSPuLj#}BAb7klm@xKu{ps`TGRcUJR}eM@ z-LTNq!PPiqy;nph*vQ6{Ri5!c)^1O}L>~pY*~xsNt;2oJuqr9-Z$f2hKe_In2@h?1 zzY;W>KRo#6Ene6M1GpcFXdUf}6b?yti4y!SjyU=5IcJH%?US8(ja|$CHV{!h|9Ag=yE%#ER~#)I19xg?Jo5y+vInKNTdcnO5#Zb zJk(0sMkLHi}iAHp-D&^ zk~WRtFq~w(WI{^F`&nb0j`)>)6FWmi9eB~T_ru(1o&7~rK>u0nz=P(D=dkO&%tg=q z_i||)T6xWxYL$KxDcl=K;~ZAC6I`(MRGi35@Hwfo-+t1`J=^S1I}Kb@&YL;7WpKG_ ziqIsU!JUAjNMir)m&W@aOXCEtn-6E?Ii18ID|v z&k((Uh|aX)g~D#O=^PHu`3DOKj}$UMP_P|D1}yVzGE6%i`RJT>BNaE*RetP2Z~GAW zgc0Z$s53>yk87k7+d1Abf`kC54WON(orOmyH7%ZO)}Klr@vFFYUV_@oBaK~C_i-wY zk==98C*2wO3{;GC`4Ui=0E}w0wupPA87#gq&veUXZrQ-3QMz;!SL60t)kJX8tsC;% zv!-N_3eMFcn1Ordsc95Xtqme}Wbd@JTQXlkh%$0?;=y_6t4hH0}L|D zzct7hr)*LmG?7eP>r(bY7>VRKbv!jZ!}#cgrk6LA$8KlQ*mH^Xysf4HI7lsW_yJue zpHBDkM#bhit?CXl#S8aF-S_Fc^0a_~!N*huUd4GIF0DJVjnrfkUj3Lwk(Qa0PepYp zt+9`{MCG1M@w+_aPR8%hI#dl0R_MkmPQ#;a9RUrp^~2Ib*f zuGP(oqy14s1LL$*0#r=@sx*lZxPJ>tQt-2f7mXBYqGWvq7D68&q8tTI*ghRTp~K-{{5Tt}D7{6zh0*k}kX5nOfA-x63V*a^iAS31g-y@P%jMKYQ47KcRGwn1; zV|t+ejWnQH3aGQAitYG%>@~^U*=_#<DxsrljcH_$CFrVz zpNMJ6st~yk-mbnHl9l(mu?^ihu<4h1?A$5rHvLTD;wyXsoaL+}LYr%C!*;_;a2o_t z{iXraC&o`wOL93*%hj;Fk!RW=HV7&{GB2_mic+z;%8_U5F}B(Grca{zuh0*CC+>(Z zK=!gw7vi7S$y;`Qpt0*- zy4-#O6am39^G~)F*7(VT#BAI2_Tyz%X$p+=NUNNSDQPU~V!4-BC}NR7-&;Fl)RLpa z_Dvq&pV_}ytUB;M41UDq9gh44CnHO#_6#W-wu;@-VGw4L?G&$iT+nvE>C5m72w!;- z9fB&es6qyXXRhX}Dl8wm9Ji`@z3O{z07_9vC2g-lPE5VZJ2NTlhKk&`9oyb=G7()c z(X&sJ+Lat_o_x@{!#ZhbYfeV;z^6}=e!56U3Z~xR?huZ{_c4=yjKc!Z) z+*xRk?uJ^rxJi9Y!g>H%e`{*khO!wtOYbW*r+Jhco=)S-ar$@#hp*Ts`8z|wc#Bg`PwPWDKWQ8+qAfrxGTWov0GIiih%e)cf~(>!IL{@jL08L zkXO-#G~o`9lca?^pSah=BhxI(Rg51bWT+FJOnPt-8v8Lr}A)4deaU9a443c92R($P+;HjyeRV=Cs3w? zY|JgrpKu1-l~a+BEQRNi-C1mhwn$k0YmUbqN*l+tk+W2^5C%$r1lH`F(tdII{NHN5 zKg`+$8H+(Kfy76>F7@WhoNvFUXk`ls1`~rN0(eIFnV*E38`5`1WpS&VbYW$ThEMQ> z)PVUDo@nXp5oyp?a97Zr;KTYuDrx(%YON_lwiKIN3QLhWPq;^wx2_tjEW*Nl`s^1A z=&Q?RD^0T0nKaMPMHiXhvmDhGAi%k*oM=$L00}0h}%LZJVM+C^5PdWCjAG6r5kVwe!rq8lq zzCvb|PaKnc3)m2e6LV|D_1om=o`JPgvCGwlB1FeYF-i`;$9fo>p==yayO)92Cr2?z zy{&w!mu$`-Qnn{9@lj|-`RG+Hq}*`W-XpOnOxmgDDv4o|z_VczUEI~1om0(Oy7-Y> ziZg%4AU(DhQW~iGw(;ADRq=ZH1na&;Kd;!SEq!!H(8vfcjrmf(>!{!kYo_bx1~_mZ zcLkm2lMbrGpSc$5m?cCaW|`32AiQ>I@5ln|7Em=TF+ZOi;>aI=kSE9OcOj7Pv5Bpz zq(JOnTJ-o9$%AB+d9^r@l+Ky?SHOW$pkD1ivlF9D;$^E)oErVPOiM*b5~V({+8>qT z?RI147e#mBCz<%Gmv=ElS_gguFIP;WHC@+AdXs$$xHh3G9q)twJKy$Hurgej5PlCF zl2dSVsu*B})Fohp0f;ydGCZ5AclAAiEU@5-<4zF?Vtq-Wpl{rYRJ|DbgM2dCQT`W5 z=Xr)7PW?vIKRS#5wl|0MR-7rg62T~nQ<<$^@j@S_*2>2Mx6YXY8*l(IgMTpg{vB5o zEd(7Sq6Lw!HcQZ7@+lu^)%eCG8f!Gx1!AZCOO*6%f+~nM-G{730dLMlG!q-UJd@A! zEeMQ>h|*Mk1#G;JV%CXtBw#OUa`gdAGEljZ3G@nftLnlMlz}rj_<_9AlorzZVKi6K z0X&}Qr^kcY{ClqGBm)S$L?VEZF96uwj@nsh>94OW{B9k-x?u|4-v1 zx&*?P0tKG$ot56k87In+YH!@A#~Nm)lX#QBHBF-5bVR!aE#d?ckrQqc@|O*5ASMOT z%t6_O!}q!Z(9}V(`NL)84fI}Y&U;idtFtaxPo^uHjR{O2GMep)MDi!ve&^JCx&o4d^qu3-@oX8 z8iK+LT(h`Sb&RW71mE!vp+kn@#C#WeU4znb-s0|y9PcL0o8gP{A&@08`*+d{X7R7% zFyUL{ma9(e4wnzOjh`B05@iw-;Q(f>AqxlwzMpKeIl$Pl(q|V-X^LVd%{fxv2+hY75MNT?6+e3%utvD3Ny;QuuqGYv_Fuim=2RjNVUbAr?xs;kyh;#16f|z~A3C;} zd|oB+`U2V;T^esu_nZSNN#-ZwZ(PoGG9o0af+PINVOeptp{h!Hr8cpgz2ZE?`BaY6 zwyt`qX@kfrlXTAz+D~qB2JIP4_pz)q{NxRq1pPF42R}WZopL08D!95H2F)V0nG}F* z>{T63y&L(CM{++Nw~+(#Tym9vvWYnyse!Y2Wx52EacP^3@W@iZD_KUY;6(^UT+~IM zi94Ub{yxlXmX96>;xz|?Z9hji-z7{fq`Q%AUnyeI6=stK7CMJq^-7Qx`61ya$RmRy zx^S|N@V7BVn%dIomz(T92wgdlt;BcKeKp5|uI-mTLT&n}ACB;DJVYPa-LtKEU?nt0 zxNGPGLQM6xbM5muU1^WpdsRaf^Xx%#=pLq?`&2j?N#blbQZouAFp4YntlcP_I6QqI zxV*57=R{ZmUc_gNyOZ|9e78mvjDGrSOWap*AH1_3I!MHZbW)Y_28J}mOV2K zv>5rS&2&vqK0EWHQYTLU+1EEG)RU2Dd&afHYh5VOi;ZQkU#Xw!LpM`FP#h!h7irgA zq|*d*DL(5Ob{8|~G8<8`(TdT?aYhfSutT%blkVEszRyRCLe^X-i_y_mBOxZ zIp3|_!O70G&t?8-4e7g}s(%FqLW$SIK&a^%_DDwD4cyYh_g>0gZ4``Ut~SiKg4;L| zWo~K;piT!8W?e4m)(yH|IB>p-wKaJ_D`AL_711eJwP|^yBRVhvX@g~;aThMwPA%#w zTabk}Fn^-b^i5YW{RYkLw#-2GK8q&GGlU#%U6it=1>>=j8M@b<1}?s5Bmz$YB9V8{ z8>OGY-@nk>lLf(Xc5Lt$`aCDuUN2<(dT$dsHlijHG1!mmkXDrIPZvNmMzd=>qd>M$ z-P5+6>Y&G*7FR*8$>-VIA2p13RjpD)K{t`QImycAQ8_z>Zr?bq(Wwgz+U9A3whE!! zFv&1C0()jmu1B9xLK%^}^l%Q>K z;QIsR^^340KV2a<;NuC8!W{>@B36C|0vFnVN-C#626ry{hOcB(6l;X+?dKAq8cuU^w> z8$_EVpHmabr)$h#xYiywLN*Wgiy7+Gre%8Kd3%c)#Aanf*5_DG$4~2g2^r4L8ztCGRQ)7p5|dJdyJ?Shzu%JOz#{ zeE>OK1tG9mD;@tfo`v_&ZKEnrt`gEsMn6&X=ppE5l4bSSW-rR>NnHX+>*Yp?^BeI1 ztHv5|&i{270Pa=iX`~pKZBcPOX2n7?|C|x33P%~BN1P%GK`}jd$ zf(!A9Y8p<+CkfF)K|A2LEce?}Zb6>lH^E7gTgxZBtHhI9=$m{yfgs)OCGPCpdEn!a z?4Flj=8)8bpSIpiy&9ghbI&h7reqL;va_xf7pPt=4ZpSFUu`(NkZ`)X+K?R2{n^Y0 z?rg518Bv2cv;5w-q@693S;w;zZ2f}i6hxB1e{(IFk)nCx`kD6tUx091^<3J@;zCz) zzWwHk6{MDq!()G^XnXNpU(MmUG*=<+6LSKVGvbuJ&FS)-Axdpu_?R6={7yurTb65r zj=%7}#jnM$QC7S!G9h)k*R1|qg!*q-03HgQn7c2{Id6|anM-|KI}fb!)AQJLdhEPU zG%(}Fc$`%Y<=Gp)dDe&ZvqwC^y8VmExKC?Lp7b=0v`*&=ZaHPgxH*`ulUmqMc30oJ zvp9T?>~1_g%cyp9407md)hM2njkoy@^2h^o@#7qOGhx+UiKS@4>~VY$U$8NL^SM@i z!Q-mgBi8&+WkiQBXZ;)V8dgN7C7SQz^$`Qpx+-dL`lrydW;n5b(eR|bb_MeJ?|)J@ zYg<;5fkZ={S$?{Mg_Etm6D_2?shMu}evO)UenYitmAHI9ju?1?d3Qwt5h5*sJkB|1 zN+opR?&C@JLoIRRmpRg6R5>nTcDw5ztxhy_i2KW*1Fvv#ol*h^ztQ5?kjGDg z97PS$EgEUikhL7NWqh6X)mhbo5ajec0X7pvEbg=dT1jwAvtJ2Y1Th{Qe_U2uNJS9B zGhQu+6Ay696lxyQQ!gZdu@#D%e!h&=?$kL>+5eSC44lA~i~mbb;Q!C^k^hzl3+ntO zpQnIbr4?GyG6s(86`>gWb6EX$)cTK#ILP|nO_I}tq)m%N-VGpg`Bok&OD~Z0R^zl1 zAX|=>z@CtwubY1-!w-_X&a4JlFDEi}r>L|BiA-a7dj%WMm^}U&<|6cOB*`7)mi>gB z@h9U{?rwtIZZJ=fP!L;?|3GuHL81Wbd9XaV99u;0XCCGZ+ zN?x2=1pg5>;1XM%JtzPMAK-mp`y;G!1`80GeD(*JO&~Q}Ib?Gl zkMX(fY9P;KH+q(fH=LNPgq@xo2gVyfe2(P14(ZWr^iA872Xa9hLB{xR@#zW{tAwXR ztHh^|&{k+7)UKCBX<0H37O=^QeuCS+Hv13>x)G_t$Ik7Nop*7)!6)MXXkXUyv2~LG zN&GGQiqcaJ>@EZ20K&(9Q=29{K_XaygMkeLom%IfT-s3Ck(K-mwY)IUL>UcWS4d%s zg18@-ed#Z88s^{QG;{H)Bw^+SpUDGNE-a+`k&VGj4}|?VBe76 z#H!5?ReXn*)rmJ;6NZ8a5R4mBLyV{@bof3Dpa6t_Zggh&aGE zX19IPC0KnUUvlG?WUBeILg3cvHPIDUgE1y7?K)H=k=bmDyAwcK@peuF_3#6NvIo;S z5U`PMd>#6BG0g<>_=vUX>H};}^?jATM!r?!nZ!ip+FH3T(JP2DQ1%tN;G zi-0#YS;oL{FkBWdYETJUz&ReOK^{x6#30huzlHee!dTm84W#TNvNF>+r zd@O6<$42dp5vE*jRsxY~v@~@F|l)?*k%rM1I>k{}0>gp)o{ywyT zj={-*gDQqu;GCa$kO{`|K&w1MnvMcZ(>~`6T!b;G6Lu@9Jp(?DYnW$YDlKD9c9#0n zBBh11WMp&Ihtr;zs_;U5bKARmsnpHz`vmARbacN}S}ktXjp+o&eYt@HF+k~# zbOC5KKv?_7zOw67;=9*}BwaHRSn6^XUcEFqeO9jw**m-cfIrw-QMy^GDtJ~Xm~}YK ztNhJcW;Xt|QcoHGKryw?GBqyQCOeNX)3g{F1n3=jsCsR0G3`jg2GV^b?5kp9(UDlc zj*yV>D>)VUswml>K!q8jCHBYE*Q;V5ghs+b>Gk9*xr7hoTonq#7D6c<(0kJ`>$&8$ zcHbBBZPT-UT1Iyv6&F)k6t43@AI5Pi?q&ZXl*GRe{x@9I|3;`Az~hW6%dhOE@vm6o z0k82Tc(*HJul_O6CiF&c-p33>bH5)ZjbO9vsntKi<4l}TZrlpv5$WDPK!TA-mh%S? zH>|@#_dQ^N7)Z`CqZ~l10e)^4EHk0ZBB0sFHd} z4MJP|bIxOxMLgyQtkB35z96c=_qxbRS~wl^Z+wp(8beT{rgG`DT^0b_aZm;Y#h6H3 zl|D!QnxGzgchVq+2MDpi#{0R83+Z4S6K%<>;*m&p^m@JybrHNRIUf1R;#->E6A}P4 ztiomtdM-wT&)G6Cd-(oM)GJLzsESwa#GaaJIi8Sx9ANNRuqO7Or{_+9HE5%MmCRpJ zjX#X+v40&(n(pprZK_oF&j72{z(Bc(wb3VU`}ERbLBk^I@Ecu&E?HDm2Q-6@Anl-P zu?_avs^^nN3I(|S_MCTgMnPieq3@f&-2X-~$csfU0pcY^Iu?B1Cv-`13!8S(9}D>O zBhC5i?qc@~06PB#j+d1- zy-T;MI4M0@icVy1+mW7ZMRPC@ZdpvaPg?Wc(}l`99TC*2ETviFt>AhPkt>x?kcyt( z#d&T|R8g(FMq?57hKT~7yu8ul)N{t?gsVN9`?bNo_``(iYUR=P2T?7a)tvw#U2(>% z>7FAvICBpJ)5qZ$Z}BCnt>> zPH7yjxcT(L;IHN!Rh%jC$7dHA0X=_R&}LM${8RIvutR7bU50Z?`N1K zaR;O$OG_RqD|G%Nfv~Zqz~n~+YS0?KaC{v%TjShu%~;#+aVof%Q@G6ZCE0+U7s4Br z2lf~iydIAYA3(qEfMj(6Hvhr*@_2cG==D|nVcg@4rlV%A)&9*Tf0~ZSpn2SMJSh;j ziYb2J9a8lnmtk*!5&sq$Djhn_jCL4U5Be71uTy@9EG;f4pJ0N}EalYkmbJ}XJCBYD zqlLXf(D5syw8so|6F6mLhm9Ujl6aKP+gK@79#Zb!Fyik|BB|)-Mc(5?67xa&sF2xs z6uA6^{G{ih37xe#wYW{muElqlfr(YaWBwFJ15>WDkI=zhUwCOwso463mxUJYIDe}V z^B~=GXaxFJ5F4wuH)R&(C)=+6A44NiXBji3{O%(^v4}GM6HsJYsY`Ynq95U6 zTOI>!+(xz=<)IO6(JEN4S8!vx2&?ai$K-x@GyaTcS7JNYB_ewE6E?+B0NP|q`*47A ze3hIM*@IIy#jnSs#oU0!ifEO$jV10N4JSC_D~Z?^=yfIQim1EPShOfy_mSg~lXAJg z_>yPNEdBq}-g`zxwX9piBnc85MI=j;B}vY?5s-`^f+R^2B`3*((qtt{kc{LcIfEdm zfaIJSkensjq_2AKea^Y}?0wGn-Z9?y#~tJB&1i?iMX#z_Pt~etK6B2}d8_TE3*>=# z;&<_G8RiAn{rJYIKa}m>f>AdH9|=t|55fA%f_hY51CsavleZs~gjA+N=+PO!LMQjE z5ElXF;g+%5fDY=flww!dY)lKl>O8+FooLI{x=z&IgpWJQ25cAsIMDgGE$)A#|MPzu zB(c+REzZX+wCp{md%ktPt`chZAlB6_$w#;F++CLyirWtI~@rVfn1YDl7OIO~j zT7B8luIptMgPp9Y!QEgv%FiHIW*Z7Wh7D{*6jp6RG6k&=B@%S}Vlv81j3)fv*?QWE z8v|NzE%j(lEn>Knb2IyBySE|qVEAv}th7wDD(K>nhw&LLug35%<-RB*g)B0E&1iZc z9+?cuJacV$t%f|c+S+Lv7}SGtxFT_;JwcZW{t!U?6PbZ?!D?8M@Ea3V)t2npJ*yQN zo#%k_&>4Vz84E1dt#%-p78uD-oqQ2-JWyH8r@n$OWUtG1TiUF*+uF)R0*c zZZ7%Mstlh*vV0{=8qrMta`RccUblG+4Z$5Eado`u z6}7BHUaCEQr|oK&8?`!O4YAL)ul!~oNSC9Bo9vXKcWY``ria2+{6iS_WvjZfU{(Ex zFw-GPa>`&G`T3dF%nE+FT?ygQf@SI$cKwEdNBoFOta87l31!2grTaq4LhG1^f!5K4 zeRl`&ZsvWUAl3x+s;qO&jBLfCkJ^w5i^Wn4j^v94Qk2Z8w@J7VCI7%UA^FQ~`w*@| zB|V6X1WRp}2UhC=QOU)}mIIuWGs*-_;;Q}QLO-VRwfI=R+lvHqPXDbSel8&PtbE;ARs4E-=ur`zXIiq0I*wo8U>)nG2RSuzd1m)84a zO$mK(6|0(8KYD@!%Aytf{vb=<)?wsu2H?pqod77vidxZy1jWKAj#Rdl=?gL_7>{m9 zyEa>LS$%*D&TA7@>*cG7Kp1G~^y72GaQn9YrwqyauSBggjjGZE6NIUCyfsrKHWbx4 zh2H$mkaVse#dqa zo}fDt&KRmTGI7VA;MZtXRW=*cH99zCD${~|l=ikg#ZYfF&5%=8cIl=TjP(&`_@HIN z6swE&B#!4JeGF(OU~1yXQM+w~n1`v|czY8mztoTm$K7_wq`3Rd+bv6Ji?+EAHG!V* zgv>aDr#Si76DZP=5uXSx?QzP#V?@%+3_ZFFaq`qp&?L<(R@w*3|wLZUi5r`?JiayY@jPb)X;QI{+}6<_QQ6NQ2f5Ef&0mQ zS`F}l-f;V&V)8x%r%)8>!`+YC5cOJWllU{Xijp^h_01XE{v4c|#lT#B5_EibfFpFt zG$f7YJ@$xAwqVSN5suWimV?6PyMW+pf5!;ipevP}J20O6Jtz7$_ebNY*4%9+Km=ai zoq8q*2n~V;Vg;kntQ!%f<`}4S2LdX;dLWg2N2WI}=75nK4);1ZI=G6JuGS3=4nBqr zzW#Uwj$EYW`&~}Dj$b?U*a=H`cXh3p z$PPVq?C0gRHe{Qn^ucX8LqEI>ft{)Ry<&(;6;JlD{D5Y>eJ+x!_{1#+*1T5j_Ap{f zH&c&GJ&%y}b@=^}GSO;m<86n_=JB`TPx2VWehc}`d54|}@!lz1(!!tpBj2vT%!o3$JG5j{?o5R7WwxKr;Vs-sgg(hi=BL&l6Ss|xJ!oSG1YC}Chta_%EW^daSR)o~5 zoPh{is+>8zOTb~hFHxlDs!}L;c8*p4u;*;*rcQSxEqWDUs+&)dvkUWp`%T;U^w=S% z;y#5n_?Xm(B_lWcO6_0cyTli?*0*Sakn9L^X?y#Gu(D&V`t5gT(Q5T}Mp>z8Xy>=< zTzW31V2|pD*|@)b&iP4b;tljO@6P@Hghl=1MI9{v`~RK(SEfL0cijDL;SV9BF5 zuPe4ppB9A5^8UdrKsd60OLi3su$uU@M|!*L#`AM2=#=uTLAu`CB=T=p@qZ+SaWWZf z00hx|pSI9foI)`Gm8 zFF+j_rcy*@fk6*;!@-I{L4WMl-QpSW)?6blhOjg3$@O4$2Y&$7Uibfj)c-C%`|ol8 zA3ouK^p^i?^_JFHbJ%u7TUAxlb!?8$5Qr(?!qvkm|9Ko?o6sXQZ!cY_sQ}_@8+$-2 zhKDtls|!#Ek_Y1Cos6M>N4vzf(`&r^)y5LQmuDZhOT__ZfBT2$nV2ZO5TGWZz{Lf@IshMzKk`kW);X%7OageYxe3&`nYg*c%* zE-_N1p;5o50JuI+Q>ut5DqX_=>vSo=5tItXF#XWQiBEsN zI}N!Dt-0oh-6S3wrwLS6i`{M0fo15=&^>H=;UsCZfjAf^*Gh5UID`zKfIC0oGqzb& z0WaZMUbP;~HEcLO@;7PrKh!x?l}4Nt6U3f3%dcge+cF0+%IYve59hc8pP^BqD_}HY ztk&>vy0w)Ags52k6ozE3T2Foo8sd1}is^toH=6H4g&1w4L9dptyh)2gZP>V@)E1&| zT93CEVv!?1!=G&y2lqs~b1Q~G3d0C*3oK}luK5u*-8x<4UED9}Kq(-KeMF{;z+#5A zgZG!~qWS9uE4}s;G{RtGT>0hU-1 z>`P!f%x{%({EAV5mavI&tM36&rnB)KS6>ZP2`~G zBY5^q+Ej)QlYhxXdoThw6unO^Kg?2t8p9x)XRVdV5hH_;%D<5SGU#5k;j1uZE3@m6 zEa>0lLAj?cJ32}W8Fg`nbv_Ib!dT3T6jKPr-6q?&Ht8e6`pQV;Cxs0j=WQ>?o5~<& zD)^0>jqD+V>^rY~-^q7=`Y=Z*6qtl67Ktq0BL>C~DY*`d-PcBI6gu4kTXUFh>p#+n z-;gV`)Jd&WfmA%zAIq?y)i2BpoTeHgjV!e3`{AjhZ@TXWh@egkX=22X%v^STUT4}2 zCTKRSb2eZXb6nk^!<7_=7p1r617_#X09C{EwPWHFP{(t|Ltdf=NF>fD63`0y!CUS_ zreLo(Bb47oCWVnp2R4H%%*M$#aHT7M#$+WGoQi%_mrD_*#D^uBBKRWiP@^gNRc14E z!@^#=JHV#?)p3X?*WP6UcAp%~D(G7w;C+mSc=z3VTjj`>4)Um9B3u=(K&VvO{3Y&d zc{?g9&WGDE9B=-U?fqai?}5u}qXk6j*oR2wwpJS+8|L5yuNijV4k@m4Ct&oaa(>-Y zvk5cMkt)Ts*AQW;oF~aGJ03$dI%xL}sIk%*a>I`a`^oJn@jm|`U zhz8gw+#s0_8v=3*BG&zwpt^m`Z6B)6$5NFe>n)Zl!t56c7Z^HAe!pKaRXwh(pa*PE zIWOLz4f4EeP*8vuS|xNQ4l7aWr#b117RZfXRxZ~!=1tyA9?diptJYkd&O;Opb63^g zZ(fUwavR1+5dyzxvAmg~e}Bp&uh?P{03r(e9e>Eyk{H7Y7}+nAY%GG|aA)WBgm=;? z^NvAY-d@kDUK4idJQ7+o&&vK{$*M~;V4|DOlq2b#~#iKb^X@u5pZ(t>5qFzF!cuMY^4gsz&&RxwwjoM ze*bO5r(58!JGa2Lu@dFhxI?&=qIUP44s~fQ0fsF)Iga%M7z7fk{)V4Z<@PNIe(XjT zB`R{?|7o=Y_7xAL*RFKVg}|ZB)ZZUtK;(lT*3^OC-x4~JdtMLPy7fy=@9)fu-}ZBX zzgvxbxl93WjYQp`K4x+cHD0lIar9AT<2td^KmAGryv|qurDk7%)$5JlIbQ(b#lc1; zXZH%6Gr(H6hIy$W7$Ht50WjdqX9N2w(grB25XlU)+bm=>{&iG)Py{C@IUU;CMCac* zf$NH0C{7?PVsd@r3*ZEnG0?dkW=FZ&H5zv-ZdiR&Ko6;&xk5M5MeMh=bM9_d8wTW| zHPq-yrmMZ4z#Dj*(D#vi?*+oX;Cq?aNkNabX(5LVuxf!I(IBBUMIvsHF(eoAO4^43Pcow`~vML8TnL zuJWtKzhMS2JeeEU%&bKNVA#yh%gHw8wyrik&fP1v*&+s6bwK5_Z%}yARrX}AmGm)F zbLp`9Bm4UM>AuzDpXJRq=4nq~^qjRSc9(6u8>6dj^5-vCHTAUXIV*fPKkyv?JY(5+ zHhcI<4Q9*a&r1h%n%V{dN0pv4QBikg#8?}5_nuCKl)cxL0-GR>!r3aIM8^DVS%ROO zf5d|^fKVRf)e8T63I1)CWuC8-U0}QliG5Y#5QF=`5!PJ9FjSK<+bzcD+ZKt$ICxzqW-MEx#j!=u)GIq zmzg#Pl6aw-dDd9AF WFY=$AW#4)09(oK7-jIzP8^{wt%SeBJiO+UBj1U^JgX`g zn1%~P-f6P?W-1xKbEI4?dQjFWDgiCNznl9=>;jV+uT-B=)I!e@oxUrGe&aSuDcYR< z|A;;IAAgwt_{034`@?87z&-EmJvE7Cf;JF2K4@5lA`;uC1Jt=H(&Srx^e@A|m&6@E zfyKor)nnC3*%4tM#(h=C0q9`1F3xKjAB5mBJpbzXAnn@wk82;$A1Y5*Sc%Gwi z7e6Qiuq}nKF8M8J-9>rQm8k&BP&;&LBJpPrE=BA$iRN)xTOtE1wYcVW8})uYKW1t6 zy@4Q(3^BmnBCtZ+XGNGI*4tKX#@8h|+v|lK1s(5|)9sZ_35bYXVegqCj@tyS@AnPc zTwVR5Mys}UKI^9~@I`vPU=g2qOk2Gp9GnCxKA3&H4{^PRf0l)!r{t6LN&7G$y4I2H}Rf zsvWS>5Xn3d2=Eu)t6=2jXVo5*UVql6t3@-FxPS~ewm3D5JU9z%%x!P#Y+nkfMf1S% zO9rMZdmW7Ohtz}^Qn<|2o@8NzJ#GInCLH3*sb!P%G%47r>)F;_1sDq%+2=GmZ|- zv^}(opSfg!&?|jNhv4yYq7U^y7AR71TMmP(GdGcNHH1pi%2lP>i zVS>O7U&5gy)n8HT*9a+v6oZyFDEqVr+A1X(WSusj%pz-ll_}0QDcj`(R}y5+xsi3( zr~Ky`tJY($EgeRB_#bW_^)+Kp#E@39if|kngu;o@Hn?@(nhyybjoQ|qyG&>5afev$ ze0^J~5DW`$`Q_gSM;oCVDI29La*k%yAMxO(xZ%mS3Y2HKq*@z%F~ZTm{M|O-3+hO!+YZPFs>X&9rlH4uIW!p(EEOjW? z;h#9~eAk{?>Lp$Hq=#>#f26jjtd!GXfE41JQZh-QV?CXX07jRu6EwBu=La470>sq*r8QGOt!x?F*Pu!bo_#pFIgmW{bzDTruEO?hlcQQKIKyP^ZrGZ z_)_2cD}&4W?K+3#!K}?{4g{a|ib_g3uuY^CkD!Fny|esmC8(xz==~VevClNW-{@VO zi^Nj?NZDtF3nlLetNWpr1FU7roFW%_`pKGj)iuvRy;q4plqt011q8pZPQ&;M+ixjy zABsUmz+=1IWe3rG{#^MvII0Sm;E7RfzPK4J=odmQ6xap5=>t|&+v@p?*MA=Nj zThNUQ;cxOa#RM#j`Q-Wc;wJ`3T3-X{xvw>vVo^$@1`)0#QN@-}B4SgAwOb|ZmA73%DM ziyI_lpL@LUI03kxD*yXtvI>*~2?;<2(VKfq;I$lJQo8yp5necqG#uDiclp}bt{hp} zr{(u?7NNJA4qXx=gAB+BjRa^~>-pufq~|H4^@)a3q*^L6#X2Zjjje|ipAxjxg@`K_PI%l8Vd@>^0VAf!*GLgX)M?!Hhp zh52Y#@yne(u*%lh9_6vGfWJ#f-3Vh z5T}X1MCr^42O>Dq-?>qkvI>| zr}=;xON#BwUUoy=)%n%sJzEntFO>gLwrq-yO=0WUo^6M0pZEZF$S7|NaC?eIv(G4K zaD5r11|9fHr!)9EK>vDHGj$cSaf<2&W}%?Oh|ttgR=PDF_GmT*g-v4uy4A1(S;?ku zO0{~Rrxi2&vP35PL+5y6?%E4Hi2coiXEv36)(?pAM*+>p`PXU}8xO;=sG)hK>x)-L z!%ED3S$(oPBivO|A*JI5WJkP8FhxhJd3;W>m^clt(xhW04S&4{-=EP#nUCl`Co(_} z4~k-?tLz@AFg8{h$elH5LuK8pJ9OWhXG@m)eaO|EnsH?_{q%pdkmmoQ^lZI3@WC5k zXPBNeukz809)PH-Mq=v&TQkS;4*`^(Es~t-`5Lw)IpfLQ9*-~wHbe9xQsC!Kqv$52eP)scYOU0SavQrHsnt>gq3_7IlkU`nsr+J zG$V?`{ua$b0R^Q^UV>2*2O(O~rqLU${tfG-P{G2H0%&q|#tpg+c?H!CPc2S`K{VGX z-q2SYeGo_kSE9dKv1qPLx4n(rkjs!HBso$;N+7#XLF>MPz0LX?XEx18Qq{0=RZ>X9 z{Y9CJEg5UeFhPM)j(4K-sj2<4FxD2O3l;^~+B2nM{tj4WO4W?~g{Jb$4XCX0tE%)@ z3D#>^Bu5TPa_&P!?nN6_it3^ zGQn|*RW+dizmS05U;COFfE}U|_~fYo5Y26ZV*|q?wd_BfMD3wjYR8CbiUeT>%@bVDz52tJfZ;f757XfKnAkorF@Ac(4Gvhx#TnT@y)=zoadAWDY=V?iEPS_gkMItW%4f~2;-fE!@KeTAB0N^5M}+&%W8K_Ac)zw0f`0gCuXmM)(ofcoTg7SNOY zqNo>KLE}Fxtu+2&|LKSZ;BZYabydDc$ak9GXEJ(NTj&mMfli6Br+(WDF?z2DLM zMNcrSpHLjxR3NkZ8u6g%6Z8|*)bU~pe6YE+C4nzT=?1O9pIH{2`=IN=C>4na8Omcm z-t!e8cXT35wH(_#>ScCa4!60mi~MM2xncR2vX`tJU9;EM%sKe7cM zxxMJmz-#IY)^bl43NB25bejPw2+FbThc;-urS>AY1<=lIj)M>7B+TysAbgAWEm0l? zt#dL&bpso50@MR2Kn+cPCm0%ly^oi1La`HhaZ*v`!W(hi;V3_I{rl9>Kq!II-N!xz zW09m8s{0rQmh)2MColpo3nF0@NsyV<_!de;QWYUg3syfAl+T<8#)3DSv<%!r7G{8F zP|`U^lA)?=gr}Q=HV(`xvQTCfKMw7IHpT3SkOzgDehJD3?+#p4mCjk~zjRyULiAZV z*bv;cAYzV{R-3PZe+gdy_kGVqx_vhRP>l9BY8B?d)E0X%0K@-&0A!CgQ`>Sc91Y)kO_Q{4MiRTLZ*(J%To#~@ia~H(n6#fa`n1egE5$+6W9m%PxO$T}67k3uK zjcV`vCB+hu0TYAe_%=VzelMy!&kHNdhQ|2-yZ)IgC8R>MoE&%yiMGuLreks|`@Z=3 zFwy<9T;RzEzlJKY>9Vo;81L#PH%>%E!niT<%ym!49`CSCiuI%2Z`4Qef8zq6A$rS<*Gp0YDF^ron5k7iaMx0t(9Oi;; z%M=R7G_HfRo-avxtu7#0@0~gCPM5Uz&^AhnZF#M1(LDl3++S3TcUeesBeH}6BT#(GbV}$^FG{WAI*JqfC-1Rk+a|7T^0Fyc{)5G0x1^(^z zg7me-g?wkFMG-X@^a1Gm`2;cPPG zKGXcr#W#oEo4?we+5`e|&|X|{^O=ku;Xp3bz%kw~M~(t9HdF;lRuAg5=~SkY^NB5x z7ZPf)wUegH=MvV~5efRa@|_P%`9N--Usij3ck5(uAJZ+A;Ae`O)m@{f zr#*rzRh3+;62?sdmERj*+S*s$^=SD_*|e)%NwKF7EB+GRa<6gB-d!YNbbL@D>8k|< zoF9TTlWz%6&-N28oYFrtib$1U#Yqu`E%JWqx`Zmw4yY-=MnC-B%p_obFt+kDtdF&ovFOf! zB{TFVN%|}#3iRALFSz1wGCfY=@fvP*hOX`Y(Q+y#^nDHlrrFO7 zhw}6Z&#S7#5}k`>F$^ip=Wi|V%&?7?Ih0%)G-}XnxmkZ}N_em~PvSU7r@6ZM4?s-OoLo2Q?|A<(1dEsA|s~ zq3{PyU7{<1Brrmp&JH;(k8mX#Nk!}pEmDD{u+)fiY;m6R!+3*B)BH&?%8_j%tC}Fw zq7S9(DO#$VQ}-xFomx!+rYmrSIeHMpf7G}g4b$a=j@0@mrDeA`F_zmhjHOcTT)wLr&@-rPlvtv3)(`~<4GZ+}Bnvrf+*0Q)_)!Frq}CFT*|&w|X)}T`jc=BZkQ%`mUI%ia)8H=%skiSrXPvctQmok71tw2J-ebdKVHy`{YVCv{vtPQACImN7NV*7c=-V4b2gzodE`I7 zFqKl=RpEci;_bg@@cp9u8{U1S`}s9uLeV5NX@1;ccwdP#cuAR@n(k+GytUg(i zH%P7+P0(HSA~uXpG2Y!UaQzxj?KZ>2o-ld76ccZ!YfPAS@aAaZX^Oz4$+nL0`eBdf zE;;v)vsV2{At137e7tHyy;n>qa(2%C=*LF7l0owip3RCm{i3}v;xcMmiIdDt=b*kv zX3>~O>=kF1b#bRB7hk-@_x;D74%-%gv(Pp8$}aVSw)OJh!Dhn2L5`rxMs&l#w? z)yz{>cfSiggThxM<%_Gk6(@Qj-L01#TuNozwLRG4dt69(^T+dx8TQlp=F;TPz`Gsa zAla$^(CfLabn87L_4MeYr0lyQOEJKrIOc*ory?~$OxM_CgRd5QGzM2^a5X*!vrsOV z(sk1%G(r1$N|&-XT6)p!I5YH8$X9KYdlPy1F}31NSDJoTfyJagZ%MzH4WNe@=dP}F zwk~#ayBOs6KP*#Qdf>|?blmVf0ihPhW z;RgS`!8^uUGOh6`J(PvSc2Y{1w|&v#a;G5kXk153GTzTIEhUYO zEwlQYN2y^paXs>0De=QXHL^PcM`CoBs+`bHsmg51Jgg$X_vKZ$7!G5 z&S<|vnYdf-iGbrtO=Og<59OYOrarXobv|7U!_{fj2aqtqAtrwbe1P;0q30oH0R<~v z$#U7;xbx}e3&N};{FTNw<%icu*+*mOxA8N_T~_RD9J4MnC;0gkE3AE|I`sXB8i1?! zy$$lQ##r-*jia|N2sm=D*rn!`?M5w+2tx@k7V@upM}g_{%fUFm&|G8-VB{neTeUIP zXIGz*Qr$h09DBJu&#ecG$aWd^2DBCA`+Uuj90~cugWUFdzq|(=YbQC9@TR+}Ud7Pi z7JQ^{qr(Oc@~~*~)`r+9owqOi)EvzE^z8Y(dF2gVWckDRnfc{l zXmywYQrZ97Z+;`_4JxX3g?B%%B|>)n$~;T^O0jC7 zv#yC__wDLz=9@b zyAJG7ReZba*p|nIILR~YLT(yF+7?${4@21-ih(t##rr&$J;C2<;3#cY@CUn8bMOgm z#m@sIm3uSxW{I!BvDBf@_p9!B_MFbh+Q*SBE&Fz*b-WJcHC9krFHyU6RpGTS_`haO zxGk5CbQj3fAE#e6BCfl8pXg{wTkO6cUv(EUdhaXcyc5>qbY(xLKe(HQTyYUz=+})* z*o4adT&L-ueM9%&kqyUZXg zdQo*Tgp}@cb)=Wp6P6|gKB;`mC-VtTN*H{rW|guqk1i~=)R%E9wezwWpPmqA6G#*F6ZcY;tM3u zMQB{vC-c2215`yzo8CMyrNxj2ncUDK?tE~HRXWpA{p0kWbggiyXB>=p8LK`55(-c` zGYQW9clTjGB9!?r2cB8(j|=N8$&?6doNc7s2D^@{rCpsRsj!<6o9qDVj3Pbam!(HX zeKZ-)A7ZuXCU($${IQfq%jk&Q@(aH_T2B!m9O@>!$gsXsbU~|qn4;8ZXidT*l1Y@& z{vP`XSwx?i0kHSO4rT^j)w8#b1GOWR5jJH6WWGJDcv-}|^NMBbIC|p`cq67lA3QAM zXB`W1_w6tuBXmA`>eqev(lT(3stw6~JxT6jV5D{G?aF8`aYfNLp<(H#yHmCz=j@Qd z)Qz0ff(v{3RsvujQz#0wY;Svv-2j?=r=Y)TS^7dL=tZA_p3Pt{#u3j^kmWjn)qtr! zQd_=1j#|T*y7oZ7@~TIzsCAS4h0BNZ@I+>C8k3Yt@?u;89*fgCT zkYA2l#v5)yG(+LttqXQ)=RM!h2l9?5gB>mxW60+Hip~!WQ%X)>pDIh~A@6o~7&*n` z{@OYzLqZy_1Z_XAnvJhMJxe{>)x)=c|6seZeWhr>$zvn?tB!n`ea&ED(+^)=!UPA` zl2KvT-AG-#xco`-yWpMJa*@#IIp}>Eot}2uU)(;G6$($3dhS~@VXl*Q5EXA%=G~|B ztJg1OFXy7)i06h$C86#@cv(I3Rco_LU_}w@(rNAXj{CIz$zVdFh6Z#0_eGlzs{aaxNnZFU6T(Uy>umL-LELAxsQ-(>Q|&_PMfR{C#Z1bkB-)zTsjp zuHehb352(JYp+4veK>+@!`tzOW!N}_t=n~3tYgR~gCNAS;tK^&t;uTrbjXCPCwXO( zOd4CQpUgWMRz-GL@D!8h4KpEAogo<6^kBCf4F55h@Cc5eS(W(Az)^6Ig(LxX8|St766G!~i)+k} z7&3E#%y-^#;Sh_6g{KRxPLr5vZD|Rn@j=rrQ8+ z+HpNminoD>k}&$XjjeqJ`>vGTU^JFVT;Ai@-*WD&Gr&g7#6MX3 zpN~ZQGS^HuB}vrGudfHg-|VkNA6=YKK27Xh3vKc<@O*G?_=ZGN7K_^z7F1{Wi5XiE zr$#g1@Y4w$70y}M5$02(WxF7LS*)~uIJC6Sc$NDE?8Ofu`@gPb?xu13@Fki|S8OtJGaZGsf zXfy~9X6U!Geo|yP#7J}^5Fp@okJ_Y%W!(As5<(;+!`Nox!t*VD>NQE=G%vSD?kD{I zEE*3QV{sGRSRazxX*ZdPWz~fxN8{^A7Swnq8)YXV=3kRsTFdgyRENmIahKIoVuEq8 z*xd~%I)ZQL++{60ypeXpv*8YgN!!AZM4T+v$+J)LxK1}5zMQW5N((D}yW3mWB`r~n z&{{(dn-*F@s?{4G`%dQ-CovRCl%+K<;x4kvf7%XT&;H483}XwfeszB1Ua z1ZHn@&V9gzR7WVFrop%}9G4>6&p~C@C5UAI zg#3)*>33oarz1vKT*UkXSuFP(f;e*#neL%Cprn+k9fp5KE+FuE=q;z^Nn>{&Y>P#rD zN&C{QfJLm{D=ya8xrV%kNz>Zu`BJ7;?aNC-kH@#VgP&?oTg&_0DZq77y6JxANw0A% zr~{YAZIe$DHjCiD-Z(fz>~Uq&E%sBE;rd?d0|kFka#n1{u0VD;YbU!%2b#{CSto*L zx{mChHalKfn%rJ2kv3Ed%zq?%>YzsdQkW-V)$>yw|9L?QBkUf)dMBbe zeoxvuG7P0NTo0=pl0dYsQ;!?PDO+nUtD6+Omk``NM``=gguuyuNc*W};`=>~xtNsb1=qx;z*4PMy6R*oc88l&0}HPQ<_dVky_u3Y(TSBE{1Rdx0ld4xBmk{c>-Dvhjt|dPQj-jUcn= zPq*(cO^L4iF&N8>>sd&2W#jiL4*Mw-CM&?IPuR@G8@x%9ot7q-wwqq7ak^UIPUu%Dkj)o%TK#yQkDbirZZ1;`jtC570QeK%bDB6NxHEwjAUVNHRN8w z9n@(o6nyK4qgoedSq~)X@s}g^f3Z{)-xG6Kc(A!aZE4o{db0JZvAx_?wlk$iDk{dP z<)d9&)GwR7icR0WdI#b(wZX|j)7vJV!Un$2j9ou=MLnsdWWh7=7{>{E`6-vLA$yo} zWv+@>lpY;@X?VJJ%AUBS#+d9Antn(Mr?^XMb*-Lj!{^GfQohpG*}8>eb#8JQI7vI7 z0e|!KJ!W+xl8Z5_m#?RIzVKE%dJ?dXFx`qXH_pw0Ks_}J zq8-cY?o^$Mkk-+bBAe`3ZD!KZKT9uSU6aC%lezD$ht+}65qU$whnzY>&M%y9o?`yh ziUnd)_Z^@I&RbSaZK=NKPGt6 zr(#{qd3bv}jSSkFX-an#x$sKmQmGcv5=pE;L997+4_4|U}qJZtZW zLKp8`@}@!P&tt7+r|Edhm9A42-v-_tElJZ3Q%&gcKj$ki2*qh2ka$6(;Td3M~1pG%8P-S?|GNMX9AF}nPF z)YIdYMmqV5ZK0WYA=by`J>Knyv?+&Q1-&oc2Y%`EpI4$8lPaI%s;{3A48|cnRGqEt zsN4CbLpL3yURIqxqg8z4E{sH$*H=Gp;a2PR#KK?!PJeU5cfZqcvbWMVz&uoiPk58p zhG80(nvBnTyLfY+N*p^Oo1Z&%&dhsj<`$lwzxRjv`;k@^+dZDJ5nFNRe*Gz9 zRe1ifomM!u~;#tj|V9f+ph}>y_Q< z#LAsh=CW8RR{Njslg>ZV%@6WjiP|-%`NEUrC$0fE)Y>`gXJ#8;I^^=$Vjee@h+gGL zyB@r6N?Z|0O%8pW{&B1;jlnKXl}ymvkc|aaE|^JF1My#lC6YXWyKydbd+x=CM@QP( z=@`Rtt);f{E0o_o_Vk-D)2%!K^wcgLU;=+L5!N|n=0eP!Z zc#9tTtFZ8`8wM#fOd?JnetYA)n=DLRp;Mza`|ZgzNM!DRv^%V>4c>pO{+iybF*F$d zB8y_fw%!MK-#lJ!Hp=V5z%-qHx z3r_U-%R~an+bHYEY9`nSZt1slC3wEnLqkn0*c}!uMi`?@rK}jxH~ydxF=vm# zJ1bj!4CF&WByYO|2UPkQ>9dkvDBG*bfo4(a7pBl-fQD#1%Vz_lFbTaw53QF1cjWtK zMu-O?g(g2YP=;GIa6Jsd#8ZUhV&&TCF@S4qC9;m;0l4O`13cmN(wcemYNW=)PBZ(`thy>RZAHk;>K%*#7jcNp)_`Ol|;L@(@VEBhkUIF1Z;5uoI z!UO?u&BrkYn`m6Pv?Z=0Tyf_*9^`Ap&&P7I!QfJ=anP#Lo)LsJxDG?6Kz|He^F=>8 zUjlR>i5}Gf_Wx}i;EyDEE8vLgaa)2M!iz7ZZdv?!Aqxn-LMg4~8Is%2EPGrI_^Tzp zG+PRm)JTmQ+cRTKCry6rbKP~W_3h}jiVefHyBpZiyH%U=;%!^&ReF*tZgG(fR3ozO zt)=_42Gjl+WVHW&x8Gv&$wlTEh_`?KkuC*6`Ni#IW8t5^9rf2c zPr%eMFOnLe{HwMJfVS1|7)hl5=}SRahl5bGI||VUA^WF(*E53<8=ox-x$&nClLXp< zfqPqWsbTw9?HLE{`O)Bg*c`%SQ zNVyWoU$n>I258Ub&S*#IUkqLiYT`Wd&;P53`^FZu$9cB-h45bu-oJmah^s8L{)be> S*+?|-pOU;9tW?(I<^KoG;XK#? literal 0 HcmV?d00001 diff --git a/source/docs/filters/http/cache/cache_filter_plugins.md b/source/docs/filters/http/cache/cache_filter_plugins.md new file mode 100644 index 0000000000..51798ccccd --- /dev/null +++ b/source/docs/filters/http/cache/cache_filter_plugins.md @@ -0,0 +1,48 @@ +### Overview + +The HTTP Cache Filter handles most of the complexity of HTTP caching semantics, +but delegates the actual storage of HTTP responses to implementations of the +HttpCache interface. These implementations can cover all points on the spectrum +of persistence, performance, and distribution, from local RAM caches to globally +distributed persistent caches. They can be fully custom caches, or +wrappers/adapters around local or remote open-source or proprietary caches. + +If you write a new cache storage implementation, please add it to the Envoy +repository if possible. This is the only way to make sure it stays up-to-date +with Envoy changes, and lets other developers contribute fixes and improvements. + +As you read this, also read the example implementation in `simple_http_cache.h/.cc`. + +You need to write implementations of four small interfaces: + +## HttpCache + * Example Implementation: `SimpleHttpCache` + * `HttpCache` represents an actual cache of responses stored somewhere. It provides methods to set up cache lookups and inserts, and to update the headers of cached responses. + +## HttpCacheFactory + * Example Implementation: `SimpleHttpCacheFactory` + * `HttpCacheFactory` does what it sounds like: it creates HttpCache implementations, based on a name that came from the cache filter's config. + +## LookupContext + * Example Implementation: `SimpleLookupContext` + * `LookupContext` represents a single lookup operation; this is a good place to store whatever per-lookup state you may need during the lookup process. + +## InsertContext + * Example Implementation: `SimpleInsertContext` + * `LookupContext` represents a single insert operation; this is a good place to store whatever per-insert state you may need during the lookup process. + +### Flow + +To initiate a lookup on an HttpCache implementation, the cache filter calls +`HttpCache::makeLookupContext`, which should return a `LookupContextPtr`. The cache filter will +call `LookupContext::getHeaders` to find out if there's a cached response. If +a result is found, the `LookupContext` implementation must call +`LookupRequest::makeLookupResult`, and pass the result to the callback. + +The cache filter will then make a series of `getBody` requests followed by `getTrailers` (if needed). + +If the `LookupResult` in the callback indicates that a response wasn't found, the cache filter will let the request pass upstream. If the origin replies with a cacheable response, the filter will call `HttpCache::makeInsertContext`, and use its methods to insert the response. + +The following diagram shows a potential GET request for a 5M resource that is present and fresh in the cache, with no trailers. In the case of a synchronous in-memory cache, this all happens within `CacheFilter::decodeHeaders`. Solid arrows denote synchronous function calls, while dashed arrows denote asynchronous function calls or their callbacks. Objects that are part of the cache implementation (`HttpCache` and `LookupContext`) are blue. (Other objects are part of the cache filter, or of Envoy. + +![Cache Filter flow diagram](cache_filter_flow.png) From 527853b4faa3106497a695a40c2322137546c142 Mon Sep 17 00:00:00 2001 From: Adam Kotwasinski Date: Mon, 10 Feb 2020 10:15:34 -0800 Subject: [PATCH 37/87] kafka: 2.4.0 support - add support for new data types added in 2.4 (#9813) Signed-off-by: Adam Kotwasinski --- source/extensions/filters/network/kafka/BUILD | 6 + .../filters/network/kafka/serialization.cc | 105 +++- .../filters/network/kafka/serialization.h | 529 +++++++++++++++++- .../filters/network/kafka/tagged_fields.h | 185 ++++++ .../network/kafka/serialization_test.cc | 212 +++++++ .../network/kafka/serialization_utilities.h | 84 ++- 6 files changed, 1117 insertions(+), 4 deletions(-) create mode 100644 source/extensions/filters/network/kafka/tagged_fields.h diff --git a/source/extensions/filters/network/kafka/BUILD b/source/extensions/filters/network/kafka/BUILD index c0608fefcb..8564c02eda 100644 --- a/source/extensions/filters/network/kafka/BUILD +++ b/source/extensions/filters/network/kafka/BUILD @@ -204,6 +204,12 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "tagged_fields_lib", + hdrs = ["tagged_fields.h"], + deps = [":serialization_lib"], +) + envoy_cc_library( name = "serialization_lib", srcs = [ diff --git a/source/extensions/filters/network/kafka/serialization.cc b/source/extensions/filters/network/kafka/serialization.cc index eb0b255a24..cc818bc7f2 100644 --- a/source/extensions/filters/network/kafka/serialization.cc +++ b/source/extensions/filters/network/kafka/serialization.cc @@ -6,12 +6,14 @@ namespace NetworkFilters { namespace Kafka { constexpr static int16_t NULL_STRING_LENGTH = -1; +constexpr static uint32_t NULL_COMPACT_STRING_LENGTH = 0; constexpr static int32_t NULL_BYTES_LENGTH = -1; +constexpr static uint32_t NULL_COMPACT_BYTES_LENGTH = 0; /** * Helper method for deserializers that get the length of data, and then copy the given bytes into a - * local buffer. Templated as there are length and byte type differences. Impl note: This method - * modifies (sets up) most of Deserializer's fields. + * local buffer. Templated as there are length and byte type differences. + * Impl note: This method modifies (sets up) most of Deserializer's fields. * @param data bytes to deserialize. * @param length_deserializer payload length deserializer. * @param length_consumed_marker marker telling whether length has been extracted from @@ -104,6 +106,105 @@ uint32_t NullableBytesDeserializer::feed(absl::string_view& data) { data, length_buf_, length_consumed_, required_, data_buf_, ready_, NULL_BYTES_LENGTH, true); } +/** + * Helper method for "compact" deserializers that get the length of data, and then copy the given + * bytes into a local buffer. Compared to `feedBytesIntoBuffers` we only use template for data type, + * as compact data types always use variable-length uint32 for data length. + * Impl note: This method modifies (sets up) most of Deserializer's fields. + * @param data bytes to deserialize. + * @param length_deserializer payload length deserializer. + * @param length_consumed_marker marker telling whether length has been extracted from + * length_deserializer, and underlying buffer has been initialized. + * @param required remaining bytes to consume. + * @param data_buffer buffer with capacity for 'required' bytes. + * @param ready marker telling whether this deserialized has finished processing. + * @param null_value_length value marking null values. + * @param allow_null_value whether null value if allowed. + * @return number of bytes consumed. + */ +template +uint32_t +feedCompactBytesIntoBuffers(absl::string_view& data, VarUInt32Deserializer& length_deserializer, + bool& length_consumed_marker, uint32_t& required, + std::vector& data_buffer, bool& ready, + const uint32_t null_value_length, const bool allow_null_value) { + + const uint32_t length_consumed = length_deserializer.feed(data); + if (!length_deserializer.ready()) { + // Break early: we still need to fill in length buffer. + return length_consumed; + } + + if (!length_consumed_marker) { + // Length buffer is ready, but we have not yet processed the result. + // We need to extract the real data length and initialize buffer for it. + required = length_deserializer.get(); + + if (null_value_length == required) { + if (allow_null_value) { + // We have received 'null' value in deserializer that allows it (e.g. NullableCompactBytes), + // no more processing is necessary. + ready = true; + } else { + // Invalid payload: null length for non-null object. + throw EnvoyException(absl::StrCat("invalid length: ", required)); + } + } else { + // Compact data types carry data length + 1 (0 is used to mark 'null' in nullable types). + required--; + data_buffer = std::vector(required); + } + + length_consumed_marker = true; + } + + if (ready) { + // Break early: we might not need to consume any bytes for nullable values OR in case of repeat + // invocation on already-ready buffer. + return length_consumed; + } + + const uint32_t data_consumed = std::min(required, data.size()); + const uint32_t written = data_buffer.size() - required; + if (data_consumed > 0) { + memcpy(data_buffer.data() + written, data.data(), data_consumed); + required -= data_consumed; + data = {data.data() + data_consumed, data.size() - data_consumed}; + } + + // We have consumed all the bytes, mark the deserializer as ready. + if (required == 0) { + ready = true; + } + + return length_consumed + data_consumed; +} + +uint32_t CompactStringDeserializer::feed(absl::string_view& data) { + return feedCompactBytesIntoBuffers(data, length_buf_, length_consumed_, required_, + data_buf_, ready_, NULL_COMPACT_STRING_LENGTH, false); +} + +uint32_t NullableCompactStringDeserializer::feed(absl::string_view& data) { + return feedCompactBytesIntoBuffers(data, length_buf_, length_consumed_, required_, + data_buf_, ready_, NULL_COMPACT_STRING_LENGTH, true); +} + +NullableString NullableCompactStringDeserializer::get() const { + const uint32_t original_data_len = length_buf_.get(); + if (NULL_COMPACT_STRING_LENGTH == original_data_len) { + return absl::nullopt; + } else { + return absl::make_optional(std::string(data_buf_.begin(), data_buf_.end())); + } +} + +uint32_t CompactBytesDeserializer::feed(absl::string_view& data) { + return feedCompactBytesIntoBuffers(data, length_buf_, length_consumed_, required_, + data_buf_, ready_, NULL_COMPACT_BYTES_LENGTH, + false); +} + } // namespace Kafka } // namespace NetworkFilters } // namespace Extensions diff --git a/source/extensions/filters/network/kafka/serialization.h b/source/extensions/filters/network/kafka/serialization.h index 40fa550128..fa2717d41e 100644 --- a/source/extensions/filters/network/kafka/serialization.h +++ b/source/extensions/filters/network/kafka/serialization.h @@ -166,6 +166,60 @@ class BooleanDeserializer : public Deserializer { Int8Deserializer buffer_; }; +/** + * Integer deserializer for uint32_t that was encoded as variable-length byte array. + * Encoding documentation: + * https://cwiki.apache.org/confluence/display/KAFKA/KIP-482%3A+The+Kafka+Protocol+should+Support+Optional+Tagged+Fields#KIP-482:TheKafkaProtocolshouldSupportOptionalTaggedFields-UnsignedVarints + * + * Impl note: + * This implementation is equivalent to the one present in Kafka 2.4.0, what means that for 5-byte + * inputs, the data at bits 5-7 in 5th byte are *ignored* (as long as 8th bit is unset). + */ +class VarUInt32Deserializer : public Deserializer { +public: + VarUInt32Deserializer() = default; + + uint32_t feed(absl::string_view& data) override { + uint32_t processed = 0; + while (!ready_ && !data.empty()) { + + // Read next byte from input. + uint8_t el; + memcpy(&el, data.data(), sizeof(uint8_t)); + data = {data.data() + 1, data.size() - 1}; + processed++; + + // Put the 7 bits where they should have been. + // Impl note: the cast is done to avoid undefined behaviour when offset_ >= 28 and some bits + // at positions 5-7 are set (we would have left shift of signed value that does not fit in + // data type). + result_ |= ((static_cast(el) & 0x7f) << offset_); + if ((el & 0x80) == 0) { + // If this was the last byte to process (what is marked by unset highest bit), we are done. + ready_ = true; + break; + } else { + // Otherwise, we need to read next byte. + offset_ += 7; + // Valid input can have at most 5 bytes. + if (offset_ >= 5 * 7) { + throw EnvoyException("VarUInt32 is too long (5th byte has highest bit set)"); + } + } + } + return processed; + } + + bool ready() const override { return ready_; } + + uint32_t get() const override { return result_; } + +private: + uint32_t result_ = 0; + uint32_t offset_ = 0; + bool ready_ = false; +}; + /** * Deserializer of string value. * First reads length (INT16) and then allocates the buffer of given length. @@ -196,6 +250,32 @@ class StringDeserializer : public Deserializer { bool ready_{false}; }; +/** + * Deserializer of compact string value. + * First reads length (UNSIGNED_VARINT) and then allocates the buffer of given length. + * + * From Kafka documentation: + * First the length N + 1 is given as an UNSIGNED_VARINT. + * Then N bytes follow which are the UTF-8 encoding of the character sequence. + */ +class CompactStringDeserializer : public Deserializer { +public: + uint32_t feed(absl::string_view& data) override; + + bool ready() const override { return ready_; } + + std::string get() const override { return std::string(data_buf_.begin(), data_buf_.end()); } + +private: + VarUInt32Deserializer length_buf_; + bool length_consumed_{false}; + + uint32_t required_; + std::vector data_buf_; + + bool ready_{false}; +}; + /** * Deserializer of nullable string value. * First reads length (INT16) and then allocates the buffer of given length. @@ -231,6 +311,35 @@ class NullableStringDeserializer : public Deserializer { bool ready_{false}; }; +/** + * Deserializer of nullable compact string value. + * First reads length (UNSIGNED_VARINT) and then allocates the buffer of given length. + * If length was 0, buffer allocation is omitted and deserializer is immediately ready (returning + * null value). + * + * From Kafka documentation: + * First the length N + 1 is given as an UNSIGNED_VARINT. + * Then N bytes follow which are the UTF-8 encoding of the character sequence. + * A null string is represented with a length of 0. + */ +class NullableCompactStringDeserializer : public Deserializer { +public: + uint32_t feed(absl::string_view& data) override; + + bool ready() const override { return ready_; } + + NullableString get() const override; + +private: + VarUInt32Deserializer length_buf_; + bool length_consumed_{false}; + + uint32_t required_; + std::vector data_buf_; + + bool ready_{false}; +}; + /** * Deserializer of bytes value. * First reads length (INT32) and then allocates the buffer of given length. @@ -258,6 +367,33 @@ class BytesDeserializer : public Deserializer { bool ready_{false}; }; +/** + * Deserializer of compact bytes value. + * First reads length (UNSIGNED_VARINT) and then allocates the buffer of given length. + * + * From Kafka documentation: + * First the length N+1 is given as an UNSIGNED_VARINT. Then N bytes follow. + */ +class CompactBytesDeserializer : public Deserializer { +public: + /** + * Can throw EnvoyException if given bytes length is not valid. + */ + uint32_t feed(absl::string_view& data) override; + + bool ready() const override { return ready_; } + + Bytes get() const override { return data_buf_; } + +private: + VarUInt32Deserializer length_buf_; + bool length_consumed_{false}; + uint32_t required_; + + std::vector data_buf_; + bool ready_{false}; +}; + /** * Deserializer of nullable bytes value. * First reads length (INT32) and then allocates the buffer of given length. @@ -367,6 +503,82 @@ class ArrayDeserializer : public Deserializer> { bool ready_{false}; }; +/** + * Deserializer for compact array of objects of the same type. + * + * First reads the length of the array, then initializes N underlying deserializers of type + * DeserializerType. After the last of N deserializers is ready, the results of each of them are + * gathered and put in a vector. + * @param ResponseType result type returned by deserializer of type DeserializerType. + * @param DeserializerType underlying deserializer type. + * + * From Kafka documentation: + * Represents a sequence of objects of a given type T. Type T can be either a primitive type (e.g. + * STRING) or a structure. First, the length N + 1 is given as an UNSIGNED_VARINT. Then N instances + * of type T follow. A null array is represented with a length of 0. + */ +template +class CompactArrayDeserializer : public Deserializer> { +public: + /** + * Can throw EnvoyException if array length is invalid or if underlying deserializer can throw. + */ + uint32_t feed(absl::string_view& data) override { + + const uint32_t length_consumed = length_buf_.feed(data); + if (!length_buf_.ready()) { + // Break early: we still need to fill in length buffer. + return length_consumed; + } + + if (!length_consumed_) { + const uint32_t required = length_buf_.get(); + if (required >= 1) { + children_ = std::vector(required - 1); + } else { + throw EnvoyException(absl::StrCat("invalid COMPACT_ARRAY length: ", required)); + } + length_consumed_ = true; + } + + if (ready_) { + return length_consumed; + } + + uint32_t child_consumed{0}; + for (DeserializerType& child : children_) { + child_consumed += child.feed(data); + } + + bool children_ready_ = true; + for (DeserializerType& child : children_) { + children_ready_ &= child.ready(); + } + ready_ = children_ready_; + + return length_consumed + child_consumed; + } + + bool ready() const override { return ready_; } + + std::vector get() const override { + std::vector result{}; + result.reserve(children_.size()); + for (const DeserializerType& child : children_) { + const ResponseType child_result = child.get(); + result.push_back(child_result); + } + return result; + } + +private: + VarUInt32Deserializer length_buf_; + bool length_consumed_{false}; + std::vector children_; + bool children_setup_{false}; + bool ready_{false}; +}; + /** * Deserializer for nullable array of objects of the same type. * @@ -456,6 +668,91 @@ class NullableArrayDeserializer : public Deserializer +class NullableCompactArrayDeserializer : public Deserializer> { +public: + /** + * Can throw EnvoyException if array length is invalid or if underlying deserializer can throw. + */ + uint32_t feed(absl::string_view& data) override { + + const uint32_t length_consumed = length_buf_.feed(data); + if (!length_buf_.ready()) { + // Break early: we still need to fill in length buffer. + return length_consumed; + } + + if (!length_consumed_) { + const uint32_t required = length_buf_.get(); + + // Length is unsigned, so we never throw exceptions. + if (required >= 1) { + children_ = std::vector(required - 1); + } else { + ready_ = true; + } + + length_consumed_ = true; + } + + if (ready_) { + return length_consumed; + } + + uint32_t child_consumed{0}; + for (DeserializerType& child : children_) { + child_consumed += child.feed(data); + } + + bool children_ready_ = true; + for (DeserializerType& child : children_) { + children_ready_ &= child.ready(); + } + ready_ = children_ready_; + + return length_consumed + child_consumed; + } + + bool ready() const override { return ready_; } + + NullableArray get() const override { + if (NULL_ARRAY_LENGTH != length_buf_.get()) { + std::vector result{}; + result.reserve(children_.size()); + for (const DeserializerType& child : children_) { + const ResponseType child_result = child.get(); + result.push_back(child_result); + } + return result; + } else { + return absl::nullopt; + } + } + +private: + constexpr static int32_t NULL_ARRAY_LENGTH{0}; + + VarUInt32Deserializer length_buf_; + bool length_consumed_{false}; + std::vector children_; + bool children_setup_{false}; + bool ready_{false}; +}; + /** * Encodes provided argument in Kafka format. * In case of primitive types, this is done explicitly as per specification. @@ -465,7 +762,6 @@ class NullableArrayDeserializer : public Deserializer uint32_t computeSize(const NullableArray& arg) const; + /** + * Compute size of given reference, if it were to be compactly encoded. + * @return serialized size of argument. + */ + template uint32_t computeCompactSize(const T& arg) const; + + /** + * Compute size of given array, if it were to be compactly encoded. + * @return serialized size of argument. + */ + template uint32_t computeCompactSize(const std::vector& arg) const; + + /** + * Compute size of given nullable array, if it were to be encoded. + * @return serialized size of argument. + */ + template uint32_t computeCompactSize(const NullableArray& arg) const; + /** * Encode given reference in a buffer. * @return bytes written @@ -506,6 +820,24 @@ class EncodingContext { */ template uint32_t encode(const NullableArray& arg, Buffer::Instance& dst); + /** + * Compactly encode given reference in a buffer. + * @return bytes written. + */ + template uint32_t encodeCompact(const T& arg, Buffer::Instance& dst); + + /** + * Compactly encode given array in a buffer. + * @return bytes written. + */ + template uint32_t encodeCompact(const std::vector& arg, Buffer::Instance& dst); + + /** + * Compactly encode given nullable array in a buffer. + * @return bytes written. + */ + template uint32_t encodeCompact(const NullableArray& arg, Buffer::Instance& dst); + int16_t apiVersion() const { return api_version_; } private: @@ -589,6 +921,89 @@ inline uint32_t EncodingContext::computeSize(const NullableArray& arg) const return arg ? computeSize(*arg) : sizeof(int32_t); } +/** + * For non-primitive types, call `computeCompactSize` on them, to delegate the work to the entity + * itself. The entity may use the information in context to decide which fields are included etc. + */ +template inline uint32_t EncodingContext::computeCompactSize(const T& arg) const { + return arg.computeCompactSize(*this); +} + +/** + * Template overload for int32_t. + * This data type is not compacted, so we just point to non-compact implementation. + */ +template <> inline uint32_t EncodingContext::computeCompactSize(const int32_t& arg) const { + return computeSize(arg); +} + +/** + * Template overload for uint32_t. + * For this data type, we notice that the result's length depends on whether there are any bits set + * in groups (1-7, 8-14, 15-21, 22-28, 29-32). + */ +template <> inline uint32_t EncodingContext::computeCompactSize(const uint32_t& arg) const { + if (arg <= 0x7f) /* 2^7-1 */ { + return 1; + } else if (arg <= 0x3fff) /* 2^14-1 */ { + return 2; + } else if (arg <= 0x1fffff) /* 2^21-1 */ { + return 3; + } else if (arg <= 0xfffffff) /* 2^28-1 */ { + return 4; + } else { + return 5; + } +} + +/** + * Template overload for compact string. + * Kafka CompactString's size is var-len encoding of N+1 + N bytes. + */ +template <> inline uint32_t EncodingContext::computeCompactSize(const std::string& arg) const { + return computeCompactSize(static_cast(arg.size()) + 1) + arg.size(); +} + +/** + * Template overload for compact nullable string. + * Kafka CompactString's size is var-len encoding of N+1 + N bytes, or 1 otherwise (because we + * var-length encode the length of 0). + */ +template <> inline uint32_t EncodingContext::computeCompactSize(const NullableString& arg) const { + return arg ? computeCompactSize(*arg) : 1; +} + +/** + * Template overload for compact byte array. + * Kafka CompactBytes' size is var-len encoding of N+1 + N bytes. + */ +template <> inline uint32_t EncodingContext::computeCompactSize(const Bytes& arg) const { + return computeCompactSize(static_cast(arg.size()) + 1) + arg.size(); +} + +/** + * Template overload for CompactArray of T. + * The size of array is compact size of header and all of its elements. + */ +template +uint32_t EncodingContext::computeCompactSize(const std::vector& arg) const { + uint32_t result = computeCompactSize(static_cast(arg.size()) + 1); + for (const T& el : arg) { + result += computeCompactSize(el); + } + return result; +} + +/** + * Template overload for CompactNullableArray of T. + * The size of array is compact size of header and all of its elements; 1 otherwise (because we + * var-length encode the length of 0). + */ +template +uint32_t EncodingContext::computeCompactSize(const NullableArray& arg) const { + return arg ? computeCompactSize(*arg) : 1; +} + /** * For non-primitive types, call `encode` on them, to delegate the serialization to the entity * itself. @@ -714,6 +1129,118 @@ uint32_t EncodingContext::encode(const NullableArray& arg, Buffer::Instance& } } +/** + * For non-primitive types, call `encodeCompact` on them, to delegate the serialization to the + * entity itself. + */ +template +inline uint32_t EncodingContext::encodeCompact(const T& arg, Buffer::Instance& dst) { + return arg.encodeCompact(dst, *this); +} + +/** + * int32_t is not encoded in compact fashion, so we just delegate to normal implementation. + */ +template <> +inline uint32_t EncodingContext::encodeCompact(const int32_t& arg, Buffer::Instance& dst) { + return encode(arg, dst); +} + +/** + * Template overload for variable-length uint32_t (VAR_UINT). + * Encode the value in 7-bit chunks + marker if field is the last one. + * Details: + * https://cwiki.apache.org/confluence/display/KAFKA/KIP-482%3A+The+Kafka+Protocol+should+Support+Optional+Tagged+Fields#KIP-482:TheKafkaProtocolshouldSupportOptionalTaggedFields-UnsignedVarints + */ +template <> +inline uint32_t EncodingContext::encodeCompact(const uint32_t& arg, Buffer::Instance& dst) { + uint32_t value = arg; + + uint32_t elements_with_1 = 0; + // As long as there are bits set on indexes 8 or higher (counting from 1). + while ((value & ~(0x7f)) != 0) { + // Save next 7-bit batch with highest bit set. + const uint8_t el = (value & 0x7f) | 0x80; + dst.add(&el, sizeof(uint8_t)); + value >>= 7; + elements_with_1++; + } + + // After the loop has finished, we are certain that bit 8 = 0, so we can just add final element. + const uint8_t el = value; + dst.add(&el, sizeof(uint8_t)); + + return elements_with_1 + 1; +} + +/** + * Template overload for std::string. + * Encode string as VAR_UINT + N bytes. + */ +template <> +inline uint32_t EncodingContext::encodeCompact(const std::string& arg, Buffer::Instance& dst) { + const uint32_t string_length = arg.length(); + const uint32_t header_length = encodeCompact(string_length + 1, dst); + dst.add(arg.c_str(), string_length); + return header_length + string_length; +} + +/** + * Template overload for NullableString. + * Encode string as VAR_UINT + N bytes, or VAR_UINT 0 for null value. + */ +template <> +inline uint32_t EncodingContext::encodeCompact(const NullableString& arg, Buffer::Instance& dst) { + if (arg.has_value()) { + return encodeCompact(*arg, dst); + } else { + const uint32_t len = 0; + return encodeCompact(len, dst); + } +} + +/** + * Template overload for Bytes. + * Encode byte array as VAR_UINT + N bytes. + */ +template <> +inline uint32_t EncodingContext::encodeCompact(const Bytes& arg, Buffer::Instance& dst) { + const uint32_t data_length = arg.size(); + const uint32_t header_length = encodeCompact(data_length + 1, dst); + dst.add(arg.data(), data_length); + return header_length + data_length; +} + +/** + * Encode object array of T as VAR_UINT + N elements. + * Each element of type T then serializes itself on its own. + */ +template +uint32_t EncodingContext::encodeCompact(const std::vector& arg, Buffer::Instance& dst) { + const NullableArray wrapped = {arg}; + return encodeCompact(wrapped, dst); +} + +/** + * Encode nullable object array of T as VAR_UINT + N elements, or VAR_UINT 0 for null value. + * Each element of type T then serializes itself on its own. + */ +template +uint32_t EncodingContext::encodeCompact(const NullableArray& arg, Buffer::Instance& dst) { + if (arg.has_value()) { + const uint32_t len = arg->size() + 1; + const uint32_t header_length = encodeCompact(len, dst); + uint32_t written{0}; + for (const T& el : *arg) { + written += encodeCompact(el, dst); + } + return header_length + written; + } else { + const uint32_t len = 0; + return encodeCompact(len, dst); + } +} + } // namespace Kafka } // namespace NetworkFilters } // namespace Extensions diff --git a/source/extensions/filters/network/kafka/tagged_fields.h b/source/extensions/filters/network/kafka/tagged_fields.h new file mode 100644 index 0000000000..cda6a7162e --- /dev/null +++ b/source/extensions/filters/network/kafka/tagged_fields.h @@ -0,0 +1,185 @@ +#pragma once + +#include + +#include "extensions/filters/network/kafka/serialization.h" + +/** + * This header file provides serialization support for tagged fields structure added in 2.4. + * https://github.com/apache/kafka/blob/2.4.0/clients/src/main/java/org/apache/kafka/common/protocol/types/TaggedFields.java + * + * Impl note: contrary to other compact data structures, data in tagged field does not have +1 in + * data length. + */ + +namespace Envoy { +namespace Extensions { +namespace NetworkFilters { +namespace Kafka { + +/** + * Simple data-holding structure. + */ +struct TaggedField { + + uint32_t tag_; + std::vector data_; + + uint32_t computeCompactSize(const EncodingContext& encoder) const { + uint32_t result{0}; + result += encoder.computeCompactSize(tag_); + result += encoder.computeCompactSize(static_cast(data_.size())); + result += data_.size(); + return result; + } + + uint32_t encodeCompact(Buffer::Instance& dst, EncodingContext& encoder) const { + uint32_t written{0}; + written += encoder.encodeCompact(tag_, dst); + written += encoder.encodeCompact(static_cast(data_.size()), dst); + dst.add(data_.data(), data_.size()); + written += data_.size(); + return written; + } + + bool operator==(const TaggedField& rhs) const { return tag_ == rhs.tag_ && data_ == rhs.data_; } +}; + +/** + * Deserializer responsible for extracting a TaggedField from data provided. + */ +class TaggedFieldDeserializer : public Deserializer { +public: + TaggedFieldDeserializer() = default; + + uint32_t feed(absl::string_view& data) override { + uint32_t consumed = 0; + consumed += tag_deserializer_.feed(data); + consumed += length_deserializer_.feed(data); + + if (!length_deserializer_.ready()) { + return consumed; + } + + if (!length_consumed_) { + required_ = length_deserializer_.get(); + data_buffer_ = std::vector(required_); + length_consumed_ = true; + } + + const uint32_t data_consumed = std::min(required_, data.size()); + const uint32_t written = data_buffer_.size() - required_; + if (data_consumed > 0) { + memcpy(data_buffer_.data() + written, data.data(), data_consumed); + required_ -= data_consumed; + data = {data.data() + data_consumed, data.size() - data_consumed}; + } + + if (required_ == 0) { + ready_ = true; + } + + return consumed; + }; + + bool ready() const override { return ready_; }; + + TaggedField get() const override { return {tag_deserializer_.get(), data_buffer_}; }; + +private: + VarUInt32Deserializer tag_deserializer_; + VarUInt32Deserializer length_deserializer_; + bool length_consumed_{false}; + uint32_t required_; + std::vector data_buffer_; + bool ready_{false}; +}; + +/** + * Aggregate of multiple TaggedField objects. + */ +struct TaggedFields { + + const std::vector fields_; + + uint32_t computeCompactSize(const EncodingContext& encoder) const { + uint32_t result{0}; + result += encoder.computeCompactSize(static_cast(fields_.size())); + for (const TaggedField& tagged_field : fields_) { + result += tagged_field.computeCompactSize(encoder); + } + return result; + } + + uint32_t encodeCompact(Buffer::Instance& dst, EncodingContext& encoder) const { + uint32_t written{0}; + written += encoder.encodeCompact(static_cast(fields_.size()), dst); + for (const TaggedField& tagged_field : fields_) { + written += tagged_field.encodeCompact(dst, encoder); + } + return written; + } + + bool operator==(const TaggedFields& rhs) const { return fields_ == rhs.fields_; } +}; + +/** + * Deserializer responsible for extracting tagged fields from data provided. + */ +class TaggedFieldsDeserializer : public Deserializer { +public: + uint32_t feed(absl::string_view& data) override { + + const uint32_t count_consumed = count_deserializer_.feed(data); + if (!count_deserializer_.ready()) { + return count_consumed; + } + + if (!children_setup_) { + const uint32_t field_count = count_deserializer_.get(); + children_ = std::vector(field_count); + children_setup_ = true; + } + + if (ready_) { + return count_consumed; + } + + uint32_t child_consumed{0}; + for (TaggedFieldDeserializer& child : children_) { + child_consumed += child.feed(data); + } + + bool children_ready_ = true; + for (TaggedFieldDeserializer& child : children_) { + children_ready_ &= child.ready(); + } + ready_ = children_ready_; + + return count_consumed + child_consumed; + }; + + bool ready() const override { return ready_; }; + + TaggedFields get() const override { + std::vector fields{}; + fields.reserve(children_.size()); + for (const TaggedFieldDeserializer& child : children_) { + const TaggedField child_result = child.get(); + fields.push_back(child_result); + } + return {fields}; + }; + +private: + VarUInt32Deserializer count_deserializer_; + std::vector children_; + + bool children_setup_ = false; + bool ready_ = false; +}; + +} // namespace Kafka +} // namespace NetworkFilters +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/filters/network/kafka/serialization_test.cc b/test/extensions/filters/network/kafka/serialization_test.cc index d52cdff25f..250d35121f 100644 --- a/test/extensions/filters/network/kafka/serialization_test.cc +++ b/test/extensions/filters/network/kafka/serialization_test.cc @@ -24,10 +24,14 @@ TEST_EmptyDeserializerShouldNotBeReady(Int32Deserializer); TEST_EmptyDeserializerShouldNotBeReady(UInt32Deserializer); TEST_EmptyDeserializerShouldNotBeReady(Int64Deserializer); TEST_EmptyDeserializerShouldNotBeReady(BooleanDeserializer); +TEST_EmptyDeserializerShouldNotBeReady(VarUInt32Deserializer); TEST_EmptyDeserializerShouldNotBeReady(StringDeserializer); +TEST_EmptyDeserializerShouldNotBeReady(CompactStringDeserializer); TEST_EmptyDeserializerShouldNotBeReady(NullableStringDeserializer); +TEST_EmptyDeserializerShouldNotBeReady(NullableCompactStringDeserializer); TEST_EmptyDeserializerShouldNotBeReady(BytesDeserializer); +TEST_EmptyDeserializerShouldNotBeReady(CompactBytesDeserializer); TEST_EmptyDeserializerShouldNotBeReady(NullableBytesDeserializer); TEST(ArrayDeserializer, EmptyBufferShouldNotBeReady) { @@ -37,6 +41,13 @@ TEST(ArrayDeserializer, EmptyBufferShouldNotBeReady) { ASSERT_EQ(testee.ready(), false); } +TEST(CompactArrayDeserializer, EmptyBufferShouldNotBeReady) { + // given + const CompactArrayDeserializer testee{}; + // when, then + ASSERT_EQ(testee.ready(), false); +} + TEST(NullableArrayDeserializer, EmptyBufferShouldNotBeReady) { // given const NullableArrayDeserializer testee{}; @@ -44,6 +55,13 @@ TEST(NullableArrayDeserializer, EmptyBufferShouldNotBeReady) { ASSERT_EQ(testee.ready(), false); } +TEST(NullableCompactArrayDeserializer, EmptyBufferShouldNotBeReady) { + // given + const NullableCompactArrayDeserializer testee{}; + // when, then + ASSERT_EQ(testee.ready(), false); +} + // Extracted test for numeric buffers. #define TEST_DeserializerShouldDeserialize(BufferClass, DataClass, Value) \ TEST(DataClass, ShouldConsumeCorrectAmountOfData) { \ @@ -61,6 +79,79 @@ TEST_DeserializerShouldDeserialize(BooleanDeserializer, bool, true); EncodingContext encoder{-1}; // Provided api_version does not matter for primitive types. +// Variable-length uint32_t tests. + +TEST(VarUInt32Deserializer, ShouldDeserialize) { + const uint32_t value = 0; + serializeCompactThenDeserializeAndCheckEquality(value); +} + +TEST(VarUInt32Deserializer, ShouldDeserializeMaxUint32) { + const uint32_t value = std::numeric_limits::max(); + serializeCompactThenDeserializeAndCheckEquality(value); +} + +TEST(VarUInt32Deserializer, ShouldDeserializeEdgeValues) { + // Each of these values should fit in 1, 2, 3, 4 bytes. + std::vector values = {0x7f, 0x3fff, 0x1fffff, 0xfffffff}; + for (auto i = 0; i < static_cast(values.size()); ++i) { + // given + Buffer::OwnedImpl buffer; + + // when + const uint32_t written = encoder.encodeCompact(values[i], buffer); + + // then + ASSERT_EQ(written, i + 1); + absl::string_view data = {getRawData(buffer), 1024}; + // All bits in lower bytes need to be set. + for (auto j = 0; j + 1 < i; ++j) { + ASSERT_EQ(static_cast(data[j]), 0xFF); + } + // Highest bit in last byte needs to be clear (end marker). + ASSERT_EQ(static_cast(data[i]), 0x7F); + } +} + +TEST(VarUInt32Deserializer, ShouldSerializeMaxUint32Properly) { + // given + Buffer::OwnedImpl buffer; + + // when + const uint32_t value = std::numeric_limits::max(); + const uint32_t result = encoder.encodeCompact(value, buffer); + + // then + ASSERT_EQ(result, 5); + absl::string_view data = {getRawData(buffer), 1024}; + ASSERT_EQ(static_cast(data[0]), 0xFF); // Bits 1-7 (starting at 1). + ASSERT_EQ(static_cast(data[1]), 0xFF); // Bits 8-14. + ASSERT_EQ(static_cast(data[2]), 0xFF); // Bits 15-21. + ASSERT_EQ(static_cast(data[3]), 0xFF); // Bits 22-28. + ASSERT_EQ(static_cast(data[4]), 0x0F); // Bits 29-32. +} + +TEST(VarUInt32Deserializer, ShouldThrowIfNoEndWith5Bytes) { + // given + VarUInt32Deserializer testee; + Buffer::OwnedImpl buffer; + + // The buffer makes no sense, it's 5 times 0xFF, while varint encoding ensures that in the worst + // case 5th byte has the highest bit clear. + for (int i = 0; i < 5; ++i) { + const uint8_t all_bits_set = 0xFF; + buffer.add(&all_bits_set, sizeof(all_bits_set)); + } + + absl::string_view data = {getRawData(buffer), 1024}; + + // when + // then + EXPECT_THROW(testee.feed(data), EnvoyException); +} + +// String tests. + TEST(StringDeserializer, ShouldDeserialize) { const std::string value = "sometext"; serializeThenDeserializeAndCheckEquality(value); @@ -86,6 +177,35 @@ TEST(StringDeserializer, ShouldThrowOnInvalidLength) { EXPECT_THROW(testee.feed(data), EnvoyException); } +// Compact string tests. + +TEST(CompactStringDeserializer, ShouldDeserialize) { + const std::string value = "sometext"; + serializeCompactThenDeserializeAndCheckEquality(value); +} + +TEST(CompactStringDeserializer, ShouldDeserializeEmptyString) { + const std::string value = ""; + serializeCompactThenDeserializeAndCheckEquality(value); +} + +TEST(CompactStringDeserializer, ShouldThrowOnInvalidLength) { + // given + CompactStringDeserializer testee; + Buffer::OwnedImpl buffer; + + const uint32_t len = 0; // COMPACT_STRING requires length >= 1. + encoder.encodeCompact(len, buffer); + + absl::string_view data = {getRawData(buffer), 1024}; + + // when + // then + EXPECT_THROW(testee.feed(data), EnvoyException); +} + +// Nullable string tests. + TEST(NullableStringDeserializer, ShouldDeserializeString) { // given const NullableString value{"sometext"}; @@ -119,6 +239,28 @@ TEST(NullableStringDeserializer, ShouldThrowOnInvalidLength) { EXPECT_THROW(testee.feed(data), EnvoyException); } +// Nullable compact string tests. + +TEST(NullableCompactStringDeserializer, ShouldDeserializeString) { + // given + const NullableString value{"sometext"}; + serializeCompactThenDeserializeAndCheckEquality(value); +} + +TEST(NullableCompactStringDeserializer, ShouldDeserializeEmptyString) { + // given + const NullableString value{""}; + serializeCompactThenDeserializeAndCheckEquality(value); +} + +TEST(NullableCompactStringDeserializer, ShouldDeserializeAbsentString) { + // given + const NullableString value = absl::nullopt; + serializeCompactThenDeserializeAndCheckEquality(value); +} + +// Byte array tests. + TEST(BytesDeserializer, ShouldDeserialize) { const Bytes value{'a', 'b', 'c', 'd'}; serializeThenDeserializeAndCheckEquality(value); @@ -144,6 +286,35 @@ TEST(BytesDeserializer, ShouldThrowOnInvalidLength) { EXPECT_THROW(testee.feed(data), EnvoyException); } +// Compact byte array tests. + +TEST(CompactBytesDeserializer, ShouldDeserialize) { + const Bytes value{'a', 'b', 'c', 'd'}; + serializeCompactThenDeserializeAndCheckEquality(value); +} + +TEST(CompactBytesDeserializer, ShouldDeserializeEmptyBytes) { + const Bytes value{}; + serializeCompactThenDeserializeAndCheckEquality(value); +} + +TEST(CompactBytesDeserializer, ShouldThrowOnInvalidLength) { + // given + CompactBytesDeserializer testee; + Buffer::OwnedImpl buffer; + + const uint32_t bytes_length = 0; // COMPACT_BYTES requires length >= 1. + encoder.encodeCompact(bytes_length, buffer); + + absl::string_view data = {getRawData(buffer), 1024}; + + // when + // then + EXPECT_THROW(testee.feed(data), EnvoyException); +} + +// Nullable byte array tests. + TEST(NullableBytesDeserializer, ShouldDeserialize) { const NullableBytes value{{'a', 'b', 'c', 'd'}}; serializeThenDeserializeAndCheckEquality(value); @@ -174,6 +345,8 @@ TEST(NullableBytesDeserializer, ShouldThrowOnInvalidLength) { EXPECT_THROW(testee.feed(data), EnvoyException); } +// Generic array tests. + TEST(ArrayDeserializer, ShouldConsumeCorrectAmountOfData) { const std::vector value{{"aaa", "bbbbb", "cc", "d", "e", "ffffffff"}}; serializeThenDeserializeAndCheckEquality>( @@ -195,6 +368,31 @@ TEST(ArrayDeserializer, ShouldThrowOnInvalidLength) { EXPECT_THROW(testee.feed(data), EnvoyException); } +// Compact generic array tests. + +TEST(CompactArrayDeserializer, ShouldConsumeCorrectAmountOfData) { + const std::vector value{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}; + serializeCompactThenDeserializeAndCheckEquality< + CompactArrayDeserializer>(value); +} + +TEST(CompactArrayDeserializer, ShouldThrowOnInvalidLength) { + // given + CompactArrayDeserializer testee; + Buffer::OwnedImpl buffer; + + const uint32_t len = 0; // COMPACT_ARRAY accepts length >= 1. + encoder.encodeCompact(len, buffer); + + absl::string_view data = {getRawData(buffer), 1024}; + + // when + // then + EXPECT_THROW(testee.feed(data), EnvoyException); +} + +// Generic nullable array tests. + TEST(NullableArrayDeserializer, ShouldConsumeCorrectAmountOfData) { const NullableArray value{{"aaa", "bbbbb", "cc", "d", "e", "ffffffff"}}; serializeThenDeserializeAndCheckEquality< @@ -222,6 +420,20 @@ TEST(NullableArrayDeserializer, ShouldThrowOnInvalidLength) { EXPECT_THROW(testee.feed(data), EnvoyException); } +// Compact nullable generic array tests. + +TEST(NullableCompactArrayDeserializer, ShouldConsumeCorrectAmountOfData) { + const NullableArray value{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}; + serializeCompactThenDeserializeAndCheckEquality< + NullableCompactArrayDeserializer>(value); +} + +TEST(NullableCompactArrayDeserializer, ShouldConsumeNullArray) { + const NullableArray value = absl::nullopt; + serializeCompactThenDeserializeAndCheckEquality< + NullableCompactArrayDeserializer>(value); +} + } // namespace SerializationTest } // namespace Kafka } // namespace NetworkFilters diff --git a/test/extensions/filters/network/kafka/serialization_utilities.h b/test/extensions/filters/network/kafka/serialization_utilities.h index 7b37d9b310..e9fb2a4491 100644 --- a/test/extensions/filters/network/kafka/serialization_utilities.h +++ b/test/extensions/filters/network/kafka/serialization_utilities.h @@ -106,12 +106,94 @@ void serializeThenDeserializeAndCheckEqualityWithChunks(AT expected) { ASSERT_EQ(more_data.size(), garbage_size); } -// Wrapper to run both tests. +// Same thing as 'serializeThenDeserializeAndCheckEqualityInOneGo', just uses compact encoding. +template +void serializeCompactThenDeserializeAndCheckEqualityInOneGo(AT expected) { + // given + BT testee{}; + + Buffer::OwnedImpl buffer; + EncodingContext encoder{-1}; + const uint32_t written = encoder.encodeCompact(expected, buffer); + // Insert garbage after serialized payload. + const uint32_t garbage_size = encoder.encode(Bytes(10000), buffer); + + // Tell parser that there is more data, it should never consume more than written. + const absl::string_view orig_data = {getRawData(buffer), written + garbage_size}; + absl::string_view data = orig_data; + + // when + const uint32_t consumed = testee.feed(data); + + // then + ASSERT_EQ(consumed, written); + ASSERT_EQ(testee.ready(), true); + ASSERT_EQ(testee.get(), expected); + assertStringViewIncrement(data, orig_data, consumed); + + // when - 2 + const uint32_t consumed2 = testee.feed(data); + + // then - 2 (nothing changes) + ASSERT_EQ(consumed2, 0); + assertStringViewIncrement(data, orig_data, consumed); +} + +// Same thing as 'serializeThenDeserializeAndCheckEqualityWithChunks', just uses compact encoding. +template +void serializeCompactThenDeserializeAndCheckEqualityWithChunks(AT expected) { + // given + BT testee{}; + + Buffer::OwnedImpl buffer; + EncodingContext encoder{-1}; + const uint32_t written = encoder.encodeCompact(expected, buffer); + // Insert garbage after serialized payload. + const uint32_t garbage_size = encoder.encode(Bytes(10000), buffer); + + const absl::string_view orig_data = {getRawData(buffer), written + garbage_size}; + + // when + absl::string_view data = orig_data; + uint32_t consumed = 0; + for (uint32_t i = 0; i < written; ++i) { + data = {data.data(), 1}; // Consume data byte-by-byte. + uint32_t step = testee.feed(data); + consumed += step; + ASSERT_EQ(step, 1); + ASSERT_EQ(data.size(), 0); + } + + // then + ASSERT_EQ(consumed, written); + ASSERT_EQ(testee.ready(), true); + ASSERT_EQ(testee.get(), expected); + + ASSERT_EQ(data.data(), orig_data.data() + consumed); + + // when - 2 + absl::string_view more_data = {data.data(), garbage_size}; + const uint32_t consumed2 = testee.feed(more_data); + + // then - 2 (nothing changes) + ASSERT_EQ(consumed2, 0); + ASSERT_EQ(more_data.data(), data.data()); + ASSERT_EQ(more_data.size(), garbage_size); +} + +// Wrapper to run both tests for normal serialization. template void serializeThenDeserializeAndCheckEquality(AT expected) { serializeThenDeserializeAndCheckEqualityInOneGo(expected); serializeThenDeserializeAndCheckEqualityWithChunks(expected); } +// Wrapper to run both tests for compact serialization. +template +void serializeCompactThenDeserializeAndCheckEquality(AT expected) { + serializeCompactThenDeserializeAndCheckEqualityInOneGo(expected); + serializeCompactThenDeserializeAndCheckEqualityWithChunks(expected); +} + /** * Message callback that captures the messages. */ From 7e60f33641cb005aaee6c8b878c7bf0476a863d9 Mon Sep 17 00:00:00 2001 From: Kuat Date: Mon, 10 Feb 2020 15:08:25 -0800 Subject: [PATCH 38/87] change ip_tagging to buffer for a test (#9997) Signed-off-by: Kuat Yessenov --- test/server/BUILD | 6 +++--- test/server/options_impl_test.cc | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/server/BUILD b/test/server/BUILD index 358ec82456..f9336a23f8 100644 --- a/test/server/BUILD +++ b/test/server/BUILD @@ -146,7 +146,7 @@ envoy_cc_test( "//source/common/common:utility_lib", "//source/common/stats:stats_lib", "//source/extensions/filters/http:well_known_names", - "//source/extensions/filters/http/ip_tagging:config", + "//source/extensions/filters/http/buffer:config", "//source/server:options_lib", "//test/mocks/api:api_mocks", "//test/test_common:environment_lib", @@ -155,8 +155,8 @@ envoy_cc_test( "//test/test_common:utility_lib", "@envoy_api//envoy/admin/v3:pkg_cc_proto", "@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto", - "@envoy_api//envoy/config/filter/http/ip_tagging/v2:pkg_cc_proto", - "@envoy_api//envoy/extensions/filters/http/ip_tagging/v3:pkg_cc_proto", + "@envoy_api//envoy/config/filter/http/buffer/v2:pkg_cc_proto", + "@envoy_api//envoy/extensions/filters/http/buffer/v3:pkg_cc_proto", ], ) diff --git a/test/server/options_impl_test.cc b/test/server/options_impl_test.cc index 276a99747c..39be5bd8a8 100644 --- a/test/server/options_impl_test.cc +++ b/test/server/options_impl_test.cc @@ -8,16 +8,16 @@ #include "envoy/admin/v3/server_info.pb.h" #include "envoy/common/exception.h" #include "envoy/config/bootstrap/v3/bootstrap.pb.h" -#include "envoy/config/filter/http/ip_tagging/v2/ip_tagging.pb.h" +#include "envoy/config/filter/http/buffer/v2/buffer.pb.h" #include "envoy/config/typed_config.h" -#include "envoy/extensions/filters/http/ip_tagging/v3/ip_tagging.pb.h" +#include "envoy/extensions/filters/http/buffer/v3/buffer.pb.h" #include "envoy/server/filter_config.h" #include "common/common/utility.h" #include "server/options_impl.h" -#include "extensions/filters/http/ip_tagging/ip_tagging_filter.h" +#include "extensions/filters/http/buffer/buffer_filter.h" #include "extensions/filters/http/well_known_names.h" #if defined(__linux__) @@ -553,17 +553,17 @@ TEST(DisableExtensions, IsDisabled) { } TEST(FactoryByTypeTest, EarlierVersionConfigType) { - envoy::config::filter::http::ip_tagging::v2::IPTagging v2_config; + envoy::config::filter::http::buffer::v2::Buffer v2_config; auto factory = Registry::FactoryRegistry:: getFactoryByType(v2_config.GetDescriptor()->full_name()); EXPECT_NE(factory, nullptr); - EXPECT_EQ(factory->name(), Extensions::HttpFilters::HttpFilterNames::get().IpTagging); + EXPECT_EQ(factory->name(), Extensions::HttpFilters::HttpFilterNames::get().Buffer); - envoy::extensions::filters::http::ip_tagging::v3::IPTagging v3_config; + envoy::extensions::filters::http::buffer::v3::Buffer v3_config; factory = Registry::FactoryRegistry:: getFactoryByType(v3_config.GetDescriptor()->full_name()); EXPECT_NE(factory, nullptr); - EXPECT_EQ(factory->name(), Extensions::HttpFilters::HttpFilterNames::get().IpTagging); + EXPECT_EQ(factory->name(), Extensions::HttpFilters::HttpFilterNames::get().Buffer); ProtobufWkt::Any non_api_type; factory = Registry::FactoryRegistry:: From 4e1753fd683e8c0a901da62251640a434042d2d5 Mon Sep 17 00:00:00 2001 From: Henry Yang <4411287+HenryYYang@users.noreply.github.com> Date: Mon, 10 Feb 2020 15:51:54 -0800 Subject: [PATCH 39/87] Fix refresh manager test (#9999) Signed-off-by: Henry Yang --- .../redis/cluster_refresh_manager_test.cc | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/test/extensions/common/redis/cluster_refresh_manager_test.cc b/test/extensions/common/redis/cluster_refresh_manager_test.cc index fd28ae17ef..506dbf44a6 100644 --- a/test/extensions/common/redis/cluster_refresh_manager_test.cc +++ b/test/extensions/common/redis/cluster_refresh_manager_test.cc @@ -127,23 +127,27 @@ TEST_F(ClusterRefreshManagerTest, Basic) { Thread::ThreadPtr thread_1 = platform_.threadFactory().createThread([&]() { waitForTime(MonotonicTime(std::chrono::seconds(1))); EXPECT_TRUE(refresh_manager_->onRedirection(cluster_name_)); - waitForTime(MonotonicTime(std::chrono::seconds(2))); - refresh_manager_->onRedirection(cluster_name_); + // wait for 3 ensures that thread_1's first onRedirection is completed, + // as wait for 2 would only ensure onRedirection was started waitForTime(MonotonicTime(std::chrono::seconds(3))); + refresh_manager_->onRedirection(cluster_name_); + waitForTime(MonotonicTime(std::chrono::seconds(4))); }); Thread::ThreadPtr thread_2 = platform_.threadFactory().createThread([&]() { - waitForTime(MonotonicTime(std::chrono::seconds(2))); - refresh_manager_->onRedirection(cluster_name_); + // wait for 3 ensures that thread_1's first onRedirection is completed, + // as wait for 2 would only ensure onRedirection was started waitForTime(MonotonicTime(std::chrono::seconds(3))); + refresh_manager_->onRedirection(cluster_name_); + waitForTime(MonotonicTime(std::chrono::seconds(4))); }); - advanceTime(MonotonicTime(std::chrono::seconds(3)), 2); + advanceTime(MonotonicTime(std::chrono::seconds(4)), 2); thread_1->join(); thread_2->join(); EXPECT_GE(callback_count_, 2); EXPECT_EQ(cluster_info->redirects_count_, 0); - EXPECT_EQ(cluster_info->last_callback_time_ms_.load(), 2000); + EXPECT_EQ(cluster_info->last_callback_time_ms_.load(), 3000); EXPECT_EQ(cluster_info->min_time_between_triggering_, std::chrono::milliseconds(1000)); EXPECT_EQ(cluster_info->redirects_threshold_, 1); EXPECT_EQ(cluster_info->failure_threshold_, 1); @@ -169,23 +173,27 @@ TEST_F(ClusterRefreshManagerTest, BasicFailureEvents) { Thread::ThreadPtr thread_1 = platform_.threadFactory().createThread([&]() { waitForTime(MonotonicTime(std::chrono::seconds(1))); EXPECT_TRUE(refresh_manager_->onFailure(cluster_name_)); - waitForTime(MonotonicTime(std::chrono::seconds(2))); - refresh_manager_->onFailure(cluster_name_); + // wait for 3 ensures that thread_1's first onRedirection is completed, + // as wait for 2 would only ensure onRedirection was started waitForTime(MonotonicTime(std::chrono::seconds(3))); + refresh_manager_->onFailure(cluster_name_); + waitForTime(MonotonicTime(std::chrono::seconds(4))); }); Thread::ThreadPtr thread_2 = platform_.threadFactory().createThread([&]() { - waitForTime(MonotonicTime(std::chrono::seconds(2))); - refresh_manager_->onFailure(cluster_name_); + // wait for 3 ensures that thread_1's first onRedirection is completed, + // as wait for 2 would only ensure onRedirection was started waitForTime(MonotonicTime(std::chrono::seconds(3))); + refresh_manager_->onFailure(cluster_name_); + waitForTime(MonotonicTime(std::chrono::seconds(4))); }); - advanceTime(MonotonicTime(std::chrono::seconds(3)), 2); + advanceTime(MonotonicTime(std::chrono::seconds(4)), 2); thread_1->join(); thread_2->join(); EXPECT_GE(callback_count_, 2); EXPECT_EQ(cluster_info->failures_count_, 0); - EXPECT_EQ(cluster_info->last_callback_time_ms_.load(), 2000); + EXPECT_EQ(cluster_info->last_callback_time_ms_.load(), 3000); EXPECT_EQ(cluster_info->min_time_between_triggering_, std::chrono::milliseconds(1000)); EXPECT_EQ(cluster_info->redirects_threshold_, 1); EXPECT_EQ(cluster_info->failure_threshold_, 1); @@ -211,23 +219,27 @@ TEST_F(ClusterRefreshManagerTest, BasicDegradedEvents) { Thread::ThreadPtr thread_1 = platform_.threadFactory().createThread([&]() { waitForTime(MonotonicTime(std::chrono::seconds(1))); EXPECT_TRUE(refresh_manager_->onHostDegraded(cluster_name_)); - waitForTime(MonotonicTime(std::chrono::seconds(2))); - refresh_manager_->onHostDegraded(cluster_name_); + // wait for 3 ensures that thread_1's first onRedirection is completed, + // as wait for 2 would only ensure onRedirection was started waitForTime(MonotonicTime(std::chrono::seconds(3))); + refresh_manager_->onHostDegraded(cluster_name_); + waitForTime(MonotonicTime(std::chrono::seconds(4))); }); Thread::ThreadPtr thread_2 = platform_.threadFactory().createThread([&]() { - waitForTime(MonotonicTime(std::chrono::seconds(2))); - refresh_manager_->onHostDegraded(cluster_name_); + // wait for 3 ensures that thread_1's first onRedirection is completed, + // as wait for 2 would only ensure onRedirection was started waitForTime(MonotonicTime(std::chrono::seconds(3))); + refresh_manager_->onHostDegraded(cluster_name_); + waitForTime(MonotonicTime(std::chrono::seconds(4))); }); - advanceTime(MonotonicTime(std::chrono::seconds(3)), 2); + advanceTime(MonotonicTime(std::chrono::seconds(4)), 2); thread_1->join(); thread_2->join(); EXPECT_GE(callback_count_, 2); EXPECT_EQ(cluster_info->host_degraded_count_, 0); - EXPECT_EQ(cluster_info->last_callback_time_ms_.load(), 2000); + EXPECT_EQ(cluster_info->last_callback_time_ms_.load(), 3000); EXPECT_EQ(cluster_info->min_time_between_triggering_, std::chrono::milliseconds(1000)); EXPECT_EQ(cluster_info->redirects_threshold_, 1); EXPECT_EQ(cluster_info->failure_threshold_, 1); From b7ef8b82780060efb877fe717092bac879ae33e8 Mon Sep 17 00:00:00 2001 From: alyssawilk Date: Tue, 11 Feb 2020 12:20:10 -0500 Subject: [PATCH 40/87] tcp: refactors for HTTP-over-tcp (#9928) Pulling both the connection pool logic and interaction with upstream into generic APIs which can be reused for sending TCP data out over the HTTP connection pool. Risk Level: High (intended no-op but it is a big refactor) Testing: n/a Docs Changes: n/a Release Notes: n/a Part of #1630 Signed-off-by: Alyssa Wilk --- source/common/tcp_proxy/BUILD | 10 ++- source/common/tcp_proxy/tcp_proxy.cc | 106 ++++++++++++------------ source/common/tcp_proxy/tcp_proxy.h | 8 +- source/common/tcp_proxy/upstream.cc | 50 +++++++++++ source/common/tcp_proxy/upstream.h | 66 +++++++++++++++ test/common/tcp_proxy/tcp_proxy_test.cc | 40 ++++++++- 6 files changed, 220 insertions(+), 60 deletions(-) create mode 100644 source/common/tcp_proxy/upstream.cc create mode 100644 source/common/tcp_proxy/upstream.h diff --git a/source/common/tcp_proxy/BUILD b/source/common/tcp_proxy/BUILD index 553bb95b3b..07cb8faaac 100644 --- a/source/common/tcp_proxy/BUILD +++ b/source/common/tcp_proxy/BUILD @@ -10,8 +10,14 @@ envoy_package() envoy_cc_library( name = "tcp_proxy", - srcs = ["tcp_proxy.cc"], - hdrs = ["tcp_proxy.h"], + srcs = [ + "tcp_proxy.cc", + "upstream.cc", + ], + hdrs = [ + "tcp_proxy.h", + "upstream.h", + ], deps = [ "//include/envoy/access_log:access_log_interface", "//include/envoy/buffer:buffer_interface", diff --git a/source/common/tcp_proxy/tcp_proxy.cc b/source/common/tcp_proxy/tcp_proxy.cc index 4c10ffc6e2..6f23bd83ab 100644 --- a/source/common/tcp_proxy/tcp_proxy.cc +++ b/source/common/tcp_proxy/tcp_proxy.cc @@ -219,7 +219,7 @@ Filter::~Filter() { } ASSERT(upstream_handle_ == nullptr); - ASSERT(upstream_conn_data_ == nullptr); + ASSERT(upstream_ == nullptr); } TcpProxyStats Config::SharedConfig::generateStats(Stats::Scope& scope) { @@ -256,15 +256,13 @@ void Filter::initialize(Network::ReadFilterCallbacks& callbacks, bool set_connec } void Filter::readDisableUpstream(bool disable) { - if (upstream_conn_data_ == nullptr || - upstream_conn_data_->connection().state() != Network::Connection::State::Open) { - // Because we flush write downstream, we can have a case where upstream has already disconnected - // and we are waiting to flush. If we had a watermark event during this time we should no - // longer touch the upstream connection. + bool success = false; + if (upstream_) { + success = upstream_->readDisable(disable); + } + if (!success) { return; } - - upstream_conn_data_->connection().readDisable(disable); if (disable) { read_callbacks_->upstreamHost() ->cluster() @@ -367,7 +365,7 @@ void Filter::UpstreamCallbacks::drain(Drainer& drainer) { } Network::FilterStatus Filter::initializeUpstreamConnection() { - ASSERT(upstream_conn_data_ == nullptr); + ASSERT(upstream_ == nullptr); route_ = pickRoute(); @@ -422,15 +420,23 @@ Network::FilterStatus Filter::initializeUpstreamConnection() { connecting_ = true; connect_attempts_++; - // Because we never return open connections to the pool, this should either return a handle while - // a connection completes or it invokes onPoolFailure inline. Either way, stop iteration. - upstream_handle_ = conn_pool->newConnection(*this); + // Given this function is reentrant, make sure we only reset the upstream_handle_ if given a valid + // connection handle. If newConnection fails inline it may result in attempting to select a new + // host, and a recursive call to initializeUpstreamConnection. In this case the first call to + // newConnection will return null and the inner call will persist. + Tcp::ConnectionPool::Cancellable* handle = conn_pool->newConnection(*this); + if (handle) { + ASSERT(upstream_handle_.get() == nullptr); + upstream_handle_.reset(new TcpConnectionHandle(handle)); + } + // Because we never return open connections to the pool, this either has a handle waiting on + // connection completion, or onPoolFailure has been invoked. Either way, stop iteration. return Network::FilterStatus::StopIteration; } void Filter::onPoolFailure(Tcp::ConnectionPool::PoolFailureReason reason, Upstream::HostDescriptionConstSharedPtr host) { - upstream_handle_ = nullptr; + upstream_handle_.reset(); read_callbacks_->upstreamHost(host); getStreamInfo().onUpstreamHostSelected(host); @@ -456,21 +462,17 @@ void Filter::onPoolFailure(Tcp::ConnectionPool::PoolFailureReason reason, void Filter::onPoolReady(Tcp::ConnectionPool::ConnectionDataPtr&& conn_data, Upstream::HostDescriptionConstSharedPtr host) { - upstream_handle_ = nullptr; - upstream_conn_data_ = std::move(conn_data); - read_callbacks_->upstreamHost(host); - - upstream_conn_data_->addUpstreamCallbacks(*upstream_callbacks_); - - Network::ClientConnection& connection = upstream_conn_data_->connection(); + upstream_handle_.reset(); + getStreamInfo().setUpstreamLocalAddress(conn_data->connection().localAddress()); + getStreamInfo().setUpstreamSslConnection( + conn_data->connection().streamInfo().downstreamSslConnection()); + read_callbacks_->connection().streamInfo().setUpstreamFilterState( + conn_data->connection().streamInfo().filterState()); - connection.enableHalfClose(true); + upstream_.reset(new TcpUpstream(std::move(conn_data), *upstream_callbacks_)); + read_callbacks_->upstreamHost(host); getStreamInfo().onUpstreamHostSelected(host); - getStreamInfo().setUpstreamLocalAddress(connection.localAddress()); - getStreamInfo().setUpstreamSslConnection(connection.streamInfo().downstreamSslConnection()); - read_callbacks_->connection().streamInfo().setUpstreamFilterState( - connection.streamInfo().filterState()); // Simulate the event that onPoolReady represents. upstream_callbacks_->onEvent(Network::ConnectionEvent::Connected); @@ -492,40 +494,37 @@ Network::FilterStatus Filter::onData(Buffer::Instance& data, bool end_stream) { ENVOY_CONN_LOG(trace, "downstream connection received {} bytes, end_stream={}", read_callbacks_->connection(), data.length(), end_stream); getStreamInfo().addBytesReceived(data.length()); - upstream_conn_data_->connection().write(data, end_stream); + if (upstream_) { + upstream_->encodeData(data, end_stream); + } + // The upstream should consume all of the data. + // Before there is an upstream the connection should be readDisabled. If the upstream is + // destroyed, there should be no further reads as well. ASSERT(0 == data.length()); resetIdleTimer(); // TODO(ggreenway) PERF: do we need to reset timer on both send and receive? return Network::FilterStatus::StopIteration; } void Filter::onDownstreamEvent(Network::ConnectionEvent event) { - if (upstream_conn_data_) { - if (event == Network::ConnectionEvent::RemoteClose) { - upstream_conn_data_->connection().close(Network::ConnectionCloseType::FlushWrite); - - // Events raised from the previous line may cause upstream_conn_data_ to be NULL if - // it was able to immediately flush all data. - - if (upstream_conn_data_ != nullptr) { - if (upstream_conn_data_->connection().state() != Network::Connection::State::Closed) { - config_->drainManager().add(config_->sharedConfig(), std::move(upstream_conn_data_), - std::move(upstream_callbacks_), std::move(idle_timer_), - read_callbacks_->upstreamHost()); - } else { - upstream_conn_data_.reset(); - } - } - } else if (event == Network::ConnectionEvent::LocalClose) { - upstream_conn_data_->connection().close(Network::ConnectionCloseType::NoFlush); - upstream_conn_data_.reset(); + if (upstream_) { + Tcp::ConnectionPool::ConnectionDataPtr conn_data(upstream_->onDownstreamEvent(event)); + if (conn_data != nullptr && + conn_data->connection().state() != Network::Connection::State::Closed) { + config_->drainManager().add(config_->sharedConfig(), std::move(conn_data), + std::move(upstream_callbacks_), std::move(idle_timer_), + read_callbacks_->upstreamHost()); + } + if (event != Network::ConnectionEvent::Connected) { + upstream_.reset(); disableIdleTimer(); } - } else if (upstream_handle_) { + } + if (upstream_handle_) { if (event == Network::ConnectionEvent::LocalClose || event == Network::ConnectionEvent::RemoteClose) { // Cancel the conn pool request and close any excess pending requests. - upstream_handle_->cancel(Tcp::ConnectionPool::CancelPolicy::CloseExcess); - upstream_handle_ = nullptr; + upstream_handle_->cancel(); + upstream_handle_.reset(); } } } @@ -547,7 +546,7 @@ void Filter::onUpstreamEvent(Network::ConnectionEvent event) { if (event == Network::ConnectionEvent::RemoteClose || event == Network::ConnectionEvent::LocalClose) { - upstream_conn_data_.reset(); + upstream_.reset(); disableIdleTimer(); if (connecting) { @@ -583,10 +582,11 @@ void Filter::onUpstreamEvent(Network::ConnectionEvent event) { [upstream_callbacks = upstream_callbacks_]() { upstream_callbacks->onIdleTimeout(); }); resetIdleTimer(); read_callbacks_->connection().addBytesSentCallback([this](uint64_t) { resetIdleTimer(); }); - upstream_conn_data_->connection().addBytesSentCallback( - [upstream_callbacks = upstream_callbacks_](uint64_t) { - upstream_callbacks->onBytesSent(); - }); + if (upstream_) { + upstream_->addBytesSentCallback([upstream_callbacks = upstream_callbacks_](uint64_t) { + upstream_callbacks->onBytesSent(); + }); + } } } } diff --git a/source/common/tcp_proxy/tcp_proxy.h b/source/common/tcp_proxy/tcp_proxy.h index 86fd0c0f4a..cef36312df 100644 --- a/source/common/tcp_proxy/tcp_proxy.h +++ b/source/common/tcp_proxy/tcp_proxy.h @@ -17,7 +17,6 @@ #include "envoy/stats/stats_macros.h" #include "envoy/stats/timespan.h" #include "envoy/stream_info/filter_state.h" -#include "envoy/tcp/conn_pool.h" #include "envoy/upstream/cluster_manager.h" #include "envoy/upstream/upstream.h" @@ -27,6 +26,7 @@ #include "common/network/hash_policy.h" #include "common/network/utility.h" #include "common/stream_info/stream_info_impl.h" +#include "common/tcp_proxy/upstream.h" #include "common/upstream/load_balancer_impl.h" namespace Envoy { @@ -346,12 +346,14 @@ class Filter : public Network::ReadFilter, const ConfigSharedPtr config_; Upstream::ClusterManager& cluster_manager_; Network::ReadFilterCallbacks* read_callbacks_{}; - Tcp::ConnectionPool::Cancellable* upstream_handle_{}; - Tcp::ConnectionPool::ConnectionDataPtr upstream_conn_data_; + DownstreamCallbacks downstream_callbacks_; Event::TimerPtr idle_timer_; + + std::shared_ptr upstream_handle_; std::shared_ptr upstream_callbacks_; // shared_ptr required for passing as a // read filter. + std::unique_ptr upstream_; StreamInfo::StreamInfoImpl stream_info_; RouteConstSharedPtr route_; Network::TransportSocketOptionsSharedPtr transport_socket_options_; diff --git a/source/common/tcp_proxy/upstream.cc b/source/common/tcp_proxy/upstream.cc new file mode 100644 index 0000000000..0996ad3069 --- /dev/null +++ b/source/common/tcp_proxy/upstream.cc @@ -0,0 +1,50 @@ +#include "common/tcp_proxy/upstream.h" + +namespace Envoy { +namespace TcpProxy { + +TcpUpstream::TcpUpstream(Tcp::ConnectionPool::ConnectionDataPtr&& data, + Tcp::ConnectionPool::UpstreamCallbacks& upstream_callbacks) + : upstream_conn_data_(std::move(data)) { + Network::ClientConnection& connection = upstream_conn_data_->connection(); + connection.enableHalfClose(true); + upstream_conn_data_->addUpstreamCallbacks(upstream_callbacks); +} + +bool TcpUpstream::readDisable(bool disable) { + if (upstream_conn_data_ == nullptr || + upstream_conn_data_->connection().state() != Network::Connection::State::Open) { + // Because we flush write downstream, we can have a case where upstream has already disconnected + // and we are waiting to flush. If we had a watermark event during this time we should no + // longer touch the upstream connection. + return false; + } + + upstream_conn_data_->connection().readDisable(disable); + return true; +} + +void TcpUpstream::encodeData(Buffer::Instance& data, bool end_stream) { + upstream_conn_data_->connection().write(data, end_stream); +} + +void TcpUpstream::addBytesSentCallback(Network::Connection::BytesSentCb cb) { + upstream_conn_data_->connection().addBytesSentCallback(cb); +} + +Tcp::ConnectionPool::ConnectionData* +TcpUpstream::onDownstreamEvent(Network::ConnectionEvent event) { + if (event == Network::ConnectionEvent::RemoteClose) { + // The close call may result in this object being deleted. Latch the + // connection locally so it can be returned for potential draining. + auto* conn_data = upstream_conn_data_.release(); + conn_data->connection().close(Network::ConnectionCloseType::FlushWrite); + return conn_data; + } else if (event == Network::ConnectionEvent::LocalClose) { + upstream_conn_data_->connection().close(Network::ConnectionCloseType::NoFlush); + } + return nullptr; +} + +} // namespace TcpProxy +} // namespace Envoy diff --git a/source/common/tcp_proxy/upstream.h b/source/common/tcp_proxy/upstream.h new file mode 100644 index 0000000000..6b2d103f3a --- /dev/null +++ b/source/common/tcp_proxy/upstream.h @@ -0,0 +1,66 @@ +#pragma once + +#include "envoy/network/connection.h" +#include "envoy/tcp/conn_pool.h" +#include "envoy/upstream/upstream.h" + +namespace Envoy { +namespace TcpProxy { + +// Interface for a generic ConnectionHandle, which can wrap a TcpConnectionHandle +// or an HttpConnectionHandle +class ConnectionHandle { +public: + virtual ~ConnectionHandle() {} + // Cancel the conn pool request and close any excess pending requests. + virtual void cancel() PURE; +}; + +// An implementation of ConnectionHandle which works with the Tcp::ConnectionPool. +class TcpConnectionHandle : public ConnectionHandle { +public: + TcpConnectionHandle(Tcp::ConnectionPool::Cancellable* handle) : upstream_handle_(handle) {} + + void cancel() override { + upstream_handle_->cancel(Tcp::ConnectionPool::CancelPolicy::CloseExcess); + } + +private: + Tcp::ConnectionPool::Cancellable* upstream_handle_{}; +}; + +// Interface for a generic Upstream, which can communicate with a TCP or HTTP +// upstream. +class GenericUpstream { +public: + virtual ~GenericUpstream() {} + // Calls readDisable on the upstream connection. Returns false if readDisable could not be + // performed (e.g. if the connection is closed) + virtual bool readDisable(bool disable) PURE; + // Encodes data upstream. + virtual void encodeData(Buffer::Instance& data, bool end_stream) PURE; + // Adds a callback to be called when the data is sent to the kernel. + virtual void addBytesSentCallback(Network::Connection::BytesSentCb cb) PURE; + // Called when a Network::ConnectionEvent is received on the downstream connection, to allow the + // upstream to do any cleanup. + virtual Tcp::ConnectionPool::ConnectionData* + onDownstreamEvent(Network::ConnectionEvent event) PURE; +}; + +class TcpUpstream : public GenericUpstream { +public: + TcpUpstream(Tcp::ConnectionPool::ConnectionDataPtr&& data, + Tcp::ConnectionPool::UpstreamCallbacks& callbacks); + + // GenericUpstream + bool readDisable(bool disable) override; + void encodeData(Buffer::Instance& data, bool end_stream) override; + void addBytesSentCallback(Network::Connection::BytesSentCb cb) override; + Tcp::ConnectionPool::ConnectionData* onDownstreamEvent(Network::ConnectionEvent event) override; + +private: + Tcp::ConnectionPool::ConnectionDataPtr upstream_conn_data_; +}; + +} // namespace TcpProxy +} // namespace Envoy diff --git a/test/common/tcp_proxy/tcp_proxy_test.cc b/test/common/tcp_proxy/tcp_proxy_test.cc index 4e1e2c742a..70675d23ad 100644 --- a/test/common/tcp_proxy/tcp_proxy_test.cc +++ b/test/common/tcp_proxy/tcp_proxy_test.cc @@ -895,7 +895,8 @@ class TcpProxyTest : public testing::Test { .WillOnce(Invoke( [=](Tcp::ConnectionPool::Callbacks& cb) -> Tcp::ConnectionPool::Cancellable* { conn_pool_callbacks_.push_back(&cb); - return conn_pool_handles_.at(i).get(); + + return onNewConnection(conn_pool_handles_.at(i).get()); })) .RetiresOnSaturation(); } @@ -904,7 +905,6 @@ class TcpProxyTest : public testing::Test { } { - testing::InSequence sequence; filter_ = std::make_unique(config_, factory_context_.cluster_manager_, timeSystem()); EXPECT_CALL(filter_callbacks_.connection_, enableHalfClose(true)); EXPECT_CALL(filter_callbacks_.connection_, readDisable(true)); @@ -940,6 +940,15 @@ class TcpProxyTest : public testing::Test { conn_pool_callbacks_.at(conn_index)->onPoolFailure(reason, upstream_hosts_.at(conn_index)); } + Tcp::ConnectionPool::Cancellable* onNewConnection(Tcp::ConnectionPool::Cancellable* connection) { + if (!new_connection_functions_.empty()) { + auto fn = new_connection_functions_.front(); + new_connection_functions_.pop_front(); + return fn(connection); + } + return connection; + } + Event::TestTimeSystem& timeSystem() { return factory_context_.timeSystem(); } NiceMock factory_context_; @@ -957,6 +966,8 @@ class TcpProxyTest : public testing::Test { StringViewSaver access_log_data_; Network::Address::InstanceConstSharedPtr upstream_local_address_; Network::Address::InstanceConstSharedPtr upstream_remote_address_; + std::list> + new_connection_functions_; }; TEST_F(TcpProxyTest, DEPRECATED_FEATURE_TEST(DefaultRoutes)) { @@ -1046,6 +1057,31 @@ TEST_F(TcpProxyTest, DEPRECATED_FEATURE_TEST(ConnectAttemptsUpstreamLocalFail)) .value()); } +// Make sure that the tcp proxy code handles reentrant calls to onPoolFailure. +TEST_F(TcpProxyTest, DEPRECATED_FEATURE_TEST(ConnectAttemptsUpstreamLocalFailReentrant)) { + envoy::extensions::filters::network::tcp_proxy::v3::TcpProxy config = defaultConfig(); + config.mutable_max_connect_attempts()->set_value(2); + + // Set up a call to onPoolFailure from inside the first newConnection call. + // This simulates a connection failure from under the stack of newStream. + new_connection_functions_.push_back( + [&](Tcp::ConnectionPool::Cancellable*) -> Tcp::ConnectionPool::Cancellable* { + raiseEventUpstreamConnectFailed( + 0, Tcp::ConnectionPool::PoolFailureReason::LocalConnectionFailure); + return nullptr; + }); + + setup(2, config); + + // Make sure the last connection pool to be created is the one which gets the + // cancellation call. + EXPECT_CALL(*conn_pool_handles_.at(0), cancel(Tcp::ConnectionPool::CancelPolicy::CloseExcess)) + .Times(0); + EXPECT_CALL(*conn_pool_handles_.at(1), cancel(Tcp::ConnectionPool::CancelPolicy::CloseExcess)) + .Times(1); + filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); +} + // Test that reconnect is attempted after a remote connect failure TEST_F(TcpProxyTest, DEPRECATED_FEATURE_TEST(ConnectAttemptsUpstreamRemoteFail)) { envoy::extensions::filters::network::tcp_proxy::v3::TcpProxy config = defaultConfig(); From c472e94fee6e30022f35f46c8e98ca3b5cd8dfe9 Mon Sep 17 00:00:00 2001 From: Jose Ulises Nino Rivera Date: Tue, 11 Feb 2020 09:27:24 -0800 Subject: [PATCH 41/87] dns cache: do not runRemoveCallbacks if runAddUpdateCallbacks has not fired (#10003) Signed-off-by: Jose Nino --- .../common/dynamic_forward_proxy/dns_cache_impl.cc | 7 ++++++- .../dynamic_forward_proxy/dns_cache_impl_test.cc | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) 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 e95d456302..0413c5d5ef 100644 --- a/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc +++ b/source/extensions/common/dynamic_forward_proxy/dns_cache_impl.cc @@ -120,7 +120,12 @@ void DnsCacheImpl::onReResolve(const std::string& host) { primary_host_it->second->host_info_->last_used_time_.load().count()); if (now_duration - primary_host_it->second->host_info_->last_used_time_.load() > host_ttl_) { ENVOY_LOG(debug, "host='{}' TTL expired, removing", host); - runRemoveCallbacks(host); + // If the host has no address then that means that the DnsCacheImpl has never + // runAddUpdateCallbacks for this host, and thus the callback targets are not aware of it. + // Therefore, runRemoveCallbacks should only be ran if the host's address != nullptr. + if (primary_host_it->second->host_info_->address_) { + runRemoveCallbacks(host); + } primary_hosts_.erase(primary_host_it); updateTlsHostsMap(); } else { 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 38b1f5ee71..16416e59c3 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 @@ -354,6 +354,7 @@ TEST_F(DnsCacheImplTest, ResolveFailure) { MockLoadDnsCacheEntryCallbacks callbacks; Network::DnsResolver::ResolveCb resolve_cb; + Event::MockTimer* resolve_timer = new Event::MockTimer(&dispatcher_); EXPECT_CALL(*resolver_, resolve("foo.com", _, _)) .WillOnce(DoAll(SaveArg<2>(&resolve_cb), Return(&resolver_->active_query_))); auto result = dns_cache_->loadDnsCacheEntry("foo.com", 80, callbacks); @@ -364,6 +365,7 @@ TEST_F(DnsCacheImplTest, ResolveFailure) { EXPECT_CALL(update_callbacks_, onDnsHostAddOrUpdate(_, _)).Times(0); EXPECT_CALL(callbacks, onLoadDnsCacheComplete()); + EXPECT_CALL(*resolve_timer, enableTimer(std::chrono::milliseconds(60000), _)); resolve_cb(TestUtility::makeDnsResponse({})); checkStats(1 /* attempt */, 0 /* success */, 1 /* failure */, 0 /* address changed */, 1 /* added */, 0 /* removed */, 1 /* num hosts */); @@ -371,6 +373,17 @@ TEST_F(DnsCacheImplTest, ResolveFailure) { result = dns_cache_->loadDnsCacheEntry("foo.com", 80, callbacks); EXPECT_EQ(DnsCache::LoadDnsCacheEntryStatus::InCache, result.status_); EXPECT_EQ(result.handle_, nullptr); + + // Re-resolve with ~5m passed. This is not realistic as we would have re-resolved many times + // during this period but it's good enough for the test. + simTime().sleep(std::chrono::milliseconds(300001)); + // Because resolution failed for the host, onDnsHostAddOrUpdate was not called. + // Therefore, onDnsHostRemove should not be called either. + EXPECT_CALL(update_callbacks_, onDnsHostRemove(_)).Times(0); + resolve_timer->invokeCallback(); + // DnsCacheImpl state is updated accordingly: the host is removed. + checkStats(1 /* attempt */, 0 /* success */, 1 /* failure */, 0 /* address changed */, + 1 /* added */, 1 /* removed */, 0 /* num hosts */); } // Cancel a cache load before the resolve completes. From 74df8b3f1f36d60563b2dc0e9200ed65d1e43d31 Mon Sep 17 00:00:00 2001 From: Michael Rebello Date: Tue, 11 Feb 2020 12:41:43 -0800 Subject: [PATCH 42/87] libevent: fix duplicate symbols on macOS (#10002) Risk Level: low, macOS only Testing: n/a Docs Changes: n/a Release Notes: n/a Fixes: lyft/envoy-mobile#677 Signed-off-by: Michael Rebello --- bazel/foreign_cc/BUILD | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bazel/foreign_cc/BUILD b/bazel/foreign_cc/BUILD index afec2a3246..c5a4f84aaf 100644 --- a/bazel/foreign_cc/BUILD +++ b/bazel/foreign_cc/BUILD @@ -129,6 +129,14 @@ envoy_cmake_external( }, lib_source = "@com_github_libevent_libevent//:all", static_libraries = select({ + # macOS organization of libevent is different from Windows/Linux. + # Including libevent_core is a requirement on those platforms, but + # results in duplicate symbols when built on macOS. + # See https://github.com/lyft/envoy-mobile/issues/677 for details. + "//bazel:apple": [ + "libevent.a", + "libevent_pthreads.a", + ], "//bazel:windows_x86_64": [ "event.lib", "event_core.lib", From b09184f8e9e17839f555f78ad8dbbcc57e3709db Mon Sep 17 00:00:00 2001 From: Stephan Zuercher Date: Tue, 11 Feb 2020 19:48:37 -0800 Subject: [PATCH 43/87] stat sinks/tracers: use new style names (#9970) Modifies the well-known-names of the built-in stat sinks and tracers to use the same name as the extension build system. Risk Level: low, previous name is still accepted Testing: existing tests + deprecated tests for old names Docs Changes: updated names Release Notes: updated Deprecated: old names are logged as deprecated Signed-off-by: Stephan Zuercher --- .../config/metrics/v2/metrics_service.proto | 2 +- api/envoy/config/metrics/v2/stats.proto | 10 +++---- .../config/metrics/v3/metrics_service.proto | 2 +- api/envoy/config/metrics/v3/stats.proto | 10 +++---- api/envoy/config/trace/v2/trace.proto | 6 ++--- api/envoy/config/trace/v3/trace.proto | 6 ++--- configs/envoy_double_proxy_v2.template.yaml | 4 +-- configs/envoy_front_proxy_v2.template.yaml | 2 +- .../envoy_service_to_service_v2.template.yaml | 4 +-- configs/using_deprecated_config.v2.yaml | 2 +- docs/root/intro/deprecated.rst | 10 +++++-- docs/root/intro/version_history.rst | 6 ++++- .../front-envoy-jaeger.yaml | 2 +- .../service1-envoy-jaeger.yaml | 2 +- .../service2-envoy-jaeger.yaml | 2 +- .../jaeger-tracing/front-envoy-jaeger.yaml | 2 +- .../jaeger-tracing/service1-envoy-jaeger.yaml | 2 +- .../jaeger-tracing/service2-envoy-jaeger.yaml | 2 +- .../zipkin-tracing/front-envoy-zipkin.yaml | 2 +- .../zipkin-tracing/service1-envoy-zipkin.yaml | 2 +- .../zipkin-tracing/service2-envoy-zipkin.yaml | 2 +- .../config/metrics/v2/metrics_service.proto | 2 +- .../envoy/config/metrics/v2/stats.proto | 10 +++---- .../config/metrics/v3/metrics_service.proto | 2 +- .../envoy/config/metrics/v3/stats.proto | 10 +++---- .../envoy/config/trace/v2/trace.proto | 6 ++--- .../envoy/config/trace/v3/trace.proto | 6 ++--- .../stat_sinks/dog_statsd/config.cc | 2 +- .../stat_sinks/metrics_service/config.cc | 3 ++- source/extensions/stat_sinks/statsd/config.cc | 2 +- .../extensions/stat_sinks/well_known_names.h | 6 ++--- .../extensions/tracers/dynamic_ot/config.cc | 3 ++- source/extensions/tracers/lightstep/config.cc | 2 +- source/extensions/tracers/well_known_names.h | 6 ++--- source/extensions/tracers/zipkin/config.cc | 2 +- test/config/integration/server.yaml | 4 +-- .../stats_sinks/dog_statsd/config_test.cc | 8 ++++++ .../stats_sinks/metrics_service/BUILD | 11 ++++++++ .../metrics_service/config_test.cc | 27 +++++++++++++++++++ .../metrics_service_integration_test.cc | 2 +- .../stats_sinks/statsd/config_test.cc | 8 ++++++ .../tracers/dynamic_ot/config_test.cc | 10 ++++++- .../tracers/lightstep/config_test.cc | 10 ++++++- test/extensions/tracers/zipkin/config_test.cc | 14 +++++++--- .../test_data/server/zipkin_tracing.yaml | 2 +- 45 files changed, 165 insertions(+), 75 deletions(-) create mode 100644 test/extensions/stats_sinks/metrics_service/config_test.cc diff --git a/api/envoy/config/metrics/v2/metrics_service.proto b/api/envoy/config/metrics/v2/metrics_service.proto index 0cf1921367..d2f60a6a67 100644 --- a/api/envoy/config/metrics/v2/metrics_service.proto +++ b/api/envoy/config/metrics/v2/metrics_service.proto @@ -12,7 +12,7 @@ option java_multiple_files = true; // [#protodoc-title: Metrics service] -// Metrics Service is configured as a built-in *envoy.metrics_service* :ref:`StatsSink +// Metrics Service is configured as a built-in *envoy.stat_sinks.metrics_service* :ref:`StatsSink // `. This opaque configuration will be used to create // Metrics Service. // [#extension: envoy.stat_sinks.metrics_service] diff --git a/api/envoy/config/metrics/v2/stats.proto b/api/envoy/config/metrics/v2/stats.proto index 321e14072b..d3f797543a 100644 --- a/api/envoy/config/metrics/v2/stats.proto +++ b/api/envoy/config/metrics/v2/stats.proto @@ -23,9 +23,9 @@ message StatsSink { // The name of the stats sink to instantiate. The name must match a supported // stats sink. The built-in stats sinks are: // - // * :ref:`envoy.statsd ` - // * :ref:`envoy.dog_statsd ` - // * :ref:`envoy.metrics_service ` + // * :ref:`envoy.stat_sinks.statsd ` + // * :ref:`envoy.stat_sinks.dog_statsd ` + // * :ref:`envoy.stat_sinks.metrics_service ` // * :ref:`envoy.stat_sinks.hystrix ` // // Sinks optionally support tagged/multiple dimensional metrics. @@ -243,7 +243,7 @@ message TagSpecifier { } } -// Stats configuration proto schema for built-in *envoy.statsd* sink. This sink does not support +// Stats configuration proto schema for built-in *envoy.stat_sinks.statsd* sink. This sink does not support // tagged metrics. // [#extension: envoy.stat_sinks.statsd] message StatsdSink { @@ -290,7 +290,7 @@ message StatsdSink { string prefix = 3; } -// Stats configuration proto schema for built-in *envoy.dog_statsd* sink. +// Stats configuration proto schema for built-in *envoy.stat_sinks.dog_statsd* sink. // The sink emits stats with `DogStatsD `_ // compatible tags. Tags are configurable via :ref:`StatsConfig // `. diff --git a/api/envoy/config/metrics/v3/metrics_service.proto b/api/envoy/config/metrics/v3/metrics_service.proto index 5a26875c0f..002aa7482e 100644 --- a/api/envoy/config/metrics/v3/metrics_service.proto +++ b/api/envoy/config/metrics/v3/metrics_service.proto @@ -14,7 +14,7 @@ option java_multiple_files = true; // [#protodoc-title: Metrics service] -// Metrics Service is configured as a built-in *envoy.metrics_service* :ref:`StatsSink +// Metrics Service is configured as a built-in *envoy.stat_sinks.metrics_service* :ref:`StatsSink // `. This opaque configuration will be used to create // Metrics Service. // [#extension: envoy.stat_sinks.metrics_service] diff --git a/api/envoy/config/metrics/v3/stats.proto b/api/envoy/config/metrics/v3/stats.proto index 01f6bfa1c1..2f6f5bade4 100644 --- a/api/envoy/config/metrics/v3/stats.proto +++ b/api/envoy/config/metrics/v3/stats.proto @@ -31,9 +31,9 @@ message StatsSink { // The name of the stats sink to instantiate. The name must match a supported // stats sink. The built-in stats sinks are: // - // * :ref:`envoy.statsd ` - // * :ref:`envoy.dog_statsd ` - // * :ref:`envoy.metrics_service ` + // * :ref:`envoy.stat_sinks.statsd ` + // * :ref:`envoy.stat_sinks.dog_statsd ` + // * :ref:`envoy.stat_sinks.metrics_service ` // * :ref:`envoy.stat_sinks.hystrix ` // // Sinks optionally support tagged/multiple dimensional metrics. @@ -258,7 +258,7 @@ message TagSpecifier { } } -// Stats configuration proto schema for built-in *envoy.statsd* sink. This sink does not support +// Stats configuration proto schema for built-in *envoy.stat_sinks.statsd* sink. This sink does not support // tagged metrics. // [#extension: envoy.stat_sinks.statsd] message StatsdSink { @@ -307,7 +307,7 @@ message StatsdSink { string prefix = 3; } -// Stats configuration proto schema for built-in *envoy.dog_statsd* sink. +// Stats configuration proto schema for built-in *envoy.stat_sinks.dog_statsd* sink. // The sink emits stats with `DogStatsD `_ // compatible tags. Tags are configurable via :ref:`StatsConfig // `. diff --git a/api/envoy/config/trace/v2/trace.proto b/api/envoy/config/trace/v2/trace.proto index 4d87a03429..ae578972ef 100644 --- a/api/envoy/config/trace/v2/trace.proto +++ b/api/envoy/config/trace/v2/trace.proto @@ -30,9 +30,9 @@ message Tracing { // The name of the HTTP trace driver to instantiate. The name must match a // supported HTTP trace driver. Built-in trace drivers: // - // - *envoy.lightstep* - // - *envoy.zipkin* - // - *envoy.dynamic.ot* + // - *envoy.tracers.lightstep* + // - *envoy.tracers.zipkin* + // - *envoy.tracers.dynamic_ot* // - *envoy.tracers.datadog* // - *envoy.tracers.opencensus* // - *envoy.tracers.xray* diff --git a/api/envoy/config/trace/v3/trace.proto b/api/envoy/config/trace/v3/trace.proto index ec5ac0a511..d1adb5cade 100644 --- a/api/envoy/config/trace/v3/trace.proto +++ b/api/envoy/config/trace/v3/trace.proto @@ -40,9 +40,9 @@ message Tracing { // The name of the HTTP trace driver to instantiate. The name must match a // supported HTTP trace driver. Built-in trace drivers: // - // - *envoy.lightstep* - // - *envoy.zipkin* - // - *envoy.dynamic.ot* + // - *envoy.tracers.lightstep* + // - *envoy.tracers.zipkin* + // - *envoy.tracers.dynamic_ot* // - *envoy.tracers.datadog* // - *envoy.tracers.opencensus* // - *envoy.tracers.xray* diff --git a/configs/envoy_double_proxy_v2.template.yaml b/configs/envoy_double_proxy_v2.template.yaml index 9b880b53c8..3082c1dbff 100644 --- a/configs/envoy_double_proxy_v2.template.yaml +++ b/configs/envoy_double_proxy_v2.template.yaml @@ -173,13 +173,13 @@ static_resources: exact: "collector-grpc.lightstep.com" flags_path: "/etc/envoy/flags" stats_sinks: -- name: envoy.statsd +- name: envoy.stat_sinks.statsd typed_config: "@type": type.googleapis.com/envoy.config.metrics.v2.StatsdSink tcp_cluster_name: statsd tracing: http: - name: envoy.lightstep + name: envoy.tracers.lightstep typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.LightstepConfig access_token_file: "/etc/envoy/lightstep_access_token" diff --git a/configs/envoy_front_proxy_v2.template.yaml b/configs/envoy_front_proxy_v2.template.yaml index c50b9adb78..60894c6cc0 100644 --- a/configs/envoy_front_proxy_v2.template.yaml +++ b/configs/envoy_front_proxy_v2.template.yaml @@ -157,7 +157,7 @@ cluster_manager: flags_path: /etc/envoy/flags tracing: http: - name: envoy.lightstep + name: envoy.tracers.lightstep typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.LightstepConfig collector_cluster: lightstep_saas diff --git a/configs/envoy_service_to_service_v2.template.yaml b/configs/envoy_service_to_service_v2.template.yaml index 3e1c893c42..175e367d79 100644 --- a/configs/envoy_service_to_service_v2.template.yaml +++ b/configs/envoy_service_to_service_v2.template.yaml @@ -546,14 +546,14 @@ dynamic_resources: cluster_manager: {} flags_path: "/etc/envoy/flags" stats_sinks: - - name: envoy.statsd + - name: envoy.stat_sinks.statsd typed_config: "@type": type.googleapis.com/envoy.config.metrics.v2.StatsdSink tcp_cluster_name: statsd watchdog: {} tracing: http: - name: envoy.lightstep + name: envoy.tracers.lightstep typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.LightstepConfig access_token_file: "/etc/envoy/lightstep_access_token" diff --git a/configs/using_deprecated_config.v2.yaml b/configs/using_deprecated_config.v2.yaml index fb454ad29b..4e9f66738e 100644 --- a/configs/using_deprecated_config.v2.yaml +++ b/configs/using_deprecated_config.v2.yaml @@ -58,7 +58,7 @@ static_resources: sni: www.google.com tracing: http: - name: envoy.zipkin + name: envoy.tracers.zipkin config: collector_cluster: service_google collector_endpoint: /api/v1/spans diff --git a/docs/root/intro/deprecated.rst b/docs/root/intro/deprecated.rst index 87849c6da7..d9ea30dc4f 100644 --- a/docs/root/intro/deprecated.rst +++ b/docs/root/intro/deprecated.rst @@ -15,8 +15,8 @@ Deprecated items below are listed in chronological order. * The previous behavior for upstream connection pool circuit breaking described `here `_ has been deprecated in favor of the new behavior described :ref:`here `. -* Access Logger names have been deprecated in favor of the extension name from the envoy build - system. +* Access Logger, Stats Sink, and Tracer names have been deprecated in favor of the extension name + from the envoy build system. .. csv-table:: :header: Canonical Names, Deprecated Names @@ -25,6 +25,12 @@ Deprecated items below are listed in chronological order. envoy.access_loggers.file, envoy.file_access_log envoy.access_loggers.http_grpc, envoy.http_grpc_access_log envoy.access_loggers.tcp_grpc, envoy.tcp_grpc_access_log + envoy.stat_sinks.dog_statsd, envoy.dog_statsd + envoy.stat_sinks.metrics_service, envoy.metrics_service + envoy.stat_sinks.statsd, envoy.statsd + envoy.tracers.dynamic_ot, envoy.dynamic.ot + envoy.tracers.lightstep, envoy.lightstep + envoy.tracers.zipkin, envoy.zipkin 1.13.0 (January 20, 2020) ========================= diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index 39b6a2b4f7..d8b23a2d5c 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -14,7 +14,11 @@ Version history * router: added the ability to match a route based on whether a downstream TLS connection certificate has been :ref:`validated `. * sds: added :ref:`GenericSecret ` to support secret of generic type. +* stat sinks: stat sink extensions use the "envoy.stat_sinks" name space. A mapping of extension + names is available in the :ref:`deprecated ` documentation. * thrift_proxy: add router filter stats to docs. +* tracers: tracer extensions use the "envoy.tracers" name space. A mapping of extension names is + available in the :ref:`deprecated ` documentation. * tracing: added gRPC service configuration to the OpenCensus Stackdriver tracer. * upstream: combined HTTP/1 and HTTP/2 connection pool code. This means that circuit breaker limits for both requests and connections apply to both pool types. Also, HTTP/2 now has @@ -24,7 +28,7 @@ Version history "envoy.reloadable_features.new_http2_connection_pool_behavior" and then re-configure your clusters or restart Envoy. The behavior will not switch until the connection pools are recreated. The new circuit breaker behavior is described :ref:`here `. -* upstream: changed load distribution algorithm when all priorities enter :ref:`panic mode`. +* upstream: changed load distribution algorithm when all priorities enter :ref:`panic mode`. 1.13.0 (January 20, 2020) ========================= diff --git a/examples/jaeger-native-tracing/front-envoy-jaeger.yaml b/examples/jaeger-native-tracing/front-envoy-jaeger.yaml index cd0cad8424..070e41540c 100644 --- a/examples/jaeger-native-tracing/front-envoy-jaeger.yaml +++ b/examples/jaeger-native-tracing/front-envoy-jaeger.yaml @@ -47,7 +47,7 @@ static_resources: port_value: 80 tracing: http: - name: envoy.dynamic.ot + name: envoy.tracers.dynamic_ot typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.DynamicOtConfig library: /usr/local/lib/libjaegertracing_plugin.so diff --git a/examples/jaeger-native-tracing/service1-envoy-jaeger.yaml b/examples/jaeger-native-tracing/service1-envoy-jaeger.yaml index 9db41dbfda..54c192f614 100644 --- a/examples/jaeger-native-tracing/service1-envoy-jaeger.yaml +++ b/examples/jaeger-native-tracing/service1-envoy-jaeger.yaml @@ -86,7 +86,7 @@ static_resources: port_value: 80 tracing: http: - name: envoy.dynamic.ot + name: envoy.tracers.dynamic_ot typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.DynamicOtConfig library: /usr/local/lib/libjaegertracing_plugin.so diff --git a/examples/jaeger-native-tracing/service2-envoy-jaeger.yaml b/examples/jaeger-native-tracing/service2-envoy-jaeger.yaml index 14a3a77ca4..3c7fcf5f7a 100644 --- a/examples/jaeger-native-tracing/service2-envoy-jaeger.yaml +++ b/examples/jaeger-native-tracing/service2-envoy-jaeger.yaml @@ -44,7 +44,7 @@ static_resources: port_value: 8080 tracing: http: - name: envoy.dynamic.ot + name: envoy.tracers.dynamic_ot typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.DynamicOtConfig library: /usr/local/lib/libjaegertracing_plugin.so diff --git a/examples/jaeger-tracing/front-envoy-jaeger.yaml b/examples/jaeger-tracing/front-envoy-jaeger.yaml index d66e746539..8c5f87a754 100644 --- a/examples/jaeger-tracing/front-envoy-jaeger.yaml +++ b/examples/jaeger-tracing/front-envoy-jaeger.yaml @@ -61,7 +61,7 @@ static_resources: port_value: 9411 tracing: http: - name: envoy.zipkin + name: envoy.tracers.zipkin typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig collector_cluster: jaeger diff --git a/examples/jaeger-tracing/service1-envoy-jaeger.yaml b/examples/jaeger-tracing/service1-envoy-jaeger.yaml index c2b6855ded..b39e525fcf 100644 --- a/examples/jaeger-tracing/service1-envoy-jaeger.yaml +++ b/examples/jaeger-tracing/service1-envoy-jaeger.yaml @@ -101,7 +101,7 @@ static_resources: port_value: 9411 tracing: http: - name: envoy.zipkin + name: envoy.tracers.zipkin typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig collector_cluster: jaeger diff --git a/examples/jaeger-tracing/service2-envoy-jaeger.yaml b/examples/jaeger-tracing/service2-envoy-jaeger.yaml index 7abfae8ca5..2fbd42f967 100644 --- a/examples/jaeger-tracing/service2-envoy-jaeger.yaml +++ b/examples/jaeger-tracing/service2-envoy-jaeger.yaml @@ -58,7 +58,7 @@ static_resources: port_value: 9411 tracing: http: - name: envoy.zipkin + name: envoy.tracers.zipkin typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig collector_cluster: jaeger diff --git a/examples/zipkin-tracing/front-envoy-zipkin.yaml b/examples/zipkin-tracing/front-envoy-zipkin.yaml index 9dc8be0f1b..24ee3f89b4 100644 --- a/examples/zipkin-tracing/front-envoy-zipkin.yaml +++ b/examples/zipkin-tracing/front-envoy-zipkin.yaml @@ -67,7 +67,7 @@ static_resources: port_value: 9411 tracing: http: - name: envoy.zipkin + name: envoy.tracers.zipkin typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig collector_cluster: zipkin diff --git a/examples/zipkin-tracing/service1-envoy-zipkin.yaml b/examples/zipkin-tracing/service1-envoy-zipkin.yaml index c82bdc4a25..99c8de634e 100644 --- a/examples/zipkin-tracing/service1-envoy-zipkin.yaml +++ b/examples/zipkin-tracing/service1-envoy-zipkin.yaml @@ -101,7 +101,7 @@ static_resources: port_value: 9411 tracing: http: - name: envoy.zipkin + name: envoy.tracers.zipkin typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig collector_cluster: zipkin diff --git a/examples/zipkin-tracing/service2-envoy-zipkin.yaml b/examples/zipkin-tracing/service2-envoy-zipkin.yaml index e39e906f2d..6d1d988f30 100644 --- a/examples/zipkin-tracing/service2-envoy-zipkin.yaml +++ b/examples/zipkin-tracing/service2-envoy-zipkin.yaml @@ -58,7 +58,7 @@ static_resources: port_value: 9411 tracing: http: - name: envoy.zipkin + name: envoy.tracers.zipkin typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig collector_cluster: zipkin diff --git a/generated_api_shadow/envoy/config/metrics/v2/metrics_service.proto b/generated_api_shadow/envoy/config/metrics/v2/metrics_service.proto index 0cf1921367..d2f60a6a67 100644 --- a/generated_api_shadow/envoy/config/metrics/v2/metrics_service.proto +++ b/generated_api_shadow/envoy/config/metrics/v2/metrics_service.proto @@ -12,7 +12,7 @@ option java_multiple_files = true; // [#protodoc-title: Metrics service] -// Metrics Service is configured as a built-in *envoy.metrics_service* :ref:`StatsSink +// Metrics Service is configured as a built-in *envoy.stat_sinks.metrics_service* :ref:`StatsSink // `. This opaque configuration will be used to create // Metrics Service. // [#extension: envoy.stat_sinks.metrics_service] diff --git a/generated_api_shadow/envoy/config/metrics/v2/stats.proto b/generated_api_shadow/envoy/config/metrics/v2/stats.proto index 321e14072b..d3f797543a 100644 --- a/generated_api_shadow/envoy/config/metrics/v2/stats.proto +++ b/generated_api_shadow/envoy/config/metrics/v2/stats.proto @@ -23,9 +23,9 @@ message StatsSink { // The name of the stats sink to instantiate. The name must match a supported // stats sink. The built-in stats sinks are: // - // * :ref:`envoy.statsd ` - // * :ref:`envoy.dog_statsd ` - // * :ref:`envoy.metrics_service ` + // * :ref:`envoy.stat_sinks.statsd ` + // * :ref:`envoy.stat_sinks.dog_statsd ` + // * :ref:`envoy.stat_sinks.metrics_service ` // * :ref:`envoy.stat_sinks.hystrix ` // // Sinks optionally support tagged/multiple dimensional metrics. @@ -243,7 +243,7 @@ message TagSpecifier { } } -// Stats configuration proto schema for built-in *envoy.statsd* sink. This sink does not support +// Stats configuration proto schema for built-in *envoy.stat_sinks.statsd* sink. This sink does not support // tagged metrics. // [#extension: envoy.stat_sinks.statsd] message StatsdSink { @@ -290,7 +290,7 @@ message StatsdSink { string prefix = 3; } -// Stats configuration proto schema for built-in *envoy.dog_statsd* sink. +// Stats configuration proto schema for built-in *envoy.stat_sinks.dog_statsd* sink. // The sink emits stats with `DogStatsD `_ // compatible tags. Tags are configurable via :ref:`StatsConfig // `. diff --git a/generated_api_shadow/envoy/config/metrics/v3/metrics_service.proto b/generated_api_shadow/envoy/config/metrics/v3/metrics_service.proto index 5a26875c0f..002aa7482e 100644 --- a/generated_api_shadow/envoy/config/metrics/v3/metrics_service.proto +++ b/generated_api_shadow/envoy/config/metrics/v3/metrics_service.proto @@ -14,7 +14,7 @@ option java_multiple_files = true; // [#protodoc-title: Metrics service] -// Metrics Service is configured as a built-in *envoy.metrics_service* :ref:`StatsSink +// Metrics Service is configured as a built-in *envoy.stat_sinks.metrics_service* :ref:`StatsSink // `. This opaque configuration will be used to create // Metrics Service. // [#extension: envoy.stat_sinks.metrics_service] diff --git a/generated_api_shadow/envoy/config/metrics/v3/stats.proto b/generated_api_shadow/envoy/config/metrics/v3/stats.proto index 878eb54081..fa734b6cdd 100644 --- a/generated_api_shadow/envoy/config/metrics/v3/stats.proto +++ b/generated_api_shadow/envoy/config/metrics/v3/stats.proto @@ -27,9 +27,9 @@ message StatsSink { // The name of the stats sink to instantiate. The name must match a supported // stats sink. The built-in stats sinks are: // - // * :ref:`envoy.statsd ` - // * :ref:`envoy.dog_statsd ` - // * :ref:`envoy.metrics_service ` + // * :ref:`envoy.stat_sinks.statsd ` + // * :ref:`envoy.stat_sinks.dog_statsd ` + // * :ref:`envoy.stat_sinks.metrics_service ` // * :ref:`envoy.stat_sinks.hystrix ` // // Sinks optionally support tagged/multiple dimensional metrics. @@ -256,7 +256,7 @@ message TagSpecifier { } } -// Stats configuration proto schema for built-in *envoy.statsd* sink. This sink does not support +// Stats configuration proto schema for built-in *envoy.stat_sinks.statsd* sink. This sink does not support // tagged metrics. // [#extension: envoy.stat_sinks.statsd] message StatsdSink { @@ -305,7 +305,7 @@ message StatsdSink { string prefix = 3; } -// Stats configuration proto schema for built-in *envoy.dog_statsd* sink. +// Stats configuration proto schema for built-in *envoy.stat_sinks.dog_statsd* sink. // The sink emits stats with `DogStatsD `_ // compatible tags. Tags are configurable via :ref:`StatsConfig // `. diff --git a/generated_api_shadow/envoy/config/trace/v2/trace.proto b/generated_api_shadow/envoy/config/trace/v2/trace.proto index 4d87a03429..ae578972ef 100644 --- a/generated_api_shadow/envoy/config/trace/v2/trace.proto +++ b/generated_api_shadow/envoy/config/trace/v2/trace.proto @@ -30,9 +30,9 @@ message Tracing { // The name of the HTTP trace driver to instantiate. The name must match a // supported HTTP trace driver. Built-in trace drivers: // - // - *envoy.lightstep* - // - *envoy.zipkin* - // - *envoy.dynamic.ot* + // - *envoy.tracers.lightstep* + // - *envoy.tracers.zipkin* + // - *envoy.tracers.dynamic_ot* // - *envoy.tracers.datadog* // - *envoy.tracers.opencensus* // - *envoy.tracers.xray* diff --git a/generated_api_shadow/envoy/config/trace/v3/trace.proto b/generated_api_shadow/envoy/config/trace/v3/trace.proto index 03eb068ab3..00913bd54e 100644 --- a/generated_api_shadow/envoy/config/trace/v3/trace.proto +++ b/generated_api_shadow/envoy/config/trace/v3/trace.proto @@ -36,9 +36,9 @@ message Tracing { // The name of the HTTP trace driver to instantiate. The name must match a // supported HTTP trace driver. Built-in trace drivers: // - // - *envoy.lightstep* - // - *envoy.zipkin* - // - *envoy.dynamic.ot* + // - *envoy.tracers.lightstep* + // - *envoy.tracers.zipkin* + // - *envoy.tracers.dynamic_ot* // - *envoy.tracers.datadog* // - *envoy.tracers.opencensus* // - *envoy.tracers.xray* diff --git a/source/extensions/stat_sinks/dog_statsd/config.cc b/source/extensions/stat_sinks/dog_statsd/config.cc index 6c7930916f..fecd087b2f 100644 --- a/source/extensions/stat_sinks/dog_statsd/config.cc +++ b/source/extensions/stat_sinks/dog_statsd/config.cc @@ -37,7 +37,7 @@ std::string DogStatsdSinkFactory::name() const { return StatsSinkNames::get().Do /** * Static registration for the this sink factory. @see RegisterFactory. */ -REGISTER_FACTORY(DogStatsdSinkFactory, Server::Configuration::StatsSinkFactory); +REGISTER_FACTORY(DogStatsdSinkFactory, Server::Configuration::StatsSinkFactory){"envoy.dog_statsd"}; } // namespace DogStatsd } // namespace StatSinks diff --git a/source/extensions/stat_sinks/metrics_service/config.cc b/source/extensions/stat_sinks/metrics_service/config.cc index 58b46fc217..4f8402e201 100644 --- a/source/extensions/stat_sinks/metrics_service/config.cc +++ b/source/extensions/stat_sinks/metrics_service/config.cc @@ -46,7 +46,8 @@ std::string MetricsServiceSinkFactory::name() const { return StatsSinkNames::get /** * Static registration for the this sink factory. @see RegisterFactory. */ -REGISTER_FACTORY(MetricsServiceSinkFactory, Server::Configuration::StatsSinkFactory); +REGISTER_FACTORY(MetricsServiceSinkFactory, + Server::Configuration::StatsSinkFactory){"envoy.metrics_service"}; } // namespace MetricsService } // namespace StatSinks diff --git a/source/extensions/stat_sinks/statsd/config.cc b/source/extensions/stat_sinks/statsd/config.cc index c60b6c90b8..fa0c1e758e 100644 --- a/source/extensions/stat_sinks/statsd/config.cc +++ b/source/extensions/stat_sinks/statsd/config.cc @@ -50,7 +50,7 @@ std::string StatsdSinkFactory::name() const { return StatsSinkNames::get().Stats /** * Static registration for the statsd sink factory. @see RegisterFactory. */ -REGISTER_FACTORY(StatsdSinkFactory, Server::Configuration::StatsSinkFactory); +REGISTER_FACTORY(StatsdSinkFactory, Server::Configuration::StatsSinkFactory){"envoy.statsd"}; } // namespace Statsd } // namespace StatSinks diff --git a/source/extensions/stat_sinks/well_known_names.h b/source/extensions/stat_sinks/well_known_names.h index a564d168d6..afb16a0a4b 100644 --- a/source/extensions/stat_sinks/well_known_names.h +++ b/source/extensions/stat_sinks/well_known_names.h @@ -15,11 +15,11 @@ namespace StatSinks { class StatsSinkNameValues { public: // Statsd sink - const std::string Statsd = "envoy.statsd"; + const std::string Statsd = "envoy.stat_sinks.statsd"; // DogStatsD compatible statsd sink - const std::string DogStatsd = "envoy.dog_statsd"; + const std::string DogStatsd = "envoy.stat_sinks.dog_statsd"; // MetricsService sink - const std::string MetricsService = "envoy.metrics_service"; + const std::string MetricsService = "envoy.stat_sinks.metrics_service"; // Hystrix sink const std::string Hystrix = "envoy.stat_sinks.hystrix"; }; diff --git a/source/extensions/tracers/dynamic_ot/config.cc b/source/extensions/tracers/dynamic_ot/config.cc index 9bd2fc733b..7e2a6068ce 100644 --- a/source/extensions/tracers/dynamic_ot/config.cc +++ b/source/extensions/tracers/dynamic_ot/config.cc @@ -30,7 +30,8 @@ Tracing::HttpTracerPtr DynamicOpenTracingTracerFactory::createHttpTracerTyped( /** * Static registration for the dynamic opentracing tracer. @see RegisterFactory. */ -REGISTER_FACTORY(DynamicOpenTracingTracerFactory, Server::Configuration::TracerFactory); +REGISTER_FACTORY(DynamicOpenTracingTracerFactory, + Server::Configuration::TracerFactory){"envoy.dynamic.ot"}; } // namespace DynamicOt } // namespace Tracers diff --git a/source/extensions/tracers/lightstep/config.cc b/source/extensions/tracers/lightstep/config.cc index 3ed59c465f..3198f8a342 100644 --- a/source/extensions/tracers/lightstep/config.cc +++ b/source/extensions/tracers/lightstep/config.cc @@ -38,7 +38,7 @@ Tracing::HttpTracerPtr LightstepTracerFactory::createHttpTracerTyped( /** * Static registration for the lightstep tracer. @see RegisterFactory. */ -REGISTER_FACTORY(LightstepTracerFactory, Server::Configuration::TracerFactory); +REGISTER_FACTORY(LightstepTracerFactory, Server::Configuration::TracerFactory){"envoy.lightstep"}; } // namespace Lightstep } // namespace Tracers diff --git a/source/extensions/tracers/well_known_names.h b/source/extensions/tracers/well_known_names.h index 8b48fd0aeb..8a83cdf21d 100644 --- a/source/extensions/tracers/well_known_names.h +++ b/source/extensions/tracers/well_known_names.h @@ -14,11 +14,11 @@ namespace Tracers { class TracerNameValues { public: // Lightstep tracer - const std::string Lightstep = "envoy.lightstep"; + const std::string Lightstep = "envoy.tracers.lightstep"; // Zipkin tracer - const std::string Zipkin = "envoy.zipkin"; + const std::string Zipkin = "envoy.tracers.zipkin"; // Dynamic tracer - const std::string DynamicOt = "envoy.dynamic.ot"; + const std::string DynamicOt = "envoy.tracers.dynamic_ot"; // Datadog tracer const std::string Datadog = "envoy.tracers.datadog"; // OpenCensus tracer diff --git a/source/extensions/tracers/zipkin/config.cc b/source/extensions/tracers/zipkin/config.cc index c2b2eff758..35b14e777b 100644 --- a/source/extensions/tracers/zipkin/config.cc +++ b/source/extensions/tracers/zipkin/config.cc @@ -29,7 +29,7 @@ Tracing::HttpTracerPtr ZipkinTracerFactory::createHttpTracerTyped( /** * Static registration for the Zipkin tracer. @see RegisterFactory. */ -REGISTER_FACTORY(ZipkinTracerFactory, Server::Configuration::TracerFactory); +REGISTER_FACTORY(ZipkinTracerFactory, Server::Configuration::TracerFactory){"envoy.zipkin"}; } // namespace Zipkin } // namespace Tracers diff --git a/test/config/integration/server.yaml b/test/config/integration/server.yaml index 78551fe8a1..2f6dc29180 100644 --- a/test/config/integration/server.yaml +++ b/test/config/integration/server.yaml @@ -155,14 +155,14 @@ dynamic_resources: {} cluster_manager: {} flags_path: "/invalid_flags" stats_sinks: -- name: envoy.statsd +- name: envoy.stat_sinks.statsd typed_config: "@type": type.googleapis.com/envoy.config.metrics.v2.StatsdSink address: socket_address: address: {{ ip_loopback_address }} port_value: 8125 -- name: envoy.statsd +- name: envoy.stat_sinks.statsd typed_config: "@type": type.googleapis.com/envoy.config.metrics.v2.StatsdSink tcp_cluster_name: statsd diff --git a/test/extensions/stats_sinks/dog_statsd/config_test.cc b/test/extensions/stats_sinks/dog_statsd/config_test.cc index cfd1b49e7d..8108dd6618 100644 --- a/test/extensions/stats_sinks/dog_statsd/config_test.cc +++ b/test/extensions/stats_sinks/dog_statsd/config_test.cc @@ -94,6 +94,14 @@ TEST_P(DogStatsdConfigLoopbackTest, WithCustomPrefix) { EXPECT_EQ(udp_sink->getPrefix(), customPrefix); } +// Test that the deprecated extension name still functions. +TEST(DogStatsdConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.dog_statsd"; + + ASSERT_NE(nullptr, Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + } // namespace } // namespace DogStatsd } // namespace StatSinks diff --git a/test/extensions/stats_sinks/metrics_service/BUILD b/test/extensions/stats_sinks/metrics_service/BUILD index 7a069b15ab..e8ff78cc02 100644 --- a/test/extensions/stats_sinks/metrics_service/BUILD +++ b/test/extensions/stats_sinks/metrics_service/BUILD @@ -11,6 +11,17 @@ load( envoy_package() +envoy_extension_cc_test( + name = "config_test", + srcs = ["config_test.cc"], + extension_name = "envoy.stat_sinks.metrics_service", + deps = [ + "//include/envoy/registry", + "//source/extensions/stat_sinks/metrics_service:config", + "//test/test_common:utility_lib", + ], +) + envoy_extension_cc_test( name = "metrics_service_test", srcs = ["grpc_metrics_service_impl_test.cc"], diff --git a/test/extensions/stats_sinks/metrics_service/config_test.cc b/test/extensions/stats_sinks/metrics_service/config_test.cc new file mode 100644 index 0000000000..0813088261 --- /dev/null +++ b/test/extensions/stats_sinks/metrics_service/config_test.cc @@ -0,0 +1,27 @@ +#include "envoy/registry/registry.h" + +#include "extensions/stat_sinks/metrics_service/config.h" + +#include "test/test_common/utility.h" + +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace StatSinks { +namespace MetricsService { +namespace { + +// Test that the deprecated extension name still functions. +TEST(MetricsServiceConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.metrics_service"; + + ASSERT_NE(nullptr, Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + +} // namespace +} // namespace MetricsService +} // namespace StatSinks +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/stats_sinks/metrics_service/metrics_service_integration_test.cc b/test/extensions/stats_sinks/metrics_service/metrics_service_integration_test.cc index 02e755b79b..b7598cdc12 100644 --- a/test/extensions/stats_sinks/metrics_service/metrics_service_integration_test.cc +++ b/test/extensions/stats_sinks/metrics_service/metrics_service_integration_test.cc @@ -40,7 +40,7 @@ class MetricsServiceIntegrationTest : public Grpc::GrpcClientIntegrationParamTes metrics_service_cluster->mutable_http2_protocol_options(); // metrics_service gRPC service definition. auto* metrics_sink = bootstrap.add_stats_sinks(); - metrics_sink->set_name("envoy.metrics_service"); + metrics_sink->set_name("envoy.stat_sinks.metrics_service"); envoy::config::metrics::v3::MetricsServiceConfig config; setGrpcService(*config.mutable_grpc_service(), "metrics_service", fake_upstreams_.back()->localAddress()); diff --git a/test/extensions/stats_sinks/statsd/config_test.cc b/test/extensions/stats_sinks/statsd/config_test.cc index 133e40d38c..44c89aa5e5 100644 --- a/test/extensions/stats_sinks/statsd/config_test.cc +++ b/test/extensions/stats_sinks/statsd/config_test.cc @@ -45,6 +45,14 @@ TEST(StatsConfigTest, ValidTcpStatsd) { EXPECT_NE(dynamic_cast(sink.get()), nullptr); } +// Test that the deprecated extension name still functions. +TEST(StatsConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.statsd"; + + ASSERT_NE(nullptr, Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + class StatsConfigParameterizedTest : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P(IpVersions, StatsConfigParameterizedTest, diff --git a/test/extensions/tracers/dynamic_ot/config_test.cc b/test/extensions/tracers/dynamic_ot/config_test.cc index 5842a65601..2d6dc6990a 100644 --- a/test/extensions/tracers/dynamic_ot/config_test.cc +++ b/test/extensions/tracers/dynamic_ot/config_test.cc @@ -30,7 +30,7 @@ TEST(DynamicOtTracerConfigTest, DynamicOpentracingHttpTracer) { const std::string yaml_string = fmt::sprintf( R"EOF( http: - name: envoy.dynamic.ot + name: envoy.tracers.dynamic_ot config: library: %s config: @@ -47,6 +47,14 @@ TEST(DynamicOtTracerConfigTest, DynamicOpentracingHttpTracer) { EXPECT_NE(nullptr, tracer); } +// Test that the deprecated extension name still functions. +TEST(DynamicOtTracerConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.dynamic.ot"; + + ASSERT_NE(nullptr, Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + } // namespace } // namespace DynamicOt } // namespace Tracers diff --git a/test/extensions/tracers/lightstep/config_test.cc b/test/extensions/tracers/lightstep/config_test.cc index 7dabc9e063..05e4a9204d 100644 --- a/test/extensions/tracers/lightstep/config_test.cc +++ b/test/extensions/tracers/lightstep/config_test.cc @@ -27,7 +27,7 @@ TEST(LightstepTracerConfigTest, LightstepHttpTracer) { const std::string yaml_string = R"EOF( http: - name: envoy.lightstep + name: envoy.tracers.lightstep config: collector_cluster: fake_cluster access_token_file: fake_file @@ -42,6 +42,14 @@ TEST(LightstepTracerConfigTest, LightstepHttpTracer) { EXPECT_NE(nullptr, lightstep_tracer); } +// Test that the deprecated extension name still functions. +TEST(LightstepTracerConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.lightstep"; + + ASSERT_NE(nullptr, Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + } // namespace } // namespace Lightstep } // namespace Tracers diff --git a/test/extensions/tracers/zipkin/config_test.cc b/test/extensions/tracers/zipkin/config_test.cc index 9c883c03b8..e0eb22b29c 100644 --- a/test/extensions/tracers/zipkin/config_test.cc +++ b/test/extensions/tracers/zipkin/config_test.cc @@ -25,7 +25,7 @@ TEST(ZipkinTracerConfigTest, ZipkinHttpTracer) { const std::string yaml_string = R"EOF( http: - name: envoy.zipkin + name: envoy.tracers.zipkin config: collector_cluster: fake_cluster collector_endpoint: /api/v1/spans @@ -50,7 +50,7 @@ TEST(ZipkinTracerConfigTest, ZipkinHttpTracerWithTypedConfig) { const std::string yaml_string = R"EOF( http: - name: envoy.zipkin + name: envoy.tracers.zipkin typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig collector_cluster: fake_cluster @@ -71,7 +71,15 @@ TEST(ZipkinTracerConfigTest, ZipkinHttpTracerWithTypedConfig) { TEST(ZipkinTracerConfigTest, DoubleRegistrationTest) { EXPECT_THROW_WITH_MESSAGE( (Registry::RegisterFactory()), - EnvoyException, "Double registration for name: 'envoy.zipkin'"); + EnvoyException, "Double registration for name: 'envoy.tracers.zipkin'"); +} + +// Test that the deprecated extension name still functions. +TEST(ZipkinTracerConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.zipkin"; + + ASSERT_NE(nullptr, Registry::FactoryRegistry::getFactory( + deprecated_name)); } } // namespace diff --git a/test/server/test_data/server/zipkin_tracing.yaml b/test/server/test_data/server/zipkin_tracing.yaml index 726c80c7e2..5880466b97 100644 --- a/test/server/test_data/server/zipkin_tracing.yaml +++ b/test/server/test_data/server/zipkin_tracing.yaml @@ -4,7 +4,7 @@ static_resources: connect_timeout: 1s tracing: http: - name: envoy.zipkin + name: envoy.tracers.zipkin typed_config: "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig collector_cluster: zipkin From 855ceebd4c2c6d711d7b400188a06804ac46a604 Mon Sep 17 00:00:00 2001 From: toddmgreer Date: Tue, 11 Feb 2020 19:57:38 -0800 Subject: [PATCH 44/87] filter: Add SimpleHttpCache (#9974) Signed-off-by: Todd Greer --- source/extensions/extensions_build_config.bzl | 6 + source/extensions/filters/http/cache/BUILD | 1 + .../filters/http/cache/http_cache.h | 8 +- .../http/cache/simple_http_cache/BUILD | 37 +++ .../http/cache/simple_http_cache/config.proto | 9 + .../simple_http_cache/simple_http_cache.cc | 157 +++++++++++++ .../simple_http_cache/simple_http_cache.h | 42 ++++ test/extensions/filters/http/cache/BUILD | 13 +- .../http/cache/simple_http_cache/BUILD | 20 ++ .../simple_http_cache_test.cc | 220 ++++++++++++++++++ 10 files changed, 505 insertions(+), 8 deletions(-) create mode 100644 source/extensions/filters/http/cache/simple_http_cache/BUILD create mode 100644 source/extensions/filters/http/cache/simple_http_cache/config.proto create mode 100644 source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc create mode 100644 source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.h create mode 100644 test/extensions/filters/http/cache/simple_http_cache/BUILD create mode 100644 test/extensions/filters/http/cache/simple_http_cache/simple_http_cache_test.cc diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index 1dddce3adb..509b78ad8c 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -160,6 +160,12 @@ EXTENSIONS = { # "envoy.retry_priorities.previous_priorities": "//source/extensions/retry/priority/previous_priorities:config", + + # + # CacheFilter plugins + # + + "envoy.filters.http.cache.simple_http_cache": "//source/extensions/filters/http/cache/simple_http_cache:simple_http_cache_lib", } WINDOWS_EXTENSIONS = { diff --git a/source/extensions/filters/http/cache/BUILD b/source/extensions/filters/http/cache/BUILD index 3bfa5e87a5..aa8b976639 100644 --- a/source/extensions/filters/http/cache/BUILD +++ b/source/extensions/filters/http/cache/BUILD @@ -32,6 +32,7 @@ envoy_cc_library( "//source/common/common:assert_lib", "//source/common/http:headers_lib", "//source/common/protobuf:utility_lib", + "@envoy_api//envoy/extensions/filters/http/cache/v3alpha:pkg_cc_proto", ], ) diff --git a/source/extensions/filters/http/cache/http_cache.h b/source/extensions/filters/http/cache/http_cache.h index 46a02884eb..9bea3a43ea 100644 --- a/source/extensions/filters/http/cache/http_cache.h +++ b/source/extensions/filters/http/cache/http_cache.h @@ -7,6 +7,7 @@ #include "envoy/buffer/buffer.h" #include "envoy/common/time.h" #include "envoy/config/typed_config.h" +#include "envoy/extensions/filters/http/cache/v3alpha/cache.pb.h" #include "envoy/http/header_map.h" #include "common/common/assert.h" @@ -302,14 +303,13 @@ class HttpCache { // Factory interface for cache implementations to implement and register. class HttpCacheFactory : public Config::TypedFactory { public: - // name should be in reverse DNS format, though this is not enforced. - explicit HttpCacheFactory(std::string name) : name_(std::move(name)) {} - std::string name() const override { return name_; } + // From UntypedFactory std::string category() const override { return "http_cache_factory"; } // Returns an HttpCache that will remain valid indefinitely (at least as long // as the calling CacheFilter). - virtual HttpCache& getCache() PURE; + virtual HttpCache& + getCache(const envoy::extensions::filters::http::cache::v3alpha::CacheConfig& config) PURE; virtual ~HttpCacheFactory() = default; private: diff --git a/source/extensions/filters/http/cache/simple_http_cache/BUILD b/source/extensions/filters/http/cache/simple_http_cache/BUILD new file mode 100644 index 0000000000..6f569711d5 --- /dev/null +++ b/source/extensions/filters/http/cache/simple_http_cache/BUILD @@ -0,0 +1,37 @@ +licenses(["notice"]) # Apache 2 + +## WIP: Simple in-memory cache storage plugin. Not ready for deployment. + +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_extension", + "envoy_package", + "envoy_proto_library", +) + +envoy_package() + +envoy_cc_extension( + name = "simple_http_cache_lib", + srcs = ["simple_http_cache.cc"], + hdrs = ["simple_http_cache.h"], + security_posture = "robust_to_untrusted_downstream_and_upstream", + status = "wip", + deps = [ + ":config_cc_proto", + "//include/envoy/registry", + "//include/envoy/runtime:runtime_interface", + "//source/common/buffer:buffer_lib", + "//source/common/common:macros", + "//source/common/http:header_map_lib", + "//source/common/http:headers_lib", + "//source/common/protobuf", + "//source/extensions/filters/http/cache:http_cache_lib", + "//source/extensions/filters/http/common:pass_through_filter_lib", + ], +) + +envoy_proto_library( + name = "config", + srcs = ["config.proto"], +) diff --git a/source/extensions/filters/http/cache/simple_http_cache/config.proto b/source/extensions/filters/http/cache/simple_http_cache/config.proto new file mode 100644 index 0000000000..313b07a7f9 --- /dev/null +++ b/source/extensions/filters/http/cache/simple_http_cache/config.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package envoy.source.extensions.filters.http.cache; + +// [#protodoc-title: SimpleHttpCache CacheFilter storage plugin] +// [#extension: envoy.extensions.http.cache] + +message SimpleHttpCacheConfig { +} diff --git a/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc b/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc new file mode 100644 index 0000000000..8c0a1e205b --- /dev/null +++ b/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc @@ -0,0 +1,157 @@ +#include "extensions/filters/http/cache/simple_http_cache/simple_http_cache.h" + +#include "envoy/registry/registry.h" + +#include "common/buffer/buffer_impl.h" +#include "common/http/header_map_impl.h" + +#include "source/extensions/filters/http/cache/simple_http_cache/config.pb.h" + +namespace Envoy { +namespace Extensions { +namespace HttpFilters { +namespace Cache { +namespace { + +class SimpleLookupContext : public LookupContext { +public: + SimpleLookupContext(SimpleHttpCache& cache, LookupRequest&& request) + : cache_(cache), request_(std::move(request)) {} + + void getHeaders(LookupHeadersCallback&& cb) override { + auto entry = cache_.lookup(request_); + body_ = std::move(entry.body_); + cb(entry.response_headers_ + ? request_.makeLookupResult(std::move(entry.response_headers_), body_.size()) + : LookupResult{}); + } + + void getBody(const AdjustedByteRange& range, LookupBodyCallback&& cb) override { + ASSERT(range.end() <= body_.length(), "Attempt to read past end of body."); + cb(std::make_unique(&body_[range.begin()], range.length())); + } + + void getTrailers(LookupTrailersCallback&&) override { + // TODO(toddmgreer): Support trailers. + NOT_IMPLEMENTED_GCOVR_EXCL_LINE; + } + + const LookupRequest& request() const { return request_; } + +private: + SimpleHttpCache& cache_; + const LookupRequest request_; + std::string body_; +}; + +class SimpleInsertContext : public InsertContext { +public: + SimpleInsertContext(LookupContext& lookup_context, SimpleHttpCache& cache) + : key_(dynamic_cast(lookup_context).request().key()), cache_(cache) {} + + void insertHeaders(const Http::HeaderMap& response_headers, bool end_stream) override { + ASSERT(!committed_); + response_headers_ = std::make_unique(response_headers); + if (end_stream) { + commit(); + } + } + + void insertBody(const Buffer::Instance& chunk, InsertCallback ready_for_next_chunk, + bool end_stream) override { + ASSERT(!committed_); + ASSERT(ready_for_next_chunk || end_stream); + + body_.add(chunk); + if (end_stream) { + commit(); + } else { + ready_for_next_chunk(true); + } + } + + void insertTrailers(const Http::HeaderMap&) override { + NOT_IMPLEMENTED_GCOVR_EXCL_LINE; // TODO(toddmgreer): support trailers + } + +private: + void commit() { + committed_ = true; + cache_.insert(key_, std::move(response_headers_), body_.toString()); + } + + Key key_; + Http::HeaderMapImplPtr response_headers_; + SimpleHttpCache& cache_; + Buffer::OwnedImpl body_; + bool committed_ = false; +}; +} // namespace + +LookupContextPtr SimpleHttpCache::makeLookupContext(LookupRequest&& request) { + return std::make_unique(*this, std::move(request)); +} + +void SimpleHttpCache::updateHeaders(LookupContextPtr&& lookup_context, + Http::HeaderMapPtr&& response_headers) { + ASSERT(lookup_context); + ASSERT(response_headers); + // TODO(toddmgreer): Support updating headers. + NOT_IMPLEMENTED_GCOVR_EXCL_LINE; +} + +SimpleHttpCache::Entry SimpleHttpCache::lookup(const LookupRequest& request) { + absl::ReaderMutexLock lock(&mutex_); + auto iter = map_.find(request.key()); + if (iter == map_.end()) { + return Entry{}; + } + ASSERT(iter->second.response_headers_); + return SimpleHttpCache::Entry{ + std::make_unique(*iter->second.response_headers_), iter->second.body_}; +} + +void SimpleHttpCache::insert(const Key& key, Http::HeaderMapPtr&& response_headers, + std::string&& body) { + absl::WriterMutexLock lock(&mutex_); + map_[key] = SimpleHttpCache::Entry{std::move(response_headers), std::move(body)}; +} + +InsertContextPtr SimpleHttpCache::makeInsertContext(LookupContextPtr&& lookup_context) { + ASSERT(lookup_context != nullptr); + return std::make_unique(*lookup_context, *this); +} + +constexpr absl::string_view Name = "envoy.extensions.http.cache.simple"; + +CacheInfo SimpleHttpCache::cacheInfo() const { + CacheInfo cache_info; + cache_info.name_ = Name; + return cache_info; +} + +class SimpleHttpCacheFactory : public HttpCacheFactory { +public: + // From UntypedFactory + std::string name() const override { return std::string(Name); } + // From TypedFactory + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return std::make_unique< + envoy::source::extensions::filters::http::cache::SimpleHttpCacheConfig>(); + } + // From HttpCacheFactory + HttpCache& + getCache(const envoy::extensions::filters::http::cache::v3alpha::CacheConfig&) override { + return cache_; + } + +private: + SimpleHttpCache cache_; +}; + +static Registry::RegisterFactory register_; + +} // namespace Cache +} // namespace HttpFilters +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.h b/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.h new file mode 100644 index 0000000000..4f53c28ec3 --- /dev/null +++ b/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.h @@ -0,0 +1,42 @@ +#pragma once + +#include "common/protobuf/utility.h" + +#include "extensions/filters/http/cache/http_cache.h" + +#include "absl/base/thread_annotations.h" +#include "absl/container/flat_hash_map.h" +#include "absl/synchronization/mutex.h" + +namespace Envoy { +namespace Extensions { +namespace HttpFilters { +namespace Cache { + +// Example cache backend that never evicts. Not suitable for production use. +class SimpleHttpCache : public HttpCache { +private: + struct Entry { + Http::HeaderMapPtr response_headers_; + std::string body_; + }; + +public: + // HttpCache + LookupContextPtr makeLookupContext(LookupRequest&& request) override; + InsertContextPtr makeInsertContext(LookupContextPtr&& lookup_context) override; + void updateHeaders(LookupContextPtr&& lookup_context, + Http::HeaderMapPtr&& response_headers) override; + CacheInfo cacheInfo() const override; + + Entry lookup(const LookupRequest& request); + void insert(const Key& key, Http::HeaderMapPtr&& response_headers, std::string&& body); + + absl::Mutex mutex_; + absl::flat_hash_map map_ GUARDED_BY(mutex_); +}; + +} // namespace Cache +} // namespace HttpFilters +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/filters/http/cache/BUILD b/test/extensions/filters/http/cache/BUILD index cc18f260aa..d2ac0fb3f7 100644 --- a/test/extensions/filters/http/cache/BUILD +++ b/test/extensions/filters/http/cache/BUILD @@ -1,13 +1,17 @@ licenses(["notice"]) # Apache 2 -load("//bazel:envoy_build_system.bzl", "envoy_cc_test", "envoy_package") +load("//bazel:envoy_build_system.bzl", "envoy_package") +load( + "//test/extensions:extensions_build_system.bzl", + "envoy_extension_cc_test", +) envoy_package() -# TODO(toddmgreer) Change to envoy_extension_cc_test when adding the full filter. -envoy_cc_test( +envoy_extension_cc_test( name = "http_cache_utils_test", srcs = ["http_cache_utils_test.cc"], + extension_name = "envoy.filters.http.cache", deps = [ "//include/envoy/http:header_map_interface", "//source/common/http:header_map_lib", @@ -16,9 +20,10 @@ envoy_cc_test( ], ) -envoy_cc_test( +envoy_extension_cc_test( name = "http_cache_test", srcs = ["http_cache_test.cc"], + extension_name = "envoy.filters.http.cache", deps = [ "//source/extensions/filters/http/cache:http_cache_lib", "//test/mocks/http:http_mocks", diff --git a/test/extensions/filters/http/cache/simple_http_cache/BUILD b/test/extensions/filters/http/cache/simple_http_cache/BUILD new file mode 100644 index 0000000000..89198975f3 --- /dev/null +++ b/test/extensions/filters/http/cache/simple_http_cache/BUILD @@ -0,0 +1,20 @@ +licenses(["notice"]) # Apache 2 + +load("//bazel:envoy_build_system.bzl", "envoy_package") +load( + "//test/extensions:extensions_build_system.bzl", + "envoy_extension_cc_test", +) + +envoy_package() + +envoy_extension_cc_test( + name = "simple_http_cache_test", + srcs = ["simple_http_cache_test.cc"], + extension_name = "envoy.filters.http.cache.simple_http_cache", + deps = [ + "//source/extensions/filters/http/cache/simple_http_cache:simple_http_cache_lib", + "//test/test_common:simulated_time_system_lib", + "//test/test_common:utility_lib", + ], +) diff --git a/test/extensions/filters/http/cache/simple_http_cache/simple_http_cache_test.cc b/test/extensions/filters/http/cache/simple_http_cache/simple_http_cache_test.cc new file mode 100644 index 0000000000..323da092cf --- /dev/null +++ b/test/extensions/filters/http/cache/simple_http_cache/simple_http_cache_test.cc @@ -0,0 +1,220 @@ +#include "envoy/http/header_map.h" +#include "envoy/registry/registry.h" + +#include "common/buffer/buffer_impl.h" + +#include "extensions/filters/http/cache/simple_http_cache/simple_http_cache.h" + +#include "test/test_common/simulated_time_system.h" +#include "test/test_common/utility.h" + +#include "gtest/gtest.h" + +namespace Envoy { +namespace Extensions { +namespace HttpFilters { +namespace Cache { +namespace { + +const std::string EpochDate = "Thu, 01 Jan 1970 00:00:00 GMT"; + +class SimpleHttpCacheTest : public testing::Test { +protected: + SimpleHttpCacheTest() { + request_headers_.setMethod("GET"); + request_headers_.setHost("example.com"); + request_headers_.setForwardedProto("https"); + request_headers_.setCacheControl("max-age=3600"); + } + + // Performs a cache lookup. + LookupContextPtr lookup(absl::string_view request_path) { + LookupRequest request = makeLookupRequest(request_path); + LookupContextPtr context = cache_.makeLookupContext(std::move(request)); + context->getHeaders([this](LookupResult&& result) { lookup_result_ = std::move(result); }); + return context; + } + + // Inserts a value into the cache. + void insert(LookupContextPtr lookup, const Http::TestHeaderMapImpl& response_headers, + const absl::string_view response_body) { + InsertContextPtr inserter = cache_.makeInsertContext(move(lookup)); + inserter->insertHeaders(response_headers, false); + inserter->insertBody(Buffer::OwnedImpl(response_body), nullptr, true); + } + + void insert(absl::string_view request_path, const Http::TestHeaderMapImpl& response_headers, + const absl::string_view response_body) { + insert(lookup(request_path), response_headers, response_body); + } + + std::string getBody(LookupContext& context, uint64_t start, uint64_t end) { + AdjustedByteRange range(start, end); + std::string body; + context.getBody(range, [&body](Buffer::InstancePtr&& data) { + EXPECT_NE(data, nullptr); + if (data) { + body = data->toString(); + } + }); + return body; + } + + LookupRequest makeLookupRequest(absl::string_view request_path) { + request_headers_.setPath(request_path); + return LookupRequest(request_headers_, current_time_); + } + + AssertionResult expectLookupSuccessWithBody(LookupContext* lookup_context, + absl::string_view body) { + if (lookup_result_.cache_entry_status_ != CacheEntryStatus::Ok) { + return AssertionFailure() << "Expected: lookup_result_.cache_entry_status == " + "CacheEntryStatus::Ok\n Actual: " + << lookup_result_.cache_entry_status_; + } + if (!lookup_result_.headers_) { + return AssertionFailure() << "Expected nonnull lookup_result_.headers"; + } + if (!lookup_context) { + return AssertionFailure() << "Expected nonnull lookup_context"; + } + const std::string actual_body = getBody(*lookup_context, 0, body.size()); + if (body != actual_body) { + return AssertionFailure() << "Expected body == " << body << "\n Actual: " << actual_body; + } + return AssertionSuccess(); + } + + SimpleHttpCache cache_; + LookupResult lookup_result_; + Http::TestHeaderMapImpl request_headers_; + Event::SimulatedTimeSystem time_source_; + SystemTime current_time_ = time_source_.systemTime(); + DateFormatter formatter_{"%a, %d %b %Y %H:%M:%S GMT"}; +}; + +// Simple flow of putting in an item, getting it, deleting it. +TEST_F(SimpleHttpCacheTest, PutGet) { + const std::string RequestPath1("Name"); + LookupContextPtr name_lookup_context = lookup(RequestPath1); + EXPECT_EQ(CacheEntryStatus::Unusable, lookup_result_.cache_entry_status_); + + Http::TestHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, + {"cache-control", "public,max-age=3600"}}; + + const std::string Body1("Value"); + insert(move(name_lookup_context), response_headers, Body1); + name_lookup_context = lookup(RequestPath1); + EXPECT_TRUE(expectLookupSuccessWithBody(name_lookup_context.get(), Body1)); + + const std::string& RequestPath2("Another Name"); + LookupContextPtr another_name_lookup_context = lookup(RequestPath2); + EXPECT_EQ(CacheEntryStatus::Unusable, lookup_result_.cache_entry_status_); + + const std::string NewBody1("NewValue"); + insert(move(name_lookup_context), response_headers, NewBody1); + EXPECT_TRUE(expectLookupSuccessWithBody(lookup(RequestPath1).get(), NewBody1)); +} + +TEST_F(SimpleHttpCacheTest, PrivateResponse) { + Http::TestHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, + {"age", "2"}, + {"cache-control", "private,max-age=3600"}}; + const std::string request_path("Name"); + + LookupContextPtr name_lookup_context = lookup(request_path); + EXPECT_EQ(CacheEntryStatus::Unusable, lookup_result_.cache_entry_status_); + + const std::string Body("Value"); + // We must make sure at cache insertion time, private responses must not be + // inserted. However, if the insertion did happen, it would be served at the + // time of lookup. + insert(move(name_lookup_context), response_headers, Body); + EXPECT_TRUE(expectLookupSuccessWithBody(lookup(request_path).get(), Body)); +} + +TEST_F(SimpleHttpCacheTest, Miss) { + LookupContextPtr name_lookup_context = lookup("Name"); + EXPECT_EQ(CacheEntryStatus::Unusable, lookup_result_.cache_entry_status_); +} + +TEST_F(SimpleHttpCacheTest, Fresh) { + const Http::TestHeaderMapImpl response_headers = {{"date", formatter_.fromTime(current_time_)}, + {"cache-control", "public, max-age=3600"}}; + // TODO(toddmgreer): Test with various date headers. + insert("/", response_headers, ""); + time_source_.sleep(std::chrono::seconds(3600)); + lookup("/"); + EXPECT_EQ(CacheEntryStatus::Ok, lookup_result_.cache_entry_status_); +} + +TEST_F(SimpleHttpCacheTest, Stale) { + const Http::TestHeaderMapImpl response_headers = {{"date", formatter_.fromTime(current_time_)}, + {"cache-control", "public, max-age=3600"}}; + // TODO(toddmgreer): Test with various date headers. + insert("/", response_headers, ""); + time_source_.sleep(std::chrono::seconds(3601)); + lookup("/"); + EXPECT_EQ(CacheEntryStatus::Ok, lookup_result_.cache_entry_status_); +} + +TEST_F(SimpleHttpCacheTest, RequestSmallMinFresh) { + request_headers_.setReferenceKey(Http::Headers::get().CacheControl, "min-fresh=1000"); + const std::string request_path("Name"); + LookupContextPtr name_lookup_context = lookup(request_path); + EXPECT_EQ(CacheEntryStatus::Unusable, lookup_result_.cache_entry_status_); + + Http::TestHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, + {"age", "6000"}, + {"cache-control", "public, max-age=9000"}}; + const std::string Body("Value"); + insert(move(name_lookup_context), response_headers, Body); + EXPECT_TRUE(expectLookupSuccessWithBody(lookup(request_path).get(), Body)); +} + +TEST_F(SimpleHttpCacheTest, ResponseStaleWithRequestLargeMaxStale) { + request_headers_.setReferenceKey(Http::Headers::get().CacheControl, "max-stale=9000"); + + const std::string request_path("Name"); + LookupContextPtr name_lookup_context = lookup(request_path); + EXPECT_EQ(CacheEntryStatus::Unusable, lookup_result_.cache_entry_status_); + + Http::TestHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, + {"age", "7200"}, + {"cache-control", "public, max-age=3600"}}; + + const std::string Body("Value"); + insert(move(name_lookup_context), response_headers, Body); + EXPECT_TRUE(expectLookupSuccessWithBody(lookup(request_path).get(), Body)); +} + +TEST_F(SimpleHttpCacheTest, StreamingPut) { + Http::TestHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, + {"age", "2"}, + {"cache-control", "public, max-age=3600"}}; + InsertContextPtr inserter = cache_.makeInsertContext(lookup("request_path")); + inserter->insertHeaders(response_headers, false); + inserter->insertBody( + Buffer::OwnedImpl("Hello, "), [](bool ready) { EXPECT_TRUE(ready); }, false); + inserter->insertBody(Buffer::OwnedImpl("World!"), nullptr, true); + LookupContextPtr name_lookup_context = lookup("request_path"); + EXPECT_EQ(CacheEntryStatus::Ok, lookup_result_.cache_entry_status_); + EXPECT_NE(nullptr, lookup_result_.headers_); + ASSERT_EQ(13, lookup_result_.content_length_); + EXPECT_EQ("Hello, World!", getBody(*name_lookup_context, 0, 13)); +} + +TEST(Registration, GetFactory) { + HttpCacheFactory* factory = Registry::FactoryRegistry::getFactoryByType( + "envoy.source.extensions.filters.http.cache.SimpleHttpCacheConfig"); + ASSERT_NE(factory, nullptr); + envoy::extensions::filters::http::cache::v3alpha::CacheConfig config; + config.mutable_typed_config()->PackFrom(*factory->createEmptyConfigProto()); + EXPECT_EQ(factory->getCache(config).cacheInfo().name_, "envoy.extensions.http.cache.simple"); +} + +} // namespace +} // namespace Cache +} // namespace HttpFilters +} // namespace Extensions +} // namespace Envoy From acdc6c7658638891253b2a49e74535de11984a72 Mon Sep 17 00:00:00 2001 From: Matt Klein Date: Wed, 12 Feb 2020 07:26:12 -0800 Subject: [PATCH 45/87] http: split header decoding into concrete types (#10001) This continues the refactor to used typed headers throughout the code base. This change only implements the decoding path, as encoding will require changing the HTTP filter interface. This completes the minimum amount of changes that will allow us to fix https://github.com/envoyproxy/envoy/issues/9873 in a type safe and easy to understand way. Signed-off-by: Matt Klein --- include/envoy/http/codec.h | 14 +- include/envoy/http/header_map.h | 16 + source/common/http/codec_client.cc | 3 +- source/common/http/codec_wrappers.h | 6 +- source/common/http/conn_manager_impl.cc | 7 +- source/common/http/conn_manager_impl.h | 6 +- source/common/http/exception.h | 9 +- source/common/http/header_map_impl.h | 16 +- source/common/http/http1/codec_impl.cc | 104 +++-- source/common/http/http1/codec_impl.h | 87 +++- source/common/http/http1/conn_pool.cc | 2 +- source/common/http/http1/conn_pool.h | 2 +- source/common/http/http1/conn_pool_legacy.cc | 2 +- source/common/http/http1/conn_pool_legacy.h | 2 +- source/common/http/http2/codec_impl.cc | 56 +-- source/common/http/http2/codec_impl.h | 43 +- source/common/router/router.cc | 6 +- source/common/router/router.h | 6 +- source/common/upstream/health_checker_impl.cc | 6 +- source/common/upstream/health_checker_impl.h | 12 +- .../quiche/envoy_quic_client_stream.cc | 9 +- .../quiche/envoy_quic_server_stream.cc | 9 +- .../quic_listeners/quiche/envoy_quic_utils.cc | 20 - .../quic_listeners/quiche/envoy_quic_utils.h | 26 +- test/BUILD | 1 - test/common/http/async_client_impl_test.cc | 63 +-- test/common/http/codec_client_test.cc | 12 +- .../http/conn_manager_impl_fuzz_test.cc | 4 +- test/common/http/conn_manager_impl_test.cc | 430 +++++++++--------- test/common/http/header_map_impl_fuzz_test.cc | 4 +- test/common/http/http1/codec_impl_test.cc | 5 +- .../http/http1/conn_pool_legacy_test.cc | 29 +- test/common/http/http1/conn_pool_test.cc | 29 +- .../http/http2/conn_pool_legacy_test.cc | 39 +- test/common/http/http2/conn_pool_test.cc | 45 +- test/common/router/router_test.cc | 236 ++++++---- .../common/router/router_upstream_log_test.cc | 9 +- .../upstream/health_checker_impl_test.cc | 22 +- .../quiche/envoy_quic_client_session_test.cc | 2 +- .../quiche/envoy_quic_client_stream_test.cc | 8 +- .../quiche/envoy_quic_server_session_test.cc | 12 +- .../quiche/envoy_quic_server_stream_test.cc | 12 +- .../quiche/envoy_quic_utils_test.cc | 4 +- .../api_listener_integration_test.cc | 4 +- test/integration/fake_upstream.cc | 4 +- test/integration/fake_upstream.h | 4 +- test/integration/integration.cc | 7 +- test/integration/integration.h | 8 +- test/integration/utility.cc | 4 +- test/integration/utility.h | 8 +- test/mocks/http/stream_decoder.cc | 21 +- test/mocks/http/stream_decoder.h | 20 +- test/test_common/utility.h | 37 +- test/test_runner.cc | 1 - 54 files changed, 910 insertions(+), 643 deletions(-) diff --git a/include/envoy/http/codec.h b/include/envoy/http/codec.h index fb7c8b5978..17b861cab2 100644 --- a/include/envoy/http/codec.h +++ b/include/envoy/http/codec.h @@ -134,8 +134,6 @@ class StreamDecoder { /** * Stream decoder used for receiving a request (client to server). Virtual inheritance is required * due to a parallel implementation split between the shared base class and the derived class. - * TODO(mattklein123): In a future change the header types will be changed to differentiate from - * the response path. */ class RequestDecoder : public virtual StreamDecoder { public: @@ -144,20 +142,18 @@ class RequestDecoder : public virtual StreamDecoder { * @param headers supplies the decoded headers map. * @param end_stream supplies whether this is a header only request. */ - virtual void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) PURE; + virtual void decodeHeaders(RequestHeaderMapPtr&& headers, bool end_stream) PURE; /** * Called with a decoded trailers frame. This implicitly ends the stream. * @param trailers supplies the decoded trailers. */ - virtual void decodeTrailers(HeaderMapPtr&& trailers) PURE; + virtual void decodeTrailers(RequestTrailerMapPtr&& trailers) PURE; }; /** * Stream decoder used for receiving a response (server to client). Virtual inheritance is required * due to a parallel implementation split between the shared base class and the derived class. - * TODO(mattklein123): In a future change the header types will be changed to differentiate from - * the request path. */ class ResponseDecoder : public virtual StreamDecoder { public: @@ -165,20 +161,20 @@ class ResponseDecoder : public virtual StreamDecoder { * Called with decoded 100-Continue headers. * @param headers supplies the decoded 100-Continue headers map. */ - virtual void decode100ContinueHeaders(HeaderMapPtr&& headers) PURE; + virtual void decode100ContinueHeaders(ResponseHeaderMapPtr&& headers) PURE; /** * Called with decoded headers, optionally indicating end of stream. * @param headers supplies the decoded headers map. * @param end_stream supplies whether this is a header only response. */ - virtual void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) PURE; + virtual void decodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) PURE; /** * Called with a decoded trailers frame. This implicitly ends the stream. * @param trailers supplies the decoded trailers. */ - virtual void decodeTrailers(HeaderMapPtr&& trailers) PURE; + virtual void decodeTrailers(ResponseTrailerMapPtr&& trailers) PURE; }; /** diff --git a/include/envoy/http/header_map.h b/include/envoy/http/header_map.h index 9c65dfa1bc..b47015f4a3 100644 --- a/include/envoy/http/header_map.h +++ b/include/envoy/http/header_map.h @@ -590,6 +590,22 @@ class HeaderMap { using HeaderMapPtr = std::unique_ptr; +/** + * Typed derived classes for all header map types. + * TODO(mattklein123): In future changes we will be differentiating the implementation between + * these classes to both fix bugs and improve performance. + * TODO(mattklein123): Virtual inheritance is currently required due to a layered implementation. + * Consider also removing virtual inheritance once we finish the typed header refactor. + */ +class RequestHeaderMap : public virtual HeaderMap {}; +using RequestHeaderMapPtr = std::unique_ptr; +class RequestTrailerMap : public virtual HeaderMap {}; +using RequestTrailerMapPtr = std::unique_ptr; +class ResponseHeaderMap : public virtual HeaderMap {}; +using ResponseHeaderMapPtr = std::unique_ptr; +class ResponseTrailerMap : public virtual HeaderMap {}; +using ResponseTrailerMapPtr = std::unique_ptr; + /** * Convenient container type for storing Http::LowerCaseString and std::string key/value pairs. */ diff --git a/source/common/http/codec_client.cc b/source/common/http/codec_client.cc index d4a65c5aa0..09c294af4a 100644 --- a/source/common/http/codec_client.cc +++ b/source/common/http/codec_client.cc @@ -132,8 +132,7 @@ void CodecClient::onData(Buffer::Instance& data) { close(); // Don't count 408 responses where we have no active requests as protocol errors - if (!active_requests_.empty() || - Utility::getResponseStatus(e.headers()) != enumToInt(Code::RequestTimeout)) { + if (!active_requests_.empty() || e.responseCode() != Code::RequestTimeout) { protocol_error = true; } } diff --git a/source/common/http/codec_wrappers.h b/source/common/http/codec_wrappers.h index ec99ddd29c..da14021045 100644 --- a/source/common/http/codec_wrappers.h +++ b/source/common/http/codec_wrappers.h @@ -11,11 +11,11 @@ namespace Http { class ResponseDecoderWrapper : public ResponseDecoder { public: // ResponseDecoder - void decode100ContinueHeaders(HeaderMapPtr&& headers) override { + void decode100ContinueHeaders(ResponseHeaderMapPtr&& headers) override { inner_.decode100ContinueHeaders(std::move(headers)); } - void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) override { + void decodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) override { if (end_stream) { onPreDecodeComplete(); } @@ -39,7 +39,7 @@ class ResponseDecoderWrapper : public ResponseDecoder { } } - void decodeTrailers(HeaderMapPtr&& trailers) override { + void decodeTrailers(ResponseTrailerMapPtr&& trailers) override { onPreDecodeComplete(); inner_.decodeTrailers(std::move(trailers)); onDecodeComplete(); diff --git a/source/common/http/conn_manager_impl.cc b/source/common/http/conn_manager_impl.cc index 0827e0022e..5060fbd9fc 100644 --- a/source/common/http/conn_manager_impl.cc +++ b/source/common/http/conn_manager_impl.cc @@ -705,7 +705,8 @@ const Network::Connection* ConnectionManagerImpl::ActiveStream::connection() { // // TODO(alyssawilk) all the calls here should be audited for order priority, // e.g. many early returns do not currently handle connection: close properly. -void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers, bool end_stream) { +void ConnectionManagerImpl::ActiveStream::decodeHeaders(RequestHeaderMapPtr&& headers, + bool end_stream) { ScopeTrackerScopeState scope(this, connection_manager_.read_callbacks_->connection().dispatcher()); request_headers_ = std::move(headers); @@ -1193,7 +1194,7 @@ MetadataMapVector& ConnectionManagerImpl::ActiveStream::addDecodedMetadata() { return *getRequestMetadataMapVector(); } -void ConnectionManagerImpl::ActiveStream::decodeTrailers(HeaderMapPtr&& trailers) { +void ConnectionManagerImpl::ActiveStream::decodeTrailers(RequestTrailerMapPtr&& trailers) { ScopeTrackerScopeState scope(this, connection_manager_.read_callbacks_->connection().dispatcher()); resetIdleTimer(); @@ -2308,7 +2309,7 @@ bool ConnectionManagerImpl::ActiveStreamDecoderFilter::recreateStream() { // n.b. we do not currently change the codecs to point at the new stream // decoder because the decoder callbacks are complete. It would be good to // null out that pointer but should not be necessary. - HeaderMapPtr request_headers(std::move(parent_.request_headers_)); + RequestHeaderMapPtr request_headers(std::move(parent_.request_headers_)); ResponseEncoder* response_encoder = parent_.response_encoder_; parent_.response_encoder_ = nullptr; response_encoder->getStream().removeCallbacks(parent_); diff --git a/source/common/http/conn_manager_impl.h b/source/common/http/conn_manager_impl.h index b1d2ad22bd..bfa35f788d 100644 --- a/source/common/http/conn_manager_impl.h +++ b/source/common/http/conn_manager_impl.h @@ -522,8 +522,8 @@ class ConnectionManagerImpl : Logger::Loggable, void decodeMetadata(MetadataMapPtr&&) override; // Http::RequestDecoder - void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) override; - void decodeTrailers(HeaderMapPtr&& trailers) override; + void decodeHeaders(RequestHeaderMapPtr&& headers, bool end_stream) override; + void decodeTrailers(RequestTrailerMapPtr&& trailers) override; // Http::FilterChainFactoryCallbacks void addStreamDecoderFilter(StreamDecoderFilterSharedPtr filter) override { @@ -688,7 +688,7 @@ class ConnectionManagerImpl : Logger::Loggable, HeaderMapPtr response_headers_; Buffer::WatermarkBufferPtr buffered_response_data_; HeaderMapPtr response_trailers_{}; - HeaderMapPtr request_headers_; + RequestHeaderMapPtr request_headers_; Buffer::WatermarkBufferPtr buffered_request_data_; HeaderMapPtr request_trailers_; std::list decoder_filters_; diff --git a/source/common/http/exception.h b/source/common/http/exception.h index 1a7ef668b2..605ee29306 100644 --- a/source/common/http/exception.h +++ b/source/common/http/exception.h @@ -3,6 +3,7 @@ #include #include "envoy/common/exception.h" +#include "envoy/http/codes.h" #include "envoy/http/header_map.h" namespace Envoy { @@ -30,13 +31,13 @@ class FrameFloodException : public CodecProtocolException { */ class PrematureResponseException : public EnvoyException { public: - PrematureResponseException(HeaderMapPtr&& headers) - : EnvoyException(""), headers_(std::move(headers)) {} + PrematureResponseException(Http::Code response_code) + : EnvoyException(""), response_code_(response_code) {} - const HeaderMap& headers() { return *headers_; } + Http::Code responseCode() { return response_code_; } private: - HeaderMapPtr headers_; + const Http::Code response_code_; }; /** diff --git a/source/common/http/header_map_impl.h b/source/common/http/header_map_impl.h index bba7221c7d..155b364e12 100644 --- a/source/common/http/header_map_impl.h +++ b/source/common/http/header_map_impl.h @@ -56,7 +56,7 @@ public: * paths use O(1) direct access. In general, we try to copy as little as possible and allocate as * little as possible in any of the paths. */ -class HeaderMapImpl : public HeaderMap, NonCopyable { +class HeaderMapImpl : public virtual HeaderMap, NonCopyable { public: HeaderMapImpl(); explicit HeaderMapImpl( @@ -240,5 +240,19 @@ class HeaderMapImpl : public HeaderMap, NonCopyable { using HeaderMapImplPtr = std::unique_ptr; +/** + * Typed derived classes for all header map types. + * TODO(mattklein123): In future changes we will be differentiating the implementation between + * these classes to both fix bugs and improve performance. + */ +class RequestHeaderMapImpl : public HeaderMapImpl, public RequestHeaderMap {}; +using RequestHeaderMapImplPtr = std::unique_ptr; +class RequestTrailerMapImpl : public HeaderMapImpl, public RequestTrailerMap {}; +using RequestTrailerMapImplPtr = std::unique_ptr; +class ResponseHeaderMapImpl : public HeaderMapImpl, public ResponseHeaderMap {}; +using ResponseHeaderMapImplPtr = std::unique_ptr; +class ResponseTrailerMapImpl : public HeaderMapImpl, public ResponseTrailerMap {}; +using ResponseTrailerMapImplPtr = std::unique_ptr; + } // namespace Http } // namespace Envoy diff --git a/source/common/http/http1/codec_impl.cc b/source/common/http/http1/codec_impl.cc index 8cb2190267..b99acad04e 100644 --- a/source/common/http/http1/codec_impl.cc +++ b/source/common/http/http1/codec_impl.cc @@ -372,7 +372,7 @@ ConnectionImpl::ConnectionImpl(Network::Connection& connection, Stats::Scope& st HeaderKeyFormatterPtr&& header_key_formatter, bool enable_trailers) : connection_(connection), stats_{ALL_HTTP1_CODEC_STATS(POOL_COUNTER_PREFIX(stats, "http1."))}, header_key_formatter_(std::move(header_key_formatter)), processing_trailers_(false), - handling_upgrade_(false), reset_stream_called_(false), + handling_upgrade_(false), reset_stream_called_(false), deferred_end_stream_headers_(false), strict_header_validation_( Runtime::runtimeFeatureEnabled("envoy.reloadable_features.strict_header_validation")), connection_header_sanitization_(Runtime::runtimeFeatureEnabled( @@ -392,12 +392,11 @@ void ConnectionImpl::completeLastHeader() { if (!current_header_field_.empty()) { toLowerTable().toLowerCase(current_header_field_.buffer(), current_header_field_.size()); - current_header_map_->addViaMove(std::move(current_header_field_), - std::move(current_header_value_)); + headers().addViaMove(std::move(current_header_field_), std::move(current_header_value_)); } // Check if the number of headers exceeds the limit. - if (current_header_map_->size() > max_headers_count_) { + if (headers().size() > max_headers_count_) { error_code_ = Http::Code::RequestHeaderFieldsTooLarge; sendProtocolError(Http1ResponseCodeDetails::get().TooManyHeaders); const absl::string_view header_type = @@ -494,9 +493,10 @@ void ConnectionImpl::onHeaderValue(const char* data, size_t length) { return; } - if (!current_header_map_) { - current_header_map_ = std::make_unique(); + if (processing_trailers_) { + maybeAllocTrailers(); } + // Work around a bug in http_parser where trailing whitespace is not trimmed // as the spec requires: https://tools.ietf.org/html/rfc7230#section-3.2.4 const absl::string_view header_value = StringUtil::trim(absl::string_view(data, length)); @@ -520,7 +520,7 @@ void ConnectionImpl::onHeaderValue(const char* data, size_t length) { current_header_value_.append(header_value.data(), header_value.length()); const uint32_t total = - current_header_field_.size() + current_header_value_.size() + current_header_map_->byteSize(); + current_header_field_.size() + current_header_value_.size() + headers().byteSize(); if (total > (max_headers_kb_ * 1024)) { const absl::string_view header_type = processing_trailers_ ? Http1HeaderTypes::get().Trailers : Http1HeaderTypes::get().Headers; @@ -541,33 +541,34 @@ int ConnectionImpl::onHeadersCompleteBase() { // HTTP/1.1 or not. protocol_ = Protocol::Http10; } - if (Utility::isUpgrade(*current_header_map_)) { + HeaderMap& current_headers = headers(); + if (Utility::isUpgrade(current_headers)) { // Ignore h2c upgrade requests until we support them. // See https://github.com/envoyproxy/envoy/issues/7161 for details. - if (current_header_map_->Upgrade() && - absl::EqualsIgnoreCase(current_header_map_->Upgrade()->value().getStringView(), + if (current_headers.Upgrade() && + absl::EqualsIgnoreCase(current_headers.Upgrade()->value().getStringView(), Http::Headers::get().UpgradeValues.H2c)) { ENVOY_CONN_LOG(trace, "removing unsupported h2c upgrade headers.", connection_); - current_header_map_->removeUpgrade(); - if (current_header_map_->Connection()) { + current_headers.removeUpgrade(); + if (current_headers.Connection()) { const auto& tokens_to_remove = caseUnorderdSetContainingUpgradeAndHttp2Settings(); std::string new_value = StringUtil::removeTokens( - current_header_map_->Connection()->value().getStringView(), ",", tokens_to_remove, ","); + current_headers.Connection()->value().getStringView(), ",", tokens_to_remove, ","); if (new_value.empty()) { - current_header_map_->removeConnection(); + current_headers.removeConnection(); } else { - current_header_map_->setConnection(new_value); + current_headers.setConnection(new_value); } } - current_header_map_->remove(Headers::get().Http2Settings); + current_headers.remove(Headers::get().Http2Settings); } else { ENVOY_CONN_LOG(trace, "codec entering upgrade mode.", connection_); handling_upgrade_ = true; } - } else if (connection_header_sanitization_ && current_header_map_->Connection()) { + } else if (connection_header_sanitization_ && current_headers.Connection()) { // If we fail to sanitize the request, return a 400 to the client - if (!Utility::sanitizeConnectionHeader(*current_header_map_)) { - absl::string_view header_value = current_header_map_->Connection()->value().getStringView(); + if (!Utility::sanitizeConnectionHeader(current_headers)) { + absl::string_view header_value = current_headers.Connection()->value().getStringView(); ENVOY_CONN_LOG(debug, "Invalid nominated headers in Connection: {}", connection_, header_value); error_code_ = Http::Code::BadRequest; @@ -578,8 +579,8 @@ int ConnectionImpl::onHeadersCompleteBase() { // Per https://tools.ietf.org/html/rfc7230#section-3.3.1 Envoy should reject // transfer-codings it does not understand. - if (current_header_map_->TransferEncoding()) { - absl::string_view encoding = current_header_map_->TransferEncoding()->value().getStringView(); + if (current_headers.TransferEncoding()) { + absl::string_view encoding = current_headers.TransferEncoding()->value().getStringView(); if (Runtime::runtimeFeatureEnabled( "envoy.reloadable_features.reject_unsupported_transfer_encodings") && encoding != Headers::get().TransferEncodingValues.Identity && @@ -590,9 +591,7 @@ int ConnectionImpl::onHeadersCompleteBase() { } } - int rc = onHeadersComplete(std::move(current_header_map_)); - current_header_map_.reset(); - + int rc = onHeadersComplete(); header_parsing_state_ = HeaderParsingState::Done; // Returning 2 informs http_parser to not expect a body or further data on this connection. @@ -617,7 +616,7 @@ void ConnectionImpl::onMessageCompleteBase() { completeLastHeader(); } - onMessageComplete(std::move(current_header_map_)); + onMessageComplete(); } void ConnectionImpl::onMessageBeginBase() { @@ -626,9 +625,9 @@ void ConnectionImpl::onMessageBeginBase() { // protocol for each request. Envoy defaults to 1.1 but sets the protocol to 1.0 where applicable // in onHeadersCompleteBase protocol_ = Protocol::Http11; - ASSERT(!current_header_map_); - current_header_map_ = std::make_unique(); + processing_trailers_ = false; header_parsing_state_ = HeaderParsingState::Field; + allocHeaders(); onMessageBegin(); } @@ -700,13 +699,13 @@ void ServerConnectionImpl::handlePath(HeaderMapImpl& headers, unsigned int metho active_request_->request_url_.clear(); } -int ServerConnectionImpl::onHeadersComplete(HeaderMapImplPtr&& headers) { - ENVOY_CONN_LOG(trace, "Server: onHeadersComplete size={}", connection_, headers->size()); - +int ServerConnectionImpl::onHeadersComplete() { // Handle the case where response happens prior to request complete. It's up to upper layer code // to disconnect the connection but we shouldn't fire any more events since it doesn't make // sense. if (active_request_) { + auto& headers = absl::get(headers_or_trailers_); + ENVOY_CONN_LOG(trace, "Server: onHeadersComplete size={}", connection_, headers->size()); const char* method_string = http_method_str(static_cast(parser_.method)); // Inform the response encoder about any HEAD method, so it can set content @@ -743,9 +742,8 @@ int ServerConnectionImpl::onHeadersComplete(HeaderMapImplPtr&& headers) { if (connection_.state() != Network::Connection::State::Open) { http_parser_pause(&parser_, 1); } - } else { - deferred_end_stream_headers_ = std::move(headers); + deferred_end_stream_headers_ = true; } } @@ -775,19 +773,23 @@ void ServerConnectionImpl::onBody(const char* data, size_t length) { } } -void ServerConnectionImpl::onMessageComplete(HeaderMapImplPtr&& trailers) { +void ServerConnectionImpl::onMessageComplete() { if (active_request_) { active_request_->remote_complete_ = true; if (deferred_end_stream_headers_) { - active_request_->request_decoder_->decodeHeaders(std::move(deferred_end_stream_headers_), - true); - deferred_end_stream_headers_.reset(); + active_request_->request_decoder_->decodeHeaders( + std::move(absl::get(headers_or_trailers_)), true); + deferred_end_stream_headers_ = false; } else if (processing_trailers_) { - active_request_->request_decoder_->decodeTrailers(std::move(trailers)); + active_request_->request_decoder_->decodeTrailers( + std::move(absl::get(headers_or_trailers_))); } else { Buffer::OwnedImpl buffer; active_request_->request_decoder_->decodeData(buffer, true); } + + // Reset for assertion purposes. + headers_or_trailers_.emplace(nullptr); } // Always pause the parser so that the calling code can process 1 request at a time and apply @@ -866,23 +868,24 @@ void ClientConnectionImpl::onEncodeHeaders(const HeaderMap& headers) { } } -int ClientConnectionImpl::onHeadersComplete(HeaderMapImplPtr&& headers) { - ENVOY_CONN_LOG(trace, "Client: onHeadersComplete size={}", connection_, headers->size()); - headers->setStatus(parser_.status_code); - +int ClientConnectionImpl::onHeadersComplete() { // Handle the case where the client is closing a kept alive connection (by sending a 408 // with a 'Connection: close' header). In this case we just let response flush out followed // by the remote close. if (pending_responses_.empty() && !resetStreamCalled()) { - throw PrematureResponseException(std::move(headers)); + throw PrematureResponseException(static_cast(parser_.status_code)); } else if (!pending_responses_.empty()) { + auto& headers = absl::get(headers_or_trailers_); + ENVOY_CONN_LOG(trace, "Client: onHeadersComplete size={}", connection_, headers->size()); + headers->setStatus(parser_.status_code); + if (parser_.status_code == 100) { // http-parser treats 100 continue headers as their own complete response. // Swallow the spurious onMessageComplete and continue processing. ignore_message_complete_for_100_continue_ = true; pending_responses_.front().decoder_->decode100ContinueHeaders(std::move(headers)); } else if (cannotHaveBody()) { - deferred_end_stream_headers_ = std::move(headers); + deferred_end_stream_headers_ = true; } else { pending_responses_.front().decoder_->decodeHeaders(std::move(headers), false); } @@ -902,7 +905,7 @@ void ClientConnectionImpl::onBody(const char* data, size_t length) { } } -void ClientConnectionImpl::onMessageComplete(HeaderMapImplPtr&& trailers) { +void ClientConnectionImpl::onMessageComplete() { ENVOY_CONN_LOG(trace, "message complete", connection_); if (ignore_message_complete_for_100_continue_) { ignore_message_complete_for_100_continue_ = false; @@ -910,7 +913,7 @@ void ClientConnectionImpl::onMessageComplete(HeaderMapImplPtr&& trailers) { } if (!pending_responses_.empty()) { // After calling decodeData() with end stream set to true, we should no longer be able to reset. - PendingResponse response = pending_responses_.front(); + PendingResponse response = std::move(pending_responses_.front()); pending_responses_.pop_front(); // Streams are responsible for unwinding any outstanding readDisable(true) @@ -926,14 +929,19 @@ void ClientConnectionImpl::onMessageComplete(HeaderMapImplPtr&& trailers) { } if (deferred_end_stream_headers_) { - response.decoder_->decodeHeaders(std::move(deferred_end_stream_headers_), true); - deferred_end_stream_headers_.reset(); + response.decoder_->decodeHeaders( + std::move(absl::get(headers_or_trailers_)), true); + deferred_end_stream_headers_ = false; } else if (processing_trailers_) { - response.decoder_->decodeTrailers(std::move(trailers)); + response.decoder_->decodeTrailers( + std::move(absl::get(headers_or_trailers_))); } else { Buffer::OwnedImpl buffer; response.decoder_->decodeData(buffer, true); } + + // Reset for assertion purposes. + headers_or_trailers_.emplace(nullptr); } } diff --git a/source/common/http/http1/codec_impl.h b/source/common/http/http1/codec_impl.h index 4dc1744b9e..d43d220df1 100644 --- a/source/common/http/http1/codec_impl.h +++ b/source/common/http/http1/codec_impl.h @@ -183,6 +183,12 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable(headers_or_trailers_)) { + return *absl::get(headers_or_trailers_); + } else { + return *absl::get(headers_or_trailers_); + } + } + void allocHeaders() override { + ASSERT(nullptr == absl::get(headers_or_trailers_)); + headers_or_trailers_.emplace(std::make_unique()); + } + void maybeAllocTrailers() override { + ASSERT(processing_trailers_); + if (!absl::holds_alternative(headers_or_trailers_)) { + headers_or_trailers_.emplace( + std::make_unique()); + } + } ServerConnectionCallbacks& callbacks_; std::unique_ptr active_request_; Http1Settings codec_settings_; + // TODO(mattklein123): This should be a member of ActiveRequest but this change needs dedicated + // thought as some of the reset and no header code paths make this difficult. Headers are + // populated on message begin. Trailers are populated on the first parsed trailer field (if + // trailers are enabled). The variant is reset to null headers on message complete for assertion + // purposes. + absl::variant headers_or_trailers_; }; /** @@ -403,18 +429,43 @@ class ClientConnectionImpl : public ClientConnection, public ConnectionImpl { void onEncodeHeaders(const HeaderMap& headers) override; void onMessageBegin() override {} void onUrl(const char*, size_t) override { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } - int onHeadersComplete(HeaderMapImplPtr&& headers) override; + int onHeadersComplete() override; void onBody(const char* data, size_t length) override; - void onMessageComplete(HeaderMapImplPtr&& trailers) override; + void onMessageComplete() override; void onResetStream(StreamResetReason reason) override; void sendProtocolError(absl::string_view details) override; void onAboveHighWatermark() override; void onBelowLowWatermark() override; + HeaderMapImpl& headers() override { + if (absl::holds_alternative(headers_or_trailers_)) { + return *absl::get(headers_or_trailers_); + } else { + return *absl::get(headers_or_trailers_); + } + } + void allocHeaders() override { + ASSERT(nullptr == absl::get(headers_or_trailers_)); + headers_or_trailers_.emplace( + std::make_unique()); + } + void maybeAllocTrailers() override { + ASSERT(processing_trailers_); + if (!absl::holds_alternative(headers_or_trailers_)) { + headers_or_trailers_.emplace( + std::make_unique()); + } + } std::unique_ptr request_encoder_; std::list pending_responses_; // Set true between receiving 100-Continue headers and receiving the spurious onMessageComplete. bool ignore_message_complete_for_100_continue_{}; + // TODO(mattklein123): This should be a member of PendingResponse but this change needs dedicated + // thought as some of the reset and no header code paths make this difficult. Headers are + // populated on message begin. Trailers are populated on the first parsed trailer field (if + // trailers are enabled). The variant is reset to null headers on message complete for assertion + // purposes. + absl::variant headers_or_trailers_; // The default limit of 80 KiB is the vanilla http_parser behaviour. static constexpr uint32_t MAX_RESPONSE_HEADERS_KB = 80; diff --git a/source/common/http/http1/conn_pool.cc b/source/common/http/http1/conn_pool.cc index 89499113d7..428657bcd8 100644 --- a/source/common/http/http1/conn_pool.cc +++ b/source/common/http/http1/conn_pool.cc @@ -81,7 +81,7 @@ ConnPoolImpl::StreamWrapper::~StreamWrapper() { void ConnPoolImpl::StreamWrapper::onEncodeComplete() { encode_complete_ = true; } -void ConnPoolImpl::StreamWrapper::decodeHeaders(HeaderMapPtr&& headers, bool end_stream) { +void ConnPoolImpl::StreamWrapper::decodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) { // If Connection: close OR // Http/1.0 and not Connection: keep-alive OR // Proxy-Connection: close diff --git a/source/common/http/http1/conn_pool.h b/source/common/http/http1/conn_pool.h index 4a7d7c8b70..0d9665f184 100644 --- a/source/common/http/http1/conn_pool.h +++ b/source/common/http/http1/conn_pool.h @@ -45,7 +45,7 @@ class ConnPoolImpl : public ConnPoolImplBase { void onEncodeComplete() override; // StreamDecoderWrapper - void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) override; + void decodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) override; void onPreDecodeComplete() override {} void onDecodeComplete() override; diff --git a/source/common/http/http1/conn_pool_legacy.cc b/source/common/http/http1/conn_pool_legacy.cc index 9f761c768a..b0dc47be25 100644 --- a/source/common/http/http1/conn_pool_legacy.cc +++ b/source/common/http/http1/conn_pool_legacy.cc @@ -279,7 +279,7 @@ ConnPoolImpl::StreamWrapper::~StreamWrapper() { void ConnPoolImpl::StreamWrapper::onEncodeComplete() { encode_complete_ = true; } -void ConnPoolImpl::StreamWrapper::decodeHeaders(HeaderMapPtr&& headers, bool end_stream) { +void ConnPoolImpl::StreamWrapper::decodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) { // If Connection: close OR // Http/1.0 and not Connection: keep-alive OR // Proxy-Connection: close diff --git a/source/common/http/http1/conn_pool_legacy.h b/source/common/http/http1/conn_pool_legacy.h index 75065bace4..be76eb5e77 100644 --- a/source/common/http/http1/conn_pool_legacy.h +++ b/source/common/http/http1/conn_pool_legacy.h @@ -64,7 +64,7 @@ class ConnPoolImpl : public ConnectionPool::Instance, public Legacy::ConnPoolImp void onEncodeComplete() override; // StreamDecoderWrapper - void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) override; + void decodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) override; void onPreDecodeComplete() override {} void onDecodeComplete() override; diff --git a/source/common/http/http2/codec_impl.cc b/source/common/http/http2/codec_impl.cc index 1542bda34b..1bbd99f6cf 100644 --- a/source/common/http/http2/codec_impl.cc +++ b/source/common/http/http2/codec_impl.cc @@ -51,9 +51,8 @@ template static T* remove_const(const void* object) { } ConnectionImpl::StreamImpl::StreamImpl(ConnectionImpl& parent, uint32_t buffer_limit) - : parent_(parent), headers_(new HeaderMapImpl()), local_end_stream_sent_(false), - remote_end_stream_(false), data_deferred_(false), - waiting_for_non_informational_headers_(false), + : parent_(parent), local_end_stream_sent_(false), remote_end_stream_(false), + data_deferred_(false), waiting_for_non_informational_headers_(false), pending_receive_buffer_high_watermark_called_(false), pending_send_buffer_high_watermark_called_(false), reset_due_to_messaging_error_(false) { if (buffer_limit > 0) { @@ -128,8 +127,8 @@ void ConnectionImpl::StreamImpl::encodeTrailersBase(const HeaderMap& trailers) { if (pending_send_data_.length() > 0) { // In this case we want trailers to come after we release all pending body data that is // waiting on window updates. We need to save the trailers so that we can emit them later. - ASSERT(!pending_trailers_); - pending_trailers_ = std::make_unique(trailers); + ASSERT(!pending_trailers_to_encode_); + pending_trailers_to_encode_ = std::make_unique(trailers); } else { submitTrailers(trailers); parent_.sendPendingFrames(); @@ -186,31 +185,35 @@ void ConnectionImpl::StreamImpl::pendingRecvBufferLowWatermark() { } void ConnectionImpl::ClientStreamImpl::decodeHeaders() { - if (!upgrade_type_.empty() && headers_->Status()) { - Http::Utility::transformUpgradeResponseFromH2toH1(*headers_, upgrade_type_); + auto& headers = absl::get(headers_or_trailers_); + if (!upgrade_type_.empty() && headers->Status()) { + Http::Utility::transformUpgradeResponseFromH2toH1(*headers, upgrade_type_); } - if (headers_->Status()->value() == "100") { + if (headers->Status()->value() == "100") { ASSERT(!remote_end_stream_); - response_decoder_.decode100ContinueHeaders(std::move(headers_)); + response_decoder_.decode100ContinueHeaders(std::move(headers)); } else { - response_decoder_.decodeHeaders(std::move(headers_), remote_end_stream_); + response_decoder_.decodeHeaders(std::move(headers), remote_end_stream_); } } void ConnectionImpl::ClientStreamImpl::decodeTrailers() { - response_decoder_.decodeTrailers(std::move(headers_)); + response_decoder_.decodeTrailers( + std::move(absl::get(headers_or_trailers_))); } void ConnectionImpl::ServerStreamImpl::decodeHeaders() { - if (Http::Utility::isH2UpgradeRequest(*headers_)) { - Http::Utility::transformUpgradeRequestFromH2toH1(*headers_); + auto& headers = absl::get(headers_or_trailers_); + if (Http::Utility::isH2UpgradeRequest(*headers)) { + Http::Utility::transformUpgradeRequestFromH2toH1(*headers); } - request_decoder_->decodeHeaders(std::move(headers_), remote_end_stream_); + request_decoder_->decodeHeaders(std::move(headers), remote_end_stream_); } void ConnectionImpl::ServerStreamImpl::decodeTrailers() { - request_decoder_->decodeTrailers(std::move(headers_)); + request_decoder_->decodeTrailers( + std::move(absl::get(headers_or_trailers_))); } void ConnectionImpl::StreamImpl::pendingSendBufferHighWatermark() { @@ -229,7 +232,7 @@ void ConnectionImpl::StreamImpl::pendingSendBufferLowWatermark() { void ConnectionImpl::StreamImpl::saveHeader(HeaderString&& name, HeaderString&& value) { if (!Utility::reconstituteCrumbledCookies(name, value, cookies_)) { - headers_->addViaMove(std::move(name), std::move(value)); + headers().addViaMove(std::move(name), std::move(value)); } } @@ -258,11 +261,11 @@ ssize_t ConnectionImpl::StreamImpl::onDataSourceRead(uint64_t length, uint32_t* *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY; if (local_end_stream_ && pending_send_data_.length() <= length) { *data_flags |= NGHTTP2_DATA_FLAG_EOF; - if (pending_trailers_) { + if (pending_trailers_to_encode_) { // We need to tell the library to not set end stream so that we can emit the trailers. *data_flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM; - submitTrailers(*pending_trailers_); - pending_trailers_.reset(); + submitTrailers(*pending_trailers_to_encode_); + pending_trailers_to_encode_.reset(); } } @@ -507,12 +510,12 @@ int ConnectionImpl::onFrameReceived(const nghttp2_frame* frame) { stream->remote_end_stream_ = frame->hd.flags & NGHTTP2_FLAG_END_STREAM; if (!stream->cookies_.empty()) { HeaderString key(Headers::get().Cookie); - stream->headers_->addViaMove(std::move(key), std::move(stream->cookies_)); + stream->headers().addViaMove(std::move(key), std::move(stream->cookies_)); } switch (frame->headers.cat) { case NGHTTP2_HCAT_RESPONSE: { - if (CodeUtility::is1xx(Http::Utility::getResponseStatus(*stream->headers_))) { + if (CodeUtility::is1xx(Http::Utility::getResponseStatus(stream->headers()))) { stream->waiting_for_non_informational_headers_ = true; } FALLTHRU; @@ -559,7 +562,6 @@ int ConnectionImpl::onFrameReceived(const nghttp2_frame* frame) { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } - stream->headers_.reset(); break; } case NGHTTP2_DATA: { @@ -798,8 +800,8 @@ int ConnectionImpl::saveHeader(const nghttp2_frame* frame, HeaderString&& name, } stream->saveHeader(std::move(name), std::move(value)); - if (stream->headers_->byteSize() > max_headers_kb_ * 1024 || - stream->headers_->size() > max_headers_count_) { + if (stream->headers().byteSize() > max_headers_kb_ * 1024 || + stream->headers().size() > max_headers_count_) { // This will cause the library to reset/close the stream. stats_.header_overflow_.inc(); return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; @@ -1099,8 +1101,7 @@ int ClientConnectionImpl::onBeginHeaders(const nghttp2_frame* frame) { ""); if (frame->headers.cat == NGHTTP2_HCAT_HEADERS) { StreamImpl* stream = getStream(frame->hd.stream_id); - ASSERT(!stream->headers_); - stream->headers_ = std::make_unique(); + stream->allocTrailers(); } return 0; @@ -1142,8 +1143,7 @@ int ServerConnectionImpl::onBeginHeaders(const nghttp2_frame* frame) { ASSERT(frame->headers.cat == NGHTTP2_HCAT_HEADERS); StreamImpl* stream = getStream(frame->hd.stream_id); - ASSERT(!stream->headers_); - stream->headers_ = std::make_unique(); + stream->allocTrailers(); return 0; } diff --git a/source/common/http/http2/codec_impl.h b/source/common/http/http2/codec_impl.h index e9390acd3d..7d6079791b 100644 --- a/source/common/http/http2/codec_impl.h +++ b/source/common/http/http2/codec_impl.h @@ -161,6 +161,8 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable 0; } ConnectionImpl& parent_; - HeaderMapImplPtr headers_; int32_t stream_id_{-1}; uint32_t unconsumed_bytes_{0}; uint32_t read_disable_count_{0}; @@ -218,7 +219,7 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable void { this->pendingSendBufferLowWatermark(); }, [this]() -> void { this->pendingSendBufferHighWatermark(); }}; - HeaderMapPtr pending_trailers_; + HeaderMapPtr pending_trailers_to_encode_; std::unique_ptr metadata_decoder_; std::unique_ptr metadata_encoder_; absl::optional deferred_reset_; @@ -240,7 +241,8 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable()) {} // StreamImpl void submitHeaders(const std::vector& final_headers, @@ -252,6 +254,24 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable(headers_or_trailers_)) { + return *absl::get(headers_or_trailers_); + } else { + return *absl::get(headers_or_trailers_); + } + } + void allocTrailers() override { + // If we are waiting for informational headers, make a new response header map, otherwise + // we are about to receive trailers. The codec makes sure this is the only valid sequence. + if (waiting_for_non_informational_headers_) { + headers_or_trailers_.emplace( + std::make_unique()); + } else { + headers_or_trailers_.emplace( + std::make_unique()); + } + } // RequestEncoder void encodeHeaders(const HeaderMap& headers, bool end_stream) override { @@ -260,6 +280,7 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable headers_or_trailers_; std::string upgrade_type_; }; @@ -269,7 +290,9 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable()) {} // StreamImpl void submitHeaders(const std::vector& final_headers, @@ -280,6 +303,17 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable(headers_or_trailers_)) { + return *absl::get(headers_or_trailers_); + } else { + return *absl::get(headers_or_trailers_); + } + } + void allocTrailers() override { + headers_or_trailers_.emplace( + std::make_unique()); + } // ResponseEncoder void encode100ContinueHeaders(const HeaderMap& headers) override; @@ -291,6 +325,7 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable headers_or_trailers_; }; using ServerStreamImplPtr = std::unique_ptr; diff --git a/source/common/router/router.cc b/source/common/router/router.cc index f21f585043..dcbf7757ea 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -1493,14 +1493,14 @@ Filter::UpstreamRequest::~UpstreamRequest() { } } -void Filter::UpstreamRequest::decode100ContinueHeaders(Http::HeaderMapPtr&& headers) { +void Filter::UpstreamRequest::decode100ContinueHeaders(Http::ResponseHeaderMapPtr&& headers) { ScopeTrackerScopeState scope(&parent_.callbacks_->scope(), parent_.callbacks_->dispatcher()); ASSERT(100 == Http::Utility::getResponseStatus(*headers)); parent_.onUpstream100ContinueHeaders(std::move(headers), *this); } -void Filter::UpstreamRequest::decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) { +void Filter::UpstreamRequest::decodeHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) { ScopeTrackerScopeState scope(&parent_.callbacks_->scope(), parent_.callbacks_->dispatcher()); // TODO(rodaine): This is actually measuring after the headers are parsed and not the first @@ -1525,7 +1525,7 @@ void Filter::UpstreamRequest::decodeData(Buffer::Instance& data, bool end_stream parent_.onUpstreamData(data, *this, end_stream); } -void Filter::UpstreamRequest::decodeTrailers(Http::HeaderMapPtr&& trailers) { +void Filter::UpstreamRequest::decodeTrailers(Http::ResponseTrailerMapPtr&& trailers) { ScopeTrackerScopeState scope(&parent_.callbacks_->scope(), parent_.callbacks_->dispatcher()); maybeEndDecode(true); diff --git a/source/common/router/router.h b/source/common/router/router.h index 8674b6ac21..f45b4a378f 100644 --- a/source/common/router/router.h +++ b/source/common/router/router.h @@ -397,9 +397,9 @@ class Filter : Logger::Loggable, void decodeMetadata(Http::MetadataMapPtr&& metadata_map) override; // Http::ResponseDecoder - void decode100ContinueHeaders(Http::HeaderMapPtr&& headers) override; - void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; - void decodeTrailers(Http::HeaderMapPtr&& trailers) override; + void decode100ContinueHeaders(Http::ResponseHeaderMapPtr&& headers) override; + void decodeHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) override; + void decodeTrailers(Http::ResponseTrailerMapPtr&& trailers) override; // Http::StreamCallbacks void onResetStream(Http::StreamResetReason reason, diff --git a/source/common/upstream/health_checker_impl.cc b/source/common/upstream/health_checker_impl.cc index 74a5288867..a8417f341c 100644 --- a/source/common/upstream/health_checker_impl.cc +++ b/source/common/upstream/health_checker_impl.cc @@ -199,7 +199,7 @@ void HttpHealthCheckerImpl::HttpActiveHealthCheckSession::onDeferredDelete() { } void HttpHealthCheckerImpl::HttpActiveHealthCheckSession::decodeHeaders( - Http::HeaderMapPtr&& headers, bool end_stream) { + Http::ResponseHeaderMapPtr&& headers, bool end_stream) { ASSERT(!response_headers_); response_headers_ = std::move(headers); if (end_stream) { @@ -539,7 +539,7 @@ void GrpcHealthCheckerImpl::GrpcActiveHealthCheckSession::onDeferredDelete() { } void GrpcHealthCheckerImpl::GrpcActiveHealthCheckSession::decodeHeaders( - Http::HeaderMapPtr&& headers, bool end_stream) { + Http::ResponseHeaderMapPtr&& headers, bool end_stream) { const auto http_response_status = Http::Utility::getResponseStatus(*headers); if (http_response_status != enumToInt(Http::Code::OK)) { // https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md requires that @@ -607,7 +607,7 @@ void GrpcHealthCheckerImpl::GrpcActiveHealthCheckSession::decodeData(Buffer::Ins } void GrpcHealthCheckerImpl::GrpcActiveHealthCheckSession::decodeTrailers( - Http::HeaderMapPtr&& trailers) { + Http::ResponseTrailerMapPtr&& trailers) { auto maybe_grpc_status = Grpc::Common::getGrpcStatus(*trailers); auto grpc_status = maybe_grpc_status diff --git a/source/common/upstream/health_checker_impl.h b/source/common/upstream/health_checker_impl.h index 4976f563b8..2cf2017e94 100644 --- a/source/common/upstream/health_checker_impl.h +++ b/source/common/upstream/health_checker_impl.h @@ -93,9 +93,9 @@ class HttpHealthCheckerImpl : public HealthCheckerImplBase { void decodeMetadata(Http::MetadataMapPtr&&) override {} // Http::ResponseDecoder - void decode100ContinueHeaders(Http::HeaderMapPtr&&) override {} - void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; - void decodeTrailers(Http::HeaderMapPtr&&) override { onResponseComplete(); } + void decode100ContinueHeaders(Http::ResponseHeaderMapPtr&&) override {} + void decodeHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) override; + void decodeTrailers(Http::ResponseTrailerMapPtr&&) override { onResponseComplete(); } // Http::StreamCallbacks void onResetStream(Http::StreamResetReason reason, @@ -312,9 +312,9 @@ class GrpcHealthCheckerImpl : public HealthCheckerImplBase { void decodeMetadata(Http::MetadataMapPtr&&) override {} // Http::ResponseDecoder - void decode100ContinueHeaders(Http::HeaderMapPtr&&) override {} - void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; - void decodeTrailers(Http::HeaderMapPtr&&) override; + void decode100ContinueHeaders(Http::ResponseHeaderMapPtr&&) override {} + void decodeHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) override; + void decodeTrailers(Http::ResponseTrailerMapPtr&&) override; // Http::StreamCallbacks void onResetStream(Http::StreamResetReason reason, diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc index c70228d0e0..166698505e 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc @@ -105,7 +105,8 @@ void EnvoyQuicClientStream::OnInitialHeadersComplete(bool fin, size_t frame_len, return; } ASSERT(headers_decompressed()); - response_decoder_->decodeHeaders(quicHeadersToEnvoyHeaders(header_list), /*end_stream=*/fin); + response_decoder_->decodeHeaders( + quicHeadersToEnvoyHeaders(header_list), /*end_stream=*/fin); if (fin) { end_stream_decoded_ = true; } @@ -164,7 +165,8 @@ void EnvoyQuicClientStream::OnBodyAvailable() { // For Google QUIC implementation, trailers may arrived earlier and wait to // be consumed after reading all the body. Consume it here. // IETF QUIC shouldn't reach here because trailers are sent on same stream. - response_decoder_->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); + response_decoder_->decodeTrailers( + spdyHeaderBlockToEnvoyHeaders(received_trailers())); MarkTrailersConsumed(); } OnFinRead(); @@ -180,7 +182,8 @@ void EnvoyQuicClientStream::OnTrailingHeadersComplete(bool fin, size_t frame_len !FinishedReadingTrailers()) { // Before QPack, trailers can arrive before body. Only decode trailers after finishing decoding // body. - response_decoder_->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); + response_decoder_->decodeTrailers( + spdyHeaderBlockToEnvoyHeaders(received_trailers())); MarkTrailersConsumed(); } } diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc index 35878eeb34..958efd02ae 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc @@ -127,7 +127,8 @@ void EnvoyQuicServerStream::OnInitialHeadersComplete(bool fin, size_t frame_len, const quic::QuicHeaderList& header_list) { quic::QuicSpdyServerStreamBase::OnInitialHeadersComplete(fin, frame_len, header_list); ASSERT(headers_decompressed()); - request_decoder_->decodeHeaders(quicHeadersToEnvoyHeaders(header_list), /*end_stream=*/fin); + request_decoder_->decodeHeaders( + quicHeadersToEnvoyHeaders(header_list), /*end_stream=*/fin); if (fin) { end_stream_decoded_ = true; } @@ -186,7 +187,8 @@ void EnvoyQuicServerStream::OnBodyAvailable() { // For Google QUIC implementation, trailers may arrived earlier and wait to // be consumed after reading all the body. Consume it here. // IETF QUIC shouldn't reach here because trailers are sent on same stream. - request_decoder_->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); + request_decoder_->decodeTrailers( + spdyHeaderBlockToEnvoyHeaders(received_trailers())); MarkTrailersConsumed(); } OnFinRead(); @@ -201,7 +203,8 @@ void EnvoyQuicServerStream::OnTrailingHeadersComplete(bool fin, size_t frame_len !FinishedReadingTrailers()) { // Before QPack trailers can arrive before body. Only decode trailers after finishing decoding // body. - request_decoder_->decodeTrailers(spdyHeaderBlockToEnvoyHeaders(received_trailers())); + request_decoder_->decodeTrailers( + spdyHeaderBlockToEnvoyHeaders(received_trailers())); MarkTrailersConsumed(); } } diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_utils.cc b/source/extensions/quic_listeners/quiche/envoy_quic_utils.cc index 1dd8c0c43b..de1cf601c3 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_utils.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_utils.cc @@ -45,26 +45,6 @@ quic::QuicSocketAddress envoyAddressInstanceToQuicSocketAddress( return quic::QuicSocketAddress(ss); } -Http::HeaderMapImplPtr quicHeadersToEnvoyHeaders(const quic::QuicHeaderList& header_list) { - Http::HeaderMapImplPtr headers = std::make_unique(); - for (const auto& entry : header_list) { - // TODO(danzh): Avoid copy by referencing entry as header_list is already validated by QUIC. - headers->addCopy(Http::LowerCaseString(entry.first), entry.second); - } - return headers; -} - -Http::HeaderMapImplPtr spdyHeaderBlockToEnvoyHeaders(const spdy::SpdyHeaderBlock& header_block) { - Http::HeaderMapImplPtr headers = std::make_unique(); - for (auto entry : header_block) { - // TODO(danzh): Avoid temporary strings and addCopy() with std::string_view. - std::string key(entry.first); - std::string value(entry.second); - headers->addCopy(Http::LowerCaseString(key), value); - } - return headers; -} - spdy::SpdyHeaderBlock envoyHeadersToSpdyHeaderBlock(const Http::HeaderMap& headers) { spdy::SpdyHeaderBlock header_block; headers.iterate( diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_utils.h b/source/extensions/quic_listeners/quiche/envoy_quic_utils.h index 4236c1deee..3348a1096b 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_utils.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_utils.h @@ -1,3 +1,5 @@ +#pragma once + #include "envoy/common/platform.h" #include "envoy/http/codec.h" @@ -34,9 +36,27 @@ quic::QuicSocketAddress envoyAddressInstanceToQuicSocketAddress( const Network::Address::InstanceConstSharedPtr& envoy_address); // The returned header map has all keys in lower case. -Http::HeaderMapImplPtr quicHeadersToEnvoyHeaders(const quic::QuicHeaderList& header_list); - -Http::HeaderMapImplPtr spdyHeaderBlockToEnvoyHeaders(const spdy::SpdyHeaderBlock& header_block); +template +std::unique_ptr quicHeadersToEnvoyHeaders(const quic::QuicHeaderList& header_list) { + auto headers = std::make_unique(); + for (const auto& entry : header_list) { + // TODO(danzh): Avoid copy by referencing entry as header_list is already validated by QUIC. + headers->addCopy(Http::LowerCaseString(entry.first), entry.second); + } + return headers; +} + +template +std::unique_ptr spdyHeaderBlockToEnvoyHeaders(const spdy::SpdyHeaderBlock& header_block) { + auto headers = std::make_unique(); + for (auto entry : header_block) { + // TODO(danzh): Avoid temporary strings and addCopy() with std::string_view. + std::string key(entry.first); + std::string value(entry.second); + headers->addCopy(Http::LowerCaseString(key), value); + } + return headers; +} spdy::SpdyHeaderBlock envoyHeadersToSpdyHeaderBlock(const Http::HeaderMap& headers); diff --git a/test/BUILD b/test/BUILD index 87a1713b9d..0c90654726 100644 --- a/test/BUILD +++ b/test/BUILD @@ -30,7 +30,6 @@ envoy_cc_test_library( "//source/common/common:logger_lib", "//source/common/common:thread_lib", "//source/common/event:libevent_lib", - "//source/common/http/http2:codec_lib", "//source/exe:process_wide_lib", "//test/common/runtime:utility_lib", "//test/mocks/access_log:access_log_mocks", diff --git a/test/common/http/async_client_impl_test.cc b/test/common/http/async_client_impl_test.cc index e4a0f63231..c45d31faca 100644 --- a/test/common/http/async_client_impl_test.cc +++ b/test/common/http/async_client_impl_test.cc @@ -119,8 +119,9 @@ TEST_F(AsyncClientImplTest, BasicStream) { stream->sendData(*body, true); response_decoder_->decode100ContinueHeaders( - HeaderMapPtr(new TestHeaderMapImpl{{":status", "100"}})); - response_decoder_->decodeHeaders(HeaderMapPtr(new TestHeaderMapImpl{{":status", "200"}}), false); + ResponseHeaderMapPtr(new TestResponseHeaderMapImpl{{":status", "100"}})); + response_decoder_->decodeHeaders( + ResponseHeaderMapPtr(new TestResponseHeaderMapImpl{{":status", "200"}}), false); response_decoder_->decodeData(*body, true); EXPECT_EQ( @@ -154,7 +155,7 @@ TEST_F(AsyncClientImplTest, Basic) { client_.send(std::move(message_), callbacks_, AsyncClient::RequestOptions()); - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers), false); response_decoder_->decodeData(data, true); @@ -200,7 +201,7 @@ TEST_F(AsyncClientImplTracingTest, Basic) { EXPECT_CALL(*child_span, setTag(Eq(Tracing::Tags::get().ResponseFlags), Eq("-"))); EXPECT_CALL(*child_span, finishSpan()); - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers), false); response_decoder_->decodeData(data, true); } @@ -239,7 +240,7 @@ TEST_F(AsyncClientImplTracingTest, BasicNamedChildSpan) { EXPECT_CALL(*child_span, setTag(Eq(Tracing::Tags::get().ResponseFlags), Eq("-"))); EXPECT_CALL(*child_span, finishSpan()); - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers), false); response_decoder_->decodeData(data, true); } @@ -279,7 +280,7 @@ TEST_F(AsyncClientImplTest, BasicHashPolicy) { options.setHashPolicy(hash_policy); client_.send(std::move(message_), callbacks_, options); - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers), false); response_decoder_->decodeData(data, true); } @@ -308,7 +309,7 @@ TEST_F(AsyncClientImplTest, Retry) { // Expect retry and retry timer create. timer_ = new NiceMock(&dispatcher_); - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "503"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "503"}}); response_decoder_->decodeHeaders(std::move(response_headers), true); // Retry request. @@ -326,7 +327,7 @@ TEST_F(AsyncClientImplTest, Retry) { // Normal response. expectSuccess(200); - HeaderMapPtr response_headers2(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers2(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers2), true); } @@ -356,7 +357,7 @@ TEST_F(AsyncClientImplTest, RetryWithStream) { // Expect retry and retry timer create. timer_ = new NiceMock(&dispatcher_); - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "503"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "503"}}); response_decoder_->decodeHeaders(std::move(response_headers), true); // Retry request. @@ -375,7 +376,7 @@ TEST_F(AsyncClientImplTest, RetryWithStream) { // Normal response. expectResponseHeaders(stream_callbacks_, 200, true); EXPECT_CALL(stream_callbacks_, onComplete()); - HeaderMapPtr response_headers2(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers2(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers2), true); } @@ -429,11 +430,11 @@ TEST_F(AsyncClientImplTest, MultipleStreams) { stream2->sendData(*body2, true); // Finish stream 2. - HeaderMapPtr response_headers2(new TestHeaderMapImpl{{":status", "503"}}); + ResponseHeaderMapPtr response_headers2(new TestResponseHeaderMapImpl{{":status", "503"}}); response_decoder2->decodeHeaders(std::move(response_headers2), true); // Finish stream 1. - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers), false); response_decoder_->decodeData(*body, true); } @@ -473,12 +474,12 @@ TEST_F(AsyncClientImplTest, MultipleRequests) { client_.send(std::move(message2), callbacks2, AsyncClient::RequestOptions()); // Finish request 2. - HeaderMapPtr response_headers2(new TestHeaderMapImpl{{":status", "503"}}); + ResponseHeaderMapPtr response_headers2(new TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(callbacks2, onSuccess_(_)); response_decoder2->decodeHeaders(std::move(response_headers2), true); // Finish request 1. - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers), false); expectSuccess(200); response_decoder_->decodeData(data, true); @@ -529,12 +530,12 @@ TEST_F(AsyncClientImplTest, StreamAndRequest) { stream->sendData(*body, true); // Finish stream. - HeaderMapPtr response_headers2(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers2(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder2->decodeHeaders(std::move(response_headers2), false); response_decoder2->decodeData(*body, true); // Finish request. - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers), false); expectSuccess(200); response_decoder_->decodeData(data, true); @@ -569,10 +570,11 @@ TEST_F(AsyncClientImplTest, StreamWithTrailers) { stream->sendData(*body, false); stream->sendTrailers(trailers); - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers), false); response_decoder_->decodeData(*body, false); - response_decoder_->decodeTrailers(HeaderMapPtr{new TestHeaderMapImpl{{"some", "trailer"}}}); + response_decoder_->decodeTrailers( + ResponseTrailerMapPtr{new TestResponseTrailerMapImpl{{"some", "trailer"}}}); } TEST_F(AsyncClientImplTest, Trailers) { @@ -592,10 +594,11 @@ TEST_F(AsyncClientImplTest, Trailers) { expectSuccess(200); client_.send(std::move(message_), callbacks_, AsyncClient::RequestOptions()); - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers), false); response_decoder_->decodeData(data, false); - response_decoder_->decodeTrailers(HeaderMapPtr{new TestHeaderMapImpl{{"some", "trailer"}}}); + response_decoder_->decodeTrailers( + ResponseTrailerMapPtr{new TestResponseTrailerMapImpl{{"some", "trailer"}}}); } TEST_F(AsyncClientImplTest, ImmediateReset) { @@ -646,7 +649,8 @@ TEST_F(AsyncClientImplTest, LocalResetAfterStreamStart) { stream->sendHeaders(headers, false); stream->sendData(*body, false); - response_decoder_->decodeHeaders(HeaderMapPtr(new TestHeaderMapImpl{{":status", "200"}}), false); + response_decoder_->decodeHeaders( + ResponseHeaderMapPtr(new TestResponseHeaderMapImpl{{":status", "200"}}), false); response_decoder_->decodeData(*body, false); stream->reset(); @@ -679,7 +683,8 @@ TEST_F(AsyncClientImplTest, SendDataAfterRemoteClosure) { AsyncClient::Stream* stream = client_.start(stream_callbacks_, AsyncClient::StreamOptions()); stream->sendHeaders(headers, false); - response_decoder_->decodeHeaders(HeaderMapPtr(new TestHeaderMapImpl{{":status", "200"}}), false); + response_decoder_->decodeHeaders( + ResponseHeaderMapPtr(new TestResponseHeaderMapImpl{{":status", "200"}}), false); response_decoder_->decodeData(*body, true); EXPECT_CALL(stream_encoder_, encodeData(_, _)).Times(0); @@ -716,7 +721,8 @@ TEST_F(AsyncClientImplTest, SendTrailersRemoteClosure) { AsyncClient::Stream* stream = client_.start(stream_callbacks_, AsyncClient::StreamOptions()); stream->sendHeaders(headers, false); - response_decoder_->decodeHeaders(HeaderMapPtr(new TestHeaderMapImpl{{":status", "200"}}), false); + response_decoder_->decodeHeaders( + ResponseHeaderMapPtr(new TestResponseHeaderMapImpl{{":status", "200"}}), false); response_decoder_->decodeData(*body, true); EXPECT_CALL(stream_encoder_, encodeTrailers(_)).Times(0); @@ -757,7 +763,8 @@ TEST_F(AsyncClientImplTest, ResetInOnHeaders) { Http::StreamDecoderFilterCallbacks* filter_callbacks = static_cast(stream); - filter_callbacks->encodeHeaders(HeaderMapPtr(new TestHeaderMapImpl{{":status", "200"}}), false); + filter_callbacks->encodeHeaders( + ResponseHeaderMapPtr(new TestResponseHeaderMapImpl{{":status", "200"}}), false); } TEST_F(AsyncClientImplTest, RemoteResetAfterStreamStart) { @@ -789,7 +796,8 @@ TEST_F(AsyncClientImplTest, RemoteResetAfterStreamStart) { stream->sendHeaders(headers, false); stream->sendData(*body, false); - response_decoder_->decodeHeaders(HeaderMapPtr(new TestHeaderMapImpl{{":status", "200"}}), false); + response_decoder_->decodeHeaders( + ResponseHeaderMapPtr(new TestResponseHeaderMapImpl{{":status", "200"}}), false); response_decoder_->decodeData(*body, false); stream_encoder_.getStream().resetStream(StreamResetReason::RemoteReset); @@ -808,7 +816,7 @@ TEST_F(AsyncClientImplTest, ResetAfterResponseStart) { EXPECT_CALL(callbacks_, onFailure(_)); client_.send(std::move(message_), callbacks_, AsyncClient::RequestOptions()); - HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder_->decodeHeaders(std::move(response_headers), false); stream_encoder_.getStream().resetStream(StreamResetReason::RemoteReset); } @@ -1159,7 +1167,8 @@ TEST_F(AsyncClientImplTest, MultipleDataStream) { stream->sendHeaders(headers, false); stream->sendData(*body, false); - response_decoder_->decodeHeaders(HeaderMapPtr(new TestHeaderMapImpl{{":status", "200"}}), false); + response_decoder_->decodeHeaders( + ResponseHeaderMapPtr(new TestResponseHeaderMapImpl{{":status", "200"}}), false); response_decoder_->decodeData(*body, false); EXPECT_CALL(stream_encoder_, encodeData(BufferEqual(body2.get()), true)); diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index e8876f8c31..f0e7b5fc7c 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -101,7 +101,7 @@ TEST_F(CodecClientTest, BasicHeaderOnlyResponse) { Http::MockResponseDecoder outer_decoder; client_->newStream(outer_decoder); - Http::HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; EXPECT_CALL(outer_decoder, decodeHeaders_(Pointee(Ref(*response_headers)), true)); inner_decoder->decodeHeaders(std::move(response_headers), true); } @@ -118,7 +118,7 @@ TEST_F(CodecClientTest, BasicResponseWithBody) { Http::MockResponseDecoder outer_decoder; client_->newStream(outer_decoder); - Http::HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; EXPECT_CALL(outer_decoder, decodeHeaders_(Pointee(Ref(*response_headers)), false)); inner_decoder->decodeHeaders(std::move(response_headers), false); @@ -164,7 +164,7 @@ TEST_F(CodecClientTest, IdleTimerWithNoActiveRequests) { request_encoder.getStream().addCallbacks(callbacks); connection_cb_->onEvent(Network::ConnectionEvent::Connected); - Http::HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; EXPECT_CALL(outer_decoder, decodeHeaders_(Pointee(Ref(*response_headers)), false)); inner_decoder->decodeHeaders(std::move(response_headers), false); @@ -240,8 +240,7 @@ TEST_F(CodecClientTest, ProtocolError) { TEST_F(CodecClientTest, 408Response) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([](Buffer::Instance&) -> void { - Http::HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "408"}}}; - throw PrematureResponseException(std::move(response_headers)); + throw PrematureResponseException(Code::RequestTimeout); })); EXPECT_CALL(*connection_, close(Network::ConnectionCloseType::NoFlush)); @@ -254,8 +253,7 @@ TEST_F(CodecClientTest, 408Response) { TEST_F(CodecClientTest, PrematureResponse) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([](Buffer::Instance&) -> void { - Http::HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; - throw PrematureResponseException(std::move(response_headers)); + throw PrematureResponseException(Code::OK); })); EXPECT_CALL(*connection_, close(Network::ConnectionCloseType::NoFlush)); diff --git a/test/common/http/conn_manager_impl_fuzz_test.cc b/test/common/http/conn_manager_impl_fuzz_test.cc index 72a490308a..3ba02f3618 100644 --- a/test/common/http/conn_manager_impl_fuzz_test.cc +++ b/test/common/http/conn_manager_impl_fuzz_test.cc @@ -205,7 +205,7 @@ class FuzzStream { EXPECT_CALL(*config_.codec_, dispatch(_)) .WillOnce(InvokeWithoutArgs([this, &request_headers, end_stream] { decoder_ = &conn_manager_.newStream(encoder_); - auto headers = std::make_unique(request_headers); + auto headers = std::make_unique(request_headers); if (headers->Method() == nullptr) { headers->setReferenceKey(Headers::get().Method, "GET"); } @@ -312,7 +312,7 @@ class FuzzStream { })); EXPECT_CALL(*config_.codec_, dispatch(_)) .WillOnce(InvokeWithoutArgs([this, &trailers_action] { - decoder_->decodeTrailers(std::make_unique( + decoder_->decodeTrailers(std::make_unique( Fuzz::fromHeaders(trailers_action.headers()))); })); fakeOnData(); diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc index c2db560ffb..fb227e775c 100644 --- a/test/common/http/conn_manager_impl_test.cc +++ b/test/common/http/conn_manager_impl_test.cc @@ -205,15 +205,15 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan EXPECT_CALL(*codec_, dispatch(_)) .WillOnce(Invoke([&, request_with_data_and_trailers](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ + {":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; if (request_with_data_and_trailers) { decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("12345"); decoder->decodeData(fake_data, false); - HeaderMapPtr trailers{new TestHeaderMapImpl{{"foo", "bar"}}}; + RequestTrailerMapPtr trailers{new TestRequestTrailerMapImpl{{"foo", "bar"}}}; decoder->decodeTrailers(std::move(trailers)); } else { decoder->decodeHeaders(std::move(headers), true); @@ -445,11 +445,11 @@ TEST_F(HttpConnectionManagerImplTest, HeaderOnlyRequestAndResponse) { // Test not charging stats on the second call. if (data.length() == 4) { - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ + {":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); } else { - HeaderMapPtr headers{new TestHeaderMapImpl{ + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ {":authority", "host"}, {":path", "/healthcheck"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); } @@ -502,8 +502,8 @@ TEST_F(HttpConnectionManagerImplTest, 100ContinueResponse) { decoder = &conn_manager_->newStream(encoder); // Test not charging stats on the second call. - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr continue_headers{new TestHeaderMapImpl{{":status", "100"}}}; @@ -668,7 +668,7 @@ TEST_F(HttpConnectionManagerImplTest, InvalidPathWithDualFilter) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{new TestHeaderMapImpl{ + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ {":authority", "host"}, {":path", "http://api.lyft.com/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); data.drain(4); @@ -705,10 +705,10 @@ TEST_F(HttpConnectionManagerImplTest, PathFailedtoSanitize) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, - {":path", "/ab%00c"}, // "%00" is not valid in path according to RFC - {":method", "GET"}}}; + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ + {":authority", "host"}, + {":path", "/ab%00c"}, // "%00" is not valid in path according to RFC + {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); data.drain(4); })); @@ -761,7 +761,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterShouldUseSantizedPath) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{new TestHeaderMapImpl{ + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ {":authority", "host"}, {":path", original_path}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); })); @@ -782,7 +782,7 @@ TEST_F(HttpConnectionManagerImplTest, RouteShouldUseSantizedPath) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{new TestHeaderMapImpl{ + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ {":authority", "host"}, {":path", original_path}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); })); @@ -939,11 +939,11 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlow) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -1007,11 +1007,11 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecorat EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -1073,11 +1073,11 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecorat EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -1137,12 +1137,12 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecorat EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}, - {"x-envoy-decorator-operation", "testOp"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}, + {"x-envoy-decorator-operation", "testOp"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -1218,11 +1218,11 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecorato EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -1300,11 +1300,11 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecorato EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -1380,11 +1380,11 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecorato EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{ @@ -1436,11 +1436,11 @@ TEST_F(HttpConnectionManagerImplTest, EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{ @@ -1492,12 +1492,12 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLog) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-forwarded-for", xff_address}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-forwarded-for", xff_address}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -1536,8 +1536,8 @@ TEST_F(HttpConnectionManagerImplTest, TestDownstreamDisconnectAccessLog) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, {":authority", "host"}, {":path", "/"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, {":authority", "host"}, {":path", "/"}}}; decoder->decodeHeaders(std::move(headers), true); data.drain(4); @@ -1575,11 +1575,11 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLogWithTrailers) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -1625,7 +1625,7 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLogWithInvalidRequest) { decoder = &conn_manager_->newStream(encoder); // These request headers are missing the necessary ":host" - HeaderMapPtr headers{new TestHeaderMapImpl{{":method", "GET"}, {":path", "/"}}}; + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{{":method", "GET"}, {":path", "/"}}}; decoder->decodeHeaders(std::move(headers), true); data.drain(0); })); @@ -1663,11 +1663,11 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLogSsl) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -1706,11 +1706,11 @@ TEST_F(HttpConnectionManagerImplTest, DoNotStartSpanIfTracingIsNotEnabled) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, - {":authority", "host"}, - {":path", "/"}, - {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, + {":authority", "host"}, + {":path", "/"}, + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -1730,7 +1730,8 @@ TEST_F(HttpConnectionManagerImplTest, NoPath) { NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{new TestHeaderMapImpl{{":authority", "host"}, {":method", "NOT_CONNECT"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":method", "NOT_CONNECT"}}}; decoder->decodeHeaders(std::move(headers), true); data.drain(4); })); @@ -1754,8 +1755,8 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutNotConfigured) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); data.drain(4); @@ -1909,8 +1910,8 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutRouteOverride) { EXPECT_CALL(*idle_timer, enableTimer(std::chrono::milliseconds(10), _)); RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; EXPECT_CALL(*idle_timer, enableTimer(std::chrono::milliseconds(30), _)); decoder->decodeHeaders(std::move(headers), false); @@ -1935,8 +1936,8 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutRouteZeroOverride) { EXPECT_CALL(*idle_timer, enableTimer(std::chrono::milliseconds(10), _)); RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; EXPECT_CALL(*idle_timer, disableTimer()); decoder->decodeHeaders(std::move(headers), false); @@ -1960,8 +1961,8 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutAfterDownstreamHeaders RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); Event::MockTimer* idle_timer = setUpTimer(); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; EXPECT_CALL(*idle_timer, enableTimer(_, _)); decoder->decodeHeaders(std::move(headers), false); @@ -2000,8 +2001,8 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutNormalTermination) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; EXPECT_CALL(*idle_timer, enableTimer(_, _)); decoder->decodeHeaders(std::move(headers), false); @@ -2029,8 +2030,8 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutAfterDownstreamHeaders RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); Event::MockTimer* idle_timer = setUpTimer(); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; EXPECT_CALL(*idle_timer, enableTimer(_, _)); decoder->decodeHeaders(std::move(headers), false); @@ -2082,8 +2083,8 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutAfterUpstreamHeaders) RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); Event::MockTimer* idle_timer = setUpTimer(); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; EXPECT_CALL(*idle_timer, enableTimer(_, _)); decoder->decodeHeaders(std::move(headers), false); @@ -2131,8 +2132,8 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutAfterBidiData) { RequestDecoder* decoder; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; EXPECT_CALL(*idle_timer, enableTimer(_, _)); decoder->decodeHeaders(std::move(headers), false); @@ -2147,7 +2148,7 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutAfterBidiData) { EXPECT_CALL(*idle_timer, enableTimer(_, _)); decoder->decodeData(data, false); - HeaderMapPtr trailers{new TestHeaderMapImpl{{"foo", "bar"}}}; + RequestTrailerMapPtr trailers{new TestRequestTrailerMapImpl{{"foo", "bar"}}}; EXPECT_CALL(*idle_timer, enableTimer(_, _)); decoder->decodeTrailers(std::move(trailers)); @@ -2258,8 +2259,8 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsNotDisarmedOnIncompleteReq EXPECT_CALL(*request_timer, disableTimer()).Times(0); RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; // the second parameter 'false' leaves the stream open decoder->decodeHeaders(std::move(headers), false); @@ -2280,8 +2281,8 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnCompleteRequestW EXPECT_CALL(*request_timer, enableTimer(request_timeout_, _)).Times(1); RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; EXPECT_CALL(*request_timer, disableTimer()).Times(1); decoder->decodeHeaders(std::move(headers), true); @@ -2302,8 +2303,8 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnCompleteRequestW EXPECT_CALL(*request_timer, enableTimer(request_timeout_, _)).Times(1); RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "POST"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "POST"}}}; decoder->decodeHeaders(std::move(headers), false); EXPECT_CALL(*request_timer, disableTimer()).Times(1); @@ -2325,13 +2326,13 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnCompleteRequestW EXPECT_CALL(*request_timer, enableTimer(request_timeout_, _)).Times(1); RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); decoder->decodeData(data, false); EXPECT_CALL(*request_timer, disableTimer()).Times(1); - HeaderMapPtr trailers{new TestHeaderMapImpl{{"foo", "bar"}}}; + RequestTrailerMapPtr trailers{new TestRequestTrailerMapImpl{{"foo", "bar"}}}; decoder->decodeTrailers(std::move(trailers)); })); @@ -2356,8 +2357,8 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnEncodeHeaders) { EXPECT_CALL(*request_timer, enableTimer(request_timeout_, _)).Times(1); RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); @@ -2379,8 +2380,8 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnConnectionTermin Event::MockTimer* request_timer = setUpTimer(); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); })); @@ -2402,11 +2403,11 @@ TEST_F(HttpConnectionManagerImplTest, RejectWebSocketOnNonWebSocketRoute) { NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{new TestHeaderMapImpl{{":authority", "host"}, - {":method", "GET"}, - {":path", "/"}, - {"connection", "Upgrade"}, - {"upgrade", "websocket"}}}; + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{{":authority", "host"}, + {":method", "GET"}, + {":path", "/"}, + {"connection", "Upgrade"}, + {"upgrade", "websocket"}}}; decoder->decodeHeaders(std::move(headers), true); data.drain(4); })); @@ -2462,11 +2463,11 @@ TEST_F(HttpConnectionManagerImplTest, FooUpgradeDrainClose) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{new TestHeaderMapImpl{{":authority", "host"}, - {":method", "GET"}, - {":path", "/"}, - {"connection", "Upgrade"}, - {"upgrade", "foo"}}}; + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{{":authority", "host"}, + {":method", "GET"}, + {":path", "/"}, + {"connection", "Upgrade"}, + {"upgrade", "foo"}}}; decoder->decodeHeaders(std::move(headers), false); HeaderMapPtr response_headers{ @@ -2501,8 +2502,8 @@ TEST_F(HttpConnectionManagerImplTest, DrainClose) { NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); })); @@ -2536,8 +2537,8 @@ TEST_F(HttpConnectionManagerImplTest, ResponseBeforeRequestComplete) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); })); @@ -2568,7 +2569,7 @@ TEST_F(HttpConnectionManagerImplTest, DisconnectOnProxyConnectionDisconnect) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{new TestHeaderMapImpl{ + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ {":authority", "host"}, {":path", "/"}, {":method", "GET"}, {"proxy-connection", "close"}}}; decoder->decodeHeaders(std::move(headers), false); })); @@ -2614,8 +2615,8 @@ TEST_F(HttpConnectionManagerImplTest, ResponseStartBeforeRequestComplete) { NiceMock encoder; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); })); @@ -2740,8 +2741,8 @@ TEST_F(HttpConnectionManagerImplTest, TestDownstreamProtocolErrorAfterHeadersAcc EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":method", "GET"}, {":authority", "host"}, {":path", "/"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":method", "GET"}, {":authority", "host"}, {":path", "/"}}}; decoder->decodeHeaders(std::move(headers), true); throw CodecProtocolException("protocol error"); @@ -2836,8 +2837,8 @@ TEST_F(HttpConnectionManagerImplTest, IdleTimeout) { RequestDecoder* decoder = nullptr; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); @@ -2905,8 +2906,8 @@ TEST_F(HttpConnectionManagerImplTest, ConnectionDuration) { RequestDecoder* decoder = nullptr; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); @@ -2945,8 +2946,8 @@ TEST_F(HttpConnectionManagerImplTest, IntermediateBufferingEarlyResponse) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); @@ -2991,8 +2992,8 @@ TEST_F(HttpConnectionManagerImplTest, DoubleBuffering) { Buffer::OwnedImpl fake_data_copy("hello"); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); decoder->decodeData(fake_data, true); })); @@ -3034,8 +3035,8 @@ TEST_F(HttpConnectionManagerImplTest, ZeroByteDataFiltering) { RequestDecoder* decoder = nullptr; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); })); @@ -3073,14 +3074,14 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddTrailersInTrailersCallback) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); decoder->decodeData(fake_data, false); - HeaderMapPtr trailers{new TestHeaderMapImpl{{"bazzz", "bar"}}}; + RequestTrailerMapPtr trailers{new TestRequestTrailerMapImpl{{"bazzz", "bar"}}}; decoder->decodeTrailers(std::move(trailers)); })); @@ -3159,8 +3160,8 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddTrailersInDataCallbackNoTrailers) EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); @@ -3250,14 +3251,14 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); decoder->decodeData(fake_data, false); - HeaderMapPtr trailers{new TestHeaderMapImpl{{"foo", "bar"}}}; + RequestTrailerMapPtr trailers{new TestRequestTrailerMapImpl{{"foo", "bar"}}}; decoder->decodeTrailers(std::move(trailers)); })); @@ -3331,11 +3332,11 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback_NoDataFram EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); - HeaderMapPtr trailers{new TestHeaderMapImpl{{"foo", "bar"}}}; + RequestTrailerMapPtr trailers{new TestRequestTrailerMapImpl{{"foo", "bar"}}}; decoder->decodeTrailers(std::move(trailers)); })); @@ -3390,11 +3391,11 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback_ContinueAf EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); - HeaderMapPtr trailers{new TestHeaderMapImpl{{"foo", "bar"}}}; + RequestTrailerMapPtr trailers{new TestRequestTrailerMapImpl{{"foo", "bar"}}}; decoder->decodeTrailers(std::move(trailers)); })); @@ -3455,8 +3456,8 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyDuringDecodeData) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl data1("hello"); @@ -3523,8 +3524,8 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInline) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); })); @@ -3573,8 +3574,8 @@ TEST_F(HttpConnectionManagerImplTest, FilterClearRouteCache) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); })); @@ -3714,8 +3715,8 @@ TEST_F(HttpConnectionManagerImplTest, UnderlyingConnectionWatermarksPassedOnWith setupFilterChain(2, 2); EXPECT_CALL(filter_callbacks_.connection_, aboveHighWatermark()).Times(0); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); })); EXPECT_CALL(*decoder_filters_[0], decodeHeaders(_, true)) @@ -3781,8 +3782,8 @@ TEST_F(HttpConnectionManagerImplTest, UnderlyingConnectionWatermarksUnwoundWithL setupFilterChain(2, 2); EXPECT_CALL(filter_callbacks_.connection_, aboveHighWatermark()).Times(0); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); })); EXPECT_CALL(*decoder_filters_[0], decodeHeaders(_, true)) @@ -3906,8 +3907,8 @@ TEST_F(HttpConnectionManagerImplTest, HitRequestBufferLimitsIntermediateFilter) EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); @@ -4014,8 +4015,8 @@ TEST_F(HttpConnectionManagerImplTest, FilterHeadReply) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "HEAD"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "HEAD"}}}; decoder->decodeHeaders(std::move(headers), true); data.drain(4); })); @@ -4052,8 +4053,8 @@ TEST_F(HttpConnectionManagerImplTest, ResetWithStoppedFilter) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); data.drain(4); })); @@ -4096,7 +4097,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterContinueAndEndStreamHeaders) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - auto headers = std::make_unique( + auto headers = std::make_unique( std::initializer_list>( {{":authority", "host"}, {":path", "/"}, {":method", "GET"}})); decoder->decodeHeaders(std::move(headers), false); @@ -4124,7 +4125,8 @@ TEST_F(HttpConnectionManagerImplTest, FilterContinueAndEndStreamHeaders) { expectOnDestroy(); - decoder_filters_[1]->callbacks_->encodeHeaders(makeHeaderMap({{":status", "200"}}), true); + decoder_filters_[1]->callbacks_->encodeHeaders( + makeHeaderMap({{":status", "200"}}), true); Buffer::OwnedImpl response_body("response"); decoder_filters_[1]->callbacks_->encodeData(response_body, true); @@ -4136,7 +4138,8 @@ TEST_F(HttpConnectionManagerImplTest, FilterContinueAndEndStreamData) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - auto headers = makeHeaderMap({{":authority", "host"}, {":path", "/"}, {":method", "GET"}}); + auto headers = makeHeaderMap( + {{":authority", "host"}, {":path", "/"}, {":method", "GET"}}); decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); @@ -4164,7 +4167,8 @@ TEST_F(HttpConnectionManagerImplTest, FilterContinueAndEndStreamData) { expectOnDestroy(); - decoder_filters_[1]->callbacks_->encodeHeaders(makeHeaderMap({{":status", "200"}}), false); + decoder_filters_[1]->callbacks_->encodeHeaders( + makeHeaderMap({{":status", "200"}}), false); Buffer::OwnedImpl response_body("response"); decoder_filters_[1]->callbacks_->encodeData(response_body, true); @@ -4176,13 +4180,14 @@ TEST_F(HttpConnectionManagerImplTest, FilterContinueAndEndStreamTrailers) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - auto headers = makeHeaderMap({{":authority", "host"}, {":path", "/"}, {":method", "GET"}}); + auto headers = makeHeaderMap( + {{":authority", "host"}, {":path", "/"}, {":method", "GET"}}); decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); decoder->decodeData(fake_data, false); - auto trailers = makeHeaderMap({{"foo", "bar"}}); + auto trailers = makeHeaderMap({{"foo", "bar"}}); decoder->decodeTrailers(std::move(trailers)); })); @@ -4207,12 +4212,13 @@ TEST_F(HttpConnectionManagerImplTest, FilterContinueAndEndStreamTrailers) { expectOnDestroy(); - decoder_filters_[1]->callbacks_->encodeHeaders(makeHeaderMap({{":status", "200"}}), false); + decoder_filters_[1]->callbacks_->encodeHeaders( + makeHeaderMap({{":status", "200"}}), false); Buffer::OwnedImpl response_body("response"); decoder_filters_[1]->callbacks_->encodeData(response_body, false); - auto response_trailers = makeHeaderMap({{"x-trailer", "1"}}); + auto response_trailers = makeHeaderMap({{"x-trailer", "1"}}); decoder_filters_[1]->callbacks_->encodeTrailers(std::move(response_trailers)); } @@ -4222,8 +4228,8 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyContinuation) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); })); @@ -4307,8 +4313,8 @@ TEST_F(HttpConnectionManagerImplTest, AddDataWithAllContinue) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); })); @@ -4409,8 +4415,8 @@ TEST_F(HttpConnectionManagerImplTest, AddDataWithStopAndContinue) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); })); @@ -4484,8 +4490,8 @@ TEST_F(HttpConnectionManagerImplTest, FilterDirectDecodeEncodeDataNoTrailers) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); @@ -4563,14 +4569,14 @@ TEST_F(HttpConnectionManagerImplTest, FilterDirectDecodeEncodeDataTrailers) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); decoder->decodeData(fake_data, false); - HeaderMapPtr trailers{new TestHeaderMapImpl{{"foo", "bar"}}}; + RequestTrailerMapPtr trailers{new TestRequestTrailerMapImpl{{"foo", "bar"}}}; decoder->decodeTrailers(std::move(trailers)); })); @@ -4657,8 +4663,8 @@ TEST_F(HttpConnectionManagerImplTest, MultipleFilters) { EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); Buffer::OwnedImpl fake_data("hello"); @@ -4768,8 +4774,8 @@ TEST_F(HttpConnectionManagerImplTest, NoNewStreamWhenOverloaded) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), false); })); @@ -4802,7 +4808,7 @@ TEST_F(HttpConnectionManagerImplTest, DisableKeepAliveWhenOverloaded) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{new TestHeaderMapImpl{ + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ {":authority", "host"}, {":path", "/"}, {":method", "GET"}, {"connection", "keep-alive"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -4921,7 +4927,7 @@ TEST_F(HttpConnectionManagerImplTest, DisableKeepAliveWhenDraining) { EXPECT_CALL(*codec_, dispatch(_)).WillRepeatedly(Invoke([&](Buffer::Instance& data) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{new TestHeaderMapImpl{ + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ {":authority", "host"}, {":path", "/"}, {":method", "GET"}, {"connection", "keep-alive"}}}; decoder->decodeHeaders(std::move(headers), true); @@ -4957,8 +4963,8 @@ TEST_F(HttpConnectionManagerImplTest, TestSessionTrace) { // Send headers to that stream, and verify we both set and clear the tracked object. { - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "POST"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "POST"}}}; EXPECT_CALL(filter_callbacks_.connection_.dispatcher_, setTrackedObject(_)) .Times(2) .WillOnce(Invoke([](const ScopeTrackedObject* object) -> const ScopeTrackedObject* { @@ -4980,7 +4986,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSessionTrace) { // Send trailers to that stream, and verify by this point headers are in logged state. { - HeaderMapPtr trailers{new TestHeaderMapImpl{{"foo", "bar"}}}; + RequestTrailerMapPtr trailers{new TestRequestTrailerMapImpl{{"foo", "bar"}}}; EXPECT_CALL(filter_callbacks_.connection_.dispatcher_, setTrackedObject(_)) .Times(2) .WillOnce(Invoke([](const ScopeTrackedObject* object) -> const ScopeTrackedObject* { @@ -5013,8 +5019,8 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsRouteNotFound) { .WillRepeatedly(Return(nullptr)); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":method", "GET"}, {":path", "/foo"}}}; + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ + {":authority", "host"}, {":method", "GET"}, {":path", "/foo"}}}; decoder->decodeHeaders(std::move(headers), true); data.drain(4); })); @@ -5043,8 +5049,8 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsUpdate) { .WillOnce(Return(route_config_)); // triggered by callbacks_->route(), SRDS now updated. EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":method", "GET"}, {":path", "/foo"}}}; + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ + {":authority", "host"}, {":method", "GET"}, {":path", "/foo"}}}; decoder->decodeHeaders(std::move(headers), true); data.drain(4); })); @@ -5098,7 +5104,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsCrossScopeReroute) { // 3. then refreshCachedRoute triggered by decoder_filters_[1]->callbacks_->route(). .Times(3) .WillRepeatedly(Invoke([&](const HeaderMap& headers) -> Router::ConfigConstSharedPtr { - auto& test_headers = static_cast(headers); + auto& test_headers = dynamic_cast(headers); if (test_headers.get_("scope_key") == "foo") { return route_config1; } @@ -5106,7 +5112,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsCrossScopeReroute) { })); EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{new TestHeaderMapImpl{ + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ {":authority", "host"}, {":method", "GET"}, {"scope_key", "foo"}, {":path", "/foo"}}}; decoder->decodeHeaders(std::move(headers), false); data.drain(4); @@ -5115,7 +5121,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsCrossScopeReroute) { EXPECT_CALL(*decoder_filters_[0], decodeHeaders(_, false)) .WillOnce(Invoke([&](Http::HeaderMap& headers, bool) -> FilterHeadersStatus { EXPECT_EQ(route1, decoder_filters_[0]->callbacks_->route()); - auto& test_headers = static_cast(headers); + auto& test_headers = dynamic_cast(headers); // Clear cached route and change scope key to "bar". decoder_filters_[0]->callbacks_->clearRouteCache(); test_headers.remove("scope_key"); @@ -5124,7 +5130,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsCrossScopeReroute) { })); EXPECT_CALL(*decoder_filters_[1], decodeHeaders(_, false)) .WillOnce(Invoke([&](Http::HeaderMap& headers, bool) -> FilterHeadersStatus { - auto& test_headers = static_cast(headers); + auto& test_headers = dynamic_cast(headers); EXPECT_EQ(test_headers.get_("scope_key"), "bar"); // Route now switched to route2 as header "scope_key" has changed. EXPECT_EQ(route2, decoder_filters_[1]->callbacks_->route()); @@ -5159,8 +5165,8 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsRouteFound) { RequestDecoder* decoder = nullptr; EXPECT_CALL(*codec_, dispatch(_)).WillOnce(Invoke([&](Buffer::Instance& data) -> void { decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":method", "GET"}, {":path", "/foo"}}}; + RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ + {":authority", "host"}, {":method", "GET"}, {":path", "/foo"}}}; decoder->decodeHeaders(std::move(headers), true); data.drain(4); })); @@ -5225,8 +5231,8 @@ TEST_F(HttpConnectionManagerImplTest, HeaderOnlyRequestAndResponseUsingHttp3) { // the filter. NiceMock encoder; RequestDecoder& decoder = conn_manager_->newStream(encoder); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder.decodeHeaders(std::move(headers), true); HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; @@ -5262,8 +5268,8 @@ TEST_F(HttpConnectionManagerImplTest, ConnectionFilterState) { EXPECT_CALL(*codec_, dispatch(_)).Times(2).WillRepeatedly(Invoke([&](Buffer::Instance&) -> void { RequestDecoder* decoder = &conn_manager_->newStream(response_encoder_); - HeaderMapPtr headers{ - new TestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; + RequestHeaderMapPtr headers{ + new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); })); { diff --git a/test/common/http/header_map_impl_fuzz_test.cc b/test/common/http/header_map_impl_fuzz_test.cc index fb952f600b..4bf7473a0e 100644 --- a/test/common/http/header_map_impl_fuzz_test.cc +++ b/test/common/http/header_map_impl_fuzz_test.cc @@ -136,8 +136,8 @@ DEFINE_PROTO_FUZZER(const test::common::http::HeaderMapImplFuzzTestCase& input) break; } case test::common::http::Action::kCopy: { - header_map = std::make_unique( - *reinterpret_cast(header_map.get())); + header_map = + std::make_unique(*static_cast(header_map.get())); break; } case test::common::http::Action::kLookup: { diff --git a/test/common/http/http1/codec_impl_test.cc b/test/common/http/http1/codec_impl_test.cc index 9f0fdde50e..88f8c9a1f4 100644 --- a/test/common/http/http1/codec_impl_test.cc +++ b/test/common/http/http1/codec_impl_test.cc @@ -753,9 +753,10 @@ TEST_F(Http1ServerConnectionImplTest, CloseDuringHeadersComplete) { MockRequestDecoder decoder; EXPECT_CALL(callbacks_, newStream(_, _)).WillOnce(ReturnRef(decoder)); - TestHeaderMapImpl expected_headers{{"content-length", "5"}, {":path", "/"}, {":method", "POST"}}; + TestRequestHeaderMapImpl expected_headers{ + {"content-length", "5"}, {":path", "/"}, {":method", "POST"}}; EXPECT_CALL(decoder, decodeHeaders_(HeaderMapEqual(&expected_headers), false)) - .WillOnce(Invoke([&](Http::HeaderMapPtr&, bool) -> void { + .WillOnce(Invoke([&](Http::RequestHeaderMapPtr&, bool) -> void { connection_.state_ = Network::Connection::State::Closing; })); EXPECT_CALL(decoder, decodeData(_, _)).Times(0); diff --git a/test/common/http/http1/conn_pool_legacy_test.cc b/test/common/http/http1/conn_pool_legacy_test.cc index 1e25075e74..89b9f4602f 100644 --- a/test/common/http/http1/conn_pool_legacy_test.cc +++ b/test/common/http/http1/conn_pool_legacy_test.cc @@ -187,8 +187,8 @@ struct ActiveTestRequest { void completeResponse(bool with_body) { // Test additional metric writes also. - Http::HeaderMapPtr response_headers( - new TestHeaderMapImpl{{":status", "200"}, {"x-envoy-upstream-canary", "true"}}); + Http::ResponseHeaderMapPtr response_headers( + new TestResponseHeaderMapImpl{{":status", "200"}, {"x-envoy-upstream-canary", "true"}}); inner_decoder_->decodeHeaders(std::move(response_headers), !with_body); if (with_body) { @@ -581,14 +581,14 @@ TEST_F(Http1ConnPoolImplLegacyTest, MaxConnections) { callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); - Http::HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); conn_pool_.expectAndRunUpstreamReady(); callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. - response_headers = std::make_unique( + response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); @@ -635,7 +635,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseWithoutHeader) { callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); - Http::HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); // Cause the connection to go away. @@ -654,7 +654,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseWithoutHeader) { callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. - response_headers = std::make_unique( + response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); @@ -689,8 +689,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseHeader) { // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); - Http::HeaderMapPtr response_headers( - new TestHeaderMapImpl{{":status", "200"}, {"Connection", "Close"}}); + Http::ResponseHeaderMapPtr response_headers( + new TestResponseHeaderMapImpl{{":status", "200"}, {"Connection", "Close"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); dispatcher_.clearDeferredDeleteList(); @@ -723,8 +723,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, ProxyConnectionCloseHeader) { // Response with 'proxy-connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); - Http::HeaderMapPtr response_headers( - new TestHeaderMapImpl{{":status", "200"}, {"Proxy-Connection", "Close"}}); + Http::ResponseHeaderMapPtr response_headers( + new TestResponseHeaderMapImpl{{":status", "200"}, {"Proxy-Connection", "Close"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); dispatcher_.clearDeferredDeleteList(); @@ -757,8 +757,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, Http10NoConnectionKeepAlive) { // Response without 'connection: keep-alive' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); - Http::HeaderMapPtr response_headers( - new TestHeaderMapImpl{{":protocol", "HTTP/1.0"}, {":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new TestResponseHeaderMapImpl{{":protocol", "HTTP/1.0"}, {":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); dispatcher_.clearDeferredDeleteList(); @@ -793,7 +793,7 @@ TEST_F(Http1ConnPoolImplLegacyTest, MaxRequestsPerConnection) { // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); - Http::HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); dispatcher_.clearDeferredDeleteList(); @@ -897,7 +897,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, RemoteCloseToCompleteResponse) { callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); - inner_decoder->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); + inner_decoder->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); Buffer::OwnedImpl dummy_data("12345"); inner_decoder->decodeData(dummy_data, false); diff --git a/test/common/http/http1/conn_pool_test.cc b/test/common/http/http1/conn_pool_test.cc index ddc8ddeb12..7c7f509809 100644 --- a/test/common/http/http1/conn_pool_test.cc +++ b/test/common/http/http1/conn_pool_test.cc @@ -186,8 +186,8 @@ struct ActiveTestRequest { void completeResponse(bool with_body) { // Test additional metric writes also. - Http::HeaderMapPtr response_headers( - new TestHeaderMapImpl{{":status", "200"}, {"x-envoy-upstream-canary", "true"}}); + Http::ResponseHeaderMapPtr response_headers( + new TestResponseHeaderMapImpl{{":status", "200"}, {"x-envoy-upstream-canary", "true"}}); inner_decoder_->decodeHeaders(std::move(response_headers), !with_body); if (with_body) { @@ -578,14 +578,14 @@ TEST_F(Http1ConnPoolImplTest, MaxConnections) { callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); - Http::HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); conn_pool_.expectAndRunUpstreamReady(); callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. - response_headers = std::make_unique( + response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); @@ -632,7 +632,7 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseWithoutHeader) { callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); - Http::HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); // Cause the connection to go away. @@ -651,7 +651,7 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseWithoutHeader) { callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. - response_headers = std::make_unique( + response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); @@ -686,8 +686,8 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseHeader) { // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); - Http::HeaderMapPtr response_headers( - new TestHeaderMapImpl{{":status", "200"}, {"Connection", "Close"}}); + ResponseHeaderMapPtr response_headers( + new TestResponseHeaderMapImpl{{":status", "200"}, {"Connection", "Close"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); dispatcher_.clearDeferredDeleteList(); @@ -720,8 +720,8 @@ TEST_F(Http1ConnPoolImplTest, ProxyConnectionCloseHeader) { // Response with 'proxy-connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); - Http::HeaderMapPtr response_headers( - new TestHeaderMapImpl{{":status", "200"}, {"Proxy-Connection", "Close"}}); + ResponseHeaderMapPtr response_headers( + new TestResponseHeaderMapImpl{{":status", "200"}, {"Proxy-Connection", "Close"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); dispatcher_.clearDeferredDeleteList(); @@ -754,8 +754,8 @@ TEST_F(Http1ConnPoolImplTest, Http10NoConnectionKeepAlive) { // Response without 'connection: keep-alive' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); - Http::HeaderMapPtr response_headers( - new TestHeaderMapImpl{{":protocol", "HTTP/1.0"}, {":status", "200"}}); + ResponseHeaderMapPtr response_headers( + new TestResponseHeaderMapImpl{{":protocol", "HTTP/1.0"}, {":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); dispatcher_.clearDeferredDeleteList(); @@ -790,7 +790,7 @@ TEST_F(Http1ConnPoolImplTest, MaxRequestsPerConnection) { // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); - Http::HeaderMapPtr response_headers(new TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); dispatcher_.clearDeferredDeleteList(); @@ -893,7 +893,8 @@ TEST_F(Http1ConnPoolImplTest, RemoteCloseToCompleteResponse) { callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); - inner_decoder->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); + inner_decoder->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); Buffer::OwnedImpl dummy_data("12345"); inner_decoder->decodeData(dummy_data, false); diff --git a/test/common/http/http2/conn_pool_legacy_test.cc b/test/common/http/http2/conn_pool_legacy_test.cc index 1521d5d9e6..b99cd98b74 100644 --- a/test/common/http/http2/conn_pool_legacy_test.cc +++ b/test/common/http/http2/conn_pool_legacy_test.cc @@ -191,7 +191,8 @@ void Http2ConnPoolImplLegacyTest::completeRequest(ActiveTestRequest& r) { r.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r.decoder_, decodeHeaders_(_, true)); - r.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); } void Http2ConnPoolImplLegacyTest::completeRequestCloseUpstream(size_t index, ActiveTestRequest& r) { @@ -400,7 +401,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, VerifyConnectionTimingStats) { r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -425,7 +427,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, VerifyBufferLimits) { r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -445,14 +448,16 @@ TEST_F(Http2ConnPoolImplLegacyTest, RequestAndResponse) { r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); ActiveTestRequest r2(*this, 0, true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -549,7 +554,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainDisconnectDrainingWithActiveRequest) { EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); @@ -586,14 +592,16 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainPrimary) { EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(drained, ready()); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); @@ -610,7 +618,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainPrimaryNoActiveRequest) { r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(dispatcher_, deferredDelete_(_)); expectClientCreate(); @@ -622,7 +631,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainPrimaryNoActiveRequest) { r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); ReadyWatcher drained; EXPECT_CALL(dispatcher_, deferredDelete_(_)); @@ -655,7 +665,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, ConnectTimeout) { r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); test_clients_[1].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -704,7 +715,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, GoAway) { r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].codec_client_->raiseGoAway(); @@ -715,7 +727,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, GoAway) { r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); test_clients_[1].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index f6de88d185..23fb0efc57 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -192,7 +192,8 @@ void Http2ConnPoolImplTest::completeRequest(ActiveTestRequest& r) { r.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r.decoder_, decodeHeaders_(_, true)); - r.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); } void Http2ConnPoolImplTest::completeRequestCloseUpstream(size_t index, ActiveTestRequest& r) { @@ -238,7 +239,8 @@ TEST_F(Http2ConnPoolImplTest, DrainConnectionReadyWithRequest) { EXPECT_CALL(r.decoder_, decodeHeaders_(_, true)); EXPECT_CALL(*this, onClientDestroy()); - r.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); } /** @@ -260,7 +262,8 @@ TEST_F(Http2ConnPoolImplTest, DrainConnectionBusy) { EXPECT_CALL(r.decoder_, decodeHeaders_(_, true)); EXPECT_CALL(*this, onClientDestroy()); - r.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); } /** @@ -613,7 +616,8 @@ TEST_F(Http2ConnPoolImplTest, VerifyConnectionTimingStats) { r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(cluster_->stats_store_, deliverHistogramToSinks(Property(&Stats::Metric::name, "upstream_cx_length_ms"), _)); @@ -638,7 +642,8 @@ TEST_F(Http2ConnPoolImplTest, VerifyBufferLimits) { r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -659,14 +664,16 @@ TEST_F(Http2ConnPoolImplTest, RequestAndResponse) { true); EXPECT_EQ(1U, cluster_->stats_.upstream_cx_active_.value()); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); ActiveTestRequest r2(*this, 0, true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -768,7 +775,8 @@ TEST_F(Http2ConnPoolImplTest, DrainDisconnectDrainingWithActiveRequest) { EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); @@ -807,14 +815,16 @@ TEST_F(Http2ConnPoolImplTest, DrainPrimary) { EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(drained, ready()); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); @@ -834,7 +844,8 @@ TEST_F(Http2ConnPoolImplTest, DrainPrimaryNoActiveRequest) { true); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); @@ -846,7 +857,8 @@ TEST_F(Http2ConnPoolImplTest, DrainPrimaryNoActiveRequest) { true); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); ReadyWatcher drained; EXPECT_CALL(drained, ready()); @@ -878,7 +890,8 @@ TEST_F(Http2ConnPoolImplTest, ConnectTimeout) { r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); test_clients_[1].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); EXPECT_CALL(*this, onClientDestroy()); @@ -927,7 +940,8 @@ TEST_F(Http2ConnPoolImplTest, GoAway) { r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); - r1.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r1.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); test_clients_[0].codec_client_->raiseGoAway(); @@ -938,7 +952,8 @@ TEST_F(Http2ConnPoolImplTest, GoAway) { r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); - r2.inner_decoder_->decodeHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + r2.inner_decoder_->decodeHeaders( + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); test_clients_[1].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); diff --git a/test/common/router/router_test.cc b/test/common/router/router_test.cc index fc02dbe2e5..036c66470c 100644 --- a/test/common/router/router_test.cc +++ b/test/common/router/router_test.cc @@ -278,8 +278,8 @@ class RouterTestBase : public testing::Test { NiceMock connection_; Http::ResponseDecoder* response_decoder_ = nullptr; Http::TestHeaderMapImpl default_request_headers_{}; - Http::HeaderMapPtr redirect_headers_{ - new Http::TestHeaderMapImpl{{":status", "302"}, {"location", "http://www.foo.com"}}}; + Http::ResponseHeaderMapPtr redirect_headers_{ + new Http::TestResponseHeaderMapImpl{{":status", "302"}, {"location", "http://www.foo.com"}}}; NiceMock span_; NiceMock upstream_stream_info_; }; @@ -565,7 +565,8 @@ TEST_F(RouterTest, AddCookie) { absl::string_view rc_details2 = "via_upstream"; EXPECT_CALL(callbacks_.stream_info_, setResponseCodeDetails(rc_details2)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder->decodeHeaders(std::move(response_headers), true); // When the router filter gets reset we should cancel the pool request. router_.onDestroy(); @@ -612,8 +613,8 @@ TEST_F(RouterTest, AddCookieNoDuplicate) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers( - new Http::TestHeaderMapImpl{{":status", "200"}, {"set-cookie", "foo=baz"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"set-cookie", "foo=baz"}}); response_decoder->decodeHeaders(std::move(response_headers), true); // When the router filter gets reset we should cancel the pool request. router_.onDestroy(); @@ -673,7 +674,8 @@ TEST_F(RouterTest, AddMultipleCookies) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder->decodeHeaders(std::move(response_headers), true); router_.onDestroy(); } @@ -824,7 +826,8 @@ TEST_F(RouterTest, ResponseCodeDetailsSetByUpstream) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); absl::string_view rc_details = StreamInfo::ResponseCodeDetails::get().ViaUpstream; EXPECT_CALL(callbacks_.stream_info_, setResponseCodeDetails(rc_details)); response_decoder->decodeHeaders(std::move(response_headers), true); @@ -850,7 +853,8 @@ TEST_F(RouterTest, EnvoyUpstreamServiceTime) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); EXPECT_CALL(callbacks_, encodeHeaders_(_, true)) .WillOnce(Invoke([](Http::HeaderMap& headers, bool) { @@ -890,7 +894,8 @@ void RouterTestBase::testAppendCluster(absl::optional clu HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); EXPECT_CALL(callbacks_, encodeHeaders_(_, true)) .WillOnce(Invoke([&cluster_header_name](Http::HeaderMap& headers, bool) { @@ -944,7 +949,8 @@ void RouterTestBase::testAppendUpstreamHost( HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); EXPECT_CALL(callbacks_, encodeHeaders_(_, true)) .WillOnce(Invoke([&hostname_header_name, &host_address_header_name](Http::HeaderMap& headers, @@ -1068,7 +1074,8 @@ TEST_F(RouterTestSuppressEnvoyHeaders, EnvoyUpstreamServiceTime) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); Http::TestHeaderMapImpl downstream_response_headers{{":status", "200"}, {"x-envoy-upstream-service-time", "0"}}; @@ -1099,7 +1106,8 @@ TEST_F(RouterTest, NoRetriesOverflow) { // 5xx response. router_.retry_state_->expectHeadersRetry(); - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); response_decoder->decodeHeaders(std::move(response_headers1), true); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -1122,7 +1130,8 @@ TEST_F(RouterTest, NoRetriesOverflow) { EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)) .WillOnce(Return(RetryStatus::NoOverflow)); EXPECT_CALL(cm_.conn_pool_.host_->health_checker_, setUnhealthy()).Times(0); - Http::HeaderMapPtr response_headers2(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr response_headers2( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); response_decoder->decodeHeaders(std::move(response_headers2), true); EXPECT_TRUE(verifyHostUpstreamStats(0, 2)); @@ -1236,7 +1245,8 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStat) { Property(&Stats::Metric::name, "upstream_rq_timeout_budget_per_try_percent_used"), 40ull)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder->decodeHeaders(std::move(response_headers), false); test_time_.sleep(std::chrono::milliseconds(80)); response_decoder->decodeData(data, true); @@ -1276,7 +1286,8 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatFailure) { Property(&Stats::Metric::name, "upstream_rq_timeout_budget_per_try_percent_used"), 40ull)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "500"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "500"}}); response_decoder->decodeHeaders(std::move(response_headers), false); test_time_.sleep(std::chrono::milliseconds(80)); response_decoder->decodeData(data, true); @@ -1313,7 +1324,8 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatOnlyGlobal) { deliverHistogramToSinks( Property(&Stats::Metric::name, "upstream_rq_timeout_budget_per_try_percent_used"), 0ull)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder->decodeHeaders(std::move(response_headers), false); test_time_.sleep(std::chrono::milliseconds(80)); response_decoder->decodeData(data, true); @@ -1356,7 +1368,8 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringRetries) { // Per-try timeout. test_time_.sleep(std::chrono::milliseconds(100)); router_.retry_state_->expectHeadersRetry(); - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "504"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "504"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(504)); response_decoder1->decodeHeaders(std::move(response_headers1), true); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -1445,7 +1458,8 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringGlobalTimeout) { // 5xx response. router_.retry_state_->expectHeadersRetry(); - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); test_time_.sleep(std::chrono::milliseconds(160)); response_decoder1->decodeHeaders(std::move(response_headers1), true); @@ -1517,8 +1531,8 @@ TEST_F(RouterTest, GrpcOkTrailersOnly) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers( - new Http::TestHeaderMapImpl{{":status", "200"}, {"grpc-status", "0"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "0"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 0)); @@ -1542,8 +1556,8 @@ TEST_F(RouterTest, GrpcAlreadyExistsTrailersOnly) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers( - new Http::TestHeaderMapImpl{{":status", "200"}, {"grpc-status", "6"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "6"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(409)); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 0)); @@ -1567,8 +1581,8 @@ TEST_F(RouterTest, GrpcOutlierDetectionUnavailableStatusCode) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers( - new Http::TestHeaderMapImpl{{":status", "200"}, {"grpc-status", "14"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "14"}}); // Outlier detector will use the gRPC response status code. EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); response_decoder->decodeHeaders(std::move(response_headers), true); @@ -1593,8 +1607,8 @@ TEST_F(RouterTest, GrpcInternalTrailersOnly) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers( - new Http::TestHeaderMapImpl{{":status", "200"}, {"grpc-status", "13"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "13"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(500)); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -1619,7 +1633,8 @@ TEST_F(RouterTest, GrpcDataEndStream) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), false); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -1647,7 +1662,8 @@ TEST_F(RouterTest, GrpcReset) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), false); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -1677,13 +1693,15 @@ TEST_F(RouterTest, GrpcOk) { router_.decodeHeaders(headers, true); EXPECT_CALL(callbacks_.dispatcher_, setTrackedObject(_)).Times(2); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), false); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); EXPECT_CALL(callbacks_.dispatcher_, setTrackedObject(_)).Times(2); - Http::HeaderMapPtr response_trailers(new Http::TestHeaderMapImpl{{"grpc-status", "0"}}); + Http::ResponseTrailerMapPtr response_trailers( + new Http::TestResponseTrailerMapImpl{{"grpc-status", "0"}}); response_decoder->decodeTrailers(std::move(response_trailers)); EXPECT_TRUE(verifyHostUpstreamStats(1, 0)); } @@ -1706,11 +1724,13 @@ TEST_F(RouterTest, GrpcInternal) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), false); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); - Http::HeaderMapPtr response_trailers(new Http::TestHeaderMapImpl{{"grpc-status", "13"}}); + Http::ResponseTrailerMapPtr response_trailers( + new Http::TestResponseTrailerMapImpl{{"grpc-status", "13"}}); response_decoder->decodeTrailers(std::move(response_trailers)); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); } @@ -1970,7 +1990,8 @@ TEST_F(RouterTest, HedgedPerTryTimeoutFirstRequestSucceeds) { // Now write a 200 back. We expect the 2nd stream to be reset and stats to be // incremented properly. - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); EXPECT_CALL(encoder2.stream_, resetStream(_)); @@ -2045,7 +2066,8 @@ TEST_F(RouterTest, HedgedPerTryTimeoutResetsOnBadHeaders) { // Now write a 5xx back on the 2nd request with no retries remaining. The 2nd request // should be reset immediately. - Http::HeaderMapPtr bad_response_headers(new Http::TestHeaderMapImpl{{":status", "500"}}); + Http::ResponseHeaderMapPtr bad_response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "500"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(500)); EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); EXPECT_CALL(encoder2.stream_, resetStream(_)); @@ -2056,7 +2078,8 @@ TEST_F(RouterTest, HedgedPerTryTimeoutResetsOnBadHeaders) { // Now write a 200 back. We expect the 2nd stream to be reset and stats to be // incremented properly. - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); @@ -2096,7 +2119,8 @@ TEST_F(RouterTest, HedgedPerTryTimeoutThirdRequestSucceeds) { EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "500"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "500"}}); // Local origin connect success happens for first and third try. EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess, @@ -2149,7 +2173,8 @@ TEST_F(RouterTest, HedgedPerTryTimeoutThirdRequestSucceeds) { // Now write a 200 back. We expect the 2nd stream to be reset and stats to be // incremented properly. - Http::HeaderMapPtr response_headers2(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers2( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); EXPECT_CALL(encoder1.stream_, resetStream(_)).Times(0); EXPECT_CALL(encoder2.stream_, resetStream(_)); @@ -2218,7 +2243,8 @@ TEST_F(RouterTest, RetryOnlyOnceForSameUpstreamRequest) { router_.retry_state_->callback_(); // Now send a 5xx back and make sure we don't ask whether we should retry it. - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "500"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "500"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(500)); EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).Times(0); EXPECT_CALL(*router_.retry_state_, wouldRetryFromHeaders(_)).WillOnce(Return(true)); @@ -2272,7 +2298,8 @@ TEST_F(RouterTest, BadHeadersDroppedIfPreviousRetryScheduled) { // Now send a 5xx back and make sure we don't ask whether we should retry it // and also that we don't respond downstream with it. - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "500"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "500"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(500)); EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).Times(0); EXPECT_CALL(*router_.retry_state_, wouldRetryFromHeaders(_)).WillOnce(Return(true)); @@ -2293,7 +2320,8 @@ TEST_F(RouterTest, BadHeadersDroppedIfPreviousRetryScheduled) { })); router_.retry_state_->callback_(); - Http::HeaderMapPtr response_headers2(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers2( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); EXPECT_CALL(callbacks_, encodeHeaders_(_, _)) .WillOnce(Invoke([&](Http::HeaderMap& headers, bool end_stream) -> void { @@ -2458,7 +2486,8 @@ TEST_F(RouterTest, HedgingRetriesExhaustedBadResponse) { EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); // Now trigger a 503 in response to the second request. - Http::HeaderMapPtr bad_response_headers1(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr bad_response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)) @@ -2468,7 +2497,8 @@ TEST_F(RouterTest, HedgingRetriesExhaustedBadResponse) { EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Now trigger a 502 in response to the first request. - Http::HeaderMapPtr bad_response_headers2(new Http::TestHeaderMapImpl{{":status", "502"}}); + Http::ResponseHeaderMapPtr bad_response_headers2( + new Http::TestResponseHeaderMapImpl{{":status", "502"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(502)); // We should not call shouldRetryHeaders() because you never retry the same @@ -2550,7 +2580,8 @@ TEST_F(RouterTest, HedgingRetriesProceedAfterReset) { EXPECT_CALL(*router_.retry_state_, shouldRetryReset(_, _)).Times(0); // Now trigger a 200 in response to the second request. - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); EXPECT_CALL(callbacks_, encodeHeaders_(_, _)) @@ -2624,7 +2655,8 @@ TEST_F(RouterTest, HedgingRetryImmediatelyReset) { EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); // Now trigger a 200 in response to the first request. - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); // The request was already retried when the per try timeout occurred so it // should't even consult the retry state. @@ -2721,7 +2753,8 @@ TEST_F(RouterTest, RetryUpstreamReset) { // Normal response. EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 1)); @@ -2750,7 +2783,8 @@ TEST_F(RouterTest, NoRetryWithBodyLimit) { Buffer::OwnedImpl body("t"); router_.decodeData(body, false); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder->decodeHeaders(std::move(response_headers), true); } @@ -2803,7 +2837,8 @@ TEST_F(RouterTest, RetryUpstreamPerTryTimeout) { // Normal response. EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 1)); @@ -2848,7 +2883,8 @@ TEST_F(RouterTest, RetryUpstreamConnectionFailure) { // Normal response. EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 0)); @@ -2876,7 +2912,8 @@ TEST_F(RouterTest, DontResetStartedResponseOnUpstreamPerTryTimeout) { // Since the response is already started we don't retry. EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); EXPECT_CALL(callbacks_, encodeHeaders_(_, false)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); Buffer::OwnedImpl body("test body"); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), false); @@ -2909,7 +2946,8 @@ TEST_F(RouterTest, RetryUpstreamResetResponseStarted) { // Since the response is already started we don't retry. EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); EXPECT_CALL(callbacks_, encodeHeaders_(_, false)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), false); absl::string_view rc_details2 = "upstream_reset_after_response_started{remote reset}"; @@ -2944,7 +2982,8 @@ TEST_F(RouterTest, RetryUpstreamReset100ContinueResponseStarted) { EXPECT_CALL(*router_.retry_state_, shouldRetryReset(_, _)).Times(0); EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).Times(0); EXPECT_CALL(callbacks_, encode100ContinueHeaders_(_)); - Http::HeaderMapPtr continue_headers(new Http::TestHeaderMapImpl{{":status", "100"}}); + Http::ResponseHeaderMapPtr continue_headers( + new Http::TestResponseHeaderMapImpl{{":status", "100"}}); response_decoder->decode100ContinueHeaders(std::move(continue_headers)); EXPECT_EQ( 1U, @@ -2973,7 +3012,8 @@ TEST_F(RouterTest, RetryUpstream5xx) { // 5xx response. router_.retry_state_->expectHeadersRetry(); - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); response_decoder->decodeHeaders(std::move(response_headers1), true); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -2994,7 +3034,8 @@ TEST_F(RouterTest, RetryUpstream5xx) { // Normal response. EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); EXPECT_CALL(cm_.conn_pool_.host_->health_checker_, setUnhealthy()).Times(0); - Http::HeaderMapPtr response_headers2(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers2( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers2), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 1)); @@ -3019,7 +3060,8 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelay) { // 5xx response. router_.retry_state_->expectHeadersRetry(); - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); response_decoder->decodeHeaders(std::move(response_headers1), true); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -3056,7 +3098,8 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHost) { // 5xx response. router_.retry_state_->expectHeadersRetry(); - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); response_decoder->decodeHeaders(std::move(response_headers1), true); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -3106,7 +3149,8 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHostAltRespo // 5xx response. router_.retry_state_->expectHeadersRetry(); - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); response_decoder->decodeHeaders(std::move(response_headers1), true); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -3159,7 +3203,8 @@ TEST_F(RouterTest, RetryUpstream5xxNotComplete) { // 5xx response. router_.retry_state_->expectHeadersRetry(); - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(encoder1.stream_, resetStream(Http::StreamResetReason::LocalReset)); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); response_decoder->decodeHeaders(std::move(response_headers1), false); @@ -3186,7 +3231,7 @@ TEST_F(RouterTest, RetryUpstream5xxNotComplete) { EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResponseTime(_)); EXPECT_CALL(cm_.conn_pool_.host_->health_checker_, setUnhealthy()); - Http::HeaderMapPtr response_headers2(new Http::TestHeaderMapImpl{ + Http::ResponseHeaderMapPtr response_headers2(new Http::TestResponseHeaderMapImpl{ {":status", "200"}, {"x-envoy-immediate-health-check-fail", "true"}}); response_decoder->decodeHeaders(std::move(response_headers2), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 1)); @@ -3228,8 +3273,8 @@ TEST_F(RouterTest, RetryUpstreamGrpcCancelled) { // gRPC with status "cancelled" (1) router_.retry_state_->expectHeadersRetry(); - Http::HeaderMapPtr response_headers1( - new Http::TestHeaderMapImpl{{":status", "200"}, {"grpc-status", "1"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "1"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(499)); response_decoder->decodeHeaders(std::move(response_headers1), true); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -3249,8 +3294,8 @@ TEST_F(RouterTest, RetryUpstreamGrpcCancelled) { // Normal response. EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); - Http::HeaderMapPtr response_headers( - new Http::TestHeaderMapImpl{{":status", "200"}, {"grpc-status", "0"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "0"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 1)); @@ -3291,7 +3336,8 @@ TEST_F(RouterTest, RetryRespsectsMaxHostSelectionCount) { // 5xx response. router_.retry_state_->expectHeadersRetry(); - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(encoder1.stream_, resetStream(Http::StreamResetReason::LocalReset)); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); response_decoder->decodeHeaders(std::move(response_headers1), false); @@ -3319,7 +3365,8 @@ TEST_F(RouterTest, RetryRespsectsMaxHostSelectionCount) { // Normal response. EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); EXPECT_CALL(cm_.conn_pool_.host_->health_checker_, setUnhealthy()).Times(0); - Http::HeaderMapPtr response_headers2(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers2( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers2), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 1)); @@ -3360,7 +3407,8 @@ TEST_F(RouterTest, RetryRespectsRetryHostPredicate) { // 5xx response. router_.retry_state_->expectHeadersRetry(); - Http::HeaderMapPtr response_headers1(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr response_headers1( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); EXPECT_CALL(encoder1.stream_, resetStream(Http::StreamResetReason::LocalReset)); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(503)); response_decoder->decodeHeaders(std::move(response_headers1), false); @@ -3388,7 +3436,8 @@ TEST_F(RouterTest, RetryRespectsRetryHostPredicate) { // Normal response. EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); EXPECT_CALL(cm_.conn_pool_.host_->health_checker_, setUnhealthy()).Times(0); - Http::HeaderMapPtr response_headers2(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers2( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers2), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 1)); @@ -3582,7 +3631,8 @@ TEST_F(RouterTest, Shadow) { })); router_.decodeTrailers(trailers); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 0)); } @@ -3612,10 +3662,10 @@ TEST_F(RouterTest, AltStatName) { EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResponseTime(_)); - Http::HeaderMapPtr response_headers( - new Http::TestHeaderMapImpl{{":status", "200"}, - {"x-envoy-upstream-canary", "true"}, - {"x-envoy-virtual-cluster", "hello"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"x-envoy-upstream-canary", "true"}, + {"x-envoy-virtual-cluster", "hello"}}); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 0)); @@ -3785,7 +3835,8 @@ TEST_F(RouterTest, UpstreamSSLConnection) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 0)); @@ -3823,7 +3874,8 @@ TEST_F(RouterTest, UpstreamTimingSingleRequest) { Buffer::OwnedImpl data; router_.decodeData(data, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); response_decoder->decodeHeaders(std::move(response_headers), false); test_time_.sleep(std::chrono::milliseconds(43)); @@ -3892,7 +3944,8 @@ TEST_F(RouterTest, UpstreamTimingRetry) { })); // Check that upstream timing is not set when a retry will occur. - Http::HeaderMapPtr bad_response_headers(new Http::TestHeaderMapImpl{{":status", "503"}}); + Http::ResponseHeaderMapPtr bad_response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "503"}}); response_decoder->decodeHeaders(std::move(bad_response_headers), true); EXPECT_FALSE(stream_info.firstUpstreamTxByteSent().has_value()); EXPECT_FALSE(stream_info.lastUpstreamTxByteSent().has_value()); @@ -3903,7 +3956,8 @@ TEST_F(RouterTest, UpstreamTimingRetry) { EXPECT_CALL(*router_.retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); MonotonicTime retry_time = test_time_.monotonicTime(); - Http::HeaderMapPtr good_response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr good_response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder->decodeHeaders(std::move(good_response_headers), false); test_time_.sleep(std::chrono::milliseconds(153)); @@ -3965,7 +4019,8 @@ TEST_F(RouterTest, UpstreamTimingTimeout) { test_time_.sleep(std::chrono::milliseconds(33)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder->decodeHeaders(std::move(response_headers), false); test_time_.sleep(std::chrono::milliseconds(99)); @@ -4496,10 +4551,10 @@ TEST_F(RouterTest, CanaryStatusTrue) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers( - new Http::TestHeaderMapImpl{{":status", "200"}, - {"x-envoy-upstream-canary", "false"}, - {"x-envoy-virtual-cluster", "hello"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"x-envoy-upstream-canary", "false"}, + {"x-envoy-virtual-cluster", "hello"}}); ON_CALL(*cm_.conn_pool_.host_, canary()).WillByDefault(Return(true)); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 0)); @@ -4530,10 +4585,10 @@ TEST_F(RouterTest, CanaryStatusFalse) { HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers( - new Http::TestHeaderMapImpl{{":status", "200"}, - {"x-envoy-upstream-canary", "false"}, - {"x-envoy-virtual-cluster", "hello"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"x-envoy-upstream-canary", "false"}, + {"x-envoy-virtual-cluster", "hello"}}); response_decoder->decodeHeaders(std::move(response_headers), true); EXPECT_TRUE(verifyHostUpstreamStats(1, 0)); @@ -4695,7 +4750,7 @@ class WatermarkTest : public RouterTest { } void sendResponse() { response_decoder_->decodeHeaders( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}}, true); + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}}, true); } NiceMock encoder_; @@ -4725,7 +4780,7 @@ TEST_F(WatermarkTest, UpstreamWatermarks) { sendRequest(false); response_decoder_->decodeHeaders( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}}, false); + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}}, false); ASSERT(callbacks_.callbacks_.begin() != callbacks_.callbacks_.end()); Envoy::Http::DownstreamWatermarkCallbacks* watermark_callbacks = *callbacks_.callbacks_.begin(); @@ -4856,7 +4911,8 @@ TEST_F(RouterTestChildSpan, BasicFlow) { EXPECT_CALL(callbacks_, tracingConfig()); router_.decodeHeaders(headers, true); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(*child_span, setTag(Eq(Tracing::Tags::get().Component), Eq(Tracing::Tags::get().Proxy))); EXPECT_CALL(*child_span, setTag(Eq(Tracing::Tags::get().HttpProtocol), Eq("HTTP/1.0"))); @@ -4897,7 +4953,8 @@ TEST_F(RouterTestChildSpan, ResetFlow) { router_.decodeHeaders(headers, true); // Upstream responds back to envoy. - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); response_decoder->decodeHeaders(std::move(response_headers), false); // The reset occurs after the upstream response, so the span has a valid status code but also an @@ -5020,7 +5077,8 @@ TEST_F(RouterTestChildSpan, ResetRetryFlow) { router_.retry_state_->callback_(); // Upstream responds back with a normal response. Span should be annotated as usual. - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(*child_span_2, setTag(Eq(Tracing::Tags::get().Component), Eq(Tracing::Tags::get().Proxy))); EXPECT_CALL(*child_span_2, setTag(Eq(Tracing::Tags::get().HttpProtocol), Eq("HTTP/1.0"))); diff --git a/test/common/router/router_upstream_log_test.cc b/test/common/router/router_upstream_log_test.cc index 0e2fa80922..8e57dae134 100644 --- a/test/common/router/router_upstream_log_test.cc +++ b/test/common/router/router_upstream_log_test.cc @@ -147,14 +147,16 @@ class RouterUpstreamLogTest : public testing::Test { EXPECT_CALL(*router_->retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl(response_headers_init)); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl(response_headers_init)); response_headers->setStatus(response_code); EXPECT_CALL(context_.cluster_manager_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(response_code)); response_decoder->decodeHeaders(std::move(response_headers), false); - Http::HeaderMapPtr response_trailers(new Http::TestHeaderMapImpl(response_trailers_init)); + Http::ResponseTrailerMapPtr response_trailers( + new Http::TestResponseTrailerMapImpl(response_trailers_init)); response_decoder->decodeTrailers(std::move(response_trailers)); } @@ -209,7 +211,8 @@ class RouterUpstreamLogTest : public testing::Test { // Normal response. EXPECT_CALL(*router_->retry_state_, shouldRetryHeaders(_, _)).WillOnce(Return(RetryStatus::No)); - Http::HeaderMapPtr response_headers(new Http::TestHeaderMapImpl{{":status", "200"}}); + Http::ResponseHeaderMapPtr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); EXPECT_CALL(context_.cluster_manager_.conn_pool_.host_->outlier_detector_, putHttpResponseCode(200)); response_decoder->decodeHeaders(std::move(response_headers), true); diff --git a/test/common/upstream/health_checker_impl_test.cc b/test/common/upstream/health_checker_impl_test.cc index 0ea1169811..4bf9c2019c 100644 --- a/test/common/upstream/health_checker_impl_test.cc +++ b/test/common/upstream/health_checker_impl_test.cc @@ -613,8 +613,8 @@ class HttpHealthCheckerImplTest : public testing::Test { bool body = false, bool trailers = false, const absl::optional& service_cluster = absl::optional(), bool degraded = false) { - std::unique_ptr response_headers( - new Http::TestHeaderMapImpl{{":status", code}}); + std::unique_ptr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", code}}); if (degraded) { response_headers->setEnvoyDegraded(1); @@ -640,7 +640,7 @@ class HttpHealthCheckerImplTest : public testing::Test { if (trailers) { test_sessions_[index]->stream_response_callbacks_->decodeTrailers( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{"some", "trailer"}}}); + Http::ResponseTrailerMapPtr{new Http::TestResponseTrailerMapImpl{{"some", "trailer"}}}); } } @@ -904,8 +904,8 @@ TEST_F(HttpHealthCheckerImplTest, SuccessWithSpurious100Continue) { enableTimer(std::chrono::milliseconds(45000), _)); EXPECT_CALL(*test_sessions_[0]->timeout_timer_, disableTimer()); - std::unique_ptr continue_headers( - new Http::TestHeaderMapImpl{{":status", "100"}}); + std::unique_ptr continue_headers( + new Http::TestResponseHeaderMapImpl{{":status", "100"}}); test_sessions_[0]->stream_response_callbacks_->decode100ContinueHeaders( std::move(continue_headers)); @@ -1834,8 +1834,8 @@ TEST_F(HttpHealthCheckerImplTest, TimeoutThenSuccess) { health_checker_->start(); // Do a response that is not complete but includes headers. - std::unique_ptr response_headers( - new Http::TestHeaderMapImpl{{":status", "200"}}); + std::unique_ptr response_headers( + new Http::TestResponseHeaderMapImpl{{":status", "200"}}); test_sessions_[0]->stream_response_callbacks_->decodeHeaders(std::move(response_headers), false); EXPECT_CALL(*this, onHostStatus(_, HealthTransition::ChangePending)); @@ -3629,7 +3629,7 @@ class GrpcHealthCheckerImplTestBase { void respondResponseSpec(size_t index, ResponseSpec&& spec) { const bool trailers_empty = spec.trailers.empty(); const bool end_stream_on_headers = spec.body_chunks.empty() && trailers_empty; - auto response_headers = std::make_unique(); + auto response_headers = std::make_unique(); for (const auto& header : spec.response_headers) { response_headers->addCopy(header.first, header.second); } @@ -3647,7 +3647,7 @@ class GrpcHealthCheckerImplTestBase { } } if (!trailers_empty) { - auto trailers = std::make_unique(); + auto trailers = std::make_unique(); for (const auto& header : spec.trailers) { trailers->addCopy(header.first, header.second); } @@ -3738,7 +3738,7 @@ TEST_F(GrpcHealthCheckerImplTest, SuccessResponseSplitBetweenChunks) { setupServiceNameHC(absl::nullopt); expectSingleHealthcheck(HealthTransition::Unchanged); - auto response_headers = std::make_unique( + auto response_headers = std::make_unique( std::initializer_list>{ {":status", "200"}, {"content-type", "application/grpc"}, @@ -3757,7 +3757,7 @@ TEST_F(GrpcHealthCheckerImplTest, SuccessResponseSplitBetweenChunks) { test_sessions_[0]->stream_response_callbacks_->decodeData(*chunk, false); } - auto trailers = std::make_unique( + auto trailers = std::make_unique( std::initializer_list>{{"grpc-status", "0"}}); test_sessions_[0]->stream_response_callbacks_->decodeTrailers(std::move(trailers)); diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc index 463ca86cf2..91d9f62ab2 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc @@ -188,7 +188,7 @@ TEST_P(EnvoyQuicClientSessionTest, NewStream) { headers.OnHeaderBlockEnd(/*uncompressed_header_bytes=*/0, /*compressed_header_bytes=*/0); // Response headers should be propagated to decoder. EXPECT_CALL(response_decoder, decodeHeaders_(_, /*end_stream=*/true)) - .WillOnce(Invoke([](const Http::HeaderMapPtr& decoded_headers, bool) { + .WillOnce(Invoke([](const Http::ResponseHeaderMapPtr& decoded_headers, bool) { EXPECT_EQ("200", decoded_headers->Status()->value().getStringView()); })); stream.OnStreamHeaderList(/*fin=*/true, headers.uncompressed_header_bytes(), headers); diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc index 308147e78c..78975aa7a7 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc @@ -114,7 +114,7 @@ TEST_P(EnvoyQuicClientStreamTest, PostRequestAndResponse) { quic_stream_->encodeData(request_body_, true); EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/false)) - .WillOnce(Invoke([](const Http::HeaderMapPtr& headers, bool) { + .WillOnce(Invoke([](const Http::ResponseHeaderMapPtr& headers, bool) { EXPECT_EQ("200", headers->Status()->value().getStringView()); })); quic_stream_->OnStreamHeaderList(/*fin=*/false, response_headers_.uncompressed_header_bytes(), @@ -145,7 +145,7 @@ TEST_P(EnvoyQuicClientStreamTest, PostRequestAndResponse) { quic_stream_->OnStreamFrame(frame); EXPECT_CALL(stream_decoder_, decodeTrailers_(_)) - .WillOnce(Invoke([](const Http::HeaderMapPtr& headers) { + .WillOnce(Invoke([](const Http::ResponseTrailerMapPtr& headers) { Http::LowerCaseString key1("key1"); Http::LowerCaseString key2(":final-offset"); EXPECT_EQ("value1", headers->get(key1)->value().getStringView()); @@ -161,7 +161,7 @@ TEST_P(EnvoyQuicClientStreamTest, OutOfOrderTrailers) { } quic_stream_->encodeHeaders(request_headers_, true); EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/false)) - .WillOnce(Invoke([](const Http::HeaderMapPtr& headers, bool) { + .WillOnce(Invoke([](const Http::ResponseHeaderMapPtr& headers, bool) { EXPECT_EQ("200", headers->Status()->value().getStringView()); })); quic_stream_->OnStreamHeaderList(/*fin=*/false, response_headers_.uncompressed_header_bytes(), @@ -194,7 +194,7 @@ TEST_P(EnvoyQuicClientStreamTest, OutOfOrderTrailers) { })); EXPECT_CALL(stream_decoder_, decodeTrailers_(_)) - .WillOnce(Invoke([](const Http::HeaderMapPtr& headers) { + .WillOnce(Invoke([](const Http::ResponseTrailerMapPtr& headers) { Http::LowerCaseString key1("key1"); Http::LowerCaseString key2(":final-offset"); EXPECT_EQ("value1", headers->get(key1)->value().getStringView()); diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc index ee7e0d4414..618967c5b1 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc @@ -229,7 +229,7 @@ TEST_P(EnvoyQuicServerSessionTest, NewStream) { headers.OnHeaderBlockEnd(/*uncompressed_header_bytes=*/0, /*compressed_header_bytes=*/0); // Request headers should be propagated to decoder. EXPECT_CALL(request_decoder, decodeHeaders_(_, /*end_stream=*/true)) - .WillOnce(Invoke([&host](const Http::HeaderMapPtr& decoded_headers, bool) { + .WillOnce(Invoke([&host](const Http::RequestHeaderMapPtr& decoded_headers, bool) { EXPECT_EQ(host, decoded_headers->Host()->value().getStringView()); EXPECT_EQ("/", decoded_headers->Path()->value().getStringView()); EXPECT_EQ(Http::Headers::get().MethodValues.Get, @@ -419,7 +419,7 @@ TEST_P(EnvoyQuicServerSessionTest, WriteUpdatesDelayCloseTimer) { request_headers.OnHeaderBlockEnd(/*uncompressed_header_bytes=*/0, /*compressed_header_bytes=*/0); // Request headers should be propagated to decoder. EXPECT_CALL(request_decoder, decodeHeaders_(_, /*end_stream=*/true)) - .WillOnce(Invoke([&host](const Http::HeaderMapPtr& decoded_headers, bool) { + .WillOnce(Invoke([&host](const Http::RequestHeaderMapPtr& decoded_headers, bool) { EXPECT_EQ(host, decoded_headers->Host()->value().getStringView()); EXPECT_EQ("/", decoded_headers->Path()->value().getStringView()); EXPECT_EQ(Http::Headers::get().MethodValues.Get, @@ -514,7 +514,7 @@ TEST_P(EnvoyQuicServerSessionTest, FlushCloseNoTimeout) { request_headers.OnHeaderBlockEnd(/*uncompressed_header_bytes=*/0, /*compressed_header_bytes=*/0); // Request headers should be propagated to decoder. EXPECT_CALL(request_decoder, decodeHeaders_(_, /*end_stream=*/true)) - .WillOnce(Invoke([&host](const Http::HeaderMapPtr& decoded_headers, bool) { + .WillOnce(Invoke([&host](const Http::RequestHeaderMapPtr& decoded_headers, bool) { EXPECT_EQ(host, decoded_headers->Host()->value().getStringView()); EXPECT_EQ("/", decoded_headers->Path()->value().getStringView()); EXPECT_EQ(Http::Headers::get().MethodValues.Get, @@ -811,7 +811,7 @@ TEST_P(EnvoyQuicServerSessionTest, SendBufferWatermark) { request_headers.OnHeaderBlockEnd(/*uncompressed_header_bytes=*/0, /*compressed_header_bytes=*/0); // Request headers should be propagated to decoder. EXPECT_CALL(request_decoder, decodeHeaders_(_, /*end_stream=*/true)) - .WillOnce(Invoke([&host](const Http::HeaderMapPtr& decoded_headers, bool) { + .WillOnce(Invoke([&host](const Http::RequestHeaderMapPtr& decoded_headers, bool) { EXPECT_EQ(host, decoded_headers->Host()->value().getStringView()); EXPECT_EQ("/", decoded_headers->Path()->value().getStringView()); EXPECT_EQ(Http::Headers::get().MethodValues.Get, @@ -844,7 +844,7 @@ TEST_P(EnvoyQuicServerSessionTest, SendBufferWatermark) { auto stream2 = dynamic_cast(envoy_quic_session_.GetOrCreateStream(stream_id + 4)); EXPECT_CALL(request_decoder2, decodeHeaders_(_, /*end_stream=*/true)) - .WillOnce(Invoke([&host](const Http::HeaderMapPtr& decoded_headers, bool) { + .WillOnce(Invoke([&host](const Http::RequestHeaderMapPtr& decoded_headers, bool) { EXPECT_EQ(host, decoded_headers->Host()->value().getStringView()); EXPECT_EQ("/", decoded_headers->Path()->value().getStringView()); EXPECT_EQ(Http::Headers::get().MethodValues.Get, @@ -876,7 +876,7 @@ TEST_P(EnvoyQuicServerSessionTest, SendBufferWatermark) { auto stream3 = dynamic_cast(envoy_quic_session_.GetOrCreateStream(stream_id + 8)); EXPECT_CALL(request_decoder3, decodeHeaders_(_, /*end_stream=*/true)) - .WillOnce(Invoke([&host](const Http::HeaderMapPtr& decoded_headers, bool) { + .WillOnce(Invoke([&host](const Http::RequestHeaderMapPtr& decoded_headers, bool) { EXPECT_EQ(host, decoded_headers->Host()->value().getStringView()); EXPECT_EQ("/", decoded_headers->Path()->value().getStringView()); EXPECT_EQ(Http::Headers::get().MethodValues.Get, diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc index 46eeefa6b5..b58dada95f 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc @@ -100,7 +100,7 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { size_t sendRequest(const std::string& payload, bool fin, size_t decoder_buffer_high_watermark) { EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/false)) - .WillOnce(Invoke([this](const Http::HeaderMapPtr& headers, bool) { + .WillOnce(Invoke([this](const Http::RequestHeaderMapPtr& headers, bool) { EXPECT_EQ(host_, headers->Host()->value().getStringView()); EXPECT_EQ("/", headers->Path()->value().getStringView()); EXPECT_EQ(Http::Headers::get().MethodValues.Post, @@ -160,7 +160,7 @@ TEST_P(EnvoyQuicServerStreamTest, GetRequestAndResponse) { /*compressed_header_bytes=*/0); EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/true)) - .WillOnce(Invoke([this](const Http::HeaderMapPtr& headers, bool) { + .WillOnce(Invoke([this](const Http::RequestHeaderMapPtr& headers, bool) { EXPECT_EQ(host_, headers->Host()->value().getStringView()); EXPECT_EQ("/", headers->Path()->value().getStringView()); EXPECT_EQ(Http::Headers::get().MethodValues.Get, @@ -180,7 +180,7 @@ TEST_P(EnvoyQuicServerStreamTest, PostRequestAndResponse) { TEST_P(EnvoyQuicServerStreamTest, DecodeHeadersBodyAndTrailers) { sendRequest(request_body_, false, request_body_.size() * 2); EXPECT_CALL(stream_decoder_, decodeTrailers_(_)) - .WillOnce(Invoke([](const Http::HeaderMapPtr& headers) { + .WillOnce(Invoke([](const Http::RequestTrailerMapPtr& headers) { Http::LowerCaseString key1("key1"); Http::LowerCaseString key2(":final-offset"); EXPECT_EQ("value1", headers->get(key1)->value().getStringView()); @@ -196,7 +196,7 @@ TEST_P(EnvoyQuicServerStreamTest, OutOfOrderTrailers) { return; } EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/false)) - .WillOnce(Invoke([this](const Http::HeaderMapPtr& headers, bool) { + .WillOnce(Invoke([this](const Http::RequestHeaderMapPtr& headers, bool) { EXPECT_EQ(host_, headers->Host()->value().getStringView()); EXPECT_EQ("/", headers->Path()->value().getStringView()); EXPECT_EQ(Http::Headers::get().MethodValues.Post, @@ -218,7 +218,7 @@ TEST_P(EnvoyQuicServerStreamTest, OutOfOrderTrailers) { })); EXPECT_CALL(stream_decoder_, decodeTrailers_(_)) - .WillOnce(Invoke([](const Http::HeaderMapPtr& headers) { + .WillOnce(Invoke([](const Http::RequestTrailerMapPtr& headers) { Http::LowerCaseString key1("key1"); Http::LowerCaseString key2(":final-offset"); EXPECT_EQ("value1", headers->get(key1)->value().getStringView()); @@ -269,7 +269,7 @@ TEST_P(EnvoyQuicServerStreamTest, ReadDisableUponLargePost) { // Tests that ReadDisable() doesn't cause re-entry of OnBodyAvailable(). TEST_P(EnvoyQuicServerStreamTest, ReadDisableAndReEnableImmediately) { EXPECT_CALL(stream_decoder_, decodeHeaders_(_, /*end_stream=*/false)) - .WillOnce(Invoke([this](const Http::HeaderMapPtr& headers, bool) { + .WillOnce(Invoke([this](const Http::RequestHeaderMapPtr& headers, bool) { EXPECT_EQ(host_, headers->Host()->value().getStringView()); EXPECT_EQ("/", headers->Path()->value().getStringView()); EXPECT_EQ(Http::Headers::get().MethodValues.Post, diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_utils_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_utils_test.cc index 7fff3cc792..de9883880c 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_utils_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_utils_test.cc @@ -48,7 +48,7 @@ TEST(EnvoyQuicUtilsTest, HeadersConversion) { headers_block[":host"] = "www.google.com"; headers_block[":path"] = "/index.hml"; headers_block[":scheme"] = "https"; - Http::HeaderMapImplPtr envoy_headers = spdyHeaderBlockToEnvoyHeaders(headers_block); + auto envoy_headers = spdyHeaderBlockToEnvoyHeaders(headers_block); EXPECT_EQ(headers_block.size(), envoy_headers->size()); EXPECT_EQ("www.google.com", envoy_headers->get(Http::LowerCaseString(":host"))->value().getStringView()); @@ -57,7 +57,7 @@ TEST(EnvoyQuicUtilsTest, HeadersConversion) { EXPECT_EQ("https", envoy_headers->get(Http::LowerCaseString(":scheme"))->value().getStringView()); quic::QuicHeaderList quic_headers = quic::test::AsHeaderList(headers_block); - Http::HeaderMapImplPtr envoy_headers2 = quicHeadersToEnvoyHeaders(quic_headers); + auto envoy_headers2 = quicHeadersToEnvoyHeaders(quic_headers); EXPECT_EQ(*envoy_headers, *envoy_headers2); } diff --git a/test/integration/api_listener_integration_test.cc b/test/integration/api_listener_integration_test.cc index 1a9e04ef07..bd4bfdc5f1 100644 --- a/test/integration/api_listener_integration_test.cc +++ b/test/integration/api_listener_integration_test.cc @@ -104,7 +104,7 @@ TEST_P(ApiListenerIntegrationTest, Basic) { // Send a headers-only request stream_decoder.decodeHeaders( - Http::HeaderMapPtr(new Http::TestHeaderMapImpl{ + Http::RequestHeaderMapPtr(new Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/api"}, {":scheme", "http"}, {":authority", "host"}}), true); }); @@ -128,7 +128,7 @@ TEST_P(ApiListenerIntegrationTest, DestroyWithActiveStreams) { // Send a headers-only request stream_decoder.decodeHeaders( - Http::HeaderMapPtr(new Http::TestHeaderMapImpl{ + Http::RequestHeaderMapPtr(new Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/api"}, {":scheme", "http"}, {":authority", "host"}}), false); diff --git a/test/integration/fake_upstream.cc b/test/integration/fake_upstream.cc index f9f6d7fb3b..7ac5f3831e 100644 --- a/test/integration/fake_upstream.cc +++ b/test/integration/fake_upstream.cc @@ -44,7 +44,7 @@ FakeStream::FakeStream(FakeHttpConnection& parent, Http::ResponseEncoder& encode encoder.getStream().addCallbacks(*this); } -void FakeStream::decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) { +void FakeStream::decodeHeaders(Http::RequestHeaderMapPtr&& headers, bool end_stream) { Thread::LockGuard lock(lock_); headers_ = std::move(headers); setEndStream(end_stream); @@ -59,7 +59,7 @@ void FakeStream::decodeData(Buffer::Instance& data, bool end_stream) { decoder_event_.notifyOne(); } -void FakeStream::decodeTrailers(Http::HeaderMapPtr&& trailers) { +void FakeStream::decodeTrailers(Http::RequestTrailerMapPtr&& trailers) { Thread::LockGuard lock(lock_); setEndStream(true); trailers_ = std::move(trailers); diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index 47de477a7b..b18c29de36 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -156,8 +156,8 @@ class FakeStream : public Http::RequestDecoder, void decodeMetadata(Http::MetadataMapPtr&& metadata_map_ptr) override; // Http::RequestDecoder - void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; - void decodeTrailers(Http::HeaderMapPtr&& trailers) override; + void decodeHeaders(Http::RequestHeaderMapPtr&& headers, bool end_stream) override; + void decodeTrailers(Http::RequestTrailerMapPtr&& trailers) override; // Http::StreamCallbacks void onResetStream(Http::StreamResetReason reason, diff --git a/test/integration/integration.cc b/test/integration/integration.cc index f25cdeeb56..a12c5a51f3 100644 --- a/test/integration/integration.cc +++ b/test/integration/integration.cc @@ -94,14 +94,15 @@ void IntegrationStreamDecoder::waitForReset() { } } -void IntegrationStreamDecoder::decode100ContinueHeaders(Http::HeaderMapPtr&& headers) { +void IntegrationStreamDecoder::decode100ContinueHeaders(Http::ResponseHeaderMapPtr&& headers) { continue_headers_ = std::move(headers); if (waiting_for_continue_headers_) { dispatcher_.exit(); } } -void IntegrationStreamDecoder::decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) { +void IntegrationStreamDecoder::decodeHeaders(Http::ResponseHeaderMapPtr&& headers, + bool end_stream) { saw_end_stream_ = end_stream; headers_ = std::move(headers); if ((end_stream && waiting_for_end_stream_) || waiting_for_headers_) { @@ -123,7 +124,7 @@ void IntegrationStreamDecoder::decodeData(Buffer::Instance& data, bool end_strea } } -void IntegrationStreamDecoder::decodeTrailers(Http::HeaderMapPtr&& trailers) { +void IntegrationStreamDecoder::decodeTrailers(Http::ResponseTrailerMapPtr&& trailers) { saw_end_stream_ = true; trailers_ = std::move(trailers); if (waiting_for_end_stream_) { diff --git a/test/integration/integration.h b/test/integration/integration.h index 6ba287a016..631648d528 100644 --- a/test/integration/integration.h +++ b/test/integration/integration.h @@ -57,12 +57,14 @@ class IntegrationStreamDecoder : public Http::ResponseDecoder, public Http::Stre void clearBody() { body_.clear(); } // Http::StreamDecoder - void decode100ContinueHeaders(Http::HeaderMapPtr&& headers) override; - void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; void decodeData(Buffer::Instance& data, bool end_stream) override; - void decodeTrailers(Http::HeaderMapPtr&& trailers) override; void decodeMetadata(Http::MetadataMapPtr&& metadata_map) override; + // Http::ResponseDecoder + void decode100ContinueHeaders(Http::ResponseHeaderMapPtr&& headers) override; + void decodeHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) override; + void decodeTrailers(Http::ResponseTrailerMapPtr&& trailers) override; + // Http::StreamCallbacks void onResetStream(Http::StreamResetReason reason, absl::string_view transport_failure_reason) override; diff --git a/test/integration/utility.cc b/test/integration/utility.cc index 832154d754..19f830aca3 100644 --- a/test/integration/utility.cc +++ b/test/integration/utility.cc @@ -27,7 +27,7 @@ #include "absl/strings/match.h" namespace Envoy { -void BufferingStreamDecoder::decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) { +void BufferingStreamDecoder::decodeHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) { ASSERT(!complete_); complete_ = end_stream; headers_ = std::move(headers); @@ -45,7 +45,7 @@ void BufferingStreamDecoder::decodeData(Buffer::Instance& data, bool end_stream) } } -void BufferingStreamDecoder::decodeTrailers(Http::HeaderMapPtr&&) { +void BufferingStreamDecoder::decodeTrailers(Http::ResponseTrailerMapPtr&&) { NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } diff --git a/test/integration/utility.h b/test/integration/utility.h index 93eb3459ac..f5c9cc5db1 100644 --- a/test/integration/utility.h +++ b/test/integration/utility.h @@ -31,12 +31,14 @@ class BufferingStreamDecoder : public Http::ResponseDecoder, public Http::Stream const std::string& body() { return body_; } // Http::StreamDecoder - void decode100ContinueHeaders(Http::HeaderMapPtr&&) override {} - void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; void decodeData(Buffer::Instance&, bool end_stream) override; - void decodeTrailers(Http::HeaderMapPtr&& trailers) override; void decodeMetadata(Http::MetadataMapPtr&&) override {} + // Http::ResponseDecoder + void decode100ContinueHeaders(Http::ResponseHeaderMapPtr&&) override {} + void decodeHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) override; + void decodeTrailers(Http::ResponseTrailerMapPtr&& trailers) override; + // Http::StreamCallbacks void onResetStream(Http::StreamResetReason reason, absl::string_view transport_failure_reason) override; diff --git a/test/mocks/http/stream_decoder.cc b/test/mocks/http/stream_decoder.cc index eec3f6abbd..550d7e4715 100644 --- a/test/mocks/http/stream_decoder.cc +++ b/test/mocks/http/stream_decoder.cc @@ -10,7 +10,7 @@ MockStreamDecoder::MockStreamDecoder() = default; MockStreamDecoder::~MockStreamDecoder() = default; MockRequestDecoder::MockRequestDecoder() { - ON_CALL(*this, decodeHeaders_(_, _)).WillByDefault(Invoke([](HeaderMapPtr& headers, bool) { + ON_CALL(*this, decodeHeaders_(_, _)).WillByDefault(Invoke([](RequestHeaderMapPtr& headers, bool) { // Check for passing response headers as request headers in a test. // TODO(mattklein123): In future changes this will become impossible once the header/trailer // implementation classes are split. @@ -23,15 +23,16 @@ MockRequestDecoder::MockRequestDecoder() { MockRequestDecoder::~MockRequestDecoder() = default; MockResponseDecoder::MockResponseDecoder() { - ON_CALL(*this, decodeHeaders_(_, _)).WillByDefault(Invoke([](HeaderMapPtr& headers, bool) { - // Check for passing request headers as response headers in a test. - // TODO(mattklein123): In future changes this will become impossible once the header/trailer - // implementation classes are split. - ASSERT(headers->Status() != nullptr); - ASSERT(headers->Path() == nullptr); - ASSERT(headers->Method() == nullptr); - ASSERT(headers->Host() == nullptr); - })); + ON_CALL(*this, decodeHeaders_(_, _)) + .WillByDefault(Invoke([](ResponseHeaderMapPtr& headers, bool) { + // Check for passing request headers as response headers in a test. + // TODO(mattklein123): In future changes this will become impossible once the header/trailer + // implementation classes are split. + ASSERT(headers->Status() != nullptr); + ASSERT(headers->Path() == nullptr); + ASSERT(headers->Method() == nullptr); + ASSERT(headers->Host() == nullptr); + })); } MockResponseDecoder::~MockResponseDecoder() = default; diff --git a/test/mocks/http/stream_decoder.h b/test/mocks/http/stream_decoder.h index af18cb666d..689ccfa9fc 100644 --- a/test/mocks/http/stream_decoder.h +++ b/test/mocks/http/stream_decoder.h @@ -23,14 +23,14 @@ class MockRequestDecoder : public MockStreamDecoder, public RequestDecoder { MockRequestDecoder(); ~MockRequestDecoder(); - void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) override { + void decodeHeaders(RequestHeaderMapPtr&& headers, bool end_stream) override { decodeHeaders_(headers, end_stream); } - void decodeTrailers(HeaderMapPtr&& trailers) override { decodeTrailers_(trailers); } + void decodeTrailers(RequestTrailerMapPtr&& trailers) override { decodeTrailers_(trailers); } // Http::RequestDecoder - MOCK_METHOD(void, decodeHeaders_, (HeaderMapPtr & headers, bool end_stream)); - MOCK_METHOD(void, decodeTrailers_, (HeaderMapPtr & trailers)); + MOCK_METHOD(void, decodeHeaders_, (RequestHeaderMapPtr & headers, bool end_stream)); + MOCK_METHOD(void, decodeTrailers_, (RequestTrailerMapPtr & trailers)); }; class MockResponseDecoder : public MockStreamDecoder, public ResponseDecoder { @@ -38,18 +38,18 @@ class MockResponseDecoder : public MockStreamDecoder, public ResponseDecoder { MockResponseDecoder(); ~MockResponseDecoder(); - void decode100ContinueHeaders(HeaderMapPtr&& headers) override { + void decode100ContinueHeaders(ResponseHeaderMapPtr&& headers) override { decode100ContinueHeaders_(headers); } - void decodeHeaders(HeaderMapPtr&& headers, bool end_stream) override { + void decodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) override { decodeHeaders_(headers, end_stream); } - void decodeTrailers(HeaderMapPtr&& trailers) override { decodeTrailers_(trailers); } + void decodeTrailers(ResponseTrailerMapPtr&& trailers) override { decodeTrailers_(trailers); } // Http::ResponseDecoder - MOCK_METHOD(void, decode100ContinueHeaders_, (HeaderMapPtr & headers)); - MOCK_METHOD(void, decodeHeaders_, (HeaderMapPtr & headers, bool end_stream)); - MOCK_METHOD(void, decodeTrailers_, (HeaderMapPtr & trailers)); + MOCK_METHOD(void, decode100ContinueHeaders_, (ResponseHeaderMapPtr & headers)); + MOCK_METHOD(void, decodeHeaders_, (ResponseHeaderMapPtr & headers, bool end_stream)); + MOCK_METHOD(void, decodeTrailers_, (ResponseTrailerMapPtr & trailers)); }; } // namespace Http diff --git a/test/test_common/utility.h b/test/test_common/utility.h index ca1169c0b2..159bf53736 100644 --- a/test/test_common/utility.h +++ b/test/test_common/utility.h @@ -659,12 +659,43 @@ class TestHeaderMapImpl : public HeaderMapImpl { void verifyByteSize() override { ASSERT(cached_byte_size_ == byteSizeInternal()); } }; +/** + * Typed test implementations for all of the concrete header types. + */ +class TestRequestHeaderMapImpl : public TestHeaderMapImpl, public RequestHeaderMap { +public: + TestRequestHeaderMapImpl(const std::initializer_list>& values) + : TestHeaderMapImpl(values) {} + TestRequestHeaderMapImpl(const HeaderMap& rhs) : TestHeaderMapImpl(rhs) {} +}; +class TestRequestTrailerMapImpl : public TestHeaderMapImpl, public RequestTrailerMap { +public: + TestRequestTrailerMapImpl( + const std::initializer_list>& values) + : TestHeaderMapImpl(values) {} + TestRequestTrailerMapImpl(const HeaderMap& rhs) : TestHeaderMapImpl(rhs) {} +}; +class TestResponseHeaderMapImpl : public TestHeaderMapImpl, public ResponseHeaderMap { +public: + TestResponseHeaderMapImpl( + const std::initializer_list>& values) + : TestHeaderMapImpl(values) {} + TestResponseHeaderMapImpl() : TestHeaderMapImpl() {} +}; +class TestResponseTrailerMapImpl : public TestHeaderMapImpl, public ResponseTrailerMap { +public: + TestResponseTrailerMapImpl( + const std::initializer_list>& values) + : TestHeaderMapImpl(values) {} + TestResponseTrailerMapImpl() : TestHeaderMapImpl() {} +}; + // Helper method to create a header map from an initializer list. Useful due to make_unique's // inability to infer the initializer list type. -inline HeaderMapPtr +template +inline std::unique_ptr makeHeaderMap(const std::initializer_list>& values) { - return std::make_unique>&>( + return std::make_unique>&>( values); } diff --git a/test/test_runner.cc b/test/test_runner.cc index dbcdff3589..d04ea695ed 100644 --- a/test/test_runner.cc +++ b/test/test_runner.cc @@ -6,7 +6,6 @@ #include "common/common/logger_delegates.h" #include "common/common/thread.h" #include "common/event/libevent.h" -#include "common/http/http2/codec_impl.h" #include "common/runtime/runtime_features.h" #include "exe/process_wide.h" From 7ea52d5e2b0bccbd3263a805e38778fa132b715d Mon Sep 17 00:00:00 2001 From: Yangmin Zhu Date: Wed, 12 Feb 2020 11:38:00 -0800 Subject: [PATCH 46/87] matcher: add PathMatcher and use in routing, jwt and rbac (#10010) Description: Add a new PathMatcher that strips the query and/or fragment string from the ":path" header before matching, use it in route, JWT and RBAC. Risk Level: Low Testing: Added unit tests and integration tests Docs Changes: Updated types.rst for PathMatcher Release Notes: Updated version_history.rst for RBAC API change Signed-off-by: Yangmin Zhu --- api/envoy/config/rbac/v2/rbac.proto | 18 +++- api/envoy/config/rbac/v3/rbac.proto | 18 +++- api/envoy/type/matcher/path.proto | 25 ++++++ api/envoy/type/matcher/v3/path.proto | 29 +++++++ docs/root/api-v2/types/types.rst | 1 + docs/root/api-v3/types/types.rst | 1 + docs/root/intro/version_history.rst | 1 + .../envoy/config/rbac/v2/rbac.proto | 18 +++- .../envoy/config/rbac/v3/rbac.proto | 18 +++- .../envoy/type/matcher/path.proto | 25 ++++++ .../envoy/type/matcher/v3/path.proto | 29 +++++++ source/common/common/BUILD | 1 + source/common/common/matchers.cc | 19 ++++ source/common/common/matchers.h | 18 ++++ source/common/http/path_utility.cc | 11 ++- source/common/http/path_utility.h | 5 ++ source/common/router/BUILD | 2 + source/common/router/config_impl.cc | 55 ++++-------- source/common/router/config_impl.h | 5 +- .../filters/common/rbac/matchers.cc | 12 +++ .../extensions/filters/common/rbac/matchers.h | 17 ++++ .../extensions/filters/http/jwt_authn/BUILD | 1 + .../filters/http/jwt_authn/matcher.cc | 28 +++--- test/common/common/matchers_test.cc | 86 +++++++++++++++++++ test/common/http/path_utility_test.cc | 20 +++++ .../filters/common/rbac/matchers_test.cc | 27 ++++++ .../http/rbac/rbac_filter_integration_test.cc | 82 ++++++++++++++++++ .../filters/http/rbac/rbac_filter_test.cc | 13 +++ 28 files changed, 517 insertions(+), 68 deletions(-) create mode 100644 api/envoy/type/matcher/path.proto create mode 100644 api/envoy/type/matcher/v3/path.proto create mode 100644 generated_api_shadow/envoy/type/matcher/path.proto create mode 100644 generated_api_shadow/envoy/type/matcher/v3/path.proto diff --git a/api/envoy/config/rbac/v2/rbac.proto b/api/envoy/config/rbac/v2/rbac.proto index 833eaa6f3b..fa5d27fdf6 100644 --- a/api/envoy/config/rbac/v2/rbac.proto +++ b/api/envoy/config/rbac/v2/rbac.proto @@ -5,6 +5,7 @@ package envoy.config.rbac.v2; import "envoy/api/v2/core/address.proto"; import "envoy/api/v2/route/route_components.proto"; import "envoy/type/matcher/metadata.proto"; +import "envoy/type/matcher/path.proto"; import "envoy/type/matcher/string.proto"; import "google/api/expr/v1alpha1/syntax.proto"; @@ -48,7 +49,8 @@ option java_multiple_files = true; // - and_rules: // rules: // - header: { name: ":method", exact_match: "GET" } -// - header: { name: ":path", regex_match: "/products(/.*)?" } +// - url_path: +// path: { prefix: "/products" } // - or_rules: // rules: // - destination_port: 80 @@ -99,7 +101,7 @@ message Policy { } // Permission defines an action (or actions) that a principal can take. -// [#next-free-field: 10] +// [#next-free-field: 11] message Permission { // Used in the `and_rules` and `or_rules` fields in the `rule` oneof. Depending on the context, // each are applied with the associated behavior. @@ -121,8 +123,13 @@ message Permission { // A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only // available for HTTP request. + // Note: the pseudo-header :path includes the query and fragment string. Use the `url_path` + // field if you want to match the URL path without the query and fragment string. api.v2.route.HeaderMatcher header = 4; + // A URL path on the incoming HTTP request. Only available for HTTP. + type.matcher.PathMatcher url_path = 10; + // A CIDR block that describes the destination IP. api.v2.core.CidrRange destination_ip = 5; @@ -161,7 +168,7 @@ message Permission { } // Principal defines an identity or a group of identities for a downstream subject. -// [#next-free-field: 9] +// [#next-free-field: 10] message Principal { // Used in the `and_ids` and `or_ids` fields in the `identifier` oneof. Depending on the context, // each are applied with the associated behavior. @@ -199,8 +206,13 @@ message Principal { // A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only // available for HTTP request. + // Note: the pseudo-header :path includes the query and fragment string. Use the `url_path` + // field if you want to match the URL path without the query and fragment string. api.v2.route.HeaderMatcher header = 6; + // A URL path on the incoming HTTP request. Only available for HTTP. + type.matcher.PathMatcher url_path = 9; + // Metadata that describes additional information about the principal. type.matcher.MetadataMatcher metadata = 7; diff --git a/api/envoy/config/rbac/v3/rbac.proto b/api/envoy/config/rbac/v3/rbac.proto index 3320c86a88..0d9b552d85 100644 --- a/api/envoy/config/rbac/v3/rbac.proto +++ b/api/envoy/config/rbac/v3/rbac.proto @@ -5,6 +5,7 @@ package envoy.config.rbac.v3; import "envoy/config/core/v3/address.proto"; import "envoy/config/route/v3/route_components.proto"; import "envoy/type/matcher/v3/metadata.proto"; +import "envoy/type/matcher/v3/path.proto"; import "envoy/type/matcher/v3/string.proto"; import "google/api/expr/v1alpha1/syntax.proto"; @@ -50,7 +51,8 @@ option java_multiple_files = true; // - and_rules: // rules: // - header: { name: ":method", exact_match: "GET" } -// - header: { name: ":path", regex_match: "/products(/.*)?" } +// - url_path: +// path: { prefix: "/products" } // - or_rules: // rules: // - destination_port: 80 @@ -105,7 +107,7 @@ message Policy { } // Permission defines an action (or actions) that a principal can take. -// [#next-free-field: 10] +// [#next-free-field: 11] message Permission { option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Permission"; @@ -132,8 +134,13 @@ message Permission { // A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only // available for HTTP request. + // Note: the pseudo-header :path includes the query and fragment string. Use the `url_path` + // field if you want to match the URL path without the query and fragment string. route.v3.HeaderMatcher header = 4; + // A URL path on the incoming HTTP request. Only available for HTTP. + type.matcher.v3.PathMatcher url_path = 10; + // A CIDR block that describes the destination IP. core.v3.CidrRange destination_ip = 5; @@ -172,7 +179,7 @@ message Permission { } // Principal defines an identity or a group of identities for a downstream subject. -// [#next-free-field: 9] +// [#next-free-field: 10] message Principal { option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Principal"; @@ -218,8 +225,13 @@ message Principal { // A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only // available for HTTP request. + // Note: the pseudo-header :path includes the query and fragment string. Use the `url_path` + // field if you want to match the URL path without the query and fragment string. route.v3.HeaderMatcher header = 6; + // A URL path on the incoming HTTP request. Only available for HTTP. + type.matcher.v3.PathMatcher url_path = 9; + // Metadata that describes additional information about the principal. type.matcher.v3.MetadataMatcher metadata = 7; diff --git a/api/envoy/type/matcher/path.proto b/api/envoy/type/matcher/path.proto new file mode 100644 index 0000000000..779339a2d2 --- /dev/null +++ b/api/envoy/type/matcher/path.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package envoy.type.matcher; + +import "envoy/type/matcher/string.proto"; + +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.type.matcher"; +option java_outer_classname = "PathProto"; +option java_multiple_files = true; + +// [#protodoc-title: Path matcher] + +// Specifies the way to match a path on HTTP request. +message PathMatcher { + oneof rule { + option (validate.required) = true; + + // The `path` must match the URL path portion of the :path header. The query and fragment + // string (if present) are removed in the URL path portion. + // For example, the path */data* will match the *:path* header */data#fragment?param=value*. + StringMatcher path = 1 [(validate.rules).message = {required: true}]; + } +} diff --git a/api/envoy/type/matcher/v3/path.proto b/api/envoy/type/matcher/v3/path.proto new file mode 100644 index 0000000000..68e0bee83c --- /dev/null +++ b/api/envoy/type/matcher/v3/path.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package envoy.type.matcher.v3; + +import "envoy/type/matcher/v3/string.proto"; + +import "udpa/annotations/versioning.proto"; + +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.type.matcher.v3"; +option java_outer_classname = "PathProto"; +option java_multiple_files = true; + +// [#protodoc-title: Path matcher] + +// Specifies the way to match a path on HTTP request. +message PathMatcher { + option (udpa.annotations.versioning).previous_message_type = "envoy.type.matcher.PathMatcher"; + + oneof rule { + option (validate.required) = true; + + // The `path` must match the URL path portion of the :path header. The query and fragment + // string (if present) are removed in the URL path portion. + // For example, the path */data* will match the *:path* header */data#fragment?param=value*. + StringMatcher path = 1 [(validate.rules).message = {required: true}]; + } +} diff --git a/docs/root/api-v2/types/types.rst b/docs/root/api-v2/types/types.rst index c26b9b016b..b85889bf45 100644 --- a/docs/root/api-v2/types/types.rst +++ b/docs/root/api-v2/types/types.rst @@ -15,6 +15,7 @@ Types ../type/matcher/metadata.proto ../type/matcher/node.proto ../type/matcher/number.proto + ../type/matcher/path.proto ../type/matcher/regex.proto ../type/matcher/string.proto ../type/matcher/struct.proto diff --git a/docs/root/api-v3/types/types.rst b/docs/root/api-v3/types/types.rst index b857363af2..f9c1cad3ea 100644 --- a/docs/root/api-v3/types/types.rst +++ b/docs/root/api-v3/types/types.rst @@ -15,6 +15,7 @@ Types ../type/matcher/v3/metadata.proto ../type/matcher/v3/node.proto ../type/matcher/v3/number.proto + ../type/matcher/v3/path.proto ../type/matcher/v3/regex.proto ../type/matcher/v3/string.proto ../type/matcher/v3/struct.proto diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index d8b23a2d5c..387cc502ac 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -9,6 +9,7 @@ Version history minimum. * config: use type URL to select an extension whenever the config type URL (or its previous versions) uniquely identify a typed extension, see :ref:`extension configuration `. * http: fixing a bug in HTTP/1.0 responses where Connection: keep-alive was not appended for connections which were kept alive. +* rbac: added :ref:`url_path ` for matching URL path without the query and fragment string. * retry: added a retry predicate that :ref:`rejects hosts based on metadata. ` * router: added :ref:`auto_san_validation ` to support overrriding SAN validation to transport socket for new upstream connections based on the downstream HTTP host/authority header. * router: added the ability to match a route based on whether a downstream TLS connection certificate has been diff --git a/generated_api_shadow/envoy/config/rbac/v2/rbac.proto b/generated_api_shadow/envoy/config/rbac/v2/rbac.proto index 833eaa6f3b..fa5d27fdf6 100644 --- a/generated_api_shadow/envoy/config/rbac/v2/rbac.proto +++ b/generated_api_shadow/envoy/config/rbac/v2/rbac.proto @@ -5,6 +5,7 @@ package envoy.config.rbac.v2; import "envoy/api/v2/core/address.proto"; import "envoy/api/v2/route/route_components.proto"; import "envoy/type/matcher/metadata.proto"; +import "envoy/type/matcher/path.proto"; import "envoy/type/matcher/string.proto"; import "google/api/expr/v1alpha1/syntax.proto"; @@ -48,7 +49,8 @@ option java_multiple_files = true; // - and_rules: // rules: // - header: { name: ":method", exact_match: "GET" } -// - header: { name: ":path", regex_match: "/products(/.*)?" } +// - url_path: +// path: { prefix: "/products" } // - or_rules: // rules: // - destination_port: 80 @@ -99,7 +101,7 @@ message Policy { } // Permission defines an action (or actions) that a principal can take. -// [#next-free-field: 10] +// [#next-free-field: 11] message Permission { // Used in the `and_rules` and `or_rules` fields in the `rule` oneof. Depending on the context, // each are applied with the associated behavior. @@ -121,8 +123,13 @@ message Permission { // A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only // available for HTTP request. + // Note: the pseudo-header :path includes the query and fragment string. Use the `url_path` + // field if you want to match the URL path without the query and fragment string. api.v2.route.HeaderMatcher header = 4; + // A URL path on the incoming HTTP request. Only available for HTTP. + type.matcher.PathMatcher url_path = 10; + // A CIDR block that describes the destination IP. api.v2.core.CidrRange destination_ip = 5; @@ -161,7 +168,7 @@ message Permission { } // Principal defines an identity or a group of identities for a downstream subject. -// [#next-free-field: 9] +// [#next-free-field: 10] message Principal { // Used in the `and_ids` and `or_ids` fields in the `identifier` oneof. Depending on the context, // each are applied with the associated behavior. @@ -199,8 +206,13 @@ message Principal { // A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only // available for HTTP request. + // Note: the pseudo-header :path includes the query and fragment string. Use the `url_path` + // field if you want to match the URL path without the query and fragment string. api.v2.route.HeaderMatcher header = 6; + // A URL path on the incoming HTTP request. Only available for HTTP. + type.matcher.PathMatcher url_path = 9; + // Metadata that describes additional information about the principal. type.matcher.MetadataMatcher metadata = 7; diff --git a/generated_api_shadow/envoy/config/rbac/v3/rbac.proto b/generated_api_shadow/envoy/config/rbac/v3/rbac.proto index 3320c86a88..0d9b552d85 100644 --- a/generated_api_shadow/envoy/config/rbac/v3/rbac.proto +++ b/generated_api_shadow/envoy/config/rbac/v3/rbac.proto @@ -5,6 +5,7 @@ package envoy.config.rbac.v3; import "envoy/config/core/v3/address.proto"; import "envoy/config/route/v3/route_components.proto"; import "envoy/type/matcher/v3/metadata.proto"; +import "envoy/type/matcher/v3/path.proto"; import "envoy/type/matcher/v3/string.proto"; import "google/api/expr/v1alpha1/syntax.proto"; @@ -50,7 +51,8 @@ option java_multiple_files = true; // - and_rules: // rules: // - header: { name: ":method", exact_match: "GET" } -// - header: { name: ":path", regex_match: "/products(/.*)?" } +// - url_path: +// path: { prefix: "/products" } // - or_rules: // rules: // - destination_port: 80 @@ -105,7 +107,7 @@ message Policy { } // Permission defines an action (or actions) that a principal can take. -// [#next-free-field: 10] +// [#next-free-field: 11] message Permission { option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Permission"; @@ -132,8 +134,13 @@ message Permission { // A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only // available for HTTP request. + // Note: the pseudo-header :path includes the query and fragment string. Use the `url_path` + // field if you want to match the URL path without the query and fragment string. route.v3.HeaderMatcher header = 4; + // A URL path on the incoming HTTP request. Only available for HTTP. + type.matcher.v3.PathMatcher url_path = 10; + // A CIDR block that describes the destination IP. core.v3.CidrRange destination_ip = 5; @@ -172,7 +179,7 @@ message Permission { } // Principal defines an identity or a group of identities for a downstream subject. -// [#next-free-field: 9] +// [#next-free-field: 10] message Principal { option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Principal"; @@ -218,8 +225,13 @@ message Principal { // A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only // available for HTTP request. + // Note: the pseudo-header :path includes the query and fragment string. Use the `url_path` + // field if you want to match the URL path without the query and fragment string. route.v3.HeaderMatcher header = 6; + // A URL path on the incoming HTTP request. Only available for HTTP. + type.matcher.v3.PathMatcher url_path = 9; + // Metadata that describes additional information about the principal. type.matcher.v3.MetadataMatcher metadata = 7; diff --git a/generated_api_shadow/envoy/type/matcher/path.proto b/generated_api_shadow/envoy/type/matcher/path.proto new file mode 100644 index 0000000000..779339a2d2 --- /dev/null +++ b/generated_api_shadow/envoy/type/matcher/path.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package envoy.type.matcher; + +import "envoy/type/matcher/string.proto"; + +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.type.matcher"; +option java_outer_classname = "PathProto"; +option java_multiple_files = true; + +// [#protodoc-title: Path matcher] + +// Specifies the way to match a path on HTTP request. +message PathMatcher { + oneof rule { + option (validate.required) = true; + + // The `path` must match the URL path portion of the :path header. The query and fragment + // string (if present) are removed in the URL path portion. + // For example, the path */data* will match the *:path* header */data#fragment?param=value*. + StringMatcher path = 1 [(validate.rules).message = {required: true}]; + } +} diff --git a/generated_api_shadow/envoy/type/matcher/v3/path.proto b/generated_api_shadow/envoy/type/matcher/v3/path.proto new file mode 100644 index 0000000000..68e0bee83c --- /dev/null +++ b/generated_api_shadow/envoy/type/matcher/v3/path.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package envoy.type.matcher.v3; + +import "envoy/type/matcher/v3/string.proto"; + +import "udpa/annotations/versioning.proto"; + +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.type.matcher.v3"; +option java_outer_classname = "PathProto"; +option java_multiple_files = true; + +// [#protodoc-title: Path matcher] + +// Specifies the way to match a path on HTTP request. +message PathMatcher { + option (udpa.annotations.versioning).previous_message_type = "envoy.type.matcher.PathMatcher"; + + oneof rule { + option (validate.required) = true; + + // The `path` must match the URL path portion of the :path header. The query and fragment + // string (if present) are removed in the URL path portion. + // For example, the path */data* will match the *:path* header */data#fragment?param=value*. + StringMatcher path = 1 [(validate.rules).message = {required: true}]; + } +} diff --git a/source/common/common/BUILD b/source/common/common/BUILD index c2646beed9..fbbecf5905 100644 --- a/source/common/common/BUILD +++ b/source/common/common/BUILD @@ -210,6 +210,7 @@ envoy_cc_library( "//include/envoy/common:matchers_interface", "//source/common/common:regex_lib", "//source/common/config:metadata_lib", + "//source/common/http:path_utility_lib", "//source/common/protobuf", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", "@envoy_api//envoy/type/matcher/v3:pkg_cc_proto", diff --git a/source/common/common/matchers.cc b/source/common/common/matchers.cc index 11fa907cc9..b4febd80e3 100644 --- a/source/common/common/matchers.cc +++ b/source/common/common/matchers.cc @@ -8,6 +8,7 @@ #include "common/common/regex.h" #include "common/config/metadata.h" +#include "common/http/path_utility.h" #include "absl/strings/match.h" @@ -168,10 +169,28 @@ MetadataMatcher::MetadataMatcher(const envoy::type::matcher::v3::MetadataMatcher value_matcher_ = ValueMatcher::create(v); } +PathMatcherConstSharedPtr PathMatcher::createExact(const std::string& exact, bool ignore_case) { + envoy::type::matcher::v3::StringMatcher matcher; + matcher.set_exact(exact); + matcher.set_ignore_case(ignore_case); + return std::make_shared(matcher); +} + +PathMatcherConstSharedPtr PathMatcher::createPrefix(const std::string& prefix, bool ignore_case) { + envoy::type::matcher::v3::StringMatcher matcher; + matcher.set_prefix(prefix); + matcher.set_ignore_case(ignore_case); + return std::make_shared(matcher); +} + bool MetadataMatcher::match(const envoy::config::core::v3::Metadata& metadata) const { const auto& value = Envoy::Config::Metadata::metadataValue(metadata, matcher_.filter(), path_); return value_matcher_ && value_matcher_->match(value); } +bool PathMatcher::match(const absl::string_view path) const { + return matcher_.match(Http::PathUtil::removeQueryAndFragment(path)); +} + } // namespace Matchers } // namespace Envoy diff --git a/source/common/common/matchers.h b/source/common/common/matchers.h index c90f1b20e2..0d07dfc6e6 100644 --- a/source/common/common/matchers.h +++ b/source/common/common/matchers.h @@ -7,6 +7,7 @@ #include "envoy/config/core/v3/base.pb.h" #include "envoy/type/matcher/v3/metadata.pb.h" #include "envoy/type/matcher/v3/number.pb.h" +#include "envoy/type/matcher/v3/path.pb.h" #include "envoy/type/matcher/v3/string.pb.h" #include "envoy/type/matcher/v3/value.pb.h" @@ -19,6 +20,9 @@ namespace Matchers { class ValueMatcher; using ValueMatcherConstSharedPtr = std::shared_ptr; +class PathMatcher; +using PathMatcherConstSharedPtr = std::shared_ptr; + class ValueMatcher { public: virtual ~ValueMatcher() = default; @@ -132,5 +136,19 @@ class MetadataMatcher { ValueMatcherConstSharedPtr value_matcher_; }; +class PathMatcher : public StringMatcher { +public: + PathMatcher(const envoy::type::matcher::v3::PathMatcher& path) : matcher_(path.path()) {} + PathMatcher(const envoy::type::matcher::v3::StringMatcher& matcher) : matcher_(matcher) {} + + static PathMatcherConstSharedPtr createExact(const std::string& exact, bool ignore_case); + static PathMatcherConstSharedPtr createPrefix(const std::string& prefix, bool ignore_case); + + bool match(const absl::string_view path) const override; + +private: + const StringMatcherImpl matcher_; +}; + } // namespace Matchers } // namespace Envoy diff --git a/source/common/http/path_utility.cc b/source/common/http/path_utility.cc index 0266f0b634..e9815295bf 100644 --- a/source/common/http/path_utility.cc +++ b/source/common/http/path_utility.cc @@ -6,7 +6,6 @@ #include "absl/strings/str_join.h" #include "absl/strings/str_split.h" -#include "absl/strings/string_view.h" #include "absl/types/optional.h" namespace Envoy { @@ -69,5 +68,15 @@ void PathUtil::mergeSlashes(HeaderMap& headers) { prefix, absl::StrJoin(absl::StrSplit(path, '/', absl::SkipEmpty()), "/"), query, suffix)); } +absl::string_view PathUtil::removeQueryAndFragment(const absl::string_view path) { + absl::string_view ret = path; + // Trim query parameters and/or fragment if present. + size_t offset = ret.find_first_of("?#"); + if (offset != absl::string_view::npos) { + ret.remove_suffix(ret.length() - offset); + } + return ret; +} + } // namespace Http } // namespace Envoy diff --git a/source/common/http/path_utility.h b/source/common/http/path_utility.h index 8e635ed7d3..b0ca3f1453 100644 --- a/source/common/http/path_utility.h +++ b/source/common/http/path_utility.h @@ -2,6 +2,8 @@ #include "envoy/http/header_map.h" +#include "absl/strings/string_view.h" + namespace Envoy { namespace Http { @@ -15,6 +17,9 @@ class PathUtil { static bool canonicalPath(HeaderMap& headers); // Merges two or more adjacent slashes in path part of URI into one. static void mergeSlashes(HeaderMap& headers); + // Removes the query and/or fragment string (if present) from the input path. + // For example, this function returns "/data" for the input path "/data#fragment?param=value". + static absl::string_view removeQueryAndFragment(const absl::string_view path); }; } // namespace Http diff --git a/source/common/router/BUILD b/source/common/router/BUILD index e366258670..5f40745037 100644 --- a/source/common/router/BUILD +++ b/source/common/router/BUILD @@ -50,6 +50,7 @@ envoy_cc_library( "//source/common/common:assert_lib", "//source/common/common:empty_string", "//source/common/common:hash_lib", + "//source/common/common:matchers_lib", "//source/common/common:utility_lib", "//source/common/config:metadata_lib", "//source/common/config:utility_lib", @@ -57,6 +58,7 @@ envoy_cc_library( "//source/common/http:hash_policy_lib", "//source/common/http:header_utility_lib", "//source/common/http:headers_lib", + "//source/common/http:path_utility_lib", "//source/common/http:utility_lib", "//source/common/protobuf:utility_lib", "//source/common/tracing:http_tracer_lib", diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc index a3913d96c7..d562f8e4fe 100644 --- a/source/common/router/config_impl.cc +++ b/source/common/router/config_impl.cc @@ -29,6 +29,7 @@ #include "common/config/utility.h" #include "common/config/well_known_names.h" #include "common/http/headers.h" +#include "common/http/path_utility.h" #include "common/http/utility.h" #include "common/protobuf/protobuf.h" #include "common/protobuf/utility.h" @@ -798,8 +799,8 @@ PrefixRouteEntryImpl::PrefixRouteEntryImpl( const VirtualHostImpl& vhost, const envoy::config::route::v3::Route& route, Server::Configuration::ServerFactoryContext& factory_context, ProtobufMessage::ValidationVisitor& validator) - : RouteEntryImplBase(vhost, route, factory_context, validator), - prefix_(route.match().prefix()) {} + : RouteEntryImplBase(vhost, route, factory_context, validator), prefix_(route.match().prefix()), + path_matcher_(Matchers::PathMatcher::createPrefix(prefix_, !case_sensitive_)) {} void PrefixRouteEntryImpl::rewritePathHeader(Http::HeaderMap& headers, bool insert_envoy_original_path) const { @@ -810,9 +811,7 @@ RouteConstSharedPtr PrefixRouteEntryImpl::matches(const Http::HeaderMap& headers const StreamInfo::StreamInfo& stream_info, uint64_t random_value) const { if (RouteEntryImplBase::matchRoute(headers, stream_info, random_value) && - (case_sensitive_ - ? absl::StartsWith(headers.Path()->value().getStringView(), prefix_) - : absl::StartsWithIgnoreCase(headers.Path()->value().getStringView(), prefix_))) { + path_matcher_->match(headers.Path()->value().getStringView())) { return clusterEntry(headers, random_value); } return nullptr; @@ -822,7 +821,8 @@ PathRouteEntryImpl::PathRouteEntryImpl(const VirtualHostImpl& vhost, const envoy::config::route::v3::Route& route, Server::Configuration::ServerFactoryContext& factory_context, ProtobufMessage::ValidationVisitor& validator) - : RouteEntryImplBase(vhost, route, factory_context, validator), path_(route.match().path()) {} + : RouteEntryImplBase(vhost, route, factory_context, validator), path_(route.match().path()), + path_matcher_(Matchers::PathMatcher::createExact(path_, !case_sensitive_)) {} void PathRouteEntryImpl::rewritePathHeader(Http::HeaderMap& headers, bool insert_envoy_original_path) const { @@ -832,28 +832,9 @@ void PathRouteEntryImpl::rewritePathHeader(Http::HeaderMap& headers, RouteConstSharedPtr PathRouteEntryImpl::matches(const Http::HeaderMap& headers, const StreamInfo::StreamInfo& stream_info, uint64_t random_value) const { - if (RouteEntryImplBase::matchRoute(headers, stream_info, random_value)) { - const Http::HeaderString& path = headers.Path()->value(); - absl::string_view query_string = Http::Utility::findQueryStringStart(path); - size_t compare_length = path.size(); - if (query_string.length() > 0) { - compare_length = compare_length - query_string.length(); - } - - if (compare_length != path_.size()) { - return nullptr; - } - - const absl::string_view path_section = path.getStringView().substr(0, compare_length); - if (case_sensitive_) { - if (absl::string_view(path_) == path_section) { - return clusterEntry(headers, random_value); - } - } else { - if (absl::EqualsIgnoreCase(path_, path_section)) { - return clusterEntry(headers, random_value); - } - } + if (RouteEntryImplBase::matchRoute(headers, stream_info, random_value) && + path_matcher_->match(headers.Path()->value().getStringView())) { + return clusterEntry(headers, random_value); } return nullptr; @@ -864,6 +845,7 @@ RegexRouteEntryImpl::RegexRouteEntryImpl( Server::Configuration::ServerFactoryContext& factory_context, ProtobufMessage::ValidationVisitor& validator) : RouteEntryImplBase(vhost, route, factory_context, validator) { + // TODO(yangminzhu): Use PathMatcher once hidden_envoy_deprecated_regex is removed. if (route.match().path_specifier_case() == envoy::config::route::v3::RouteMatch::PathSpecifierCase::kHiddenEnvoyDeprecatedRegex) { regex_ = Regex::Utility::parseStdRegexAsCompiledMatcher( @@ -877,26 +859,23 @@ RegexRouteEntryImpl::RegexRouteEntryImpl( } } -absl::string_view RegexRouteEntryImpl::pathOnly(const Http::HeaderMap& headers) const { - const Http::HeaderString& path = headers.Path()->value(); - const absl::string_view query_string = Http::Utility::findQueryStringStart(path); - const size_t path_string_length = path.size() - query_string.length(); - return path.getStringView().substr(0, path_string_length); -} - void RegexRouteEntryImpl::rewritePathHeader(Http::HeaderMap& headers, bool insert_envoy_original_path) const { + const absl::string_view path = + Http::PathUtil::removeQueryAndFragment(headers.Path()->value().getStringView()); // TODO(yuval-k): This ASSERT can happen if the path was changed by a filter without clearing the // route cache. We should consider if ASSERT-ing is the desired behavior in this case. - ASSERT(regex_->match(pathOnly(headers))); - finalizePathHeader(headers, pathOnly(headers), insert_envoy_original_path); + ASSERT(regex_->match(path)); + finalizePathHeader(headers, path, insert_envoy_original_path); } RouteConstSharedPtr RegexRouteEntryImpl::matches(const Http::HeaderMap& headers, const StreamInfo::StreamInfo& stream_info, uint64_t random_value) const { if (RouteEntryImplBase::matchRoute(headers, stream_info, random_value)) { - if (regex_->match(pathOnly(headers))) { + const absl::string_view path = + Http::PathUtil::removeQueryAndFragment(headers.Path()->value().getStringView()); + if (regex_->match(path)) { return clusterEntry(headers, random_value); } } diff --git a/source/common/router/config_impl.h b/source/common/router/config_impl.h index 69f482b546..b9559b66ef 100644 --- a/source/common/router/config_impl.h +++ b/source/common/router/config_impl.h @@ -19,6 +19,7 @@ #include "envoy/type/v3/percent.pb.h" #include "envoy/upstream/cluster_manager.h" +#include "common/common/matchers.h" #include "common/config/metadata.h" #include "common/http/hash_policy.h" #include "common/http/header_utility.h" @@ -738,6 +739,7 @@ class PrefixRouteEntryImpl : public RouteEntryImplBase { private: const std::string prefix_; + const Matchers::PathMatcherConstSharedPtr path_matcher_; }; /** @@ -763,6 +765,7 @@ class PathRouteEntryImpl : public RouteEntryImplBase { private: const std::string path_; + const Matchers::PathMatcherConstSharedPtr path_matcher_; }; /** @@ -787,8 +790,6 @@ class RegexRouteEntryImpl : public RouteEntryImplBase { void rewritePathHeader(Http::HeaderMap& headers, bool insert_envoy_original_path) const override; private: - absl::string_view pathOnly(const Http::HeaderMap& headers) const; - Regex::CompiledMatcherPtr regex_; std::string regex_str_; }; diff --git a/source/extensions/filters/common/rbac/matchers.cc b/source/extensions/filters/common/rbac/matchers.cc index 7699d68dd3..7d88783006 100644 --- a/source/extensions/filters/common/rbac/matchers.cc +++ b/source/extensions/filters/common/rbac/matchers.cc @@ -30,6 +30,8 @@ MatcherConstSharedPtr Matcher::create(const envoy::config::rbac::v3::Permission& return std::make_shared(permission.not_rule()); case envoy::config::rbac::v3::Permission::RuleCase::kRequestedServerName: return std::make_shared(permission.requested_server_name()); + case envoy::config::rbac::v3::Permission::RuleCase::kUrlPath: + return std::make_shared(permission.url_path()); default: NOT_REACHED_GCOVR_EXCL_LINE; } @@ -53,6 +55,8 @@ MatcherConstSharedPtr Matcher::create(const envoy::config::rbac::v3::Principal& return std::make_shared(principal.metadata()); case envoy::config::rbac::v3::Principal::IdentifierCase::kNotId: return std::make_shared(principal.not_id()); + case envoy::config::rbac::v3::Principal::IdentifierCase::kUrlPath: + return std::make_shared(principal.url_path()); default: NOT_REACHED_GCOVR_EXCL_LINE; } @@ -179,6 +183,14 @@ bool RequestedServerNameMatcher::matches(const Network::Connection& connection, return match(connection.requestedServerName()); } +bool PathMatcher::matches(const Network::Connection&, const Envoy::Http::HeaderMap& headers, + const StreamInfo::StreamInfo&) const { + if (headers.Path() == nullptr) { + return false; + } + return path_matcher_.match(headers.Path()->value().getStringView()); +} + } // namespace RBAC } // namespace Common } // namespace Filters diff --git a/source/extensions/filters/common/rbac/matchers.h b/source/extensions/filters/common/rbac/matchers.h index d0fad72022..e5baf17335 100644 --- a/source/extensions/filters/common/rbac/matchers.h +++ b/source/extensions/filters/common/rbac/matchers.h @@ -7,6 +7,7 @@ #include "envoy/config/route/v3/route_components.pb.h" #include "envoy/http/header_map.h" #include "envoy/network/connection.h" +#include "envoy/type/matcher/v3/path.pb.h" #include "envoy/type/matcher/v3/string.pb.h" #include "common/common/matchers.h" @@ -228,6 +229,22 @@ class RequestedServerNameMatcher : public Matcher, Envoy::Matchers::StringMatche const StreamInfo::StreamInfo&) const override; }; +/** + * Perform a match against the path header on the HTTP request. The query and fragment string are + * removed from the path header before matching. + */ +class PathMatcher : public Matcher { +public: + PathMatcher(const envoy::type::matcher::v3::PathMatcher& path_matcher) + : path_matcher_(path_matcher) {} + + bool matches(const Network::Connection& connection, const Envoy::Http::HeaderMap& headers, + const StreamInfo::StreamInfo&) const override; + +private: + const Matchers::PathMatcher path_matcher_; +}; + } // namespace RBAC } // namespace Common } // namespace Filters diff --git a/source/extensions/filters/http/jwt_authn/BUILD b/source/extensions/filters/http/jwt_authn/BUILD index 0602621c2f..b64922a9c4 100644 --- a/source/extensions/filters/http/jwt_authn/BUILD +++ b/source/extensions/filters/http/jwt_authn/BUILD @@ -86,6 +86,7 @@ envoy_cc_library( hdrs = ["matcher.h"], deps = [ ":verifier_lib", + "//source/common/common:matchers_lib", "//source/common/http:header_utility_lib", "//source/common/router:config_lib", "@envoy_api//envoy/config/route/v3:pkg_cc_proto", diff --git a/source/extensions/filters/http/jwt_authn/matcher.cc b/source/extensions/filters/http/jwt_authn/matcher.cc index c03395377f..1303cf4256 100644 --- a/source/extensions/filters/http/jwt_authn/matcher.cc +++ b/source/extensions/filters/http/jwt_authn/matcher.cc @@ -4,6 +4,7 @@ #include "envoy/extensions/filters/http/jwt_authn/v3/config.pb.h" #include "common/common/logger.h" +#include "common/common/matchers.h" #include "common/common/regex.h" #include "common/router/config_impl.h" @@ -61,13 +62,12 @@ class BaseMatcherImpl : public Matcher, public Logger::Loggable class PrefixMatcherImpl : public BaseMatcherImpl { public: PrefixMatcherImpl(const RequirementRule& rule) - : BaseMatcherImpl(rule), prefix_(rule.match().prefix()) {} + : BaseMatcherImpl(rule), prefix_(rule.match().prefix()), + path_matcher_(Matchers::PathMatcher::createPrefix(prefix_, !case_sensitive_)) {} bool matches(const Http::HeaderMap& headers) const override { if (BaseMatcherImpl::matchRoute(headers) && - (case_sensitive_ - ? absl::StartsWith(headers.Path()->value().getStringView(), prefix_) - : absl::StartsWithIgnoreCase(headers.Path()->value().getStringView(), prefix_))) { + path_matcher_->match(headers.Path()->value().getStringView())) { ENVOY_LOG(debug, "Prefix requirement '{}' matched.", prefix_); return true; } @@ -77,6 +77,7 @@ class PrefixMatcherImpl : public BaseMatcherImpl { private: // prefix string const std::string prefix_; + const Matchers::PathMatcherConstSharedPtr path_matcher_; }; /** @@ -85,19 +86,14 @@ class PrefixMatcherImpl : public BaseMatcherImpl { class PathMatcherImpl : public BaseMatcherImpl { public: PathMatcherImpl(const RequirementRule& rule) - : BaseMatcherImpl(rule), path_(rule.match().path()) {} + : BaseMatcherImpl(rule), path_(rule.match().path()), + path_matcher_(Matchers::PathMatcher::createExact(path_, !case_sensitive_)) {} bool matches(const Http::HeaderMap& headers) const override { - if (BaseMatcherImpl::matchRoute(headers)) { - const Http::HeaderString& path = headers.Path()->value(); - const size_t compare_length = - path.getStringView().length() - Http::Utility::findQueryStringStart(path).length(); - auto real_path = path.getStringView().substr(0, compare_length); - bool match = case_sensitive_ ? real_path == path_ : StringUtil::caseCompare(real_path, path_); - if (match) { - ENVOY_LOG(debug, "Path requirement '{}' matched.", path_); - return true; - } + if (BaseMatcherImpl::matchRoute(headers) && + path_matcher_->match(headers.Path()->value().getStringView())) { + ENVOY_LOG(debug, "Path requirement '{}' matched.", path_); + return true; } return false; } @@ -105,6 +101,7 @@ class PathMatcherImpl : public BaseMatcherImpl { private: // path string. const std::string path_; + const Matchers::PathMatcherConstSharedPtr path_matcher_; }; /** @@ -114,6 +111,7 @@ class PathMatcherImpl : public BaseMatcherImpl { class RegexMatcherImpl : public BaseMatcherImpl { public: RegexMatcherImpl(const RequirementRule& rule) : BaseMatcherImpl(rule) { + // TODO(yangminzhu): Use PathMatcher once hidden_envoy_deprecated_regex is removed. if (rule.match().path_specifier_case() == envoy::config::route::v3::RouteMatch::PathSpecifierCase::kHiddenEnvoyDeprecatedRegex) { regex_ = Regex::Utility::parseStdRegexAsCompiledMatcher( diff --git a/test/common/common/matchers_test.cc b/test/common/common/matchers_test.cc index 3dc918bc7b..7b0d783978 100644 --- a/test/common/common/matchers_test.cc +++ b/test/common/common/matchers_test.cc @@ -364,6 +364,92 @@ TEST(LowerCaseStringMatcher, MatchRegexValue) { EXPECT_FALSE(Envoy::Matchers::LowerCaseStringMatcher(matcher).match("Foo.Bar")); } +TEST(PathMatcher, MatchExactPath) { + const auto matcher = Envoy::Matchers::PathMatcher::createExact("/exact", false); + + EXPECT_TRUE(matcher->match("/exact")); + EXPECT_TRUE(matcher->match("/exact?param=val")); + EXPECT_TRUE(matcher->match("/exact#fragment")); + EXPECT_TRUE(matcher->match("/exact#fragment?param=val")); + EXPECT_FALSE(matcher->match("/EXACT")); + EXPECT_FALSE(matcher->match("/exacz")); + EXPECT_FALSE(matcher->match("/exact-abc")); + EXPECT_FALSE(matcher->match("/exacz?/exact")); + EXPECT_FALSE(matcher->match("/exacz#/exact")); +} + +TEST(PathMatcher, MatchExactPathIgnoreCase) { + const auto matcher = Envoy::Matchers::PathMatcher::createExact("/exact", true); + + EXPECT_TRUE(matcher->match("/exact")); + EXPECT_TRUE(matcher->match("/EXACT")); + EXPECT_TRUE(matcher->match("/exact?param=val")); + EXPECT_TRUE(matcher->match("/Exact#fragment")); + EXPECT_TRUE(matcher->match("/EXACT#fragment?param=val")); + EXPECT_FALSE(matcher->match("/exacz")); + EXPECT_FALSE(matcher->match("/exact-abc")); + EXPECT_FALSE(matcher->match("/exacz?/exact")); + EXPECT_FALSE(matcher->match("/exacz#/exact")); +} + +TEST(PathMatcher, MatchPrefixPath) { + const auto matcher = Envoy::Matchers::PathMatcher::createPrefix("/prefix", false); + + EXPECT_TRUE(matcher->match("/prefix")); + EXPECT_TRUE(matcher->match("/prefix-abc")); + EXPECT_TRUE(matcher->match("/prefix?param=val")); + EXPECT_TRUE(matcher->match("/prefix#fragment")); + EXPECT_TRUE(matcher->match("/prefix#fragment?param=val")); + EXPECT_FALSE(matcher->match("/PREFIX")); + EXPECT_FALSE(matcher->match("/prefiz")); + EXPECT_FALSE(matcher->match("/prefiz?/prefix")); + EXPECT_FALSE(matcher->match("/prefiz#/prefix")); +} + +TEST(PathMatcher, MatchPrefixPathIgnoreCase) { + const auto matcher = Envoy::Matchers::PathMatcher::createPrefix("/prefix", true); + + EXPECT_TRUE(matcher->match("/prefix")); + EXPECT_TRUE(matcher->match("/prefix-abc")); + EXPECT_TRUE(matcher->match("/Prefix?param=val")); + EXPECT_TRUE(matcher->match("/Prefix#fragment")); + EXPECT_TRUE(matcher->match("/PREFIX#fragment?param=val")); + EXPECT_TRUE(matcher->match("/PREFIX")); + EXPECT_FALSE(matcher->match("/prefiz")); + EXPECT_FALSE(matcher->match("/prefiz?/prefix")); + EXPECT_FALSE(matcher->match("/prefiz#/prefix")); +} + +TEST(PathMatcher, MatchSuffixPath) { + envoy::type::matcher::v3::PathMatcher matcher; + matcher.mutable_path()->set_suffix("suffix"); + + EXPECT_TRUE(Matchers::PathMatcher(matcher).match("/suffix")); + EXPECT_TRUE(Matchers::PathMatcher(matcher).match("/abc-suffix")); + EXPECT_TRUE(Matchers::PathMatcher(matcher).match("/suffix?param=val")); + EXPECT_TRUE(Matchers::PathMatcher(matcher).match("/suffix#fragment")); + EXPECT_TRUE(Matchers::PathMatcher(matcher).match("/suffix#fragment?param=val")); + EXPECT_FALSE(Matchers::PathMatcher(matcher).match("/suffiz")); + EXPECT_FALSE(Matchers::PathMatcher(matcher).match("/suffiz?param=suffix")); + EXPECT_FALSE(Matchers::PathMatcher(matcher).match("/suffiz#suffix")); +} + +TEST(PathMatcher, MatchRegexPath) { + envoy::type::matcher::v3::StringMatcher matcher; + matcher.mutable_safe_regex()->mutable_google_re2(); + matcher.mutable_safe_regex()->set_regex(".*regex.*"); + + EXPECT_TRUE(Matchers::PathMatcher(matcher).match("/regex")); + EXPECT_TRUE(Matchers::PathMatcher(matcher).match("/regex/xyz")); + EXPECT_TRUE(Matchers::PathMatcher(matcher).match("/xyz/regex")); + EXPECT_TRUE(Matchers::PathMatcher(matcher).match("/regex?param=val")); + EXPECT_TRUE(Matchers::PathMatcher(matcher).match("/regex#fragment")); + EXPECT_TRUE(Matchers::PathMatcher(matcher).match("/regex#fragment?param=val")); + EXPECT_FALSE(Matchers::PathMatcher(matcher).match("/regez")); + EXPECT_FALSE(Matchers::PathMatcher(matcher).match("/regez?param=regex")); + EXPECT_FALSE(Matchers::PathMatcher(matcher).match("/regez#regex")); +} + } // namespace } // namespace Matcher } // namespace Envoy diff --git a/test/common/http/path_utility_test.cc b/test/common/http/path_utility_test.cc index c2a7230f63..9c313ea3ec 100644 --- a/test/common/http/path_utility_test.cc +++ b/test/common/http/path_utility_test.cc @@ -107,5 +107,25 @@ TEST_F(PathUtilityTest, MergeSlashes) { EXPECT_EQ("/a/b?", mergeSlashes("/a//b?")); // empty query } +TEST_F(PathUtilityTest, RemoveQueryAndFragment) { + EXPECT_EQ("", PathUtil::removeQueryAndFragment("")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc?")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc?param=value")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc?param=value1¶m=value2")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc??")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc??param=value")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc#")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc#fragment")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc#fragment?param=value")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc##")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc#?")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc#?param=value")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc?#")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc?#fragment")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc?param=value#")); + EXPECT_EQ("/abc", PathUtil::removeQueryAndFragment("/abc?param=value#fragment")); +} + } // namespace Http } // namespace Envoy diff --git a/test/extensions/filters/common/rbac/matchers_test.cc b/test/extensions/filters/common/rbac/matchers_test.cc index 61d4072f40..13243b01f4 100644 --- a/test/extensions/filters/common/rbac/matchers_test.cc +++ b/test/extensions/filters/common/rbac/matchers_test.cc @@ -375,6 +375,33 @@ TEST(RequestedServerNameMatcher, EmptyRequestedServerName) { conn); } +TEST(PathMatcher, NoPathInHeader) { + Envoy::Http::HeaderMapImpl headers; + envoy::type::matcher::v3::PathMatcher matcher; + matcher.mutable_path()->mutable_safe_regex()->mutable_google_re2(); + matcher.mutable_path()->mutable_safe_regex()->set_regex(".*"); + + headers.setPath("/path"); + checkMatcher(PathMatcher(matcher), true, Envoy::Network::MockConnection(), headers); + headers.removePath(); + checkMatcher(PathMatcher(matcher), false, Envoy::Network::MockConnection(), headers); +} + +TEST(PathMatcher, ValidPathInHeader) { + Envoy::Http::HeaderMapImpl headers; + envoy::type::matcher::v3::PathMatcher matcher; + matcher.mutable_path()->set_exact("/exact"); + + headers.setPath("/exact"); + checkMatcher(PathMatcher(matcher), true, Envoy::Network::MockConnection(), headers); + headers.setPath("/exact?param=val"); + checkMatcher(PathMatcher(matcher), true, Envoy::Network::MockConnection(), headers); + headers.setPath("/exact#fragment"); + checkMatcher(PathMatcher(matcher), true, Envoy::Network::MockConnection(), headers); + headers.setPath("/exacz"); + checkMatcher(PathMatcher(matcher), false, Envoy::Network::MockConnection(), headers); +} + } // namespace } // namespace RBAC } // namespace Common diff --git a/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc b/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc index 8c6affba92..23a4609ab4 100644 --- a/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc +++ b/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc @@ -36,6 +36,34 @@ name: envoy.filters.http.rbac - any: true )EOF"; +const std::string RBAC_CONFIG_WITH_PATH_EXACT_MATCH = R"EOF( +name: envoy.filters.http.rbac +typed_config: + "@type": type.googleapis.com/envoy.config.filter.http.rbac.v2.RBAC + rules: + policies: + foo: + permissions: + - url_path: + path: { exact: "/allow" } + principals: + - any: true +)EOF"; + +const std::string RBAC_CONFIG_WITH_PATH_IGNORE_CASE_MATCH = R"EOF( +name: envoy.filters.http.rbac +typed_config: + "@type": type.googleapis.com/envoy.config.filter.http.rbac.v2.RBAC + rules: + policies: + foo: + permissions: + - url_path: + path: { exact: "/ignore_case", ignore_case: true } + principals: + - any: true +)EOF"; + using RBACIntegrationTest = HttpProtocolIntegrationTest; INSTANTIATE_TEST_SUITE_P(Protocols, RBACIntegrationTest, @@ -195,5 +223,59 @@ TEST_P(RBACIntegrationTest, RouteOverride) { EXPECT_EQ("200", response->headers().Status()->value().getStringView()); } +TEST_P(RBACIntegrationTest, PathWithQueryAndFragment) { + config_helper_.addFilter(RBAC_CONFIG_WITH_PATH_EXACT_MATCH); + initialize(); + + codec_client_ = makeHttpConnection(lookupPort("http")); + + const std::vector paths{"/allow", "/allow?p1=v1&p2=v2", "/allow?p1=v1#seg"}; + + for (const auto& path : paths) { + auto response = codec_client_->makeRequestWithBody( + Http::TestHeaderMapImpl{ + {":method", "POST"}, + {":path", path}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + }, + 1024); + waitForNextUpstreamRequest(); + upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + + response->waitForEndStream(); + ASSERT_TRUE(response->complete()); + EXPECT_EQ("200", response->headers().Status()->value().getStringView()); + } +} + +TEST_P(RBACIntegrationTest, PathIgnoreCase) { + config_helper_.addFilter(RBAC_CONFIG_WITH_PATH_IGNORE_CASE_MATCH); + initialize(); + + codec_client_ = makeHttpConnection(lookupPort("http")); + + const std::vector paths{"/ignore_case", "/IGNORE_CASE", "/ignore_CASE"}; + + for (const auto& path : paths) { + auto response = codec_client_->makeRequestWithBody( + Http::TestHeaderMapImpl{ + {":method", "POST"}, + {":path", path}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + }, + 1024); + waitForNextUpstreamRequest(); + upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + + response->waitForEndStream(); + ASSERT_TRUE(response->complete()); + EXPECT_EQ("200", response->headers().Status()->value().getStringView()); + } +} + } // namespace } // namespace Envoy diff --git a/test/extensions/filters/http/rbac/rbac_filter_test.cc b/test/extensions/filters/http/rbac/rbac_filter_test.cc index a82d7834b9..1e27049cc6 100644 --- a/test/extensions/filters/http/rbac/rbac_filter_test.cc +++ b/test/extensions/filters/http/rbac/rbac_filter_test.cc @@ -34,6 +34,7 @@ class RoleBasedAccessControlFilterTest : public testing::Test { policy_rules->add_rules()->mutable_requested_server_name()->set_hidden_envoy_deprecated_regex( ".*cncf.io"); policy_rules->add_rules()->set_destination_port(123); + policy_rules->add_rules()->mutable_url_path()->mutable_path()->set_suffix("suffix"); policy.add_principals()->set_any(true); config.mutable_rules()->set_action(envoy::config::rbac::v3::RBAC::ALLOW); (*config.mutable_rules()->mutable_policies())["foo"] = policy; @@ -117,6 +118,18 @@ TEST_F(RoleBasedAccessControlFilterTest, RequestedServerName) { EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(headers_)); } +TEST_F(RoleBasedAccessControlFilterTest, Path) { + setDestinationPort(999); + + auto headers = Http::TestHeaderMapImpl{ + {":method", "GET"}, + {":path", "/suffix#seg?param=value"}, + {":scheme", "http"}, + {":authority", "host"}, + }; + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(headers, false)); +} + TEST_F(RoleBasedAccessControlFilterTest, Denied) { setDestinationPort(456); setMetadata(); From 59d0436872c83458fec7366ac36cb68e7dd73a8d Mon Sep 17 00:00:00 2001 From: Greg Greenway Date: Wed, 12 Feb 2020 11:46:04 -0800 Subject: [PATCH 47/87] docs: Clarify meaning of per_try_timeout. (#10029) Clarify that this timeout only applies before the response to downstream begins, and thus it works fine for streaming APIs. Signed-off-by: Greg Greenway --- docs/root/configuration/http/http_filters/router_filter.rst | 3 ++- docs/root/faq/configuration/timeouts.rst | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/root/configuration/http/http_filters/router_filter.rst b/docs/root/configuration/http/http_filters/router_filter.rst index bc8ef3ca46..a4e8dd28aa 100644 --- a/docs/root/configuration/http/http_filters/router_filter.rst +++ b/docs/root/configuration/http/http_filters/router_filter.rst @@ -242,7 +242,8 @@ Setting this header on egress requests will cause Envoy to set a *per try* timeo requests. This timeout must be <= the global route timeout (see :ref:`config_http_filters_router_x-envoy-upstream-rq-timeout-ms`) or it is ignored. This allows a caller to set a tight per try timeout to allow for retries while maintaining a reasonable overall -timeout. +timeout. This timeout only applies before any part of the response is sent to the downstream, +which normally happens after the upstream has sent response headers. x-envoy-hedge-on-per-try-timeout ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/root/faq/configuration/timeouts.rst b/docs/root/faq/configuration/timeouts.rst index 46d927acf2..a77c72eba5 100644 --- a/docs/root/faq/configuration/timeouts.rst +++ b/docs/root/faq/configuration/timeouts.rst @@ -75,9 +75,8 @@ stream timeouts already introduced above. and does the same thing. * The route :ref:`per_try_timeout ` can be configured when using retries so that individual tries using a shorter timeout than the overall - request timeout described above. This type of timeout will not work with streaming APIs (in which - retries are typically not possible) but is useful for decreasing the tail latency of non-streaming - APIs. + request timeout described above. This timeout only applies before any part of the response + is sent to the downstream, which normally happens after the upstream has sent response headers. TCP --- From 38fe5e1ec115c0b2e83921211c2646f160a91681 Mon Sep 17 00:00:00 2001 From: "R. Kelsey Savage" Date: Wed, 12 Feb 2020 13:46:47 -0600 Subject: [PATCH 48/87] Typo fixes in gRPC-JSON Transcoder example (#10031) Signed-off-by: R. Kelsey Savage --- .../http/http_filters/grpc_json_transcoder_filter.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/root/configuration/http/http_filters/grpc_json_transcoder_filter.rst b/docs/root/configuration/http/http_filters/grpc_json_transcoder_filter.rst index 9bd750b628..0cf4222b80 100644 --- a/docs/root/configuration/http/http_filters/grpc_json_transcoder_filter.rst +++ b/docs/root/configuration/http/http_filters/grpc_json_transcoder_filter.rst @@ -121,9 +121,9 @@ gRPC or RESTful JSON requests to localhost:51051. - match: { prefix: "/helloworld.Greeter" } route: { cluster: grpc, timeout: { seconds: 60 } } http_filters: - - name: envoy. - "@type": type.googleapis.com/envoy.config.filter.http.transcoder.v2.GrpcJsonTranscoder + - name: envoy.grpc_json_transcoder typed_config: + "@type": type.googleapis.com/envoy.config.filter.http.transcoder.v2.GrpcJsonTranscoder proto_descriptor: "/tmp/envoy/proto.pb" services: ["helloworld.Greeter"] print_options: From be1051947a19010a4f5870d0ad561ef5979be9fe Mon Sep 17 00:00:00 2001 From: zyfjeff Date: Fri, 14 Feb 2020 00:30:36 +0800 Subject: [PATCH 49/87] docs: fix incorrect description (#10045) Admin /memory should be GET, not POST Risk Level: low Testing: N/A Docs Changes: yes Release Notes: N/A Signed-off-by: tianqian.zyf --- docs/root/operations/admin.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/root/operations/admin.rst b/docs/root/operations/admin.rst index da5f2e2658..b1e34de6b0 100644 --- a/docs/root/operations/admin.rst +++ b/docs/root/operations/admin.rst @@ -232,7 +232,7 @@ modify different aspects of the server: Generally only used during development. -.. http:post:: /memory +.. http:get:: /memory Prints current memory allocation / heap usage, in bytes. Useful in lieu of printing all `/stats` and filtering to get the memory-related statistics. From 85a8e8ce7a3d662cf2fffc0ed9a50c0a986bb457 Mon Sep 17 00:00:00 2001 From: rulex123 <29862113+rulex123@users.noreply.github.com> Date: Thu, 13 Feb 2020 18:22:54 +0100 Subject: [PATCH 50/87] Tools: group code formatting files under new folder in tools (#9978) Signed-off-by: Erica Manno --- bazel/README.md | 4 ++-- ci/do_ci.sh | 10 +++++----- include/envoy/stats/primitive_stats_macros.h | 2 +- include/envoy/stats/stats_macros.h | 2 +- support/README.md | 2 +- support/hooks/pre-push | 4 ++-- tools/BUILD | 6 +++--- tools/check_format_test.sh | 7 ------- tools/{ => code_format}/.style.yapf | 0 tools/{ => code_format}/check_format.py | 2 +- tools/code_format/check_format_test.sh | 7 +++++++ tools/{ => code_format}/check_format_test_helper.py | 5 +++-- tools/code_format/check_format_test_helper.sh | 9 +++++++++ tools/{ => code_format}/common.py | 0 tools/{ => code_format}/envoy_build_fixer.py | 0 tools/{ => code_format}/format_python_tools.py | 2 +- tools/{ => code_format}/format_python_tools.sh | 0 tools/{ => code_format}/header_order.py | 0 tools/{ => code_format}/paths.py | 0 tools/{ => code_format}/requirements.txt | 0 20 files changed, 36 insertions(+), 26 deletions(-) delete mode 100755 tools/check_format_test.sh rename tools/{ => code_format}/.style.yapf (100%) rename tools/{ => code_format}/check_format.py (99%) create mode 100755 tools/code_format/check_format_test.sh rename tools/{ => code_format}/check_format_test_helper.py (98%) create mode 100755 tools/code_format/check_format_test_helper.sh rename tools/{ => code_format}/common.py (100%) rename tools/{ => code_format}/envoy_build_fixer.py (100%) rename tools/{ => code_format}/format_python_tools.py (98%) rename tools/{ => code_format}/format_python_tools.sh (100%) rename tools/{ => code_format}/header_order.py (100%) rename tools/{ => code_format}/paths.py (100%) rename tools/{ => code_format}/requirements.txt (100%) diff --git a/bazel/README.md b/bazel/README.md index 3bdd2fee08..124323b82d 100644 --- a/bazel/README.md +++ b/bazel/README.md @@ -618,9 +618,9 @@ export BUILDIFIER_BIN="/usr/bin/buildifier" Once this is set up, you can run clang-format without docker: ```shell -./tools/check_format.py check +./tools/code_format/check_format.py check ./tools/check_spelling.sh check -./tools/check_format.py fix +./tools/code_format/check_format.py fix ./tools/check_spelling.sh fix ``` diff --git a/ci/do_ci.sh b/ci/do_ci.sh index bb7634c75d..1577e8a4a0 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -306,18 +306,18 @@ elif [[ "$CI_TARGET" == "fix_format" ]]; then echo "protoxform_test..." ./tools/protoxform_test.sh echo "fix_format..." - ./tools/check_format.py fix - ./tools/format_python_tools.sh fix + ./tools/code_format/check_format.py fix + ./tools/code_format/format_python_tools.sh fix ./tools/proto_format.sh fix exit 0 elif [[ "$CI_TARGET" == "check_format" ]]; then # proto_format.sh needs to build protobuf. setup_clang_toolchain echo "check_format_test..." - ./tools/check_format_test_helper.py --log=WARN + ./tools/code_format/check_format_test_helper.sh --log=WARN echo "check_format..." - ./tools/check_format.py check - ./tools/format_python_tools.sh check + ./tools/code_format/check_format.py check + ./tools/code_format/format_python_tools.sh check ./tools/proto_format.sh check exit 0 elif [[ "$CI_TARGET" == "check_repositories" ]]; then diff --git a/include/envoy/stats/primitive_stats_macros.h b/include/envoy/stats/primitive_stats_macros.h index 9b51f99f33..a3b2713bad 100644 --- a/include/envoy/stats/primitive_stats_macros.h +++ b/include/envoy/stats/primitive_stats_macros.h @@ -17,7 +17,7 @@ namespace Envoy { * * By convention, starting with #7083, we sort the lines of this macro block, so * all the counters are grouped together, then all the gauges, etc. We do not - * use clang-format-on/off etc. "./tools/check_format.py fix" will take care of + * use clang-format-on/off etc. "./tools/code_format/check_format.py fix" will take care of * lining up the backslashes. * * Now actually put these stats somewhere, usually as a member of a struct: diff --git a/include/envoy/stats/stats_macros.h b/include/envoy/stats/stats_macros.h index feabf19eb2..1cd3212e89 100644 --- a/include/envoy/stats/stats_macros.h +++ b/include/envoy/stats/stats_macros.h @@ -22,7 +22,7 @@ namespace Envoy { * * By convention, starting with #7083, we sort the lines of this macro block, so * all the counters are grouped together, then all the gauges, etc. We do not - * use clang-format-on/off etc. "./tools/check_format.py fix" will take care of + * use clang-format-on/off etc. "./tools/code_format/check_format.py fix" will take care of * lining up the backslashes. * * Now actually put these stats somewhere, usually as a member of a struct: diff --git a/support/README.md b/support/README.md index 7b8666dfcc..0217da6b0c 100644 --- a/support/README.md +++ b/support/README.md @@ -44,7 +44,7 @@ affected files manually or run the provided formatting script. To run the format fix script directly: ``` -./tools/check_format.py fix && ./tools/format_python_tools.sh fix +./tools/code_format/check_format.py fix && ./tools/code_format/format_python_tools.sh fix ``` To run the format fix script under Docker: diff --git a/support/hooks/pre-push b/support/hooks/pre-push index faaac2320b..8f66491576 100755 --- a/support/hooks/pre-push +++ b/support/hooks/pre-push @@ -59,7 +59,7 @@ do # either of these things aren't true, the check fails. for i in $(git diff --name-only $RANGE --diff-filter=ACMR --ignore-submodules=all 2>&1); do echo -ne " Checking format for $i - " - "$SCRIPT_DIR"/check_format.py check $i + "$SCRIPT_DIR"/code_format/check_format.py check $i if [[ $? -ne 0 ]]; then exit 1 fi @@ -77,7 +77,7 @@ do exit 1 fi - "$SCRIPT_DIR"/format_python_tools.sh check + "$SCRIPT_DIR"/code_format/format_python_tools.sh check if [[ $? -ne 0 ]]; then exit 1 fi diff --git a/tools/BUILD b/tools/BUILD index a4699559ae..dbf854b104 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -12,9 +12,9 @@ envoy_package() exports_files([ "gen_git_sha.sh", - "check_format.py", - "header_order.py", - "envoy_build_fixer.py", + "code_format/check_format.py", + "code_format/header_order.py", + "code_format/envoy_build_fixer.py", "check_repositories.sh", ]) diff --git a/tools/check_format_test.sh b/tools/check_format_test.sh deleted file mode 100755 index 6be24de469..0000000000 --- a/tools/check_format_test.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -tools=$(dirname $(realpath $0)) -root=$(realpath $tools/..) -ci=$root/ci -cd $root -exec ./ci/run_envoy_docker.sh ./tools/check_format_test_helper.py "$@" diff --git a/tools/.style.yapf b/tools/code_format/.style.yapf similarity index 100% rename from tools/.style.yapf rename to tools/code_format/.style.yapf diff --git a/tools/check_format.py b/tools/code_format/check_format.py similarity index 99% rename from tools/check_format.py rename to tools/code_format/check_format.py index bc481bc67f..34966071f5 100755 --- a/tools/check_format.py +++ b/tools/code_format/check_format.py @@ -968,7 +968,7 @@ def ownedDirectories(error_messages): error_messages += sum((r.get() for r in results), []) if checkErrorMessages(error_messages): - print("ERROR: check format failed. run 'tools/check_format.py fix'") + print("ERROR: check format failed. run 'tools/code_format/check_format.py fix'") sys.exit(1) if operation_type == "check": diff --git a/tools/code_format/check_format_test.sh b/tools/code_format/check_format_test.sh new file mode 100755 index 0000000000..4a26201326 --- /dev/null +++ b/tools/code_format/check_format_test.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +tools=$(dirname $(dirname $(realpath $0))) +root=$(realpath $tools/..) +ci=$root/ci +cd $root +exec ./ci/run_envoy_docker.sh ./tools/code_format/check_format_test_helper.sh "$@" \ No newline at end of file diff --git a/tools/check_format_test_helper.py b/tools/code_format/check_format_test_helper.py similarity index 98% rename from tools/check_format_test_helper.py rename to tools/code_format/check_format_test_helper.py index ac1cd083ee..7dfefb8758 100755 --- a/tools/check_format_test_helper.py +++ b/tools/code_format/check_format_test_helper.py @@ -15,9 +15,10 @@ import sys import tempfile -tools = os.path.dirname(os.path.realpath(__file__)) +curr_dir = os.path.dirname(os.path.realpath(__file__)) +tools = os.path.dirname(curr_dir) src = os.path.join(tools, 'testdata', 'check_format') -check_format = sys.executable + " " + os.path.join(tools, 'check_format.py') +check_format = sys.executable + " " + os.path.join(curr_dir, 'check_format.py') errors = 0 diff --git a/tools/code_format/check_format_test_helper.sh b/tools/code_format/check_format_test_helper.sh new file mode 100755 index 0000000000..3a62c96f9f --- /dev/null +++ b/tools/code_format/check_format_test_helper.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +tools=$(dirname $(dirname $(realpath $0))) +root=$(realpath $tools/..) + +cd $root +# to satisfy dependency on run_command +export PYTHONPATH="$tools" +./tools/code_format/check_format_test_helper.py "$@" diff --git a/tools/common.py b/tools/code_format/common.py similarity index 100% rename from tools/common.py rename to tools/code_format/common.py diff --git a/tools/envoy_build_fixer.py b/tools/code_format/envoy_build_fixer.py similarity index 100% rename from tools/envoy_build_fixer.py rename to tools/code_format/envoy_build_fixer.py diff --git a/tools/format_python_tools.py b/tools/code_format/format_python_tools.py similarity index 98% rename from tools/format_python_tools.py rename to tools/code_format/format_python_tools.py index 9d56bcc9d9..bae8eae83c 100644 --- a/tools/format_python_tools.py +++ b/tools/code_format/format_python_tools.py @@ -39,7 +39,7 @@ def validateFormat(fix=False): successful_update_files = set() for python_file in collectFiles(): reformatted_source, encoding, changed = FormatFile(python_file, - style_config='tools/.style.yapf', + style_config='tools/code_format/.style.yapf', in_place=fix, print_diff=not fix) if not fix: diff --git a/tools/format_python_tools.sh b/tools/code_format/format_python_tools.sh similarity index 100% rename from tools/format_python_tools.sh rename to tools/code_format/format_python_tools.sh diff --git a/tools/header_order.py b/tools/code_format/header_order.py similarity index 100% rename from tools/header_order.py rename to tools/code_format/header_order.py diff --git a/tools/paths.py b/tools/code_format/paths.py similarity index 100% rename from tools/paths.py rename to tools/code_format/paths.py diff --git a/tools/requirements.txt b/tools/code_format/requirements.txt similarity index 100% rename from tools/requirements.txt rename to tools/code_format/requirements.txt From 7e7c3ea4589f976fdf5cbe2de11af7ebfbd7e5b6 Mon Sep 17 00:00:00 2001 From: Rama Chavali Date: Thu, 13 Feb 2020 10:58:51 -0800 Subject: [PATCH 51/87] tls: follow dns matching semantics in match subject alt names (#10005) Signed-off-by: Rama Chavali --- api/envoy/api/v2/auth/cert.proto | 10 ++++++++++ .../extensions/transport_sockets/tls/v3/cert.proto | 10 ++++++++++ generated_api_shadow/envoy/api/v2/auth/cert.proto | 10 ++++++++++ .../extensions/transport_sockets/tls/v3/cert.proto | 10 ++++++++++ source/common/common/matchers.h | 2 ++ .../extensions/transport_sockets/tls/context_impl.cc | 7 ++++++- .../transport_sockets/tls/context_impl_test.cc | 11 +++++++++++ 7 files changed, 59 insertions(+), 1 deletion(-) diff --git a/api/envoy/api/v2/auth/cert.proto b/api/envoy/api/v2/auth/cert.proto index 7ddc11c780..52e5e29a83 100644 --- a/api/envoy/api/v2/auth/cert.proto +++ b/api/envoy/api/v2/auth/cert.proto @@ -289,6 +289,16 @@ message CertificateValidationContext { // An optional list of Subject Alternative name matchers. Envoy will verify that the // Subject Alternative Name of the presented certificate matches one of the specified matches. // + // When a certificate has wildcard DNS SAN entries, to match a specific client, it should be + // configured with exact match type in the :ref:`string matcher `. + // For example if the certificate has "\*.example.com" as DNS SAN entry, to allow only "api.example.com", + // it should be configured as shown below. + // + // .. code-block:: yaml + // + // match_subject_alt_names: + // exact: "api.example.com" + // // .. attention:: // // Subject Alternative Names are easily spoofable and verifying only them is insecure, diff --git a/api/envoy/extensions/transport_sockets/tls/v3/cert.proto b/api/envoy/extensions/transport_sockets/tls/v3/cert.proto index 123d56e306..8c6ee3d88d 100644 --- a/api/envoy/extensions/transport_sockets/tls/v3/cert.proto +++ b/api/envoy/extensions/transport_sockets/tls/v3/cert.proto @@ -296,6 +296,16 @@ message CertificateValidationContext { // An optional list of Subject Alternative name matchers. Envoy will verify that the // Subject Alternative Name of the presented certificate matches one of the specified matches. // + // When a certificate has wildcard DNS SAN entries, to match a specific client, it should be + // configured with exact match type in the :ref:`string matcher `. + // For example if the certificate has "\*.example.com" as DNS SAN entry, to allow only "api.example.com", + // it should be configured as shown below. + // + // .. code-block:: yaml + // + // match_subject_alt_names: + // exact: "api.example.com" + // // .. attention:: // // Subject Alternative Names are easily spoofable and verifying only them is insecure, diff --git a/generated_api_shadow/envoy/api/v2/auth/cert.proto b/generated_api_shadow/envoy/api/v2/auth/cert.proto index 7ddc11c780..52e5e29a83 100644 --- a/generated_api_shadow/envoy/api/v2/auth/cert.proto +++ b/generated_api_shadow/envoy/api/v2/auth/cert.proto @@ -289,6 +289,16 @@ message CertificateValidationContext { // An optional list of Subject Alternative name matchers. Envoy will verify that the // Subject Alternative Name of the presented certificate matches one of the specified matches. // + // When a certificate has wildcard DNS SAN entries, to match a specific client, it should be + // configured with exact match type in the :ref:`string matcher `. + // For example if the certificate has "\*.example.com" as DNS SAN entry, to allow only "api.example.com", + // it should be configured as shown below. + // + // .. code-block:: yaml + // + // match_subject_alt_names: + // exact: "api.example.com" + // // .. attention:: // // Subject Alternative Names are easily spoofable and verifying only them is insecure, diff --git a/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto b/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto index 261dd35ceb..61e5b21788 100644 --- a/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto +++ b/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto @@ -301,6 +301,16 @@ message CertificateValidationContext { // An optional list of Subject Alternative name matchers. Envoy will verify that the // Subject Alternative Name of the presented certificate matches one of the specified matches. // + // When a certificate has wildcard DNS SAN entries, to match a specific client, it should be + // configured with exact match type in the :ref:`string matcher `. + // For example if the certificate has "\*.example.com" as DNS SAN entry, to allow only "api.example.com", + // it should be configured as shown below. + // + // .. code-block:: yaml + // + // match_subject_alt_names: + // exact: "api.example.com" + // // .. attention:: // // Subject Alternative Names are easily spoofable and verifying only them is insecure, diff --git a/source/common/common/matchers.h b/source/common/common/matchers.h index 0d07dfc6e6..a6d0f6dc2d 100644 --- a/source/common/common/matchers.h +++ b/source/common/common/matchers.h @@ -83,6 +83,8 @@ class StringMatcherImpl : public ValueMatcher, public StringMatcher { bool match(const absl::string_view value) const override; bool match(const ProtobufWkt::Value& value) const override; + const envoy::type::matcher::v3::StringMatcher& matcher() const { return matcher_; } + private: const envoy::type::matcher::v3::StringMatcher matcher_; Regex::CompiledMatcherPtr regex_; diff --git a/source/extensions/transport_sockets/tls/context_impl.cc b/source/extensions/transport_sockets/tls/context_impl.cc index 907ad4720c..11d69e20be 100644 --- a/source/extensions/transport_sockets/tls/context_impl.cc +++ b/source/extensions/transport_sockets/tls/context_impl.cc @@ -690,7 +690,12 @@ bool ContextImpl::matchSubjectAltName( for (const GENERAL_NAME* general_name : san_names.get()) { const std::string san = generalNameAsString(general_name); for (auto& config_san_matcher : subject_alt_name_matchers) { - if (config_san_matcher.match(san)) { + // For DNS SAN, if the StringMatcher type is exact, we have to follow DNS matching semantics. + if (general_name->type == GEN_DNS && + config_san_matcher.matcher().match_pattern_case() == + envoy::type::matcher::v3::StringMatcher::MatchPatternCase::kExact + ? dnsNameMatch(config_san_matcher.matcher().exact(), san.c_str()) + : config_san_matcher.match(san)) { return true; } } diff --git a/test/extensions/transport_sockets/tls/context_impl_test.cc b/test/extensions/transport_sockets/tls/context_impl_test.cc index abd80b643d..dec545d5a1 100644 --- a/test/extensions/transport_sockets/tls/context_impl_test.cc +++ b/test/extensions/transport_sockets/tls/context_impl_test.cc @@ -75,6 +75,17 @@ TEST_F(SslContextImplTest, TestMatchSubjectAltNameDNSMatched) { EXPECT_TRUE(ContextImpl::matchSubjectAltName(cert.get(), subject_alt_name_matchers)); } +TEST_F(SslContextImplTest, TestMatchSubjectAltNameWildcardDNSMatched) { + bssl::UniquePtr cert = readCertFromFile(TestEnvironment::substitute( + "{{ test_rundir " + "}}/test/extensions/transport_sockets/tls/test_data/san_multiple_dns_cert.pem")); + envoy::type::matcher::v3::StringMatcher matcher; + matcher.set_exact("api.example.com"); + std::vector subject_alt_name_matchers; + subject_alt_name_matchers.push_back(Matchers::StringMatcherImpl(matcher)); + EXPECT_TRUE(ContextImpl::matchSubjectAltName(cert.get(), subject_alt_name_matchers)); +} + TEST_F(SslContextImplTest, TestVerifySubjectAltNameURIMatched) { bssl::UniquePtr cert = readCertFromFile(TestEnvironment::substitute( "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/san_uri_cert.pem")); From c0ab3a4374144728c1e193fc2d43951ed36ccdb7 Mon Sep 17 00:00:00 2001 From: Stephan Zuercher Date: Thu, 13 Feb 2020 11:58:14 -0800 Subject: [PATCH 52/87] network filters: use new style names (#10043) Modifies the well-known-names of the built-in network filters to use the same names as the extension build system. Risk Level: low, previous name is still accepted Testing: existing tests + deprecated tests for old names Docs Changes: updated names Release Notes: updated Deprecated: old names are logged as deprecated Signed-off-by: Stephan Zuercher --- .../network/redis_proxy/v2/redis_proxy.proto | 2 +- .../network/redis_proxy/v3/redis_proxy.proto | 2 +- configs/envoy_double_proxy_v2.template.yaml | 2 +- configs/envoy_front_proxy_v2.template.yaml | 2 +- .../envoy_service_to_service_v2.template.yaml | 14 ++++++------- configs/freebind/freebind.yaml | 2 +- configs/google_com_proxy.v2.yaml | 2 +- .../original-dst-cluster/proxy_config.yaml | 2 +- configs/using_deprecated_config.v2.yaml | 2 +- .../configuration/best_practices/edge.rst | 2 +- .../dynamic_forward_proxy_filter.rst | 2 +- .../grpc_http1_reverse_bridge_filter.rst | 2 +- .../grpc_json_transcoder_filter.rst | 2 +- .../client_ssl_auth_filter.rst | 2 +- .../listeners/network_filters/echo_filter.rst | 2 +- .../network_filters/ext_authz_filter.rst | 4 ++-- .../network_filters/kafka_broker_filter.rst | 2 +- .../network_filters/mongo_proxy_filter.rst | 2 +- .../network_filters/mysql_proxy_filter.rst | 4 ++-- .../network_filters/rate_limit_filter.rst | 2 +- .../network_filters/redis_proxy_filter.rst | 2 +- .../network_filters/tcp_proxy_filter.rst | 2 +- .../zookeeper_proxy_filter.rst | 2 +- docs/root/configuration/overview/examples.rst | 6 +++--- docs/root/faq/configuration/flow_control.rst | 2 +- docs/root/faq/configuration/sni.rst | 4 ++-- .../root/intro/arch_overview/security/ssl.rst | 2 +- docs/root/intro/deprecated.rst | 12 +++++++++-- docs/root/intro/version_history.rst | 2 ++ docs/root/start/start.rst | 2 +- examples/cors/backend/front-envoy.yaml | 2 +- examples/cors/backend/service-envoy.yaml | 2 +- examples/cors/frontend/front-envoy.yaml | 2 +- examples/cors/frontend/service-envoy.yaml | 2 +- examples/csrf/crosssite/front-envoy.yaml | 2 +- examples/csrf/samesite/front-envoy.yaml | 2 +- examples/csrf/service-envoy.yaml | 2 +- examples/fault-injection/envoy.yaml | 2 +- examples/front-proxy/front-envoy.yaml | 2 +- examples/front-proxy/service-envoy.yaml | 2 +- examples/grpc-bridge/client/envoy-proxy.yaml | 2 +- examples/grpc-bridge/server/envoy-proxy.yaml | 2 +- .../front-envoy-jaeger.yaml | 2 +- .../service1-envoy-jaeger.yaml | 4 ++-- .../service2-envoy-jaeger.yaml | 2 +- .../jaeger-tracing/front-envoy-jaeger.yaml | 2 +- .../jaeger-tracing/service1-envoy-jaeger.yaml | 4 ++-- .../jaeger-tracing/service2-envoy-jaeger.yaml | 2 +- examples/lua/envoy.yaml | 2 +- examples/mysql/envoy.yaml | 2 +- examples/redis/envoy.yaml | 2 +- .../zipkin-tracing/front-envoy-zipkin.yaml | 2 +- .../zipkin-tracing/service1-envoy-zipkin.yaml | 4 ++-- .../zipkin-tracing/service2-envoy-zipkin.yaml | 2 +- .../network/redis_proxy/v2/redis_proxy.proto | 2 +- .../network/redis_proxy/v3/redis_proxy.proto | 2 +- .../filters/network/client_ssl_auth/config.cc | 2 +- .../extensions/filters/network/echo/config.cc | 3 ++- .../filters/network/ext_authz/config.cc | 3 ++- .../network/http_connection_manager/config.cc | 3 ++- .../filters/network/mongo_proxy/config.cc | 2 +- .../filters/network/ratelimit/config.cc | 3 ++- .../filters/network/redis_proxy/config.cc | 2 +- .../filters/network/tcp_proxy/config.cc | 3 ++- .../filters/network/well_known_names.h | 16 +++++++-------- .../google_com_proxy_port_0.v2.yaml | 2 +- test/config/integration/server.yaml | 4 ++-- .../integration/server_unix_listener.yaml | 2 +- .../server_xds.lds.typed_struct.yaml | 2 +- ...s.lds.with_unknown_field.typed_struct.yaml | 2 +- .../server_xds.lds.with_unknown_field.yaml | 2 +- test/config/integration/server_xds.lds.yaml | 2 +- test/config/utility.cc | 20 +++++++++---------- .../aggregate/cluster_integration_test.cc | 2 +- .../redis/redis_cluster_integration_test.cc | 4 ++-- .../aws_metadata_fetcher_integration_test.cc | 2 +- .../network/client_ssl_auth/config_test.cc | 10 ++++++++++ .../filters/network/ext_authz/config_test.cc | 10 ++++++++++ .../http_connection_manager/config_test.cc | 10 ++++++++++ .../integration_test/envoy_config_yaml.j2 | 2 +- .../network/mongo_proxy/config_test.cc | 10 ++++++++++ .../mysql_proxy/mysql_test_config.yaml | 2 +- .../filters/network/ratelimit/config_test.cc | 10 ++++++++++ .../filters/network/rbac/integration_test.cc | 2 +- .../network/redis_proxy/config_test.cc | 10 ++++++++++ .../redis_proxy_integration_test.cc | 12 +++++------ .../filters/network/tcp_proxy/config_test.cc | 10 ++++++++++ test/integration/ads_integration.cc | 4 ++-- test/integration/echo_integration_test.cc | 6 +++--- .../filter_manager_integration_test.cc | 19 ++++++++++-------- test/integration/vhds_integration_test.cc | 2 +- test/server/listener_manager_impl_test.cc | 10 +++++----- .../server_corpus/google_com_proxy.v2.pb_text | 2 +- .../network_filter_unknown_field.yaml | 2 +- 94 files changed, 226 insertions(+), 138 deletions(-) diff --git a/api/envoy/config/filter/network/redis_proxy/v2/redis_proxy.proto b/api/envoy/config/filter/network/redis_proxy/v2/redis_proxy.proto index f0996392f9..87cdd558fc 100644 --- a/api/envoy/config/filter/network/redis_proxy/v2/redis_proxy.proto +++ b/api/envoy/config/filter/network/redis_proxy/v2/redis_proxy.proto @@ -236,7 +236,7 @@ message RedisProxy { // RedisProtocolOptions specifies Redis upstream protocol options. This object is used in // :ref:`typed_extension_protocol_options`, -// keyed by the name `envoy.redis_proxy`. +// keyed by the name `envoy.filters.network.redis_proxy`. message RedisProtocolOptions { // Upstream server password as defined by the `requirepass` directive // `_ in the server's configuration file. diff --git a/api/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto b/api/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto index 4b1b97de46..26291ad73f 100644 --- a/api/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto +++ b/api/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto @@ -237,7 +237,7 @@ message RedisProxy { // RedisProtocolOptions specifies Redis upstream protocol options. This object is used in // :ref:`typed_extension_protocol_options`, -// keyed by the name `envoy.redis_proxy`. +// keyed by the name `envoy.filters.network.redis_proxy`. message RedisProtocolOptions { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.redis_proxy.v2.RedisProtocolOptions"; diff --git a/configs/envoy_double_proxy_v2.template.yaml b/configs/envoy_double_proxy_v2.template.yaml index 3082c1dbff..67e2a25c58 100644 --- a/configs/envoy_double_proxy_v2.template.yaml +++ b/configs/envoy_double_proxy_v2.template.yaml @@ -27,7 +27,7 @@ use_proxy_proto: true {%endif -%} filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager codec_type: AUTO diff --git a/configs/envoy_front_proxy_v2.template.yaml b/configs/envoy_front_proxy_v2.template.yaml index 60894c6cc0..87680f4c0e 100644 --- a/configs/envoy_front_proxy_v2.template.yaml +++ b/configs/envoy_front_proxy_v2.template.yaml @@ -33,7 +33,7 @@ {%endif%} {%endif %} filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager codec_type: AUTO diff --git a/configs/envoy_service_to_service_v2.template.yaml b/configs/envoy_service_to_service_v2.template.yaml index 175e367d79..c365c9a77b 100644 --- a/configs/envoy_service_to_service_v2.template.yaml +++ b/configs/envoy_service_to_service_v2.template.yaml @@ -9,7 +9,7 @@ traffic_direction: INBOUND filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager codec_type: AUTO @@ -109,7 +109,7 @@ static_resources: traffic_direction: OUTBOUND filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager codec_type: AUTO @@ -175,7 +175,7 @@ static_resources: traffic_direction: OUTBOUND filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager codec_type: AUTO @@ -237,7 +237,7 @@ static_resources: port_value: 9901 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager codec_type: AUTO @@ -313,18 +313,18 @@ static_resources: port_value: 9003 filter_chains: - filters: - - name: envoy.tcp_proxy + - name: envoy.filters.network.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy stat_prefix: mongo_{{ key }} cluster: mongo_{{ key }} - - name: envoy.mongo_proxy + - name: envoy.filters.network.mongo_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.mongo_proxy.v2.MongoProxy stat_prefix: "{{ key }}" access_log: "/var/log/envoy/mongo_{{ key }}.log" {% if value.get('ratelimit', False) %} - - name: envoy.ratelimit + - name: envoy.filters.network.ratelimit typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.ratelimit.v3.RateLimit stat_prefix: "{{ key }}" diff --git a/configs/freebind/freebind.yaml b/configs/freebind/freebind.yaml index 1171795589..d89b372a51 100644 --- a/configs/freebind/freebind.yaml +++ b/configs/freebind/freebind.yaml @@ -15,7 +15,7 @@ static_resources: freebind: true filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http diff --git a/configs/google_com_proxy.v2.yaml b/configs/google_com_proxy.v2.yaml index f46f36bc3b..09352b017c 100644 --- a/configs/google_com_proxy.v2.yaml +++ b/configs/google_com_proxy.v2.yaml @@ -15,7 +15,7 @@ static_resources: port_value: 10000 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http diff --git a/configs/original-dst-cluster/proxy_config.yaml b/configs/original-dst-cluster/proxy_config.yaml index 0b35f928b5..72d1e55d9a 100644 --- a/configs/original-dst-cluster/proxy_config.yaml +++ b/configs/original-dst-cluster/proxy_config.yaml @@ -6,7 +6,7 @@ static_resources: port_value: 10000 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http diff --git a/configs/using_deprecated_config.v2.yaml b/configs/using_deprecated_config.v2.yaml index 4e9f66738e..a2fded18b7 100644 --- a/configs/using_deprecated_config.v2.yaml +++ b/configs/using_deprecated_config.v2.yaml @@ -15,7 +15,7 @@ static_resources: port_value: 10000 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http diff --git a/docs/root/configuration/best_practices/edge.rst b/docs/root/configuration/best_practices/edge.rst index 0f8b981ab5..9d35f7613b 100644 --- a/docs/root/configuration/best_practices/edge.rst +++ b/docs/root/configuration/best_practices/edge.rst @@ -76,7 +76,7 @@ The following is a YAML example of the above recommendation. # Uncomment if Envoy is behind a load balancer that exposes client IP address using the PROXY protocol. # use_proxy_proto: true filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http diff --git a/docs/root/configuration/http/http_filters/dynamic_forward_proxy_filter.rst b/docs/root/configuration/http/http_filters/dynamic_forward_proxy_filter.rst index ae5b3e7716..a8ba692dc8 100644 --- a/docs/root/configuration/http/http_filters/dynamic_forward_proxy_filter.rst +++ b/docs/root/configuration/http/http_filters/dynamic_forward_proxy_filter.rst @@ -51,7 +51,7 @@ host when forwarding. See the example below within the configured routes. port_value: 10000 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http diff --git a/docs/root/configuration/http/http_filters/grpc_http1_reverse_bridge_filter.rst b/docs/root/configuration/http/http_filters/grpc_http1_reverse_bridge_filter.rst index baebebfb92..92e48e3f1a 100644 --- a/docs/root/configuration/http/http_filters/grpc_http1_reverse_bridge_filter.rst +++ b/docs/root/configuration/http/http_filters/grpc_http1_reverse_bridge_filter.rst @@ -59,7 +59,7 @@ How to disable HTTP/1.1 reverse bridge filter per route port_value: 80 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager access_log: diff --git a/docs/root/configuration/http/http_filters/grpc_json_transcoder_filter.rst b/docs/root/configuration/http/http_filters/grpc_json_transcoder_filter.rst index 0cf4222b80..021bf53b84 100644 --- a/docs/root/configuration/http/http_filters/grpc_json_transcoder_filter.rst +++ b/docs/root/configuration/http/http_filters/grpc_json_transcoder_filter.rst @@ -105,7 +105,7 @@ gRPC or RESTful JSON requests to localhost:51051. socket_address: { address: 0.0.0.0, port_value: 51051 } filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: grpc_json diff --git a/docs/root/configuration/listeners/network_filters/client_ssl_auth_filter.rst b/docs/root/configuration/listeners/network_filters/client_ssl_auth_filter.rst index e25bf2276e..d42a235953 100644 --- a/docs/root/configuration/listeners/network_filters/client_ssl_auth_filter.rst +++ b/docs/root/configuration/listeners/network_filters/client_ssl_auth_filter.rst @@ -5,7 +5,7 @@ Client TLS authentication * Client TLS authentication filter :ref:`architecture overview ` * :ref:`v2 API reference ` -* This filter should be configured with the name *envoy.client_ssl_auth*. +* This filter should be configured with the name *envoy.filters.network.client_ssl_auth*. .. _config_network_filters_client_ssl_auth_stats: diff --git a/docs/root/configuration/listeners/network_filters/echo_filter.rst b/docs/root/configuration/listeners/network_filters/echo_filter.rst index 29a5e002e8..ff1fdfa701 100644 --- a/docs/root/configuration/listeners/network_filters/echo_filter.rst +++ b/docs/root/configuration/listeners/network_filters/echo_filter.rst @@ -5,6 +5,6 @@ Echo The echo is a trivial network filter mainly meant to demonstrate the network filter API. If installed it will echo (write) all received data back to the connected downstream client. -This filter should be configured with the name *envoy.echo*. +This filter should be configured with the name *envoy.filters.network.echo*. * :ref:`v2 API reference ` diff --git a/docs/root/configuration/listeners/network_filters/ext_authz_filter.rst b/docs/root/configuration/listeners/network_filters/ext_authz_filter.rst index c165ffe08b..65c25788a3 100644 --- a/docs/root/configuration/listeners/network_filters/ext_authz_filter.rst +++ b/docs/root/configuration/listeners/network_filters/ext_authz_filter.rst @@ -5,7 +5,7 @@ External Authorization * External authorization :ref:`architecture overview ` * :ref:`Network filter v2 API reference ` -* This filter should be configured with the name *envoy.ext_authz*. +* This filter should be configured with the name *envoy.filters.network.ext_authz*. The external authorization network filter calls an external authorization service to check if the incoming request is authorized or not. If the request is deemed unauthorized by the network filter @@ -31,7 +31,7 @@ A sample filter configuration could be: .. code-block:: yaml filters: - - name: envoy.ext_authz + - name: envoy.filters.network.ext_authz typed_config: "@type": type.googleapis.com/envoy.config.filter.http.ext_authz.v2.ExtAuthz stat_prefix: ext_authz diff --git a/docs/root/configuration/listeners/network_filters/kafka_broker_filter.rst b/docs/root/configuration/listeners/network_filters/kafka_broker_filter.rst index 40289f34fc..2443136748 100644 --- a/docs/root/configuration/listeners/network_filters/kafka_broker_filter.rst +++ b/docs/root/configuration/listeners/network_filters/kafka_broker_filter.rst @@ -40,7 +40,7 @@ in the configuration snippet below: typed_config: "@type": type.googleapis.com/envoy.config.filter.network.kafka_broker.v2alpha1.KafkaBroker stat_prefix: exampleprefix - - name: envoy.tcp_proxy + - name: envoy.filters.network.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy stat_prefix: tcp diff --git a/docs/root/configuration/listeners/network_filters/mongo_proxy_filter.rst b/docs/root/configuration/listeners/network_filters/mongo_proxy_filter.rst index a41fc1c0ac..9aa734c69e 100644 --- a/docs/root/configuration/listeners/network_filters/mongo_proxy_filter.rst +++ b/docs/root/configuration/listeners/network_filters/mongo_proxy_filter.rst @@ -5,7 +5,7 @@ Mongo proxy * MongoDB :ref:`architecture overview ` * :ref:`v2 API reference ` -* This filter should be configured with the name *envoy.mongo_proxy*. +* This filter should be configured with the name *envoy.filters.network.mongo_proxy*. .. _config_network_filters_mongo_proxy_fault_injection: diff --git a/docs/root/configuration/listeners/network_filters/mysql_proxy_filter.rst b/docs/root/configuration/listeners/network_filters/mysql_proxy_filter.rst index 2890538978..750e3b30e3 100644 --- a/docs/root/configuration/listeners/network_filters/mysql_proxy_filter.rst +++ b/docs/root/configuration/listeners/network_filters/mysql_proxy_filter.rst @@ -36,7 +36,7 @@ in the configuration snippet below: typed_config: "@type": type.googleapis.com/envoy.config.filter.network.mysql_proxy.v1alpha1.MySQLProxy stat_prefix: mysql - - name: envoy.tcp_proxy + - name: envoy.filters.network.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy stat_prefix: tcp @@ -118,7 +118,7 @@ _catalog_ table in the _productdb_ database. exact: update principals: - any: true - - name: envoy.tcp_proxy + - name: envoy.filters.network.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy stat_prefix: tcp diff --git a/docs/root/configuration/listeners/network_filters/rate_limit_filter.rst b/docs/root/configuration/listeners/network_filters/rate_limit_filter.rst index 09a7aa2801..4196956ff0 100644 --- a/docs/root/configuration/listeners/network_filters/rate_limit_filter.rst +++ b/docs/root/configuration/listeners/network_filters/rate_limit_filter.rst @@ -5,7 +5,7 @@ Rate limit * Global rate limiting :ref:`architecture overview ` * :ref:`v2 API reference ` -* This filter should be configured with the name *envoy.ratelimit*. +* This filter should be configured with the name *envoy.filters.network.ratelimit*. .. note:: Local rate limiting is also supported via the :ref:`local rate limit filter diff --git a/docs/root/configuration/listeners/network_filters/redis_proxy_filter.rst b/docs/root/configuration/listeners/network_filters/redis_proxy_filter.rst index 1dd12ee50a..666bd3bb1b 100644 --- a/docs/root/configuration/listeners/network_filters/redis_proxy_filter.rst +++ b/docs/root/configuration/listeners/network_filters/redis_proxy_filter.rst @@ -5,7 +5,7 @@ Redis proxy * Redis :ref:`architecture overview ` * :ref:`v2 API reference ` -* This filter should be configured with the name *envoy.redis_proxy*. +* This filter should be configured with the name *envoy.filters.network.redis_proxy*. .. _config_network_filters_redis_proxy_stats: diff --git a/docs/root/configuration/listeners/network_filters/tcp_proxy_filter.rst b/docs/root/configuration/listeners/network_filters/tcp_proxy_filter.rst index 5c68939cec..e137dfc58f 100644 --- a/docs/root/configuration/listeners/network_filters/tcp_proxy_filter.rst +++ b/docs/root/configuration/listeners/network_filters/tcp_proxy_filter.rst @@ -5,7 +5,7 @@ TCP proxy * TCP proxy :ref:`architecture overview ` * :ref:`v2 API reference ` -* This filter should be configured with the name *envoy.tcp_proxy*. +* This filter should be configured with the name *envoy.filters.network.tcp_proxy*. .. _config_network_filters_tcp_proxy_dynamic_cluster: diff --git a/docs/root/configuration/listeners/network_filters/zookeeper_proxy_filter.rst b/docs/root/configuration/listeners/network_filters/zookeeper_proxy_filter.rst index c74c67bee1..587ebc7f77 100644 --- a/docs/root/configuration/listeners/network_filters/zookeeper_proxy_filter.rst +++ b/docs/root/configuration/listeners/network_filters/zookeeper_proxy_filter.rst @@ -31,7 +31,7 @@ in the configuration snippet below: typed_config: "@type": type.googleapis.com/envoy.config.filter.network.zookeeper_proxy.v1alpha1.ZooKeeperProxy stat_prefix: zookeeper - - name: envoy.tcp_proxy + - name: envoy.filters.network.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy stat_prefix: tcp diff --git a/docs/root/configuration/overview/examples.rst b/docs/root/configuration/overview/examples.rst index 1a7d802792..246d6d0ca7 100644 --- a/docs/root/configuration/overview/examples.rst +++ b/docs/root/configuration/overview/examples.rst @@ -23,7 +23,7 @@ A minimal fully static bootstrap config is provided below: socket_address: { address: 127.0.0.1, port_value: 10000 } filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http @@ -75,7 +75,7 @@ on 127.0.0.1:5678 is provided below: socket_address: { address: 127.0.0.1, port_value: 10000 } filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http @@ -215,7 +215,7 @@ The management server could respond to LDS requests with: port_value: 10000 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http diff --git a/docs/root/faq/configuration/flow_control.rst b/docs/root/faq/configuration/flow_control.rst index eee0e8e157..bb9f08fd99 100644 --- a/docs/root/faq/configuration/flow_control.rst +++ b/docs/root/faq/configuration/flow_control.rst @@ -46,7 +46,7 @@ the only one which needs to be amended is the listener portValue: 0 filterChains: filters: - name: envoy.http_connection_manager + name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager http2_protocol_options: diff --git a/docs/root/faq/configuration/sni.rst b/docs/root/faq/configuration/sni.rst index 0eb1b5027e..242985ba37 100644 --- a/docs/root/faq/configuration/sni.rst +++ b/docs/root/faq/configuration/sni.rst @@ -32,7 +32,7 @@ The following is a YAML example of the above requirement. - certificate_chain: { filename: "example_com_cert.pem" } private_key: { filename: "example_com_key.pem" } filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http @@ -54,7 +54,7 @@ The following is a YAML example of the above requirement. - certificate_chain: { filename: "api_example_com_cert.pem" } private_key: { filename: "api_example_com_key.pem" } filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http diff --git a/docs/root/intro/arch_overview/security/ssl.rst b/docs/root/intro/arch_overview/security/ssl.rst index 2a34bfa60a..76ac394b75 100644 --- a/docs/root/intro/arch_overview/security/ssl.rst +++ b/docs/root/intro/arch_overview/security/ssl.rst @@ -78,7 +78,7 @@ Example configuration address: { socket_address: { address: 127.0.0.1, port_value: 10000 } } filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager # ... transport_socket: name: envoy.transport_sockets.tls diff --git a/docs/root/intro/deprecated.rst b/docs/root/intro/deprecated.rst index d9ea30dc4f..76b9e24069 100644 --- a/docs/root/intro/deprecated.rst +++ b/docs/root/intro/deprecated.rst @@ -15,8 +15,8 @@ Deprecated items below are listed in chronological order. * The previous behavior for upstream connection pool circuit breaking described `here `_ has been deprecated in favor of the new behavior described :ref:`here `. -* Access Logger, Stats Sink, and Tracer names have been deprecated in favor of the extension name - from the envoy build system. +* Access Logger, Network Filter, Stats Sink, and Tracer names have been deprecated in favor of the + extension name from the envoy build system. .. csv-table:: :header: Canonical Names, Deprecated Names @@ -25,6 +25,14 @@ Deprecated items below are listed in chronological order. envoy.access_loggers.file, envoy.file_access_log envoy.access_loggers.http_grpc, envoy.http_grpc_access_log envoy.access_loggers.tcp_grpc, envoy.tcp_grpc_access_log + envoy.filters.network.client_ssl_auth, envoy.client_ssl_auth + envoy.filters.network.echo, envoy.echo + envoy.filters.network.ext_authz, envoy.ext_authz + envoy.filters.network.http_connection_manager, envoy.http_connection_manager + envoy.filters.network.mongo_proxy, envoy.mongo_proxy + envoy.filters.network.ratelimit, envoy.ratelimit + envoy.filters.network.redis_proxy, envoy.redis_proxy + envoy.filters.network.tcp_proxy, envoy.tcp_proxy envoy.stat_sinks.dog_statsd, envoy.dog_statsd envoy.stat_sinks.metrics_service, envoy.metrics_service envoy.stat_sinks.statsd, envoy.statsd diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index 387cc502ac..82db0b2d0a 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -9,6 +9,8 @@ Version history minimum. * config: use type URL to select an extension whenever the config type URL (or its previous versions) uniquely identify a typed extension, see :ref:`extension configuration `. * http: fixing a bug in HTTP/1.0 responses where Connection: keep-alive was not appended for connections which were kept alive. +* network filters: network filter extensions use the "envoy.filters.network" name space. A mapping + of extension names is available in the :ref:`deprecated ` documentation. * rbac: added :ref:`url_path ` for matching URL path without the query and fragment string. * retry: added a retry predicate that :ref:`rejects hosts based on metadata. ` * router: added :ref:`auto_san_validation ` to support overrriding SAN validation to transport socket for new upstream connections based on the downstream HTTP host/authority header. diff --git a/docs/root/start/start.rst b/docs/root/start/start.rst index 26f0e34be0..c907fdb777 100644 --- a/docs/root/start/start.rst +++ b/docs/root/start/start.rst @@ -68,7 +68,7 @@ The specification of the :ref:`listeners `, -// keyed by the name `envoy.redis_proxy`. +// keyed by the name `envoy.filters.network.redis_proxy`. message RedisProtocolOptions { // Upstream server password as defined by the `requirepass` directive // `_ in the server's configuration file. diff --git a/generated_api_shadow/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto b/generated_api_shadow/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto index b56940edaa..5417239808 100644 --- a/generated_api_shadow/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto +++ b/generated_api_shadow/envoy/extensions/filters/network/redis_proxy/v3/redis_proxy.proto @@ -251,7 +251,7 @@ message RedisProxy { // RedisProtocolOptions specifies Redis upstream protocol options. This object is used in // :ref:`typed_extension_protocol_options`, -// keyed by the name `envoy.redis_proxy`. +// keyed by the name `envoy.filters.network.redis_proxy`. message RedisProtocolOptions { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.redis_proxy.v2.RedisProtocolOptions"; diff --git a/source/extensions/filters/network/client_ssl_auth/config.cc b/source/extensions/filters/network/client_ssl_auth/config.cc index 34ae0ff9a5..2b361023cb 100644 --- a/source/extensions/filters/network/client_ssl_auth/config.cc +++ b/source/extensions/filters/network/client_ssl_auth/config.cc @@ -30,7 +30,7 @@ Network::FilterFactoryCb ClientSslAuthConfigFactory::createFilterFactoryFromProt * Static registration for the client SSL auth filter. @see RegisterFactory. */ REGISTER_FACTORY(ClientSslAuthConfigFactory, - Server::Configuration::NamedNetworkFilterConfigFactory); + Server::Configuration::NamedNetworkFilterConfigFactory){"envoy.client_ssl_auth"}; } // namespace ClientSslAuth } // namespace NetworkFilters diff --git a/source/extensions/filters/network/echo/config.cc b/source/extensions/filters/network/echo/config.cc index c33af01ab6..179c14d2a3 100644 --- a/source/extensions/filters/network/echo/config.cc +++ b/source/extensions/filters/network/echo/config.cc @@ -35,7 +35,8 @@ class EchoConfigFactory /** * Static registration for the echo filter. @see RegisterFactory. */ -REGISTER_FACTORY(EchoConfigFactory, Server::Configuration::NamedNetworkFilterConfigFactory); +REGISTER_FACTORY(EchoConfigFactory, + Server::Configuration::NamedNetworkFilterConfigFactory){"envoy.echo"}; } // namespace Echo } // namespace NetworkFilters diff --git a/source/extensions/filters/network/ext_authz/config.cc b/source/extensions/filters/network/ext_authz/config.cc index b0b0e7928e..a47f488a6f 100644 --- a/source/extensions/filters/network/ext_authz/config.cc +++ b/source/extensions/filters/network/ext_authz/config.cc @@ -42,7 +42,8 @@ Network::FilterFactoryCb ExtAuthzConfigFactory::createFilterFactoryFromProtoType /** * Static registration for the external authorization filter. @see RegisterFactory. */ -REGISTER_FACTORY(ExtAuthzConfigFactory, Server::Configuration::NamedNetworkFilterConfigFactory); +REGISTER_FACTORY(ExtAuthzConfigFactory, + Server::Configuration::NamedNetworkFilterConfigFactory){"envoy.ext_authz"}; } // namespace ExtAuthz } // namespace NetworkFilters diff --git a/source/extensions/filters/network/http_connection_manager/config.cc b/source/extensions/filters/network/http_connection_manager/config.cc index ba46e92c99..b2ee828d1f 100644 --- a/source/extensions/filters/network/http_connection_manager/config.cc +++ b/source/extensions/filters/network/http_connection_manager/config.cc @@ -138,7 +138,8 @@ HttpConnectionManagerFilterConfigFactory::createFilterFactoryFromProtoTyped( * Static registration for the HTTP connection manager filter. */ REGISTER_FACTORY(HttpConnectionManagerFilterConfigFactory, - Server::Configuration::NamedNetworkFilterConfigFactory); + Server::Configuration::NamedNetworkFilterConfigFactory){ + "envoy.http_connection_manager"}; InternalAddressConfig::InternalAddressConfig( const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager:: diff --git a/source/extensions/filters/network/mongo_proxy/config.cc b/source/extensions/filters/network/mongo_proxy/config.cc index a7522d9222..847ac601a9 100644 --- a/source/extensions/filters/network/mongo_proxy/config.cc +++ b/source/extensions/filters/network/mongo_proxy/config.cc @@ -46,7 +46,7 @@ Network::FilterFactoryCb MongoProxyFilterConfigFactory::createFilterFactoryFromP * Static registration for the mongo filter. @see RegisterFactory. */ REGISTER_FACTORY(MongoProxyFilterConfigFactory, - Server::Configuration::NamedNetworkFilterConfigFactory); + Server::Configuration::NamedNetworkFilterConfigFactory){"envoy.mongo_proxy"}; } // namespace MongoProxy } // namespace NetworkFilters diff --git a/source/extensions/filters/network/ratelimit/config.cc b/source/extensions/filters/network/ratelimit/config.cc index ffff3d0c27..4e45468603 100644 --- a/source/extensions/filters/network/ratelimit/config.cc +++ b/source/extensions/filters/network/ratelimit/config.cc @@ -42,7 +42,8 @@ Network::FilterFactoryCb RateLimitConfigFactory::createFilterFactoryFromProtoTyp /** * Static registration for the rate limit filter. @see RegisterFactory. */ -REGISTER_FACTORY(RateLimitConfigFactory, Server::Configuration::NamedNetworkFilterConfigFactory); +REGISTER_FACTORY(RateLimitConfigFactory, + Server::Configuration::NamedNetworkFilterConfigFactory){"envoy.ratelimit"}; } // namespace RateLimitFilter } // namespace NetworkFilters diff --git a/source/extensions/filters/network/redis_proxy/config.cc b/source/extensions/filters/network/redis_proxy/config.cc index 20f840c70b..e52a04ffe0 100644 --- a/source/extensions/filters/network/redis_proxy/config.cc +++ b/source/extensions/filters/network/redis_proxy/config.cc @@ -102,7 +102,7 @@ Network::FilterFactoryCb RedisProxyFilterConfigFactory::createFilterFactoryFromP * Static registration for the redis filter. @see RegisterFactory. */ REGISTER_FACTORY(RedisProxyFilterConfigFactory, - Server::Configuration::NamedNetworkFilterConfigFactory); + Server::Configuration::NamedNetworkFilterConfigFactory){"envoy.redis_proxy"}; } // namespace RedisProxy } // namespace NetworkFilters diff --git a/source/extensions/filters/network/tcp_proxy/config.cc b/source/extensions/filters/network/tcp_proxy/config.cc index 5dd5c3a116..f9350ff7e8 100644 --- a/source/extensions/filters/network/tcp_proxy/config.cc +++ b/source/extensions/filters/network/tcp_proxy/config.cc @@ -30,7 +30,8 @@ Network::FilterFactoryCb ConfigFactory::createFilterFactoryFromProtoTyped( /** * Static registration for the tcp_proxy filter. @see RegisterFactory. */ -REGISTER_FACTORY(ConfigFactory, Server::Configuration::NamedNetworkFilterConfigFactory); +REGISTER_FACTORY(ConfigFactory, + Server::Configuration::NamedNetworkFilterConfigFactory){"envoy.tcp_proxy"}; } // namespace TcpProxy } // namespace NetworkFilters diff --git a/source/extensions/filters/network/well_known_names.h b/source/extensions/filters/network/well_known_names.h index 578ff23f23..8167f3f696 100644 --- a/source/extensions/filters/network/well_known_names.h +++ b/source/extensions/filters/network/well_known_names.h @@ -13,27 +13,27 @@ namespace NetworkFilters { class NetworkFilterNameValues { public: // Client ssl auth filter - const std::string ClientSslAuth = "envoy.client_ssl_auth"; + const std::string ClientSslAuth = "envoy.filters.network.client_ssl_auth"; // Echo filter - const std::string Echo = "envoy.echo"; + const std::string Echo = "envoy.filters.network.echo"; // Dubbo proxy filter const std::string DubboProxy = "envoy.filters.network.dubbo_proxy"; // HTTP connection manager filter - const std::string HttpConnectionManager = "envoy.http_connection_manager"; + const std::string HttpConnectionManager = "envoy.filters.network.http_connection_manager"; // Local rate limit filter const std::string LocalRateLimit = "envoy.filters.network.local_ratelimit"; // Mongo proxy filter - const std::string MongoProxy = "envoy.mongo_proxy"; + const std::string MongoProxy = "envoy.filters.network.mongo_proxy"; // MySQL proxy filter const std::string MySQLProxy = "envoy.filters.network.mysql_proxy"; // Rate limit filter - const std::string RateLimit = "envoy.ratelimit"; + const std::string RateLimit = "envoy.filters.network.ratelimit"; // Redis proxy filter - const std::string RedisProxy = "envoy.redis_proxy"; + const std::string RedisProxy = "envoy.filters.network.redis_proxy"; // TCP proxy filter - const std::string TcpProxy = "envoy.tcp_proxy"; + const std::string TcpProxy = "envoy.filters.network.tcp_proxy"; // Authorization filter - const std::string ExtAuthorization = "envoy.ext_authz"; + const std::string ExtAuthorization = "envoy.filters.network.ext_authz"; // Kafka Broker filter const std::string KafkaBroker = "envoy.filters.network.kafka_broker"; // Thrift proxy filter diff --git a/test/config/integration/google_com_proxy_port_0.v2.yaml b/test/config/integration/google_com_proxy_port_0.v2.yaml index f6f33aa33a..0edf713d8b 100644 --- a/test/config/integration/google_com_proxy_port_0.v2.yaml +++ b/test/config/integration/google_com_proxy_port_0.v2.yaml @@ -14,7 +14,7 @@ static_resources: port_value: 0 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: ingress_http diff --git a/test/config/integration/server.yaml b/test/config/integration/server.yaml index 2f6dc29180..6ee86fb72f 100644 --- a/test/config/integration/server.yaml +++ b/test/config/integration/server.yaml @@ -7,7 +7,7 @@ static_resources: reuse_port: {{ reuse_port }} filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager drain_timeout: 5s @@ -75,7 +75,7 @@ static_resources: port_value: 0 filter_chains: - filters: - - name: envoy.redis_proxy + - name: envoy.filters.network.redis_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProxy settings: diff --git a/test/config/integration/server_unix_listener.yaml b/test/config/integration/server_unix_listener.yaml index 56ce466da3..8dde1c60fe 100644 --- a/test/config/integration/server_unix_listener.yaml +++ b/test/config/integration/server_unix_listener.yaml @@ -5,7 +5,7 @@ static_resources: path: "{{ socket_dir }}/unix-sockets.listener_0" filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager http_filters: diff --git a/test/config/integration/server_xds.lds.typed_struct.yaml b/test/config/integration/server_xds.lds.typed_struct.yaml index 0609caa0e7..6cbf5fab7e 100644 --- a/test/config/integration/server_xds.lds.typed_struct.yaml +++ b/test/config/integration/server_xds.lds.typed_struct.yaml @@ -8,7 +8,7 @@ resources: port_value: 0 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/udpa.type.v1.TypedStruct type_url: "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager" diff --git a/test/config/integration/server_xds.lds.with_unknown_field.typed_struct.yaml b/test/config/integration/server_xds.lds.with_unknown_field.typed_struct.yaml index 093a90248e..aad176c3da 100644 --- a/test/config/integration/server_xds.lds.with_unknown_field.typed_struct.yaml +++ b/test/config/integration/server_xds.lds.with_unknown_field.typed_struct.yaml @@ -8,7 +8,7 @@ resources: port_value: 0 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/udpa.type.v1.TypedStruct type_url: "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager" diff --git a/test/config/integration/server_xds.lds.with_unknown_field.yaml b/test/config/integration/server_xds.lds.with_unknown_field.yaml index 09135bb3ff..bb2d9fdfbe 100644 --- a/test/config/integration/server_xds.lds.with_unknown_field.yaml +++ b/test/config/integration/server_xds.lds.with_unknown_field.yaml @@ -8,7 +8,7 @@ resources: port_value: 0 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager codec_type: HTTP2 diff --git a/test/config/integration/server_xds.lds.yaml b/test/config/integration/server_xds.lds.yaml index 777ee0e51e..2ef24aeec4 100644 --- a/test/config/integration/server_xds.lds.yaml +++ b/test/config/integration/server_xds.lds.yaml @@ -8,7 +8,7 @@ resources: port_value: 0 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager codec_type: HTTP2 diff --git a/test/config/utility.cc b/test/config/utility.cc index 4c9a0f2b89..cd6f6e0a28 100644 --- a/test/config/utility.cc +++ b/test/config/utility.cc @@ -99,7 +99,7 @@ const std::string ConfigHelper::BASE_UDP_LISTENER_CONFIG = R"EOF( const std::string ConfigHelper::TCP_PROXY_CONFIG = BASE_CONFIG + R"EOF( filter_chains: filters: - name: envoy.tcp_proxy + name: envoy.filters.network.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy stat_prefix: tcp_stats @@ -109,7 +109,7 @@ const std::string ConfigHelper::TCP_PROXY_CONFIG = BASE_CONFIG + R"EOF( const std::string ConfigHelper::HTTP_PROXY_CONFIG = BASE_CONFIG + R"EOF( filter_chains: filters: - name: envoy.http_connection_manager + name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: config_test @@ -143,7 +143,7 @@ const std::string ConfigHelper::QUIC_HTTP_PROXY_CONFIG = BASE_UDP_LISTENER_CONFI transport_socket: name: envoy.transport_sockets.quic filters: - name: envoy.http_connection_manager + name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: config_test @@ -258,7 +258,7 @@ std::string ConfigHelper::discoveredClustersBootstrap(const std::string& api_typ port_value: 0 filter_chains: filters: - name: envoy.http_connection_manager + name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: config_test @@ -575,7 +575,7 @@ void ConfigHelper::setBufferLimits(uint32_t upstream_buffer_limit, cluster->mutable_per_connection_buffer_limit_bytes()->set_value(upstream_buffer_limit); } - auto filter = getFilterFromListener("envoy.http_connection_manager"); + auto filter = getFilterFromListener("envoy.filters.network.http_connection_manager"); if (filter) { envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager hcm_config; @@ -684,7 +684,7 @@ void ConfigHelper::addSslConfig(const ServerSslOptions& options) { } bool ConfigHelper::setAccessLog(const std::string& filename, absl::string_view format) { - if (getFilterFromListener("envoy.http_connection_manager") == nullptr) { + if (getFilterFromListener("envoy.filters.network.http_connection_manager") == nullptr) { return false; } // Replace /dev/null with a real path for the file access log. @@ -775,7 +775,7 @@ void ConfigHelper::addNetworkFilter(const std::string& filter_yaml) { bool ConfigHelper::loadHttpConnectionManager( envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm) { RELEASE_ASSERT(!finalized_, ""); - auto* hcm_filter = getFilterFromListener("envoy.http_connection_manager"); + auto* hcm_filter = getFilterFromListener("envoy.filters.network.http_connection_manager"); if (hcm_filter) { auto* config = hcm_filter->mutable_typed_config(); hcm = MessageUtil::anyConvert< @@ -790,8 +790,8 @@ void ConfigHelper::storeHttpConnectionManager( const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm) { RELEASE_ASSERT(!finalized_, ""); - auto* hcm_config_any = - getFilterFromListener("envoy.http_connection_manager")->mutable_typed_config(); + auto* hcm_config_any = getFilterFromListener("envoy.filters.network.http_connection_manager") + ->mutable_typed_config(); hcm_config_any->PackFrom(hcm); } @@ -828,7 +828,7 @@ void ConfigHelper::setLds(absl::string_view version_info) { } void ConfigHelper::setOutboundFramesLimits(uint32_t max_all_frames, uint32_t max_control_frames) { - auto filter = getFilterFromListener("envoy.http_connection_manager"); + auto filter = getFilterFromListener("envoy.filters.network.http_connection_manager"); if (filter) { envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager hcm_config; diff --git a/test/extensions/clusters/aggregate/cluster_integration_test.cc b/test/extensions/clusters/aggregate/cluster_integration_test.cc index 36f5c4b32b..ab60da96b6 100644 --- a/test/extensions/clusters/aggregate/cluster_integration_test.cc +++ b/test/extensions/clusters/aggregate/cluster_integration_test.cc @@ -76,7 +76,7 @@ const std::string& config() { port_value: 0 filter_chains: filters: - name: envoy.http_connection_manager + name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: config_test diff --git a/test/extensions/clusters/redis/redis_cluster_integration_test.cc b/test/extensions/clusters/redis/redis_cluster_integration_test.cc index 10a4a94048..6349baaa41 100644 --- a/test/extensions/clusters/redis/redis_cluster_integration_test.cc +++ b/test/extensions/clusters/redis/redis_cluster_integration_test.cc @@ -34,7 +34,7 @@ const std::string& listenerConfig() { port_value: 0 filter_chains: filters: - name: envoy.redis_proxy + name: envoy.filters.network.redis_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProxy stat_prefix: redis_stats @@ -116,7 +116,7 @@ const std::string& testConfigWithReadPolicy() { const std::string& testConfigWithAuth() { CONSTRUCT_ON_FIRST_USE(std::string, testConfig() + R"EOF( typed_extension_protocol_options: - envoy.redis_proxy: + envoy.filters.network.redis_proxy: "@type": type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProtocolOptions auth_password: { inline_string: somepassword } )EOF"); diff --git a/test/extensions/common/aws/aws_metadata_fetcher_integration_test.cc b/test/extensions/common/aws/aws_metadata_fetcher_integration_test.cc index 41a0ebdd04..b211378792 100644 --- a/test/extensions/common/aws/aws_metadata_fetcher_integration_test.cc +++ b/test/extensions/common/aws/aws_metadata_fetcher_integration_test.cc @@ -20,7 +20,7 @@ class AwsMetadataIntegrationTestBase : public ::testing::Test, public BaseIntegr return fmt::format(ConfigHelper::BASE_CONFIG + R"EOF( filter_chains: filters: - name: envoy.http_connection_manager + name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: metadata_test diff --git a/test/extensions/filters/network/client_ssl_auth/config_test.cc b/test/extensions/filters/network/client_ssl_auth/config_test.cc index f47ae6f7b7..bd1fc7945e 100644 --- a/test/extensions/filters/network/client_ssl_auth/config_test.cc +++ b/test/extensions/filters/network/client_ssl_auth/config_test.cc @@ -104,6 +104,16 @@ TEST(ClientSslAuthConfigFactoryTest, DoubleRegistrationTest) { fmt::format("Double registration for name: '{}'", NetworkFilterNames::get().ClientSslAuth)); } +// Test that the deprecated extension name still functions. +TEST(ClientSslAuthConfigFactoryTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.client_ssl_auth"; + + ASSERT_NE( + nullptr, + Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + } // namespace ClientSslAuth } // namespace NetworkFilters } // namespace Extensions diff --git a/test/extensions/filters/network/ext_authz/config_test.cc b/test/extensions/filters/network/ext_authz/config_test.cc index 49972a5d90..010ad2018e 100644 --- a/test/extensions/filters/network/ext_authz/config_test.cc +++ b/test/extensions/filters/network/ext_authz/config_test.cc @@ -51,6 +51,16 @@ TEST(ExtAuthzFilterConfigTest, ExtAuthzCorrectProto) { cb(connection); } +// Test that the deprecated extension name still functions. +TEST(ExtAuthzConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.ext_authz"; + + ASSERT_NE( + nullptr, + Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + } // namespace ExtAuthz } // namespace NetworkFilters } // namespace Extensions diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index 4012048958..6bec548d7f 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -956,6 +956,16 @@ stat_prefix: my_stat_prefix "bad_type: Cannot find field"); } +// Test that the deprecated extension name still functions. +TEST_F(HttpConnectionManagerConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.http_connection_manager"; + + ASSERT_NE( + nullptr, + Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + class FilterChainTest : public HttpConnectionManagerConfigTest { public: const std::string basic_config_ = R"EOF( diff --git a/test/extensions/filters/network/kafka/broker/integration_test/envoy_config_yaml.j2 b/test/extensions/filters/network/kafka/broker/integration_test/envoy_config_yaml.j2 index 6f4ee2f3e4..f39aaff404 100644 --- a/test/extensions/filters/network/kafka/broker/integration_test/envoy_config_yaml.j2 +++ b/test/extensions/filters/network/kafka/broker/integration_test/envoy_config_yaml.j2 @@ -10,7 +10,7 @@ static_resources: typed_config: "@type": type.googleapis.com/envoy.config.filter.network.kafka_broker.v2alpha1.KafkaBroker stat_prefix: testfilter - - name: envoy.tcp_proxy + - name: envoy.filters.network.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy stat_prefix: ingress_tcp diff --git a/test/extensions/filters/network/mongo_proxy/config_test.cc b/test/extensions/filters/network/mongo_proxy/config_test.cc index fc2d702b57..bab4fcc446 100644 --- a/test/extensions/filters/network/mongo_proxy/config_test.cc +++ b/test/extensions/filters/network/mongo_proxy/config_test.cc @@ -221,6 +221,16 @@ TEST(MongoFilterConfigTest, CorrectFaultConfigurationInProto) { cb(connection); } +// Test that the deprecated extension name still functions. +TEST(MongoFilterConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.mongo_proxy"; + + ASSERT_NE( + nullptr, + Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + } // namespace MongoProxy } // namespace NetworkFilters } // namespace Extensions diff --git a/test/extensions/filters/network/mysql_proxy/mysql_test_config.yaml b/test/extensions/filters/network/mysql_proxy/mysql_test_config.yaml index b58c3777a2..98e698431a 100644 --- a/test/extensions/filters/network/mysql_proxy/mysql_test_config.yaml +++ b/test/extensions/filters/network/mysql_proxy/mysql_test_config.yaml @@ -29,7 +29,7 @@ static_resources: typed_config: "@type": type.googleapis.com/envoy.config.filter.network.mysql_proxy.v1alpha1.MySQLProxy stat_prefix: mysql_stats - - name: envoy.tcp_proxy + - name: envoy.filters.network.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy stat_prefix: tcp_stats diff --git a/test/extensions/filters/network/ratelimit/config_test.cc b/test/extensions/filters/network/ratelimit/config_test.cc index 47c185201e..9920c9dbfe 100644 --- a/test/extensions/filters/network/ratelimit/config_test.cc +++ b/test/extensions/filters/network/ratelimit/config_test.cc @@ -83,6 +83,16 @@ ip_white_list: '12' "ip_white_list: Cannot find field"); } +// Test that the deprecated extension name still functions. +TEST(RateLimitFilterConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.ratelimit"; + + ASSERT_NE( + nullptr, + Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + } // namespace RateLimitFilter } // namespace NetworkFilters } // namespace Extensions diff --git a/test/extensions/filters/network/rbac/integration_test.cc b/test/extensions/filters/network/rbac/integration_test.cc index cea44a2ad5..9b8d8f01fd 100644 --- a/test/extensions/filters/network/rbac/integration_test.cc +++ b/test/extensions/filters/network/rbac/integration_test.cc @@ -43,7 +43,7 @@ class RoleBasedAccessControlNetworkFilterIntegrationTest principals: - not_id: any: true - - name: envoy.echo + - name: envoy.filters.network.echo config: )EOF"; } diff --git a/test/extensions/filters/network/redis_proxy/config_test.cc b/test/extensions/filters/network/redis_proxy/config_test.cc index f06daecd71..9270cc637c 100644 --- a/test/extensions/filters/network/redis_proxy/config_test.cc +++ b/test/extensions/filters/network/redis_proxy/config_test.cc @@ -169,6 +169,16 @@ stat_prefix: foo cb(connection); } +// Test that the deprecated extension name still functions. +TEST(RedisProxyFilterConfigFactoryTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.redis_proxy"; + + ASSERT_NE( + nullptr, + Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + } // namespace RedisProxy } // namespace NetworkFilters } // namespace Extensions diff --git a/test/extensions/filters/network/redis_proxy/redis_proxy_integration_test.cc b/test/extensions/filters/network/redis_proxy/redis_proxy_integration_test.cc index 2ddd0487ff..ff117f5593 100644 --- a/test/extensions/filters/network/redis_proxy/redis_proxy_integration_test.cc +++ b/test/extensions/filters/network/redis_proxy/redis_proxy_integration_test.cc @@ -52,7 +52,7 @@ const std::string CONFIG = R"EOF( port_value: 0 filter_chains: filters: - name: envoy.redis_proxy + name: envoy.filters.network.redis_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProxy stat_prefix: redis_stats @@ -142,7 +142,7 @@ const std::string CONFIG_WITH_ROUTES_BASE = R"EOF( port_value: 0 filter_chains: filters: - name: envoy.redis_proxy + name: envoy.filters.network.redis_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProxy stat_prefix: redis_stats @@ -201,7 +201,7 @@ const std::string CONFIG_WITH_ROUTES_AND_AUTH_PASSWORDS = R"EOF( - name: cluster_0 type: STATIC typed_extension_protocol_options: - envoy.redis_proxy: + envoy.filters.network.redis_proxy: "@type": type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProtocolOptions auth_password: { inline_string: cluster_0_password } lb_policy: RANDOM @@ -218,7 +218,7 @@ const std::string CONFIG_WITH_ROUTES_AND_AUTH_PASSWORDS = R"EOF( type: STATIC lb_policy: RANDOM typed_extension_protocol_options: - envoy.redis_proxy: + envoy.filters.network.redis_proxy: "@type": type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProtocolOptions auth_password: { inline_string: cluster_1_password } load_assignment: @@ -233,7 +233,7 @@ const std::string CONFIG_WITH_ROUTES_AND_AUTH_PASSWORDS = R"EOF( - name: cluster_2 type: STATIC typed_extension_protocol_options: - envoy.redis_proxy: + envoy.filters.network.redis_proxy: "@type": type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProtocolOptions auth_password: { inline_string: cluster_2_password } lb_policy: RANDOM @@ -254,7 +254,7 @@ const std::string CONFIG_WITH_ROUTES_AND_AUTH_PASSWORDS = R"EOF( port_value: 0 filter_chains: filters: - name: envoy.redis_proxy + name: envoy.filters.network.redis_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProxy stat_prefix: redis_stats diff --git a/test/extensions/filters/network/tcp_proxy/config_test.cc b/test/extensions/filters/network/tcp_proxy/config_test.cc index 43cc30bbcb..635004dcf2 100644 --- a/test/extensions/filters/network/tcp_proxy/config_test.cc +++ b/test/extensions/filters/network/tcp_proxy/config_test.cc @@ -125,6 +125,16 @@ TEST(ConfigTest, ConfigTest) { cb(connection); } +// Test that the deprecated extension name still functions. +TEST(ConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + const std::string deprecated_name = "envoy.tcp_proxy"; + + ASSERT_NE( + nullptr, + Registry::FactoryRegistry::getFactory( + deprecated_name)); +} + } // namespace TcpProxy } // namespace NetworkFilters } // namespace Extensions diff --git a/test/integration/ads_integration.cc b/test/integration/ads_integration.cc index 53c7279b45..a307d5d84f 100644 --- a/test/integration/ads_integration.cc +++ b/test/integration/ads_integration.cc @@ -88,7 +88,7 @@ AdsIntegrationTest::buildListener(const std::string& name, const std::string& ro port_value: 0 filter_chains: filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager stat_prefix: {} @@ -112,7 +112,7 @@ AdsIntegrationTest::buildRedisListener(const std::string& name, const std::strin port_value: 0 filter_chains: filters: - - name: envoy.redis_proxy + - name: envoy.filters.network.redis_proxy typed_config: "@type": type.googleapis.com/envoy.config.filter.network.redis_proxy.v2.RedisProxy settings: diff --git a/test/integration/echo_integration_test.cc b/test/integration/echo_integration_test.cc index 68f02fa64b..79afa2fdee 100644 --- a/test/integration/echo_integration_test.cc +++ b/test/integration/echo_integration_test.cc @@ -17,13 +17,13 @@ class EchoIntegrationTest : public testing::TestWithParamaddOrUpdateListener(parseListenerFromV2Yaml(yaml), "", true), - EnvoyException, - "Error: envoy.tcp_proxy must be the terminal network filter."); + EXPECT_THROW_WITH_REGEX( + manager_->addOrUpdateListener(parseListenerFromV2Yaml(yaml), "", true), EnvoyException, + "Error: envoy.filters.network.tcp_proxy must be the terminal network filter."); } TEST_F(ListenerManagerImplWithRealFiltersTest, BadFilterName) { @@ -3115,7 +3115,7 @@ TEST_F(ListenerManagerImplWithRealFiltersTest, Metadata) { filter_chains: - filter_chain_match: filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager config: stat_prefix: metadata_test route_config: diff --git a/test/server/server_corpus/google_com_proxy.v2.pb_text b/test/server/server_corpus/google_com_proxy.v2.pb_text index 3585ae9c7e..1d6dd9b744 100644 --- a/test/server/server_corpus/google_com_proxy.v2.pb_text +++ b/test/server/server_corpus/google_com_proxy.v2.pb_text @@ -9,7 +9,7 @@ static_resources { } filter_chains { filters { - name: "envoy.http_connection_manager" + name: "envoy.filters.network.http_connection_manager" config { fields { key: "http_filters" diff --git a/test/server/test_data/static_validation/network_filter_unknown_field.yaml b/test/server/test_data/static_validation/network_filter_unknown_field.yaml index 79ec8943ac..9846258483 100644 --- a/test/server/test_data/static_validation/network_filter_unknown_field.yaml +++ b/test/server/test_data/static_validation/network_filter_unknown_field.yaml @@ -7,7 +7,7 @@ static_resources: port_value: 0 filter_chains: - filters: - - name: envoy.http_connection_manager + - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager codec_type: HTTP2 From 0e606768c5905b42f02b9c60ae2b3d4e78b49fe0 Mon Sep 17 00:00:00 2001 From: Dmitri Dolguikh Date: Thu, 13 Feb 2020 15:45:37 -0800 Subject: [PATCH 53/87] Fixes proxy_protocol_test failures under gcc due to the order in which destrcutors are called. (#10052) Signed-off-by: Dmitri Dolguikh --- .../filters/listener/proxy_protocol/proxy_protocol_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc index 5abfba8043..44fdd8d701 100644 --- a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc +++ b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc @@ -173,6 +173,7 @@ class ProxyProtocolTest : public testing::TestWithParam socket_; Network::MockListenSocketFactory socket_factory_; + Network::NopConnectionBalancerImpl connection_balancer_; Network::ConnectionHandlerPtr connection_handler_; Network::MockFilterChainFactory factory_; Network::ClientConnectionPtr conn_; @@ -182,7 +183,6 @@ class ProxyProtocolTest : public testing::TestWithParam read_filter_; std::string name_; const Network::FilterChainSharedPtr filter_chain_; - Network::NopConnectionBalancerImpl connection_balancer_; }; // Parameterize the listener socket address version. @@ -1006,6 +1006,7 @@ class WildcardProxyProtocolTest : public testing::TestWithParam socket_; Network::Address::InstanceConstSharedPtr local_dst_address_; + Network::NopConnectionBalancerImpl connection_balancer_; Network::ConnectionHandlerPtr connection_handler_; Network::MockFilterChainFactory factory_; Network::ClientConnectionPtr conn_; @@ -1015,7 +1016,6 @@ class WildcardProxyProtocolTest : public testing::TestWithParam read_filter_; std::string name_; const Network::FilterChainSharedPtr filter_chain_; - Network::NopConnectionBalancerImpl connection_balancer_; }; // Parameterize the listener socket address version. From f7de5ebdb2459250f4fde233bc0c73d5c5336967 Mon Sep 17 00:00:00 2001 From: Oleg Shaldybin Date: Thu, 13 Feb 2020 16:37:59 -0800 Subject: [PATCH 54/87] Use zero copy gRPC frame protector for TSI socket (#9957) Zero copy protector is more efficient but the main reason to use it is the fact that we're using some protocols internally that don't work with the default TSI protector, only with the zero copy one. Signed-off-by: Oleg Shaldibin --- .../transport_sockets/alts/grpc_tsi.h | 4 +- .../alts/tsi_frame_protector.cc | 134 ++++++++++++------ .../alts/tsi_frame_protector.h | 2 - .../transport_sockets/alts/tsi_socket.cc | 7 +- .../alts/tsi_frame_protector_test.cc | 33 ++--- 5 files changed, 106 insertions(+), 74 deletions(-) diff --git a/source/extensions/transport_sockets/alts/grpc_tsi.h b/source/extensions/transport_sockets/alts/grpc_tsi.h index d3aa0a0b15..de36141e87 100644 --- a/source/extensions/transport_sockets/alts/grpc_tsi.h +++ b/source/extensions/transport_sockets/alts/grpc_tsi.h @@ -13,6 +13,7 @@ #include "grpc/grpc_security.h" #include "src/core/tsi/alts/handshaker/alts_shared_resource.h" #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" +#include "src/core/tsi/transport_security_grpc.h" #include "src/core/tsi/transport_security_interface.h" #ifndef _MSC_VER @@ -26,7 +27,8 @@ namespace Extensions { namespace TransportSockets { namespace Alts { -using CFrameProtectorPtr = CSmartPtr; +using CFrameProtectorPtr = + CSmartPtr; using CHandshakerResultPtr = CSmartPtr; using CHandshakerPtr = CSmartPtr; diff --git a/source/extensions/transport_sockets/alts/tsi_frame_protector.cc b/source/extensions/transport_sockets/alts/tsi_frame_protector.cc index 1cb8cc2249..d248c3f380 100644 --- a/source/extensions/transport_sockets/alts/tsi_frame_protector.cc +++ b/source/extensions/transport_sockets/alts/tsi_frame_protector.cc @@ -1,49 +1,67 @@ #include "extensions/transport_sockets/alts/tsi_frame_protector.h" +#include "common/buffer/buffer_impl.h" #include "common/common/assert.h" +#include "grpc/slice_buffer.h" +#include "src/core/tsi/transport_security_grpc.h" +#include "src/core/tsi/transport_security_interface.h" + namespace Envoy { namespace Extensions { namespace TransportSockets { namespace Alts { -// TODO(lizan): tune size later -static constexpr uint32_t BUFFER_SIZE = 16384; - TsiFrameProtector::TsiFrameProtector(CFrameProtectorPtr&& frame_protector) : frame_protector_(std::move(frame_protector)) {} tsi_result TsiFrameProtector::protect(Buffer::Instance& input, Buffer::Instance& output) { ASSERT(frame_protector_); - unsigned char protected_buffer[BUFFER_SIZE]; - while (input.length() > 0) { - auto* message_bytes = reinterpret_cast(input.linearize(input.length())); - size_t protected_buffer_size = BUFFER_SIZE; - size_t processed_message_size = input.length(); - tsi_result result = - tsi_frame_protector_protect(frame_protector_.get(), message_bytes, &processed_message_size, - protected_buffer, &protected_buffer_size); - if (result != TSI_OK) { - ASSERT(result != TSI_INVALID_ARGUMENT && result != TSI_UNIMPLEMENTED); - return result; - } - output.add(protected_buffer, protected_buffer_size); - input.drain(processed_message_size); + if (input.length() == 0) { + return TSI_OK; + } + + grpc_core::ExecCtx exec_ctx; + grpc_slice input_slice = grpc_slice_from_copied_buffer( + reinterpret_cast(input.linearize(input.length())), input.length()); + + grpc_slice_buffer message_buffer; + grpc_slice_buffer_init(&message_buffer); + grpc_slice_buffer_add(&message_buffer, input_slice); + + grpc_slice_buffer protected_buffer; + grpc_slice_buffer_init(&protected_buffer); + + tsi_result result = tsi_zero_copy_grpc_protector_protect(frame_protector_.get(), &message_buffer, + &protected_buffer); + + if (result != TSI_OK) { + ASSERT(result != TSI_INVALID_ARGUMENT && result != TSI_UNIMPLEMENTED); + grpc_slice_buffer_destroy(&message_buffer); + grpc_slice_buffer_destroy(&protected_buffer); + return result; } - // TSI may buffer some of the input internally. Flush its buffer to protected_buffer. - size_t still_pending_size; - do { - size_t protected_buffer_size = BUFFER_SIZE; - tsi_result result = tsi_frame_protector_protect_flush( - frame_protector_.get(), protected_buffer, &protected_buffer_size, &still_pending_size); - if (result != TSI_OK) { - ASSERT(result != TSI_INVALID_ARGUMENT && result != TSI_UNIMPLEMENTED); - return result; - } - output.add(protected_buffer, protected_buffer_size); - } while (still_pending_size > 0); + const size_t protected_data_length = protected_buffer.length; + char* protected_data = new char[protected_data_length]; + + grpc_slice_buffer_move_first_into_buffer(&protected_buffer, protected_data_length, + protected_data); + + auto fragment = new Buffer::BufferFragmentImpl( + protected_data, protected_data_length, + [protected_data](const void*, size_t, + const Envoy::Buffer::BufferFragmentImpl* this_fragment) { + delete[] protected_data; + delete this_fragment; + }); + + output.addBufferFragment(*fragment); + input.drain(input.length()); + + grpc_slice_buffer_destroy(&message_buffer); + grpc_slice_buffer_destroy(&protected_buffer); return TSI_OK; } @@ -51,23 +69,51 @@ tsi_result TsiFrameProtector::protect(Buffer::Instance& input, Buffer::Instance& tsi_result TsiFrameProtector::unprotect(Buffer::Instance& input, Buffer::Instance& output) { ASSERT(frame_protector_); - unsigned char unprotected_buffer[BUFFER_SIZE]; - - while (input.length() > 0) { - auto* message_bytes = reinterpret_cast(input.linearize(input.length())); - size_t unprotected_buffer_size = BUFFER_SIZE; - size_t processed_message_size = input.length(); - tsi_result result = tsi_frame_protector_unprotect(frame_protector_.get(), message_bytes, - &processed_message_size, unprotected_buffer, - &unprotected_buffer_size); - if (result != TSI_OK) { - ASSERT(result != TSI_INVALID_ARGUMENT && result != TSI_UNIMPLEMENTED); - return result; - } - output.add(unprotected_buffer, unprotected_buffer_size); - input.drain(processed_message_size); + if (input.length() == 0) { + return TSI_OK; } + grpc_core::ExecCtx exec_ctx; + grpc_slice input_slice = grpc_slice_from_copied_buffer( + reinterpret_cast(input.linearize(input.length())), input.length()); + + grpc_slice_buffer protected_buffer; + grpc_slice_buffer_init(&protected_buffer); + grpc_slice_buffer_add(&protected_buffer, input_slice); + + grpc_slice_buffer unprotected_buffer; + grpc_slice_buffer_init(&unprotected_buffer); + + tsi_result result = tsi_zero_copy_grpc_protector_unprotect( + frame_protector_.get(), &protected_buffer, &unprotected_buffer); + + if (result != TSI_OK) { + ASSERT(result != TSI_INVALID_ARGUMENT && result != TSI_UNIMPLEMENTED); + grpc_slice_buffer_destroy(&protected_buffer); + grpc_slice_buffer_destroy(&unprotected_buffer); + return result; + } + + const size_t unprotected_data_length = unprotected_buffer.length; + char* unprotected_data = new char[unprotected_data_length]; + + grpc_slice_buffer_move_first_into_buffer(&unprotected_buffer, unprotected_data_length, + unprotected_data); + + auto fragment = new Buffer::BufferFragmentImpl( + unprotected_data, unprotected_data_length, + [unprotected_data](const void*, size_t, + const Envoy::Buffer::BufferFragmentImpl* this_fragment) { + delete[] unprotected_data; + delete this_fragment; + }); + + output.addBufferFragment(*fragment); + input.drain(input.length()); + + grpc_slice_buffer_destroy(&protected_buffer); + grpc_slice_buffer_destroy(&unprotected_buffer); + return TSI_OK; } diff --git a/source/extensions/transport_sockets/alts/tsi_frame_protector.h b/source/extensions/transport_sockets/alts/tsi_frame_protector.h index 7867770e81..00a3d49ed7 100644 --- a/source/extensions/transport_sockets/alts/tsi_frame_protector.h +++ b/source/extensions/transport_sockets/alts/tsi_frame_protector.h @@ -13,8 +13,6 @@ namespace Alts { * A C++ wrapper for tsi_frame_protector interface. * For detail of tsi_frame_protector, see * https://github.com/grpc/grpc/blob/v1.10.0/src/core/tsi/transport_security_interface.h#L70 - * - * TODO(lizan): migrate to tsi_zero_copy_grpc_protector for further optimization */ class TsiFrameProtector final { public: diff --git a/source/extensions/transport_sockets/alts/tsi_socket.cc b/source/extensions/transport_sockets/alts/tsi_socket.cc index efc7d9135e..0fe5b752ce 100644 --- a/source/extensions/transport_sockets/alts/tsi_socket.cc +++ b/source/extensions/transport_sockets/alts/tsi_socket.cc @@ -131,9 +131,10 @@ Network::PostIoAction TsiSocket::doHandshakeNextDone(NextResultPtr&& next_result unused_byte_size); // returns TSI_OK assuming there is no fatal error. Asserting OK. - tsi_frame_protector* frame_protector; - status = - tsi_handshaker_result_create_frame_protector(handshaker_result, nullptr, &frame_protector); + tsi_zero_copy_grpc_protector* frame_protector; + grpc_core::ExecCtx exec_ctx; + status = tsi_handshaker_result_create_zero_copy_grpc_protector(handshaker_result, nullptr, + &frame_protector); ASSERT(status == TSI_OK); frame_protector_ = std::make_unique(frame_protector); diff --git a/test/extensions/transport_sockets/alts/tsi_frame_protector_test.cc b/test/extensions/transport_sockets/alts/tsi_frame_protector_test.cc index c0db008cb2..ecc9cc066b 100644 --- a/test/extensions/transport_sockets/alts/tsi_frame_protector_test.cc +++ b/test/extensions/transport_sockets/alts/tsi_frame_protector_test.cc @@ -21,11 +21,11 @@ using namespace std::string_literals; class TsiFrameProtectorTest : public testing::Test { public: TsiFrameProtectorTest() - : raw_frame_protector_(tsi_create_fake_frame_protector(nullptr)), + : raw_frame_protector_(tsi_create_fake_zero_copy_grpc_protector(nullptr)), frame_protector_(CFrameProtectorPtr{raw_frame_protector_}) {} protected: - tsi_frame_protector* raw_frame_protector_; + tsi_zero_copy_grpc_protector* raw_frame_protector_; TsiFrameProtector frame_protector_; }; @@ -64,24 +64,9 @@ TEST_F(TsiFrameProtectorTest, Protect) { } TEST_F(TsiFrameProtectorTest, ProtectError) { - const tsi_frame_protector_vtable* vtable = raw_frame_protector_->vtable; - tsi_frame_protector_vtable mock_vtable = *raw_frame_protector_->vtable; - mock_vtable.protect = [](tsi_frame_protector*, const unsigned char*, size_t*, unsigned char*, - size_t*) { return TSI_INTERNAL_ERROR; }; - raw_frame_protector_->vtable = &mock_vtable; - - Buffer::OwnedImpl input, encrypted; - input.add("foo"); - - EXPECT_EQ(TSI_INTERNAL_ERROR, frame_protector_.protect(input, encrypted)); - - raw_frame_protector_->vtable = vtable; -} - -TEST_F(TsiFrameProtectorTest, ProtectFlushError) { - const tsi_frame_protector_vtable* vtable = raw_frame_protector_->vtable; - tsi_frame_protector_vtable mock_vtable = *raw_frame_protector_->vtable; - mock_vtable.protect_flush = [](tsi_frame_protector*, unsigned char*, size_t*, size_t*) { + const tsi_zero_copy_grpc_protector_vtable* vtable = raw_frame_protector_->vtable; + tsi_zero_copy_grpc_protector_vtable mock_vtable = *raw_frame_protector_->vtable; + mock_vtable.protect = [](tsi_zero_copy_grpc_protector*, grpc_slice_buffer*, grpc_slice_buffer*) { return TSI_INTERNAL_ERROR; }; raw_frame_protector_->vtable = &mock_vtable; @@ -125,10 +110,10 @@ TEST_F(TsiFrameProtectorTest, Unprotect) { } } TEST_F(TsiFrameProtectorTest, UnprotectError) { - const tsi_frame_protector_vtable* vtable = raw_frame_protector_->vtable; - tsi_frame_protector_vtable mock_vtable = *raw_frame_protector_->vtable; - mock_vtable.unprotect = [](tsi_frame_protector*, const unsigned char*, size_t*, unsigned char*, - size_t*) { return TSI_INTERNAL_ERROR; }; + const tsi_zero_copy_grpc_protector_vtable* vtable = raw_frame_protector_->vtable; + tsi_zero_copy_grpc_protector_vtable mock_vtable = *raw_frame_protector_->vtable; + mock_vtable.unprotect = [](tsi_zero_copy_grpc_protector*, grpc_slice_buffer*, + grpc_slice_buffer*) { return TSI_INTERNAL_ERROR; }; raw_frame_protector_->vtable = &mock_vtable; Buffer::OwnedImpl input, decrypted; From 0eebdc211918147239b0c6396e9edf42cb732811 Mon Sep 17 00:00:00 2001 From: Rama Chavali Date: Fri, 14 Feb 2020 07:59:48 -0800 Subject: [PATCH 55/87] docs: fix yaml indentation (#10067) Signed-off-by: Rama Chavali --- api/envoy/api/v2/auth/cert.proto | 4 ++-- api/envoy/extensions/transport_sockets/tls/v3/cert.proto | 4 ++-- generated_api_shadow/envoy/api/v2/auth/cert.proto | 4 ++-- .../envoy/extensions/transport_sockets/tls/v3/cert.proto | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/envoy/api/v2/auth/cert.proto b/api/envoy/api/v2/auth/cert.proto index 52e5e29a83..cdb6a3d168 100644 --- a/api/envoy/api/v2/auth/cert.proto +++ b/api/envoy/api/v2/auth/cert.proto @@ -296,8 +296,8 @@ message CertificateValidationContext { // // .. code-block:: yaml // - // match_subject_alt_names: - // exact: "api.example.com" + // match_subject_alt_names: + // exact: "api.example.com" // // .. attention:: // diff --git a/api/envoy/extensions/transport_sockets/tls/v3/cert.proto b/api/envoy/extensions/transport_sockets/tls/v3/cert.proto index 8c6ee3d88d..4d43b0ac99 100644 --- a/api/envoy/extensions/transport_sockets/tls/v3/cert.proto +++ b/api/envoy/extensions/transport_sockets/tls/v3/cert.proto @@ -303,8 +303,8 @@ message CertificateValidationContext { // // .. code-block:: yaml // - // match_subject_alt_names: - // exact: "api.example.com" + // match_subject_alt_names: + // exact: "api.example.com" // // .. attention:: // diff --git a/generated_api_shadow/envoy/api/v2/auth/cert.proto b/generated_api_shadow/envoy/api/v2/auth/cert.proto index 52e5e29a83..cdb6a3d168 100644 --- a/generated_api_shadow/envoy/api/v2/auth/cert.proto +++ b/generated_api_shadow/envoy/api/v2/auth/cert.proto @@ -296,8 +296,8 @@ message CertificateValidationContext { // // .. code-block:: yaml // - // match_subject_alt_names: - // exact: "api.example.com" + // match_subject_alt_names: + // exact: "api.example.com" // // .. attention:: // diff --git a/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto b/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto index 61e5b21788..c06c39d7c5 100644 --- a/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto +++ b/generated_api_shadow/envoy/extensions/transport_sockets/tls/v3/cert.proto @@ -308,8 +308,8 @@ message CertificateValidationContext { // // .. code-block:: yaml // - // match_subject_alt_names: - // exact: "api.example.com" + // match_subject_alt_names: + // exact: "api.example.com" // // .. attention:: // From 68a0e6ab03f3a4a1a88cd001ffe49644d09b6085 Mon Sep 17 00:00:00 2001 From: ansraliant Date: Sat, 15 Feb 2020 02:47:18 +0900 Subject: [PATCH 56/87] docs: fix reference configurations example (#10062) Fix Configuration Generator example location. Risk Level: Low Testing: No testing needed Docs Changes: Location of generated config files Signed-off-by: Gabriel Verdi --- docs/root/install/ref_configs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/root/install/ref_configs.rst b/docs/root/install/ref_configs.rst index c4c5fad8f0..5981498bef 100644 --- a/docs/root/install/ref_configs.rst +++ b/docs/root/install/ref_configs.rst @@ -34,7 +34,7 @@ To generate the example configurations run the following from the root of the re mkdir -p generated/configs bazel build //configs:example_configs - tar xvf $PWD/bazel-genfiles/configs/example_configs.tar -C generated/configs + tar xvf $PWD/bazel-out/k8-fastbuild/bin/configs/example_configs.tar -C generated/configs The previous command will produce three fully expanded configurations using some variables defined inside of `configgen.py`. See the comments inside of `configgen.py` for detailed From b0a18509993272cb7b4a4c3484890ad8a56ed68a Mon Sep 17 00:00:00 2001 From: Matt Klein Date: Fri, 14 Feb 2020 10:10:19 -0800 Subject: [PATCH 57/87] http: only convert host -> :authority for request headers (#10039) * http: only covert host -> :authority for request headers This change fixes https://github.com/envoyproxy/envoy/issues/9873. This change does two things: 1) Change the static lookup map for request headers to be different for other header types. This moves the host -> authority translation into request headers only. 2) Reimplements TestHeaderMap to be a wrapper around the underlying header map implementation. This is primarily required because the static table lookup requires a virtual call now in paths previously called via constructors. Thus, now those constructors have to use static factories. In order to keep the niceties that we have in TestHeaderMapImpl, it's now required that we wrap the underlying implementation vs derive from the production implementation. This change is IMO a much cleaner way of handling the test header map, but it required various small fixes in code that previously assumed that TestHeaderMapImpl directly derives from HeaderMapImpl as opposed to HeaderMap and friends. Signed-off-by: Matt Klein --- ci/filter_example_setup.sh | 2 +- include/envoy/http/header_map.h | 22 +++ source/common/http/conn_manager_impl.cc | 5 +- source/common/http/header_map_impl.cc | 100 ++++++---- source/common/http/header_map_impl.h | 81 ++++---- source/common/http/header_utility.cc | 2 +- source/common/http/http1/codec_impl.cc | 22 +-- source/common/http/http1/codec_impl.h | 42 ++-- source/common/http/http2/codec_impl.cc | 12 +- source/common/http/http2/codec_impl.h | 29 ++- source/common/http/utility.cc | 16 +- source/common/router/router.cc | 16 +- source/common/upstream/health_checker_impl.cc | 16 +- .../common/ext_authz/ext_authz_http_impl.cc | 13 +- .../simple_http_cache/simple_http_cache.cc | 6 +- .../filters/http/cors/cors_filter.cc | 4 +- .../extensions/filters/http/lua/lua_filter.cc | 4 +- .../grpc_client_integration_test_harness.h | 2 +- test/common/http/conn_manager_impl_test.cc | 6 +- test/common/http/conn_manager_utility_test.cc | 24 +-- test/common/http/header_map_impl_fuzz_test.cc | 3 +- test/common/http/header_map_impl_test.cc | 78 +++++--- .../filters/http/csrf/csrf_filter_test.cc | 34 ++-- test/integration/fake_upstream.cc | 15 +- test/integration/fake_upstream.h | 6 +- test/integration/http_integration.cc | 6 +- test/integration/protocol_integration_test.cc | 19 ++ .../integration/ratelimit_integration_test.cc | 4 +- test/mocks/http/mocks.h | 18 +- test/mocks/http/stream_decoder.cc | 4 + test/test_common/utility.cc | 51 ----- test/test_common/utility.h | 183 ++++++++++++------ 32 files changed, 468 insertions(+), 377 deletions(-) diff --git a/ci/filter_example_setup.sh b/ci/filter_example_setup.sh index b374eaf644..f718f85fa8 100644 --- a/ci/filter_example_setup.sh +++ b/ci/filter_example_setup.sh @@ -5,7 +5,7 @@ set -e # This is the hash on https://github.com/envoyproxy/envoy-filter-example.git we pin to. -ENVOY_FILTER_EXAMPLE_GITSHA="25eac570dd2bf3256dff01a04a9ce2a308e61f60" +ENVOY_FILTER_EXAMPLE_GITSHA="25e1ad74e3efd18c794a022038a5077725df2f6b" ENVOY_FILTER_EXAMPLE_SRCDIR="${BUILD_DIR}/envoy-filter-example" export ENVOY_FILTER_EXAMPLE_TESTS="//:echo2_integration_test //http-filter-example:http_filter_integration_test //:envoy_binary_test" diff --git a/include/envoy/http/header_map.h b/include/envoy/http/header_map.h index b47015f4a3..2524a37448 100644 --- a/include/envoy/http/header_map.h +++ b/include/envoy/http/header_map.h @@ -369,6 +369,20 @@ class HeaderMap { ALL_INLINE_HEADERS(DEFINE_INLINE_HEADER) + /** + * For testing. This is an exact match comparison (order matters). + */ + virtual bool operator==(const HeaderMap& rhs) const PURE; + virtual bool operator!=(const HeaderMap& rhs) const PURE; + + /** + * Add a header via full move. This is the expected high performance paths for codecs populating + * a map when receiving. + * @param key supplies the header key. + * @param value supplies the header value. + */ + virtual void addViaMove(HeaderString&& key, HeaderString&& value) PURE; + /** * Add a reference header to the map. Both key and value MUST point to data that will live beyond * the lifetime of any request/response using the string (since a codec may optimize for zero @@ -586,6 +600,14 @@ class HeaderMap { headers.dumpState(os); return os; } + +protected: + // In TestHeaderMapImpl and VerifiedHeaderMapImpl, this method is overridden to perform a + // time-consuming manual byte size count on each operation to verify the byte size. For prod + // HeaderMaps, this verification is skipped. + // TODO(asraa): Move this verification out of prod code and wrap virtual HeaderMap methods + // in both VerifiedHeaderMapImpl and TestHeaderMapImpl with the verification. + virtual void verifyByteSize() {} }; using HeaderMapPtr = std::unique_ptr; diff --git a/source/common/http/conn_manager_impl.cc b/source/common/http/conn_manager_impl.cc index 5060fbd9fc..8e71f7b912 100644 --- a/source/common/http/conn_manager_impl.cc +++ b/source/common/http/conn_manager_impl.cc @@ -122,8 +122,9 @@ ConnectionManagerImpl::ConnectionManagerImpl(ConnectionManagerConfig& config, time_source_(time_source) {} const HeaderMapImpl& ConnectionManagerImpl::continueHeader() { - CONSTRUCT_ON_FIRST_USE(HeaderMapImpl, - {Http::Headers::get().Status, std::to_string(enumToInt(Code::Continue))}); + static const auto headers = HeaderMapImpl::create( + {{Http::Headers::get().Status, std::to_string(enumToInt(Code::Continue))}}); + return *headers; } void ConnectionManagerImpl::initializeReadFilterCallbacks(Network::ReadFilterCallbacks& callbacks) { diff --git a/source/common/http/header_map_impl.cc b/source/common/http/header_map_impl.cc index ecc98017b8..ec290e753c 100644 --- a/source/common/http/header_map_impl.cc +++ b/source/common/http/header_map_impl.cc @@ -8,7 +8,6 @@ #include "common/common/assert.h" #include "common/common/dump_state_utils.h" #include "common/common/empty_string.h" -#include "common/common/utility.h" #include "common/singleton/const_singleton.h" #include "absl/strings/match.h" @@ -274,20 +273,25 @@ void HeaderMapImpl::HeaderEntryImpl::value(const HeaderEntry& header) { return {&h.inline_headers_.name##_, &Headers::get().name}; \ }); -/** - * This is the static lookup table that is used to determine whether a header is one of the O(1) - * headers. This uses a trie for lookup time at most equal to the size of the incoming string. - */ -struct HeaderMapImpl::StaticLookupTable : public TrieLookupTable { - StaticLookupTable() { - ALL_INLINE_HEADERS(INLINE_HEADER_STATIC_MAP_ENTRY) +HeaderMapImpl::StaticLookupTable::StaticLookupTable() { + ALL_INLINE_HEADERS(INLINE_HEADER_STATIC_MAP_ENTRY) +} - // Special case where we map a legacy host header to :authority. - add(Headers::get().HostLegacy.get().c_str(), [](HeaderMapImpl& h) -> StaticLookupResponse { - return {&h.inline_headers_.Host_, &Headers::get().Host}; - }); - } -}; +const HeaderMapImpl::StaticLookupTable& HeaderMapImpl::staticLookupTable() const { + return ConstSingleton::get(); +} + +RequestHeaderMapImpl::RequestHeaderStaticLookupTable::RequestHeaderStaticLookupTable() + : StaticLookupTable() { + // Special case where we map a legacy host header to :authority. + add(Headers::get().HostLegacy.get().c_str(), [](HeaderMapImpl& h) -> StaticLookupResponse { + return {&h.inline_headers_.Host_, &Headers::get().Host}; + }); +} + +const HeaderMapImpl::StaticLookupTable& RequestHeaderMapImpl::staticLookupTable() const { + return ConstSingleton::get(); +} uint64_t HeaderMapImpl::appendToHeader(HeaderString& header, absl::string_view data, absl::string_view delimiter) { @@ -305,17 +309,30 @@ uint64_t HeaderMapImpl::appendToHeader(HeaderString& header, absl::string_view d HeaderMapImpl::HeaderMapImpl() { inline_headers_.clear(); } -HeaderMapImpl::HeaderMapImpl( - const std::initializer_list>& values) - : HeaderMapImpl() { +HeaderMapImplPtr HeaderMapImpl::create( + const std::initializer_list>& values) { + auto new_header_map = std::make_unique(); + initFromInitList(*new_header_map, values); + return new_header_map; +} + +HeaderMapImplPtr HeaderMapImpl::create(const HeaderMap& rhs) { + auto new_header_map = std::make_unique(); + copyFrom(*new_header_map, rhs); + return new_header_map; +} + +void HeaderMapImpl::initFromInitList( + HeaderMapImpl& new_header_map, + const std::initializer_list>& values) { for (auto& value : values) { HeaderString key_string; key_string.setCopy(value.first.get().c_str(), value.first.get().size()); HeaderString value_string; value_string.setCopy(value.second.c_str(), value.second.size()); - addViaMove(std::move(key_string), std::move(value_string)); + new_header_map.addViaMove(std::move(key_string), std::move(value_string)); } - verifyByteSize(); + new_header_map.verifyByteSize(); } void HeaderMapImpl::updateSize(uint64_t from_size, uint64_t to_size) { @@ -331,7 +348,7 @@ void HeaderMapImpl::subtractSize(uint64_t size) { cached_byte_size_ -= size; } -void HeaderMapImpl::copyFrom(const HeaderMap& header_map) { +void HeaderMapImpl::copyFrom(HeaderMapImpl& lhs, const HeaderMap& header_map) { header_map.iterate( [](const HeaderEntry& header, void* context) -> HeaderMap::Iterate { // TODO(mattklein123) PERF: Avoid copying here if not necessary. @@ -344,17 +361,34 @@ void HeaderMapImpl::copyFrom(const HeaderMap& header_map) { std::move(value_string)); return HeaderMap::Iterate::Continue; }, - this); - verifyByteSize(); + &lhs); + lhs.verifyByteSize(); } -bool HeaderMapImpl::operator==(const HeaderMapImpl& rhs) const { +namespace { + +HeaderMap::Iterate collectAllHeaders(const HeaderEntry& header, void* headers) { + static_cast>*>(headers)->push_back( + std::make_pair(header.key().getStringView(), header.value().getStringView())); + return HeaderMap::Iterate::Continue; +}; + +} // namespace + +// This is currently only used in tests and is not optimized for performance. +bool HeaderMapImpl::operator==(const HeaderMap& rhs) const { if (size() != rhs.size()) { return false; } - for (auto i = headers_.begin(), j = rhs.headers_.begin(); i != headers_.end(); ++i, ++j) { - if (i->key() != j->key().getStringView() || i->value() != j->value().getStringView()) { + std::vector> rhs_headers; + rhs_headers.reserve(rhs.size()); + rhs.iterate(collectAllHeaders, &rhs_headers); + + auto i = headers_.begin(); + auto j = rhs_headers.begin(); + for (; i != headers_.end(); ++i, ++j) { + if (i->key() != j->first || i->value() != j->second) { return false; } } @@ -362,10 +396,10 @@ bool HeaderMapImpl::operator==(const HeaderMapImpl& rhs) const { return true; } -bool HeaderMapImpl::operator!=(const HeaderMapImpl& rhs) const { return !operator==(rhs); } +bool HeaderMapImpl::operator!=(const HeaderMap& rhs) const { return !operator==(rhs); } void HeaderMapImpl::insertByKey(HeaderString&& key, HeaderString&& value) { - EntryCb cb = ConstSingleton::get().find(key.getStringView()); + EntryCb cb = staticLookupTable().find(key.getStringView()); if (cb) { key.clear(); StaticLookupResponse ref_lookup_response = cb(*this); @@ -506,14 +540,14 @@ void HeaderMapImpl::setCopy(const LowerCaseString& key, absl::string_view value) uint64_t HeaderMapImpl::byteSize() const { return cached_byte_size_; } -uint64_t HeaderMapImpl::byteSizeInternal() const { +void HeaderMapImpl::verifyByteSizeInternalForTest() const { // Computes the total byte size by summing the byte size of the keys and values. uint64_t byte_size = 0; for (const HeaderEntryImpl& header : headers_) { byte_size += header.key().size(); byte_size += header.value().size(); } - return byte_size; + ASSERT(cached_byte_size_ == byte_size); } const HeaderEntry* HeaderMapImpl::get(const LowerCaseString& key) const { @@ -554,7 +588,7 @@ void HeaderMapImpl::iterateReverse(ConstIterateCb cb, void* context) const { HeaderMap::Lookup HeaderMapImpl::lookup(const LowerCaseString& key, const HeaderEntry** entry) const { - EntryCb cb = ConstSingleton::get().find(key.get()); + EntryCb cb = staticLookupTable().find(key.get()); if (cb) { // The accessor callbacks for predefined inline headers take a HeaderMapImpl& as an argument; // even though we don't make any modifications, we need to cast_cast in order to use the @@ -582,7 +616,7 @@ void HeaderMapImpl::clear() { } void HeaderMapImpl::remove(const LowerCaseString& key) { - EntryCb cb = ConstSingleton::get().find(key.get()); + EntryCb cb = staticLookupTable().find(key.get()); if (cb) { StaticLookupResponse ref_lookup_response = cb(*this); removeInline(ref_lookup_response.entry_); @@ -605,7 +639,7 @@ void HeaderMapImpl::removePrefix(const LowerCaseString& prefix) { if (to_remove) { // If this header should be removed, make sure any references in the // static lookup table are cleared as well. - EntryCb cb = ConstSingleton::get().find(entry.key().getStringView()); + EntryCb cb = staticLookupTable().find(entry.key().getStringView()); if (cb) { StaticLookupResponse ref_lookup_response = cb(*this); if (ref_lookup_response.entry_) { @@ -666,7 +700,7 @@ HeaderMapImpl::HeaderEntryImpl& HeaderMapImpl::maybeCreateInline(HeaderEntryImpl } HeaderMapImpl::HeaderEntryImpl* HeaderMapImpl::getExistingInline(absl::string_view key) { - EntryCb cb = ConstSingleton::get().find(key); + EntryCb cb = staticLookupTable().find(key); if (cb) { StaticLookupResponse ref_lookup_response = cb(*this); return *ref_lookup_response.entry_; diff --git a/source/common/http/header_map_impl.h b/source/common/http/header_map_impl.h index 155b364e12..8c223602ca 100644 --- a/source/common/http/header_map_impl.h +++ b/source/common/http/header_map_impl.h @@ -9,6 +9,7 @@ #include "envoy/http/header_map.h" #include "common/common/non_copyable.h" +#include "common/common/utility.h" #include "common/http/headers.h" namespace Envoy { @@ -49,34 +50,35 @@ public: #define DEFINE_INLINE_HEADER_STRUCT(name) HeaderEntryImpl* name##_; +class HeaderMapImpl; +using HeaderMapImplPtr = std::unique_ptr; + /** * Implementation of Http::HeaderMap. This is heavily optimized for performance. Roughly, when * headers are added to the map, we do a hash lookup to see if it's one of the O(1) headers. * If it is, we store a reference to it that can be accessed later directly. Most high performance * paths use O(1) direct access. In general, we try to copy as little as possible and allocate as * little as possible in any of the paths. + * TODO(mattklein123): The end result of the header refactor should be to make this a fully + * protected base class or a mix-in for the concrete header types below. */ class HeaderMapImpl : public virtual HeaderMap, NonCopyable { public: HeaderMapImpl(); - explicit HeaderMapImpl( - const std::initializer_list>& values); - explicit HeaderMapImpl(const HeaderMap& rhs) : HeaderMapImpl() { copyFrom(rhs); } + // The following "constructors" call virtual functions during construction and must use the + // static factory pattern. + static HeaderMapImplPtr + create(const std::initializer_list>& values); + static HeaderMapImplPtr create(const HeaderMap& rhs); + static void copyFrom(HeaderMapImpl& lhs, const HeaderMap& rhs); - /** - * Add a header via full move. This is the expected high performance paths for codecs populating - * a map when receiving. - */ - void addViaMove(HeaderString&& key, HeaderString&& value); - - /** - * For testing. Equality is based on equality of the backing list. This is an exact match - * comparison (order matters). - */ - bool operator==(const HeaderMapImpl& rhs) const; - bool operator!=(const HeaderMapImpl& rhs) const; + // Performs a manual byte size count for test verification. + void verifyByteSizeInternalForTest() const; // Http::HeaderMap + bool operator==(const HeaderMap& rhs) const override; + bool operator!=(const HeaderMap& rhs) const override; + void addViaMove(HeaderString&& key, HeaderString&& value) override; void addReference(const LowerCaseString& key, absl::string_view value) override; void addReferenceKey(const LowerCaseString& key, uint64_t value) override; void addReferenceKey(const LowerCaseString& key, absl::string_view value) override; @@ -99,9 +101,6 @@ class HeaderMapImpl : public virtual HeaderMap, NonCopyable { void dumpState(std::ostream& os, int indent_level = 0) const override; protected: - // For tests only, unoptimized, they aren't intended for regular HeaderMapImpl users. - void copyFrom(const HeaderMap& rhs); - struct HeaderEntryImpl : public HeaderEntry, NonCopyable { HeaderEntryImpl(const LowerCaseString& key); HeaderEntryImpl(const LowerCaseString& key, HeaderString&& value); @@ -120,18 +119,19 @@ class HeaderMapImpl : public virtual HeaderMap, NonCopyable { std::list::iterator entry_; }; + /** + * This is the static lookup table that is used to determine whether a header is one of the O(1) + * headers. This uses a trie for lookup time at most equal to the size of the incoming string. + */ struct StaticLookupResponse { HeaderEntryImpl** entry_; const LowerCaseString* key_; }; - using EntryCb = StaticLookupResponse (*)(HeaderMapImpl&); - - /** - * This is the static lookup table that is used to determine whether a header is one of the O(1) - * headers. This uses a trie for lookup time at most equal to the size of the incoming string. - */ - struct StaticLookupTable; // Defined in header_map_impl.cc. + struct StaticLookupTable : public TrieLookupTable { + StaticLookupTable(); + }; + virtual const StaticLookupTable& staticLookupTable() const; struct AllInlineHeaders { void clear() { memset(this, 0, sizeof(*this)); } @@ -215,44 +215,39 @@ class HeaderMapImpl : public virtual HeaderMap, NonCopyable { HeaderString&& value); HeaderEntry* getExisting(const LowerCaseString& key); HeaderEntryImpl* getExistingInline(absl::string_view key); - void removeInline(HeaderEntryImpl** entry); void updateSize(uint64_t from_size, uint64_t to_size); void addSize(uint64_t size); void subtractSize(uint64_t size); + static void + initFromInitList(HeaderMapImpl& new_header_map, + const std::initializer_list>& values); AllInlineHeaders inline_headers_; HeaderList headers_; - // This holds the internal byte size of the HeaderMap. uint64_t cached_byte_size_ = 0; - // Performs a manual byte size count. - uint64_t byteSizeInternal() const; - // In TestHeaderMapImpl and VerifiedHeaderMapImpl, this method is overridden to performs a - // time-consuming manual byte size count on each operation to verify the byte size. For prod - // HeaderMaps, this verification is skipped. - // TODO(asraa): Move this verification out of prod code and wrap virtual Http::HeaderMap methods - // in Http::TestHeaderMapImpl with the verification. - virtual void verifyByteSize() {} - ALL_INLINE_HEADERS(DEFINE_INLINE_HEADER_FUNCS) -}; -using HeaderMapImplPtr = std::unique_ptr; + // Needed so RequestHeaderStaticLookupTable can interact with inline_headers_. + friend class RequestHeaderMapImpl; +}; /** * Typed derived classes for all header map types. * TODO(mattklein123): In future changes we will be differentiating the implementation between * these classes to both fix bugs and improve performance. */ -class RequestHeaderMapImpl : public HeaderMapImpl, public RequestHeaderMap {}; -using RequestHeaderMapImplPtr = std::unique_ptr; +class RequestHeaderMapImpl : public HeaderMapImpl, public RequestHeaderMap { +protected: + struct RequestHeaderStaticLookupTable : public StaticLookupTable { + RequestHeaderStaticLookupTable(); + }; + const StaticLookupTable& staticLookupTable() const override; +}; class RequestTrailerMapImpl : public HeaderMapImpl, public RequestTrailerMap {}; -using RequestTrailerMapImplPtr = std::unique_ptr; class ResponseHeaderMapImpl : public HeaderMapImpl, public ResponseHeaderMap {}; -using ResponseHeaderMapImplPtr = std::unique_ptr; class ResponseTrailerMapImpl : public HeaderMapImpl, public ResponseTrailerMap {}; -using ResponseTrailerMapImplPtr = std::unique_ptr; } // namespace Http } // namespace Envoy diff --git a/source/common/http/header_utility.cc b/source/common/http/header_utility.cc index 0062a35993..744013e225 100644 --- a/source/common/http/header_utility.cc +++ b/source/common/http/header_utility.cc @@ -160,7 +160,7 @@ void HeaderUtility::addHeaders(HeaderMap& headers, const HeaderMap& headers_to_a k.setCopy(header.key().getStringView()); HeaderString v; v.setCopy(header.value().getStringView()); - static_cast(context)->addViaMove(std::move(k), std::move(v)); + static_cast(context)->addViaMove(std::move(k), std::move(v)); return HeaderMap::Iterate::Continue; }, &headers); diff --git a/source/common/http/http1/codec_impl.cc b/source/common/http/http1/codec_impl.cc index b99acad04e..1f04fa951f 100644 --- a/source/common/http/http1/codec_impl.cc +++ b/source/common/http/http1/codec_impl.cc @@ -656,7 +656,7 @@ void ServerConnectionImpl::onEncodeComplete() { } } -void ServerConnectionImpl::handlePath(HeaderMapImpl& headers, unsigned int method) { +void ServerConnectionImpl::handlePath(HeaderMap& headers, unsigned int method) { HeaderString path(Headers::get().Path); bool is_connect = (method == HTTP_CONNECT); @@ -704,7 +704,7 @@ int ServerConnectionImpl::onHeadersComplete() { // to disconnect the connection but we shouldn't fire any more events since it doesn't make // sense. if (active_request_) { - auto& headers = absl::get(headers_or_trailers_); + auto& headers = absl::get(headers_or_trailers_); ENVOY_CONN_LOG(trace, "Server: onHeadersComplete size={}", connection_, headers->size()); const char* method_string = http_method_str(static_cast(parser_.method)); @@ -778,18 +778,18 @@ void ServerConnectionImpl::onMessageComplete() { active_request_->remote_complete_ = true; if (deferred_end_stream_headers_) { active_request_->request_decoder_->decodeHeaders( - std::move(absl::get(headers_or_trailers_)), true); + std::move(absl::get(headers_or_trailers_)), true); deferred_end_stream_headers_ = false; } else if (processing_trailers_) { active_request_->request_decoder_->decodeTrailers( - std::move(absl::get(headers_or_trailers_))); + std::move(absl::get(headers_or_trailers_))); } else { Buffer::OwnedImpl buffer; active_request_->request_decoder_->decodeData(buffer, true); } - // Reset for assertion purposes. - headers_or_trailers_.emplace(nullptr); + // Reset to ensure no information from one requests persists to the next. + headers_or_trailers_.emplace(nullptr); } // Always pause the parser so that the calling code can process 1 request at a time and apply @@ -875,7 +875,7 @@ int ClientConnectionImpl::onHeadersComplete() { if (pending_responses_.empty() && !resetStreamCalled()) { throw PrematureResponseException(static_cast(parser_.status_code)); } else if (!pending_responses_.empty()) { - auto& headers = absl::get(headers_or_trailers_); + auto& headers = absl::get(headers_or_trailers_); ENVOY_CONN_LOG(trace, "Client: onHeadersComplete size={}", connection_, headers->size()); headers->setStatus(parser_.status_code); @@ -930,18 +930,18 @@ void ClientConnectionImpl::onMessageComplete() { if (deferred_end_stream_headers_) { response.decoder_->decodeHeaders( - std::move(absl::get(headers_or_trailers_)), true); + std::move(absl::get(headers_or_trailers_)), true); deferred_end_stream_headers_ = false; } else if (processing_trailers_) { response.decoder_->decodeTrailers( - std::move(absl::get(headers_or_trailers_))); + std::move(absl::get(headers_or_trailers_))); } else { Buffer::OwnedImpl buffer; response.decoder_->decodeData(buffer, true); } - // Reset for assertion purposes. - headers_or_trailers_.emplace(nullptr); + // Reset to ensure no information from one requests persists to the next. + headers_or_trailers_.emplace(nullptr); } } diff --git a/source/common/http/http1/codec_impl.h b/source/common/http/http1/codec_impl.h index d43d220df1..172640a411 100644 --- a/source/common/http/http1/codec_impl.h +++ b/source/common/http/http1/codec_impl.h @@ -225,7 +225,7 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable(headers_or_trailers_)) { - return *absl::get(headers_or_trailers_); + HeaderMap& headers() override { + if (absl::holds_alternative(headers_or_trailers_)) { + return *absl::get(headers_or_trailers_); } else { - return *absl::get(headers_or_trailers_); + return *absl::get(headers_or_trailers_); } } void allocHeaders() override { - ASSERT(nullptr == absl::get(headers_or_trailers_)); - headers_or_trailers_.emplace(std::make_unique()); + ASSERT(nullptr == absl::get(headers_or_trailers_)); + headers_or_trailers_.emplace(std::make_unique()); } void maybeAllocTrailers() override { ASSERT(processing_trailers_); - if (!absl::holds_alternative(headers_or_trailers_)) { - headers_or_trailers_.emplace( - std::make_unique()); + if (!absl::holds_alternative(headers_or_trailers_)) { + headers_or_trailers_.emplace(std::make_unique()); } } @@ -399,7 +398,7 @@ class ServerConnectionImpl : public ServerConnection, public ConnectionImpl { // populated on message begin. Trailers are populated on the first parsed trailer field (if // trailers are enabled). The variant is reset to null headers on message complete for assertion // purposes. - absl::variant headers_or_trailers_; + absl::variant headers_or_trailers_; }; /** @@ -436,22 +435,21 @@ class ClientConnectionImpl : public ClientConnection, public ConnectionImpl { void sendProtocolError(absl::string_view details) override; void onAboveHighWatermark() override; void onBelowLowWatermark() override; - HeaderMapImpl& headers() override { - if (absl::holds_alternative(headers_or_trailers_)) { - return *absl::get(headers_or_trailers_); + HeaderMap& headers() override { + if (absl::holds_alternative(headers_or_trailers_)) { + return *absl::get(headers_or_trailers_); } else { - return *absl::get(headers_or_trailers_); + return *absl::get(headers_or_trailers_); } } void allocHeaders() override { - ASSERT(nullptr == absl::get(headers_or_trailers_)); - headers_or_trailers_.emplace( - std::make_unique()); + ASSERT(nullptr == absl::get(headers_or_trailers_)); + headers_or_trailers_.emplace(std::make_unique()); } void maybeAllocTrailers() override { ASSERT(processing_trailers_); - if (!absl::holds_alternative(headers_or_trailers_)) { - headers_or_trailers_.emplace( + if (!absl::holds_alternative(headers_or_trailers_)) { + headers_or_trailers_.emplace( std::make_unique()); } } @@ -465,7 +463,7 @@ class ClientConnectionImpl : public ClientConnection, public ConnectionImpl { // populated on message begin. Trailers are populated on the first parsed trailer field (if // trailers are enabled). The variant is reset to null headers on message complete for assertion // purposes. - absl::variant headers_or_trailers_; + absl::variant headers_or_trailers_; // The default limit of 80 KiB is the vanilla http_parser behaviour. static constexpr uint32_t MAX_RESPONSE_HEADERS_KB = 80; diff --git a/source/common/http/http2/codec_impl.cc b/source/common/http/http2/codec_impl.cc index 1bbd99f6cf..4f8740882c 100644 --- a/source/common/http/http2/codec_impl.cc +++ b/source/common/http/http2/codec_impl.cc @@ -99,7 +99,7 @@ void ConnectionImpl::StreamImpl::encodeHeadersBase(const HeaderMap& headers, boo // needed until submitHeaders has been called. Http::HeaderMapPtr modified_headers; if (Http::Utility::isUpgrade(headers)) { - modified_headers = std::make_unique(headers); + modified_headers = Http::HeaderMapImpl::create(headers); transformUpgradeFromH1toH2(*modified_headers); buildHeaders(final_headers, *modified_headers); } else { @@ -128,7 +128,7 @@ void ConnectionImpl::StreamImpl::encodeTrailersBase(const HeaderMap& trailers) { // In this case we want trailers to come after we release all pending body data that is // waiting on window updates. We need to save the trailers so that we can emit them later. ASSERT(!pending_trailers_to_encode_); - pending_trailers_to_encode_ = std::make_unique(trailers); + pending_trailers_to_encode_ = HeaderMapImpl::create(trailers); } else { submitTrailers(trailers); parent_.sendPendingFrames(); @@ -185,7 +185,7 @@ void ConnectionImpl::StreamImpl::pendingRecvBufferLowWatermark() { } void ConnectionImpl::ClientStreamImpl::decodeHeaders() { - auto& headers = absl::get(headers_or_trailers_); + auto& headers = absl::get(headers_or_trailers_); if (!upgrade_type_.empty() && headers->Status()) { Http::Utility::transformUpgradeResponseFromH2toH1(*headers, upgrade_type_); } @@ -200,11 +200,11 @@ void ConnectionImpl::ClientStreamImpl::decodeHeaders() { void ConnectionImpl::ClientStreamImpl::decodeTrailers() { response_decoder_.decodeTrailers( - std::move(absl::get(headers_or_trailers_))); + std::move(absl::get(headers_or_trailers_))); } void ConnectionImpl::ServerStreamImpl::decodeHeaders() { - auto& headers = absl::get(headers_or_trailers_); + auto& headers = absl::get(headers_or_trailers_); if (Http::Utility::isH2UpgradeRequest(*headers)) { Http::Utility::transformUpgradeRequestFromH2toH1(*headers); } @@ -213,7 +213,7 @@ void ConnectionImpl::ServerStreamImpl::decodeHeaders() { void ConnectionImpl::ServerStreamImpl::decodeTrailers() { request_decoder_->decodeTrailers( - std::move(absl::get(headers_or_trailers_))); + std::move(absl::get(headers_or_trailers_))); } void ConnectionImpl::StreamImpl::pendingSendBufferHighWatermark() { diff --git a/source/common/http/http2/codec_impl.h b/source/common/http/http2/codec_impl.h index 7d6079791b..f000997a4d 100644 --- a/source/common/http/http2/codec_impl.h +++ b/source/common/http/http2/codec_impl.h @@ -161,7 +161,7 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable(headers_or_trailers_)) { - return *absl::get(headers_or_trailers_); + HeaderMap& headers() override { + if (absl::holds_alternative(headers_or_trailers_)) { + return *absl::get(headers_or_trailers_); } else { - return *absl::get(headers_or_trailers_); + return *absl::get(headers_or_trailers_); } } void allocTrailers() override { // If we are waiting for informational headers, make a new response header map, otherwise // we are about to receive trailers. The codec makes sure this is the only valid sequence. if (waiting_for_non_informational_headers_) { - headers_or_trailers_.emplace( + headers_or_trailers_.emplace( std::make_unique()); } else { - headers_or_trailers_.emplace( + headers_or_trailers_.emplace( std::make_unique()); } } @@ -280,7 +280,7 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable headers_or_trailers_; + absl::variant headers_or_trailers_; std::string upgrade_type_; }; @@ -303,16 +303,15 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable(headers_or_trailers_)) { - return *absl::get(headers_or_trailers_); + HeaderMap& headers() override { + if (absl::holds_alternative(headers_or_trailers_)) { + return *absl::get(headers_or_trailers_); } else { - return *absl::get(headers_or_trailers_); + return *absl::get(headers_or_trailers_); } } void allocTrailers() override { - headers_or_trailers_.emplace( - std::make_unique()); + headers_or_trailers_.emplace(std::make_unique()); } // ResponseEncoder @@ -325,7 +324,7 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable headers_or_trailers_; + absl::variant headers_or_trailers_; }; using ServerStreamImplPtr = std::unique_ptr; diff --git a/source/common/http/utility.cc b/source/common/http/utility.cc index 6d160f98c1..0740dfc621 100644 --- a/source/common/http/utility.cc +++ b/source/common/http/utility.cc @@ -313,13 +313,13 @@ void Utility::sendLocalReply( ASSERT(!is_reset); // Respond with a gRPC trailers-only response if the request is gRPC if (is_grpc) { - HeaderMapPtr response_headers{new HeaderMapImpl{ - {Headers::get().Status, std::to_string(enumToInt(Code::OK))}, - {Headers::get().ContentType, Headers::get().ContentTypeValues.Grpc}, - {Headers::get().GrpcStatus, - std::to_string( - enumToInt(grpc_status ? grpc_status.value() - : Grpc::Utility::httpToGrpcStatus(enumToInt(response_code))))}}}; + HeaderMapPtr response_headers{HeaderMapImpl::create( + {{Headers::get().Status, std::to_string(enumToInt(Code::OK))}, + {Headers::get().ContentType, Headers::get().ContentTypeValues.Grpc}, + {Headers::get().GrpcStatus, + std::to_string(enumToInt( + grpc_status ? grpc_status.value() + : Grpc::Utility::httpToGrpcStatus(enumToInt(response_code))))}})}; if (!body_text.empty() && !is_head_request) { // TODO(dio): Probably it is worth to consider caching the encoded message based on gRPC // status. @@ -330,7 +330,7 @@ void Utility::sendLocalReply( } HeaderMapPtr response_headers{ - new HeaderMapImpl{{Headers::get().Status, std::to_string(enumToInt(response_code))}}}; + HeaderMapImpl::create({{Headers::get().Status, std::to_string(enumToInt(response_code))}})}; if (!body_text.empty()) { response_headers->setContentLength(body_text.size()); response_headers->setReferenceContentType(Headers::get().ContentTypeValues.Text); diff --git a/source/common/router/router.cc b/source/common/router/router.cc index dcbf7757ea..00144f32de 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -370,9 +370,9 @@ void Filter::chargeUpstreamCode(Http::Code code, Upstream::HostDescriptionConstSharedPtr upstream_host, bool dropped) { const uint64_t response_status_code = enumToInt(code); - Http::HeaderMapImpl fake_response_headers{ - {Http::Headers::get().Status, std::to_string(response_status_code)}}; - chargeUpstreamCode(response_status_code, fake_response_headers, upstream_host, dropped); + const auto fake_response_headers = Http::HeaderMapImpl::create( + {{Http::Headers::get().Status, std::to_string(response_status_code)}}); + chargeUpstreamCode(response_status_code, *fake_response_headers, upstream_host, dropped); } Http::FilterHeadersStatus Filter::decodeHeaders(Http::HeaderMap& headers, bool end_stream) { @@ -739,13 +739,13 @@ void Filter::maybeDoShadowing() { const auto& shadow_policy = shadow_policy_wrapper.get(); ASSERT(!shadow_policy.cluster().empty()); - Http::MessagePtr request(new Http::RequestMessageImpl( - Http::HeaderMapPtr{new Http::HeaderMapImpl(*downstream_headers_)})); + Http::MessagePtr request( + new Http::RequestMessageImpl(Http::HeaderMapImpl::create(*downstream_headers_))); if (callbacks_->decodingBuffer()) { request->body() = std::make_unique(*callbacks_->decodingBuffer()); } if (downstream_trailers_) { - request->trailers(Http::HeaderMapPtr{new Http::HeaderMapImpl(*downstream_trailers_)}); + request->trailers(Http::HeaderMapImpl::create(*downstream_trailers_)); } config_.shadowWriter().shadow(shadow_policy.cluster(), std::move(request), @@ -1510,7 +1510,7 @@ void Filter::UpstreamRequest::decodeHeaders(Http::ResponseHeaderMapPtr&& headers awaiting_headers_ = false; if (!parent_.config_.upstream_logs_.empty()) { - upstream_headers_ = std::make_unique(*headers); + upstream_headers_ = Http::HeaderMapImpl::create(*headers); } const uint64_t response_code = Http::Utility::getResponseStatus(*headers); stream_info_.response_code_ = static_cast(response_code); @@ -1530,7 +1530,7 @@ void Filter::UpstreamRequest::decodeTrailers(Http::ResponseTrailerMapPtr&& trail maybeEndDecode(true); if (!parent_.config_.upstream_logs_.empty()) { - upstream_trailers_ = std::make_unique(*trailers); + upstream_trailers_ = Http::HeaderMapImpl::create(*trailers); } parent_.onUpstreamTrailers(std::move(trailers), *this); } diff --git a/source/common/upstream/health_checker_impl.cc b/source/common/upstream/health_checker_impl.cc index a8417f341c..9bfd5536b1 100644 --- a/source/common/upstream/health_checker_impl.cc +++ b/source/common/upstream/health_checker_impl.cc @@ -231,19 +231,19 @@ void HttpHealthCheckerImpl::HttpActiveHealthCheckSession::onInterval() { Http::RequestEncoder* request_encoder = &client_->newStream(*this); request_encoder->getStream().addCallbacks(*this); - Http::HeaderMapImpl request_headers{ - {Http::Headers::get().Method, "GET"}, - {Http::Headers::get().Host, hostname_}, - {Http::Headers::get().Path, parent_.path_}, - {Http::Headers::get().UserAgent, Http::Headers::get().UserAgentValues.EnvoyHealthChecker}}; + const auto request_headers = Http::HeaderMapImpl::create( + {{Http::Headers::get().Method, "GET"}, + {Http::Headers::get().Host, hostname_}, + {Http::Headers::get().Path, parent_.path_}, + {Http::Headers::get().UserAgent, Http::Headers::get().UserAgentValues.EnvoyHealthChecker}}); Router::FilterUtility::setUpstreamScheme( - request_headers, host_->transportSocketFactory().implementsSecureTransport()); + *request_headers, host_->transportSocketFactory().implementsSecureTransport()); StreamInfo::StreamInfoImpl stream_info(protocol_, parent_.dispatcher_.timeSource()); stream_info.setDownstreamLocalAddress(local_address_); stream_info.setDownstreamRemoteAddress(local_address_); stream_info.onUpstreamHostSelected(host_); - parent_.request_headers_parser_->evaluateHeaders(request_headers, stream_info); - request_encoder->encodeHeaders(request_headers, true); + parent_.request_headers_parser_->evaluateHeaders(*request_headers, stream_info); + request_encoder->encodeHeaders(*request_headers, true); } void HttpHealthCheckerImpl::HttpActiveHealthCheckSession::onResetStream(Http::StreamResetReason, diff --git a/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc b/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc index dffed2bf5f..2d114ff099 100644 --- a/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc +++ b/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc @@ -22,8 +22,9 @@ namespace { // Static header map used for creating authorization requests. const Http::HeaderMap& lengthZeroHeader() { - CONSTRUCT_ON_FIRST_USE(Http::HeaderMapImpl, - {Http::Headers::get().ContentLength, std::to_string(0)}); + static const auto headers = + Http::HeaderMapImpl::create({{Http::Headers::get().ContentLength, std::to_string(0)}}); + return *headers; } // Static response used for creating authorization ERROR responses. @@ -190,12 +191,10 @@ void RawHttpClientImpl::check(RequestCallbacks& callbacks, Http::HeaderMapPtr headers; const uint64_t request_length = request.attributes().request().http().body().size(); if (request_length > 0) { - headers = - std::make_unique>>( - {{Http::Headers::get().ContentLength, std::to_string(request_length)}}); + headers = Http::HeaderMapImpl::create( + {{Http::Headers::get().ContentLength, std::to_string(request_length)}}); } else { - headers = std::make_unique(lengthZeroHeader()); + headers = Http::HeaderMapImpl::create(lengthZeroHeader()); } for (const auto& header : request.attributes().request().http().headers()) { diff --git a/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc b/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc index 8c0a1e205b..12c1bb807f 100644 --- a/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc +++ b/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc @@ -51,7 +51,7 @@ class SimpleInsertContext : public InsertContext { void insertHeaders(const Http::HeaderMap& response_headers, bool end_stream) override { ASSERT(!committed_); - response_headers_ = std::make_unique(response_headers); + response_headers_ = Http::HeaderMapImpl::create(response_headers); if (end_stream) { commit(); } @@ -107,8 +107,8 @@ SimpleHttpCache::Entry SimpleHttpCache::lookup(const LookupRequest& request) { return Entry{}; } ASSERT(iter->second.response_headers_); - return SimpleHttpCache::Entry{ - std::make_unique(*iter->second.response_headers_), iter->second.body_}; + return SimpleHttpCache::Entry{Http::HeaderMapImpl::create(*iter->second.response_headers_), + iter->second.body_}; } void SimpleHttpCache::insert(const Key& key, Http::HeaderMapPtr&& response_headers, diff --git a/source/extensions/filters/http/cors/cors_filter.cc b/source/extensions/filters/http/cors/cors_filter.cc index 791384e116..a6702c1e56 100644 --- a/source/extensions/filters/http/cors/cors_filter.cc +++ b/source/extensions/filters/http/cors/cors_filter.cc @@ -64,8 +64,8 @@ Http::FilterHeadersStatus CorsFilter::decodeHeaders(Http::HeaderMap& headers, bo return Http::FilterHeadersStatus::Continue; } - Http::HeaderMapPtr response_headers{new Http::HeaderMapImpl{ - {Http::Headers::get().Status, std::to_string(enumToInt(Http::Code::OK))}}}; + Http::HeaderMapPtr response_headers{Http::HeaderMapImpl::create( + {{Http::Headers::get().Status, std::to_string(enumToInt(Http::Code::OK))}})}; response_headers->setAccessControlAllowOrigin(origin_->value().getStringView()); diff --git a/source/extensions/filters/http/lua/lua_filter.cc b/source/extensions/filters/http/lua/lua_filter.cc index 156cb25281..f12958d42e 100644 --- a/source/extensions/filters/http/lua/lua_filter.cc +++ b/source/extensions/filters/http/lua/lua_filter.cc @@ -265,8 +265,8 @@ void StreamHandleWrapper::onFailure(Http::AsyncClient::FailureReason) { // Just fake a basic 503 response. Http::MessagePtr response_message(new Http::ResponseMessageImpl(Http::HeaderMapPtr{ - new Http::HeaderMapImpl{{Http::Headers::get().Status, - std::to_string(enumToInt(Http::Code::ServiceUnavailable))}}})); + Http::HeaderMapImpl::create({{Http::Headers::get().Status, + std::to_string(enumToInt(Http::Code::ServiceUnavailable))}})})); response_message->body() = std::make_unique("upstream failure"); onSuccess(std::move(response_message)); } diff --git a/test/common/grpc/grpc_client_integration_test_harness.h b/test/common/grpc/grpc_client_integration_test_harness.h index 791cb3f57f..837538af95 100644 --- a/test/common/grpc/grpc_client_integration_test_harness.h +++ b/test/common/grpc/grpc_client_integration_test_harness.h @@ -139,7 +139,7 @@ class HelloworldStream : public MockAsyncStreamCallbacks reply_headers->addReference(value.first, value.second); } expectInitialMetadata(metadata); - fake_stream_->encodeHeaders(Http::HeaderMapImpl(*reply_headers), false); + fake_stream_->encodeHeaders(Http::TestHeaderMapImpl(*reply_headers), false); } void sendReply() { diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc index fb227e775c..b8d2cd8995 100644 --- a/test/common/http/conn_manager_impl_test.cc +++ b/test/common/http/conn_manager_impl_test.cc @@ -5104,7 +5104,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsCrossScopeReroute) { // 3. then refreshCachedRoute triggered by decoder_filters_[1]->callbacks_->route(). .Times(3) .WillRepeatedly(Invoke([&](const HeaderMap& headers) -> Router::ConfigConstSharedPtr { - auto& test_headers = dynamic_cast(headers); + auto& test_headers = dynamic_cast(headers); if (test_headers.get_("scope_key") == "foo") { return route_config1; } @@ -5121,7 +5121,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsCrossScopeReroute) { EXPECT_CALL(*decoder_filters_[0], decodeHeaders(_, false)) .WillOnce(Invoke([&](Http::HeaderMap& headers, bool) -> FilterHeadersStatus { EXPECT_EQ(route1, decoder_filters_[0]->callbacks_->route()); - auto& test_headers = dynamic_cast(headers); + auto& test_headers = dynamic_cast(headers); // Clear cached route and change scope key to "bar". decoder_filters_[0]->callbacks_->clearRouteCache(); test_headers.remove("scope_key"); @@ -5130,7 +5130,7 @@ TEST_F(HttpConnectionManagerImplTest, TestSrdsCrossScopeReroute) { })); EXPECT_CALL(*decoder_filters_[1], decodeHeaders(_, false)) .WillOnce(Invoke([&](Http::HeaderMap& headers, bool) -> FilterHeadersStatus { - auto& test_headers = dynamic_cast(headers); + auto& test_headers = dynamic_cast(headers); EXPECT_EQ(test_headers.get_("scope_key"), "bar"); // Route now switched to route2 as header "scope_key" has changed. EXPECT_EQ(route2, decoder_filters_[1]->callbacks_->route()); diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index 2459bd0bbc..0a0dcf569f 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -1257,10 +1257,10 @@ TEST_F(ConnectionManagerUtilityTest, RemovesProxyResponseHeaders) { // maybeNormalizePath() does nothing by default. TEST_F(ConnectionManagerUtilityTest, SanitizePathDefaultOff) { ON_CALL(config_, shouldNormalizePath()).WillByDefault(Return(false)); - HeaderMapImpl original_headers; + TestHeaderMapImpl original_headers; original_headers.setPath("/xyz/../a"); - HeaderMapImpl header_map(static_cast(original_headers)); + TestHeaderMapImpl header_map(static_cast(original_headers)); ConnectionManagerUtility::maybeNormalizePath(header_map, config_); EXPECT_EQ(original_headers, header_map); } @@ -1268,10 +1268,10 @@ TEST_F(ConnectionManagerUtilityTest, SanitizePathDefaultOff) { // maybeNormalizePath() leaves already normal paths alone. TEST_F(ConnectionManagerUtilityTest, SanitizePathNormalPath) { ON_CALL(config_, shouldNormalizePath()).WillByDefault(Return(true)); - HeaderMapImpl original_headers; + TestHeaderMapImpl original_headers; original_headers.setPath("/xyz"); - HeaderMapImpl header_map(static_cast(original_headers)); + TestHeaderMapImpl header_map(static_cast(original_headers)); ConnectionManagerUtility::maybeNormalizePath(header_map, config_); EXPECT_EQ(original_headers, header_map); } @@ -1279,10 +1279,10 @@ TEST_F(ConnectionManagerUtilityTest, SanitizePathNormalPath) { // maybeNormalizePath() normalizes relative paths. TEST_F(ConnectionManagerUtilityTest, SanitizePathRelativePAth) { ON_CALL(config_, shouldNormalizePath()).WillByDefault(Return(true)); - HeaderMapImpl original_headers; + TestHeaderMapImpl original_headers; original_headers.setPath("/xyz/../abc"); - HeaderMapImpl header_map(static_cast(original_headers)); + TestHeaderMapImpl header_map(static_cast(original_headers)); ConnectionManagerUtility::maybeNormalizePath(header_map, config_); EXPECT_EQ(header_map.Path()->value().getStringView(), "/abc"); } @@ -1291,10 +1291,10 @@ TEST_F(ConnectionManagerUtilityTest, SanitizePathRelativePAth) { TEST_F(ConnectionManagerUtilityTest, MergeSlashesDefaultOff) { ON_CALL(config_, shouldNormalizePath()).WillByDefault(Return(true)); ON_CALL(config_, shouldMergeSlashes()).WillByDefault(Return(false)); - HeaderMapImpl original_headers; + TestHeaderMapImpl original_headers; original_headers.setPath("/xyz///abc"); - HeaderMapImpl header_map(static_cast(original_headers)); + TestHeaderMapImpl header_map(static_cast(original_headers)); ConnectionManagerUtility::maybeNormalizePath(header_map, config_); EXPECT_EQ(header_map.Path()->value().getStringView(), "/xyz///abc"); } @@ -1303,10 +1303,10 @@ TEST_F(ConnectionManagerUtilityTest, MergeSlashesDefaultOff) { TEST_F(ConnectionManagerUtilityTest, MergeSlashes) { ON_CALL(config_, shouldNormalizePath()).WillByDefault(Return(true)); ON_CALL(config_, shouldMergeSlashes()).WillByDefault(Return(true)); - HeaderMapImpl original_headers; + TestHeaderMapImpl original_headers; original_headers.setPath("/xyz///abc"); - HeaderMapImpl header_map(static_cast(original_headers)); + TestHeaderMapImpl header_map(static_cast(original_headers)); ConnectionManagerUtility::maybeNormalizePath(header_map, config_); EXPECT_EQ(header_map.Path()->value().getStringView(), "/xyz/abc"); } @@ -1315,10 +1315,10 @@ TEST_F(ConnectionManagerUtilityTest, MergeSlashes) { TEST_F(ConnectionManagerUtilityTest, MergeSlashesWithoutNormalization) { ON_CALL(config_, shouldNormalizePath()).WillByDefault(Return(false)); ON_CALL(config_, shouldMergeSlashes()).WillByDefault(Return(true)); - HeaderMapImpl original_headers; + TestHeaderMapImpl original_headers; original_headers.setPath("/xyz/..//abc"); - HeaderMapImpl header_map(static_cast(original_headers)); + TestHeaderMapImpl header_map(static_cast(original_headers)); ConnectionManagerUtility::maybeNormalizePath(header_map, config_); EXPECT_EQ(header_map.Path()->value().getStringView(), "/xyz/../abc"); } diff --git a/test/common/http/header_map_impl_fuzz_test.cc b/test/common/http/header_map_impl_fuzz_test.cc index 4bf7473a0e..5b776f080b 100644 --- a/test/common/http/header_map_impl_fuzz_test.cc +++ b/test/common/http/header_map_impl_fuzz_test.cc @@ -136,8 +136,7 @@ DEFINE_PROTO_FUZZER(const test::common::http::HeaderMapImplFuzzTestCase& input) break; } case test::common::http::Action::kCopy: { - header_map = - std::make_unique(*static_cast(header_map.get())); + header_map = Http::HeaderMapImpl::create(*static_cast(header_map.get())); break; } case test::common::http::Action::kLookup: { diff --git a/test/common/http/header_map_impl_test.cc b/test/common/http/header_map_impl_test.cc index 74f2d225e3..68ec766eea 100644 --- a/test/common/http/header_map_impl_test.cc +++ b/test/common/http/header_map_impl_test.cc @@ -16,12 +16,14 @@ namespace Http { class VerifiedHeaderMapImpl : public HeaderMapImpl { public: - VerifiedHeaderMapImpl() = default; - explicit VerifiedHeaderMapImpl( - const std::initializer_list>& values) - : HeaderMapImpl(values) {} + static HeaderMapImplPtr + create(const std::initializer_list>& values) { + auto new_header_map = std::make_unique(); + new_header_map->initFromInitList(*new_header_map, values); + return new_header_map; + } - void verifyByteSize() override { ASSERT(cached_byte_size_ == byteSizeInternal()); } + void verifyByteSize() override { verifyByteSizeInternalForTest(); } }; TEST(HeaderStringTest, All) { @@ -883,22 +885,23 @@ TEST(HeaderMapImplTest, Lookup) { TEST(HeaderMapImplTest, Get) { { - const VerifiedHeaderMapImpl headers{{Headers::get().Path, "/"}, - {LowerCaseString("hello"), "world"}}; - EXPECT_EQ("/", headers.get(LowerCaseString(":path"))->value().getStringView()); - EXPECT_EQ("world", headers.get(LowerCaseString("hello"))->value().getStringView()); - EXPECT_EQ(nullptr, headers.get(LowerCaseString("foo"))); + auto headers = VerifiedHeaderMapImpl::create( + {{Headers::get().Path, "/"}, {LowerCaseString("hello"), "world"}}); + EXPECT_EQ("/", headers->get(LowerCaseString(":path"))->value().getStringView()); + EXPECT_EQ("world", headers->get(LowerCaseString("hello"))->value().getStringView()); + EXPECT_EQ(nullptr, headers->get(LowerCaseString("foo"))); } { - VerifiedHeaderMapImpl headers{{Headers::get().Path, "/"}, {LowerCaseString("hello"), "world"}}; + auto headers = VerifiedHeaderMapImpl::create( + {{Headers::get().Path, "/"}, {LowerCaseString("hello"), "world"}}); // There is not HeaderMap method to set a header and copy both the key and value. - headers.setReferenceKey(LowerCaseString(":path"), "/new_path"); - EXPECT_EQ("/new_path", headers.get(LowerCaseString(":path"))->value().getStringView()); + headers->setReferenceKey(LowerCaseString(":path"), "/new_path"); + EXPECT_EQ("/new_path", headers->get(LowerCaseString(":path"))->value().getStringView()); LowerCaseString foo("hello"); - headers.setReferenceKey(foo, "world2"); - EXPECT_EQ("world2", headers.get(foo)->value().getStringView()); - EXPECT_EQ(nullptr, headers.get(LowerCaseString("foo"))); + headers->setReferenceKey(foo, "world2"); + EXPECT_EQ("world2", headers->get(foo)->value().getStringView()); + EXPECT_EQ(nullptr, headers->get(LowerCaseString("foo"))); } } @@ -1126,11 +1129,11 @@ TEST(HeaderMapImplTest, PseudoHeaderOrder) { // Starting with a normal header { - Http::VerifiedHeaderMapImpl headers{{Headers::get().ContentType, "text/plain"}, - {Headers::get().Method, "GET"}, - {Headers::get().Path, "/"}, - {LowerCaseString("hello"), "world"}, - {Headers::get().Host, "host"}}; + auto headers = VerifiedHeaderMapImpl::create({{Headers::get().ContentType, "text/plain"}, + {Headers::get().Method, "GET"}, + {Headers::get().Path, "/"}, + {LowerCaseString("hello"), "world"}, + {Headers::get().Host, "host"}}); InSequence seq; EXPECT_CALL(cb, Call(":method", "GET")); @@ -1139,7 +1142,7 @@ TEST(HeaderMapImplTest, PseudoHeaderOrder) { EXPECT_CALL(cb, Call("content-type", "text/plain")); EXPECT_CALL(cb, Call("hello", "world")); - headers.iterate( + headers->iterate( [](const Http::HeaderEntry& header, void* cb_v) -> HeaderMap::Iterate { static_cast(cb_v)->Call(std::string(header.key().getStringView()), std::string(header.value().getStringView())); @@ -1150,11 +1153,11 @@ TEST(HeaderMapImplTest, PseudoHeaderOrder) { // Starting with a pseudo-header { - Http::VerifiedHeaderMapImpl headers{{Headers::get().Path, "/"}, - {Headers::get().ContentType, "text/plain"}, - {Headers::get().Method, "GET"}, - {LowerCaseString("hello"), "world"}, - {Headers::get().Host, "host"}}; + auto headers = VerifiedHeaderMapImpl::create({{Headers::get().Path, "/"}, + {Headers::get().ContentType, "text/plain"}, + {Headers::get().Method, "GET"}, + {LowerCaseString("hello"), "world"}, + {Headers::get().Host, "host"}}); InSequence seq; EXPECT_CALL(cb, Call(":path", "/")); @@ -1163,7 +1166,7 @@ TEST(HeaderMapImplTest, PseudoHeaderOrder) { EXPECT_CALL(cb, Call("content-type", "text/plain")); EXPECT_CALL(cb, Call("hello", "world")); - headers.iterate( + headers->iterate( [](const Http::HeaderEntry& header, void* cb_v) -> HeaderMap::Iterate { static_cast(cb_v)->Call(std::string(header.key().getStringView()), std::string(header.value().getStringView())); @@ -1189,6 +1192,25 @@ TEST(HeaderMapImplTest, TestHeaderMapImplyCopy) { EXPECT_EQ("bar", baz.get(LowerCaseString("foo"))->value().getStringView()); } +// Make sure 'host' -> ':authority' auto translation only occurs for request headers. +TEST(HeaderMapImplTest, HostHeader) { + TestRequestHeaderMapImpl request_headers{{"host", "foo"}}; + EXPECT_EQ(request_headers.size(), 1); + EXPECT_EQ(request_headers.get_(":authority"), "foo"); + + TestRequestTrailerMapImpl request_trailers{{"host", "foo"}}; + EXPECT_EQ(request_trailers.size(), 1); + EXPECT_EQ(request_trailers.get_("host"), "foo"); + + TestResponseHeaderMapImpl response_headers{{"host", "foo"}}; + EXPECT_EQ(response_headers.size(), 1); + EXPECT_EQ(response_headers.get_("host"), "foo"); + + TestResponseTrailerMapImpl response_trailers{{"host", "foo"}}; + EXPECT_EQ(response_trailers.size(), 1); + EXPECT_EQ(response_trailers.get_("host"), "foo"); +} + TEST(HeaderMapImplTest, TestInlineHeaderAdd) { VerifiedHeaderMapImpl foo; foo.addCopy(LowerCaseString(":path"), "GET"); diff --git a/test/extensions/filters/http/csrf/csrf_filter_test.cc b/test/extensions/filters/http/csrf/csrf_filter_test.cc index 27f0530051..ab90793909 100644 --- a/test/extensions/filters/http/csrf/csrf_filter_test.cc +++ b/test/extensions/filters/http/csrf/csrf_filter_test.cc @@ -92,11 +92,11 @@ class CsrfFilterTest : public testing::Test { CsrfFilterConfigSharedPtr config_; CsrfFilter filter_; - Http::TestHeaderMapImpl request_headers_; + Http::TestRequestHeaderMapImpl request_headers_; }; TEST_F(CsrfFilterTest, RequestWithNonMutableMethod) { - Http::TestHeaderMapImpl request_headers{{":method", "GET"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); @@ -110,7 +110,7 @@ TEST_F(CsrfFilterTest, RequestWithNonMutableMethod) { } TEST_F(CsrfFilterTest, RequestWithoutOrigin) { - Http::TestHeaderMapImpl request_headers{{":method", "PUT"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "PUT"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(request_headers, false)); @@ -123,7 +123,7 @@ TEST_F(CsrfFilterTest, RequestWithoutOrigin) { } TEST_F(CsrfFilterTest, RequestWithoutDestination) { - Http::TestHeaderMapImpl request_headers{{":method", "PUT"}, {"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "PUT"}, {"origin", "localhost"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(request_headers, false)); @@ -136,7 +136,7 @@ TEST_F(CsrfFilterTest, RequestWithoutDestination) { } TEST_F(CsrfFilterTest, RequestWithInvalidOrigin) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "PUT"}, {"origin", "cross-origin"}, {":authority", "localhost"}}; Http::TestHeaderMapImpl response_headers{ @@ -158,7 +158,7 @@ TEST_F(CsrfFilterTest, RequestWithInvalidOrigin) { } TEST_F(CsrfFilterTest, RequestWithValidOrigin) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "PUT"}, {"origin", "localhost"}, {"host", "localhost"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); @@ -171,7 +171,7 @@ TEST_F(CsrfFilterTest, RequestWithValidOrigin) { } TEST_F(CsrfFilterTest, RequestWithInvalidOriginCsrfDisabledShadowDisabled) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "PUT"}, {"origin", "cross-origin"}, {"host", "localhost"}}; setFilterEnabled(false); @@ -187,7 +187,7 @@ TEST_F(CsrfFilterTest, RequestWithInvalidOriginCsrfDisabledShadowDisabled) { } TEST_F(CsrfFilterTest, RequestWithInvalidOriginCsrfDisabledShadowEnabled) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "PUT"}, {"origin", "cross-origin"}, {"host", "localhost"}}; setFilterEnabled(false); @@ -203,7 +203,7 @@ TEST_F(CsrfFilterTest, RequestWithInvalidOriginCsrfDisabledShadowEnabled) { } TEST_F(CsrfFilterTest, RequestWithValidOriginCsrfDisabledShadowEnabled) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "PUT"}, {"origin", "localhost"}, {"host", "localhost"}}; setFilterEnabled(false); @@ -219,7 +219,7 @@ TEST_F(CsrfFilterTest, RequestWithValidOriginCsrfDisabledShadowEnabled) { } TEST_F(CsrfFilterTest, RequestWithInvalidOriginCsrfEnabledShadowEnabled) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "PUT"}, {"origin", "cross-origin"}, {"host", "localhost"}}; setShadowEnabled(true); @@ -242,7 +242,7 @@ TEST_F(CsrfFilterTest, RequestWithInvalidOriginCsrfEnabledShadowEnabled) { } TEST_F(CsrfFilterTest, RequestWithValidOriginCsrfEnabledShadowEnabled) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "PUT"}, {"origin", "localhost"}, {"host", "localhost"}}; setShadowEnabled(true); @@ -294,7 +294,7 @@ TEST_F(CsrfFilterTest, EmptyRouteEntry) { } TEST_F(CsrfFilterTest, NoCsrfEntry) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "PUT"}, {"origin", "cross-origin"}, {"host", "localhost"}}; setRoutePolicy(nullptr); @@ -310,7 +310,7 @@ TEST_F(CsrfFilterTest, NoCsrfEntry) { } TEST_F(CsrfFilterTest, NoRouteCsrfEntry) { - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, {"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, {"origin", "localhost"}}; setRoutePolicy(nullptr); @@ -325,7 +325,7 @@ TEST_F(CsrfFilterTest, NoRouteCsrfEntry) { } TEST_F(CsrfFilterTest, NoVHostCsrfEntry) { - Http::TestHeaderMapImpl request_headers{{":method", "DELETE"}, {"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "DELETE"}, {"origin", "localhost"}}; setVirtualHostPolicy(nullptr); @@ -340,7 +340,7 @@ TEST_F(CsrfFilterTest, NoVHostCsrfEntry) { } TEST_F(CsrfFilterTest, RequestFromAdditionalExactOrigin) { - Http::TestHeaderMapImpl request_headers{{":method", "PUT"}, {"origin", "additionalhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "PUT"}, {"origin", "additionalhost"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); @@ -352,7 +352,7 @@ TEST_F(CsrfFilterTest, RequestFromAdditionalExactOrigin) { } TEST_F(CsrfFilterTest, RequestFromAdditionalRegexOrigin) { - Http::TestHeaderMapImpl request_headers{{":method", "PUT"}, {"origin", "www-1.allow.com"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "PUT"}, {"origin", "www-1.allow.com"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); @@ -364,7 +364,7 @@ TEST_F(CsrfFilterTest, RequestFromAdditionalRegexOrigin) { } TEST_F(CsrfFilterTest, RequestFromInvalidAdditionalRegexOrigin) { - Http::TestHeaderMapImpl request_headers{{":method", "PUT"}, {"origin", "www.allow.com"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "PUT"}, {"origin", "www.allow.com"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(request_headers, false)); diff --git a/test/integration/fake_upstream.cc b/test/integration/fake_upstream.cc index 7ac5f3831e..04eef68741 100644 --- a/test/integration/fake_upstream.cc +++ b/test/integration/fake_upstream.cc @@ -73,16 +73,14 @@ void FakeStream::decodeMetadata(Http::MetadataMapPtr&& metadata_map_ptr) { } } -void FakeStream::encode100ContinueHeaders(const Http::HeaderMapImpl& headers) { - std::shared_ptr headers_copy( - new Http::HeaderMapImpl(static_cast(headers))); +void FakeStream::encode100ContinueHeaders(const Http::HeaderMap& headers) { + std::shared_ptr headers_copy(Http::HeaderMapImpl::create(headers)); parent_.connection().dispatcher().post( [this, headers_copy]() -> void { encoder_.encode100ContinueHeaders(*headers_copy); }); } -void FakeStream::encodeHeaders(const Http::HeaderMapImpl& headers, bool end_stream) { - std::shared_ptr headers_copy( - new Http::HeaderMapImpl(static_cast(headers))); +void FakeStream::encodeHeaders(const Http::HeaderMap& headers, bool end_stream) { + std::shared_ptr headers_copy(Http::HeaderMapImpl::create(headers)); if (add_served_by_header_) { headers_copy->addCopy(Http::LowerCaseString("x-served-by"), parent_.connection().localAddress()->asString()); @@ -112,9 +110,8 @@ void FakeStream::encodeData(Buffer::Instance& data, bool end_stream) { [this, data_copy, end_stream]() -> void { encoder_.encodeData(*data_copy, end_stream); }); } -void FakeStream::encodeTrailers(const Http::HeaderMapImpl& trailers) { - std::shared_ptr trailers_copy( - new Http::HeaderMapImpl(static_cast(trailers))); +void FakeStream::encodeTrailers(const Http::HeaderMap& trailers) { + std::shared_ptr trailers_copy(Http::HeaderMapImpl::create(trailers)); parent_.connection().dispatcher().post( [this, trailers_copy]() -> void { encoder_.encodeTrailers(*trailers_copy); }); } diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index b18c29de36..a28c3945bf 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -56,12 +56,12 @@ class FakeStream : public Http::RequestDecoder, Thread::LockGuard lock(lock_); return end_stream_; } - void encode100ContinueHeaders(const Http::HeaderMapImpl& headers); - void encodeHeaders(const Http::HeaderMapImpl& headers, bool end_stream); + void encode100ContinueHeaders(const Http::HeaderMap& headers); + void encodeHeaders(const Http::HeaderMap& headers, bool end_stream); void encodeData(uint64_t size, bool end_stream); void encodeData(Buffer::Instance& data, bool end_stream); void encodeData(absl::string_view data, bool end_stream); - void encodeTrailers(const Http::HeaderMapImpl& trailers); + void encodeTrailers(const Http::HeaderMap& trailers); void encodeResetStream(); void encodeMetadata(const Http::MetadataMapVector& metadata_map_vector); const Http::HeaderMap& headers() { return *headers_; } diff --git a/test/integration/http_integration.cc b/test/integration/http_integration.cc index 0ed4568767..928f6cd1c4 100644 --- a/test/integration/http_integration.cc +++ b/test/integration/http_integration.cc @@ -1017,10 +1017,8 @@ void HttpIntegrationTest::testManyRequestHeaders(std::chrono::milliseconds time) max_request_headers_count_); }); - Http::HeaderMapImpl big_headers{{Http::Headers::get().Method, "GET"}, - {Http::Headers::get().Path, "/test/long/url"}, - {Http::Headers::get().Scheme, "http"}, - {Http::Headers::get().Host, "host"}}; + Http::TestHeaderMapImpl big_headers{ + {":method", "GET"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}}; for (int i = 0; i < 20000; i++) { big_headers.addCopy(Http::LowerCaseString(std::to_string(i)), std::string(0, 'a')); diff --git a/test/integration/protocol_integration_test.cc b/test/integration/protocol_integration_test.cc index 45b3055c23..6ac15e24d4 100644 --- a/test/integration/protocol_integration_test.cc +++ b/test/integration/protocol_integration_test.cc @@ -240,6 +240,25 @@ TEST_P(ProtocolIntegrationTest, DrainClose) { test_server_->drainManager().draining_ = false; } +// Regression test for https://github.com/envoyproxy/envoy/issues/9873 +TEST_P(ProtocolIntegrationTest, ResponseWithHostHeader) { + initialize(); + codec_client_ = makeHttpConnection(lookupPort("http")); + auto response = + codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); + waitForNextUpstreamRequest(); + upstream_request_->encodeHeaders( + Http::TestResponseHeaderMapImpl{{":status", "200"}, {"host", "host"}}, true); + response->waitForEndStream(); + EXPECT_TRUE(response->complete()); + EXPECT_EQ("200", response->headers().Status()->value().getStringView()); + EXPECT_EQ("host", + response->headers().get(Http::LowerCaseString("host"))->value().getStringView()); +} + TEST_P(ProtocolIntegrationTest, Retry) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); diff --git a/test/integration/ratelimit_integration_test.cc b/test/integration/ratelimit_integration_test.cc index e830dce3af..8d6fa322cd 100644 --- a/test/integration/ratelimit_integration_test.cc +++ b/test/integration/ratelimit_integration_test.cc @@ -128,8 +128,8 @@ class RatelimitIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, } void sendRateLimitResponse(envoy::service::ratelimit::v3::RateLimitResponse::Code code, - const Http::HeaderMapImpl& response_headers_to_add, - const Http::HeaderMapImpl& request_headers_to_add) { + const Http::HeaderMap& response_headers_to_add, + const Http::HeaderMap& request_headers_to_add) { ratelimit_request_->startGrpcStream(); envoy::service::ratelimit::v3::RateLimitResponse response_msg; response_msg.set_overall_code(code); diff --git a/test/mocks/http/mocks.h b/test/mocks/http/mocks.h index b912df6c0f..4b7c72b18d 100644 --- a/test/mocks/http/mocks.h +++ b/test/mocks/http/mocks.h @@ -521,7 +521,7 @@ class IsSubsetOfHeadersMatcherImpl : public testing::MatcherInterface(arg.get()); - bool equal = (lhs == *rhs); + const bool equal = (*arg == *rhs); if (!equal) { *result_listener << "\n" << TestUtility::addLeftAndRightPadding("header map:") << "\n" << *rhs << TestUtility::addLeftAndRightPadding("is not equal to:") << "\n" - << lhs << TestUtility::addLeftAndRightPadding("") // line full of padding + << *arg << TestUtility::addLeftAndRightPadding("") // line full of padding << "\n"; } return equal; } -MATCHER_P(HeaderMapEqualRef, rhs, "") { - const Http::HeaderMapImpl& lhs = *dynamic_cast(&arg); - return lhs == *dynamic_cast(rhs); -} +MATCHER_P(HeaderMapEqualRef, rhs, "") { return arg == *rhs; } // Test that a HeaderMapPtr argument includes a given key-value pair, e.g., // HeaderHasValue("Upgrade", "WebSocket") diff --git a/test/mocks/http/stream_decoder.cc b/test/mocks/http/stream_decoder.cc index 550d7e4715..77b922c845 100644 --- a/test/mocks/http/stream_decoder.cc +++ b/test/mocks/http/stream_decoder.cc @@ -23,6 +23,10 @@ MockRequestDecoder::MockRequestDecoder() { MockRequestDecoder::~MockRequestDecoder() = default; MockResponseDecoder::MockResponseDecoder() { + ON_CALL(*this, decode100ContinueHeaders_(_)) + .WillByDefault( + Invoke([](ResponseHeaderMapPtr& headers) { auto moved_headers = std::move(headers); })); + ON_CALL(*this, decodeHeaders_(_, _)) .WillByDefault(Invoke([](ResponseHeaderMapPtr& headers, bool) { // Check for passing request headers as response headers in a test. diff --git a/test/test_common/utility.cc b/test/test_common/utility.cc index 32f15f74fd..3b31c4e6e5 100644 --- a/test/test_common/utility.cc +++ b/test/test_common/utility.cc @@ -21,7 +21,6 @@ #include "envoy/service/runtime/v3/rtds.pb.h" #include "common/api/api_impl.h" -#include "common/common/empty_string.h" #include "common/common/fmt.h" #include "common/common/lock_guard.h" #include "common/common/thread_impl.h" @@ -346,56 +345,6 @@ const uint32_t Http2Settings::DEFAULT_MAX_CONSECUTIVE_INBOUND_FRAMES_WITH_EMPTY_ const uint32_t Http2Settings::DEFAULT_MAX_INBOUND_PRIORITY_FRAMES_PER_STREAM; const uint32_t Http2Settings::DEFAULT_MAX_INBOUND_WINDOW_UPDATE_FRAMES_PER_DATA_FRAME_SENT; -TestHeaderMapImpl::TestHeaderMapImpl() = default; - -TestHeaderMapImpl::TestHeaderMapImpl( - const std::initializer_list>& values) { - for (auto& value : values) { - addCopy(value.first, value.second); - } -} - -TestHeaderMapImpl::TestHeaderMapImpl(const HeaderMap& rhs) : HeaderMapImpl(rhs) {} - -TestHeaderMapImpl::TestHeaderMapImpl(const TestHeaderMapImpl& rhs) - : TestHeaderMapImpl(static_cast(rhs)) {} - -TestHeaderMapImpl& TestHeaderMapImpl::operator=(const TestHeaderMapImpl& rhs) { - if (&rhs == this) { - return *this; - } - - clear(); - copyFrom(rhs); - - return *this; -} - -void TestHeaderMapImpl::addCopy(const std::string& key, const std::string& value) { - addCopy(LowerCaseString(key), value); -} - -void TestHeaderMapImpl::remove(const std::string& key) { remove(LowerCaseString(key)); } - -std::string TestHeaderMapImpl::get_(const std::string& key) const { - return get_(LowerCaseString(key)); -} - -std::string TestHeaderMapImpl::get_(const LowerCaseString& key) const { - const HeaderEntry* header = get(key); - if (!header) { - return EMPTY_STRING; - } else { - return std::string(header->value().getStringView()); - } -} - -bool TestHeaderMapImpl::has(const std::string& key) const { - return get(LowerCaseString(key)) != nullptr; -} - -bool TestHeaderMapImpl::has(const LowerCaseString& key) const { return get(key) != nullptr; } - } // namespace Http namespace Api { diff --git a/test/test_common/utility.h b/test/test_common/utility.h index 159bf53736..cdf10f8c4b 100644 --- a/test/test_common/utility.h +++ b/test/test_common/utility.h @@ -17,6 +17,7 @@ #include "common/buffer/buffer_impl.h" #include "common/common/c_smart_ptr.h" +#include "common/common/empty_string.h" #include "common/common/thread.h" #include "common/config/version_converter.h" #include "common/http/header_map_impl.h" @@ -620,75 +621,133 @@ class ConditionalInitializer { namespace Http { /** - * A test version of HeaderMapImpl that adds some niceties around letting us use - * std::string instead of always doing LowerCaseString() by hand. + * All of the inline header functions that just pass through to the child header map. */ -class TestHeaderMapImpl : public HeaderMapImpl { +#define DEFINE_TEST_INLINE_HEADER_FUNCS(name) \ +public: \ + const HeaderEntry* name() const override { return header_map_.name(); } \ + void append##name(absl::string_view data, absl::string_view delimiter) override { \ + header_map_.append##name(data, delimiter); \ + } \ + void setReference##name(absl::string_view value) override { \ + header_map_.setReference##name(value); \ + } \ + void set##name(absl::string_view value) override { header_map_.set##name(value); } \ + void set##name(uint64_t value) override { header_map_.set##name(value); } \ + void remove##name() override { header_map_.remove##name(); } + +/** + * Base class for all test header map types. This class wraps an underlying real header map + * implementation, passes through all calls, and adds some niceties for testing that we don't + * want in the production implementation for performance reasons. The wrapping functionality is + * primarily here to deal with complexities around virtual calls in some constructor paths in + * HeaderMapImpl. + */ +template class TestHeaderMapImplBase : public Interface { public: - TestHeaderMapImpl(); - TestHeaderMapImpl(const std::initializer_list>& values); - TestHeaderMapImpl(const HeaderMap& rhs); - - // The above constructor for TestHeaderMap is not an actual copy constructor. - TestHeaderMapImpl(const TestHeaderMapImpl& rhs); - TestHeaderMapImpl& operator=(const TestHeaderMapImpl& rhs); - - bool operator==(const TestHeaderMapImpl& rhs) const { return HeaderMapImpl::operator==(rhs); } - - friend std::ostream& operator<<(std::ostream& os, const TestHeaderMapImpl& p) { - p.iterate( - [](const HeaderEntry& header, void* context) -> HeaderMap::Iterate { - std::ostream* local_os = static_cast(context); - *local_os << header.key().getStringView() << " " << header.value().getStringView() - << std::endl; - return HeaderMap::Iterate::Continue; - }, - &os); - return os; - } - - using HeaderMapImpl::addCopy; - using HeaderMapImpl::remove; - void addCopy(const std::string& key, const std::string& value); - void remove(const std::string& key); - std::string get_(const std::string& key) const; - std::string get_(const LowerCaseString& key) const; - bool has(const std::string& key) const; - bool has(const LowerCaseString& key) const; - - void verifyByteSize() override { ASSERT(cached_byte_size_ == byteSizeInternal()); } + TestHeaderMapImplBase() = default; + TestHeaderMapImplBase(const std::initializer_list>& values) { + for (auto& value : values) { + addCopy(value.first, value.second); + } + } + TestHeaderMapImplBase(const TestHeaderMapImplBase& rhs) + : TestHeaderMapImplBase(rhs.header_map_) {} + TestHeaderMapImplBase(const HeaderMap& rhs) { HeaderMapImpl::copyFrom(header_map_, rhs); } + TestHeaderMapImplBase& operator=(const TestHeaderMapImplBase& rhs) { + if (this == &rhs) { + return *this; + } + clear(); + HeaderMapImpl::copyFrom(header_map_, rhs); + return *this; + } + + // Value added methods on top of HeaderMap. + void addCopy(const std::string& key, const std::string& value) { + addCopy(LowerCaseString(key), value); + } + std::string get_(const std::string& key) const { return get_(LowerCaseString(key)); } + std::string get_(const LowerCaseString& key) const { + const HeaderEntry* header = get(key); + if (!header) { + return EMPTY_STRING; + } else { + return std::string(header->value().getStringView()); + } + } + bool has(const std::string& key) const { return get(LowerCaseString(key)) != nullptr; } + bool has(const LowerCaseString& key) const { return get(key) != nullptr; } + void remove(const std::string& key) { remove(LowerCaseString(key)); } + + // HeaderMap + bool operator==(const HeaderMap& rhs) const override { return header_map_.operator==(rhs); } + bool operator!=(const HeaderMap& rhs) const override { return header_map_.operator!=(rhs); } + void addViaMove(HeaderString&& key, HeaderString&& value) override { + header_map_.addViaMove(std::move(key), std::move(value)); + } + void addReference(const LowerCaseString& key, absl::string_view value) override { + header_map_.addReference(key, value); + } + void addReferenceKey(const LowerCaseString& key, uint64_t value) override { + header_map_.addReferenceKey(key, value); + } + void addReferenceKey(const LowerCaseString& key, absl::string_view value) override { + header_map_.addReferenceKey(key, value); + } + void addCopy(const LowerCaseString& key, uint64_t value) override { + header_map_.addCopy(key, value); + } + void addCopy(const LowerCaseString& key, absl::string_view value) override { + header_map_.addCopy(key, value); + } + void appendCopy(const LowerCaseString& key, absl::string_view value) override { + header_map_.appendCopy(key, value); + } + void setReference(const LowerCaseString& key, absl::string_view value) override { + header_map_.setReference(key, value); + } + void setReferenceKey(const LowerCaseString& key, absl::string_view value) override { + header_map_.setReferenceKey(key, value); + } + void setCopy(const LowerCaseString& key, absl::string_view value) override { + header_map_.setCopy(key, value); + } + uint64_t byteSize() const override { return header_map_.byteSize(); } + const HeaderEntry* get(const LowerCaseString& key) const override { return header_map_.get(key); } + void iterate(HeaderMap::ConstIterateCb cb, void* context) const override { + header_map_.iterate(cb, context); + } + void iterateReverse(HeaderMap::ConstIterateCb cb, void* context) const override { + header_map_.iterateReverse(cb, context); + } + HeaderMap::Lookup lookup(const LowerCaseString& key, const HeaderEntry** entry) const override { + return header_map_.lookup(key, entry); + } + void clear() override { header_map_.clear(); } + void remove(const LowerCaseString& key) override { header_map_.remove(key); } + void removePrefix(const LowerCaseString& key) override { header_map_.removePrefix(key); } + size_t size() const override { return header_map_.size(); } + bool empty() const override { return header_map_.empty(); } + void dumpState(std::ostream& os, int indent_level = 0) const override { + header_map_.dumpState(os, indent_level); + } + void verifyByteSize() override { header_map_.verifyByteSizeInternalForTest(); } + + ALL_INLINE_HEADERS(DEFINE_TEST_INLINE_HEADER_FUNCS) + + Impl header_map_; }; /** * Typed test implementations for all of the concrete header types. */ -class TestRequestHeaderMapImpl : public TestHeaderMapImpl, public RequestHeaderMap { -public: - TestRequestHeaderMapImpl(const std::initializer_list>& values) - : TestHeaderMapImpl(values) {} - TestRequestHeaderMapImpl(const HeaderMap& rhs) : TestHeaderMapImpl(rhs) {} -}; -class TestRequestTrailerMapImpl : public TestHeaderMapImpl, public RequestTrailerMap { -public: - TestRequestTrailerMapImpl( - const std::initializer_list>& values) - : TestHeaderMapImpl(values) {} - TestRequestTrailerMapImpl(const HeaderMap& rhs) : TestHeaderMapImpl(rhs) {} -}; -class TestResponseHeaderMapImpl : public TestHeaderMapImpl, public ResponseHeaderMap { -public: - TestResponseHeaderMapImpl( - const std::initializer_list>& values) - : TestHeaderMapImpl(values) {} - TestResponseHeaderMapImpl() : TestHeaderMapImpl() {} -}; -class TestResponseTrailerMapImpl : public TestHeaderMapImpl, public ResponseTrailerMap { -public: - TestResponseTrailerMapImpl( - const std::initializer_list>& values) - : TestHeaderMapImpl(values) {} - TestResponseTrailerMapImpl() : TestHeaderMapImpl() {} -}; +using TestHeaderMapImpl = TestHeaderMapImplBase; +using TestRequestHeaderMapImpl = TestHeaderMapImplBase; +using TestRequestTrailerMapImpl = TestHeaderMapImplBase; +using TestResponseHeaderMapImpl = TestHeaderMapImplBase; +using TestResponseTrailerMapImpl = + TestHeaderMapImplBase; // Helper method to create a header map from an initializer list. Useful due to make_unique's // inability to infer the initializer list type. From fade668c7edfbade082b40df1c6b9924bc7a7e0e Mon Sep 17 00:00:00 2001 From: Nupur Garg <37600866+gargnupur@users.noreply.github.com> Date: Fri, 14 Feb 2020 10:22:16 -0800 Subject: [PATCH 58/87] Add upstream and downstream info in parent read callbacks in tcp too (#9949) Signed-off-by: gargnupur --- source/common/network/connection_impl.cc | 2 +- source/common/network/connection_impl.h | 2 +- source/common/tcp_proxy/tcp_proxy.cc | 9 ++- source/common/tcp_proxy/tcp_proxy.h | 6 +- .../filters/network/tcp_proxy/config.cc | 4 +- test/common/http/conn_manager_impl_test.cc | 2 +- .../network/filter_manager_impl_test.cc | 3 +- test/common/stream_info/BUILD | 2 +- test/common/stream_info/test_util.h | 4 +- test/common/tcp_proxy/tcp_proxy_test.cc | 68 +++++++++++-------- .../upstream/health_checker_impl_test.cc | 7 +- .../grpc/http_grpc_access_log_impl_test.cc | 4 +- .../filters/http/lua/lua_filter_test.cc | 2 +- .../filters/http/lua/wrappers_test.cc | 2 +- .../filters/network/tcp_proxy/config_test.cc | 13 +++- .../tracers/zipkin/zipkin_tracer_impl_test.cc | 2 +- test/mocks/stream_info/BUILD | 1 + test/mocks/stream_info/mocks.cc | 17 ++++- test/mocks/stream_info/mocks.h | 3 + 19 files changed, 97 insertions(+), 56 deletions(-) diff --git a/source/common/network/connection_impl.cc b/source/common/network/connection_impl.cc index 91a6446a31..16a9caf32e 100644 --- a/source/common/network/connection_impl.cc +++ b/source/common/network/connection_impl.cc @@ -45,7 +45,7 @@ ConnectionImpl::ConnectionImpl(Event::Dispatcher& dispatcher, ConnectionSocketPt TransportSocketPtr&& transport_socket, bool connected) : ConnectionImplBase(dispatcher, next_global_id_++), transport_socket_(std::move(transport_socket)), socket_(std::move(socket)), - filter_manager_(*this), stream_info_(dispatcher.timeSource()), + stream_info_(dispatcher.timeSource()), filter_manager_(*this), write_buffer_( dispatcher.getWatermarkFactory().create([this]() -> void { this->onLowWatermark(); }, [this]() -> void { this->onHighWatermark(); })), diff --git a/source/common/network/connection_impl.h b/source/common/network/connection_impl.h index 450efa869e..9042087853 100644 --- a/source/common/network/connection_impl.h +++ b/source/common/network/connection_impl.h @@ -128,8 +128,8 @@ class ConnectionImpl : public ConnectionImplBase, public TransportSocketCallback TransportSocketPtr transport_socket_; ConnectionSocketPtr socket_; - FilterManagerImpl filter_manager_; StreamInfo::StreamInfoImpl stream_info_; + FilterManagerImpl filter_manager_; Buffer::OwnedImpl read_buffer_; // This must be a WatermarkBuffer, but as it is created by a factory the ConnectionImpl only has diff --git a/source/common/tcp_proxy/tcp_proxy.cc b/source/common/tcp_proxy/tcp_proxy.cc index 6f23bd83ab..bd299ff35c 100644 --- a/source/common/tcp_proxy/tcp_proxy.cc +++ b/source/common/tcp_proxy/tcp_proxy.cc @@ -204,10 +204,9 @@ UpstreamDrainManager& Config::drainManager() { return upstream_drain_manager_slot_->getTyped(); } -Filter::Filter(ConfigSharedPtr config, Upstream::ClusterManager& cluster_manager, - TimeSource& time_source) +Filter::Filter(ConfigSharedPtr config, Upstream::ClusterManager& cluster_manager) : config_(config), cluster_manager_(cluster_manager), downstream_callbacks_(*this), - upstream_callbacks_(new UpstreamCallbacks(this)), stream_info_(time_source) { + upstream_callbacks_(new UpstreamCallbacks(this)) { ASSERT(config != nullptr); } @@ -292,6 +291,10 @@ void Filter::readDisableDownstream(bool disable) { } } +StreamInfo::StreamInfo& Filter::getStreamInfo() { + return read_callbacks_->connection().streamInfo(); +} + void Filter::DownstreamCallbacks::onAboveWriteBufferHighWatermark() { ASSERT(!on_high_watermark_called_); on_high_watermark_called_ = true; diff --git a/source/common/tcp_proxy/tcp_proxy.h b/source/common/tcp_proxy/tcp_proxy.h index cef36312df..92c2bac4c6 100644 --- a/source/common/tcp_proxy/tcp_proxy.h +++ b/source/common/tcp_proxy/tcp_proxy.h @@ -229,8 +229,7 @@ class Filter : public Network::ReadFilter, Tcp::ConnectionPool::Callbacks, protected Logger::Loggable { public: - Filter(ConfigSharedPtr config, Upstream::ClusterManager& cluster_manager, - TimeSource& time_source); + Filter(ConfigSharedPtr config, Upstream::ClusterManager& cluster_manager); ~Filter() override; // Network::ReadFilter @@ -302,7 +301,7 @@ class Filter : public Network::ReadFilter, bool on_high_watermark_called_{false}; }; - virtual StreamInfo::StreamInfo& getStreamInfo() { return stream_info_; } + virtual StreamInfo::StreamInfo& getStreamInfo(); protected: struct DownstreamCallbacks : public Network::ConnectionCallbacks { @@ -354,7 +353,6 @@ class Filter : public Network::ReadFilter, std::shared_ptr upstream_callbacks_; // shared_ptr required for passing as a // read filter. std::unique_ptr upstream_; - StreamInfo::StreamInfoImpl stream_info_; RouteConstSharedPtr route_; Network::TransportSocketOptionsSharedPtr transport_socket_options_; uint32_t connect_attempts_{}; diff --git a/source/extensions/filters/network/tcp_proxy/config.cc b/source/extensions/filters/network/tcp_proxy/config.cc index f9350ff7e8..d9ca1049b9 100644 --- a/source/extensions/filters/network/tcp_proxy/config.cc +++ b/source/extensions/filters/network/tcp_proxy/config.cc @@ -22,8 +22,8 @@ Network::FilterFactoryCb ConfigFactory::createFilterFactoryFromProtoTyped( Envoy::TcpProxy::ConfigSharedPtr filter_config( std::make_shared(proto_config, context)); return [filter_config, &context](Network::FilterManager& filter_manager) -> void { - filter_manager.addReadFilter(std::make_shared( - filter_config, context.clusterManager(), context.dispatcher().timeSource())); + filter_manager.addReadFilter( + std::make_shared(filter_config, context.clusterManager())); }; } diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc index b8d2cd8995..31c6c5315a 100644 --- a/test/common/http/conn_manager_impl_test.cc +++ b/test/common/http/conn_manager_impl_test.cc @@ -344,7 +344,7 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan bool shouldNormalizePath() const override { return normalize_path_; } bool shouldMergeSlashes() const override { return merge_slashes_; } - DangerousDeprecatedTestTime test_time_; + Envoy::Event::SimulatedTimeSystem test_time_; NiceMock route_config_provider_; std::shared_ptr route_config_{new NiceMock()}; NiceMock scoped_route_config_provider_; diff --git a/test/common/network/filter_manager_impl_test.cc b/test/common/network/filter_manager_impl_test.cc index 3dd955f586..f8dea3442a 100644 --- a/test/common/network/filter_manager_impl_test.cc +++ b/test/common/network/filter_manager_impl_test.cc @@ -397,8 +397,7 @@ stat_prefix: name tcp_proxy.set_cluster("fake_cluster"); TcpProxy::ConfigSharedPtr tcp_proxy_config(new TcpProxy::Config(tcp_proxy, factory_context)); manager.addReadFilter( - std::make_shared(tcp_proxy_config, factory_context.cluster_manager_, - factory_context.dispatcher().timeSource())); + std::make_shared(tcp_proxy_config, factory_context.cluster_manager_)); Extensions::Filters::Common::RateLimit::RequestCallbacks* request_callbacks{}; EXPECT_CALL(*rl_client, limit(_, "foo", diff --git a/test/common/stream_info/BUILD b/test/common/stream_info/BUILD index 6b8f159e86..9c60f05c1c 100644 --- a/test/common/stream_info/BUILD +++ b/test/common/stream_info/BUILD @@ -46,7 +46,7 @@ envoy_cc_test_library( "//include/envoy/stream_info:stream_info_interface", "//source/common/common:assert_lib", "//source/common/stream_info:filter_state_lib", - "//test/test_common:test_time_lib", + "//test/test_common:simulated_time_system_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) diff --git a/test/common/stream_info/test_util.h b/test/common/stream_info/test_util.h index 7d3805f076..cba0355f4b 100644 --- a/test/common/stream_info/test_util.h +++ b/test/common/stream_info/test_util.h @@ -6,7 +6,7 @@ #include "common/common/assert.h" #include "common/stream_info/filter_state_impl.h" -#include "test/test_common/test_time.h" +#include "test/test_common/simulated_time_system.h" namespace Envoy { @@ -242,7 +242,7 @@ class TestStreamInfo : public StreamInfo::StreamInfo { std::string requested_server_name_; std::string upstream_transport_failure_reason_; const Http::HeaderMap* request_headers_{}; - DangerousDeprecatedTestTime test_time_; + Envoy::Event::SimulatedTimeSystem test_time_; }; } // namespace Envoy diff --git a/test/common/tcp_proxy/tcp_proxy_test.cc b/test/common/tcp_proxy/tcp_proxy_test.cc index 70675d23ad..80d676f5b9 100644 --- a/test/common/tcp_proxy/tcp_proxy_test.cc +++ b/test/common/tcp_proxy/tcp_proxy_test.cc @@ -827,6 +827,11 @@ class TcpProxyTest : public testing::Test { TcpProxyTest() { ON_CALL(*factory_context_.access_log_manager_.file_, write(_)) .WillByDefault(SaveArg<0>(&access_log_data_)); + ON_CALL(filter_callbacks_.connection_.stream_info_, onUpstreamHostSelected(_)) + .WillByDefault(Invoke( + [this](Upstream::HostDescriptionConstSharedPtr host) { upstream_host_ = host; })); + ON_CALL(filter_callbacks_.connection_.stream_info_, upstreamHost()) + .WillByDefault(ReturnPointee(&upstream_host_)); } ~TcpProxyTest() override { @@ -905,7 +910,7 @@ class TcpProxyTest : public testing::Test { } { - filter_ = std::make_unique(config_, factory_context_.cluster_manager_, timeSystem()); + filter_ = std::make_unique(config_, factory_context_.cluster_manager_); EXPECT_CALL(filter_callbacks_.connection_, enableHalfClose(true)); EXPECT_CALL(filter_callbacks_.connection_, readDisable(true)); filter_->initializeReadFilterCallbacks(filter_callbacks_); @@ -953,8 +958,8 @@ class TcpProxyTest : public testing::Test { NiceMock factory_context_; ConfigSharedPtr config_; - std::unique_ptr filter_; NiceMock filter_callbacks_; + std::unique_ptr filter_; std::vector>> upstream_hosts_{}; std::vector>> upstream_connections_{}; std::vector>> @@ -968,6 +973,7 @@ class TcpProxyTest : public testing::Test { Network::Address::InstanceConstSharedPtr upstream_remote_address_; std::list> new_connection_functions_; + Upstream::HostDescriptionConstSharedPtr upstream_host_{}; }; TEST_F(TcpProxyTest, DEPRECATED_FEATURE_TEST(DefaultRoutes)) { @@ -1253,7 +1259,7 @@ TEST_F(TcpProxyTest, DEPRECATED_FEATURE_TEST(RouteWithMetadataMatch)) { {Envoy::Config::MetadataFilters::get().ENVOY_LB, metadata_struct}); configure(config); - filter_ = std::make_unique(config_, factory_context_.cluster_manager_, timeSystem()); + filter_ = std::make_unique(config_, factory_context_.cluster_manager_); filter_->initializeReadFilterCallbacks(filter_callbacks_); EXPECT_EQ(Network::FilterStatus::StopIteration, filter_->onNewConnection()); @@ -1301,7 +1307,7 @@ TEST_F(TcpProxyTest, WeightedClusterWithMetadataMatch) { v2.set_string_value("v2"); HashedValue hv0(v0), hv1(v1), hv2(v2); - filter_ = std::make_unique(config_, factory_context_.cluster_manager_, timeSystem()); + filter_ = std::make_unique(config_, factory_context_.cluster_manager_); filter_->initializeReadFilterCallbacks(filter_callbacks_); // Expect filter to try to open a connection to cluster1. @@ -1355,7 +1361,7 @@ TEST_F(TcpProxyTest, WeightedClusterWithMetadataMatch) { TEST_F(TcpProxyTest, DEPRECATED_FEATURE_TEST(DisconnectBeforeData)) { configure(defaultConfig()); - filter_ = std::make_unique(config_, factory_context_.cluster_manager_, timeSystem()); + filter_ = std::make_unique(config_, factory_context_.cluster_manager_); filter_->initializeReadFilterCallbacks(filter_callbacks_); filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -1394,7 +1400,7 @@ TEST_F(TcpProxyTest, DEPRECATED_FEATURE_TEST(UpstreamConnectionLimit)) { 0, 0, 0, 0, 0); // setup sets up expectation for tcpConnForCluster but this test is expected to NOT call that - filter_ = std::make_unique(config_, factory_context_.cluster_manager_, timeSystem()); + filter_ = std::make_unique(config_, factory_context_.cluster_manager_); // The downstream connection closes if the proxy can't make an upstream connection. EXPECT_CALL(filter_callbacks_.connection_, close(Network::ConnectionCloseType::NoFlush)); filter_->initializeReadFilterCallbacks(filter_callbacks_); @@ -1746,6 +1752,23 @@ TEST_F(TcpProxyTest, ShareFilterState) { .value()); } +// Tests that filter callback can access downstream and upstream address and ssl properties. +TEST_F(TcpProxyTest, AccessDownstreamAndUpstreamProperties) { + setup(1); + + raiseEventUpstreamConnected(0); + EXPECT_EQ(filter_callbacks_.connection().streamInfo().downstreamLocalAddress(), + filter_callbacks_.connection().localAddress()); + EXPECT_EQ(filter_callbacks_.connection().streamInfo().downstreamRemoteAddress(), + filter_callbacks_.connection().remoteAddress()); + EXPECT_EQ(filter_callbacks_.connection().streamInfo().downstreamSslConnection(), + filter_callbacks_.connection().ssl()); + EXPECT_EQ(filter_callbacks_.connection().streamInfo().upstreamLocalAddress(), + upstream_connections_.at(0)->localAddress()); + EXPECT_EQ(filter_callbacks_.connection().streamInfo().upstreamSslConnection(), + upstream_connections_.at(0)->streamInfo().downstreamSslConnection()); +} + class TcpProxyRoutingTest : public testing::Test { public: TcpProxyRoutingTest() = default; @@ -1766,7 +1789,7 @@ class TcpProxyRoutingTest : public testing::Test { void initializeFilter() { EXPECT_CALL(filter_callbacks_, connection()).WillRepeatedly(ReturnRef(connection_)); - filter_ = std::make_unique(config_, factory_context_.cluster_manager_, timeSystem()); + filter_ = std::make_unique(config_, factory_context_.cluster_manager_); filter_->initializeReadFilterCallbacks(filter_callbacks_); } @@ -1826,13 +1849,10 @@ TEST_F(TcpProxyRoutingTest, DEPRECATED_FEATURE_TEST(UseClusterFromPerConnectionC setup(); initializeFilter(); - NiceMock stream_info; - stream_info.filterState()->setData("envoy.tcp_proxy.cluster", - std::make_unique("filter_state_cluster"), - StreamInfo::FilterState::StateType::Mutable, - StreamInfo::FilterState::LifeSpan::DownstreamConnection); - ON_CALL(connection_, streamInfo()).WillByDefault(ReturnRef(stream_info)); - EXPECT_CALL(Const(connection_), streamInfo()).WillRepeatedly(ReturnRef(stream_info)); + connection_.streamInfo().filterState()->setData( + "envoy.tcp_proxy.cluster", std::make_unique("filter_state_cluster"), + StreamInfo::FilterState::StateType::Mutable, + StreamInfo::FilterState::LifeSpan::DownstreamConnection); // Expect filter to try to open a connection to specified cluster. EXPECT_CALL(factory_context_.cluster_manager_, @@ -1847,14 +1867,10 @@ TEST_F(TcpProxyRoutingTest, DEPRECATED_FEATURE_TEST(UpstreamServerName)) { setup(); initializeFilter(); - NiceMock stream_info; - stream_info.filterState()->setData("envoy.network.upstream_server_name", - std::make_unique("www.example.com"), - StreamInfo::FilterState::StateType::ReadOnly, - StreamInfo::FilterState::LifeSpan::DownstreamConnection); - - ON_CALL(connection_, streamInfo()).WillByDefault(ReturnRef(stream_info)); - EXPECT_CALL(Const(connection_), streamInfo()).WillRepeatedly(ReturnRef(stream_info)); + connection_.streamInfo().filterState()->setData( + "envoy.network.upstream_server_name", std::make_unique("www.example.com"), + StreamInfo::FilterState::StateType::ReadOnly, + StreamInfo::FilterState::LifeSpan::DownstreamConnection); // Expect filter to try to open a connection to a cluster with the transport socket options with // override-server-name @@ -1882,16 +1898,12 @@ TEST_F(TcpProxyRoutingTest, DEPRECATED_FEATURE_TEST(ApplicationProtocols)) { setup(); initializeFilter(); - NiceMock stream_info; - stream_info.filterState()->setData( + connection_.streamInfo().filterState()->setData( Network::ApplicationProtocols::key(), std::make_unique(std::vector{"foo", "bar"}), StreamInfo::FilterState::StateType::ReadOnly, StreamInfo::FilterState::LifeSpan::DownstreamConnection); - ON_CALL(connection_, streamInfo()).WillByDefault(ReturnRef(stream_info)); - EXPECT_CALL(Const(connection_), streamInfo()).WillRepeatedly(ReturnRef(stream_info)); - // Expect filter to try to open a connection to a cluster with the transport socket options with // override-application-protocol EXPECT_CALL(factory_context_.cluster_manager_, tcpConnPoolForCluster(_, _, _)) @@ -1933,7 +1945,7 @@ class TcpProxyHashingTest : public testing::Test { void initializeFilter() { EXPECT_CALL(filter_callbacks_, connection()).WillRepeatedly(ReturnRef(connection_)); - filter_ = std::make_unique(config_, factory_context_.cluster_manager_, timeSystem()); + filter_ = std::make_unique(config_, factory_context_.cluster_manager_); filter_->initializeReadFilterCallbacks(filter_callbacks_); } diff --git a/test/common/upstream/health_checker_impl_test.cc b/test/common/upstream/health_checker_impl_test.cc index 4bf9c2019c..8851daeedc 100644 --- a/test/common/upstream/health_checker_impl_test.cc +++ b/test/common/upstream/health_checker_impl_test.cc @@ -1322,7 +1322,6 @@ TEST_F(HttpHealthCheckerImplTest, SuccessServiceCheckWithAdditionalHeaders) { key: value )EOF"); - std::string current_start_time; cluster_->prioritySet().getMockHostSet(0)->hosts_ = { makeTestHost(cluster_->info_, "tcp://127.0.0.1:80", metadata)}; cluster_->info_->stats().upstream_cx_total_.inc(); @@ -1348,8 +1347,10 @@ TEST_F(HttpHealthCheckerImplTest, SuccessServiceCheckWithAdditionalHeaders) { EXPECT_EQ(headers.get(downstream_local_address_without_port)->value().getStringView(), value_downstream_local_address_without_port); - EXPECT_NE(headers.get(start_time)->value().getStringView(), current_start_time); - current_start_time = std::string(headers.get(start_time)->value().getStringView()); + Envoy::DateFormatter date_formatter("%s.%9f"); + std::string current_start_time = + date_formatter.fromTime(dispatcher_.timeSource().systemTime()); + EXPECT_EQ(headers.get(start_time)->value().getStringView(), current_start_time); })); health_checker_->start(); diff --git a/test/extensions/access_loggers/grpc/http_grpc_access_log_impl_test.cc b/test/extensions/access_loggers/grpc/http_grpc_access_log_impl_test.cc index 2afcb68817..31d506ae55 100644 --- a/test/extensions/access_loggers/grpc/http_grpc_access_log_impl_test.cc +++ b/test/extensions/access_loggers/grpc/http_grpc_access_log_impl_test.cc @@ -85,6 +85,7 @@ class HttpGrpcAccessLogTest : public testing::Test { void expectLogRequestMethod(const std::string& request_method) { NiceMock stream_info; stream_info.host_ = nullptr; + stream_info.start_time_ = SystemTime(1h); Http::TestHeaderMapImpl request_headers{ {":method", request_method}, @@ -104,7 +105,8 @@ class HttpGrpcAccessLogTest : public testing::Test { socket_address: address: "127.0.0.2" port_value: 0 - start_time: {{}} + start_time: + seconds: 3600 request: request_method: {} request_headers_bytes: {} diff --git a/test/extensions/filters/http/lua/lua_filter_test.cc b/test/extensions/filters/http/lua/lua_filter_test.cc index 941f4806d7..5262528193 100644 --- a/test/extensions/filters/http/lua/lua_filter_test.cc +++ b/test/extensions/filters/http/lua/lua_filter_test.cc @@ -1558,7 +1558,7 @@ TEST_F(LuaHttpFilterTest, SetGetDynamicMetadata) { setup(SCRIPT); Http::TestHeaderMapImpl request_headers{{":path", "/"}}; - DangerousDeprecatedTestTime test_time; + Event::SimulatedTimeSystem test_time; StreamInfo::StreamInfoImpl stream_info(Http::Protocol::Http2, test_time.timeSystem()); EXPECT_EQ(0, stream_info.dynamicMetadata().filter_metadata_size()); EXPECT_CALL(decoder_callbacks_, streamInfo()).WillOnce(ReturnRef(stream_info)); diff --git a/test/extensions/filters/http/lua/wrappers_test.cc b/test/extensions/filters/http/lua/wrappers_test.cc index 31447f4508..32c003951e 100644 --- a/test/extensions/filters/http/lua/wrappers_test.cc +++ b/test/extensions/filters/http/lua/wrappers_test.cc @@ -254,7 +254,7 @@ class LuaStreamInfoWrapperTest return metadata; } - DangerousDeprecatedTestTime test_time_; + Event::SimulatedTimeSystem test_time_; }; // Return the current request protocol. diff --git a/test/extensions/filters/network/tcp_proxy/config_test.cc b/test/extensions/filters/network/tcp_proxy/config_test.cc index 635004dcf2..4104f8540e 100644 --- a/test/extensions/filters/network/tcp_proxy/config_test.cc +++ b/test/extensions/filters/network/tcp_proxy/config_test.cc @@ -97,7 +97,11 @@ TEST_P(RouteIpListConfigTest, DEPRECATED_FEATURE_TEST(TcpProxy)) { ConfigFactory factory; Network::FilterFactoryCb cb = factory.createFilterFactoryFromProto(proto_config, context); Network::MockConnection connection; - EXPECT_CALL(connection, addReadFilter(_)); + NiceMock readFilterCallback; + EXPECT_CALL(connection, addReadFilter(_)) + .WillRepeatedly(Invoke([&readFilterCallback](Network::ReadFilterSharedPtr filter) { + filter->initializeReadFilterCallbacks(readFilterCallback); + })); cb(connection); } @@ -119,9 +123,14 @@ TEST(ConfigTest, ConfigTest) { config.set_cluster("cluster"); EXPECT_TRUE(factory.isTerminalFilter()); + Network::FilterFactoryCb cb = factory.createFilterFactoryFromProto(config, context); Network::MockConnection connection; - EXPECT_CALL(connection, addReadFilter(_)); + NiceMock readFilterCallback; + EXPECT_CALL(connection, addReadFilter(_)) + .WillRepeatedly(Invoke([&readFilterCallback](Network::ReadFilterSharedPtr filter) { + filter->initializeReadFilterCallbacks(readFilterCallback); + })); cb(connection); } diff --git a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc index 5f060f7dd4..c7965b8142 100644 --- a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc +++ b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc @@ -145,7 +145,7 @@ class ZipkinDriverTest : public testing::Test { NiceMock random_; NiceMock config_; - DangerousDeprecatedTestTime test_time_; + Event::SimulatedTimeSystem test_time_; TimeSource& time_source_; }; diff --git a/test/mocks/stream_info/BUILD b/test/mocks/stream_info/BUILD index ef392a961b..c6d56c5ac6 100644 --- a/test/mocks/stream_info/BUILD +++ b/test/mocks/stream_info/BUILD @@ -16,6 +16,7 @@ envoy_cc_mock( "//include/envoy/stream_info:stream_info_interface", "//include/envoy/upstream:upstream_interface", "//test/mocks/upstream:host_mocks", + "//test/test_common:simulated_time_system_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], ) diff --git a/test/mocks/stream_info/mocks.cc b/test/mocks/stream_info/mocks.cc index f2bd5133d2..dce47cbaf2 100644 --- a/test/mocks/stream_info/mocks.cc +++ b/test/mocks/stream_info/mocks.cc @@ -15,11 +15,14 @@ namespace Envoy { namespace StreamInfo { MockStreamInfo::MockStreamInfo() - : filter_state_(std::make_shared(FilterState::LifeSpan::FilterChain)), + : start_time_(ts_.systemTime()), + filter_state_(std::make_shared(FilterState::LifeSpan::FilterChain)), downstream_local_address_(new Network::Address::Ipv4Instance("127.0.0.2")), downstream_direct_remote_address_(new Network::Address::Ipv4Instance("127.0.0.1")), downstream_remote_address_(new Network::Address::Ipv4Instance("127.0.0.1")) { - ON_CALL(*this, upstreamHost()).WillByDefault(ReturnPointee(&host_)); + ON_CALL(*this, setResponseFlag(_)).WillByDefault(Invoke([this](ResponseFlag response_flag) { + response_flags_ |= response_flag; + })); ON_CALL(*this, startTime()).WillByDefault(ReturnPointee(&start_time_)); ON_CALL(*this, startTimeMonotonic()).WillByDefault(ReturnPointee(&start_time_monotonic_)); ON_CALL(*this, lastDownstreamRxByteReceived()) @@ -37,6 +40,11 @@ MockStreamInfo::MockStreamInfo() ON_CALL(*this, lastDownstreamTxByteSent()) .WillByDefault(ReturnPointee(&last_downstream_tx_byte_sent_)); ON_CALL(*this, requestComplete()).WillByDefault(ReturnPointee(&end_time_)); + ON_CALL(*this, onRequestComplete()).WillByDefault(Invoke([this]() { + end_time_ = absl::make_optional( + std::chrono::duration_cast(ts_.systemTime() - start_time_) + .count()); + })); ON_CALL(*this, setUpstreamLocalAddress(_)) .WillByDefault( Invoke([this](const Network::Address::InstanceConstSharedPtr& upstream_local_address) { @@ -85,6 +93,11 @@ MockStreamInfo::MockStreamInfo() bytes_sent_ += bytes_sent; })); ON_CALL(*this, bytesSent()).WillByDefault(ReturnPointee(&bytes_sent_)); + ON_CALL(*this, hasResponseFlag(_)).WillByDefault(Invoke([this](ResponseFlag flag) { + return response_flags_ & flag; + })); + ON_CALL(*this, upstreamHost()).WillByDefault(ReturnPointee(&host_)); + ON_CALL(*this, dynamicMetadata()).WillByDefault(ReturnRef(metadata_)); ON_CALL(Const(*this), dynamicMetadata()).WillByDefault(ReturnRef(metadata_)); ON_CALL(*this, filterState()).WillByDefault(ReturnRef(filter_state_)); diff --git a/test/mocks/stream_info/mocks.h b/test/mocks/stream_info/mocks.h index a064f4f0f8..dfc547ff75 100644 --- a/test/mocks/stream_info/mocks.h +++ b/test/mocks/stream_info/mocks.h @@ -6,6 +6,7 @@ #include "common/stream_info/filter_state_impl.h" #include "test/mocks/upstream/host.h" +#include "test/test_common/simulated_time_system.h" #include "gmock/gmock.h" @@ -91,6 +92,7 @@ class MockStreamInfo : public StreamInfo { std::shared_ptr> host_{ new testing::NiceMock()}; + Envoy::Event::SimulatedTimeSystem ts_; SystemTime start_time_; MonotonicTime start_time_monotonic_; absl::optional last_downstream_rx_byte_received_; @@ -104,6 +106,7 @@ class MockStreamInfo : public StreamInfo { absl::optional protocol_; absl::optional response_code_; absl::optional response_code_details_; + uint64_t response_flags_{}; envoy::config::core::v3::Metadata metadata_; FilterStateSharedPtr upstream_filter_state_; FilterStateSharedPtr filter_state_; From bbf365b552bdf43d074354e98818ce3f04d35195 Mon Sep 17 00:00:00 2001 From: Adam Kotwasinski Date: Fri, 14 Feb 2020 11:49:02 -0800 Subject: [PATCH 59/87] kafka: 2.4.0 support - add support for new message types added in 2.4 (#10000) Signed-off-by: Adam Kotwasinski --- bazel/repository_locations.bzl | 18 +- .../network_filters/kafka_broker_filter.rst | 2 +- source/extensions/filters/network/kafka/BUILD | 2 + .../filters/network/kafka/kafka_request.h | 57 +++- .../network/kafka/kafka_request_parser.cc | 30 +++ .../network/kafka/kafka_request_parser.h | 40 ++- .../filters/network/kafka/kafka_response.h | 54 +++- .../network/kafka/kafka_response_parser.cc | 33 ++- .../network/kafka/kafka_response_parser.h | 18 +- .../kafka/protocol/complex_type_template.j2 | 44 ++-- .../network/kafka/protocol/generator.py | 246 ++++++++++++++---- .../protocol/kafka_request_resolver_cc.j2 | 19 ++ .../protocol/kafka_response_resolver_cc.j2 | 22 ++ .../network/kafka/serialization/generator.py | 2 +- .../filters/network/kafka/tagged_fields.h | 4 +- test/extensions/filters/network/kafka/BUILD | 1 + .../integration_test/zookeeper_properties.j2 | 2 + .../kafka/kafka_request_parser_test.cc | 5 +- .../protocol/request_codec_request_test_cc.j2 | 15 +- .../response_codec_response_test_cc.j2 | 14 +- .../network/kafka/request_codec_unit_test.cc | 4 +- .../network/kafka/serialization_test.cc | 19 ++ 22 files changed, 526 insertions(+), 125 deletions(-) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 7fab9e774e..bff4e023bd 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -303,18 +303,18 @@ REPOSITORY_LOCATIONS = dict( urls = ["https://github.com/protocolbuffers/upb/archive/8a3ae1ef3e3e3f26b45dec735c5776737fc7247f.tar.gz"], ), kafka_source = dict( - sha256 = "feaa32e5c42acf42bd587f8f0b1ccce679db227620da97eed013f4c44a44f64d", - strip_prefix = "kafka-2.3.1/clients/src/main/resources/common/message", - urls = ["https://github.com/apache/kafka/archive/2.3.1.zip"], + sha256 = "e7b748a62e432b5770db6dbb3b034c68c0ea212812cb51603ee7f3a8a35f06be", + strip_prefix = "kafka-2.4.0/clients/src/main/resources/common/message", + urls = ["https://github.com/apache/kafka/archive/2.4.0.zip"], ), kafka_server_binary = dict( - sha256 = "5a3ddd4148371284693370d56f6f66c7a86d86dd96c533447d2a94d176768d2e", - strip_prefix = "kafka_2.12-2.3.1", - urls = ["http://us.mirrors.quenda.co/apache/kafka/2.3.1/kafka_2.12-2.3.1.tgz"], + sha256 = "b9582bab0c3e8d131953b1afa72d6885ca1caae0061c2623071e7f396f2ccfee", + strip_prefix = "kafka_2.12-2.4.0", + urls = ["http://us.mirrors.quenda.co/apache/kafka/2.4.0/kafka_2.12-2.4.0.tgz"], ), kafka_python_client = dict( - sha256 = "81f24a5d297531495e0ccb931fbd6c4d1ec96583cf5a730579a3726e63f59c47", - strip_prefix = "kafka-python-1.4.7", - urls = ["https://github.com/dpkp/kafka-python/archive/1.4.7.tar.gz"], + sha256 = "454bf3aafef9348017192417b7f0828a347ec2eaf3efba59336f3a3b68f10094", + strip_prefix = "kafka-python-2.0.0", + urls = ["https://github.com/dpkp/kafka-python/archive/2.0.0.tar.gz"], ), ) diff --git a/docs/root/configuration/listeners/network_filters/kafka_broker_filter.rst b/docs/root/configuration/listeners/network_filters/kafka_broker_filter.rst index 2443136748..8f7ef37427 100644 --- a/docs/root/configuration/listeners/network_filters/kafka_broker_filter.rst +++ b/docs/root/configuration/listeners/network_filters/kafka_broker_filter.rst @@ -5,7 +5,7 @@ Kafka Broker filter The Apache Kafka broker filter decodes the client protocol for `Apache Kafka `_, both the requests and responses in the payload. -The message versions in `Kafka 2.3.1 `_ +The message versions in `Kafka 2.4.0 `_ are supported. The filter attempts not to influence the communication between client and brokers, so the messages that could not be decoded (due to Kafka client or broker running a newer version than supported by diff --git a/source/extensions/filters/network/kafka/BUILD b/source/extensions/filters/network/kafka/BUILD index 8564c02eda..f4588076cf 100644 --- a/source/extensions/filters/network/kafka/BUILD +++ b/source/extensions/filters/network/kafka/BUILD @@ -81,6 +81,7 @@ envoy_cc_library( deps = [ ":kafka_request_lib", ":parser_lib", + ":tagged_fields_lib", "//source/common/common:assert_lib", "//source/common/common:minimal_logger_lib", ], @@ -143,6 +144,7 @@ envoy_cc_library( deps = [ ":kafka_response_lib", ":parser_lib", + ":tagged_fields_lib", "//source/common/common:assert_lib", "//source/common/common:minimal_logger_lib", ], diff --git a/source/extensions/filters/network/kafka/kafka_request.h b/source/extensions/filters/network/kafka/kafka_request.h index 0c21543cc2..ff9f57282a 100644 --- a/source/extensions/filters/network/kafka/kafka_request.h +++ b/source/extensions/filters/network/kafka/kafka_request.h @@ -4,12 +4,22 @@ #include "extensions/filters/network/kafka/external/serialization_composite.h" #include "extensions/filters/network/kafka/serialization.h" +#include "extensions/filters/network/kafka/tagged_fields.h" namespace Envoy { namespace Extensions { namespace NetworkFilters { namespace Kafka { +/** + * Decides if request with given api key & version should have tagged fields in header. + * This method gets implemented in generated code through 'kafka_request_resolver_cc.j2'. + * @param api_key Kafka request key. + * @param api_version Kafka request's version. + * @return Whether tagged fields should be used for this request. + */ +bool requestUsesTaggedFieldsInHeader(const uint16_t api_key, const uint16_t api_version); + /** * Represents fields that are present in every Kafka request message. * @see http://kafka.apache.org/protocol.html#protocol_messages @@ -19,10 +29,45 @@ struct RequestHeader { int16_t api_version_; int32_t correlation_id_; NullableString client_id_; + TaggedFields tagged_fields_; + + RequestHeader(const int16_t api_key, const int16_t api_version, const int32_t correlation_id, + const NullableString& client_id) + : RequestHeader{api_key, api_version, correlation_id, client_id, TaggedFields{}} {}; + + RequestHeader(const int16_t api_key, const int16_t api_version, const int32_t correlation_id, + const NullableString& client_id, const TaggedFields& tagged_fields) + : api_key_{api_key}, api_version_{api_version}, correlation_id_{correlation_id}, + client_id_{client_id}, tagged_fields_{tagged_fields} {}; + + uint32_t computeSize(const EncodingContext& context) const { + uint32_t result{0}; + result += context.computeSize(api_key_); + result += context.computeSize(api_version_); + result += context.computeSize(correlation_id_); + result += context.computeSize(client_id_); + if (requestUsesTaggedFieldsInHeader(api_key_, api_version_)) { + result += context.computeCompactSize(tagged_fields_); + } + return result; + } + + uint32_t encode(Buffer::Instance& dst, EncodingContext& context) const { + uint32_t written{0}; + written += context.encode(api_key_, dst); + written += context.encode(api_version_, dst); + written += context.encode(correlation_id_, dst); + written += context.encode(client_id_, dst); + if (requestUsesTaggedFieldsInHeader(api_key_, api_version_)) { + written += context.encodeCompact(tagged_fields_, dst); + } + return written; + } bool operator==(const RequestHeader& rhs) const { return api_key_ == rhs.api_key_ && api_version_ == rhs.api_version_ && - correlation_id_ == rhs.correlation_id_ && client_id_ == rhs.client_id_; + correlation_id_ == rhs.correlation_id_ && client_id_ == rhs.client_id_ && + tagged_fields_ == rhs.tagged_fields_; }; }; @@ -95,10 +140,7 @@ template class Request : public AbstractRequest { const EncodingContext context{request_header_.api_version_}; uint32_t result{0}; // Compute size of header. - result += context.computeSize(request_header_.api_key_); - result += context.computeSize(request_header_.api_version_); - result += context.computeSize(request_header_.correlation_id_); - result += context.computeSize(request_header_.client_id_); + result += context.computeSize(request_header_); // Compute size of request data. result += context.computeSize(data_); return result; @@ -111,10 +153,7 @@ template class Request : public AbstractRequest { EncodingContext context{request_header_.api_version_}; uint32_t written{0}; // Encode request header. - written += context.encode(request_header_.api_key_, dst); - written += context.encode(request_header_.api_version_, dst); - written += context.encode(request_header_.correlation_id_, dst); - written += context.encode(request_header_.client_id_, dst); + written += context.encode(request_header_, dst); // Encode request-specific data. written += context.encode(data_, dst); return written; diff --git a/source/extensions/filters/network/kafka/kafka_request_parser.cc b/source/extensions/filters/network/kafka/kafka_request_parser.cc index 2c6be950f0..811c051182 100644 --- a/source/extensions/filters/network/kafka/kafka_request_parser.cc +++ b/source/extensions/filters/network/kafka/kafka_request_parser.cc @@ -20,6 +20,36 @@ RequestParseResponse RequestStartParser::parse(absl::string_view& data) { } } +uint32_t RequestHeaderDeserializer::feed(absl::string_view& data) { + uint32_t consumed = 0; + + consumed += common_part_deserializer_.feed(data); + if (common_part_deserializer_.ready()) { + const auto request_header = common_part_deserializer_.get(); + if (requestUsesTaggedFieldsInHeader(request_header.api_key_, request_header.api_version_)) { + tagged_fields_present_ = true; + consumed += tagged_fields_deserializer_.feed(data); + } + } + + return consumed; +} + +bool RequestHeaderDeserializer::ready() const { + // Header is only fully parsed after we have processed everything, including tagged fields (if + // they are present). + return common_part_deserializer_.ready() && + (tagged_fields_present_ ? tagged_fields_deserializer_.ready() : true); +} + +RequestHeader RequestHeaderDeserializer::get() const { + auto result = common_part_deserializer_.get(); + if (tagged_fields_present_) { + result.tagged_fields_ = tagged_fields_deserializer_.get(); + } + return result; +} + RequestParseResponse RequestHeaderParser::parse(absl::string_view& data) { context_->remaining_request_size_ -= deserializer_->feed(data); // One of the two needs must have happened when feeding finishes: diff --git a/source/extensions/filters/network/kafka/kafka_request_parser.h b/source/extensions/filters/network/kafka/kafka_request_parser.h index b588b9aff4..15d304b8d1 100644 --- a/source/extensions/filters/network/kafka/kafka_request_parser.h +++ b/source/extensions/filters/network/kafka/kafka_request_parser.h @@ -8,6 +8,7 @@ #include "extensions/filters/network/kafka/kafka_request.h" #include "extensions/filters/network/kafka/parser.h" +#include "extensions/filters/network/kafka/tagged_fields.h" namespace Envoy { namespace Extensions { @@ -22,8 +23,16 @@ using RequestParserSharedPtr = std::shared_ptr; * Context that is shared between parsers that are handling the same single message. */ struct RequestContext { + + /** + * Bytes left to consume. + */ uint32_t remaining_request_size_{0}; - RequestHeader request_header_{}; + + /** + * Request header that gets filled in during the parse. + */ + RequestHeader request_header_{-1, -1, -1, absl::nullopt}; /** * Bytes left to consume. @@ -91,10 +100,31 @@ class RequestStartParser : public RequestParser { * Can throw, as one of the fields (client-id) can throw (nullable string with invalid length). * @see http://kafka.apache.org/protocol.html#protocol_messages */ -class RequestHeaderDeserializer - : public CompositeDeserializerWith4Delegates {}; +class RequestHeaderDeserializer : public Deserializer, + private Logger::Loggable { + + // Request header, no matter what, has at least 4 fields. They are extracted here. + using CommonPartDeserializer = + CompositeDeserializerWith4Delegates; + +public: + RequestHeaderDeserializer() = default; + + uint32_t feed(absl::string_view& data) override; + bool ready() const override; + RequestHeader get() const override; + +private: + // Deserializer for the first 4 fields, that are present in every request header. + CommonPartDeserializer common_part_deserializer_; + + // Tagged fields are used only in request header v2. + // This flag will be set depending on common part's result (api key & version), and will decide + // whether we want to feed data to tagged fields deserializer. + bool tagged_fields_present_; + TaggedFieldsDeserializer tagged_fields_deserializer_; +}; using RequestHeaderDeserializerPtr = std::unique_ptr; diff --git a/source/extensions/filters/network/kafka/kafka_response.h b/source/extensions/filters/network/kafka/kafka_response.h index 8e6a8e5b35..e53ae70de0 100644 --- a/source/extensions/filters/network/kafka/kafka_response.h +++ b/source/extensions/filters/network/kafka/kafka_response.h @@ -2,28 +2,67 @@ #include "extensions/filters/network/kafka/external/serialization_composite.h" #include "extensions/filters/network/kafka/serialization.h" +#include "extensions/filters/network/kafka/tagged_fields.h" namespace Envoy { namespace Extensions { namespace NetworkFilters { namespace Kafka { +/** + * Decides if response with given api key & version should have tagged fields in header. + * Bear in mind, that ApiVersions responses DO NOT contain tagged fields in header (despite having + * flexible versions) as per + * https://github.com/apache/kafka/blob/2.4.0/clients/src/main/resources/common/message/ApiVersionsResponse.json#L24 + * This method gets implemented in generated code through 'kafka_response_resolver_cc.j2'. + * + * @param api_key Kafka request key. + * @param api_version Kafka request's version. + * @return Whether tagged fields should be used for this request. + */ +bool responseUsesTaggedFieldsInHeader(const uint16_t api_key, const uint16_t api_version); + /** * Represents Kafka response metadata: expected api key, version and correlation id. * @see http://kafka.apache.org/protocol.html#protocol_messages */ struct ResponseMetadata { ResponseMetadata(const int16_t api_key, const int16_t api_version, const int32_t correlation_id) - : api_key_{api_key}, api_version_{api_version}, correlation_id_{correlation_id} {}; + : ResponseMetadata{api_key, api_version, correlation_id, TaggedFields{}} {}; + + ResponseMetadata(const int16_t api_key, const int16_t api_version, const int32_t correlation_id, + const TaggedFields& tagged_fields) + : api_key_{api_key}, api_version_{api_version}, correlation_id_{correlation_id}, + tagged_fields_{tagged_fields} {}; + + uint32_t computeSize(const EncodingContext& context) const { + uint32_t result{0}; + result += context.computeSize(correlation_id_); + if (responseUsesTaggedFieldsInHeader(api_key_, api_version_)) { + result += context.computeCompactSize(tagged_fields_); + } + return result; + } + + uint32_t encode(Buffer::Instance& dst, EncodingContext& context) const { + uint32_t written{0}; + // Encode correlation id (api key / version are not present in responses). + written += context.encode(correlation_id_, dst); + if (responseUsesTaggedFieldsInHeader(api_key_, api_version_)) { + written += context.encodeCompact(tagged_fields_, dst); + } + return written; + } bool operator==(const ResponseMetadata& rhs) const { return api_key_ == rhs.api_key_ && api_version_ == rhs.api_version_ && - correlation_id_ == rhs.correlation_id_; + correlation_id_ == rhs.correlation_id_ && tagged_fields_ == rhs.tagged_fields_; }; const int16_t api_key_; const int16_t api_version_; const int32_t correlation_id_; + const TaggedFields tagged_fields_; }; using ResponseMetadataSharedPtr = std::shared_ptr; @@ -77,7 +116,12 @@ template class Response : public AbstractResponse { */ uint32_t computeSize() const override { const EncodingContext context{metadata_.api_version_}; - return context.computeSize(metadata_.correlation_id_) + context.computeSize(data_); + uint32_t result{0}; + // Compute size of header. + result += context.computeSize(metadata_); + // Compute size of response data. + result += context.computeSize(data_); + return result; } /** @@ -86,8 +130,8 @@ template class Response : public AbstractResponse { uint32_t encode(Buffer::Instance& dst) const override { EncodingContext context{metadata_.api_version_}; uint32_t written{0}; - // Encode correlation id (api key / version are not present in responses). - written += context.encode(metadata_.correlation_id_, dst); + // Encode response header. + written += context.encode(metadata_, dst); // Encode response-specific data. written += context.encode(data_, dst); return written; diff --git a/source/extensions/filters/network/kafka/kafka_response_parser.cc b/source/extensions/filters/network/kafka/kafka_response_parser.cc index fb17814464..3adbb1b287 100644 --- a/source/extensions/filters/network/kafka/kafka_response_parser.cc +++ b/source/extensions/filters/network/kafka/kafka_response_parser.cc @@ -22,16 +22,33 @@ ResponseParseResponse ResponseHeaderParser::parse(absl::string_view& data) { return ResponseParseResponse::stillWaiting(); } - context_->remaining_response_size_ = length_deserializer_.get(); - context_->remaining_response_size_ -= sizeof(context_->correlation_id_); - context_->correlation_id_ = correlation_id_deserializer_.get(); + if (!context_->api_info_set_) { + // We have consumed first two response header fields: payload length and correlation id. + context_->remaining_response_size_ = length_deserializer_.get(); + context_->remaining_response_size_ -= sizeof(context_->correlation_id_); + context_->correlation_id_ = correlation_id_deserializer_.get(); - const ExpectedResponseSpec spec = getResponseSpec(context_->correlation_id_); - context_->api_key_ = spec.first; - context_->api_version_ = spec.second; - // At this stage, we have setup the context - we know the response's api key & version, so we can - // safely create the payload parser. + // We have correlation id now, so we can see what is the expected response api key & version. + const ExpectedResponseSpec spec = getResponseSpec(context_->correlation_id_); + context_->api_key_ = spec.first; + context_->api_version_ = spec.second; + // Mark that version data has been set, so we do not attempt to re-initialize again. + context_->api_info_set_ = true; + } + + // Depending on response's api key & version, we might need to parse tagged fields element. + if (responseUsesTaggedFieldsInHeader(context_->api_key_, context_->api_version_)) { + context_->remaining_response_size_ -= tagged_fields_deserializer_.feed(data); + if (tagged_fields_deserializer_.ready()) { + context_->tagged_fields_ = tagged_fields_deserializer_.get(); + } else { + return ResponseParseResponse::stillWaiting(); + } + } + + // At this stage, we have fully setup the context - we know the response's api key & version, + // so we can safely create the payload parser. auto next_parser = parser_resolver_.createParser(context_); return ResponseParseResponse::nextParser(next_parser); } diff --git a/source/extensions/filters/network/kafka/kafka_response_parser.h b/source/extensions/filters/network/kafka/kafka_response_parser.h index 335da7f5d9..428511bac5 100644 --- a/source/extensions/filters/network/kafka/kafka_response_parser.h +++ b/source/extensions/filters/network/kafka/kafka_response_parser.h @@ -5,6 +5,7 @@ #include "extensions/filters/network/kafka/kafka_response.h" #include "extensions/filters/network/kafka/parser.h" +#include "extensions/filters/network/kafka/tagged_fields.h" namespace Envoy { namespace Extensions { @@ -20,6 +21,11 @@ using ResponseParserSharedPtr = std::shared_ptr; */ struct ResponseContext { + /** + * Whether the 'api_key_' & 'api_version_' fields have been initialized. + */ + bool api_info_set_ = false; + /** * Api key of response that's being parsed. */ @@ -40,6 +46,11 @@ struct ResponseContext { */ int32_t correlation_id_; + /** + * Response's tagged fields. + */ + TaggedFields tagged_fields_; + /** * Bytes left to consume. */ @@ -48,7 +59,9 @@ struct ResponseContext { /** * Returns data needed for construction of parse failure message. */ - const ResponseMetadata asFailureData() const { return {api_key_, api_version_, correlation_id_}; } + const ResponseMetadata asFailureData() const { + return {api_key_, api_version_, correlation_id_, tagged_fields_}; + } }; using ResponseContextSharedPtr = std::shared_ptr; @@ -119,6 +132,7 @@ class ResponseHeaderParser : public ResponseParser { Int32Deserializer length_deserializer_; Int32Deserializer correlation_id_deserializer_; + TaggedFieldsDeserializer tagged_fields_deserializer_; }; /** @@ -166,7 +180,7 @@ class ResponseDataParser : public ResponseParser { if (0 == context_->remaining_response_size_) { // After a successful parse, there should be nothing left - we have consumed all the bytes. const ResponseMetadata metadata = {context_->api_key_, context_->api_version_, - context_->correlation_id_}; + context_->correlation_id_, context_->tagged_fields_}; const AbstractResponseSharedPtr response = std::make_shared>(metadata, deserializer_.get()); return ResponseParseResponse::parsedMessage(response); diff --git a/source/extensions/filters/network/kafka/protocol/complex_type_template.j2 b/source/extensions/filters/network/kafka/protocol/complex_type_template.j2 index a605337779..744fd87498 100644 --- a/source/extensions/filters/network/kafka/protocol/complex_type_template.j2 +++ b/source/extensions/filters/network/kafka/protocol/complex_type_template.j2 @@ -25,38 +25,40 @@ struct {{ complex_type.name }} { {{ constructor['full_declaration'] }}{% endfor %} {# For every field that's used in version, just compute its size using an encoder. #} - {% if complex_type.fields|length > 0 %} uint32_t computeSize(const EncodingContext& encoder) const { const int16_t api_version = encoder.apiVersion(); - uint32_t written{0};{% for field in complex_type.fields %} - if (api_version >= {{ field.version_usage[0] }} - && api_version < {{ field.version_usage[-1] + 1 }}) { - written += encoder.computeSize({{ field.name }}_); - }{% endfor %} + uint32_t written{0}; + + {% for spec in complex_type.compute_serialization_specs() %} + if (api_version >= {{ spec.versions[0] }} && api_version < {{ spec.versions[-1] + 1 }}) { + written += encoder.{{ spec.compute_size_method_name }}({{ spec.field.name }}_); + } + {% endfor %} + return written; } - {% else %} - uint32_t computeSize(const EncodingContext&) const { - return 0; + + uint32_t computeCompactSize(const EncodingContext& encoder) const { + return computeSize(encoder); } - {% endif %} {# For every field that's used in version, just serialize it. #} - {% if complex_type.fields|length > 0 %} uint32_t encode(Buffer::Instance& dst, EncodingContext& encoder) const { const int16_t api_version = encoder.apiVersion(); - uint32_t written{0};{% for field in complex_type.fields %} - if (api_version >= {{ field.version_usage[0] }} - && api_version < {{ field.version_usage[-1] + 1 }}) { - written += encoder.encode({{ field.name }}_, dst); - }{% endfor %} + uint32_t written{0}; + + {% for spec in complex_type.compute_serialization_specs() %} + if (api_version >= {{ spec.versions[0] }} && api_version < {{ spec.versions[-1] + 1 }}) { + written += encoder.{{ spec.encode_method_name }}({{ spec.field.name }}_, dst); + } + {% endfor %} + return written; } - {% else %} - uint32_t encode(Buffer::Instance&, EncodingContext&) const { - return 0; + + uint32_t encodeCompact(Buffer::Instance& dst, EncodingContext& encoder) const { + return encode(dst, encoder); } - {% endif %} {% if complex_type.fields|length > 0 %} bool operator==(const {{ complex_type.name }}& rhs) const { @@ -77,7 +79,7 @@ class {{ complex_type.name }}V{{ field_list.version }}Deserializer: public CompositeDeserializerWith{{ field_list.field_count() }}Delegates< {{ complex_type.name }} {% for field in field_list.used_fields() %}, - {{ field.deserializer_name_in_version(field_list.version) }} + {{ field.deserializer_name_in_version(field_list.version, field_list.uses_compact_fields) }} {% endfor %}>{}; {% endfor %} diff --git a/source/extensions/filters/network/kafka/protocol/generator.py b/source/extensions/filters/network/kafka/protocol/generator.py index c683821b0f..87cd7b1fe8 100755 --- a/source/extensions/filters/network/kafka/protocol/generator.py +++ b/source/extensions/filters/network/kafka/protocol/generator.py @@ -26,7 +26,8 @@ def generate_main_code(type, main_header_file, resolver_cc_file, metrics_header_ for message in messages: # For each child structure that is used by request/response, render its matching C++ code. - for dependency in message.declaration_chain: + dependencies = message.compute_declaration_chain() + for dependency in dependencies: main_header_contents += complex_type_template.render(complex_type=dependency) # Each top-level structure (e.g. FetchRequest/FetchResponse) needs corresponding parsers. main_header_contents += parsers_template.render(complex_type=message) @@ -101,6 +102,8 @@ def __init__(self): self.known_types = set() # Name of parent message type that's being processed right now. self.currently_processed_message_type = None + # Common structs declared in this message type. + self.common_structs = {} def parse_messages(self, input_files): """ @@ -114,12 +117,17 @@ def parse_messages(self, input_files): input_files.sort() # For each specification file, remove comments, and parse the remains. for input_file in input_files: - with open(input_file, 'r') as fd: - raw_contents = fd.read() - without_comments = re.sub(r'//.*\n', '', raw_contents) - message_spec = json.loads(without_comments) - message = self.parse_top_level_element(message_spec) - messages.append(message) + try: + with open(input_file, 'r') as fd: + raw_contents = fd.read() + without_comments = re.sub(r'\s*//.*\n', '\n', raw_contents) + without_empty_newlines = re.sub(r'^\s*$', '', without_comments, flags=re.MULTILINE) + message_spec = json.loads(without_empty_newlines) + message = self.parse_top_level_element(message_spec) + messages.append(message) + except Exception as e: + print('could not process %s' % input_file) + raise # Sort messages by api_key. messages.sort(key=lambda x: x.get_extra('api_key')) @@ -132,33 +140,75 @@ def parse_top_level_element(self, spec): named fields, compared to sub-structures in a message. """ self.currently_processed_message_type = spec['name'] + + # Figure out all versions of this message type. versions = Statics.parse_version_string(spec['validVersions'], 2 << 16 - 1) - complex_type = self.parse_complex_type(self.currently_processed_message_type, spec, versions) - # Request / response types need to carry api key version. - return complex_type.with_extra('api_key', spec['apiKey']) + + # Figure out the flexible versions. + flexible_versions_string = spec.get('flexibleVersions', 'none') + if 'none' != flexible_versions_string: + flexible_versions = Statics.parse_version_string(flexible_versions_string, versions[-1]) + else: + flexible_versions = [] + + # Sanity check - all flexible versions need to be versioned. + if [x for x in flexible_versions if x not in versions]: + raise ValueError('invalid flexible versions') + + try: + # In 2.4 some types are declared at top level, and only referenced inside. + # So let's parse them and store them in state. + common_structs = spec.get('commonStructs') + if common_structs is not None: + for common_struct in common_structs: + common_struct_name = common_struct['name'] + common_struct_versions = Statics.parse_version_string(common_struct['versions'], + versions[-1]) + parsed_complex = self.parse_complex_type(common_struct_name, common_struct, + common_struct_versions) + self.common_structs[parsed_complex.name] = parsed_complex + + # Parse the type itself. + complex_type = self.parse_complex_type(self.currently_processed_message_type, spec, versions) + complex_type.register_flexible_versions(flexible_versions) + + # Request / response types need to carry api key version. + result = complex_type.with_extra('api_key', spec['apiKey']) + return result + + finally: + self.common_structs = {} + self.currently_processed_message_type = None def parse_complex_type(self, type_name, field_spec, versions): """ Parse given complex type, returning a structure that holds its name, field specification and allowed versions. """ - fields = [] - for child_field in field_spec['fields']: - child = self.parse_field(child_field, versions[-1]) - fields.append(child) - - # Some of the types repeat multiple times (e.g. AlterableConfig). - # In such a case, every second or later occurrence of the same name is going to be prefixed - # with parent type, e.g. we have AlterableConfig (for AlterConfigsRequest) and then - # IncrementalAlterConfigsRequestAlterableConfig (for IncrementalAlterConfigsRequest). - # This keeps names unique, while keeping non-duplicate ones short. - if type_name not in self.known_types: - self.known_types.add(type_name) - else: - type_name = self.currently_processed_message_type + type_name - self.known_types.add(type_name) + fields_el = field_spec.get('fields') + + if fields_el is not None: + fields = [] + for child_field in field_spec['fields']: + child = self.parse_field(child_field, versions[-1]) + if child is not None: + fields.append(child) + + # Some of the types repeat multiple times (e.g. AlterableConfig). + # In such a case, every second or later occurrence of the same name is going to be prefixed + # with parent type, e.g. we have AlterableConfig (for AlterConfigsRequest) and then + # IncrementalAlterConfigsRequestAlterableConfig (for IncrementalAlterConfigsRequest). + # This keeps names unique, while keeping non-duplicate ones short. + if type_name not in self.known_types: + self.known_types.add(type_name) + else: + type_name = self.currently_processed_message_type + type_name + self.known_types.add(type_name) - return Complex(type_name, fields, versions) + return Complex(type_name, fields, versions) + + else: + return self.common_structs[type_name] def parse_field(self, field_spec, highest_possible_version): """ @@ -166,6 +216,9 @@ def parse_field(self, field_spec, highest_possible_version): actually used (nullable or not). Obviously, field cannot be used in version higher than its type's usage. """ + if field_spec.get('tag') is not None: + return None + version_usage = Statics.parse_version_string(field_spec['versions'], highest_possible_version) version_usage_as_nullable = Statics.parse_version_string( field_spec['nullableVersions'], @@ -183,7 +236,7 @@ def parse_type(self, type_name, field_spec, highest_possible_version): underlying_type = self.parse_type(type_name[2:], field_spec, highest_possible_version) return Array(underlying_type) else: - if (type_name in Primitive.PRIMITIVE_TYPE_NAMES): + if (type_name in Primitive.USABLE_PRIMITIVE_TYPE_NAMES): return Primitive(type_name, field_spec.get('default')) else: versions = Statics.parse_version_string(field_spec['versions'], highest_possible_version) @@ -211,11 +264,12 @@ def parse_version_string(raw_versions, highest_possible_version): class FieldList: """ List of fields used by given entity (request or child structure) in given message version - (as fields get added or removed across versions). + (as fields get added or removed across versions and/or they change compaction level). """ - def __init__(self, version, fields): + def __init__(self, version, uses_compact_fields, fields): self.version = version + self.uses_compact_fields = uses_compact_fields self.fields = fields def used_fields(self): @@ -327,11 +381,11 @@ def example_value_for_test(self, version): else: return str(self.type.example_value_for_test(version)) - def deserializer_name_in_version(self, version): + def deserializer_name_in_version(self, version, compact): if self.is_nullable_in_version(version): - return 'Nullable%s' % self.type.deserializer_name_in_version(version) + return 'Nullable%s' % self.type.deserializer_name_in_version(version, compact) else: - return self.type.deserializer_name_in_version(version) + return self.type.deserializer_name_in_version(version, compact) def is_printable(self): return self.type.is_printable() @@ -339,7 +393,13 @@ def is_printable(self): class TypeSpecification: - def deserializer_name_in_version(self, version): + def compute_declaration_chain(self): + """ + Computes types that need to be declared before this type can be declared, in C++ sense. + """ + raise NotImplementedError() + + def deserializer_name_in_version(self, version, compact): """ Renders the deserializer name of given type, in message with given version. """ @@ -351,6 +411,12 @@ def default_value(self): """ raise NotImplementedError() + def has_flexible_handling(self): + """ + Whether the given type has special encoding when carrying message is using flexible encoding. + """ + raise NotImplementedError() + def example_value_for_test(self, version): raise NotImplementedError() @@ -367,19 +433,26 @@ class Array(TypeSpecification): def __init__(self, underlying): self.underlying = underlying - self.declaration_chain = self.underlying.declaration_chain @property def name(self): return 'std::vector<%s>' % self.underlying.name - def deserializer_name_in_version(self, version): - return 'ArrayDeserializer<%s, %s>' % (self.underlying.name, - self.underlying.deserializer_name_in_version(version)) + def compute_declaration_chain(self): + # To use an array of type T, we just need to be capable of using type T. + return self.underlying.compute_declaration_chain() + + def deserializer_name_in_version(self, version, compact): + return '%sArrayDeserializer<%s, %s>' % ("Compact" if compact else "", self.underlying.name, + self.underlying.deserializer_name_in_version( + version, compact)) def default_value(self): return 'std::vector<%s>{}' % (self.underlying.name) + def has_flexible_handling(self): + return True + def example_value_for_test(self, version): return 'std::vector<%s>{ %s }' % (self.underlying.name, self.underlying.example_value_for_test(version)) @@ -393,7 +466,7 @@ class Primitive(TypeSpecification): Represents a Kafka primitive value. """ - PRIMITIVE_TYPE_NAMES = ['bool', 'int8', 'int16', 'int32', 'int64', 'string', 'bytes'] + USABLE_PRIMITIVE_TYPE_NAMES = ['bool', 'int8', 'int16', 'int32', 'int64', 'string', 'bytes'] KAFKA_TYPE_TO_ENVOY_TYPE = { 'string': 'std::string', @@ -403,6 +476,7 @@ class Primitive(TypeSpecification): 'int32': 'int32_t', 'int64': 'int64_t', 'bytes': 'Bytes', + 'tagged_fields': 'TaggedFields', } KAFKA_TYPE_TO_DESERIALIZER = { @@ -413,6 +487,12 @@ class Primitive(TypeSpecification): 'int32': 'Int32Deserializer', 'int64': 'Int64Deserializer', 'bytes': 'BytesDeserializer', + 'tagged_fields': 'TaggedFieldsDeserializer', + } + + KAFKA_TYPE_TO_COMPACT_DESERIALIZER = { + 'string': 'CompactStringDeserializer', + 'bytes': 'CompactBytesDeserializer' } # See https://github.com/apache/kafka/tree/trunk/clients/src/main/resources/common/message#deserializing-messages @@ -424,25 +504,33 @@ class Primitive(TypeSpecification): 'int32': '0', 'int64': '0', 'bytes': '{}', + 'tagged_fields': 'TaggedFields({})', } # Custom values that make test code more readable. KAFKA_TYPE_TO_EXAMPLE_VALUE_FOR_TEST = { - 'string': '"string"', - 'bool': 'false', - 'int8': 'static_cast(8)', - 'int16': 'static_cast(16)', - 'int32': 'static_cast(32)', - 'int64': 'static_cast(64)', - 'bytes': 'Bytes({0, 1, 2, 3})', + 'string': + '"string"', + 'bool': + 'false', + 'int8': + 'static_cast(8)', + 'int16': + 'static_cast(16)', + 'int32': + 'static_cast(32)', + 'int64': + 'static_cast(64)', + 'bytes': + 'Bytes({0, 1, 2, 3})', + 'tagged_fields': + 'TaggedFields{std::vector{{10, Bytes({1, 2, 3})}, {20, Bytes({4, 5, 6})}}}', } def __init__(self, name, custom_default_value): self.original_name = name self.name = Primitive.compute(name, Primitive.KAFKA_TYPE_TO_ENVOY_TYPE) self.custom_default_value = custom_default_value - self.declaration_chain = [] - self.deserializer_name = Primitive.compute(name, Primitive.KAFKA_TYPE_TO_DESERIALIZER) @staticmethod def compute(name, map): @@ -451,8 +539,15 @@ def compute(name, map): else: raise ValueError(name) - def deserializer_name_in_version(self, version): - return self.deserializer_name + def compute_declaration_chain(self): + # Primitives need no declarations. + return [] + + def deserializer_name_in_version(self, version, compact): + if compact and self.original_name in Primitive.KAFKA_TYPE_TO_COMPACT_DESERIALIZER.keys(): + return Primitive.compute(self.original_name, Primitive.KAFKA_TYPE_TO_COMPACT_DESERIALIZER) + else: + return Primitive.compute(self.original_name, Primitive.KAFKA_TYPE_TO_DESERIALIZER) def default_value(self): if self.custom_default_value is not None: @@ -460,6 +555,9 @@ def default_value(self): else: return Primitive.compute(self.original_name, Primitive.KAFKA_TYPE_TO_DEFAULT_VALUE) + def has_flexible_handling(self): + return self.original_name in ['string', 'bytes', 'tagged_fields'] + def example_value_for_test(self, version): return Primitive.compute(self.original_name, Primitive.KAFKA_TYPE_TO_EXAMPLE_VALUE_FOR_TEST) @@ -467,6 +565,15 @@ def is_printable(self): return self.name not in ['Bytes'] +class FieldSerializationSpec(): + + def __init__(self, field, versions, compute_size_method_name, encode_method_name): + self.field = field + self.versions = versions + self.compute_size_method_name = compute_size_method_name + self.encode_method_name = encode_method_name + + class Complex(TypeSpecification): """ Represents a complex type (multiple types aggregated into one). @@ -477,17 +584,30 @@ def __init__(self, name, fields, versions): self.name = name self.fields = fields self.versions = versions - self.declaration_chain = self.__compute_declaration_chain() + self.flexible_versions = None # Will be set in 'register_flexible_versions'. self.attributes = {} - def __compute_declaration_chain(self): + def register_flexible_versions(self, flexible_versions): + # If flexible versions are present, so we need to add placeholder 'tagged_fields' field to + # *every* type that's used in by this message type. + for type in self.compute_declaration_chain(): + type.flexible_versions = flexible_versions + if len(flexible_versions) > 0: + tagged_fields_field = FieldSpec('tagged_fields', Primitive('tagged_fields', None), + flexible_versions, []) + type.fields.append(tagged_fields_field) + + def compute_declaration_chain(self): """ Computes all dependencies, what means all non-primitive types used by this type. They need to be declared before this struct is declared. """ result = [] for field in self.fields: - result.extend(field.type.declaration_chain) + field_dependencies = field.type.compute_declaration_chain() + for field_dependency in field_dependencies: + if field_dependency not in result: + result.append(field_dependency) result.append(self) return result @@ -528,11 +648,26 @@ def compute_field_lists(self): """ field_lists = [] for version in self.versions: - field_list = FieldList(version, self.fields) + field_list = FieldList(version, version in self.flexible_versions, self.fields) field_lists.append(field_list) return field_lists - def deserializer_name_in_version(self, version): + def compute_serialization_specs(self): + result = [] + for field in self.fields: + if field.type.has_flexible_handling(): + flexible = [x for x in field.version_usage if x in self.flexible_versions] + non_flexible = [x for x in field.version_usage if x not in flexible] + if non_flexible: + result.append(FieldSerializationSpec(field, non_flexible, 'computeSize', 'encode')) + if flexible: + result.append( + FieldSerializationSpec(field, flexible, 'computeCompactSize', 'encodeCompact')) + else: + result.append(FieldSerializationSpec(field, field.version_usage, 'computeSize', 'encode')) + return result + + def deserializer_name_in_version(self, version, compact): return '%sV%dDeserializer' % (self.name, version) def name_in_c_case(self): @@ -543,6 +678,9 @@ def name_in_c_case(self): def default_value(self): raise NotImplementedError('unable to create default value of complex type') + def has_flexible_handling(self): + return False + def example_value_for_test(self, version): field_list = next(fl for fl in self.compute_field_lists() if fl.version == version) example_values = map(lambda x: x.example_value_for_test(version), field_list.used_fields()) diff --git a/source/extensions/filters/network/kafka/protocol/kafka_request_resolver_cc.j2 b/source/extensions/filters/network/kafka/protocol/kafka_request_resolver_cc.j2 index e754248fc1..d82c23864f 100644 --- a/source/extensions/filters/network/kafka/protocol/kafka_request_resolver_cc.j2 +++ b/source/extensions/filters/network/kafka/protocol/kafka_request_resolver_cc.j2 @@ -12,6 +12,25 @@ namespace Extensions { namespace NetworkFilters { namespace Kafka { +// Implements declaration from 'kafka_request.h'. +bool requestUsesTaggedFieldsInHeader(const uint16_t api_key, const uint16_t api_version) { + switch (api_key) { + {% for message_type in message_types %} + case {{ message_type.get_extra('api_key') }}: + switch (api_version) { + {% for flexible_version in message_type.flexible_versions %} + case {{ flexible_version }}: + return true; + {% endfor %} + default: + return false; + } + {% endfor %} + default: + return false; + } +} + /** * Creates a parser that corresponds to provided key and version. * If corresponding parser cannot be found (what means a newer version of Kafka protocol), diff --git a/source/extensions/filters/network/kafka/protocol/kafka_response_resolver_cc.j2 b/source/extensions/filters/network/kafka/protocol/kafka_response_resolver_cc.j2 index bc107a18dd..b89df698a5 100644 --- a/source/extensions/filters/network/kafka/protocol/kafka_response_resolver_cc.j2 +++ b/source/extensions/filters/network/kafka/protocol/kafka_response_resolver_cc.j2 @@ -11,6 +11,28 @@ namespace Extensions { namespace NetworkFilters { namespace Kafka { +// Implements declaration from 'kafka_response.h'. +bool responseUsesTaggedFieldsInHeader(const uint16_t api_key, const uint16_t api_version) { + switch (api_key) { + {% for message_type in message_types %} + case {{ message_type.get_extra('api_key') }}: + switch (api_version) { + {# ApiVersions responses require special handling. #} + {% if message_type.get_extra('api_key') != 18 %} + {% for flexible_version in message_type.flexible_versions %} + case {{ flexible_version }}: + return true; + {% endfor %} + {% endif %} + default: + return false; + } + {% endfor %} + default: + return false; + } +} + /** * Creates a parser that is going to process data specific for given response. * If corresponding parser cannot be found (what means a newer version of Kafka protocol), diff --git a/source/extensions/filters/network/kafka/serialization/generator.py b/source/extensions/filters/network/kafka/serialization/generator.py index 857f39c0ee..a05012e483 100755 --- a/source/extensions/filters/network/kafka/serialization/generator.py +++ b/source/extensions/filters/network/kafka/serialization/generator.py @@ -37,7 +37,7 @@ def get_field_counts(): """ Generate argument counts that should be processed by composite deserializers. """ - return range(1, 11) + return range(1, 12) class RenderingHelper: diff --git a/source/extensions/filters/network/kafka/tagged_fields.h b/source/extensions/filters/network/kafka/tagged_fields.h index cda6a7162e..7e60952c03 100644 --- a/source/extensions/filters/network/kafka/tagged_fields.h +++ b/source/extensions/filters/network/kafka/tagged_fields.h @@ -79,7 +79,7 @@ class TaggedFieldDeserializer : public Deserializer { ready_ = true; } - return consumed; + return consumed + data_consumed; }; bool ready() const override { return ready_; }; @@ -100,7 +100,7 @@ class TaggedFieldDeserializer : public Deserializer { */ struct TaggedFields { - const std::vector fields_; + std::vector fields_; uint32_t computeCompactSize(const EncodingContext& encoder) const { uint32_t result{0}; diff --git a/test/extensions/filters/network/kafka/BUILD b/test/extensions/filters/network/kafka/BUILD index cf59d94584..da6612efa7 100644 --- a/test/extensions/filters/network/kafka/BUILD +++ b/test/extensions/filters/network/kafka/BUILD @@ -39,6 +39,7 @@ envoy_extension_cc_test( deps = [ ":serialization_utilities_lib", "//source/extensions/filters/network/kafka:serialization_lib", + "//source/extensions/filters/network/kafka:tagged_fields_lib", "//test/mocks/server:server_mocks", ], ) diff --git a/test/extensions/filters/network/kafka/broker/integration_test/zookeeper_properties.j2 b/test/extensions/filters/network/kafka/broker/integration_test/zookeeper_properties.j2 index 5a563d1f4d..be524bea34 100644 --- a/test/extensions/filters/network/kafka/broker/integration_test/zookeeper_properties.j2 +++ b/test/extensions/filters/network/kafka/broker/integration_test/zookeeper_properties.j2 @@ -1,3 +1,5 @@ clientPort={{ data['zk_port'] }} dataDir={{ data['data_dir'] }} maxClientCnxns=0 +# ZK 3.5 tries to bind 8080 for introspection capacility - we do not need that. +admin.enableServer=false diff --git a/test/extensions/filters/network/kafka/kafka_request_parser_test.cc b/test/extensions/filters/network/kafka/kafka_request_parser_test.cc index e9c72ad3e9..7125e50750 100644 --- a/test/extensions/filters/network/kafka/kafka_request_parser_test.cc +++ b/test/extensions/filters/network/kafka/kafka_request_parser_test.cc @@ -112,7 +112,7 @@ TEST_F(KafkaRequestParserTest, RequestDataParserShouldHandleDeserializerExceptio int32_t get() const override { throw std::runtime_error("should not be invoked at all"); }; }; - RequestContextSharedPtr request_context{new RequestContext{1024, {}}}; + RequestContextSharedPtr request_context{new RequestContext{1024, {0, 0, 0, absl::nullopt}}}; RequestDataParser testee{request_context}; absl::string_view data = putGarbageIntoBuffer(); @@ -146,7 +146,8 @@ TEST_F(KafkaRequestParserTest, RequestDataParserShouldHandleDeserializerReturningReadyButLeavingData) { // given const int32_t request_size = 1024; // There are still 1024 bytes to read to complete the request. - RequestContextSharedPtr request_context{new RequestContext{request_size, {}}}; + RequestContextSharedPtr request_context{ + new RequestContext{request_size, {0, 0, 0, absl::nullopt}}}; RequestDataParser testee{request_context}; diff --git a/test/extensions/filters/network/kafka/protocol/request_codec_request_test_cc.j2 b/test/extensions/filters/network/kafka/protocol/request_codec_request_test_cc.j2 index c4f872e253..744fe0ac9e 100644 --- a/test/extensions/filters/network/kafka/protocol/request_codec_request_test_cc.j2 +++ b/test/extensions/filters/network/kafka/protocol/request_codec_request_test_cc.j2 @@ -42,8 +42,18 @@ TEST_F(RequestCodecRequestTest, shouldHandle{{ message_type.name }}Messages) { {% for field_list in message_type.compute_field_lists() %} for (int i = 0; i < 100; ++i ) { - const RequestHeader header = - { {{ message_type.get_extra('api_key') }}, {{ field_list.version }}, correlation++, "id" }; + {# Request header cannot contain tagged fields if request does not support them. #} + const TaggedFields tagged_fields = requestUsesTaggedFieldsInHeader( + {{ message_type.get_extra('api_key') }}, {{ field_list.version }}) ? + TaggedFields{ { TaggedField{ 10, Bytes{1, 2, 3, 4} } } }: + TaggedFields({}); + const RequestHeader header = { + {{ message_type.get_extra('api_key') }}, + {{ field_list.version }}, + correlation++, + "id", + tagged_fields + }; const {{ message_type.name }} data = { {{ field_list.example_value() }} }; const RequestUnderTest request = {header, data}; putMessageIntoBuffer(request); @@ -64,6 +74,7 @@ TEST_F(RequestCodecRequestTest, shouldHandle{{ message_type.name }}Messages) { // then const std::vector& received = callback->getCapturedMessages(); ASSERT_EQ(received.size(), sent.size()); + ASSERT_EQ(received.size(), correlation); for (size_t i = 0; i < received.size(); ++i) { const std::shared_ptr request = diff --git a/test/extensions/filters/network/kafka/protocol/response_codec_response_test_cc.j2 b/test/extensions/filters/network/kafka/protocol/response_codec_response_test_cc.j2 index 87b977f64e..c85b9d5044 100644 --- a/test/extensions/filters/network/kafka/protocol/response_codec_response_test_cc.j2 +++ b/test/extensions/filters/network/kafka/protocol/response_codec_response_test_cc.j2 @@ -45,8 +45,17 @@ TEST_F(ResponseCodecResponseTest, shouldHandle{{ message_type.name }}Messages) { {% for field_list in message_type.compute_field_lists() %} for (int i = 0; i < 100; ++i ) { - const ResponseMetadata metadata = - { {{ message_type.get_extra('api_key') }}, {{ field_list.version }}, ++correlation_id }; + {# Response header cannot contain tagged fields if response does not support them. #} + const TaggedFields tagged_fields = responseUsesTaggedFieldsInHeader( + {{ message_type.get_extra('api_key') }}, {{ field_list.version }}) ? + TaggedFields{ { TaggedField{ 10, Bytes{1, 2, 3, 4} } } }: + TaggedFields({}); + const ResponseMetadata metadata = { + {{ message_type.get_extra('api_key') }}, + {{ field_list.version }}, + ++correlation_id, + tagged_fields, + }; const {{ message_type.name }} data = { {{ field_list.example_value() }} }; const ResponseUnderTest response = {metadata, data}; putMessageIntoBuffer(response); @@ -62,6 +71,7 @@ TEST_F(ResponseCodecResponseTest, shouldHandle{{ message_type.name }}Messages) { // then const std::vector& received = callback->getCapturedMessages(); ASSERT_EQ(received.size(), sent.size()); + ASSERT_EQ(received.size(), correlation_id); for (size_t i = 0; i < received.size(); ++i) { const std::shared_ptr response = diff --git a/test/extensions/filters/network/kafka/request_codec_unit_test.cc b/test/extensions/filters/network/kafka/request_codec_unit_test.cc index c1f6e94ed7..edbeb57c47 100644 --- a/test/extensions/filters/network/kafka/request_codec_unit_test.cc +++ b/test/extensions/filters/network/kafka/request_codec_unit_test.cc @@ -139,7 +139,7 @@ TEST_F(RequestCodecUnitTest, shouldPassParsedMessageToCallbackAndInitializeNextP putGarbageIntoBuffer(); const AbstractRequestSharedPtr parsed_message = - std::make_shared>(RequestHeader(), 0); + std::make_shared>(RequestHeader{0, 0, 0, absl::nullopt}, 0); MockParserSharedPtr parser1 = std::make_shared(); EXPECT_CALL(*parser1, parse(_)) @@ -170,7 +170,7 @@ TEST_F(RequestCodecUnitTest, shouldPassParseFailureDataToCallback) { putGarbageIntoBuffer(); const RequestParseFailureSharedPtr failure_data = - std::make_shared(RequestHeader()); + std::make_shared(RequestHeader{0, 0, 0, absl::nullopt}); MockParserSharedPtr parser = std::make_shared(); auto consume_and_return = [&failure_data](absl::string_view& data) -> RequestParseResponse { diff --git a/test/extensions/filters/network/kafka/serialization_test.cc b/test/extensions/filters/network/kafka/serialization_test.cc index 250d35121f..903a66470c 100644 --- a/test/extensions/filters/network/kafka/serialization_test.cc +++ b/test/extensions/filters/network/kafka/serialization_test.cc @@ -1,3 +1,5 @@ +#include "extensions/filters/network/kafka/tagged_fields.h" + #include "test/extensions/filters/network/kafka/serialization_utilities.h" namespace Envoy { @@ -434,6 +436,23 @@ TEST(NullableCompactArrayDeserializer, ShouldConsumeNullArray) { NullableCompactArrayDeserializer>(value); } +// Tagged fields. + +TEST(TaggedFieldDeserializer, ShouldConsumeCorrectAmountOfData) { + const TaggedField value{200, Bytes{1, 2, 3, 4, 5, 6}}; + serializeCompactThenDeserializeAndCheckEquality(value); +} + +TEST(TaggedFieldsDeserializer, ShouldConsumeCorrectAmountOfData) { + std::vector fields; + for (uint32_t i = 0; i < 200; ++i) { + const TaggedField tagged_field = {i, Bytes{1, 2, 3, 4}}; + fields.push_back(tagged_field); + } + const TaggedFields value{fields}; + serializeCompactThenDeserializeAndCheckEquality(value); +} + } // namespace SerializationTest } // namespace Kafka } // namespace NetworkFilters From d7f2034b923c45c8ce7669c49ae74346752e439e Mon Sep 17 00:00:00 2001 From: asraa Date: Fri, 14 Feb 2020 14:49:36 -0500 Subject: [PATCH 60/87] [utility] redundant case insensitive comparisons (#10068) Signed-off-by: Asra Ali --- source/common/common/utility.cc | 15 +++++---------- source/common/common/utility.h | 14 -------------- .../extensions/filters/http/gzip/gzip_filter.cc | 11 +++++------ test/common/common/utility_fuzz_test.cc | 5 ----- test/common/common/utility_test.cc | 7 ------- 5 files changed, 10 insertions(+), 42 deletions(-) diff --git a/source/common/common/utility.cc b/source/common/common/utility.cc index 072825cfb9..55177cb650 100644 --- a/source/common/common/utility.cc +++ b/source/common/common/utility.cc @@ -294,21 +294,16 @@ bool StringUtil::caseFindToken(absl::string_view source, absl::string_view delim std::function predicate; if (trim_whitespace) { - predicate = [&](absl::string_view token) { return caseCompare(key_token, trim(token)); }; + predicate = [&](absl::string_view token) { + return absl::EqualsIgnoreCase(key_token, trim(token)); + }; } else { - predicate = [&](absl::string_view token) { return caseCompare(key_token, token); }; + predicate = [&](absl::string_view token) { return absl::EqualsIgnoreCase(key_token, token); }; } return std::find_if(tokens.begin(), tokens.end(), predicate) != tokens.end(); } -bool StringUtil::caseCompare(absl::string_view lhs, absl::string_view rhs) { - if (rhs.size() != lhs.size()) { - return false; - } - return absl::StartsWithIgnoreCase(rhs, lhs); -} - absl::string_view StringUtil::cropRight(absl::string_view source, absl::string_view delimiter) { const absl::string_view::size_type pos = source.find(delimiter); if (pos != absl::string_view::npos) { @@ -460,7 +455,7 @@ std::string StringUtil::toLower(absl::string_view s) { bool StringUtil::CaseInsensitiveCompare::operator()(absl::string_view lhs, absl::string_view rhs) const { - return StringUtil::caseCompare(lhs, rhs); + return absl::EqualsIgnoreCase(lhs, rhs); } uint64_t StringUtil::CaseInsensitiveHash::operator()(absl::string_view key) const { diff --git a/source/common/common/utility.h b/source/common/common/utility.h index 488d0c7e50..5c2f6847f4 100644 --- a/source/common/common/utility.h +++ b/source/common/common/utility.h @@ -267,20 +267,6 @@ class StringUtil { static bool caseFindToken(absl::string_view source, absl::string_view delimiters, absl::string_view key_token, bool trim_whitespace = true); - /** - * Compare one string view with another string view ignoring case sensitivity. - * @param lhs supplies the first string view. - * @param rhs supplies the second string view. - * @return true if strings are semantically the same and false otherwise. - * - * E.g., - * - * caseCompare("hello", "hello") . true - * caseCompare("hello", "HELLO") . true - * caseCompare("hello", "HellO") . true - */ - static bool caseCompare(absl::string_view lhs, absl::string_view rhs); - /** * Crop characters from a string view starting at the first character of the matched * delimiter string view until the end of the source string view. diff --git a/source/extensions/filters/http/gzip/gzip_filter.cc b/source/extensions/filters/http/gzip/gzip_filter.cc index d9db61b791..a6a6d4a503 100644 --- a/source/extensions/filters/http/gzip/gzip_filter.cc +++ b/source/extensions/filters/http/gzip/gzip_filter.cc @@ -178,7 +178,7 @@ bool GzipFilter::isAcceptEncodingAllowed(Http::HeaderMap& headers) const { const auto q_value = StringUtil::trim(StringUtil::cropLeft(token, ";")); // If value is the gzip coding, check the qvalue and return. if (value == Http::Headers::get().AcceptEncodingValues.Gzip) { - const bool is_gzip = !StringUtil::caseCompare(q_value, ZeroQvalueString); + const bool is_gzip = !absl::EqualsIgnoreCase(q_value, ZeroQvalueString); if (is_gzip) { config_->stats().header_gzip_.inc(); return true; @@ -198,7 +198,7 @@ bool GzipFilter::isAcceptEncodingAllowed(Http::HeaderMap& headers) const { // identity is weighted higher. Note that this filter disregards // order/priority at this time. if (value == Http::Headers::get().AcceptEncodingValues.Wildcard) { - is_wildcard = !StringUtil::caseCompare(q_value, ZeroQvalueString); + is_wildcard = !absl::EqualsIgnoreCase(q_value, ZeroQvalueString); } } // If neither identity nor gzip codings are present, return the result of the wildcard. @@ -260,10 +260,9 @@ bool GzipFilter::isTransferEncodingAllowed(Http::HeaderMap& headers) const { // computed twice. Find all other sites where this can be improved. StringUtil::splitToken(transfer_encoding->value().getStringView(), ",", true)) { const auto trimmed_value = StringUtil::trim(header_value); - if (StringUtil::caseCompare(trimmed_value, - Http::Headers::get().TransferEncodingValues.Gzip) || - StringUtil::caseCompare(trimmed_value, - Http::Headers::get().TransferEncodingValues.Deflate)) { + if (absl::EqualsIgnoreCase(trimmed_value, Http::Headers::get().TransferEncodingValues.Gzip) || + absl::EqualsIgnoreCase(trimmed_value, + Http::Headers::get().TransferEncodingValues.Deflate)) { return false; } } diff --git a/test/common/common/utility_fuzz_test.cc b/test/common/common/utility_fuzz_test.cc index 99006fdc0d..e7daf80a45 100644 --- a/test/common/common/utility_fuzz_test.cc +++ b/test/common/common/utility_fuzz_test.cc @@ -44,11 +44,6 @@ DEFINE_FUZZER(const uint8_t* buf, size_t len) { const std::string string_buffer(reinterpret_cast(buf), len); absl::EndsWith(string_buffer.substr(0, split_point), string_buffer.substr(split_point)); } - { - const std::string string_buffer(reinterpret_cast(buf), len); - StringUtil::caseCompare(string_buffer.substr(0, split_point), - string_buffer.substr(split_point)); - } { const std::string string_buffer(reinterpret_cast(buf), len); StringUtil::cropLeft(string_buffer.substr(0, split_point), string_buffer.substr(split_point)); diff --git a/test/common/common/utility_test.cc b/test/common/common/utility_test.cc index d6f35cac9a..989df53d4f 100644 --- a/test/common/common/utility_test.cc +++ b/test/common/common/utility_test.cc @@ -249,13 +249,6 @@ TEST(StringUtil, StringViewCaseFindToken) { EXPECT_TRUE(StringUtil::caseFindToken("A=5", ".", "A=5")); } -TEST(StringUtil, StringViewCaseCompare) { - EXPECT_TRUE(StringUtil::caseCompare("HELLO world", "hello world")); - EXPECT_TRUE(StringUtil::caseCompare("hello world", "HELLO world")); - EXPECT_FALSE(StringUtil::caseCompare("hello world", "hello")); - EXPECT_FALSE(StringUtil::caseCompare("hello", "hello world")); -} - TEST(StringUtil, StringViewCropRight) { EXPECT_EQ("hello", StringUtil::cropRight("hello; world\t\f\v\n\r", ";")); EXPECT_EQ("foo ", StringUtil::cropRight("foo ; ; ; ; ; ; ", ";")); From 0377b405b27fab546e2a55e44d104c4f63395dd8 Mon Sep 17 00:00:00 2001 From: asraa Date: Fri, 14 Feb 2020 16:47:52 -0500 Subject: [PATCH 61/87] fuzz: Add dictionary support to fuzzers and package for OSS-Fuzz (#9720) Fuzzers can now add dictionaries with .dict in their directory. These are packaged in along with corpus entries and handled by OSS-Fuzz, which automatically picks them up to use in fuzzing. https://google.github.io/oss-fuzz/getting-started/new-project-guide/#dictionaries OSS-Fuzz unpacks the tar and moves the dictionary to $OUT here: https://github.com/google/oss-fuzz/pull/3247 Signed-off-by: Asra Ali --- bazel/envoy_test.bzl | 6 ++++- test/common/access_log/BUILD | 4 ++++ .../access_log_formatter_fuzz_test.dict | 24 +++++++++++++++++++ test/fuzz/BUILD | 2 ++ test/fuzz/headers.dict | 17 +++++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 test/common/access_log/access_log_formatter_fuzz_test.dict create mode 100644 test/fuzz/headers.dict diff --git a/bazel/envoy_test.bzl b/bazel/envoy_test.bzl index 17d67ff060..1ea82dbe4b 100644 --- a/bazel/envoy_test.bzl +++ b/bazel/envoy_test.bzl @@ -70,6 +70,7 @@ def _envoy_test_linkopts(): def envoy_cc_fuzz_test( name, corpus, + dictionaries = [], repository = "", size = "medium", deps = [], @@ -84,9 +85,12 @@ def envoy_cc_fuzz_test( ) else: corpus_name = corpus + tar_src = [corpus_name] + if dictionaries: + tar_src += dictionaries pkg_tar( name = name + "_corpus_tar", - srcs = [corpus_name], + srcs = tar_src, testonly = 1, ) test_lib_name = name + "_lib" diff --git a/test/common/access_log/BUILD b/test/common/access_log/BUILD index 8fdc442375..74be77ad35 100644 --- a/test/common/access_log/BUILD +++ b/test/common/access_log/BUILD @@ -21,6 +21,10 @@ envoy_cc_fuzz_test( name = "access_log_formatter_fuzz_test", srcs = ["access_log_formatter_fuzz_test.cc"], corpus = "access_log_formatter_corpus", + dictionaries = [ + "access_log_formatter_fuzz_test.dict", + "//test/fuzz:headers.dict", + ], deps = [ ":access_log_formatter_fuzz_proto_cc_proto", "//source/common/access_log:access_log_formatter_lib", diff --git a/test/common/access_log/access_log_formatter_fuzz_test.dict b/test/common/access_log/access_log_formatter_fuzz_test.dict new file mode 100644 index 0000000000..1ad40f873c --- /dev/null +++ b/test/common/access_log/access_log_formatter_fuzz_test.dict @@ -0,0 +1,24 @@ +# format strings +"[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% \"%REQ(X-FORWARDED-FOR)%\" \"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\" \"%REQ(:AUTHORITY)%\" \"%UPSTREAM_HOST%\"\x0A" +"%START_TIME%" +"%BYTES_RECEIVED%" +"%PROTOCOL%" +"%RESPONSE_CODE%" +"%RESPONSE_CODE_DETAILS%" +"%BYTES_SENT%" +"%DURATION%" +"%RESPONSE_DURATION%" +"%RESPONSE_FLAGS%" +"%RESPONSE_TX_DURATION%" +"%ROUTE_NAME%" +"%UPSTREAM_HOST%" +"%UPSTREAM_CLUSTER%" +"%UPSTREAM_LOCAL_ADDRESS%" +"%UPSTREAM_TRANSPORT_FAILURE_REASON%" +"%DOWNSTREAM_REMOTE_ADDRESS%" +"%REQUESTED_SERVER_NAME%" +"%REQ" +"%TRAILER" +"%RESP" +"%DOWNSTREAM_PEER_CERT_V_END%" +"%HOSTNAME%" \ No newline at end of file diff --git a/test/fuzz/BUILD b/test/fuzz/BUILD index 4ff22728f2..d46ae39a51 100644 --- a/test/fuzz/BUILD +++ b/test/fuzz/BUILD @@ -15,6 +15,8 @@ envoy_proto_library( deps = ["@envoy_api//envoy/config/core/v3:pkg"], ) +exports_files(["headers.dict"]) + envoy_cc_test_library( name = "main", srcs = ["main.cc"], diff --git a/test/fuzz/headers.dict b/test/fuzz/headers.dict new file mode 100644 index 0000000000..787e8fde79 --- /dev/null +++ b/test/fuzz/headers.dict @@ -0,0 +1,17 @@ +# Dictionary to populate HeaderValueOptions +":path" +":method" +":scheme" +":status" +":authority" +"host" +"keep-alive" +":protocol" +"set-cookie" +"upgrade" +"via" +"te" +"user-agent" +"content-length" +"chunked" +"transfer-encoding" From 29f6b9f312789a291b9b7f4e3ece22bca7aae0e7 Mon Sep 17 00:00:00 2001 From: rulex123 <29862113+rulex123@users.noreply.github.com> Date: Sat, 15 Feb 2020 01:07:51 +0100 Subject: [PATCH 62/87] Tools: group spelling files under new folder in tools (#10065) Signed-off-by: Erica Manno --- bazel/README.md | 4 ++-- ci/do_ci.sh | 8 ++++---- support/hooks/pre-push | 2 +- tools/{ => spelling}/check_spelling.sh | 10 +++++----- tools/{ => spelling}/check_spelling_pedantic.py | 11 ++++++----- tools/{ => spelling}/spelling_dictionary.txt | 0 tools/{ => spelling}/spelling_skip_files.txt | 0 tools/{ => spelling}/spelling_whitelist_words.txt | 0 8 files changed, 18 insertions(+), 17 deletions(-) rename tools/{ => spelling}/check_spelling.sh (84%) rename tools/{ => spelling}/check_spelling_pedantic.py (98%) rename tools/{ => spelling}/spelling_dictionary.txt (100%) rename tools/{ => spelling}/spelling_skip_files.txt (100%) rename tools/{ => spelling}/spelling_whitelist_words.txt (100%) diff --git a/bazel/README.md b/bazel/README.md index 124323b82d..1a29f3db5b 100644 --- a/bazel/README.md +++ b/bazel/README.md @@ -619,9 +619,9 @@ Once this is set up, you can run clang-format without docker: ```shell ./tools/code_format/check_format.py check -./tools/check_spelling.sh check +./tools/spelling/check_spelling.sh check ./tools/code_format/check_format.py fix -./tools/check_spelling.sh fix +./tools/spelling/check_spelling.sh fix ``` # Advanced caching setup diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 1577e8a4a0..6f407d7df2 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -326,19 +326,19 @@ elif [[ "$CI_TARGET" == "check_repositories" ]]; then exit 0 elif [[ "$CI_TARGET" == "check_spelling" ]]; then echo "check_spelling..." - ./tools/check_spelling.sh check + ./tools/spelling/check_spelling.sh check exit 0 elif [[ "$CI_TARGET" == "fix_spelling" ]];then echo "fix_spell..." - ./tools/check_spelling.sh fix + ./tools/spelling/check_spelling.sh fix exit 0 elif [[ "$CI_TARGET" == "check_spelling_pedantic" ]]; then echo "check_spelling_pedantic..." - ./tools/check_spelling_pedantic.py --mark check + ./tools/spelling/check_spelling_pedantic.py --mark check exit 0 elif [[ "$CI_TARGET" == "fix_spelling_pedantic" ]]; then echo "fix_spelling_pedantic..." - ./tools/check_spelling_pedantic.py fix + ./tools/spelling/check_spelling_pedantic.py fix exit 0 elif [[ "$CI_TARGET" == "docs" ]]; then echo "generating docs..." diff --git a/support/hooks/pre-push b/support/hooks/pre-push index 8f66491576..7b08dd4e0e 100755 --- a/support/hooks/pre-push +++ b/support/hooks/pre-push @@ -65,7 +65,7 @@ do fi echo " Checking spelling for $i" - "$SCRIPT_DIR"/check_spelling_pedantic.py check $i + "$SCRIPT_DIR"/spelling/check_spelling_pedantic.py check $i if [[ $? -ne 0 ]]; then exit 1 fi diff --git a/tools/check_spelling.sh b/tools/spelling/check_spelling.sh similarity index 84% rename from tools/check_spelling.sh rename to tools/spelling/check_spelling.sh index 7597e80e77..df43aadcec 100755 --- a/tools/check_spelling.sh +++ b/tools/spelling/check_spelling.sh @@ -36,7 +36,7 @@ else fi SCRIPTPATH=$( cd "$(dirname "$0")" ; pwd -P ) -ROOTDIR="${SCRIPTPATH}/.." +ROOTDIR="${SCRIPTPATH}/../.." cd "$ROOTDIR" BIN_FILENAME="misspell_"${VERSION}"_"${OS}"_64bit.tar.gz" @@ -69,11 +69,11 @@ fi chmod +x "${TMP_DIR}/misspell" # Spell checking -# All the skipping files are defined in tools/spelling_skip_files.txt -SPELLING_SKIP_FILES="${ROOTDIR}/tools/spelling_skip_files.txt" +# All the skipping files are defined in tools/spelling/spelling_skip_files.txt +SPELLING_SKIP_FILES="${ROOTDIR}/tools/spelling/spelling_skip_files.txt" -# All the ignore words are defined in tools/spelling_whitelist_words.txt -SPELLING_WHITELIST_WORDS_FILE="${ROOTDIR}/tools/spelling_whitelist_words.txt" +# All the ignore words are defined in tools/spelling/spelling_whitelist_words.txt +SPELLING_WHITELIST_WORDS_FILE="${ROOTDIR}/tools/spelling/spelling_whitelist_words.txt" WHITELIST_WORDS=$(echo -n $(cat "${SPELLING_WHITELIST_WORDS_FILE}" | \ grep -v "^#"|grep -v "^$") | tr ' ' ',') diff --git a/tools/check_spelling_pedantic.py b/tools/spelling/check_spelling_pedantic.py similarity index 98% rename from tools/check_spelling_pedantic.py rename to tools/spelling/check_spelling_pedantic.py index 2512872fed..ce1333f384 100755 --- a/tools/check_spelling_pedantic.py +++ b/tools/spelling/check_spelling_pedantic.py @@ -27,7 +27,7 @@ def cmp(x, y): return (x > y) - (x < y) -TOOLS_DIR = os.path.dirname(os.path.realpath(__file__)) +CURR_DIR = os.path.dirname(os.path.realpath(__file__)) # Single line comments: // comment OR /* comment */ # Limit the characters that may precede // to help filter out some code @@ -106,7 +106,7 @@ def start(self): words = self.load_dictionary() # Generate aspell personal dictionary. - pws = os.path.join(TOOLS_DIR, '.aspell.en.pws') + pws = os.path.join(CURR_DIR, '.aspell.en.pws') with open(pws, 'w') as f: f.write("personal_ws-1.1 en %d\n" % (len(words))) f.writelines(words) @@ -542,7 +542,7 @@ def execute(files, dictionary_file, fix): except: locale.setlocale(locale.LC_ALL, 'C.UTF-8') - default_dictionary = os.path.join(TOOLS_DIR, 'spelling_dictionary.txt') + default_dictionary = os.path.join(CURR_DIR, 'spelling_dictionary.txt') parser = argparse.ArgumentParser(description="Check comment spelling.") parser.add_argument('operation_type', @@ -589,8 +589,9 @@ def execute(files, dictionary_file, fix): if args.operation_type == 'check': if not rv: - print("ERROR: spell check failed. Run 'tools/check_spelling_pedantic.py fix and/or add new " - "words to tools/spelling_dictionary.txt'") + print( + "ERROR: spell check failed. Run 'tools/spelling/check_spelling_pedantic.py fix and/or add new " + "words to tools/spelling/spelling_dictionary.txt'") sys.exit(1) print("PASS") diff --git a/tools/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt similarity index 100% rename from tools/spelling_dictionary.txt rename to tools/spelling/spelling_dictionary.txt diff --git a/tools/spelling_skip_files.txt b/tools/spelling/spelling_skip_files.txt similarity index 100% rename from tools/spelling_skip_files.txt rename to tools/spelling/spelling_skip_files.txt diff --git a/tools/spelling_whitelist_words.txt b/tools/spelling/spelling_whitelist_words.txt similarity index 100% rename from tools/spelling_whitelist_words.txt rename to tools/spelling/spelling_whitelist_words.txt From 5df4c55ea0f8e1e915d70a297240a301677013f8 Mon Sep 17 00:00:00 2001 From: Jose Ulises Nino Rivera Date: Mon, 17 Feb 2020 08:17:08 -0600 Subject: [PATCH 63/87] dns resolver: invoke resolve callback if not cancelled (#10060) Description:PendingResolutions get destroyed when complete or when c-ares sent ARES_EDESTRUCTION. Prior to #9899 ARES_EDESTRUCTION only happened when the resolver was destroyed. However, after #9899 the channel, and thus PendingResolutions can be destroyed, without the callback target being aware. This leads to potential use after free issues. This PR calls the resolve callback when the status received is ARES_EDESTRUCTION. Risk Level: med Testing: added test that reproduced segfault and passed after fix. Signed-off-by: Jose Nino --- source/common/network/dns_impl.cc | 12 ++++++-- test/common/network/dns_impl_test.cc | 45 ++++++++++++++++++---------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/source/common/network/dns_impl.cc b/source/common/network/dns_impl.cc index 505b1bea7d..b07a078042 100644 --- a/source/common/network/dns_impl.cc +++ b/source/common/network/dns_impl.cc @@ -84,6 +84,13 @@ void DnsResolverImpl::PendingResolution::onAresGetAddrInfoCallback(int status, i // We receive ARES_EDESTRUCTION when destructing with pending queries. if (status == ARES_EDESTRUCTION) { ASSERT(owned_); + // This destruction might have been triggered by a peer PendingResolution that received a + // ARES_ECONNREFUSED. If the PendingResolution has not been cancelled that means that the + // callback_ target _should_ still be around. In that case, raise the callback_ so the target + // can be done with this query and initiate a new one. + if (!cancelled_) { + callback_({}); + } delete this; return; } @@ -251,8 +258,9 @@ ActiveDnsQuery* DnsResolverImpl::resolve(const std::string& dns_name, // Enable timer to wake us up if the request times out. updateAresTimer(); - // The PendingResolution will self-delete when the request completes - // (including if cancelled or if ~DnsResolverImpl() happens). + // The PendingResolution will self-delete when the request completes (including if cancelled or + // if ~DnsResolverImpl() happens via ares_destroy() and subsequent handling of ARES_EDESTRUCTION + // in DnsResolverImpl::PendingResolution::onAresGetAddrInfoCallback()). pending_resolution->owned_ = true; return pending_resolution.release(); } diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index 65bc03c10d..6884766987 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -476,20 +476,41 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, DnsImplTest, TestUtility::ipTestParamsToString); // Validate that when DnsResolverImpl is destructed with outstanding requests, -// that we don't invoke any callbacks. This is a regression test from +// that we don't invoke any callbacks if the query was cancelled. This is a regression test from // development, where segfaults were encountered due to callback invocations on // destruction. TEST_P(DnsImplTest, DestructPending) { - EXPECT_NE(nullptr, resolver_->resolve("", DnsLookupFamily::V4Only, - [&](std::list&& results) -> void { - FAIL(); - UNREFERENCED_PARAMETER(results); - })); + ActiveDnsQuery* query = resolver_->resolve("", DnsLookupFamily::V4Only, + [&](std::list&& results) -> void { + FAIL(); + UNREFERENCED_PARAMETER(results); + }); + ASSERT_NE(nullptr, query); + query->cancel(); // Also validate that pending events are around to exercise the resource // reclamation path. EXPECT_GT(peer_->events().size(), 0U); } +TEST_P(DnsImplTest, DestructCallback) { + server_->addHosts("some.good.domain", {"201.134.56.7"}, RecordType::A); + + ActiveDnsQuery* query = resolver_->resolve("some.domain", DnsLookupFamily::Auto, + [&](std::list &&) -> void { + query = nullptr; + dispatcher_->exit(); + }); + + // This simulates destruction thanks to another query setting the dirty_channel_ bit, thus causing + // a subsequent result to call ares_destroy. + peer_->resetChannelTcpOnly(zero_timeout()); + ares_set_servers_ports_csv(peer_->channel(), socket_->localAddress()->asString().c_str()); + + dispatcher_->run(Event::Dispatcher::RunType::Block); + + ASSERT_EQ(nullptr, query); +} + // Validate basic success/fail lookup behavior. The empty request will connect // to TestDnsServer, but localhost should resolve via the hosts file with no // asynchronous behavior or network events. @@ -946,16 +967,12 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, DnsImplAresFlagsForTcpTest, TEST_P(DnsImplAresFlagsForTcpTest, TcpLookupsEnabled) { server_->addCName("root.cnam.domain", "result.cname.domain"); server_->addHosts("result.cname.domain", {"201.134.56.7"}, RecordType::A); - std::list address_list; ares_options opts{}; int optmask = 0; EXPECT_EQ(ARES_SUCCESS, ares_save_options(peer_->channel(), &opts, &optmask)); EXPECT_TRUE((opts.flags & ARES_FLAG_USEVC) == ARES_FLAG_USEVC); EXPECT_NE(nullptr, resolver_->resolve("root.cnam.domain", DnsLookupFamily::Auto, - [&](std::list&& results) -> void { - address_list = getAddressList(results); - dispatcher_->exit(); - })); + [&](std::list &&) -> void {})); ares_destroy_options(&opts); } @@ -974,16 +991,12 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, DnsImplAresFlagsForUdpTest, TEST_P(DnsImplAresFlagsForUdpTest, UdpLookupsEnabled) { server_->addCName("root.cnam.domain", "result.cname.domain"); server_->addHosts("result.cname.domain", {"201.134.56.7"}, RecordType::A); - std::list address_list; ares_options opts{}; int optmask = 0; EXPECT_EQ(ARES_SUCCESS, ares_save_options(peer_->channel(), &opts, &optmask)); EXPECT_FALSE((opts.flags & ARES_FLAG_USEVC) == ARES_FLAG_USEVC); EXPECT_NE(nullptr, resolver_->resolve("root.cnam.domain", DnsLookupFamily::Auto, - [&](std::list&& results) -> void { - address_list = getAddressList(results); - dispatcher_->exit(); - })); + [&](std::list &&) -> void {})); ares_destroy_options(&opts); } From b71eae00c1de77364c656067f7d4fc1149c7b22b Mon Sep 17 00:00:00 2001 From: "Adi (Suissa) Peleg" Date: Mon, 17 Feb 2020 12:33:59 -0500 Subject: [PATCH 64/87] Rewriting HeaderString to use absl::variant. See #9593 (#9952) Signed-off-by: Adi Suissa-Peleg --- include/envoy/http/BUILD | 1 + include/envoy/http/header_map.h | 70 ++--- source/common/http/header_map_impl.cc | 255 ++++++------------ source/common/http/http1/codec_impl.cc | 8 +- source/common/http/http1/codec_impl.h | 2 - source/common/http/http2/codec_impl.cc | 4 +- test/common/http/header_map_impl_fuzz_test.cc | 15 +- test/common/http/header_map_impl_test.cc | 124 ++++----- 8 files changed, 193 insertions(+), 286 deletions(-) diff --git a/include/envoy/http/BUILD b/include/envoy/http/BUILD index 36217efeee..1ad8b91135 100644 --- a/include/envoy/http/BUILD +++ b/include/envoy/http/BUILD @@ -96,6 +96,7 @@ envoy_cc_library( deps = [ "//source/common/common:assert_lib", "//source/common/common:hash_lib", + "@com_google_absl//absl/container:inlined_vector", ], ) diff --git a/include/envoy/http/header_map.h b/include/envoy/http/header_map.h index 2524a37448..d07ad3127f 100644 --- a/include/envoy/http/header_map.h +++ b/include/envoy/http/header_map.h @@ -15,6 +15,7 @@ #include "common/common/hash.h" #include "common/common/macros.h" +#include "absl/container/inlined_vector.h" #include "absl/strings/string_view.h" namespace Envoy { @@ -85,17 +86,26 @@ using LowerCaseStrUnorderedSet = std::unordered_set>; +/** + * Convenient type for an inline vector that will be used by HeaderString. + */ +using InlineHeaderVector = absl::InlinedVector; + +/** + * Convenient type for the underlying type of HeaderString that allows a variant + * between string_view and the InlinedVector. + */ +using VariantHeader = absl::variant; + /** * This is a string implementation for use in header processing. It is heavily optimized for - * performance. It supports 3 different types of storage and can switch between them: + * performance. It supports 2 different types of storage and can switch between them: * 1) A reference. - * 2) Interned string. - * 3) Heap allocated storage. + * 2) An InlinedVector (an optimized interned string for small strings, but allows heap + * allocation if needed). */ class HeaderString { public: - enum class Type { Inline, Reference, Dynamic }; - /** * Default constructor. Sets up for inline storage. */ @@ -116,7 +126,7 @@ class HeaderString { explicit HeaderString(absl::string_view ref_value); HeaderString(HeaderString&& move_value) noexcept; - ~HeaderString(); + ~HeaderString() = default; /** * Append data to an existing string. If the string is a reference string the reference data is @@ -125,16 +135,23 @@ class HeaderString { void append(const char* data, uint32_t size); /** - * @return the modifiable backing buffer (either inline or heap allocated). + * Transforms the inlined vector data using the given UnaryOperation (conforms + * to std::transform). + * @param unary_op the operations to be performed on each of the elements. */ - char* buffer() { return buffer_.dynamic_; } + template void inlineTransform(UnaryOperation&& unary_op) { + ASSERT(type() == Type::Inline); + std::transform(absl::get(buffer_).begin(), + absl::get(buffer_).end(), + absl::get(buffer_).begin(), unary_op); + } /** * Get an absl::string_view. It will NOT be NUL terminated! * * @return an absl::string_view. */ - absl::string_view getStringView() const { return {buffer_.ref_, string_length_}; } + absl::string_view getStringView() const; /** * Return the string to a default state. Reference strings are not touched. Both inline/dynamic @@ -145,7 +162,7 @@ class HeaderString { /** * @return whether the string is empty or not. */ - bool empty() const { return string_length_ == 0; } + bool empty() const { return size() == 0; } // Looking for find? Use getStringView().find() @@ -172,14 +189,14 @@ class HeaderString { void setReference(absl::string_view ref_value); /** - * @return the size of the string, not including the null terminator. + * @return whether the string is a reference or an InlinedVector. */ - uint32_t size() const { return string_length_; } + bool isReference() const { return type() == Type::Reference; } /** - * @return the type of backing storage for the string. + * @return the size of the string, not including the null terminator. */ - Type type() const { return type_; } + uint32_t size() const; bool operator==(const char* rhs) const { return getStringView() == absl::NullSafeStringView(rhs); @@ -191,25 +208,16 @@ class HeaderString { bool operator!=(absl::string_view rhs) const { return getStringView() != rhs; } private: - union Buffer { - // This should reference inline_buffer_ for Type::Inline. - char* dynamic_; - const char* ref_; - } buffer_; - - // Capacity in both Type::Inline and Type::Dynamic cases must be at least MinDynamicCapacity in - // header_map_impl.cc. - union { - char inline_buffer_[128]; - // Since this is a union, this is only valid for type_ == Type::Dynamic. - uint32_t dynamic_capacity_; - }; - - void freeDynamic(); + enum class Type { Reference, Inline }; + + VariantHeader buffer_; + bool valid() const; - uint32_t string_length_; - Type type_; + /** + * @return the type of backing storage for the string. + */ + Type type() const; }; /** diff --git a/source/common/http/header_map_impl.cc b/source/common/http/header_map_impl.cc index ec290e753c..f914f6709c 100644 --- a/source/common/http/header_map_impl.cc +++ b/source/common/http/header_map_impl.cc @@ -16,195 +16,101 @@ namespace Envoy { namespace Http { namespace { -constexpr size_t MinDynamicCapacity{32}; // This includes the NULL (StringUtil::itoa technically only needs 21). constexpr size_t MaxIntegerLength{32}; -uint64_t newCapacity(uint32_t existing_capacity, uint32_t size_to_append) { - return (static_cast(existing_capacity) + size_to_append) * 2; -} - void validateCapacity(uint64_t new_capacity) { // If the resizing will cause buffer overflow due to hitting uint32_t::max, an OOM is likely // imminent. Fast-fail rather than allow a buffer overflow attack (issue #1421) RELEASE_ASSERT(new_capacity <= std::numeric_limits::max(), "Trying to allocate overly large headers."); - ASSERT(new_capacity >= MinDynamicCapacity); } -} // namespace +absl::string_view get_str_view(const VariantHeader& buffer) { + return absl::get(buffer); +} -HeaderString::HeaderString() : type_(Type::Inline) { - buffer_.dynamic_ = inline_buffer_; - clear(); - static_assert(sizeof(inline_buffer_) >= MaxIntegerLength, ""); - static_assert(MinDynamicCapacity >= MaxIntegerLength, ""); - ASSERT(valid()); +InlineHeaderVector& get_in_vec(VariantHeader& buffer) { + return absl::get(buffer); } -HeaderString::HeaderString(const LowerCaseString& ref_value) : type_(Type::Reference) { - buffer_.ref_ = ref_value.get().c_str(); - string_length_ = ref_value.get().size(); - ASSERT(valid()); +const InlineHeaderVector& get_in_vec(const VariantHeader& buffer) { + return absl::get(buffer); } +} // namespace -HeaderString::HeaderString(absl::string_view ref_value) : type_(Type::Reference) { - buffer_.ref_ = ref_value.data(); - string_length_ = ref_value.size(); +// Initialize as a Type::Inline +HeaderString::HeaderString() : buffer_(InlineHeaderVector()) { + ASSERT((get_in_vec(buffer_).capacity()) >= MaxIntegerLength); ASSERT(valid()); } -HeaderString::HeaderString(HeaderString&& move_value) noexcept { - type_ = move_value.type_; - string_length_ = move_value.string_length_; - switch (move_value.type_) { - case Type::Reference: { - buffer_.ref_ = move_value.buffer_.ref_; - break; - } - case Type::Dynamic: { - // When we move a dynamic header, we switch the moved header back to its default state (inline). - buffer_.dynamic_ = move_value.buffer_.dynamic_; - dynamic_capacity_ = move_value.dynamic_capacity_; - move_value.type_ = Type::Inline; - move_value.buffer_.dynamic_ = move_value.inline_buffer_; - move_value.clear(); - break; - } - case Type::Inline: { - buffer_.dynamic_ = inline_buffer_; - memcpy(inline_buffer_, move_value.inline_buffer_, string_length_); - move_value.string_length_ = 0; - break; - } - } +// Initialize as a Type::Reference +HeaderString::HeaderString(const LowerCaseString& ref_value) + : buffer_(absl::string_view(ref_value.get().c_str(), ref_value.get().size())) { ASSERT(valid()); } -HeaderString::~HeaderString() { freeDynamic(); } +// Initialize as a Type::Reference +HeaderString::HeaderString(absl::string_view ref_value) : buffer_(ref_value) { ASSERT(valid()); } -void HeaderString::freeDynamic() { - if (type_ == Type::Dynamic) { - free(buffer_.dynamic_); - } +HeaderString::HeaderString(HeaderString&& move_value) noexcept + : buffer_(std::move(move_value.buffer_)) { + move_value.clear(); + ASSERT(valid()); } bool HeaderString::valid() const { return validHeaderString(getStringView()); } -void HeaderString::append(const char* data, uint32_t size) { - switch (type_) { +void HeaderString::append(const char* data, uint32_t data_size) { + // Make sure the requested memory allocation is below uint32_t::max + const uint64_t new_capacity = static_cast(data_size) + size(); + validateCapacity(new_capacity); + ASSERT(validHeaderString(absl::string_view(data, data_size))); + + switch (type()) { case Type::Reference: { - // Rather than be too clever and optimize this uncommon case, we dynamically - // allocate and copy. - type_ = Type::Dynamic; - const uint64_t new_capacity = newCapacity(string_length_, size); - if (new_capacity > MinDynamicCapacity) { - validateCapacity(new_capacity); - dynamic_capacity_ = new_capacity; - } else { - dynamic_capacity_ = MinDynamicCapacity; - } - char* buf = static_cast(malloc(dynamic_capacity_)); - RELEASE_ASSERT(buf != nullptr, ""); - memcpy(buf, buffer_.ref_, string_length_); - buffer_.dynamic_ = buf; + // Rather than be too clever and optimize this uncommon case, we switch to + // Inline mode and copy. + const absl::string_view prev = get_str_view(buffer_); + buffer_ = InlineHeaderVector(); + // Assigning new_capacity to avoid resizing when appending the new data + get_in_vec(buffer_).reserve(new_capacity); + get_in_vec(buffer_).assign(prev.begin(), prev.end()); break; } - case Type::Inline: { - const uint64_t new_capacity = static_cast(size) + string_length_; - if (new_capacity <= sizeof(inline_buffer_)) { - // Already inline and the new value fits in inline storage. - break; - } - - FALLTHRU; + get_in_vec(buffer_).reserve(new_capacity); + break; } - - case Type::Dynamic: { - // We can get here either because we didn't fit in inline or we are already dynamic. - if (type_ == Type::Inline) { - const uint64_t new_capacity = newCapacity(string_length_, size); - validateCapacity(new_capacity); - buffer_.dynamic_ = static_cast(malloc(new_capacity)); - RELEASE_ASSERT(buffer_.dynamic_ != nullptr, ""); - memcpy(buffer_.dynamic_, inline_buffer_, string_length_); - dynamic_capacity_ = new_capacity; - type_ = Type::Dynamic; - } else { - if (size + string_length_ > dynamic_capacity_) { - const uint64_t new_capacity = newCapacity(string_length_, size); - validateCapacity(new_capacity); - - // Need to reallocate. - dynamic_capacity_ = new_capacity; - buffer_.dynamic_ = static_cast(realloc(buffer_.dynamic_, dynamic_capacity_)); - RELEASE_ASSERT(buffer_.dynamic_ != nullptr, ""); - } - } } + get_in_vec(buffer_).insert(get_in_vec(buffer_).end(), data, data + data_size); +} + +absl::string_view HeaderString::getStringView() const { + if (type() == Type::Reference) { + return get_str_view(buffer_); } - ASSERT(validHeaderString(absl::string_view(data, size))); - memcpy(buffer_.dynamic_ + string_length_, data, size); - string_length_ += size; + ASSERT(type() == Type::Inline); + return {get_in_vec(buffer_).data(), get_in_vec(buffer_).size()}; } void HeaderString::clear() { - switch (type_) { - case Type::Reference: { - break; - } - case Type::Inline: { - FALLTHRU; - } - case Type::Dynamic: { - string_length_ = 0; - } + if (type() == Type::Inline) { + get_in_vec(buffer_).clear(); } } void HeaderString::setCopy(const char* data, uint32_t size) { - switch (type_) { - case Type::Reference: { - // Switch back to inline and fall through. - type_ = Type::Inline; - buffer_.dynamic_ = inline_buffer_; - - FALLTHRU; - } - - case Type::Inline: { - if (size <= sizeof(inline_buffer_)) { - // Already inline and the new value fits in inline storage. - break; - } - - FALLTHRU; - } + ASSERT(validHeaderString(absl::string_view(data, size))); - case Type::Dynamic: { - // We can get here either because we didn't fit in inline or we are already dynamic. - if (type_ == Type::Inline) { - dynamic_capacity_ = size * 2; - validateCapacity(dynamic_capacity_); - buffer_.dynamic_ = static_cast(malloc(dynamic_capacity_)); - RELEASE_ASSERT(buffer_.dynamic_ != nullptr, ""); - type_ = Type::Dynamic; - } else { - if (size > dynamic_capacity_) { - // Need to reallocate. Use free/malloc to avoid the copy since we are about to overwrite. - dynamic_capacity_ = size * 2; - validateCapacity(dynamic_capacity_); - free(buffer_.dynamic_); - buffer_.dynamic_ = static_cast(malloc(dynamic_capacity_)); - RELEASE_ASSERT(buffer_.dynamic_ != nullptr, ""); - } - } - } + if (!absl::holds_alternative(buffer_)) { + // Switching from Type::Reference to Type::Inline + buffer_ = InlineHeaderVector(); } - memcpy(buffer_.dynamic_, data, size); - string_length_ = size; + get_in_vec(buffer_).reserve(size); + get_in_vec(buffer_).assign(data, data + size); ASSERT(valid()); } @@ -213,38 +119,47 @@ void HeaderString::setCopy(absl::string_view view) { } void HeaderString::setInteger(uint64_t value) { - switch (type_) { - case Type::Reference: { - // Switch back to inline and fall through. - type_ = Type::Inline; - buffer_.dynamic_ = inline_buffer_; + // Initialize the size to the max length, copy the actual data, and then + // reduce the size (but not the capacity) as needed + // Note: instead of using the inner_buffer, attempted the following: + // resize buffer_ to MaxIntegerLength, apply StringUtil::itoa to the buffer_.data(), and then + // resize buffer_ to int_length (the number of digits in value). + // However it was slower than the following approach. + char inner_buffer[MaxIntegerLength]; + const uint32_t int_length = StringUtil::itoa(inner_buffer, MaxIntegerLength, value); - FALLTHRU; - } - - case Type::Inline: - // buffer_.dynamic_ should always point at inline_buffer_ for Type::Inline. - ASSERT(buffer_.dynamic_ == inline_buffer_); - FALLTHRU; - case Type::Dynamic: { - // Whether dynamic or inline the buffer is guaranteed to be large enough. - ASSERT(type_ == Type::Inline || dynamic_capacity_ >= MaxIntegerLength); - // It's safe to use buffer.dynamic_, since buffer.ref_ is union aliased. - // This better not change without verifying assumptions across this file. - static_assert(offsetof(Buffer, dynamic_) == offsetof(Buffer, ref_), ""); - string_length_ = StringUtil::itoa(buffer_.dynamic_, 32, value); - } + if (type() == Type::Reference) { + // Switching from Type::Reference to Type::Inline + buffer_ = InlineHeaderVector(); } + ASSERT((get_in_vec(buffer_).capacity()) > MaxIntegerLength); + get_in_vec(buffer_).assign(inner_buffer, inner_buffer + int_length); } void HeaderString::setReference(absl::string_view ref_value) { - freeDynamic(); - type_ = Type::Reference; - buffer_.ref_ = ref_value.data(); - string_length_ = ref_value.size(); + buffer_ = ref_value; ASSERT(valid()); } +uint32_t HeaderString::size() const { + if (type() == Type::Reference) { + return get_str_view(buffer_).size(); + } + ASSERT(type() == Type::Inline); + return get_in_vec(buffer_).size(); +} + +HeaderString::Type HeaderString::type() const { + // buffer_.index() is correlated with the order of Reference and Inline in the + // enum. + ASSERT(buffer_.index() == 0 || buffer_.index() == 1); + ASSERT((buffer_.index() == 0 && absl::holds_alternative(buffer_)) || + (buffer_.index() != 0)); + ASSERT((buffer_.index() == 1 && absl::holds_alternative(buffer_)) || + (buffer_.index() != 1)); + return Type(buffer_.index()); +} + // Specialization needed for HeaderMapImpl::HeaderList::insert() when key is LowerCaseString. // A fully specialized template must be defined once in the program, hence this may not be in // a header file. diff --git a/source/common/http/http1/codec_impl.cc b/source/common/http/http1/codec_impl.cc index 1f04fa951f..d53f567538 100644 --- a/source/common/http/http1/codec_impl.cc +++ b/source/common/http/http1/codec_impl.cc @@ -19,6 +19,7 @@ #include "common/runtime/runtime_impl.h" #include "absl/container/fixed_array.h" +#include "absl/strings/ascii.h" namespace Envoy { namespace Http { @@ -361,11 +362,6 @@ http_parser_settings ConnectionImpl::settings_{ nullptr // on_chunk_complete }; -const ToLowerTable& ConnectionImpl::toLowerTable() { - static auto* table = new ToLowerTable(); - return *table; -} - ConnectionImpl::ConnectionImpl(Network::Connection& connection, Stats::Scope& stats, http_parser_type type, uint32_t max_headers_kb, const uint32_t max_headers_count, @@ -391,7 +387,7 @@ void ConnectionImpl::completeLastHeader() { current_header_field_.getStringView(), current_header_value_.getStringView()); if (!current_header_field_.empty()) { - toLowerTable().toLowerCase(current_header_field_.buffer(), current_header_field_.size()); + current_header_field_.inlineTransform([](char c) { return absl::ascii_tolower(c); }); headers().addViaMove(std::move(current_header_field_), std::move(current_header_value_)); } diff --git a/source/common/http/http1/codec_impl.h b/source/common/http/http1/codec_impl.h index 172640a411..bb7ee5d376 100644 --- a/source/common/http/http1/codec_impl.h +++ b/source/common/http/http1/codec_impl.h @@ -14,7 +14,6 @@ #include "common/buffer/watermark_buffer.h" #include "common/common/assert.h" -#include "common/common/to_lower_table.h" #include "common/http/codec_helper.h" #include "common/http/codes.h" #include "common/http/header_map_impl.h" @@ -314,7 +313,6 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable& headers, const HeaderEntry& header) { uint8_t flags = 0; - if (header.key().type() == HeaderString::Type::Reference) { + if (header.key().isReference()) { flags |= NGHTTP2_NV_FLAG_NO_COPY_NAME; } - if (header.value().type() == HeaderString::Type::Reference) { + if (header.value().isReference()) { flags |= NGHTTP2_NV_FLAG_NO_COPY_VALUE; } const absl::string_view header_key = header.key().getStringView(); diff --git a/test/common/http/header_map_impl_fuzz_test.cc b/test/common/http/header_map_impl_fuzz_test.cc index 5b776f080b..5c3cc0f5ed 100644 --- a/test/common/http/header_map_impl_fuzz_test.cc +++ b/test/common/http/header_map_impl_fuzz_test.cc @@ -8,6 +8,8 @@ #include "test/fuzz/fuzz_runner.h" #include "test/fuzz/utility.h" +#include "absl/strings/ascii.h" + using Envoy::Fuzz::replaceInvalidCharacters; namespace Envoy { @@ -98,7 +100,18 @@ DEFINE_PROTO_FUZZER(const test::common::http::HeaderMapImplFuzzTestCase& input) const auto& mutate_and_move = action.mutate_and_move(); lower_case_strings.emplace_back( std::make_unique(replaceInvalidCharacters(mutate_and_move.key()))); - Http::HeaderString header_field(*lower_case_strings.back()); + // Randomly (using fuzzer data) set the header_field to either be of type Reference or Inline + const auto& str = lower_case_strings.back(); + Http::HeaderString header_field; // By default it's Inline + if ((str->get().size() > 0) && (str->get().at(0) & 0x1)) { + // Keeping header_field as Inline + header_field.setCopy(str->get()); + // inlineTransform can only be applied to Inline type! + header_field.inlineTransform(absl::ascii_tolower); + } else { + // Changing header_field to Reference + header_field.setReference(str->get()); + } Http::HeaderString header_value; // Do some mutation or parameterized action. switch (mutate_and_move.mutate_selector_case()) { diff --git a/test/common/http/header_map_impl_test.cc b/test/common/http/header_map_impl_test.cc index 68ec766eea..179b78573a 100644 --- a/test/common/http/header_map_impl_test.cc +++ b/test/common/http/header_map_impl_test.cc @@ -70,11 +70,11 @@ TEST(HeaderStringTest, All) { { HeaderString string; string.setCopy("hello"); - EXPECT_EQ(HeaderString::Type::Inline, string.type()); + EXPECT_FALSE(string.isReference()); HeaderString string2(std::move(string)); EXPECT_TRUE(string.empty()); // NOLINT(bugprone-use-after-move) - EXPECT_EQ(HeaderString::Type::Inline, string.type()); - EXPECT_EQ(HeaderString::Type::Inline, string2.type()); + EXPECT_FALSE(string.isReference()); + EXPECT_FALSE(string2.isReference()); string.append("world", 5); EXPECT_EQ("world", string.getStringView()); EXPECT_EQ(5UL, string.size()); @@ -82,16 +82,16 @@ TEST(HeaderStringTest, All) { EXPECT_EQ(5UL, string2.size()); } - // Dynamic move constructor + // Inline move large constructor { std::string large(4096, 'a'); HeaderString string; string.setCopy(large); - EXPECT_EQ(HeaderString::Type::Dynamic, string.type()); + EXPECT_FALSE(string.isReference()); HeaderString string2(std::move(string)); EXPECT_TRUE(string.empty()); // NOLINT(bugprone-use-after-move) - EXPECT_EQ(HeaderString::Type::Inline, string.type()); - EXPECT_EQ(HeaderString::Type::Dynamic, string2.type()); + EXPECT_FALSE(string.isReference()); + EXPECT_FALSE(string2.isReference()); string.append("b", 1); EXPECT_EQ("b", string.getStringView()); EXPECT_EQ(1UL, string.size()); @@ -104,7 +104,7 @@ TEST(HeaderStringTest, All) { std::string static_string("HELLO"); HeaderString string(static_string); string.setInteger(5); - EXPECT_EQ(HeaderString::Type::Inline, string.type()); + EXPECT_FALSE(string.isReference()); EXPECT_EQ("5", string.getStringView()); } @@ -113,7 +113,7 @@ TEST(HeaderStringTest, All) { std::string static_string("HELLO"); HeaderString string(static_string); string.setCopy(static_string); - EXPECT_EQ(HeaderString::Type::Inline, string.type()); + EXPECT_FALSE(string.isReference()); EXPECT_EQ("HELLO", string.getStringView()); } @@ -121,9 +121,9 @@ TEST(HeaderStringTest, All) { { std::string static_string("HELLO"); HeaderString string(static_string); - EXPECT_EQ(HeaderString::Type::Reference, string.type()); + EXPECT_TRUE(string.isReference()); string.clear(); - EXPECT_EQ(HeaderString::Type::Reference, string.type()); + EXPECT_TRUE(string.isReference()); EXPECT_EQ("HELLO", string.getStringView()); } @@ -131,7 +131,7 @@ TEST(HeaderStringTest, All) { { std::string static_string("HELLO"); HeaderString string(static_string); - EXPECT_EQ(HeaderString::Type::Reference, string.type()); + EXPECT_TRUE(string.isReference()); string.append("a", 1); EXPECT_EQ("HELLOa", string.getStringView()); } @@ -200,58 +200,36 @@ TEST(HeaderStringTest, All) { HeaderString string; std::string large(128, 'z'); string.setCopy(large); - EXPECT_EQ(string.type(), HeaderString::Type::Inline); + EXPECT_FALSE(string.isReference()); EXPECT_EQ(string.getStringView(), large); } - // Ensure setCopy does not add NUL. - { - HeaderString string; - std::string large(128, 'z'); - string.setCopy(large); - EXPECT_EQ(string.type(), HeaderString::Type::Inline); - EXPECT_EQ(string.getStringView(), large); - std::string small(1, 'a'); - string.setCopy(small); - EXPECT_EQ(string.type(), HeaderString::Type::Inline); - EXPECT_EQ(string.getStringView(), small); - // If we peek past the valid first character of the - // header string_view it should still be 'z' and not '\0'. - // We know this peek is OK since the memory is much larger - // than two bytes. - EXPECT_EQ(string.getStringView().data()[1], 'z'); - } - // Copy, exactly filling dynamic capacity // - // ASAN should catch a write one past the end of the dynamic buffer. This test + // ASAN should catch a write one past the end of the inline buffer. This test // forces a dynamic buffer with one copy and then fills it with the next. { HeaderString string; - // Force Dynamic with setCopy of inline buffer size + 1. + // Force dynamic vector allocation with setCopy of inline buffer size + 1. std::string large1(129, 'z'); string.setCopy(large1); - EXPECT_EQ(string.type(), HeaderString::Type::Dynamic); - const void* dynamic_buffer_address = string.getStringView().data(); + EXPECT_FALSE(string.isReference()); // Dynamic capacity in setCopy is 2x required by the size. - // So to fill it exactly setCopy with a total of 258 chars. - std::string large2(258, 'z'); + // So to fill it exactly setCopy with a total of 256 chars. + std::string large2(256, 'z'); string.setCopy(large2); - EXPECT_EQ(string.type(), HeaderString::Type::Dynamic); - // The actual buffer address should be the same as it was after - // setCopy(large1), ensuring no reallocation occurred. - EXPECT_EQ(string.getStringView().data(), dynamic_buffer_address); + EXPECT_FALSE(string.isReference()); EXPECT_EQ(string.getStringView(), large2); } - // Append, small buffer to dynamic + // Append, small buffer to inline { HeaderString string; std::string test(128, 'a'); string.append(test.c_str(), test.size()); - EXPECT_EQ(HeaderString::Type::Inline, string.type()); + EXPECT_FALSE(string.isReference()); string.append("a", 1); - EXPECT_EQ(HeaderString::Type::Dynamic, string.type()); + EXPECT_FALSE(string.isReference()); test += 'a'; EXPECT_EQ(test, string.getStringView()); } @@ -272,25 +250,12 @@ TEST(HeaderStringTest, All) { EXPECT_EQ(4106U, string.size()); } - // Append, realloc dynamic. - { - HeaderString string; - std::string large(129, 'a'); - string.append(large.c_str(), large.size()); - EXPECT_EQ(HeaderString::Type::Dynamic, string.type()); - std::string large2 = large + large; - string.append(large2.c_str(), large2.size()); - large += large2; - EXPECT_EQ(large, string.getStringView()); - EXPECT_EQ(387U, string.size()); - } - // Append, realloc close to limit with small buffer. { HeaderString string; std::string large(129, 'a'); string.append(large.c_str(), large.size()); - EXPECT_EQ(HeaderString::Type::Dynamic, string.type()); + EXPECT_FALSE(string.isReference()); std::string large2(120, 'b'); string.append(large2.c_str(), large2.size()); std::string large3(32, 'c'); @@ -305,19 +270,15 @@ TEST(HeaderStringTest, All) { // forces a dynamic buffer with one copy and then fills it with the next. { HeaderString string; - // Force Dynamic with setCopy of inline buffer size + 1. + // Force dynamic allocation with setCopy of inline buffer size + 1. std::string large1(129, 'z'); string.setCopy(large1); - EXPECT_EQ(string.type(), HeaderString::Type::Dynamic); - const void* dynamic_buffer_address = string.getStringView().data(); + EXPECT_FALSE(string.isReference()); // Dynamic capacity in setCopy is 2x required by the size. - // So to fill it exactly append 129 chars for a total of 258 chars. - std::string large2(129, 'z'); + // So to fill it exactly append 127 chars for a total of 256 chars. + std::string large2(127, 'z'); string.append(large2.c_str(), large2.size()); - EXPECT_EQ(string.type(), HeaderString::Type::Dynamic); - // The actual buffer address should be the same as it was after - // setCopy(large1), ensuring no reallocation occurred. - EXPECT_EQ(string.getStringView().data(), dynamic_buffer_address); + EXPECT_FALSE(string.isReference()); EXPECT_EQ(string.getStringView(), large1 + large2); } @@ -337,27 +298,27 @@ TEST(HeaderStringTest, All) { string.setInteger(123456789); EXPECT_EQ("123456789", string.getStringView()); EXPECT_EQ(9U, string.size()); - EXPECT_EQ(HeaderString::Type::Dynamic, string.type()); + EXPECT_FALSE(string.isReference()); } - // Set static, switch to dynamic, back to static. + // Set static, switch to inline, back to static. { const std::string static_string = "hello world"; HeaderString string; string.setReference(static_string); EXPECT_EQ(string.getStringView(), static_string); EXPECT_EQ(11U, string.size()); - EXPECT_EQ(HeaderString::Type::Reference, string.type()); + EXPECT_TRUE(string.isReference()); const std::string large(129, 'a'); string.setCopy(large); EXPECT_NE(string.getStringView().data(), large.c_str()); - EXPECT_EQ(HeaderString::Type::Dynamic, string.type()); + EXPECT_FALSE(string.isReference()); string.setReference(static_string); EXPECT_EQ(string.getStringView(), static_string); EXPECT_EQ(11U, string.size()); - EXPECT_EQ(HeaderString::Type::Reference, string.type()); + EXPECT_TRUE(string.isReference()); } // getString @@ -372,6 +333,21 @@ TEST(HeaderStringTest, All) { absl::string_view retString2 = headerString2.getStringView(); EXPECT_EQ(0U, retString2.size()); } + + // inlineTransform + { + const std::string static_string = "HELLO"; + HeaderString string; + string.setCopy(static_string); + string.inlineTransform([](char c) { return static_cast(tolower(c)); }); + EXPECT_FALSE(string.isReference()); + EXPECT_EQ(5U, string.size()); + EXPECT_EQ(string.getStringView(), "hello"); + string.inlineTransform(toupper); + EXPECT_EQ(string.getStringView(), static_string); + EXPECT_EQ(5U, string.size()); + EXPECT_FALSE(string.isReference()); + } } TEST(HeaderMapImplTest, InlineInsert) { @@ -460,7 +436,7 @@ TEST(HeaderMapImplTest, Remove) { std::string ref_value("value"); headers.addReference(static_key, ref_value); EXPECT_EQ("value", headers.get(static_key)->value().getStringView()); - EXPECT_EQ(HeaderString::Type::Reference, headers.get(static_key)->value().type()); + EXPECT_TRUE(headers.get(static_key)->value().isReference()); EXPECT_EQ(1UL, headers.size()); EXPECT_FALSE(headers.empty()); headers.remove(static_key); @@ -1226,7 +1202,7 @@ TEST(HeaderMapImplTest, ClearHeaderMap) { // Add random header and then clear. headers.addReference(static_key, ref_value); EXPECT_EQ("value", headers.get(static_key)->value().getStringView()); - EXPECT_EQ(HeaderString::Type::Reference, headers.get(static_key)->value().type()); + EXPECT_TRUE(headers.get(static_key)->value().isReference()); EXPECT_EQ(1UL, headers.size()); EXPECT_FALSE(headers.empty()); headers.clear(); From 3a88288d8313ce8c4a738526abbd1e9de4bb2666 Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Mon, 17 Feb 2020 12:34:51 -0500 Subject: [PATCH 65/87] Update Datadog tracer version to v1.1.3 (#10077) Signed-off-by: Caleb Gilmour --- 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 bff4e023bd..5dbbb706e4 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -134,9 +134,9 @@ REPOSITORY_LOCATIONS = dict( urls = ["https://github.com/lightstep/lightstep-tracer-cpp/archive/v0.8.0.tar.gz"], ), com_github_datadog_dd_opentracing_cpp = dict( - sha256 = "052fd37cd698e24ab73ee18fc3fa55acd1d43153c12a0e65b0fba0447de1117e", - strip_prefix = "dd-opentracing-cpp-1.1.1", - urls = ["https://github.com/DataDog/dd-opentracing-cpp/archive/v1.1.1.tar.gz"], + sha256 = "6dc1088ab7f788b6c849fbaa6300517c8fdf88991a70b778be79c284c36857bf", + strip_prefix = "dd-opentracing-cpp-1.1.3", + urls = ["https://github.com/DataDog/dd-opentracing-cpp/archive/v1.1.3.tar.gz"], ), com_github_google_benchmark = dict( sha256 = "3c6a165b6ecc948967a1ead710d4a181d7b0fbcaa183ef7ea84604994966221a", From d4e62c046e3fb7c1e3d9677fda1df66a5ef44f2f Mon Sep 17 00:00:00 2001 From: John Plevyak Date: Mon, 17 Feb 2020 09:35:53 -0800 Subject: [PATCH 66/87] Add parsing for ASAN error stack output. (#10069) Signed-off-by: John Plevyak --- tools/stack_decode.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/stack_decode.py b/tools/stack_decode.py index cc22bfd82a..d19f10b686 100755 --- a/tools/stack_decode.py +++ b/tools/stack_decode.py @@ -31,6 +31,9 @@ def decode_stacktrace_log(object_file, input_source): # or: # ${backtrace_marker} #10: [0xADDR] stackaddr_re = re.compile("%s #\d+:(?: .*)? \[(0x[0-9a-fA-F]+)\]$" % backtrace_marker) + # Match something like: + # #10 0xLOCATION (BINARY+0xADDR) + asan_re = re.compile(" *#\d+ *0x[0-9a-fA-F]+ *\([^+]*\+(0x[0-9a-fA-F]+)\)") try: while True: @@ -38,6 +41,8 @@ def decode_stacktrace_log(object_file, input_source): if line == "": return # EOF stackaddr_match = stackaddr_re.search(line) + if not stackaddr_match: + stackaddr_match = asan_re.search(line) if stackaddr_match: address = stackaddr_match.groups()[0] file_and_line_number = run_addr2line(object_file, address) From 4423dcd8528d65a2f6aa919e89301efddd53e8f2 Mon Sep 17 00:00:00 2001 From: wozz Date: Mon, 17 Feb 2020 09:37:46 -0800 Subject: [PATCH 67/87] tracing: google grpc service support for ocagent/opencensus (#9955) Signed-off-by: michael.wozniak --- api/envoy/config/trace/v2/trace.proto | 11 +++-- api/envoy/config/trace/v3/trace.proto | 11 +++-- docs/root/intro/version_history.rst | 2 +- .../envoy/config/trace/v2/trace.proto | 11 +++-- .../envoy/config/trace/v3/trace.proto | 11 +++-- .../opencensus/opencensus_tracer_impl.cc | 12 +++++- .../tracers/opencensus/config_test.cc | 40 +++++++++++++++++++ tools/spelling/spelling_dictionary.txt | 1 + 8 files changed, 85 insertions(+), 14 deletions(-) diff --git a/api/envoy/config/trace/v2/trace.proto b/api/envoy/config/trace/v2/trace.proto index ae578972ef..420e4aa28f 100644 --- a/api/envoy/config/trace/v2/trace.proto +++ b/api/envoy/config/trace/v2/trace.proto @@ -142,7 +142,7 @@ message DatadogConfig { } // Configuration for the OpenCensus tracer. -// [#next-free-field: 14] +// [#next-free-field: 15] // [#extension: envoy.tracers.opencensus] message OpenCensusConfig { enum TraceContext { @@ -196,14 +196,19 @@ message OpenCensusConfig { // The URL to Zipkin, e.g. "http://127.0.0.1:9411/api/v2/spans" string zipkin_url = 6; - // Enables the OpenCensus Agent exporter if set to true. The address must also - // be set. + // Enables the OpenCensus Agent exporter if set to true. The ocagent_address or + // ocagent_grpc_service must also be set. bool ocagent_exporter_enabled = 11; // The address of the OpenCensus Agent, if its exporter is enabled, in gRPC // format: https://github.com/grpc/grpc/blob/master/doc/naming.md + // [#comment:TODO: deprecate this field] string ocagent_address = 12; + // (optional) The gRPC server hosted by the OpenCensus Agent. Only Google gRPC is supported. + // This is only used if the ocagent_address is left empty. + api.v2.core.GrpcService ocagent_grpc_service = 14; + // List of incoming trace context headers we will accept. First one found // wins. repeated TraceContext incoming_trace_context = 8; diff --git a/api/envoy/config/trace/v3/trace.proto b/api/envoy/config/trace/v3/trace.proto index d1adb5cade..12e944269a 100644 --- a/api/envoy/config/trace/v3/trace.proto +++ b/api/envoy/config/trace/v3/trace.proto @@ -162,7 +162,7 @@ message DatadogConfig { } // Configuration for the OpenCensus tracer. -// [#next-free-field: 14] +// [#next-free-field: 15] // [#extension: envoy.tracers.opencensus] message OpenCensusConfig { option (udpa.annotations.versioning).previous_message_type = @@ -219,14 +219,19 @@ message OpenCensusConfig { // The URL to Zipkin, e.g. "http://127.0.0.1:9411/api/v2/spans" string zipkin_url = 6; - // Enables the OpenCensus Agent exporter if set to true. The address must also - // be set. + // Enables the OpenCensus Agent exporter if set to true. The ocagent_address or + // ocagent_grpc_service must also be set. bool ocagent_exporter_enabled = 11; // The address of the OpenCensus Agent, if its exporter is enabled, in gRPC // format: https://github.com/grpc/grpc/blob/master/doc/naming.md + // [#comment:TODO: deprecate this field] string ocagent_address = 12; + // (optional) The gRPC server hosted by the OpenCensus Agent. Only Google gRPC is supported. + // This is only used if the ocagent_address is left empty. + core.v3.GrpcService ocagent_grpc_service = 14; + // List of incoming trace context headers we will accept. First one found // wins. repeated TraceContext incoming_trace_context = 8; diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index 82db0b2d0a..f0a0201823 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -22,7 +22,7 @@ Version history * thrift_proxy: add router filter stats to docs. * tracers: tracer extensions use the "envoy.tracers" name space. A mapping of extension names is available in the :ref:`deprecated ` documentation. -* tracing: added gRPC service configuration to the OpenCensus Stackdriver tracer. +* tracing: added gRPC service configuration to the OpenCensus Stackdriver and OpenCensus Agent tracers. * upstream: combined HTTP/1 and HTTP/2 connection pool code. This means that circuit breaker limits for both requests and connections apply to both pool types. Also, HTTP/2 now has the option to limit concurrent requests on a connection, and allow multiple draining diff --git a/generated_api_shadow/envoy/config/trace/v2/trace.proto b/generated_api_shadow/envoy/config/trace/v2/trace.proto index ae578972ef..420e4aa28f 100644 --- a/generated_api_shadow/envoy/config/trace/v2/trace.proto +++ b/generated_api_shadow/envoy/config/trace/v2/trace.proto @@ -142,7 +142,7 @@ message DatadogConfig { } // Configuration for the OpenCensus tracer. -// [#next-free-field: 14] +// [#next-free-field: 15] // [#extension: envoy.tracers.opencensus] message OpenCensusConfig { enum TraceContext { @@ -196,14 +196,19 @@ message OpenCensusConfig { // The URL to Zipkin, e.g. "http://127.0.0.1:9411/api/v2/spans" string zipkin_url = 6; - // Enables the OpenCensus Agent exporter if set to true. The address must also - // be set. + // Enables the OpenCensus Agent exporter if set to true. The ocagent_address or + // ocagent_grpc_service must also be set. bool ocagent_exporter_enabled = 11; // The address of the OpenCensus Agent, if its exporter is enabled, in gRPC // format: https://github.com/grpc/grpc/blob/master/doc/naming.md + // [#comment:TODO: deprecate this field] string ocagent_address = 12; + // (optional) The gRPC server hosted by the OpenCensus Agent. Only Google gRPC is supported. + // This is only used if the ocagent_address is left empty. + api.v2.core.GrpcService ocagent_grpc_service = 14; + // List of incoming trace context headers we will accept. First one found // wins. repeated TraceContext incoming_trace_context = 8; diff --git a/generated_api_shadow/envoy/config/trace/v3/trace.proto b/generated_api_shadow/envoy/config/trace/v3/trace.proto index 00913bd54e..82b34fe7d2 100644 --- a/generated_api_shadow/envoy/config/trace/v3/trace.proto +++ b/generated_api_shadow/envoy/config/trace/v3/trace.proto @@ -160,7 +160,7 @@ message DatadogConfig { } // Configuration for the OpenCensus tracer. -// [#next-free-field: 14] +// [#next-free-field: 15] // [#extension: envoy.tracers.opencensus] message OpenCensusConfig { option (udpa.annotations.versioning).previous_message_type = @@ -217,14 +217,19 @@ message OpenCensusConfig { // The URL to Zipkin, e.g. "http://127.0.0.1:9411/api/v2/spans" string zipkin_url = 6; - // Enables the OpenCensus Agent exporter if set to true. The address must also - // be set. + // Enables the OpenCensus Agent exporter if set to true. The ocagent_address or + // ocagent_grpc_service must also be set. bool ocagent_exporter_enabled = 11; // The address of the OpenCensus Agent, if its exporter is enabled, in gRPC // format: https://github.com/grpc/grpc/blob/master/doc/naming.md + // [#comment:TODO: deprecate this field] string ocagent_address = 12; + // (optional) The gRPC server hosted by the OpenCensus Agent. Only Google gRPC is supported. + // This is only used if the ocagent_address is left empty. + core.v3.GrpcService ocagent_grpc_service = 14; + // List of incoming trace context headers we will accept. First one found // wins. repeated TraceContext incoming_trace_context = 8; diff --git a/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc b/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc index 2b4fd1f3a7..6a31b0d068 100644 --- a/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc +++ b/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc @@ -277,7 +277,17 @@ Driver::Driver(const envoy::config::trace::v3::OpenCensusConfig& oc_config, } if (oc_config.ocagent_exporter_enabled()) { ::opencensus::exporters::trace::OcAgentOptions opts; - opts.address = oc_config.ocagent_address(); + if (!oc_config.ocagent_address().empty()) { + opts.address = oc_config.ocagent_address(); + } else if (oc_config.has_ocagent_grpc_service()) { + if (!oc_config.ocagent_grpc_service().has_google_grpc()) { + throw EnvoyException("Opencensus ocagent tracer only supports GoogleGrpc."); + } + envoy::config::core::v3::GrpcService ocagent_service = oc_config.ocagent_grpc_service(); + auto channel = Envoy::Grpc::GoogleGrpcUtils::createChannel(ocagent_service, api); + opts.trace_service_stub = + ::opencensus::proto::agent::trace::v1::TraceService::NewStub(channel); + } opts.service_name = local_info_.clusterName(); ::opencensus::exporters::trace::OcAgentExporter::Register(std::move(opts)); } diff --git a/test/extensions/tracers/opencensus/config_test.cc b/test/extensions/tracers/opencensus/config_test.cc index 6c07bc8e73..5f743c8e3c 100644 --- a/test/extensions/tracers/opencensus/config_test.cc +++ b/test/extensions/tracers/opencensus/config_test.cc @@ -75,6 +75,46 @@ TEST(OpenCensusTracerConfigTest, OpenCensusHttpTracerWithTypedConfig) { {32, 32, 128, 32, ::opencensus::trace::ProbabilitySampler(1e-4)}); } +TEST(OpenCensusTracerConfigTest, OpenCensusHttpTracerGrpc) { + NiceMock server; + const std::string yaml_string = R"EOF( + http: + name: envoy.tracers.opencensus + typed_config: + "@type": type.googleapis.com/envoy.config.trace.v2.OpenCensusConfig + trace_config: + rate_limiting_sampler: + qps: 123 + max_number_of_attributes: 12 + max_number_of_annotations: 34 + max_number_of_message_events: 56 + max_number_of_links: 78 + ocagent_exporter_enabled: true + ocagent_grpc_service: + google_grpc: + target_uri: 127.0.0.1:55678 + stat_prefix: test + incoming_trace_context: b3 + incoming_trace_context: trace_context + incoming_trace_context: grpc_trace_bin + incoming_trace_context: cloud_trace_context + outgoing_trace_context: trace_context + )EOF"; + + envoy::config::trace::v3::Tracing configuration; + TestUtility::loadFromYaml(yaml_string, configuration); + + OpenCensusTracerFactory factory; + auto message = Config::Utility::translateToFactoryConfig( + configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); + Tracing::HttpTracerPtr tracer = factory.createHttpTracer(*message, server); + EXPECT_NE(nullptr, tracer); + + // Reset TraceParams back to default. + ::opencensus::trace::TraceConfig::SetCurrentTraceParams( + {32, 32, 128, 32, ::opencensus::trace::ProbabilitySampler(1e-4)}); +} + TEST(OpenCensusTracerConfigTest, DoubleRegistrationTest) { EXPECT_THROW_WITH_MESSAGE( (Registry::RegisterFactory()), diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt index 217468c6db..0629254396 100644 --- a/tools/spelling/spelling_dictionary.txt +++ b/tools/spelling/spelling_dictionary.txt @@ -784,6 +784,7 @@ nullptr num numkeys observability +ocagent offsetof oneof oneway From 423fe76d5572bb4f1505391ccaaacf39b2bf2c85 Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Mon, 17 Feb 2020 09:39:49 -0800 Subject: [PATCH 68/87] api: introduce WiP file-level annotations. (#9971) This is the new style for indicating a file is WiP and subject to breaking changes. Rather than rely on alpha major versions, which are coarse grained and introduce migration difficulties for operators, we use a file-level annotation. Risk level: Low Testing: API/docs build, manual inspection of docs. Fixes #9769. Signed-off-by: Lizan Zhou Co-authored-by: htuch --- api/STYLE.md | 18 ++++++++++++----- api/bazel/repository_locations.bzl | 4 ++-- .../filter/http/cache/v2alpha/cache.proto | 3 +++ .../transport_socket/tap/v2alpha/tap.proto | 3 +++ .../filters/http/cache/v3alpha/cache.proto | 2 ++ .../bazel/repository_locations.bzl | 4 ++-- .../filter/http/cache/v2alpha/cache.proto | 3 +++ .../transport_socket/tap/v2alpha/tap.proto | 3 +++ .../filters/http/cache/v3alpha/cache.proto | 2 ++ tools/protodoc/BUILD | 1 + tools/protodoc/protodoc.py | 8 +++++++- tools/protoxform/protoxform.py | 20 ++++++++++++++----- 12 files changed, 56 insertions(+), 15 deletions(-) diff --git a/api/STYLE.md b/api/STYLE.md index ffd595b5a9..48bab57b91 100644 --- a/api/STYLE.md +++ b/api/STYLE.md @@ -120,6 +120,10 @@ Extensions must currently be added as v2 APIs following the [package organization](#package-organization) above. To add an extension config to the API, the steps below should be followed: +1. If this is still WiP and subject to breaking changes, use `vNalpha` instead of `vN` in steps + below. Refer to the [Cache filter config](envoy/config/filter/http/cache/v2alpha/cache.proto) + as an example of `v2alpha`, and the + [Buffer filter config](envoy/config/filter/http/buffer/v2/buffer.proto) as an example of `v2`. 1. Place the v2 extension configuration `.proto` in `api/envoy/config`, e.g. `api/envoy/config/filter/http/foobar/v2/foobar.proto` together with an initial BUILD file: ``` @@ -132,13 +136,15 @@ To add an extension config to the API, the steps below should be followed: ) ``` 1. Add to the v2 extension config proto `import "udpa/annotations/migrate.proto";` -2. Add to the v2 extension config proto a package level `option (udpa.annotations.file_migrate).move_to_package = "envoy.extensions.filters.http.foobar.v3";`. - This places the filter in the correct [v3 package hierarchy](#package-organization). -3. Add a reference to the v2 extension config in (1) in [api/docs/BUILD](docs/BUILD). -4. Run `./tools/proto_format fix`. This should regenerate the `BUILD` file, +1. Add to the v2 extension config proto a file level `option (udpa.annotations.file_migrate).move_to_package = "envoy.extensions.filters.http.foobar.v3";`. + This places the filter in the correct [v3 package hierarchy](#package-organization). +1. If this is still WiP and subject to breaking changes, import + `udpa/annotations/status.proto` and set `option (udpa.annotations.file_status).work_in_progress = true;`. +1. Add a reference to the v2 extension config in (1) in [api/docs/BUILD](docs/BUILD). +1. Run `./tools/proto_format fix`. This should regenerate the `BUILD` file, reformat `foobar.proto` as needed and also generate the v3 extension config, together with shadow API protos. -4. `git add api/ generated_api_shadow/` to add any new files to your Git index. +1. `git add api/ generated_api_shadow/` to add any new files to your Git index. ## API annotations @@ -177,3 +183,5 @@ metadata. We describe these annotations below by category. * `option (udpa.annotations.file_migrate).move_to_package = "";` to denote that in the next major version of the API, the file will be moved to the given package. This is consumed by `protoxform`. +* `option (udpa.annotations.file_status).work_in_progress = true;` to denote a + file that is still work-in-progress and subject to breaking changes. diff --git a/api/bazel/repository_locations.bzl b/api/bazel/repository_locations.bzl index 58006daee4..50390b2a79 100644 --- a/api/bazel/repository_locations.bzl +++ b/api/bazel/repository_locations.bzl @@ -13,8 +13,8 @@ GOOGLEAPIS_SHA = "a45019af4d3290f02eaeb1ce10990166978c807cb33a9692141a076ba46d14 PROMETHEUS_GIT_SHA = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c" # Nov 17, 2017 PROMETHEUS_SHA = "783bdaf8ee0464b35ec0c8704871e1e72afa0005c3f3587f65d9d6694bf3911b" -UDPA_GIT_SHA = "edbea6a78f6d1ba34edc69c53a396b1d88d59651" # Dec 30, 2019 -UDPA_SHA256 = "8cabd617b68354fa8b4adab8a031f80c10e2ea43f57d5f6210bc7b3ebb79b684" +UDPA_GIT_SHA = "db4b343e48c1264bb4d9ff491b059300701dc7c7" # Jan 24, 2020 +UDPA_SHA256 = "800624f44592a24898f133e39ae7fbb7a6c4b85bdddd448185fb7e277f097a56" ZIPKINAPI_RELEASE = "0.2.2" # Aug 23, 2019 ZIPKINAPI_SHA256 = "688c4fe170821dd589f36ec45aaadc03a618a40283bc1f97da8fa11686fc816b" diff --git a/api/envoy/config/filter/http/cache/v2alpha/cache.proto b/api/envoy/config/filter/http/cache/v2alpha/cache.proto index 6d1cf5d2a7..4005b32a55 100644 --- a/api/envoy/config/filter/http/cache/v2alpha/cache.proto +++ b/api/envoy/config/filter/http/cache/v2alpha/cache.proto @@ -7,6 +7,8 @@ import "envoy/type/matcher/string.proto"; import "google/protobuf/any.proto"; +import "udpa/annotations/status.proto"; + import "udpa/annotations/migrate.proto"; import "validate/validate.proto"; @@ -15,6 +17,7 @@ option java_outer_classname = "CacheProto"; option java_multiple_files = true; option (udpa.annotations.file_migrate).move_to_package = "envoy.extensions.filters.http.cache.v3alpha"; +option (udpa.annotations.file_status).work_in_progress = true; // [#protodoc-title: HTTP Cache Filter] // [#extension: envoy.filters.http.cache] diff --git a/api/envoy/config/transport_socket/tap/v2alpha/tap.proto b/api/envoy/config/transport_socket/tap/v2alpha/tap.proto index e25449a0ff..53add0a9f7 100644 --- a/api/envoy/config/transport_socket/tap/v2alpha/tap.proto +++ b/api/envoy/config/transport_socket/tap/v2alpha/tap.proto @@ -5,6 +5,8 @@ package envoy.config.transport_socket.tap.v2alpha; import "envoy/api/v2/core/base.proto"; import "envoy/config/common/tap/v2alpha/common.proto"; +import "udpa/annotations/status.proto"; + import "udpa/annotations/migrate.proto"; import "validate/validate.proto"; @@ -13,6 +15,7 @@ option java_outer_classname = "TapProto"; option java_multiple_files = true; option (udpa.annotations.file_migrate).move_to_package = "envoy.extensions.transport_sockets.tap.v3"; +option (udpa.annotations.file_status).work_in_progress = true; // [#protodoc-title: Tap] // [#extension: envoy.transport_sockets.tap] diff --git a/api/envoy/extensions/filters/http/cache/v3alpha/cache.proto b/api/envoy/extensions/filters/http/cache/v3alpha/cache.proto index ad74fe7e0e..26016442bb 100644 --- a/api/envoy/extensions/filters/http/cache/v3alpha/cache.proto +++ b/api/envoy/extensions/filters/http/cache/v3alpha/cache.proto @@ -7,6 +7,7 @@ import "envoy/type/matcher/v3/string.proto"; import "google/protobuf/any.proto"; +import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -14,6 +15,7 @@ import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.http.cache.v3alpha"; option java_outer_classname = "CacheProto"; option java_multiple_files = true; +option (udpa.annotations.file_status).work_in_progress = true; // [#protodoc-title: HTTP Cache Filter] // [#extension: envoy.filters.http.cache] diff --git a/generated_api_shadow/bazel/repository_locations.bzl b/generated_api_shadow/bazel/repository_locations.bzl index 58006daee4..50390b2a79 100644 --- a/generated_api_shadow/bazel/repository_locations.bzl +++ b/generated_api_shadow/bazel/repository_locations.bzl @@ -13,8 +13,8 @@ GOOGLEAPIS_SHA = "a45019af4d3290f02eaeb1ce10990166978c807cb33a9692141a076ba46d14 PROMETHEUS_GIT_SHA = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c" # Nov 17, 2017 PROMETHEUS_SHA = "783bdaf8ee0464b35ec0c8704871e1e72afa0005c3f3587f65d9d6694bf3911b" -UDPA_GIT_SHA = "edbea6a78f6d1ba34edc69c53a396b1d88d59651" # Dec 30, 2019 -UDPA_SHA256 = "8cabd617b68354fa8b4adab8a031f80c10e2ea43f57d5f6210bc7b3ebb79b684" +UDPA_GIT_SHA = "db4b343e48c1264bb4d9ff491b059300701dc7c7" # Jan 24, 2020 +UDPA_SHA256 = "800624f44592a24898f133e39ae7fbb7a6c4b85bdddd448185fb7e277f097a56" ZIPKINAPI_RELEASE = "0.2.2" # Aug 23, 2019 ZIPKINAPI_SHA256 = "688c4fe170821dd589f36ec45aaadc03a618a40283bc1f97da8fa11686fc816b" diff --git a/generated_api_shadow/envoy/config/filter/http/cache/v2alpha/cache.proto b/generated_api_shadow/envoy/config/filter/http/cache/v2alpha/cache.proto index 6d1cf5d2a7..4005b32a55 100644 --- a/generated_api_shadow/envoy/config/filter/http/cache/v2alpha/cache.proto +++ b/generated_api_shadow/envoy/config/filter/http/cache/v2alpha/cache.proto @@ -7,6 +7,8 @@ import "envoy/type/matcher/string.proto"; import "google/protobuf/any.proto"; +import "udpa/annotations/status.proto"; + import "udpa/annotations/migrate.proto"; import "validate/validate.proto"; @@ -15,6 +17,7 @@ option java_outer_classname = "CacheProto"; option java_multiple_files = true; option (udpa.annotations.file_migrate).move_to_package = "envoy.extensions.filters.http.cache.v3alpha"; +option (udpa.annotations.file_status).work_in_progress = true; // [#protodoc-title: HTTP Cache Filter] // [#extension: envoy.filters.http.cache] diff --git a/generated_api_shadow/envoy/config/transport_socket/tap/v2alpha/tap.proto b/generated_api_shadow/envoy/config/transport_socket/tap/v2alpha/tap.proto index e25449a0ff..53add0a9f7 100644 --- a/generated_api_shadow/envoy/config/transport_socket/tap/v2alpha/tap.proto +++ b/generated_api_shadow/envoy/config/transport_socket/tap/v2alpha/tap.proto @@ -5,6 +5,8 @@ package envoy.config.transport_socket.tap.v2alpha; import "envoy/api/v2/core/base.proto"; import "envoy/config/common/tap/v2alpha/common.proto"; +import "udpa/annotations/status.proto"; + import "udpa/annotations/migrate.proto"; import "validate/validate.proto"; @@ -13,6 +15,7 @@ option java_outer_classname = "TapProto"; option java_multiple_files = true; option (udpa.annotations.file_migrate).move_to_package = "envoy.extensions.transport_sockets.tap.v3"; +option (udpa.annotations.file_status).work_in_progress = true; // [#protodoc-title: Tap] // [#extension: envoy.transport_sockets.tap] diff --git a/generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/cache.proto b/generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/cache.proto index ad74fe7e0e..26016442bb 100644 --- a/generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/cache.proto +++ b/generated_api_shadow/envoy/extensions/filters/http/cache/v3alpha/cache.proto @@ -7,6 +7,7 @@ import "envoy/type/matcher/v3/string.proto"; import "google/protobuf/any.proto"; +import "udpa/annotations/status.proto"; import "udpa/annotations/versioning.proto"; import "validate/validate.proto"; @@ -14,6 +15,7 @@ import "validate/validate.proto"; option java_package = "io.envoyproxy.envoy.extensions.filters.http.cache.v3alpha"; option java_outer_classname = "CacheProto"; option java_multiple_files = true; +option (udpa.annotations.file_status).work_in_progress = true; // [#protodoc-title: HTTP Cache Filter] // [#extension: envoy.filters.http.cache] diff --git a/tools/protodoc/BUILD b/tools/protodoc/BUILD index 2bd707940b..a3aa5d5987 100644 --- a/tools/protodoc/BUILD +++ b/tools/protodoc/BUILD @@ -16,6 +16,7 @@ py_binary( deps = [ "//tools/api_proto_plugin", "@com_envoyproxy_protoc_gen_validate//validate:validate_py", + "@com_github_cncf_udpa//udpa/annotations:pkg_py_proto", "@com_google_protobuf//:protobuf_python", ], ) diff --git a/tools/protodoc/protodoc.py b/tools/protodoc/protodoc.py index eef3e9bd5f..f360741db2 100755 --- a/tools/protodoc/protodoc.py +++ b/tools/protodoc/protodoc.py @@ -15,6 +15,7 @@ from tools.api_proto_plugin import plugin from tools.api_proto_plugin import visitor +from udpa.annotations import status_pb2 from validate import validate_pb2 # Namespace prefix for Envoy core APIs. @@ -576,8 +577,13 @@ def VisitFile(self, file_proto, type_context, services, msgs, enums): # toctrees. if not has_messages: header = ':orphan:\n\n' + header + warnings = '' + if file_proto.options.HasExtension(status_pb2.file_status): + if file_proto.options.Extensions[status_pb2.file_status].work_in_progress: + warnings += ('.. warning::\n This API is work-in-progress and is ' + 'subject to breaking changes.\n\n') debug_proto = FormatProtoAsBlockComment(file_proto) - return header + comment + '\n'.join(msgs) + '\n'.join(enums) # + debug_proto + return header + warnings + comment + '\n'.join(msgs) + '\n'.join(enums) # + debug_proto def Main(): diff --git a/tools/protoxform/protoxform.py b/tools/protoxform/protoxform.py index e183a6f448..ad4a139387 100755 --- a/tools/protoxform/protoxform.py +++ b/tools/protoxform/protoxform.py @@ -33,11 +33,12 @@ # Note: we have to include those proto definitions to make FormatOptions work, # this also serves as whitelist of extended options. from google.api import annotations_pb2 as _ -from udpa.annotations import sensitive_pb2 as _ from validate import validate_pb2 as _ from envoy.annotations import deprecation_pb2 as _ from envoy.annotations import resource_pb2 from udpa.annotations import migrate_pb2 +from udpa.annotations import sensitive_pb2 as _ +from udpa.annotations import status_pb2 NEXT_FREE_FIELD_MIN = 5 @@ -223,6 +224,11 @@ def CamelCase(s): options.Extensions[migrate_pb2.file_migrate].CopyFrom( file_proto.options.Extensions[migrate_pb2.file_migrate]) + if file_proto.options.HasExtension( + status_pb2.file_status) and file_proto.package.endswith('alpha'): + options.Extensions[status_pb2.file_status].CopyFrom( + file_proto.options.Extensions[status_pb2.file_status]) + options_block = FormatOptions(options) requires_versioning_import = any( @@ -239,8 +245,9 @@ def CamelCase(s): public_imports.append(d) continue elif d in [ - 'envoy/annotations/resource.proto', 'envoy/annotations/deprecation.proto', - 'udpa/annotations/migrate.proto' + 'envoy/annotations/resource.proto', + 'envoy/annotations/deprecation.proto', + 'udpa/annotations/migrate.proto', ]: infra_imports.append(d) elif d.startswith('envoy/'): @@ -251,12 +258,15 @@ def CamelCase(s): google_imports.append(d) elif d.startswith('validate/'): infra_imports.append(d) - elif d in ['udpa/annotations/versioning.proto']: - # Skip, we decide to add this based on requires_versioning_import + elif d in ['udpa/annotations/versioning.proto', 'udpa/annotations/status.proto']: + # Skip, we decide to add this based on requires_versioning_import and options. pass else: misc_imports.append(d) + if options.HasExtension(status_pb2.file_status): + misc_imports.append('udpa/annotations/status.proto') + if requires_versioning_import: misc_imports.append('udpa/annotations/versioning.proto') From bf132fbdd837dceefd523d056334595bdd9d96f8 Mon Sep 17 00:00:00 2001 From: danzh Date: Mon, 17 Feb 2020 12:50:29 -0500 Subject: [PATCH 69/87] quiche: update quiche tar (#10040) Signed-off-by: Dan Zhang --- bazel/external/quiche.BUILD | 164 ++++++++++---- bazel/repository_locations.bzl | 6 +- source/extensions/quic_listeners/quiche/BUILD | 1 + .../quiche/active_quic_listener.cc | 4 +- .../quic_listeners/quiche/envoy_quic_alarm.h | 2 +- .../quiche/envoy_quic_client_session.cc | 7 +- .../quiche/envoy_quic_client_session.h | 2 +- .../quiche/envoy_quic_server_session.cc | 14 +- .../quiche/envoy_quic_server_session.h | 4 +- .../quic_listeners/quiche/platform/BUILD | 19 +- .../quiche/platform/envoy_quic_clock.h | 2 +- .../quiche/platform/flags_list.h | 204 +++++++++--------- .../quiche/platform/http2_export_impl.h | 10 - .../quiche/platform/http2_flags_impl.h | 4 + .../quiche/platform/http2_logging_impl.h | 14 +- .../quiche/platform/quic_bbr2_sender_impl.h | 15 -- .../quiche/platform/quic_bug_tracker_impl.h | 8 +- .../quiche/platform/quic_logging_impl.h | 82 +++---- .../quiche/platform/quic_mem_slice_impl.cc | 14 +- .../quiche/platform/quic_mem_slice_impl.h | 9 +- ...map_util_impl.h => quiche_map_util_impl.h} | 8 +- ...optional_impl.h => quiche_optional_impl.h} | 6 +- ...ng_piece_impl.h => quiche_ptr_util_impl.h} | 12 +- .../platform/quiche_string_piece_impl.h | 9 + .../quiche_unordered_containers_impl.h | 4 +- .../quiche/platform/spdy_containers_impl.h | 12 +- .../quiche/platform/spdy_export_impl.h | 10 - .../quiche/platform/spdy_flags_impl.h | 4 + .../quiche/platform/spdy_logging_impl.h | 12 +- .../quiche/platform/spdy_ptr_util_impl.h | 23 -- .../quiche/platform/spdy_string_utils_impl.h | 18 +- .../active_quic_listener_config_test.cc | 4 +- .../quiche/envoy_quic_client_session_test.cc | 2 +- .../quiche/envoy_quic_client_stream_test.cc | 2 +- .../quiche/envoy_quic_server_session_test.cc | 8 +- .../quiche/envoy_quic_server_stream_test.cc | 2 +- .../quic_listeners/quiche/platform/BUILD | 7 +- .../quiche/platform/epoll_logging_impl.h | 8 +- .../quiche/platform/http2_platform_test.cc | 23 -- .../platform/http2_reconstruct_object_impl.h | 32 --- .../quiche/platform/quic_epoll_clock.h | 2 +- .../quiche/platform/quic_platform_test.cc | 6 - .../quiche/platform/quiche_platform_test.cc | 6 + .../quiche/platform/quiche_test_impl.h | 2 + .../quiche/platform/spdy_platform_test.cc | 13 -- .../quiche/platform/spdy_test_impl.h | 10 - 46 files changed, 405 insertions(+), 425 deletions(-) delete mode 100644 source/extensions/quic_listeners/quiche/platform/http2_export_impl.h delete mode 100644 source/extensions/quic_listeners/quiche/platform/quic_bbr2_sender_impl.h rename source/extensions/quic_listeners/quiche/platform/{spdy_map_util_impl.h => quiche_map_util_impl.h} (70%) rename source/extensions/quic_listeners/quiche/platform/{http2_optional_impl.h => quiche_optional_impl.h} (70%) rename source/extensions/quic_listeners/quiche/platform/{spdy_string_piece_impl.h => quiche_ptr_util_impl.h} (55%) delete mode 100644 source/extensions/quic_listeners/quiche/platform/spdy_export_impl.h delete mode 100644 source/extensions/quic_listeners/quiche/platform/spdy_ptr_util_impl.h delete mode 100644 test/extensions/quic_listeners/quiche/platform/http2_reconstruct_object_impl.h delete mode 100644 test/extensions/quic_listeners/quiche/platform/spdy_test_impl.h diff --git a/bazel/external/quiche.BUILD b/bazel/external/quiche.BUILD index ee780c98dd..480c960cee 100644 --- a/bazel/external/quiche.BUILD +++ b/bazel/external/quiche.BUILD @@ -59,6 +59,7 @@ quiche_copts = select({ # Remove these after upstream fix. "-Wno-unused-parameter", "-Wno-unused-function", + "-Wno-unused-const-variable", "-Wno-type-limits", # quic_inlined_frame.h uses offsetof() to optimize memory usage in frames. "-Wno-invalid-offsetof", @@ -67,13 +68,6 @@ quiche_copts = select({ ], }) -envoy_cc_test_library( - name = "http2_platform_reconstruct_object", - hdrs = ["quiche/http2/platform/api/http2_reconstruct_object.h"], - repository = "@envoy", - deps = ["@envoy//test/extensions/quic_listeners/quiche/platform:http2_platform_reconstruct_object_impl_lib"], -) - envoy_cc_test_library( name = "http2_test_tools_random", srcs = ["quiche/http2/test_tools/http2_random.cc"], @@ -89,12 +83,10 @@ envoy_cc_library( "quiche/http2/platform/api/http2_bug_tracker.h", "quiche/http2/platform/api/http2_containers.h", "quiche/http2/platform/api/http2_estimate_memory_usage.h", - "quiche/http2/platform/api/http2_export.h", "quiche/http2/platform/api/http2_flag_utils.h", "quiche/http2/platform/api/http2_flags.h", "quiche/http2/platform/api/http2_logging.h", "quiche/http2/platform/api/http2_macros.h", - "quiche/http2/platform/api/http2_optional.h", "quiche/http2/platform/api/http2_string_utils.h", # TODO: uncomment the following files as implementations are added. # "quiche/http2/platform/api/http2_test_helpers.h", @@ -452,6 +444,7 @@ envoy_cc_library( deps = [ ":http2_decoder_decode_buffer_lib", ":http2_decoder_decode_status_lib", + ":http2_hpack_decoder_hpack_decoding_error_lib", ":http2_hpack_decoder_hpack_entry_decoder_lib", ":http2_hpack_decoder_hpack_entry_decoder_listener_lib", ":http2_platform", @@ -471,6 +464,7 @@ envoy_cc_library( ":http2_hpack_decoder_hpack_decoder_listener_lib", ":http2_hpack_decoder_hpack_decoder_state_lib", ":http2_hpack_decoder_hpack_decoder_tables_lib", + ":http2_hpack_decoder_hpack_decoding_error_lib", ":http2_hpack_decoder_hpack_whole_entry_buffer_lib", ":http2_platform", ], @@ -500,6 +494,7 @@ envoy_cc_library( ":http2_hpack_decoder_hpack_decoder_listener_lib", ":http2_hpack_decoder_hpack_decoder_string_buffer_lib", ":http2_hpack_decoder_hpack_decoder_tables_lib", + ":http2_hpack_decoder_hpack_decoding_error_lib", ":http2_hpack_decoder_hpack_whole_entry_listener_lib", ":http2_hpack_hpack_constants_lib", ":http2_hpack_hpack_string_lib", @@ -534,6 +529,17 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "http2_hpack_decoder_hpack_decoding_error_lib", + srcs = ["quiche/http2/hpack/decoder/hpack_decoding_error.cc"], + hdrs = ["quiche/http2/hpack/decoder/hpack_decoding_error.h"], + copts = quiche_copts, + repository = "@envoy", + deps = [ + ":quiche_common_platform", + ], +) + envoy_cc_library( name = "http2_hpack_decoder_hpack_entry_decoder_lib", srcs = ["quiche/http2/hpack/decoder/hpack_entry_decoder.cc"], @@ -543,6 +549,7 @@ envoy_cc_library( deps = [ ":http2_decoder_decode_buffer_lib", ":http2_decoder_decode_status_lib", + ":http2_hpack_decoder_hpack_decoding_error_lib", ":http2_hpack_decoder_hpack_entry_decoder_listener_lib", ":http2_hpack_decoder_hpack_entry_type_decoder_lib", ":http2_hpack_decoder_hpack_string_decoder_lib", @@ -609,6 +616,7 @@ envoy_cc_library( repository = "@envoy", deps = [ ":http2_hpack_decoder_hpack_decoder_string_buffer_lib", + ":http2_hpack_decoder_hpack_decoding_error_lib", ":http2_hpack_decoder_hpack_entry_decoder_listener_lib", ":http2_hpack_decoder_hpack_whole_entry_listener_lib", ":http2_hpack_hpack_constants_lib", @@ -624,6 +632,7 @@ envoy_cc_library( repository = "@envoy", deps = [ ":http2_hpack_decoder_hpack_decoder_string_buffer_lib", + ":http2_hpack_decoder_hpack_decoding_error_lib", ":http2_hpack_hpack_constants_lib", ":http2_platform", ], @@ -718,14 +727,10 @@ envoy_cc_library( "quiche/spdy/platform/api/spdy_containers.h", "quiche/spdy/platform/api/spdy_endianness_util.h", "quiche/spdy/platform/api/spdy_estimate_memory_usage.h", - "quiche/spdy/platform/api/spdy_export.h", "quiche/spdy/platform/api/spdy_flags.h", "quiche/spdy/platform/api/spdy_logging.h", "quiche/spdy/platform/api/spdy_macros.h", - "quiche/spdy/platform/api/spdy_map_util.h", "quiche/spdy/platform/api/spdy_mem_slice.h", - "quiche/spdy/platform/api/spdy_ptr_util.h", - "quiche/spdy/platform/api/spdy_string_piece.h", "quiche/spdy/platform/api/spdy_string_utils.h", ], repository = "@envoy", @@ -745,13 +750,6 @@ envoy_cc_library( deps = [":spdy_platform"], ) -envoy_cc_test_library( - name = "spdy_platform_test", - hdrs = ["quiche/spdy/platform/api/spdy_test.h"], - repository = "@envoy", - deps = ["@envoy//test/extensions/quic_listeners/quiche/platform:spdy_platform_test_impl_lib"], -) - envoy_cc_test_library( name = "spdy_platform_test_helpers", hdrs = ["quiche/spdy/platform/api/spdy_test_helpers.h"], @@ -997,11 +995,11 @@ envoy_cc_test_library( copts = quiche_copts, repository = "@envoy", deps = [ + ":quiche_common_test_tools_test_utils_lib", ":spdy_core_header_block_lib", ":spdy_core_headers_handler_interface_lib", ":spdy_core_protocol_lib", ":spdy_platform", - ":spdy_platform_test", ], ) @@ -1015,14 +1013,12 @@ envoy_cc_library( envoy_cc_library( name = "quic_platform", srcs = [ - "quiche/quic/platform/api/quic_clock.cc", "quiche/quic/platform/api/quic_file_utils.cc", "quiche/quic/platform/api/quic_hostname_utils.cc", "quiche/quic/platform/api/quic_mutex.cc", ], hdrs = [ "quiche/quic/platform/api/quic_cert_utils.h", - "quiche/quic/platform/api/quic_clock.h", "quiche/quic/platform/api/quic_file_utils.h", "quiche/quic/platform/api/quic_hostname_utils.h", "quiche/quic/platform/api/quic_mutex.h", @@ -1079,14 +1075,6 @@ envoy_cc_library( ], ) -envoy_cc_library( - name = "quic_platform_bbr2_sender", - hdrs = ["quiche/quic/platform/api/quic_bbr2_sender.h"], - repository = "@envoy", - tags = ["nofips"], - deps = ["@envoy//source/extensions/quic_listeners/quiche/platform:quic_platform_bbr2_sender_impl_lib"], -) - envoy_cc_library( name = "quic_platform_export", hdrs = ["quiche/quic/platform/api/quic_export.h"], @@ -1228,6 +1216,21 @@ envoy_cc_library( ["@envoy//source/extensions/quic_listeners/quiche/platform:quiche_common_platform_export_impl_lib"], ) +envoy_cc_test_library( + name = "quiche_common_test_tools_test_utils_lib", + srcs = ["quiche/common/test_tools/quiche_test_utils.cc"], + hdrs = [ + "quiche/common/platform/api/quiche_test.h", + "quiche/common/test_tools/quiche_test_utils.h", + ], + repository = "@envoy", + tags = ["nofips"], + deps = [ + ":quiche_common_platform", + "@envoy//test/extensions/quic_listeners/quiche/platform:quiche_common_platform_test_impl_lib", + ], +) + #TODO(danzh) Figure out why using envoy_proto_library() fails. proto_library( name = "quic_core_proto_cached_network_parameters_proto", @@ -1373,6 +1376,20 @@ envoy_cc_library( deps = [":quic_platform_export"], ) +envoy_cc_library( + name = "quic_core_clock_lib", + srcs = ["quiche/quic/core/quic_clock.cc"], + hdrs = ["quiche/quic/core/quic_clock.h"], + copts = quiche_copts, + repository = "@envoy", + tags = ["nofips"], + visibility = ["//visibility:public"], + deps = [ + ":quic_core_time_lib", + ":quic_platform_base", + ], +) + envoy_cc_library( name = "quic_core_coalesced_packet_lib", srcs = ["quiche/quic/core/quic_coalesced_packet.cc"], @@ -1446,6 +1463,40 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "quic_core_congestion_control_bbr2_lib", + srcs = [ + "quiche/quic/core/congestion_control/bbr2_drain.cc", + "quiche/quic/core/congestion_control/bbr2_misc.cc", + "quiche/quic/core/congestion_control/bbr2_probe_bw.cc", + "quiche/quic/core/congestion_control/bbr2_probe_rtt.cc", + "quiche/quic/core/congestion_control/bbr2_sender.cc", + "quiche/quic/core/congestion_control/bbr2_startup.cc", + ], + hdrs = [ + "quiche/quic/core/congestion_control/bbr2_drain.h", + "quiche/quic/core/congestion_control/bbr2_misc.h", + "quiche/quic/core/congestion_control/bbr2_probe_bw.h", + "quiche/quic/core/congestion_control/bbr2_probe_rtt.h", + "quiche/quic/core/congestion_control/bbr2_sender.h", + "quiche/quic/core/congestion_control/bbr2_startup.h", + ], + copts = quiche_copts, + repository = "@envoy", + tags = ["nofips"], + deps = [ + ":quic_core_bandwidth_lib", + ":quic_core_congestion_control_bandwidth_sampler_lib", + ":quic_core_congestion_control_congestion_control_interface_lib", + ":quic_core_congestion_control_rtt_stats_lib", + ":quic_core_congestion_control_windowed_filter_lib", + ":quic_core_crypto_encryption_lib", + ":quic_core_time_lib", + ":quic_core_types_lib", + ":quic_platform", + ], +) + envoy_cc_library( name = "quic_core_congestion_control_general_loss_algorithm_lib", srcs = ["quiche/quic/core/congestion_control/general_loss_algorithm.cc"], @@ -1474,6 +1525,7 @@ envoy_cc_library( tags = ["nofips"], deps = [ ":quic_core_bandwidth_lib", + ":quic_core_clock_lib", ":quic_core_config_lib", ":quic_core_connection_stats_lib", ":quic_core_crypto_random_lib", @@ -1500,6 +1552,8 @@ envoy_cc_library( deps = [ ":quic_core_bandwidth_lib", ":quic_core_config_lib", + ":quic_core_congestion_control_bbr2_lib", + ":quic_core_congestion_control_bbr_lib", ":quic_core_congestion_control_tcp_cubic_bytes_lib", ":quic_core_connection_stats_lib", ":quic_core_crypto_random_lib", @@ -1508,7 +1562,6 @@ envoy_cc_library( ":quic_core_types_lib", ":quic_core_unacked_packet_map_lib", ":quic_platform", - ":quic_platform_bbr2_sender", ], ) @@ -1691,6 +1744,7 @@ envoy_cc_library( "quiche/quic/core/crypto/quic_compressed_certs_cache.cc", "quiche/quic/core/crypto/quic_crypto_client_config.cc", "quiche/quic/core/crypto/quic_crypto_server_config.cc", + "quiche/quic/core/crypto/server_proof_verifier.h", "quiche/quic/core/crypto/transport_parameters.cc", ], hdrs = [ @@ -1732,6 +1786,7 @@ envoy_cc_library( ], visibility = ["//visibility:public"], deps = [ + ":quic_core_clock_lib", ":quic_core_crypto_encryption_lib", ":quic_core_crypto_hkdf_lib", ":quic_core_crypto_proof_source_interface_lib", @@ -1886,6 +1941,17 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "quic_core_circular_deque_lib", + hdrs = ["quiche/quic/core/quic_circular_deque.h"], + copts = quiche_copts, + repository = "@envoy", + tags = ["nofips"], + deps = [ + ":quic_platform_export", + ], +) + envoy_cc_library( name = "quic_core_data_lib", srcs = [ @@ -1952,6 +2018,7 @@ envoy_cc_library( "quiche/quic/core/frames/quic_crypto_frame.cc", "quiche/quic/core/frames/quic_frame.cc", "quiche/quic/core/frames/quic_goaway_frame.cc", + "quiche/quic/core/frames/quic_handshake_done_frame.cc", "quiche/quic/core/frames/quic_max_streams_frame.cc", "quiche/quic/core/frames/quic_message_frame.cc", "quiche/quic/core/frames/quic_new_connection_id_frame.cc", @@ -1975,6 +2042,7 @@ envoy_cc_library( "quiche/quic/core/frames/quic_crypto_frame.h", "quiche/quic/core/frames/quic_frame.h", "quiche/quic/core/frames/quic_goaway_frame.h", + "quiche/quic/core/frames/quic_handshake_done_frame.h", "quiche/quic/core/frames/quic_inlined_frame.h", "quiche/quic/core/frames/quic_max_streams_frame.h", "quiche/quic/core/frames/quic_message_frame.h", @@ -2064,6 +2132,7 @@ envoy_cc_library( tags = ["nofips"], visibility = ["//visibility:public"], deps = [ + ":quic_core_circular_deque_lib", ":quic_core_packets_lib", ":quic_platform_base", ":spdy_core_header_block_lib", @@ -2231,6 +2300,7 @@ envoy_cc_library( repository = "@envoy", tags = ["nofips"], deps = [ + ":quic_core_circular_deque_lib", ":quic_core_interval_lib", ":quic_core_types_lib", ":quic_platform", @@ -2290,6 +2360,7 @@ envoy_cc_library( repository = "@envoy", tags = ["nofips"], deps = [ + ":quic_core_circular_deque_lib", ":quic_core_coalesced_packet_lib", ":quic_core_constants_lib", ":quic_core_crypto_encryption_lib", @@ -2309,6 +2380,7 @@ envoy_cc_library( repository = "@envoy", tags = ["nofips"], deps = [ + ":quic_core_circular_deque_lib", ":quic_core_constants_lib", ":quic_core_types_lib", ":quic_platform_base", @@ -2773,6 +2845,7 @@ envoy_cc_library( "quiche/quic/core/quic_crypto_server_handshaker.cc", "quiche/quic/core/quic_crypto_server_stream.cc", "quiche/quic/core/quic_crypto_stream.cc", + "quiche/quic/core/quic_datagram_queue.cc", "quiche/quic/core/quic_flow_controller.cc", "quiche/quic/core/quic_session.cc", "quiche/quic/core/quic_stream.cc", @@ -2793,11 +2866,13 @@ envoy_cc_library( "quiche/quic/core/quic_crypto_server_handshaker.h", "quiche/quic/core/quic_crypto_server_stream.h", "quiche/quic/core/quic_crypto_stream.h", + "quiche/quic/core/quic_datagram_queue.h", "quiche/quic/core/quic_flow_controller.h", "quiche/quic/core/quic_session.h", "quiche/quic/core/quic_stream.h", "quiche/quic/core/quic_stream_id_manager.h", "quiche/quic/core/quic_stream_sequencer.h", + "quiche/quic/core/stream_delegate_interface.h", "quiche/quic/core/tls_client_handshaker.h", "quiche/quic/core/tls_handshaker.h", "quiche/quic/core/tls_server_handshaker.h", @@ -2873,6 +2948,7 @@ envoy_cc_library( tags = ["nofips"], visibility = ["//visibility:public"], deps = [ + ":quic_core_circular_deque_lib", ":quic_core_data_lib", ":quic_core_frames_frames_lib", ":quic_core_interval_deque_lib", @@ -3138,8 +3214,8 @@ envoy_cc_test_library( repository = "@envoy", tags = ["nofips"], deps = [ + ":quic_core_clock_lib", ":quic_core_time_lib", - ":quic_platform", ], ) @@ -3282,6 +3358,7 @@ envoy_cc_test_library( ":quic_test_tools_sent_packet_manager_peer_lib", ":quic_test_tools_simple_quic_framer_lib", ":quic_test_tools_stream_peer_lib", + ":quiche_common_test_tools_test_utils_lib", ":spdy_core_framer_lib", ], ) @@ -3342,9 +3419,11 @@ envoy_cc_library( "quiche/common/platform/api/quiche_arraysize.h", "quiche/common/platform/api/quiche_export.h", "quiche/common/platform/api/quiche_logging.h", + "quiche/common/platform/api/quiche_map_util.h", + "quiche/common/platform/api/quiche_optional.h", + "quiche/common/platform/api/quiche_ptr_util.h", "quiche/common/platform/api/quiche_str_cat.h", "quiche/common/platform/api/quiche_string_piece.h", - "quiche/common/platform/api/quiche_test.h", "quiche/common/platform/api/quiche_text_utils.h", "quiche/common/platform/api/quiche_unordered_containers.h", ], @@ -3376,11 +3455,22 @@ envoy_cc_test_library( envoy_cc_library( name = "quiche_common_lib", - hdrs = ["quiche/common/simple_linked_hash_map.h"], + srcs = [ + "quiche/common/quiche_data_reader.cc", + "quiche/common/quiche_data_writer.cc", + ], + hdrs = [ + "quiche/common/quiche_data_reader.h", + "quiche/common/quiche_data_writer.h", + "quiche/common/simple_linked_hash_map.h", + ], repository = "@envoy", tags = ["nofips"], visibility = ["//visibility:public"], - deps = [":quiche_common_platform"], + deps = [ + ":quiche_common_platform", + ":quiche_common_platform_endian", + ], ) envoy_cc_test( @@ -3427,8 +3517,8 @@ envoy_cc_test( repository = "@envoy", tags = ["nofips"], deps = [ + ":quiche_common_test_tools_test_utils_lib", ":spdy_platform", - ":spdy_platform_test", ], ) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 5dbbb706e4..b5b2d4b595 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -268,9 +268,9 @@ REPOSITORY_LOCATIONS = dict( urls = ["https://storage.googleapis.com/envoyproxy-wee8/wee8-8.0.426.12.tar.gz"], ), com_googlesource_quiche = dict( - # Static snapshot of https://quiche.googlesource.com/quiche/+archive/85240a12ed2b9ccb08ae449bca1bbf9eb93c8a12.tar.gz - sha256 = "63ca7aa58511beb8cd6e6b93dbb25154bd14c8c8a316a1b20430e830060fa7db", - urls = ["https://storage.googleapis.com/quiche-envoy-integration/85240a12ed2b9ccb08ae449bca1bbf9eb93c8a12.tar.gz"], + # Static snapshot of https://quiche.googlesource.com/quiche/+archive/372452f3cea7ef3888eb1bedb19a041a037fd7a7.tar.gz + sha256 = "4993b776fe596f141366d62f09c1f8e91be9f968631477a8e8e1432f0569391c", + urls = ["https://storage.googleapis.com/quiche-envoy-integration/372452f3cea7ef3888eb1bedb19a041a037fd7a7.tar.gz"], ), com_google_cel_cpp = dict( sha256 = "b4eaf871d4910c599bb70eaef2eec852747989f15f26885353b7c5188a940ca8", diff --git a/source/extensions/quic_listeners/quiche/BUILD b/source/extensions/quic_listeners/quiche/BUILD index 93dac2bac3..dde1927d81 100644 --- a/source/extensions/quic_listeners/quiche/BUILD +++ b/source/extensions/quic_listeners/quiche/BUILD @@ -18,6 +18,7 @@ envoy_cc_library( "//include/envoy/event:dispatcher_interface", "//include/envoy/event:timer_interface", "@com_googlesource_quiche//:quic_core_alarm_interface_lib", + "@com_googlesource_quiche//:quic_core_clock_lib", ], ) diff --git a/source/extensions/quic_listeners/quiche/active_quic_listener.cc b/source/extensions/quic_listeners/quiche/active_quic_listener.cc index b79ef84e3e..3a167c78d4 100644 --- a/source/extensions/quic_listeners/quiche/active_quic_listener.cc +++ b/source/extensions/quic_listeners/quiche/active_quic_listener.cc @@ -117,8 +117,8 @@ ActiveQuicListenerFactory::ActiveQuicListenerFactory( quic_config_.set_max_time_before_crypto_handshake( quic::QuicTime::Delta::FromMilliseconds(max_time_before_crypto_handshake_ms)); int32_t max_streams = PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, max_concurrent_streams, 100); - quic_config_.SetMaxIncomingBidirectionalStreamsToSend(max_streams); - quic_config_.SetMaxIncomingUnidirectionalStreamsToSend(max_streams); + quic_config_.SetMaxBidirectionalStreamsToSend(max_streams); + quic_config_.SetMaxUnidirectionalStreamsToSend(max_streams); } Network::ConnectionHandler::ActiveListenerPtr diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_alarm.h b/source/extensions/quic_listeners/quiche/envoy_quic_alarm.h index 115e68d1f8..ffe4d020e0 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_alarm.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_alarm.h @@ -6,8 +6,8 @@ #include "common/common/assert.h" #include "quiche/quic/core/quic_alarm.h" +#include "quiche/quic/core/quic_clock.h" #include "quiche/quic/core/quic_time.h" -#include "quiche/quic/platform/api/quic_clock.h" namespace Envoy { namespace Quic { diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_session.cc b/source/extensions/quic_listeners/quiche/envoy_quic_client_session.cc index 646540ca98..930e470528 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_session.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_session.cc @@ -55,9 +55,10 @@ void EnvoyQuicClientSession::OnGoAway(const quic::QuicGoAwayFrame& frame) { } } -void EnvoyQuicClientSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) { - quic::QuicSpdyClientSession::OnCryptoHandshakeEvent(event); - if (event == HANDSHAKE_CONFIRMED) { +void EnvoyQuicClientSession::SetDefaultEncryptionLevel(quic::EncryptionLevel level) { + quic::QuicSpdyClientSession::SetDefaultEncryptionLevel(level); + if (level == quic::ENCRYPTION_FORWARD_SECURE) { + // This is only reached once, when handshake is done. raiseConnectionEvent(Network::ConnectionEvent::Connected); } } diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_session.h b/source/extensions/quic_listeners/quiche/envoy_quic_client_session.h index 364478c041..a3b2542dfb 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_session.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_session.h @@ -56,7 +56,7 @@ class EnvoyQuicClientSession : public QuicFilterManagerConnectionImpl, void OnCanWrite() override; void OnGoAway(const quic::QuicGoAwayFrame& frame) override; // quic::QuicSpdyClientSessionBase - void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override; + void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override; using quic::QuicSpdyClientSession::stream_map; diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_session.cc b/source/extensions/quic_listeners/quiche/envoy_quic_server_session.cc index 77457350d4..cc8f60d22c 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_session.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_session.cc @@ -35,11 +35,12 @@ absl::string_view EnvoyQuicServerSession::requestedServerName() const { return {GetCryptoStream()->crypto_negotiated_params().sni}; } -quic::QuicCryptoServerStreamBase* EnvoyQuicServerSession::CreateQuicCryptoServerStream( +std::unique_ptr +EnvoyQuicServerSession::CreateQuicCryptoServerStream( const quic::QuicCryptoServerConfig* crypto_config, quic::QuicCompressedCertsCache* compressed_certs_cache) { - return new quic::QuicCryptoServerStream(crypto_config, compressed_certs_cache, this, - stream_helper()); + return quic::CreateCryptoServerStream(crypto_config, compressed_certs_cache, this, + stream_helper()); } quic::QuicSpdyStream* EnvoyQuicServerSession::CreateIncomingStream(quic::QuicStreamId id) { @@ -100,9 +101,10 @@ void EnvoyQuicServerSession::OnCanWrite() { maybeApplyDelayClosePolicy(); } -void EnvoyQuicServerSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) { - quic::QuicServerSessionBase::OnCryptoHandshakeEvent(event); - if (event == HANDSHAKE_CONFIRMED) { +void EnvoyQuicServerSession::SetDefaultEncryptionLevel(quic::EncryptionLevel level) { + quic::QuicServerSessionBase::SetDefaultEncryptionLevel(level); + if (level == quic::ENCRYPTION_FORWARD_SECURE) { + // This is only reached once, when handshake is done. raiseConnectionEvent(Network::ConnectionEvent::Connected); } } diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_session.h b/source/extensions/quic_listeners/quiche/envoy_quic_server_session.h index 50d348fb5f..74edb84523 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_session.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_session.h @@ -52,13 +52,13 @@ class EnvoyQuicServerSession : public quic::QuicServerSessionBase, void SendGoAway(quic::QuicErrorCode error_code, const std::string& reason) override; void OnCanWrite() override; // quic::QuicSpdySession - void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override; + void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override; using quic::QuicSession::stream_map; protected: // quic::QuicServerSessionBase - quic::QuicCryptoServerStreamBase* + std::unique_ptr CreateQuicCryptoServerStream(const quic::QuicCryptoServerConfig* crypto_config, quic::QuicCompressedCertsCache* compressed_certs_cache) override; diff --git a/source/extensions/quic_listeners/quiche/platform/BUILD b/source/extensions/quic_listeners/quiche/platform/BUILD index 4dbe056f46..50981c860b 100644 --- a/source/extensions/quic_listeners/quiche/platform/BUILD +++ b/source/extensions/quic_listeners/quiche/platform/BUILD @@ -66,12 +66,10 @@ envoy_cc_library( "http2_bug_tracker_impl.h", "http2_containers_impl.h", "http2_estimate_memory_usage_impl.h", - "http2_export_impl.h", "http2_flag_utils_impl.h", "http2_flags_impl.h", "http2_logging_impl.h", "http2_macros_impl.h", - "http2_optional_impl.h", "http2_string_utils_impl.h", ], external_deps = [ @@ -231,14 +229,6 @@ envoy_cc_library( ], ) -envoy_cc_library( - name = "quic_platform_bbr2_sender_impl_lib", - hdrs = ["quic_bbr2_sender_impl.h"], - tags = ["nofips"], - visibility = ["//visibility:public"], - deps = ["@com_googlesource_quiche//:quic_core_congestion_control_bbr_lib"], -) - envoy_cc_library( name = "envoy_quic_clock_lib", srcs = ["envoy_quic_clock.cc"], @@ -247,7 +237,7 @@ envoy_cc_library( visibility = ["//visibility:public"], deps = [ "//include/envoy/event:dispatcher_interface", - "@com_googlesource_quiche//:quic_platform", + "@com_googlesource_quiche//:quic_core_clock_lib", ], ) @@ -256,6 +246,9 @@ envoy_cc_library( hdrs = [ "quiche_arraysize_impl.h", "quiche_logging_impl.h", + "quiche_map_util_impl.h", + "quiche_optional_impl.h", + "quiche_ptr_util_impl.h", "quiche_str_cat_impl.h", "quiche_string_piece_impl.h", "quiche_text_utils_impl.h", @@ -280,14 +273,10 @@ envoy_cc_library( "spdy_containers_impl.h", "spdy_endianness_util_impl.h", "spdy_estimate_memory_usage_impl.h", - "spdy_export_impl.h", "spdy_flags_impl.h", "spdy_logging_impl.h", "spdy_macros_impl.h", - "spdy_map_util_impl.h", "spdy_mem_slice_impl.h", - "spdy_ptr_util_impl.h", - "spdy_string_piece_impl.h", "spdy_string_utils_impl.h", "spdy_test_helpers_impl.h", "spdy_test_utils_prod_impl.h", diff --git a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h index 5a85ebf932..275b20b567 100644 --- a/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h +++ b/source/extensions/quic_listeners/quiche/platform/envoy_quic_clock.h @@ -4,7 +4,7 @@ #include "envoy/event/dispatcher.h" -#include "quiche/quic/platform/api/quic_clock.h" +#include "quiche/quic/core/quic_clock.h" namespace Envoy { namespace Quic { diff --git a/source/extensions/quic_listeners/quiche/platform/flags_list.h b/source/extensions/quic_listeners/quiche/platform/flags_list.h index e48bf5cd1d..8d50defbd8 100644 --- a/source/extensions/quic_listeners/quiche/platform/flags_list.h +++ b/source/extensions/quic_listeners/quiche/platform/flags_list.h @@ -17,6 +17,10 @@ QUICHE_FLAG(bool, quic_reloadable_flag_advertise_quic_for_https_for_debugips, fa QUICHE_FLAG(bool, quic_reloadable_flag_advertise_quic_for_https_for_external_users, false, "") +QUICHE_FLAG(bool, quic_reloadable_flag_quic_ack_delay_alarm_granularity, false, + "When true, ensure the ACK delay is never less than the alarm granularity when ACK " + "decimation is enabled.") + QUICHE_FLAG(bool, quic_reloadable_flag_quic_allow_backend_set_stream_ttl, false, "If true, check backend response header for X-Response-Ttl. If it is provided, the " "stream TTL is set. A QUIC stream will be immediately canceled when tries to write " @@ -28,11 +32,16 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, true, QUICHE_FLAG(bool, quic_reloadable_flag_quic_alpn_dispatch, false, "Support different QUIC sessions, as indicated by ALPN. Used for QBONE.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr2_cut_inflight_hi_gradually, false, - "If true, QUIC BBRv2 will cut inflight_hi gradually upon loss from PROBE_UP.") +QUICHE_FLAG( + bool, quic_reloadable_flag_quic_batch_writer_flush_after_mtu_probe, false, + "If true and batch writer is used, QuicConnection will flush after a mtu probe is sent.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr2_exit_probe_bw_down_after_one_rtt, false, - "If true, for QUIC BBRv2 flows, exit PROBE_BW_DOWN phase after one round trip time.") +QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr2_always_count_loss_events, false, + "If true, QUIC BBRv2 will always count the number of loss events in a round, instead " + "of just counting it in STARTUP.") + +QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr2_cut_inflight_hi_gradually, true, + "If true, QUIC BBRv2 will cut inflight_hi gradually upon loss from PROBE_UP.") QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr_donot_inject_bandwidth, true, "If true, do not inject bandwidth in BbrSender::AdjustNetworkParameters.") @@ -44,8 +53,12 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr_flexible_app_limited, false, "When true and the BBR9 connection option is present, BBR only considers bandwidth " "samples app-limited if they're not filling the pipe.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr_less_probe_rtt, false, - "Enables 3 new connection options to make PROBE_RTT more aggressive.") +QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr_loss_based_startup_exit, true, + "If true, support QUIC BBRv2-style loss based startup exit in BBRv1.") + +QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr_mitigate_overly_large_bandwidth_sample, true, + "If true, when cwnd gets bootstrapped and causing badly overshoot, reset cwnd and " + "pacing rate based on measured bw.") QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr_no_bytes_acked_in_startup_recovery, false, "When in STARTUP and recovery, do not add bytes_acked to QUIC BBR's CWND in " @@ -55,30 +68,25 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr_one_mss_conservation, false, "When true, ensure BBR allows at least one MSS to be sent in response to an ACK in " "packet conservation.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr_slower_startup4, true, - "Enables the BBQ5 connection option, which forces saved aggregation values to expire " - "when the bandwidth increases more than 25% in QUIC BBR STARTUP.") - QUICHE_FLAG(bool, quic_reloadable_flag_quic_bbr_startup_rate_reduction, false, "When true, enables the BBS4 and BBS5 connection options, which reduce BBR's pacing " "rate in STARTUP as more losses occur as a fraction of CWND.") +QUICHE_FLAG(bool, quic_reloadable_flag_quic_better_mtu_packet_check, false, + "If true, QuicConnection will check MTU_DISCOVERY_FRAME in nonretransmittable_frames " + "to see if a packet is a MTU probe.") + +QUICHE_FLAG(bool, quic_reloadable_flag_quic_bundle_retransmittable_with_pto_ack, false, + "When the EACK connection option is sent by the client, an ack-eliciting frame is " + "bundled with ACKs sent after the PTO fires.") + QUICHE_FLAG(bool, quic_reloadable_flag_quic_bw_sampler_remove_packets_once_per_congestion_event2, - false, + true, "If true, quic::BandwidthSampler will solely rely on RemoveObsoletePackets, which is " "called once per congestion event, to remove packets from its connection_state_map_.") -QUICHE_FLAG( - bool, quic_reloadable_flag_quic_close_all_encryptions_levels2, false, - "If true, QUIC connection close packet will be sent at all available encryption levels.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_close_connection_and_discard_data_on_wrong_offset, - false, - "If true, when a stream receives data with wrong close offset, it closes the " - "connection. And the stream frame data will be discarded.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_close_connection_on_failed_consume_data_fast_path, true, - "If true, close connection if CreateAndSerializeStreamFrame fails.") +QUICHE_FLAG(bool, quic_reloadable_flag_quic_check_handshake_timeout_before_idle_timeout, false, + "If true, QuicConnection will check handshake timeout before idle timeout.") QUICHE_FLAG(bool, quic_reloadable_flag_quic_conservative_bursts, false, "If true, set burst token to 2 in cwnd bootstrapping experiment.") @@ -86,7 +94,7 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_conservative_bursts, false, QUICHE_FLAG(bool, quic_reloadable_flag_quic_conservative_cwnd_and_pacing_gains, false, "If true, uses conservative cwnd gain and pacing gain when cwnd gets bootstrapped.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_create_server_handshaker_in_constructor, false, +QUICHE_FLAG(bool, quic_reloadable_flag_quic_create_server_handshaker_in_constructor, true, "If true, QuicCryptoServerStream creates its HandshakerDelegate in its constructor " "instead of in OnSuccessfulVersionNegotiation") @@ -100,9 +108,6 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_default_to_bbr_v2, false, "If true, use BBRv2 as the default congestion controller. Takes precedence over " "--quic_default_to_bbr.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_delete_send_rst_stream_inner, false, - "If true, QuicSession::SendRstStreamInner will be factored out and deleted.") - QUICHE_FLAG(bool, quic_reloadable_flag_quic_disable_version_q043, false, "If true, disable QUIC version Q043.") @@ -128,32 +133,15 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_t QUICHE_FLAG(bool, quic_reloadable_flag_quic_drop_small_initial_packets, false, "If true, the QUIC dispatcher will drop INITIAL packets that are too small.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_ack_decimation, false, +QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_ack_decimation, true, "Default enables QUIC ack decimation and adds a connection option to disable it.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_fifo_write_scheduler, true, - "If true and FIFO connection option is received, write_blocked_streams uses " - "FIFO(stream with smallest ID has highest priority) write scheduler.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_ietf_loss_detection, true, - "If true, enable IETF loss detection as described in " - "https://tools.ietf.org/html/draft-ietf-quic-recovery-22#section-6.1.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_lifo_write_scheduler, true, - "If true and LIFO connection option is received, write_blocked_streams uses " - "LIFO(stream with largest ID has highest priority) write scheduler.") - QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_pcc3, false, "If true, enable experiment for testing PCC congestion-control.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_pto, true, "If true, enable probe timeout.") - QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_rr_write_scheduler, true, "If true, enable HTTP/2 default scheduling(round robin).") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_version_q099, false, - "If true, enable QUIC version Q099.") - QUICHE_FLAG(bool, quic_reloadable_flag_quic_enable_version_t050, false, "If true, enable QUIC version T050.") @@ -165,15 +153,20 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_enabled, false, "") QUICHE_FLAG(bool, quic_reloadable_flag_quic_fix_bbr_cwnd_in_bandwidth_resumption, true, "If true, adjust congestion window when doing bandwidth resumption in BBR.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_interval_deque, false, - "If true, frames will be hold in an optimized wrapper data structure.") +QUICHE_FLAG(bool, quic_reloadable_flag_quic_interval_deque, true, + "If true, frames will be held in an optimized wrapper data structure.") QUICHE_FLAG(bool, quic_reloadable_flag_quic_listener_never_fake_epollout, false, "If true, QuicListener::OnSocketIsWritable will always return false, which means there " "will never be a fake EPOLLOUT event in the next epoll iteration.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_log_ack_aggregation_stats, false, - "If true, log number of ack aggregation epochs in QUIC transport connection stats.") +QUICHE_FLAG(bool, quic_reloadable_flag_quic_log_bbr_flags_and_num_cycles, false, + "If true, for QUIC BBRv1 and v2, log bbr_flags and number of PROBE_BW cycles into " + "transport connection stats.") + +QUICHE_FLAG(bool, quic_reloadable_flag_quic_log_coalesce_stream_frame_frequency, true, + "If true, the frequency of stream frame coalescing will be logged as " + "QuicSession.CoalesceStreamFrameStatus.") QUICHE_FLAG(bool, quic_reloadable_flag_quic_monotonic_epoll_clock, false, "If true, QuicEpollClock::Now() will monotonically increase.") @@ -181,24 +174,25 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_monotonic_epoll_clock, false, QUICHE_FLAG(bool, quic_reloadable_flag_quic_negotiate_ack_delay_time, false, "If true, will negotiate the ACK delay time.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_neuter_handshake_packets_once2, true, - "Call NeuterHandshakePackets() at most once per connection.") +QUICHE_FLAG( + bool, quic_reloadable_flag_quic_neuter_unencrypted_control_frames, false, + "If true, neuter unencrypted control frames in QuicUnackedPacketMap::NeuterUnencryptedPackets.") QUICHE_FLAG(bool, quic_reloadable_flag_quic_no_dup_experiment_id_2, false, "If true, transport connection stats doesn't report duplicated experiments for same " "connection.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_no_v2_scaling_factor, false, - "When true, don't use an extra scaling factor when reading packets from QUIC's RX_RING " - "with TPACKET_V2.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_on_packet_numbers_skipped, false, - "If true, add a up call when N packet numbers get skipped.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_one_bw_sample_per_ack_event, false, +QUICHE_FLAG(bool, quic_reloadable_flag_quic_one_bw_sample_per_ack_event2, true, "If true, QUIC will call bandwidth sampler once per ack event, instead of once per " "acked packet.") +QUICHE_FLAG( + bool, quic_reloadable_flag_quic_one_immediate_ack, false, + "If true, enable the 1ACK connection option to only send 1 immediate ACK after reordering.") + +QUICHE_FLAG(bool, quic_reloadable_flag_quic_populate_mean_rtt_deviation_in_tcs, true, + "If true, populate mean rtt deviation in transport connection stats.") + QUICHE_FLAG(bool, quic_reloadable_flag_quic_proxy_write_packed_strings, false, "If true, QuicProxyDispatcher will write packed_client_address and packed_server_vip " "in TcpProxyHeaderProto.") @@ -213,7 +207,7 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_require_handshake_confirmation, fals "If true, require handshake confirmation for QUIC connections, functionally disabling " "0-rtt handshakes.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_sanitize_ack_delay, false, +QUICHE_FLAG(bool, quic_reloadable_flag_quic_sanitize_ack_delay, true, "If true, QuicSentPacketManager will cap ack_delay to peer_advertized_ack_delay before " "using it.") @@ -224,8 +218,9 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_send_timestamps, false, QUICHE_FLAG(bool, quic_reloadable_flag_quic_server_push, true, "If true, enable server push feature on QUIC.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_skip_packet_number_for_pto, true, - "If true, skip packet number before sending the last PTO retransmission.") +QUICHE_FLAG(bool, quic_reloadable_flag_quic_set_send_algorithm_noop_if_cc_type_unchanged, false, + "If true, QuicSentPacketManager::SetSendAlgorithm(CongestionControlType) will become a " + "no-op if the current and the requested cc_type are the same.") QUICHE_FLAG(bool, quic_reloadable_flag_quic_testonly_default_false, false, "A testonly reloadable flag that will always default to false.") @@ -233,9 +228,6 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_testonly_default_false, false, QUICHE_FLAG(bool, quic_reloadable_flag_quic_testonly_default_true, true, "A testonly reloadable flag that will always default to true.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_tracegraf_populate_ack_packet_number, true, - "If true, populate packet_number of received ACK in tracegraf.") - QUICHE_FLAG(bool, quic_reloadable_flag_quic_tracegraf_populate_rtt_variation, true, "If true, QUIC tracegraf populates RTT variation.") @@ -243,16 +235,9 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_unified_iw_options, false, "When true, set the initial congestion control window from connection options in " "QuicSentPacketManager rather than TcpCubicSenderBytes.") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_use_common_stream_check, false, - "If true, use common code for checking whether a new stream ID may be allocated.") - -QUICHE_FLAG( - bool, quic_reloadable_flag_quic_use_connection_encryption_level, true, - "If true, QuicCryptoStream::OnCryptoFrame() will never use the frame's encryption level.") - -QUICHE_FLAG(bool, quic_reloadable_flag_quic_use_handshaker_delegate2, false, - "If true, QUIC crypto handshaker uses handshaker delegate to notify session about " - "handshake events.") +QUICHE_FLAG(bool, quic_reloadable_flag_quic_use_get_handshake_state, false, + "If true, instead of getting handshake state from sent packet manager, ask session for " + "current handshake state.") QUICHE_FLAG(bool, quic_reloadable_flag_quic_use_header_stage_idle_list2, false, "If true, use header stage idle list for QUIC connections in GFE.") @@ -275,22 +260,15 @@ QUICHE_FLAG(bool, quic_reloadable_flag_quic_use_quic_time_for_received_timestamp "If true, use QuicClock::Now() for the fallback source of packet received time instead " "of WallNow().") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_use_session_max_inbound_header_list_size, false, +QUICHE_FLAG(bool, quic_reloadable_flag_quic_use_session_max_inbound_header_list_size, true, "Use SpdySession::max_inbound_header_list_size() instead of " "QuicHeaderList::max_header_list_size().") -QUICHE_FLAG(bool, quic_reloadable_flag_quic_version_negotiated_by_default_at_server, false, - "If true, for server QUIC connections, set version_negotiated_ to true by default.") - QUICHE_FLAG(bool, quic_reloadable_flag_send_quic_fallback_server_config_on_leto_error, false, "If true and using Leto for QUIC shared-key calculations, GFE will react to a failure " "to contact Leto by sending a REJ containing a fallback ServerConfig, allowing the " "client to continue the handshake.") -QUICHE_FLAG(bool, quic_restart_flag_do_not_create_raw_socket_selector_if_quic_enabled, true, - "If true, do not create the RawSocketSelector in QuicListener::Initialize() if QUIC is " - "disabled by flag.") - QUICHE_FLAG( bool, quic_restart_flag_dont_fetch_quic_private_keys_from_leto, false, "If true, GFE will not request private keys when fetching QUIC ServerConfigs from Leto.") @@ -299,15 +277,8 @@ QUICHE_FLAG( bool, quic_restart_flag_quic_allow_loas_multipacket_chlo, false, "If true, inspects QUIC CHLOs for kLOAS and early creates sessions to allow multi-packet CHLOs") -QUICHE_FLAG(bool, quic_restart_flag_quic_allow_very_long_connection_ids, false, - "If true, allow connection IDs of length [21,255] in version negotiation packets.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_coalesce_stream_frames_2, true, - "If true, adjacent stream frames will be coalesced into one.") - -QUICHE_FLAG(bool, quic_restart_flag_quic_default_on_ietf_loss_detection, false, - "If true, default on IETF style loss detection with 1/4 RTT time threshold and " - "adaptive packet threshold.") +QUICHE_FLAG(bool, quic_restart_flag_quic_fix_handling_of_bad_prox_packet, true, + "If true, correctly stop processing bad PROX packets.") QUICHE_FLAG( bool, quic_restart_flag_quic_no_cap_net_raw_for_usps_egress, false, @@ -319,6 +290,14 @@ QUICHE_FLAG(bool, quic_restart_flag_quic_no_fallback_for_pigeon_socket, false, QUICHE_FLAG(bool, quic_restart_flag_quic_offload_pacing_to_usps2, false, "If true, QUIC offload pacing when using USPS as egress method.") +QUICHE_FLAG(bool, quic_restart_flag_quic_remove_quic_socket_utils_from_gfe, false, + "If true, replace calls to QuicSocketUtils functions by QuicUdpSocketApi or " + "QuicLinuxSocketUtils functions.") + +QUICHE_FLAG(bool, quic_restart_flag_quic_remove_quic_socket_utils_from_packet_reader, false, + "If true, in QuicPacketReader, replace the use of QuicSocketUtils by equivalent " + "QuicUdpSocketApi or QuicLinuxSocketUtils functions.") + QUICHE_FLAG(bool, quic_restart_flag_quic_rx_ring_use_tpacket_v3, false, "If true, use TPACKET_V3 for QuicRxRing instead of TPACKET_V2.") @@ -328,9 +307,6 @@ QUICHE_FLAG(bool, quic_restart_flag_quic_testonly_default_false, false, QUICHE_FLAG(bool, quic_restart_flag_quic_testonly_default_true, true, "A testonly restart flag that will always default to true.") -QUICHE_FLAG(bool, quic_restart_flag_quic_use_circular_deque, true, - "If true, replace the backing type of QuicDeque from std::deque to QuicCircularDeque.") - QUICHE_FLAG( bool, quic_restart_flag_quic_use_leto_for_quic_configs, false, "If true, use Leto to fetch QUIC server configs instead of using the seeds from Memento.") @@ -339,6 +315,35 @@ QUICHE_FLAG(bool, quic_restart_flag_quic_use_pigeon_socket_to_backend, false, "If true, create a shared pigeon socket for all quic to backend connections and switch " "to use it after successful handshake.") +QUICHE_FLAG(bool, quic_restart_flag_quic_use_rxring_when_explicitly_specified, false, + "If true, GFE will use QuicRxRing for ingress only when ingress_method is explicitly " + "set to RXRING_INGRESS in quic_config.") + +QUICHE_FLAG( + bool, http2_reloadable_flag_http2_backend_alpn_failure_error_code, false, + "If true, the GFE will return a new ResponseCodeDetails error when ALPN to the backend fails.") + +QUICHE_FLAG(bool, http2_reloadable_flag_http2_security_requirement_for_client3, false, + "If true, check whether client meets security requirements during SSL handshake. If " + "flag is true and client does not meet security requirements, do not negotiate HTTP/2 " + "with client or terminate the session with SPDY_INADEQUATE_SECURITY if HTTP/2 is " + "already negotiated. The spec contains both cipher and TLS version requirements.") + +QUICHE_FLAG( + bool, http2_reloadable_flag_http2_skip_querying_entry_buffer_error, false, + "If true, do not query entry_buffer_.error_detected() in HpackDecoder::error_detected().") + +QUICHE_FLAG(bool, http2_reloadable_flag_quic_use_http2_priority_write_scheduler, true, + "If true and H2PR connection option is received, write_blocked_streams_ uses HTTP2 " + "(tree-style) priority write scheduler.") + +QUICHE_FLAG( + bool, spdy_reloadable_flag_spdy_discard_response_body_if_disallowed, false, + "If true, SPDY will discard all response body bytes when response code indicates no response " + "body should exist. Previously, we only discard partial bytes on the first response processing " + "and the rest of the response bytes would still be delivered even though the response code " + "said there should not be any body associated with the response code.") + QUICHE_FLAG(bool, quic_allow_chlo_buffering, true, "If true, allows packets to be buffered in anticipation of a " "future CHLO, and allow CHLO packets to be buffered until next " @@ -388,6 +393,9 @@ QUICHE_FLAG(bool, quic_export_server_num_packets_per_write_histogram, false, QUICHE_FLAG(bool, quic_disable_version_negotiation_grease_randomness, false, "If true, use predictable version negotiation versions.") +QUICHE_FLAG(bool, quic_enable_http3_grease_randomness, true, + "If true, use random greased settings and frames.") + QUICHE_FLAG(int64_t, quic_max_tracked_packet_count, 10000, "Maximum number of tracked packets.") QUICHE_FLAG(bool, quic_prober_uses_length_prefixed_connection_ids, false, @@ -415,10 +423,16 @@ QUICHE_FLAG(double, quic_bbr2_default_loss_threshold, 0.3, QUICHE_FLAG(int32_t, quic_bbr2_default_startup_full_loss_count, 8, "The default minimum number of loss marking events to exit STARTUP.") +QUICHE_FLAG(int32_t, quic_bbr2_default_probe_bw_full_loss_count, 2, + "The default minimum number of loss marking events to exit PROBE_UP phase.") + QUICHE_FLAG(double, quic_bbr2_default_inflight_hi_headroom, 0.01, "The default fraction of unutilized headroom to try to leave in path " "upon high loss.") +QUICHE_FLAG(int32_t, quic_bbr2_default_initial_ack_height_filter_window, 10, + "The default initial value of the max ack height filter's window length.") + QUICHE_FLAG(double, quic_ack_aggregation_bandwidth_threshold, 1.0, "If the bandwidth during ack aggregation is smaller than (estimated " "bandwidth * this flag), consider the current aggregation completed " @@ -431,8 +445,6 @@ QUICHE_FLAG(int32_t, quic_anti_amplification_factor, 3, QUICHE_FLAG(int32_t, quic_max_buffered_crypto_bytes, 16 * 1024, "The maximum amount of CRYPTO frame data that can be buffered.") -QUICHE_FLAG(bool, quic_allow_http3_priority, false, "If true, support HTTP/3 priority") - QUICHE_FLAG(int32_t, quic_max_aggressive_retransmittable_on_wire_ping_count, 0, "If set to non-zero, the maximum number of consecutive pings that " "can be sent with aggressive initial retransmittable on wire timeout " diff --git a/source/extensions/quic_listeners/quiche/platform/http2_export_impl.h b/source/extensions/quic_listeners/quiche/platform/http2_export_impl.h deleted file mode 100644 index 802f6fb591..0000000000 --- a/source/extensions/quic_listeners/quiche/platform/http2_export_impl.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#define HTTP2_EXPORT -#define HTTP2_EXPORT_PRIVATE diff --git a/source/extensions/quic_listeners/quiche/platform/http2_flags_impl.h b/source/extensions/quic_listeners/quiche/platform/http2_flags_impl.h index f1b53f4067..7d25614697 100644 --- a/source/extensions/quic_listeners/quiche/platform/http2_flags_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/http2_flags_impl.h @@ -12,3 +12,7 @@ #define SetHttp2ReloadableFlagImpl(flag, value) \ quiche::FLAGS_http2_reloadable_flag_##flag->SetValue(value) + +#define HTTP2_CODE_COUNT_N_IMPL(flag, instance, total) \ + do { \ + } while (0) diff --git a/source/extensions/quic_listeners/quiche/platform/http2_logging_impl.h b/source/extensions/quic_listeners/quiche/platform/http2_logging_impl.h index 473c2d00d4..1f2dd7d037 100644 --- a/source/extensions/quic_listeners/quiche/platform/http2_logging_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/http2_logging_impl.h @@ -8,16 +8,16 @@ #include "extensions/quic_listeners/quiche/platform/quic_logging_impl.h" -#define HTTP2_LOG_IMPL(severity) QUIC_LOG_IMPL(severity) +#define HTTP2_LOG_IMPL(severity) QUICHE_LOG_IMPL(severity) -#define HTTP2_VLOG_IMPL(verbose_level) QUIC_VLOG_IMPL(verbose_level) +#define HTTP2_VLOG_IMPL(verbose_level) QUICHE_VLOG_IMPL(verbose_level) -#define HTTP2_DLOG_IMPL(severity) QUIC_DLOG_IMPL(severity) +#define HTTP2_DLOG_IMPL(severity) QUICHE_DLOG_IMPL(severity) -#define HTTP2_DLOG_IF_IMPL(severity, condition) QUIC_DLOG_IF_IMPL(severity, condition) +#define HTTP2_DLOG_IF_IMPL(severity, condition) QUICHE_DLOG_IF_IMPL(severity, condition) -#define HTTP2_DVLOG_IMPL(verbose_level) QUIC_DVLOG_IMPL(verbose_level) +#define HTTP2_DVLOG_IMPL(verbose_level) QUICHE_DVLOG_IMPL(verbose_level) -#define HTTP2_DVLOG_IF_IMPL(verbose_level, condition) QUIC_DVLOG_IF_IMPL(verbose_level, condition) +#define HTTP2_DVLOG_IF_IMPL(verbose_level, condition) QUICHE_DVLOG_IF_IMPL(verbose_level, condition) -#define HTTP2_DLOG_EVERY_N_IMPL(severity, n) QUIC_DLOG_EVERY_N_IMPL(severity, n) +#define HTTP2_DLOG_EVERY_N_IMPL(severity, n) QUICHE_DLOG_EVERY_N_IMPL(severity, n) diff --git a/source/extensions/quic_listeners/quiche/platform/quic_bbr2_sender_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_bbr2_sender_impl.h deleted file mode 100644 index 8995e1a443..0000000000 --- a/source/extensions/quic_listeners/quiche/platform/quic_bbr2_sender_impl.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include "quiche/quic/core/congestion_control/bbr_sender.h" - -namespace quic { - -using QuicBbr2SenderImpl = BbrSender; - -} // namespace quic diff --git a/source/extensions/quic_listeners/quiche/platform/quic_bug_tracker_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_bug_tracker_impl.h index 050bd385d8..02f9cb1017 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_bug_tracker_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quic_bug_tracker_impl.h @@ -10,7 +10,7 @@ // TODO(wub): Implement exponential back off to avoid performance problems due // to excessive QUIC_BUG. -#define QUIC_BUG_IMPL QUIC_LOG_IMPL(DFATAL) -#define QUIC_BUG_IF_IMPL(condition) QUIC_LOG_IF_IMPL(DFATAL, condition) -#define QUIC_PEER_BUG_IMPL QUIC_LOG_IMPL(ERROR) -#define QUIC_PEER_BUG_IF_IMPL(condition) QUIC_LOG_IF_IMPL(ERROR, condition) +#define QUIC_BUG_IMPL QUICHE_LOG_IMPL(DFATAL) +#define QUIC_BUG_IF_IMPL(condition) QUICHE_LOG_IF_IMPL(DFATAL, condition) +#define QUIC_PEER_BUG_IMPL QUICHE_LOG_IMPL(ERROR) +#define QUIC_PEER_BUG_IF_IMPL(condition) QUICHE_LOG_IF_IMPL(ERROR, condition) diff --git a/source/extensions/quic_listeners/quiche/platform/quic_logging_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_logging_impl.h index 43dfe66613..551abc6fbc 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_logging_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quic_logging_impl.h @@ -29,44 +29,44 @@ // If |condition| is true, use |logstream| to stream the log message and send it to spdlog. // If |condition| is false, |logstream| will not be instantiated. // The switch(0) is used to suppress a compiler warning on ambiguous "else". -#define QUIC_LOG_IMPL_INTERNAL(condition, logstream) \ +#define QUICHE_LOG_IMPL_INTERNAL(condition, logstream) \ switch (0) \ default: \ if (!(condition)) { \ } else \ logstream -#define QUIC_LOG_IF_IMPL(severity, condition) \ - QUIC_LOG_IMPL_INTERNAL((condition) && quic::IsLogLevelEnabled(quic::severity), \ - quic::QuicLogEmitter(quic::severity).stream()) +#define QUICHE_LOG_IF_IMPL(severity, condition) \ + QUICHE_LOG_IMPL_INTERNAL((condition) && quic::IsLogLevelEnabled(quic::severity), \ + quic::QuicLogEmitter(quic::severity).stream()) -#define QUIC_LOG_IMPL(severity) QUIC_LOG_IF_IMPL(severity, true) +#define QUICHE_LOG_IMPL(severity) QUICHE_LOG_IF_IMPL(severity, true) -#define QUIC_VLOG_IF_IMPL(verbosity, condition) \ - QUIC_LOG_IMPL_INTERNAL((condition) && quic::IsVerboseLogEnabled(verbosity), \ - quic::QuicLogEmitter(quic::INFO).stream()) +#define QUICHE_VLOG_IF_IMPL(verbosity, condition) \ + QUICHE_LOG_IMPL_INTERNAL((condition) && quic::IsVerboseLogEnabled(verbosity), \ + quic::QuicLogEmitter(quic::INFO).stream()) -#define QUIC_VLOG_IMPL(verbosity) QUIC_VLOG_IF_IMPL(verbosity, true) +#define QUICHE_VLOG_IMPL(verbosity) QUICHE_VLOG_IF_IMPL(verbosity, true) -// TODO(wub): Implement QUIC_LOG_FIRST_N_IMPL. -#define QUIC_LOG_FIRST_N_IMPL(severity, n) QUIC_LOG_IMPL(severity) +// TODO(wub): Implement QUICHE_LOG_FIRST_N_IMPL. +#define QUICHE_LOG_FIRST_N_IMPL(severity, n) QUICHE_LOG_IMPL(severity) -// TODO(wub): Implement QUIC_LOG_EVERY_N_IMPL. -#define QUIC_LOG_EVERY_N_IMPL(severity, n) QUIC_LOG_IMPL(severity) +// TODO(wub): Implement QUICHE_LOG_EVERY_N_IMPL. +#define QUICHE_LOG_EVERY_N_IMPL(severity, n) QUICHE_LOG_IMPL(severity) -// TODO(wub): Implement QUIC_LOG_EVERY_N_SEC_IMPL. -#define QUIC_LOG_EVERY_N_SEC_IMPL(severity, seconds) QUIC_LOG_IMPL(severity) +// TODO(wub): Implement QUICHE_LOG_EVERY_N_SEC_IMPL. +#define QUICHE_LOG_EVERY_N_SEC_IMPL(severity, seconds) QUICHE_LOG_IMPL(severity) -#define QUIC_PLOG_IMPL(severity) \ - QUIC_LOG_IMPL_INTERNAL(quic::IsLogLevelEnabled(quic::severity), \ - quic::QuicLogEmitter(quic::severity).SetPerror().stream()) +#define QUICHE_PLOG_IMPL(severity) \ + QUICHE_LOG_IMPL_INTERNAL(quic::IsLogLevelEnabled(quic::severity), \ + quic::QuicLogEmitter(quic::severity).SetPerror().stream()) -#define QUIC_LOG_INFO_IS_ON_IMPL() quic::IsLogLevelEnabled(quic::INFO) -#define QUIC_LOG_WARNING_IS_ON_IMPL() quic::IsLogLevelEnabled(quic::WARNING) -#define QUIC_LOG_ERROR_IS_ON_IMPL() quic::IsLogLevelEnabled(quic::ERROR) +#define QUICHE_LOG_INFO_IS_ON_IMPL() quic::IsLogLevelEnabled(quic::INFO) +#define QUICHE_LOG_WARNING_IS_ON_IMPL() quic::IsLogLevelEnabled(quic::WARNING) +#define QUICHE_LOG_ERROR_IS_ON_IMPL() quic::IsLogLevelEnabled(quic::ERROR) #define CHECK(condition) \ - QUIC_LOG_IF_IMPL(FATAL, ABSL_PREDICT_FALSE(!(condition))) << "CHECK failed: " #condition "." + QUICHE_LOG_IF_IMPL(FATAL, ABSL_PREDICT_FALSE(!(condition))) << "CHECK failed: " #condition "." #define CHECK_GT(a, b) CHECK((a) > (b)) #define CHECK_GE(a, b) CHECK((a) >= (b)) @@ -77,26 +77,26 @@ #ifdef NDEBUG // Release build -#define DCHECK(condition) QUIC_COMPILED_OUT_LOG(condition) -#define QUIC_COMPILED_OUT_LOG(condition) \ - QUIC_LOG_IMPL_INTERNAL(false && (condition), quic::NullLogStream().stream()) -#define QUIC_DVLOG_IMPL(verbosity) QUIC_COMPILED_OUT_LOG(false) -#define QUIC_DVLOG_IF_IMPL(verbosity, condition) QUIC_COMPILED_OUT_LOG(condition) -#define QUIC_DLOG_IMPL(severity) QUIC_COMPILED_OUT_LOG(false) -#define QUIC_DLOG_IF_IMPL(severity, condition) QUIC_COMPILED_OUT_LOG(condition) -#define QUIC_DLOG_INFO_IS_ON_IMPL() 0 -#define QUIC_DLOG_EVERY_N_IMPL(severity, n) QUIC_COMPILED_OUT_LOG(false) -#define QUIC_NOTREACHED_IMPL() +#define DCHECK(condition) QUICHE_COMPILED_OUT_LOG(condition) +#define QUICHE_COMPILED_OUT_LOG(condition) \ + QUICHE_LOG_IMPL_INTERNAL(false && (condition), quic::NullLogStream().stream()) +#define QUICHE_DVLOG_IMPL(verbosity) QUICHE_COMPILED_OUT_LOG(false) +#define QUICHE_DVLOG_IF_IMPL(verbosity, condition) QUICHE_COMPILED_OUT_LOG(condition) +#define QUICHE_DLOG_IMPL(severity) QUICHE_COMPILED_OUT_LOG(false) +#define QUICHE_DLOG_IF_IMPL(severity, condition) QUICHE_COMPILED_OUT_LOG(condition) +#define QUICHE_DLOG_INFO_IS_ON_IMPL() 0 +#define QUICHE_DLOG_EVERY_N_IMPL(severity, n) QUICHE_COMPILED_OUT_LOG(false) +#define QUICHE_NOTREACHED_IMPL() #else // Debug build #define DCHECK(condition) CHECK(condition) -#define QUIC_DVLOG_IMPL(verbosity) QUIC_VLOG_IMPL(verbosity) -#define QUIC_DVLOG_IF_IMPL(verbosity, condition) QUIC_VLOG_IF_IMPL(verbosity, condition) -#define QUIC_DLOG_IMPL(severity) QUIC_LOG_IMPL(severity) -#define QUIC_DLOG_IF_IMPL(severity, condition) QUIC_LOG_IF_IMPL(severity, condition) -#define QUIC_DLOG_INFO_IS_ON_IMPL() QUIC_LOG_INFO_IS_ON_IMPL() -#define QUIC_DLOG_EVERY_N_IMPL(severity, n) QUIC_LOG_EVERY_N_IMPL(severity, n) -#define QUIC_NOTREACHED_IMPL() NOT_REACHED_GCOVR_EXCL_LINE +#define QUICHE_DVLOG_IMPL(verbosity) QUICHE_VLOG_IMPL(verbosity) +#define QUICHE_DVLOG_IF_IMPL(verbosity, condition) QUICHE_VLOG_IF_IMPL(verbosity, condition) +#define QUICHE_DLOG_IMPL(severity) QUICHE_LOG_IMPL(severity) +#define QUICHE_DLOG_IF_IMPL(severity, condition) QUICHE_LOG_IF_IMPL(severity, condition) +#define QUICHE_DLOG_INFO_IS_ON_IMPL() QUICHE_LOG_INFO_IS_ON_IMPL() +#define QUICHE_DLOG_EVERY_N_IMPL(severity, n) QUICHE_LOG_EVERY_N_IMPL(severity, n) +#define QUICHE_NOTREACHED_IMPL() NOT_REACHED_GCOVR_EXCL_LINE #endif #define DCHECK_GE(a, b) DCHECK((a) >= (b)) @@ -106,7 +106,7 @@ #define DCHECK_NE(a, b) DCHECK((a) != (b)) #define DCHECK_EQ(a, b) DCHECK((a) == (b)) -#define QUIC_PREDICT_FALSE_IMPL(x) ABSL_PREDICT_FALSE(x) +#define QUICHE_PREDICT_FALSE_IMPL(x) ABSL_PREDICT_FALSE(x) namespace quic { @@ -167,7 +167,7 @@ inline bool IsVerboseLogEnabled(int verbosity) { bool IsDFatalExitDisabled(); void SetDFatalExitDisabled(bool is_disabled); -// QuicLogSink is used to capture logs emitted from the QUIC_LOG... macros. +// QuicLogSink is used to capture logs emitted from the QUICHE_LOG... macros. class QuicLogSink { public: virtual ~QuicLogSink() = default; diff --git a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.cc b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.cc index 10ba3647f5..8f71e70040 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.cc +++ b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.cc @@ -12,13 +12,13 @@ namespace quic { -QuicMemSliceImpl::QuicMemSliceImpl(QuicBufferAllocator* /*allocator*/, size_t length) { - Envoy::Buffer::RawSlice iovec; - uint64_t num_iov = single_slice_buffer_.reserve(length, &iovec, 1); - ASSERT(num_iov == 1); - // OwnedImpl may return a slice longer than needed, trim it to requested length. - iovec.len_ = length; - single_slice_buffer_.commit(&iovec, 1); +QuicMemSliceImpl::QuicMemSliceImpl(QuicUniqueBufferPtr buffer, size_t length) + : fragment_(std::make_unique( + buffer.release(), length, + [](const void* p, size_t, const Envoy::Buffer::BufferFragmentImpl*) { + delete static_cast(p); + })) { + single_slice_buffer_.addBufferFragment(*fragment_); ASSERT(this->length() == length); } diff --git a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.h index e1dc857ae5..8b6986a072 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_impl.h @@ -23,11 +23,8 @@ class QuicMemSliceImpl { // Constructs an empty QuicMemSliceImpl. QuicMemSliceImpl() = default; - // Constructs a QuicMemSliceImpl by letting |single_slice_buffer_| allocate |length| memory. - // TODO(danzh) Note that |allocator| is not used to allocate memory currently, instead, - // Buffer::OwnedImpl allocates memory on its own. Investigate if a customized - // QuicBufferAllocator can improve cache hit. - QuicMemSliceImpl(QuicBufferAllocator* allocator, size_t length); + // Constructs a QuicMemSliceImpl by taking ownership of the memory in |buffer|. + QuicMemSliceImpl(QuicUniqueBufferPtr buffer, size_t length); // Constructs a QuicMemSliceImpl from a Buffer::Instance with first |length| bytes in it. // Data will be moved from |buffer| to this mem slice. @@ -42,6 +39,7 @@ class QuicMemSliceImpl { QuicMemSliceImpl& operator=(const QuicMemSliceImpl& other) = delete; QuicMemSliceImpl& operator=(QuicMemSliceImpl&& other) noexcept { if (this != &other) { + fragment_ = std::move(other.fragment_); single_slice_buffer_.move(other.single_slice_buffer_); } return *this; @@ -62,6 +60,7 @@ class QuicMemSliceImpl { // Prerequisite: buffer has at least one slice. size_t firstSliceLength(Envoy::Buffer::Instance& buffer); + std::unique_ptr fragment_; Envoy::Buffer::OwnedImpl single_slice_buffer_; }; diff --git a/source/extensions/quic_listeners/quiche/platform/spdy_map_util_impl.h b/source/extensions/quic_listeners/quiche/platform/quiche_map_util_impl.h similarity index 70% rename from source/extensions/quic_listeners/quiche/platform/spdy_map_util_impl.h rename to source/extensions/quic_listeners/quiche/platform/quiche_map_util_impl.h index befd8c7f8c..434b8d70f3 100644 --- a/source/extensions/quic_listeners/quiche/platform/spdy_map_util_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quiche_map_util_impl.h @@ -6,13 +6,11 @@ // consumed or referenced directly by other Envoy code. It serves purely as a // porting layer for QUICHE. -#include - -namespace spdy { +namespace quiche { template -bool SpdyContainsKeyImpl(const Collection& collection, const Key& key) { +bool QuicheContainsKeyImpl(const Collection& collection, const Key& key) { return collection.find(key) != collection.end(); } -} // namespace spdy +} // namespace quiche diff --git a/source/extensions/quic_listeners/quiche/platform/http2_optional_impl.h b/source/extensions/quic_listeners/quiche/platform/quiche_optional_impl.h similarity index 70% rename from source/extensions/quic_listeners/quiche/platform/http2_optional_impl.h rename to source/extensions/quic_listeners/quiche/platform/quiche_optional_impl.h index 5f1cd8b30b..7cc2237ca3 100644 --- a/source/extensions/quic_listeners/quiche/platform/http2_optional_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quiche_optional_impl.h @@ -8,8 +8,8 @@ // consumed or referenced directly by other Envoy code. It serves purely as a // porting layer for QUICHE. -namespace http2 { +namespace quiche { -template using Http2OptionalImpl = absl::optional; +template using QuicheOptionalImpl = absl::optional; -} // namespace http2 +} // namespace quiche diff --git a/source/extensions/quic_listeners/quiche/platform/spdy_string_piece_impl.h b/source/extensions/quic_listeners/quiche/platform/quiche_ptr_util_impl.h similarity index 55% rename from source/extensions/quic_listeners/quiche/platform/spdy_string_piece_impl.h rename to source/extensions/quic_listeners/quiche/platform/quiche_ptr_util_impl.h index 46e9695bb7..aaebe5d5c3 100644 --- a/source/extensions/quic_listeners/quiche/platform/spdy_string_piece_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quiche_ptr_util_impl.h @@ -1,15 +1,17 @@ #pragma once -#include "absl/strings/string_view.h" - // NOLINT(namespace-envoy) // This file is part of the QUICHE platform implementation, and is not to be // consumed or referenced directly by other Envoy code. It serves purely as a // porting layer for QUICHE. -namespace spdy { +#include "absl/memory/memory.h" + +namespace quiche { -using SpdyStringPieceImpl = absl::string_view; +template std::unique_ptr QuicheWrapUniqueImpl(T* ptr) { + return absl::WrapUnique(ptr); +} -} // namespace spdy +} // namespace quiche diff --git a/source/extensions/quic_listeners/quiche/platform/quiche_string_piece_impl.h b/source/extensions/quic_listeners/quiche/platform/quiche_string_piece_impl.h index 0ee96a12eb..474e50b781 100644 --- a/source/extensions/quic_listeners/quiche/platform/quiche_string_piece_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quiche_string_piece_impl.h @@ -1,5 +1,8 @@ #pragma once +#include "extensions/quic_listeners/quiche/platform/quic_logging_impl.h" + +#include "absl/hash/hash.h" #include "absl/strings/string_view.h" // NOLINT(namespace-envoy) @@ -12,4 +15,10 @@ namespace quiche { using QuicheStringPieceImpl = absl::string_view; +using QuicheStringPieceHashImpl = absl::Hash; + +inline size_t QuicheHashStringPairImpl(QuicheStringPieceImpl a, QuicheStringPieceImpl b) { + return absl::Hash()(a) ^ absl::Hash()(b); +} + } // namespace quiche diff --git a/source/extensions/quic_listeners/quiche/platform/quiche_unordered_containers_impl.h b/source/extensions/quic_listeners/quiche/platform/quiche_unordered_containers_impl.h index cefb261521..508efe2ee0 100644 --- a/source/extensions/quic_listeners/quiche/platform/quiche_unordered_containers_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quiche_unordered_containers_impl.h @@ -15,7 +15,7 @@ namespace quiche { template using QuicheDefaultHasherImpl = absl::Hash; // Similar to std::unordered_map, but with better performance and memory usage. -template -using QuicheUnorderedMapImpl = absl::node_hash_map; +template +using QuicheUnorderedMapImpl = absl::node_hash_map; } // namespace quiche diff --git a/source/extensions/quic_listeners/quiche/platform/spdy_containers_impl.h b/source/extensions/quic_listeners/quiche/platform/spdy_containers_impl.h index d0205a46e3..8b13c993f1 100644 --- a/source/extensions/quic_listeners/quiche/platform/spdy_containers_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/spdy_containers_impl.h @@ -6,8 +6,6 @@ // consumed or referenced directly by other Envoy code. It serves purely as a // porting layer for QUICHE. -#include "extensions/quic_listeners/quiche/platform/spdy_string_piece_impl.h" - #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/container/inlined_vector.h" @@ -24,18 +22,12 @@ using SpdyHashMapImpl = absl::flat_hash_map; template using SpdyHashSetImpl = absl::flat_hash_set; -template -using SpdyLinkedHashMapImpl = quiche::SimpleLinkedHashMap; +template +using SpdyLinkedHashMapImpl = quiche::SimpleLinkedHashMap; template > using SpdyInlinedVectorImpl = absl::InlinedVector; -using SpdyStringPieceHashImpl = absl::Hash; - -inline size_t SpdyHashStringPairImpl(SpdyStringPieceImpl a, SpdyStringPieceImpl b) { - return absl::Hash>()(std::make_pair(a, b)); -} - template using SpdySmallMapImpl = absl::flat_hash_map; } // namespace spdy diff --git a/source/extensions/quic_listeners/quiche/platform/spdy_export_impl.h b/source/extensions/quic_listeners/quiche/platform/spdy_export_impl.h deleted file mode 100644 index 1b1c46a816..0000000000 --- a/source/extensions/quic_listeners/quiche/platform/spdy_export_impl.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#define SPDY_EXPORT -#define SPDY_EXPORT_PRIVATE diff --git a/source/extensions/quic_listeners/quiche/platform/spdy_flags_impl.h b/source/extensions/quic_listeners/quiche/platform/spdy_flags_impl.h index b0d690b4bf..8ab7fc87e2 100644 --- a/source/extensions/quic_listeners/quiche/platform/spdy_flags_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/spdy_flags_impl.h @@ -11,3 +11,7 @@ #define GetSpdyReloadableFlagImpl(flag) quiche::FLAGS_spdy_reloadable_flag_##flag->value() #define GetSpdyRestartFlagImpl(flag) quiche::FLAGS_spdy_restart_flag_##flag->value() + +#define SPDY_CODE_COUNT_N_IMPL(flag, instance, total) \ + do { \ + } while (0) diff --git a/source/extensions/quic_listeners/quiche/platform/spdy_logging_impl.h b/source/extensions/quic_listeners/quiche/platform/spdy_logging_impl.h index 4a21b95ab3..7c98e7ca62 100644 --- a/source/extensions/quic_listeners/quiche/platform/spdy_logging_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/spdy_logging_impl.h @@ -8,14 +8,14 @@ #include "extensions/quic_listeners/quiche/platform/quic_logging_impl.h" -#define SPDY_LOG_IMPL(severity) QUIC_LOG_IMPL(severity) +#define SPDY_LOG_IMPL(severity) QUICHE_LOG_IMPL(severity) -#define SPDY_VLOG_IMPL(verbose_level) QUIC_VLOG_IMPL(verbose_level) +#define SPDY_VLOG_IMPL(verbose_level) QUICHE_VLOG_IMPL(verbose_level) -#define SPDY_DLOG_IMPL(severity) QUIC_DLOG_IMPL(severity) +#define SPDY_DLOG_IMPL(severity) QUICHE_DLOG_IMPL(severity) -#define SPDY_DLOG_IF_IMPL(severity, condition) QUIC_DLOG_IF_IMPL(severity, condition) +#define SPDY_DLOG_IF_IMPL(severity, condition) QUICHE_DLOG_IF_IMPL(severity, condition) -#define SPDY_DVLOG_IMPL(verbose_level) QUIC_DVLOG_IMPL(verbose_level) +#define SPDY_DVLOG_IMPL(verbose_level) QUICHE_DVLOG_IMPL(verbose_level) -#define SPDY_DVLOG_IF_IMPL(verbose_level, condition) QUIC_DVLOG_IF_IMPL(verbose_level, condition) +#define SPDY_DVLOG_IF_IMPL(verbose_level, condition) QUICHE_DVLOG_IF_IMPL(verbose_level, condition) diff --git a/source/extensions/quic_listeners/quiche/platform/spdy_ptr_util_impl.h b/source/extensions/quic_listeners/quiche/platform/spdy_ptr_util_impl.h deleted file mode 100644 index 5613f12f5c..0000000000 --- a/source/extensions/quic_listeners/quiche/platform/spdy_ptr_util_impl.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include - -#include "absl/memory/memory.h" - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -namespace spdy { - -template std::unique_ptr SpdyMakeUniqueImpl(Args&&... args) { - return std::make_unique(std::forward(args)...); -} - -template std::unique_ptr SpdyWrapUniqueImpl(T* ptr) { - return absl::WrapUnique(ptr); -} - -} // namespace spdy diff --git a/source/extensions/quic_listeners/quiche/platform/spdy_string_utils_impl.h b/source/extensions/quic_listeners/quiche/platform/spdy_string_utils_impl.h index 20a44e88d1..08884d56b8 100644 --- a/source/extensions/quic_listeners/quiche/platform/spdy_string_utils_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/spdy_string_utils_impl.h @@ -9,16 +9,13 @@ #include "extensions/quic_listeners/quiche/platform/string_utils.h" #include "absl/strings/escaping.h" +#include "absl/strings/match.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "fmt/printf.h" namespace spdy { -template inline std::string SpdyStrCatImpl(const Args&... args) { - return absl::StrCat(std::forward(args)...); -} - template inline void SpdyStrAppendImpl(std::string* output, const Args&... args) { absl::StrAppend(output, std::forward(args)...); @@ -44,4 +41,17 @@ inline std::string SpdyHexEncodeUInt32AndTrimImpl(uint32_t data) { inline std::string SpdyHexDumpImpl(absl::string_view data) { return quiche::HexDump(data); } +struct SpdyStringPieceCaseHashImpl { + size_t operator()(quiche::QuicheStringPiece data) const { + std::string lower = absl::AsciiStrToLower(data); + return absl::Hash()(lower); + } +}; + +struct SpdyStringPieceCaseEqImpl { + bool operator()(absl::string_view piece1, absl::string_view piece2) const { + return absl::EqualsIgnoreCase(piece1, piece2); + } +}; + } // namespace spdy diff --git a/test/extensions/quic_listeners/quiche/active_quic_listener_config_test.cc b/test/extensions/quic_listeners/quiche/active_quic_listener_config_test.cc index 2077101e81..b93afa375e 100644 --- a/test/extensions/quic_listeners/quiche/active_quic_listener_config_test.cc +++ b/test/extensions/quic_listeners/quiche/active_quic_listener_config_test.cc @@ -36,8 +36,8 @@ TEST(ActiveQuicListenerConfigTest, CreateActiveQuicListenerFactory) { EXPECT_NE(nullptr, listener_factory); quic::QuicConfig& quic_config = ActiveQuicListenerFactoryPeer::quicConfig( dynamic_cast(*listener_factory)); - EXPECT_EQ(10u, quic_config.GetMaxIncomingBidirectionalStreamsToSend()); - EXPECT_EQ(10u, quic_config.GetMaxIncomingUnidirectionalStreamsToSend()); + EXPECT_EQ(10u, quic_config.GetMaxBidirectionalStreamsToSend()); + EXPECT_EQ(10u, quic_config.GetMaxUnidirectionalStreamsToSend()); EXPECT_EQ(2000u, quic_config.IdleNetworkTimeout().ToMilliseconds()); // Default value if not present in config. EXPECT_EQ(20000u, quic_config.max_time_before_crypto_handshake().ToMilliseconds()); diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc index 91d9f62ab2..714321df06 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc @@ -95,7 +95,7 @@ class EnvoyQuicClientSessionTest : public testing::TestWithParam { : api_(Api::createApiForTest(time_system_)), dispatcher_(api_->allocateDispatcher()), connection_helper_(*dispatcher_), alarm_factory_(*dispatcher_, *connection_helper_.GetClock()), quic_version_([]() { - SetQuicReloadableFlag(quic_enable_version_q099, GetParam()); + SetQuicReloadableFlag(quic_enable_version_t099, GetParam()); return quic::ParsedVersionOfIndex(quic::CurrentSupportedVersions(), 0); }()), peer_addr_(Network::Utility::getAddressWithPort(*Network::Utility::getIpv6LoopbackAddress(), diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc index 78975aa7a7..260138a4cf 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc @@ -26,7 +26,7 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { : api_(Api::createApiForTest()), dispatcher_(api_->allocateDispatcher()), connection_helper_(*dispatcher_), alarm_factory_(*dispatcher_, *connection_helper_.GetClock()), quic_version_([]() { - SetQuicReloadableFlag(quic_enable_version_q099, GetParam()); + SetQuicReloadableFlag(quic_enable_version_t099, GetParam()); return quic::CurrentSupportedVersions()[0]; }()), peer_addr_(Network::Utility::getAddressWithPort(*Network::Utility::getIpv6LoopbackAddress(), diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc index 618967c5b1..323b1a2d88 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc @@ -85,6 +85,12 @@ class TestEnvoyQuicServerSession : public EnvoyQuicServerSession { class TestQuicCryptoServerStream : public quic::QuicCryptoServerStream { public: + explicit TestQuicCryptoServerStream(const quic::QuicCryptoServerConfig* crypto_config, + quic::QuicCompressedCertsCache* compressed_certs_cache, + quic::QuicSession* session, + quic::QuicCryptoServerStream::Helper* helper) + : quic::QuicCryptoServerStream(crypto_config, compressed_certs_cache, session, helper) {} + using quic::QuicCryptoServerStream::QuicCryptoServerStream; bool encryption_established() const override { return true; } @@ -96,7 +102,7 @@ class EnvoyQuicServerSessionTest : public testing::TestWithParam { : api_(Api::createApiForTest(time_system_)), dispatcher_(api_->allocateDispatcher()), connection_helper_(*dispatcher_), alarm_factory_(*dispatcher_, *connection_helper_.GetClock()), quic_version_([]() { - SetQuicReloadableFlag(quic_enable_version_q099, GetParam()); + SetQuicReloadableFlag(quic_enable_version_t099, GetParam()); return quic::ParsedVersionOfIndex(quic::CurrentSupportedVersions(), 0); }()), listener_stats_({ALL_LISTENER_STATS(POOL_COUNTER(listener_config_.listenerScope()), diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc index b58dada95f..22ab4fdf80 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc @@ -31,7 +31,7 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { : api_(Api::createApiForTest()), dispatcher_(api_->allocateDispatcher()), connection_helper_(*dispatcher_), alarm_factory_(*dispatcher_, *connection_helper_.GetClock()), quic_version_([]() { - SetQuicReloadableFlag(quic_enable_version_q099, GetParam()); + SetQuicReloadableFlag(quic_enable_version_t099, GetParam()); return quic::CurrentSupportedVersions()[0]; }()), listener_stats_({ALL_LISTENER_STATS(POOL_COUNTER(listener_config_.listenerScope()), diff --git a/test/extensions/quic_listeners/quiche/platform/BUILD b/test/extensions/quic_listeners/quiche/platform/BUILD index 55717a9abc..ced7bf9465 100644 --- a/test/extensions/quic_listeners/quiche/platform/BUILD +++ b/test/extensions/quic_listeners/quiche/platform/BUILD @@ -27,7 +27,6 @@ envoy_cc_test( "//source/extensions/quic_listeners/quiche/platform:flags_impl_lib", "//test/test_common:logging_lib", "//test/test_common:utility_lib", - "@com_googlesource_quiche//:http2_platform_reconstruct_object", "@com_googlesource_quiche//:http2_test_tools_random", ], ) @@ -106,11 +105,6 @@ envoy_cc_test_library( ], ) -envoy_cc_test_library( - name = "http2_platform_reconstruct_object_impl_lib", - hdrs = ["http2_reconstruct_object_impl.h"], -) - envoy_cc_test_library( name = "quic_platform_epoll_clock_lib", srcs = select({ @@ -123,6 +117,7 @@ envoy_cc_test_library( }), tags = ["nofips"], deps = [ + "@com_googlesource_quiche//:quic_core_clock_lib", "@com_googlesource_quiche//:quic_platform", "@com_googlesource_quiche//:quic_platform_epoll_lib", ], diff --git a/test/extensions/quic_listeners/quiche/platform/epoll_logging_impl.h b/test/extensions/quic_listeners/quiche/platform/epoll_logging_impl.h index 36ca6d4f79..e61e383d84 100644 --- a/test/extensions/quic_listeners/quiche/platform/epoll_logging_impl.h +++ b/test/extensions/quic_listeners/quiche/platform/epoll_logging_impl.h @@ -10,11 +10,11 @@ namespace epoll_server { -#define EPOLL_LOG_IMPL(severity) QUIC_LOG_IMPL(severity) -#define EPOLL_VLOG_IMPL(verbosity) QUIC_VLOG_IMPL(verbosity) +#define EPOLL_LOG_IMPL(severity) QUICHE_LOG_IMPL(severity) +#define EPOLL_VLOG_IMPL(verbosity) QUICHE_VLOG_IMPL(verbosity) -#define EPOLL_PLOG_IMPL(severity) QUIC_PLOG_IMPL(severity) +#define EPOLL_PLOG_IMPL(severity) QUICHE_PLOG_IMPL(severity) -#define EPOLL_DVLOG_IMPL(verbosity) QUIC_DVLOG_IMPL(verbosity) +#define EPOLL_DVLOG_IMPL(verbosity) QUICHE_DVLOG_IMPL(verbosity) } // namespace epoll_server diff --git a/test/extensions/quic_listeners/quiche/platform/http2_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/http2_platform_test.cc index 55c2093e1b..069a79eab0 100644 --- a/test/extensions/quic_listeners/quiche/platform/http2_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/http2_platform_test.cc @@ -18,8 +18,6 @@ #include "quiche/http2/platform/api/http2_flags.h" #include "quiche/http2/platform/api/http2_logging.h" #include "quiche/http2/platform/api/http2_macros.h" -#include "quiche/http2/platform/api/http2_optional.h" -#include "quiche/http2/platform/api/http2_reconstruct_object.h" #include "quiche/http2/test_tools/http2_random.h" // Basic tests to validate functioning of the QUICHE http2 platform @@ -74,27 +72,6 @@ TEST(Http2PlatformTest, Http2Log) { HTTP2_DLOG_EVERY_N(ERROR, 2) << "DLOG_EVERY_N(ERROR, 2)"; } -TEST(Http2PlatformTest, Http2Optional) { - http2::Http2Optional opt; - EXPECT_FALSE(opt.has_value()); - opt = 3; - EXPECT_TRUE(opt.has_value()); -} - -TEST(Http2PlatformTest, Http2ReconstructObject) { - http2::test::Http2Random rng; - std::string s; - - http2::test::Http2ReconstructObject(&s, &rng, "123"); - EXPECT_EQ("123", s); - - http2::test::Http2ReconstructObject(&s, &rng, "456"); - EXPECT_EQ("456", s); - - http2::test::Http2DefaultReconstructObject(&s, &rng); - EXPECT_EQ("", s); -} - TEST(Http2PlatformTest, Http2StringPiece) { std::string s = "bar"; quiche::QuicheStringPiece sp(s); diff --git a/test/extensions/quic_listeners/quiche/platform/http2_reconstruct_object_impl.h b/test/extensions/quic_listeners/quiche/platform/http2_reconstruct_object_impl.h deleted file mode 100644 index 974e3fa48b..0000000000 --- a/test/extensions/quic_listeners/quiche/platform/http2_reconstruct_object_impl.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include - -namespace http2 { -namespace test { - -class Http2Random; - -// Reconstruct an object so that it is initialized as when it was first -// constructed. Runs the destructor to handle objects that might own resources, -// and runs the constructor with the provided arguments, if any. -template -void Http2ReconstructObjectImpl(T* ptr, Http2Random* /*rng*/, Args&&... args) { - ptr->~T(); - ::new (ptr) T(std::forward(args)...); -} - -// This version applies default-initialization to the object. -template void Http2DefaultReconstructObjectImpl(T* ptr, Http2Random* /*rng*/) { - ptr->~T(); - ::new (ptr) T; -} - -} // namespace test -} // namespace http2 diff --git a/test/extensions/quic_listeners/quiche/platform/quic_epoll_clock.h b/test/extensions/quic_listeners/quiche/platform/quic_epoll_clock.h index f1446dbb4b..575b4d61aa 100644 --- a/test/extensions/quic_listeners/quiche/platform/quic_epoll_clock.h +++ b/test/extensions/quic_listeners/quiche/platform/quic_epoll_clock.h @@ -7,8 +7,8 @@ // porting layer for QUICHE. #include "quiche/epoll_server/simple_epoll_server.h" +#include "quiche/quic/core/quic_clock.h" #include "quiche/quic/core/quic_time.h" -#include "quiche/quic/platform/api/quic_clock.h" namespace quic { diff --git a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc index 09f610ede4..feb101cbb8 100644 --- a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc @@ -170,12 +170,6 @@ TEST_F(QuicPlatformTest, QuicQueue) { EXPECT_EQ(10, queue.back()); } -TEST_F(QuicPlatformTest, QuicDeque) { - QuicDeque deque; - deque.push_back(10); - EXPECT_EQ(10, deque.back()); -} - TEST_F(QuicPlatformTest, QuicInlinedVector) { QuicInlinedVector vec; vec.push_back(3); diff --git a/test/extensions/quic_listeners/quiche/platform/quiche_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/quiche_platform_test.cc index 3e08139968..ad311ae03f 100644 --- a/test/extensions/quic_listeners/quiche/platform/quiche_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/quiche_platform_test.cc @@ -7,6 +7,7 @@ #include "gtest/gtest.h" #include "quiche/common/platform/api/quiche_arraysize.h" #include "quiche/common/platform/api/quiche_endian.h" +#include "quiche/common/platform/api/quiche_ptr_util.h" #include "quiche/common/platform/api/quiche_string_piece.h" namespace quiche { @@ -22,4 +23,9 @@ TEST(QuichePlatformTest, StringPiece) { EXPECT_EQ('b', sp[0]); } +TEST(QuichePlatformTest, WrapUnique) { + auto p = QuicheWrapUnique(new int(6)); + EXPECT_EQ(6, *p); +} + } // namespace quiche diff --git a/test/extensions/quic_listeners/quiche/platform/quiche_test_impl.h b/test/extensions/quic_listeners/quiche/platform/quiche_test_impl.h index 3d9fcf729b..34e5f3eeef 100644 --- a/test/extensions/quic_listeners/quiche/platform/quiche_test_impl.h +++ b/test/extensions/quic_listeners/quiche/platform/quiche_test_impl.h @@ -14,5 +14,7 @@ namespace test { using QuicheTest = ::testing::Test; +template using QuicheTestWithParamImpl = ::testing::TestWithParam; + } // namespace test } // namespace quiche diff --git a/test/extensions/quic_listeners/quiche/platform/spdy_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/spdy_platform_test.cc index 66a342c06a..56453e232c 100644 --- a/test/extensions/quic_listeners/quiche/platform/spdy_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/spdy_platform_test.cc @@ -12,8 +12,6 @@ #include "quiche/spdy/platform/api/spdy_estimate_memory_usage.h" #include "quiche/spdy/platform/api/spdy_flags.h" #include "quiche/spdy/platform/api/spdy_logging.h" -#include "quiche/spdy/platform/api/spdy_ptr_util.h" -#include "quiche/spdy/platform/api/spdy_string_piece.h" #include "quiche/spdy/platform/api/spdy_test_helpers.h" // Basic tests to validate functioning of the QUICHE spdy platform @@ -81,22 +79,11 @@ TEST(SpdyPlatformTest, SpdyLog) { SPDY_DVLOG_IF(4, false) << "DVLOG_IF(4, false)"; } -TEST(SpdyPlatformTest, SpdyWrapUnique) { - auto p = spdy::SpdyWrapUnique(new int(6)); - EXPECT_EQ(6, *p); -} - TEST(SpdyPlatformTest, SpdyString) { std::string s = "foo"; EXPECT_EQ('o', s[1]); } -TEST(SpdyPlatformTest, SpdyStringPiece) { - std::string s = "bar"; - spdy::SpdyStringPiece sp(s); - EXPECT_EQ('b', sp[0]); -} - TEST(SpdyPlatformTest, SpdyTestHelpers) { auto bug = [](const char* error_message) { SPDY_BUG << error_message; }; diff --git a/test/extensions/quic_listeners/quiche/platform/spdy_test_impl.h b/test/extensions/quic_listeners/quiche/platform/spdy_test_impl.h deleted file mode 100644 index e351735c3a..0000000000 --- a/test/extensions/quic_listeners/quiche/platform/spdy_test_impl.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -// NOLINT(namespace-envoy) - -// This file is part of the QUICHE platform implementation, and is not to be -// consumed or referenced directly by other Envoy code. It serves purely as a -// porting layer for QUICHE. - -#include "gmock/gmock.h" -#include "gtest/gtest.h" From d46ffd20c5cfdd7b6cc8af6b648d4eee49ecf31f Mon Sep 17 00:00:00 2001 From: Neal Patel Date: Tue, 18 Feb 2020 09:41:12 -0800 Subject: [PATCH 70/87] tracing: Add source IP address to XRay trace (#10014) Signed-off-by: Neal Patel --- source/common/tracing/http_tracer_impl.cc | 10 +++ source/extensions/tracers/xray/tracer.cc | 9 +++ test/common/tracing/http_tracer_impl_test.cc | 66 ++++++++++++++++++++ test/extensions/tracers/xray/tracer_test.cc | 11 +++- 4 files changed, 95 insertions(+), 1 deletion(-) diff --git a/source/common/tracing/http_tracer_impl.cc b/source/common/tracing/http_tracer_impl.cc index 3e15539382..b1f97c81ec 100644 --- a/source/common/tracing/http_tracer_impl.cc +++ b/source/common/tracing/http_tracer_impl.cc @@ -3,6 +3,7 @@ #include #include "envoy/config/core/v3/base.pb.h" +#include "envoy/network/address.h" #include "envoy/type/metadata/v3/metadata.pb.h" #include "envoy/type/tracing/v3/custom_tag.pb.h" @@ -173,6 +174,15 @@ void HttpTracerUtility::finalizeDownstreamSpan(Span& span, const Http::HeaderMap span.setTag(Tracing::Tags::get().HttpProtocol, AccessLog::AccessLogFormatUtils::protocolToString(stream_info.protocol())); + const auto& remote_address = stream_info.downstreamDirectRemoteAddress(); + + if (remote_address->type() == Network::Address::Type::Ip) { + const auto remote_ip = remote_address->ip(); + span.setTag(Tracing::Tags::get().PeerAddress, remote_ip->addressAsString()); + } else { + span.setTag(Tracing::Tags::get().PeerAddress, remote_address->logicalName()); + } + if (request_headers->ClientTraceId()) { span.setTag(Tracing::Tags::get().GuidXClientTraceId, std::string(request_headers->ClientTraceId()->value().getStringView())); diff --git a/source/extensions/tracers/xray/tracer.cc b/source/extensions/tracers/xray/tracer.cc index 466e08abc7..5fbbc0cb52 100644 --- a/source/extensions/tracers/xray/tracer.cc +++ b/source/extensions/tracers/xray/tracer.cc @@ -169,11 +169,15 @@ void Span::setTag(absl::string_view name, absl::string_view value) { constexpr auto SpanStatus = "status"; constexpr auto SpanUserAgent = "user_agent"; constexpr auto SpanUrl = "url"; + constexpr auto SpanClientIp = "client_ip"; + constexpr auto SpanXForwardedFor = "x_forwarded_for"; + constexpr auto HttpUrl = "http.url"; constexpr auto HttpMethod = "http.method"; constexpr auto HttpStatusCode = "http.status_code"; constexpr auto HttpUserAgent = "user_agent"; constexpr auto HttpResponseSize = "response_size"; + constexpr auto PeerAddress = "peer.address"; if (name.empty() || value.empty()) { return; @@ -189,6 +193,11 @@ void Span::setTag(absl::string_view name, absl::string_view value) { http_response_annotations_.emplace(SpanStatus, value); } else if (name == HttpResponseSize) { http_response_annotations_.emplace(SpanContentLength, value); + } else if (name == PeerAddress) { + http_request_annotations_.emplace(SpanClientIp, value); + // In this case, PeerAddress refers to the client's actual IP address, not + // the address specified in the the HTTP X-Forwarded-For header. + http_request_annotations_.emplace(SpanXForwardedFor, "false"); } else { custom_annotations_.emplace(name, value); } diff --git a/test/common/tracing/http_tracer_impl_test.cc b/test/common/tracing/http_tracer_impl_test.cc index a250a794d2..8c3df62178 100644 --- a/test/common/tracing/http_tracer_impl_test.cc +++ b/test/common/tracing/http_tracer_impl_test.cc @@ -9,6 +9,7 @@ #include "common/http/header_map_impl.h" #include "common/http/headers.h" #include "common/http/message_impl.h" +#include "common/network/utility.h" #include "common/runtime/runtime_impl.h" #include "common/runtime/uuid_util.h" #include "common/tracing/http_tracer_impl.h" @@ -29,6 +30,7 @@ #include "gtest/gtest.h" using testing::_; +using testing::AnyNumber; using testing::Eq; using testing::NiceMock; using testing::Return; @@ -145,6 +147,9 @@ TEST_F(HttpConnManFinalizerImplTest, OriginalAndLongPath) { const std::string path(300, 'a'); const std::string path_prefix = "http://"; const std::string expected_path(256, 'a'); + const std::string expected_ip = "10.0.0.100"; + const auto remote_address = + Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; Http::TestHeaderMapImpl request_headers{{"x-request-id", "id"}, {"x-envoy-original-path", path}, @@ -159,11 +164,14 @@ TEST_F(HttpConnManFinalizerImplTest, OriginalAndLongPath) { EXPECT_CALL(stream_info, protocol()).WillRepeatedly(ReturnPointee(&protocol)); absl::optional response_code; EXPECT_CALL(stream_info, responseCode()).WillRepeatedly(ReturnPointee(&response_code)); + EXPECT_CALL(stream_info, downstreamDirectRemoteAddress()) + .WillRepeatedly(ReturnPointee(&remote_address)); EXPECT_CALL(span, setTag(_, _)).Times(testing::AnyNumber()); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().HttpUrl), Eq(path_prefix + expected_path))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().HttpMethod), Eq("GET"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().HttpProtocol), Eq("HTTP/2"))); + EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().PeerAddress), Eq(expected_ip))); HttpTracerUtility::finalizeDownstreamSpan(span, &request_headers, &response_headers, &response_trailers, stream_info, config); @@ -173,6 +181,9 @@ TEST_F(HttpConnManFinalizerImplTest, NoGeneratedId) { const std::string path(300, 'a'); const std::string path_prefix = "http://"; const std::string expected_path(256, 'a'); + const std::string expected_ip = "10.0.0.100"; + const auto remote_address = + Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; Http::TestHeaderMapImpl request_headers{ {"x-envoy-original-path", path}, {":method", "GET"}, {"x-forwarded-proto", "http"}}; @@ -185,11 +196,14 @@ TEST_F(HttpConnManFinalizerImplTest, NoGeneratedId) { EXPECT_CALL(stream_info, protocol()).WillRepeatedly(ReturnPointee(&protocol)); absl::optional response_code; EXPECT_CALL(stream_info, responseCode()).WillRepeatedly(ReturnPointee(&response_code)); + EXPECT_CALL(stream_info, downstreamDirectRemoteAddress()) + .WillRepeatedly(ReturnPointee(&remote_address)); EXPECT_CALL(span, setTag(_, _)).Times(testing::AnyNumber()); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().HttpUrl), Eq(path_prefix + expected_path))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().HttpMethod), Eq("GET"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().HttpProtocol), Eq("HTTP/2"))); + EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().PeerAddress), Eq(expected_ip))); HttpTracerUtility::finalizeDownstreamSpan(span, &request_headers, &response_headers, &response_trailers, stream_info, config); @@ -298,10 +312,15 @@ TEST_F(HttpConnManFinalizerImplTest, SpanOptionalHeaders) { {"x-forwarded-proto", "https"}}; Http::TestHeaderMapImpl response_headers; Http::TestHeaderMapImpl response_trailers; + const std::string expected_ip = "10.0.0.100"; + const auto remote_address = + Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; absl::optional protocol = Http::Protocol::Http10; EXPECT_CALL(stream_info, bytesReceived()).WillOnce(Return(10)); EXPECT_CALL(stream_info, protocol()).WillRepeatedly(ReturnPointee(&protocol)); + EXPECT_CALL(stream_info, downstreamDirectRemoteAddress()) + .WillRepeatedly(ReturnPointee(&remote_address)); // Check that span is populated correctly. EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GuidXRequestId), Eq("id"))); @@ -311,6 +330,7 @@ TEST_F(HttpConnManFinalizerImplTest, SpanOptionalHeaders) { EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().HttpProtocol), Eq("HTTP/1.0"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().DownstreamCluster), Eq("-"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().RequestSize), Eq("10"))); + EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().PeerAddress), Eq(expected_ip))); absl::optional response_code; EXPECT_CALL(stream_info, responseCode()).WillRepeatedly(ReturnPointee(&response_code)); @@ -329,6 +349,28 @@ TEST_F(HttpConnManFinalizerImplTest, SpanOptionalHeaders) { &response_trailers, stream_info, config); } +TEST_F(HttpConnManFinalizerImplTest, UnixDomainSocketPeerAddressTag) { + Http::TestHeaderMapImpl request_headers{{"x-request-id", "id"}, + {":path", "/test"}, + {":method", "GET"}, + {"x-forwarded-proto", "https"}}; + Http::TestHeaderMapImpl response_headers; + Http::TestHeaderMapImpl response_trailers; + const std::string path_{TestEnvironment::unixDomainSocketPath("foo")}; + const auto remote_address = Network::Utility::resolveUrl("unix://" + path_); + + EXPECT_CALL(stream_info, downstreamDirectRemoteAddress()) + .WillRepeatedly(ReturnPointee(&remote_address)); + + // Check that the PeerAddress is populated correctly for Unix domain sockets. + EXPECT_CALL(span, setTag(_, _)).Times(AnyNumber()); + EXPECT_CALL(span, + setTag(Eq(Tracing::Tags::get().PeerAddress), Eq(remote_address->logicalName()))); + + HttpTracerUtility::finalizeDownstreamSpan(span, &request_headers, &response_headers, + &response_trailers, stream_info, config); +} + TEST_F(HttpConnManFinalizerImplTest, SpanCustomTags) { TestEnvironment::setEnvVar("E_CC", "c", 1); @@ -455,6 +497,9 @@ TEST_F(HttpConnManFinalizerImplTest, SpanPopulatedFailureResponse) { {"x-forwarded-proto", "http"}}; Http::TestHeaderMapImpl response_headers; Http::TestHeaderMapImpl response_trailers; + const std::string expected_ip = "10.0.0.100"; + const auto remote_address = + Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; request_headers.setHost("api"); request_headers.setUserAgent("agent"); @@ -464,6 +509,8 @@ TEST_F(HttpConnManFinalizerImplTest, SpanPopulatedFailureResponse) { absl::optional protocol = Http::Protocol::Http10; EXPECT_CALL(stream_info, protocol()).WillRepeatedly(ReturnPointee(&protocol)); EXPECT_CALL(stream_info, bytesReceived()).WillOnce(Return(10)); + EXPECT_CALL(stream_info, downstreamDirectRemoteAddress()) + .WillRepeatedly(ReturnPointee(&remote_address)); // Check that span is populated correctly. EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GuidXRequestId), Eq("id"))); @@ -474,6 +521,7 @@ TEST_F(HttpConnManFinalizerImplTest, SpanPopulatedFailureResponse) { EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().DownstreamCluster), Eq("downstream_cluster"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().RequestSize), Eq("10"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GuidXClientTraceId), Eq("client_trace_id"))); + EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().PeerAddress), Eq(expected_ip))); EXPECT_CALL(config, verbose).WillOnce(Return(false)); EXPECT_CALL(config, maxPathTagLength).WillOnce(Return(256)); @@ -499,6 +547,9 @@ TEST_F(HttpConnManFinalizerImplTest, SpanPopulatedFailureResponse) { TEST_F(HttpConnManFinalizerImplTest, GrpcOkStatus) { const std::string path_prefix = "http://"; + const std::string expected_ip = "10.0.0.100"; + const auto remote_address = + Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; Http::TestHeaderMapImpl request_headers{{":method", "POST"}, {":scheme", "http"}, @@ -518,6 +569,8 @@ TEST_F(HttpConnManFinalizerImplTest, GrpcOkStatus) { EXPECT_CALL(stream_info, bytesReceived()).WillOnce(Return(10)); EXPECT_CALL(stream_info, bytesSent()).WillOnce(Return(11)); EXPECT_CALL(stream_info, protocol()).WillRepeatedly(ReturnPointee(&protocol)); + EXPECT_CALL(stream_info, downstreamDirectRemoteAddress()) + .WillRepeatedly(ReturnPointee(&remote_address)); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().Component), Eq(Tracing::Tags::get().Proxy))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().DownstreamCluster), Eq("-"))); @@ -536,6 +589,7 @@ TEST_F(HttpConnManFinalizerImplTest, GrpcOkStatus) { EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GrpcContentType), Eq("application/grpc"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GrpcStatusCode), Eq("0"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GrpcMessage), Eq(""))); + EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().PeerAddress), Eq(expected_ip))); HttpTracerUtility::finalizeDownstreamSpan(span, &request_headers, &response_headers, &response_trailers, stream_info, config); @@ -543,6 +597,9 @@ TEST_F(HttpConnManFinalizerImplTest, GrpcOkStatus) { TEST_F(HttpConnManFinalizerImplTest, GrpcErrorTag) { const std::string path_prefix = "http://"; + const std::string expected_ip = "10.0.0.100"; + const auto remote_address = + Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; Http::TestHeaderMapImpl request_headers{{":method", "POST"}, {":scheme", "http"}, @@ -564,6 +621,8 @@ TEST_F(HttpConnManFinalizerImplTest, GrpcErrorTag) { EXPECT_CALL(stream_info, bytesReceived()).WillOnce(Return(10)); EXPECT_CALL(stream_info, bytesSent()).WillOnce(Return(11)); EXPECT_CALL(stream_info, protocol()).WillRepeatedly(ReturnPointee(&protocol)); + EXPECT_CALL(stream_info, downstreamDirectRemoteAddress()) + .WillRepeatedly(ReturnPointee(&remote_address)); EXPECT_CALL(span, setTag(_, _)).Times(testing::AnyNumber()); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().Error), Eq(Tracing::Tags::get().True))); @@ -576,6 +635,7 @@ TEST_F(HttpConnManFinalizerImplTest, GrpcErrorTag) { EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GrpcTimeout), Eq("10s"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GrpcStatusCode), Eq("7"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GrpcMessage), Eq("permission denied"))); + EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().PeerAddress), Eq(expected_ip))); HttpTracerUtility::finalizeDownstreamSpan(span, &request_headers, &response_headers, &response_trailers, stream_info, config); @@ -583,6 +643,9 @@ TEST_F(HttpConnManFinalizerImplTest, GrpcErrorTag) { TEST_F(HttpConnManFinalizerImplTest, GrpcTrailersOnly) { const std::string path_prefix = "http://"; + const std::string expected_ip = "10.0.0.100"; + const auto remote_address = + Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; Http::TestHeaderMapImpl request_headers{{":method", "POST"}, {":scheme", "http"}, @@ -604,6 +667,8 @@ TEST_F(HttpConnManFinalizerImplTest, GrpcTrailersOnly) { EXPECT_CALL(stream_info, bytesReceived()).WillOnce(Return(10)); EXPECT_CALL(stream_info, bytesSent()).WillOnce(Return(11)); EXPECT_CALL(stream_info, protocol()).WillRepeatedly(ReturnPointee(&protocol)); + EXPECT_CALL(stream_info, downstreamDirectRemoteAddress()) + .WillRepeatedly(ReturnPointee(&remote_address)); EXPECT_CALL(span, setTag(_, _)).Times(testing::AnyNumber()); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().Error), Eq(Tracing::Tags::get().True))); @@ -615,6 +680,7 @@ TEST_F(HttpConnManFinalizerImplTest, GrpcTrailersOnly) { EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GrpcContentType), Eq("application/grpc"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GrpcStatusCode), Eq("7"))); EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().GrpcMessage), Eq("permission denied"))); + EXPECT_CALL(span, setTag(Eq(Tracing::Tags::get().PeerAddress), Eq(expected_ip))); HttpTracerUtility::finalizeDownstreamSpan(span, &request_headers, &response_headers, &response_trailers, stream_info, config); diff --git a/test/extensions/tracers/xray/tracer_test.cc b/test/extensions/tracers/xray/tracer_test.cc index 6e9743d376..6f8d636f92 100644 --- a/test/extensions/tracers/xray/tracer_test.cc +++ b/test/extensions/tracers/xray/tracer_test.cc @@ -48,13 +48,17 @@ TEST_F(XRayTracerTest, SerializeSpanTest) { constexpr auto expected_user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X)"; constexpr auto expected_status_code = "202"; constexpr auto expected_content_length = "1337"; + constexpr auto expected_client_ip = "10.0.0.100"; + constexpr auto expected_x_forwarded_for = "false"; + constexpr auto expected_upstream_address = "10.0.0.200"; + auto on_send = [](const std::string& json) { ASSERT_FALSE(json.empty()); daemon::Segment s; MessageUtil::loadFromJson(json, s, ProtobufMessage::getNullValidationVisitor()); ASSERT_FALSE(s.trace_id().empty()); ASSERT_FALSE(s.id().empty()); - ASSERT_TRUE(s.annotations().empty()); + ASSERT_EQ(1, s.annotations().size()); ASSERT_TRUE(s.parent_id().empty()); ASSERT_STREQ(expected_span_name, s.name().c_str()); ASSERT_STREQ(expected_http_method, s.http().request().at("method").c_str()); @@ -62,6 +66,9 @@ TEST_F(XRayTracerTest, SerializeSpanTest) { ASSERT_STREQ(expected_user_agent, s.http().request().at("user_agent").c_str()); ASSERT_STREQ(expected_status_code, s.http().response().at("status").c_str()); ASSERT_STREQ(expected_content_length, s.http().response().at("content_length").c_str()); + ASSERT_STREQ(expected_client_ip, s.http().request().at("client_ip").c_str()); + ASSERT_STREQ(expected_x_forwarded_for, s.http().request().at("x_forwarded_for").c_str()); + ASSERT_STREQ(expected_upstream_address, s.annotations().at("upstream_address").c_str()); }; EXPECT_CALL(*broker_, send(_)).WillOnce(Invoke(on_send)); @@ -73,6 +80,8 @@ TEST_F(XRayTracerTest, SerializeSpanTest) { span->setTag("user_agent", expected_user_agent); span->setTag("http.status_code", expected_status_code); span->setTag("response_size", expected_content_length); + span->setTag("peer.address", expected_client_ip); + span->setTag("upstream_address", expected_upstream_address); span->finishSpan(); } From 5a42baaad435631dd1d2df2d1a5486afd9280222 Mon Sep 17 00:00:00 2001 From: Lisa Lu Date: Tue, 18 Feb 2020 12:38:50 -0800 Subject: [PATCH 71/87] runtime: Add support for setting default value when parsing string value (#10058) This change adds the ability to set a default value when calling get(...) in runtime. Prior to this change, if there was no entry matching the key, an empty string was returned. This change is to make the return value more flexible. Risk Level: Low Testing: Changed existing unit test result Docs Changes: N/A Release Notes: N/A Signed-off-by: Lisa Lu --- include/envoy/runtime/runtime.h | 3 +- source/common/runtime/runtime_impl.cc | 5 +- source/common/runtime/runtime_impl.h | 3 +- test/common/runtime/runtime_impl_test.cc | 122 +++++++++++------------ test/mocks/runtime/mocks.cc | 1 + test/mocks/runtime/mocks.h | 3 +- test/server/server_test.cc | 4 +- 7 files changed, 72 insertions(+), 69 deletions(-) diff --git a/include/envoy/runtime/runtime.h b/include/envoy/runtime/runtime.h index 7b37b85bc6..42c07ff50f 100644 --- a/include/envoy/runtime/runtime.h +++ b/include/envoy/runtime/runtime.h @@ -210,7 +210,8 @@ class Snapshot { * @param key supplies the key to fetch. * @return const std::string& the value or empty string if the key does not exist. */ - virtual const std::string& get(absl::string_view key) const PURE; + virtual const std::string& get(absl::string_view key, + const std::string& default_value) const PURE; /** * Returns whether the key has any value set. diff --git a/source/common/runtime/runtime_impl.cc b/source/common/runtime/runtime_impl.cc index e8f63fef53..feb62971d5 100644 --- a/source/common/runtime/runtime_impl.cc +++ b/source/common/runtime/runtime_impl.cc @@ -233,11 +233,12 @@ bool SnapshotImpl::featureEnabled(absl::string_view key, uint64_t default_value, return featureEnabled(key, default_value, random_value, 100); } -const std::string& SnapshotImpl::get(absl::string_view key) const { +const std::string& SnapshotImpl::get(absl::string_view key, + const std::string& default_value) const { ASSERT(!isRuntimeFeature(key)); // Make sure runtime guarding is only used for getBoolean auto entry = key.empty() ? values_.end() : values_.find(key); if (entry == values_.end()) { - return EMPTY_STRING; + return default_value; } else { return entry->second.raw_string_value_; } diff --git a/source/common/runtime/runtime_impl.h b/source/common/runtime/runtime_impl.h index 5c6936ef3a..933ddee36b 100644 --- a/source/common/runtime/runtime_impl.h +++ b/source/common/runtime/runtime_impl.h @@ -21,7 +21,6 @@ #include "envoy/upstream/cluster_manager.h" #include "common/common/assert.h" -#include "common/common/empty_string.h" #include "common/common/logger.h" #include "common/common/thread.h" #include "common/init/target_impl.h" @@ -93,7 +92,7 @@ class SnapshotImpl : public Snapshot, bool featureEnabled(absl::string_view key, const envoy::type::v3::FractionalPercent& default_value, uint64_t random_value) const override; - const std::string& get(absl::string_view key) const override; + const std::string& get(absl::string_view key, const std::string& default_value) const override; uint64_t getInteger(absl::string_view key, uint64_t default_value) const override; double getDouble(absl::string_view key, double default_value) const override; bool getBoolean(absl::string_view key, bool value) const override; diff --git a/test/common/runtime/runtime_impl_test.cc b/test/common/runtime/runtime_impl_test.cc index 36e71b5609..a183678761 100644 --- a/test/common/runtime/runtime_impl_test.cc +++ b/test/common/runtime/runtime_impl_test.cc @@ -165,7 +165,7 @@ TEST_F(DiskLoaderImplTest, EmptyKeyTest) { setup(); run("test/common/runtime/test_data/current", "envoy_override"); - EXPECT_EQ("", loader_->snapshot().get("")); + EXPECT_EQ("default", loader_->snapshot().get("", "default")); EXPECT_EQ(11, loader_->snapshot().getInteger("", 11)); EXPECT_EQ(1.1, loader_->snapshot().getDouble("", 1.1)); EXPECT_EQ(false, loader_->snapshot().featureEnabled("", 0)); @@ -195,9 +195,9 @@ TEST_F(DiskLoaderImplTest, All) { run("test/common/runtime/test_data/current", "envoy_override"); // Basic string getting. - EXPECT_EQ("world", loader_->snapshot().get("file2")); - EXPECT_EQ("hello\nworld", loader_->snapshot().get("subdir.file3")); - EXPECT_EQ("", loader_->snapshot().get("invalid")); + EXPECT_EQ("world", loader_->snapshot().get("file2", "")); + EXPECT_EQ("hello\nworld", loader_->snapshot().get("subdir.file3", "")); + EXPECT_EQ("", loader_->snapshot().get("invalid", "")); // Existence checking. EXPECT_EQ(true, loader_->snapshot().exists("file2")); @@ -256,8 +256,8 @@ TEST_F(DiskLoaderImplTest, All) { // Files with comments. EXPECT_EQ(123UL, loader_->snapshot().getInteger("file5", 1)); EXPECT_EQ(2.718, loader_->snapshot().getDouble("file_with_double_comment", 1.1)); - EXPECT_EQ("/home#about-us", loader_->snapshot().get("file6")); - EXPECT_EQ("", loader_->snapshot().get("file7")); + EXPECT_EQ("/home#about-us", loader_->snapshot().get("file6", "")); + EXPECT_EQ("", loader_->snapshot().get("file7", "")); // Feature enablement. EXPECT_CALL(generator_, random()).WillOnce(Return(1)); @@ -307,7 +307,7 @@ TEST_F(DiskLoaderImplTest, All) { EXPECT_TRUE(loader_->snapshot().featureEnabled("file4", 1, 122, 300)); // Overrides from override dir - EXPECT_EQ("hello override", loader_->snapshot().get("file1")); + EXPECT_EQ("hello override", loader_->snapshot().get("file1", "")); EXPECT_EQ(0, store_.counter("runtime.load_error").value()); EXPECT_EQ(1, store_.counter("runtime.load_success").value()); @@ -372,7 +372,7 @@ TEST_F(DiskLoaderImplTest, OverrideFolderDoesNotExist) { setup(); run("test/common/runtime/test_data/current", "envoy_override_does_not_exist"); - EXPECT_EQ("hello", loader_->snapshot().get("file1")); + EXPECT_EQ("hello", loader_->snapshot().get("file1", "")); EXPECT_EQ(0, store_.counter("runtime.load_error").value()); EXPECT_EQ(1, store_.counter("runtime.load_success").value()); EXPECT_EQ(3, store_.gauge("runtime.num_layers", Stats::Gauge::ImportMode::NeverImport).value()); @@ -428,12 +428,12 @@ void testNewOverrides(Loader& loader, Stats::Store& store) { // New string. loader.mergeValues({{"foo", "bar"}}); - EXPECT_EQ("bar", loader.snapshot().get("foo")); + EXPECT_EQ("bar", loader.snapshot().get("foo", "")); EXPECT_EQ(1, admin_overrides_active.value()); // Remove new string. loader.mergeValues({{"foo", ""}}); - EXPECT_EQ("", loader.snapshot().get("foo")); + EXPECT_EQ("", loader.snapshot().get("foo", "")); EXPECT_EQ(0, admin_overrides_active.value()); // New integer. @@ -466,12 +466,12 @@ TEST_F(DiskLoaderImplTest, MergeValues) { // Override string loader_->mergeValues({{"file2", "new world"}}); - EXPECT_EQ("new world", loader_->snapshot().get("file2")); + EXPECT_EQ("new world", loader_->snapshot().get("file2", "")); EXPECT_EQ(1, admin_overrides_active.value()); // Remove overridden string loader_->mergeValues({{"file2", ""}}); - EXPECT_EQ("world", loader_->snapshot().get("file2")); + EXPECT_EQ("world", loader_->snapshot().get("file2", "")); EXPECT_EQ(0, admin_overrides_active.value()); // Override integer @@ -496,12 +496,12 @@ TEST_F(DiskLoaderImplTest, MergeValues) { // Override override string loader_->mergeValues({{"file1", "hello overridden override"}}); - EXPECT_EQ("hello overridden override", loader_->snapshot().get("file1")); + EXPECT_EQ("hello overridden override", loader_->snapshot().get("file1", "")); EXPECT_EQ(1, admin_overrides_active.value()); // Remove overridden override string loader_->mergeValues({{"file1", ""}}); - EXPECT_EQ("hello override", loader_->snapshot().get("file1")); + EXPECT_EQ("hello override", loader_->snapshot().get("file1", "")); EXPECT_EQ(0, admin_overrides_active.value()); EXPECT_EQ(0, store_.gauge("runtime.admin_overrides_active", Stats::Gauge::ImportMode::NeverImport) .value()); @@ -520,25 +520,25 @@ TEST_F(DiskLoaderImplTest, LayersOverride) { setup(); run("test/common/runtime/test_data/current", "envoy_override"); // Disk overrides bootstrap. - EXPECT_EQ("world", loader_->snapshot().get("file2")); - EXPECT_EQ("thing", loader_->snapshot().get("some")); - EXPECT_EQ("thang", loader_->snapshot().get("other")); + EXPECT_EQ("world", loader_->snapshot().get("file2", "")); + EXPECT_EQ("thing", loader_->snapshot().get("some", "")); + EXPECT_EQ("thang", loader_->snapshot().get("other", "")); // Admin overrides disk and bootstrap. loader_->mergeValues({{"file2", "pluto"}, {"some", "day soon"}}); - EXPECT_EQ("pluto", loader_->snapshot().get("file2")); - EXPECT_EQ("day soon", loader_->snapshot().get("some")); - EXPECT_EQ("thang", loader_->snapshot().get("other")); + EXPECT_EQ("pluto", loader_->snapshot().get("file2", "")); + EXPECT_EQ("day soon", loader_->snapshot().get("some", "")); + EXPECT_EQ("thang", loader_->snapshot().get("other", "")); // Admin overrides stick over filesystem updates. - EXPECT_EQ("Layer cake", loader_->snapshot().get("file14")); - EXPECT_EQ("Cheese cake", loader_->snapshot().get("file15")); + EXPECT_EQ("Layer cake", loader_->snapshot().get("file14", "")); + EXPECT_EQ("Cheese cake", loader_->snapshot().get("file15", "")); loader_->mergeValues({{"file14", "Mega layer cake"}}); - EXPECT_EQ("Mega layer cake", loader_->snapshot().get("file14")); - EXPECT_EQ("Cheese cake", loader_->snapshot().get("file15")); + EXPECT_EQ("Mega layer cake", loader_->snapshot().get("file14", "")); + EXPECT_EQ("Cheese cake", loader_->snapshot().get("file15", "")); write("test/common/runtime/test_data/current/envoy/file14", "Sad cake"); write("test/common/runtime/test_data/current/envoy/file15", "Happy cake"); updateDiskLayer(0); - EXPECT_EQ("Mega layer cake", loader_->snapshot().get("file14")); - EXPECT_EQ("Happy cake", loader_->snapshot().get("file15")); + EXPECT_EQ("Mega layer cake", loader_->snapshot().get("file14", "")); + EXPECT_EQ("Happy cake", loader_->snapshot().get("file15", "")); } // Validate that multiple admin layers leads to a configuration load failure. @@ -587,7 +587,7 @@ class StaticLoaderImplTest : public LoaderImplTest { TEST_F(StaticLoaderImplTest, All) { setup(); - EXPECT_EQ("", loader_->snapshot().get("foo")); + EXPECT_EQ("", loader_->snapshot().get("foo", "")); EXPECT_EQ(1UL, loader_->snapshot().getInteger("foo", 1)); EXPECT_EQ(1.1, loader_->snapshot().getDouble("foo", 1.1)); EXPECT_CALL(generator_, random()).WillOnce(Return(49)); @@ -628,9 +628,9 @@ TEST_F(StaticLoaderImplTest, ProtoParsing) { setup(); // Basic string getting. - EXPECT_EQ("world", loader_->snapshot().get("file2")); - EXPECT_EQ("hello\nworld", loader_->snapshot().get("subdir.file3")); - EXPECT_EQ("", loader_->snapshot().get("invalid")); + EXPECT_EQ("world", loader_->snapshot().get("file2", "")); + EXPECT_EQ("hello\nworld", loader_->snapshot().get("subdir.file3", "")); + EXPECT_EQ("", loader_->snapshot().get("invalid", "")); // Integer getting. EXPECT_EQ(1UL, loader_->snapshot().getInteger("file1", 1)); @@ -725,7 +725,7 @@ TEST_F(StaticLoaderImplTest, RuntimeFromNonWorkerThreads) { // Set up foo -> bar loader_->mergeValues({{"foo", "bar"}}); - EXPECT_EQ("bar", loader_->threadsafeSnapshot()->get("foo")); + EXPECT_EQ("bar", loader_->threadsafeSnapshot()->get("foo", "")); const Snapshot* original_snapshot_pointer = loader_->threadsafeSnapshot().get(); // Now set up a test thread which verifies foo -> bar @@ -740,7 +740,7 @@ TEST_F(StaticLoaderImplTest, RuntimeFromNonWorkerThreads) { auto thread = Thread::threadFactoryForTest().createThread([&]() { { Thread::LockGuard lock(mutex); - EXPECT_EQ("bar", loader_->threadsafeSnapshot()->get("foo")); + EXPECT_EQ("bar", loader_->threadsafeSnapshot()->get("foo", "")); read_bar = true; original_thread_snapshot_pointer = loader_->threadsafeSnapshot().get(); EXPECT_EQ(original_thread_snapshot_pointer, loader_->threadsafeSnapshot().get()); @@ -752,7 +752,7 @@ TEST_F(StaticLoaderImplTest, RuntimeFromNonWorkerThreads) { if (!updated_eep) { foo_changed.wait(mutex); } - EXPECT_EQ("eep", loader_->threadsafeSnapshot()->get("foo")); + EXPECT_EQ("eep", loader_->threadsafeSnapshot()->get("foo", "")); } }); @@ -768,7 +768,7 @@ TEST_F(StaticLoaderImplTest, RuntimeFromNonWorkerThreads) { { Thread::LockGuard lock(mutex); foo_changed.notifyOne(); - EXPECT_EQ("eep", loader_->threadsafeSnapshot()->get("foo")); + EXPECT_EQ("eep", loader_->threadsafeSnapshot()->get("foo", "")); } thread->join(); @@ -872,9 +872,9 @@ class RtdsLoaderImplTest : public LoaderImplTest { // Validate that the layer name is set properly for dynamic layers. EXPECT_EQ(layers_[0], loader_->snapshot().getLayers()[1]->name()); - EXPECT_EQ("whatevs", loader_->snapshot().get("foo")); - EXPECT_EQ("yar", loader_->snapshot().get("bar")); - EXPECT_EQ("", loader_->snapshot().get("baz")); + EXPECT_EQ("whatevs", loader_->snapshot().get("foo", "")); + EXPECT_EQ("yar", loader_->snapshot().get("bar", "")); + EXPECT_EQ("", loader_->snapshot().get("baz", "")); EXPECT_EQ(0, store_.counter("runtime.load_error").value()); EXPECT_EQ(1, store_.counter("runtime.load_success").value()); @@ -971,9 +971,9 @@ TEST_F(RtdsLoaderImplTest, WrongResourceName) { EXPECT_THROW_WITH_MESSAGE(rtds_callbacks_[0]->onConfigUpdate(resources, ""), EnvoyException, "Unexpected RTDS runtime (expecting some_resource): other_resource"); - EXPECT_EQ("whatevs", loader_->snapshot().get("foo")); - EXPECT_EQ("yar", loader_->snapshot().get("bar")); - EXPECT_EQ("", loader_->snapshot().get("baz")); + EXPECT_EQ("whatevs", loader_->snapshot().get("foo", "")); + EXPECT_EQ("yar", loader_->snapshot().get("bar", "")); + EXPECT_EQ("", loader_->snapshot().get("baz", "")); EXPECT_EQ(0, store_.counter("runtime.load_error").value()); EXPECT_EQ(1, store_.counter("runtime.load_success").value()); @@ -994,9 +994,9 @@ TEST_F(RtdsLoaderImplTest, OnConfigUpdateSuccess) { EXPECT_CALL(init_watcher_, ready()); doOnConfigUpdateVerifyNoThrow(runtime); - EXPECT_EQ("bar", loader_->snapshot().get("foo")); - EXPECT_EQ("yar", loader_->snapshot().get("bar")); - EXPECT_EQ("meh", loader_->snapshot().get("baz")); + EXPECT_EQ("bar", loader_->snapshot().get("foo", "")); + EXPECT_EQ("yar", loader_->snapshot().get("bar", "")); + EXPECT_EQ("meh", loader_->snapshot().get("baz", "")); EXPECT_EQ(0, store_.counter("runtime.load_error").value()); EXPECT_EQ(2, store_.counter("runtime.load_success").value()); @@ -1010,9 +1010,9 @@ TEST_F(RtdsLoaderImplTest, OnConfigUpdateSuccess) { )EOF"); doOnConfigUpdateVerifyNoThrow(runtime); - EXPECT_EQ("whatevs", loader_->snapshot().get("foo")); - EXPECT_EQ("yar", loader_->snapshot().get("bar")); - EXPECT_EQ("saz", loader_->snapshot().get("baz")); + EXPECT_EQ("whatevs", loader_->snapshot().get("foo", "")); + EXPECT_EQ("yar", loader_->snapshot().get("bar", "")); + EXPECT_EQ("saz", loader_->snapshot().get("baz", "")); EXPECT_EQ(0, store_.counter("runtime.load_error").value()); EXPECT_EQ(3, store_.counter("runtime.load_success").value()); @@ -1033,9 +1033,9 @@ TEST_F(RtdsLoaderImplTest, DeltaOnConfigUpdateSuccess) { EXPECT_CALL(init_watcher_, ready()); doDeltaOnConfigUpdateVerifyNoThrow(runtime); - EXPECT_EQ("bar", loader_->snapshot().get("foo")); - EXPECT_EQ("yar", loader_->snapshot().get("bar")); - EXPECT_EQ("meh", loader_->snapshot().get("baz")); + EXPECT_EQ("bar", loader_->snapshot().get("foo", "")); + EXPECT_EQ("yar", loader_->snapshot().get("bar", "")); + EXPECT_EQ("meh", loader_->snapshot().get("baz", "")); EXPECT_EQ(0, store_.counter("runtime.load_error").value()); EXPECT_EQ(2, store_.counter("runtime.load_success").value()); @@ -1049,9 +1049,9 @@ TEST_F(RtdsLoaderImplTest, DeltaOnConfigUpdateSuccess) { )EOF"); doDeltaOnConfigUpdateVerifyNoThrow(runtime); - EXPECT_EQ("whatevs", loader_->snapshot().get("foo")); - EXPECT_EQ("yar", loader_->snapshot().get("bar")); - EXPECT_EQ("saz", loader_->snapshot().get("baz")); + EXPECT_EQ("whatevs", loader_->snapshot().get("foo", "")); + EXPECT_EQ("yar", loader_->snapshot().get("bar", "")); + EXPECT_EQ("saz", loader_->snapshot().get("baz", "")); EXPECT_EQ(0, store_.counter("runtime.load_error").value()); EXPECT_EQ(3, store_.counter("runtime.load_success").value()); @@ -1064,9 +1064,9 @@ TEST_F(RtdsLoaderImplTest, MultipleRtdsLayers) { addLayer("another_resource"); setup(); - EXPECT_EQ("whatevs", loader_->snapshot().get("foo")); - EXPECT_EQ("yar", loader_->snapshot().get("bar")); - EXPECT_EQ("", loader_->snapshot().get("baz")); + EXPECT_EQ("whatevs", loader_->snapshot().get("foo", "")); + EXPECT_EQ("yar", loader_->snapshot().get("bar", "")); + EXPECT_EQ("", loader_->snapshot().get("baz", "")); auto runtime = TestUtility::parseYaml(R"EOF( name: some_resource @@ -1077,9 +1077,9 @@ TEST_F(RtdsLoaderImplTest, MultipleRtdsLayers) { EXPECT_CALL(init_watcher_, ready()).Times(2); doOnConfigUpdateVerifyNoThrow(runtime, 0); - EXPECT_EQ("bar", loader_->snapshot().get("foo")); - EXPECT_EQ("yar", loader_->snapshot().get("bar")); - EXPECT_EQ("meh", loader_->snapshot().get("baz")); + EXPECT_EQ("bar", loader_->snapshot().get("foo", "")); + EXPECT_EQ("yar", loader_->snapshot().get("bar", "")); + EXPECT_EQ("meh", loader_->snapshot().get("baz", "")); EXPECT_EQ(0, store_.counter("runtime.load_error").value()); EXPECT_EQ(2, store_.counter("runtime.load_success").value()); @@ -1095,9 +1095,9 @@ TEST_F(RtdsLoaderImplTest, MultipleRtdsLayers) { // Unlike in OnConfigUpdateSuccess, foo latches onto bar as the some_resource // layer still applies. - EXPECT_EQ("bar", loader_->snapshot().get("foo")); - EXPECT_EQ("yar", loader_->snapshot().get("bar")); - EXPECT_EQ("saz", loader_->snapshot().get("baz")); + EXPECT_EQ("bar", loader_->snapshot().get("foo", "")); + EXPECT_EQ("yar", loader_->snapshot().get("bar", "")); + EXPECT_EQ("saz", loader_->snapshot().get("baz", "")); EXPECT_EQ(0, store_.counter("runtime.load_error").value()); EXPECT_EQ(3, store_.counter("runtime.load_success").value()); diff --git a/test/mocks/runtime/mocks.cc b/test/mocks/runtime/mocks.cc index 330c4a53d2..4967ce1d8b 100644 --- a/test/mocks/runtime/mocks.cc +++ b/test/mocks/runtime/mocks.cc @@ -18,6 +18,7 @@ MockSnapshot::MockSnapshot() { ON_CALL(*this, getInteger(_, _)).WillByDefault(ReturnArg<1>()); ON_CALL(*this, getDouble(_, _)).WillByDefault(ReturnArg<1>()); ON_CALL(*this, getBoolean(_, _)).WillByDefault(ReturnArg<1>()); + ON_CALL(*this, get(_, _)).WillByDefault(ReturnArg<1>()); ON_CALL(*this, exists(_)).WillByDefault(Return(false)); } diff --git a/test/mocks/runtime/mocks.h b/test/mocks/runtime/mocks.h index a59a662c3d..7551f9c56b 100644 --- a/test/mocks/runtime/mocks.h +++ b/test/mocks/runtime/mocks.h @@ -58,7 +58,8 @@ class MockSnapshot : public Snapshot { (absl::string_view key, const envoy::type::v3::FractionalPercent& default_value, uint64_t random_value), (const)); - MOCK_METHOD(const std::string&, get, (absl::string_view key), (const)); + MOCK_METHOD(const std::string&, get, (absl::string_view key, const std::string& default_value), + (const)); MOCK_METHOD(bool, exists, (absl::string_view key), (const)); MOCK_METHOD(uint64_t, getInteger, (absl::string_view key, uint64_t default_value), (const)); MOCK_METHOD(double, getDouble, (absl::string_view key, double default_value), (const)); diff --git a/test/server/server_test.cc b/test/server/server_test.cc index f508c2783a..97bb076da8 100644 --- a/test/server/server_test.cc +++ b/test/server/server_test.cc @@ -644,9 +644,9 @@ TEST_P(ServerInstanceImplTest, BootstrapNodeWithOptionsOverride) { TEST_P(ServerInstanceImplTest, BootstrapRuntime) { options_.service_cluster_name_ = "some_service"; initialize("test/server/test_data/server/runtime_bootstrap.yaml"); - EXPECT_EQ("bar", server_->runtime().snapshot().get("foo")); + EXPECT_EQ("bar", server_->runtime().snapshot().get("foo", "")); // This should access via the override/some_service overlay. - EXPECT_EQ("fozz", server_->runtime().snapshot().get("fizz")); + EXPECT_EQ("fozz", server_->runtime().snapshot().get("fizz", "")); EXPECT_EQ("foobar", server_->runtime().snapshot().getLayers()[3]->name()); } From 6c3c2b3dec83966ef6f84a8d767c4b5acc341aca Mon Sep 17 00:00:00 2001 From: "William A. Rowe Jr" Date: Tue, 18 Feb 2020 15:44:13 -0600 Subject: [PATCH 72/87] Introduce os_fd_t and windows port of os_sys_calls_impl (#10036) Co-authored-by: Sunjay Bhatia Signed-off-by: Sunjay Bhatia Co-authored-by: William A Rowe Jr Signed-off-by: William A Rowe Jr --- include/envoy/api/os_sys_calls.h | 59 +++- include/envoy/api/os_sys_calls_common.h | 1 + include/envoy/common/platform.h | 89 ++++- include/envoy/event/dispatcher.h | 2 +- include/envoy/network/address.h | 4 +- include/envoy/network/io_handle.h | 2 +- source/common/api/BUILD | 3 + source/common/api/posix/os_sys_calls_impl.cc | 110 ++++-- source/common/api/posix/os_sys_calls_impl.h | 31 +- source/common/api/win32/os_sys_calls_impl.cc | 333 ++++++++++++++++++ source/common/api/win32/os_sys_calls_impl.h | 48 +++ source/common/event/dispatcher_impl.cc | 2 +- source/common/event/dispatcher_impl.h | 2 +- source/common/event/file_event_impl.cc | 2 +- source/common/event/file_event_impl.h | 4 +- .../common/filesystem/win32/watcher_impl.cc | 4 +- source/common/filesystem/win32/watcher_impl.h | 6 +- source/common/network/address_impl.cc | 34 +- source/common/network/address_impl.h | 16 +- source/common/network/base_listener_impl.cc | 2 +- source/common/network/base_listener_impl.h | 2 +- source/common/network/dns_impl.cc | 6 +- source/common/network/dns_impl.h | 4 +- .../common/network/io_socket_handle_impl.cc | 2 +- source/common/network/io_socket_handle_impl.h | 6 +- source/common/network/utility.cc | 2 +- source/common/network/utility.h | 2 +- .../listener/original_dst/original_dst.cc | 2 +- .../listener/original_dst/original_dst.h | 2 +- .../listener/proxy_protocol/proxy_protocol.cc | 4 +- .../listener/proxy_protocol/proxy_protocol.h | 4 +- .../quiche/envoy_quic_client_stream.cc | 2 +- .../quiche/envoy_quic_server_stream.cc | 2 +- .../platform/quic_mem_slice_storage_impl.cc | 2 +- .../platform/quic_mem_slice_storage_impl.h | 2 +- .../quiche/quic_io_handle_wrapper.h | 2 +- test/common/event/file_event_impl_test.cc | 4 +- test/common/network/dns_impl_test.cc | 4 +- test/common/network/listener_impl_test.cc | 12 +- .../network/socket_option_factory_test.cc | 6 +- .../common/network/socket_option_impl_test.cc | 4 +- .../upstream/cluster_manager_impl_test.cc | 19 +- .../proxy_protocol/proxy_protocol_test.cc | 44 +-- .../tls_inspector/tls_inspector_test.cc | 16 +- .../quiche/platform/quic_platform_test.cc | 6 +- .../quiche/quic_io_handle_wrapper_test.cc | 6 +- test/mocks/api/mocks.cc | 8 +- test/mocks/api/mocks.h | 36 +- test/mocks/event/mocks.h | 4 +- test/mocks/network/mocks.h | 4 +- test/server/listener_manager_impl_test.cc | 38 +- tools/spelling/spelling_dictionary.txt | 3 + 52 files changed, 788 insertions(+), 226 deletions(-) create mode 100644 source/common/api/win32/os_sys_calls_impl.cc create mode 100644 source/common/api/win32/os_sys_calls_impl.h diff --git a/include/envoy/api/os_sys_calls.h b/include/envoy/api/os_sys_calls.h index 1051699dbf..1c6accb3af 100644 --- a/include/envoy/api/os_sys_calls.h +++ b/include/envoy/api/os_sys_calls.h @@ -19,7 +19,7 @@ class OsSysCalls { /** * @see bind (man 2 bind) */ - virtual SysCallIntResult bind(int sockfd, const sockaddr* addr, socklen_t addrlen) PURE; + virtual SysCallIntResult bind(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) PURE; /** * @see chmod (man 2 chmod) @@ -29,33 +29,33 @@ class OsSysCalls { /** * @see ioctl (man 2 ioctl) */ - virtual SysCallIntResult ioctl(int sockfd, unsigned long int request, void* argp) PURE; + virtual SysCallIntResult ioctl(os_fd_t sockfd, unsigned long int request, void* argp) PURE; /** * @see writev (man 2 writev) */ - virtual SysCallSizeResult writev(int fd, const iovec* iovec, int num_iovec) PURE; + virtual SysCallSizeResult writev(os_fd_t fd, const iovec* iov, int num_iov) PURE; /** * @see readv (man 2 readv) */ - virtual SysCallSizeResult readv(int fd, const iovec* iovec, int num_iovec) PURE; + virtual SysCallSizeResult readv(os_fd_t fd, const iovec* iov, int num_iov) PURE; /** * @see recv (man 2 recv) */ - virtual SysCallSizeResult recv(int socket, void* buffer, size_t length, int flags) PURE; + virtual SysCallSizeResult recv(os_fd_t socket, void* buffer, size_t length, int flags) PURE; /** * @see recvmsg (man 2 recvmsg) */ - virtual SysCallSizeResult recvmsg(int sockfd, struct msghdr* msg, int flags) PURE; + virtual SysCallSizeResult recvmsg(os_fd_t sockfd, msghdr* msg, int flags) PURE; /** * Release all resources allocated for fd. * @return zero on success, -1 returned otherwise. */ - virtual SysCallIntResult close(int fd) PURE; + virtual SysCallIntResult close(os_fd_t fd) PURE; /** * @see man 2 ftruncate @@ -76,34 +76,69 @@ class OsSysCalls { /** * @see man 2 setsockopt */ - virtual SysCallIntResult setsockopt(int sockfd, int level, int optname, const void* optval, + virtual SysCallIntResult setsockopt(os_fd_t sockfd, int level, int optname, const void* optval, socklen_t optlen) PURE; /** * @see man 2 getsockopt */ - virtual SysCallIntResult getsockopt(int sockfd, int level, int optname, void* optval, + virtual SysCallIntResult getsockopt(os_fd_t sockfd, int level, int optname, void* optval, socklen_t* optlen) PURE; /** * @see man 2 socket */ - virtual SysCallIntResult socket(int domain, int type, int protocol) PURE; + virtual SysCallSocketResult socket(int domain, int type, int protocol) PURE; /** * @see man 2 sendmsg */ - virtual SysCallSizeResult sendmsg(int fd, const msghdr* message, int flags) PURE; + virtual SysCallSizeResult sendmsg(os_fd_t sockfd, const msghdr* message, int flags) PURE; /** * @see man 2 getsockname */ - virtual SysCallIntResult getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen) PURE; + virtual SysCallIntResult getsockname(os_fd_t sockfd, sockaddr* addr, socklen_t* addrlen) PURE; /** * @see man 2 gethostname */ virtual SysCallIntResult gethostname(char* name, size_t length) PURE; + + /** + * @see man 2 getpeername + */ + virtual SysCallIntResult getpeername(os_fd_t sockfd, sockaddr* name, socklen_t* namelen) PURE; + + /** + * Toggle the blocking state bit using fcntl + */ + virtual SysCallIntResult setsocketblocking(os_fd_t sockfd, bool blocking) PURE; + + /** + * @see man 2 connect + */ + virtual SysCallIntResult connect(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) PURE; + + /** + * @see man 2 shutdown + */ + virtual SysCallIntResult shutdown(os_fd_t sockfd, int how) PURE; + + /** + * @see man 2 socketpair + */ + virtual SysCallIntResult socketpair(int domain, int type, int protocol, os_fd_t sv[2]) PURE; + + /** + * @see man 2 listen + */ + virtual SysCallIntResult listen(os_fd_t sockfd, int backlog) PURE; + + /** + * @see man 2 write + */ + virtual SysCallSizeResult write(os_fd_t socket, const void* buffer, size_t length) PURE; }; using OsSysCallsPtr = std::unique_ptr; diff --git a/include/envoy/api/os_sys_calls_common.h b/include/envoy/api/os_sys_calls_common.h index 4689e29897..c59469e53e 100644 --- a/include/envoy/api/os_sys_calls_common.h +++ b/include/envoy/api/os_sys_calls_common.h @@ -28,6 +28,7 @@ using SysCallSizeResult = SysCallResult; using SysCallPtrResult = SysCallResult; using SysCallStringResult = SysCallResult; using SysCallBoolResult = SysCallResult; +using SysCallSocketResult = SysCallResult; } // namespace Api } // namespace Envoy diff --git a/include/envoy/common/platform.h b/include/envoy/common/platform.h index cfb8c3bda3..f80390cce5 100644 --- a/include/envoy/common/platform.h +++ b/include/envoy/common/platform.h @@ -18,7 +18,8 @@ #include #include -// defines some frequently used symbols, so we need to undef these interfering symbols. +// defines some frequently used symbols, so we need to undef these +// interfering symbols. #undef DELETE #undef ERROR #undef GetMessage @@ -34,11 +35,80 @@ using ssize_t = ptrdiff_t; +// This is needed so the OsSysCalls interface compiles on Windows, +// shmOpen takes mode_t as an argument. +using mode_t = uint32_t; + +using os_fd_t = SOCKET; + typedef unsigned int sa_family_t; +// Posix structure for scatter/gather I/O, not present on Windows. +struct iovec { + void* iov_base; + size_t iov_len; +}; + +// Posix structure for describing messages sent by 'sendmsg` and received by +// 'recvmsg' +struct msghdr { + void* msg_name; + socklen_t msg_namelen; + iovec* msg_iov; + size_t msg_iovlen; + void* msg_control; + size_t msg_controllen; + int msg_flags; +}; + +// Windows cmsghdr elements are just slightly different than Posix, +// they are defined with the cmsg_len as a 32 bit uint, not size_t +// We express our sendmsg and recvmsg in terms of Posix structures +// and semantics, but won't adjust the cmsghdr elements. +// The default Windows macros dereference the Windows style msghdr +// member Control, which is an indirection that doesn't exist on posix. + +#undef CMSG_FIRSTHDR +#define CMSG_FIRSTHDR(msg) \ + (((msg)->msg_controllen >= sizeof(WSACMSGHDR)) ? (LPWSACMSGHDR)(msg)->msg_control \ + : (LPWSACMSGHDR)NULL) + +#undef CMSG_NXTHDR +#define CMSG_NXTHDR(msg, cmsg) \ + (((cmsg) == NULL) \ + ? CMSG_FIRSTHDR(msg) \ + : ((((PUCHAR)(cmsg) + WSA_CMSGHDR_ALIGN((cmsg)->cmsg_len) + sizeof(WSACMSGHDR)) > \ + (PUCHAR)((msg)->msg_control) + (msg)->msg_controllen) \ + ? (LPWSACMSGHDR)NULL \ + : (LPWSACMSGHDR)((PUCHAR)(cmsg) + WSA_CMSGHDR_ALIGN((cmsg)->cmsg_len)))) + +#ifdef CMSG_DATA +#undef CMSG_DATA +#endif +#define CMSG_DATA(msg) WSA_CMSG_DATA(msg) + +// Following Cygwin's porting example (may not be comprehensive) +#define SO_REUSEPORT SO_REUSEADDR + +// Solve for rfc2292 (need to address rfc3542?) +#ifndef IPV6_RECVPKTINFO +#define IPV6_RECVPKTINFO IPV6_PKTINFO +#endif + +#define SOCKET_VALID(sock) ((sock) != INVALID_SOCKET) +#define SOCKET_INVALID(sock) ((sock) == INVALID_SOCKET) +#define SOCKET_FAILURE(rc) ((rc) == SOCKET_ERROR) +#define SET_SOCKET_INVALID(sock) (sock) = INVALID_SOCKET + +// arguments to shutdown +#define ENVOY_SHUT_RD SD_RECEIVE +#define ENVOY_SHUT_WR SD_SEND +#define ENVOY_SHUT_RDWR SD_BOTH + #else // POSIX #include +#include #include #include #include @@ -46,10 +116,10 @@ typedef unsigned int sa_family_t; #include #include // for mode_t #include +#include #include // for iovec #include -#include -#include +#include #include #if defined(__linux__) @@ -63,4 +133,17 @@ typedef unsigned int sa_family_t; #define IP6T_SO_ORIGINAL_DST 80 #endif +using os_fd_t = int; + +#define INVALID_SOCKET -1 +#define SOCKET_VALID(sock) ((sock) >= 0) +#define SOCKET_INVALID(sock) ((sock) == -1) +#define SOCKET_FAILURE(rc) ((rc) == -1) +#define SET_SOCKET_INVALID(sock) (sock) = -1 + +// arguments to shutdown +#define ENVOY_SHUT_RD SHUT_RD +#define ENVOY_SHUT_WR SHUT_WR +#define ENVOY_SHUT_RDWR SHUT_RDWR + #endif diff --git a/include/envoy/event/dispatcher.h b/include/envoy/event/dispatcher.h index 823e38a514..96bae513a4 100644 --- a/include/envoy/event/dispatcher.h +++ b/include/envoy/event/dispatcher.h @@ -119,7 +119,7 @@ class Dispatcher { * @param events supplies a logical OR of FileReadyType events that the file event should * initially listen on. */ - virtual FileEventPtr createFileEvent(int fd, FileReadyCb cb, FileTriggerType trigger, + virtual FileEventPtr createFileEvent(os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events) PURE; /** diff --git a/include/envoy/network/address.h b/include/envoy/network/address.h index 5117b4bc17..fd5a3b4563 100644 --- a/include/envoy/network/address.h +++ b/include/envoy/network/address.h @@ -139,7 +139,7 @@ class Instance { * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call * is successful, errno_ shouldn't be used. */ - virtual Api::SysCallIntResult bind(int fd) const PURE; + virtual Api::SysCallIntResult bind(os_fd_t fd) const PURE; /** * Connect a socket to this address. The socket should have been created with a call to socket() @@ -148,7 +148,7 @@ class Instance { * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call * is successful, errno_ shouldn't be used. */ - virtual Api::SysCallIntResult connect(int fd) const PURE; + virtual Api::SysCallIntResult connect(os_fd_t fd) const PURE; /** * @return the IP address information IFF type() == Type::Ip, otherwise nullptr. diff --git a/include/envoy/network/io_handle.h b/include/envoy/network/io_handle.h index d5a63e5713..6965f6a146 100644 --- a/include/envoy/network/io_handle.h +++ b/include/envoy/network/io_handle.h @@ -28,7 +28,7 @@ class IoHandle { * TODO(danzh) move it to IoSocketHandle after replacing the calls to it with * calls to IoHandle API's everywhere. */ - virtual int fd() const PURE; + virtual os_fd_t fd() const PURE; /** * Clean up IoHandle resources diff --git a/source/common/api/BUILD b/source/common/api/BUILD index f10bdc078d..25c142ce78 100644 --- a/source/common/api/BUILD +++ b/source/common/api/BUILD @@ -27,6 +27,7 @@ envoy_cc_library( "posix/os_sys_calls_impl.cc", "posix/os_sys_calls_impl_linux.cc", ], + "//bazel:windows_x86_64": ["win32/os_sys_calls_impl.cc"], "//conditions:default": ["posix/os_sys_calls_impl.cc"], }) + envoy_select_hot_restart(["posix/os_sys_calls_impl_hot_restart.cc"]), hdrs = select({ @@ -34,9 +35,11 @@ envoy_cc_library( "posix/os_sys_calls_impl.h", "posix/os_sys_calls_impl_linux.h", ], + "//bazel:windows_x86_64": ["win32/os_sys_calls_impl.h"], "//conditions:default": ["posix/os_sys_calls_impl.h"], }) + envoy_select_hot_restart(["posix/os_sys_calls_impl_hot_restart.h"]), strip_include_prefix = select({ + "//bazel:windows_x86_64": "win32", "//conditions:default": "posix", }), deps = [ diff --git a/source/common/api/posix/os_sys_calls_impl.cc b/source/common/api/posix/os_sys_calls_impl.cc index a75df5a029..865d0dc964 100644 --- a/source/common/api/posix/os_sys_calls_impl.cc +++ b/source/common/api/posix/os_sys_calls_impl.cc @@ -10,92 +10,136 @@ namespace Envoy { namespace Api { -SysCallIntResult OsSysCallsImpl::bind(int sockfd, const sockaddr* addr, socklen_t addrlen) { +SysCallIntResult OsSysCallsImpl::bind(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) { const int rc = ::bind(sockfd, addr, addrlen); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } SysCallIntResult OsSysCallsImpl::chmod(const std::string& path, mode_t mode) { const int rc = ::chmod(path.c_str(), mode); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } -SysCallIntResult OsSysCallsImpl::ioctl(int sockfd, unsigned long int request, void* argp) { +SysCallIntResult OsSysCallsImpl::ioctl(os_fd_t sockfd, unsigned long int request, void* argp) { const int rc = ::ioctl(sockfd, request, argp); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } -SysCallIntResult OsSysCallsImpl::close(int fd) { +SysCallIntResult OsSysCallsImpl::close(os_fd_t fd) { const int rc = ::close(fd); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } -SysCallSizeResult OsSysCallsImpl::writev(int fd, const iovec* iovec, int num_iovec) { - const ssize_t rc = ::writev(fd, iovec, num_iovec); - return {rc, errno}; +SysCallSizeResult OsSysCallsImpl::writev(os_fd_t fd, const iovec* iov, int num_iov) { + const ssize_t rc = ::writev(fd, iov, num_iov); + return {rc, rc != -1 ? 0 : errno}; } -SysCallSizeResult OsSysCallsImpl::readv(int fd, const iovec* iovec, int num_iovec) { - const ssize_t rc = ::readv(fd, iovec, num_iovec); - return {rc, errno}; +SysCallSizeResult OsSysCallsImpl::readv(os_fd_t fd, const iovec* iov, int num_iov) { + const ssize_t rc = ::readv(fd, iov, num_iov); + return {rc, rc != -1 ? 0 : errno}; } -SysCallSizeResult OsSysCallsImpl::recv(int socket, void* buffer, size_t length, int flags) { +SysCallSizeResult OsSysCallsImpl::recv(os_fd_t socket, void* buffer, size_t length, int flags) { const ssize_t rc = ::recv(socket, buffer, length, flags); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } -SysCallSizeResult OsSysCallsImpl::recvmsg(int sockfd, struct msghdr* msg, int flags) { +SysCallSizeResult OsSysCallsImpl::recvmsg(int sockfd, msghdr* msg, int flags) { const ssize_t rc = ::recvmsg(sockfd, msg, flags); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } SysCallIntResult OsSysCallsImpl::ftruncate(int fd, off_t length) { const int rc = ::ftruncate(fd, length); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } SysCallPtrResult OsSysCallsImpl::mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) { void* rc = ::mmap(addr, length, prot, flags, fd, offset); - return {rc, errno}; + return {rc, rc != MAP_FAILED ? 0 : errno}; } SysCallIntResult OsSysCallsImpl::stat(const char* pathname, struct stat* buf) { const int rc = ::stat(pathname, buf); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } -SysCallIntResult OsSysCallsImpl::setsockopt(int sockfd, int level, int optname, const void* optval, - socklen_t optlen) { +SysCallIntResult OsSysCallsImpl::setsockopt(os_fd_t sockfd, int level, int optname, + const void* optval, socklen_t optlen) { const int rc = ::setsockopt(sockfd, level, optname, optval, optlen); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } -SysCallIntResult OsSysCallsImpl::getsockopt(int sockfd, int level, int optname, void* optval, +SysCallIntResult OsSysCallsImpl::getsockopt(os_fd_t sockfd, int level, int optname, void* optval, socklen_t* optlen) { const int rc = ::getsockopt(sockfd, level, optname, optval, optlen); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } -SysCallIntResult OsSysCallsImpl::socket(int domain, int type, int protocol) { - const int rc = ::socket(domain, type, protocol); - return {rc, errno}; +SysCallSocketResult OsSysCallsImpl::socket(int domain, int type, int protocol) { + const os_fd_t rc = ::socket(domain, type, protocol); + return {rc, SOCKET_VALID(rc) ? 0 : errno}; } -SysCallSizeResult OsSysCallsImpl::sendmsg(int fd, const msghdr* message, int flags) { +SysCallSizeResult OsSysCallsImpl::sendmsg(os_fd_t fd, const msghdr* message, int flags) { const int rc = ::sendmsg(fd, message, flags); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } -SysCallIntResult OsSysCallsImpl::getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen) { +SysCallIntResult OsSysCallsImpl::getsockname(os_fd_t sockfd, sockaddr* addr, socklen_t* addrlen) { const int rc = ::getsockname(sockfd, addr, addrlen); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; } SysCallIntResult OsSysCallsImpl::gethostname(char* name, size_t length) { const int rc = ::gethostname(name, length); - return {rc, errno}; + return {rc, rc != -1 ? 0 : errno}; +} + +SysCallIntResult OsSysCallsImpl::getpeername(os_fd_t sockfd, sockaddr* name, socklen_t* namelen) { + const int rc = ::getpeername(sockfd, name, namelen); + return {rc, rc != -1 ? 0 : errno}; +} + +SysCallIntResult OsSysCallsImpl::setsocketblocking(os_fd_t sockfd, bool blocking) { + const int flags = ::fcntl(sockfd, F_GETFL, 0); + int rc; + if (flags == -1) { + return {-1, errno}; + } + if (blocking) { + rc = ::fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK); + } else { + rc = ::fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); + } + return {rc, rc != -1 ? 0 : errno}; +} + +SysCallIntResult OsSysCallsImpl::connect(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) { + const int rc = ::connect(sockfd, addr, addrlen); + return {rc, rc != -1 ? 0 : errno}; +} + +SysCallIntResult OsSysCallsImpl::shutdown(os_fd_t sockfd, int how) { + const int rc = ::shutdown(sockfd, how); + return {rc, rc != -1 ? 0 : errno}; +} + +SysCallIntResult OsSysCallsImpl::socketpair(int domain, int type, int protocol, os_fd_t sv[2]) { + const int rc = ::socketpair(domain, type, protocol, sv); + return {rc, rc != -1 ? 0 : errno}; +} + +SysCallIntResult OsSysCallsImpl::listen(os_fd_t sockfd, int backlog) { + const int rc = ::listen(sockfd, backlog); + return {rc, rc != -1 ? 0 : errno}; +} + +SysCallSizeResult OsSysCallsImpl::write(os_fd_t sockfd, const void* buffer, size_t length) { + const ssize_t rc = ::write(sockfd, buffer, length); + return {rc, rc != -1 ? 0 : errno}; } } // namespace Api diff --git a/source/common/api/posix/os_sys_calls_impl.h b/source/common/api/posix/os_sys_calls_impl.h index 6fe6ba54ce..8cd2ecb5e0 100644 --- a/source/common/api/posix/os_sys_calls_impl.h +++ b/source/common/api/posix/os_sys_calls_impl.h @@ -12,26 +12,33 @@ namespace Api { class OsSysCallsImpl : public OsSysCalls { public: // Api::OsSysCalls - SysCallIntResult bind(int sockfd, const sockaddr* addr, socklen_t addrlen) override; + SysCallIntResult bind(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) override; SysCallIntResult chmod(const std::string& path, mode_t mode) override; - SysCallIntResult ioctl(int sockfd, unsigned long int request, void* argp) override; - SysCallSizeResult writev(int fd, const iovec* iovec, int num_iovec) override; - SysCallSizeResult readv(int fd, const iovec* iovec, int num_iovec) override; - SysCallSizeResult recv(int socket, void* buffer, size_t length, int flags) override; - SysCallSizeResult recvmsg(int sockfd, struct msghdr* msg, int flags) override; - SysCallIntResult close(int fd) override; + SysCallIntResult ioctl(os_fd_t sockfd, unsigned long int request, void* argp) override; + SysCallSizeResult writev(os_fd_t fd, const iovec* iov, int num_iov) override; + SysCallSizeResult readv(os_fd_t fd, const iovec* iov, int num_iov) override; + SysCallSizeResult recv(os_fd_t socket, void* buffer, size_t length, int flags) override; + SysCallSizeResult recvmsg(os_fd_t sockfd, msghdr* msg, int flags) override; + SysCallIntResult close(os_fd_t fd) override; SysCallIntResult ftruncate(int fd, off_t length) override; SysCallPtrResult mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) override; SysCallIntResult stat(const char* pathname, struct stat* buf) override; - SysCallIntResult setsockopt(int sockfd, int level, int optname, const void* optval, + SysCallIntResult setsockopt(os_fd_t sockfd, int level, int optname, const void* optval, socklen_t optlen) override; - SysCallIntResult getsockopt(int sockfd, int level, int optname, void* optval, + SysCallIntResult getsockopt(os_fd_t sockfd, int level, int optname, void* optval, socklen_t* optlen) override; - SysCallIntResult socket(int domain, int type, int protocol) override; - SysCallSizeResult sendmsg(int fd, const msghdr* message, int flags) override; - SysCallIntResult getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen) override; + SysCallSocketResult socket(int domain, int type, int protocol) override; + SysCallSizeResult sendmsg(os_fd_t fd, const msghdr* message, int flags) override; + SysCallIntResult getsockname(os_fd_t sockfd, sockaddr* addr, socklen_t* addrlen) override; SysCallIntResult gethostname(char* name, size_t length) override; + SysCallIntResult getpeername(os_fd_t sockfd, sockaddr* name, socklen_t* namelen) override; + SysCallIntResult setsocketblocking(os_fd_t sockfd, bool blocking) override; + SysCallIntResult connect(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) override; + SysCallIntResult shutdown(os_fd_t sockfd, int how) override; + SysCallIntResult socketpair(int domain, int type, int protocol, os_fd_t sv[2]) override; + SysCallIntResult listen(os_fd_t sockfd, int backlog) override; + SysCallSizeResult write(os_fd_t socket, const void* buffer, size_t length) override; }; using OsSysCallsSingleton = ThreadSafeSingleton; diff --git a/source/common/api/win32/os_sys_calls_impl.cc b/source/common/api/win32/os_sys_calls_impl.cc new file mode 100644 index 0000000000..febab4fdcf --- /dev/null +++ b/source/common/api/win32/os_sys_calls_impl.cc @@ -0,0 +1,333 @@ +#include +#include +#include +#include + +#include +#include + +#include "common/api/os_sys_calls_impl.h" + +#define DWORD_MAX UINT32_MAX + +namespace Envoy { +namespace Api { +namespace { + +using WSABUFPtr = std::unique_ptr; + +struct wsabufResult { + DWORD num_vec_; + WSABUFPtr wsabuf_; +}; + +wsabufResult iovecToWSABUF(const iovec* vec, int in_vec) { + DWORD num_vec = 0; + for (int i = 0; i < in_vec; i++) { + size_t cur_len = vec[i].iov_len; + num_vec++; + while (cur_len > DWORD_MAX) { + num_vec++; + cur_len -= DWORD_MAX; + } + } + + WSABUFPtr wsa_buf(new WSABUF[num_vec]); + + WSABUF* wsa_elt = wsa_buf.get(); + for (int i = 0; i < in_vec; i++) { + CHAR* base = static_cast(vec[i].iov_base); + size_t cur_len = vec[i].iov_len; + do { + wsa_elt->buf = base; + if (cur_len > DWORD_MAX) { + wsa_elt->len = DWORD_MAX; + } else { + wsa_elt->len = static_cast(cur_len); + } + base += wsa_elt->len; + cur_len -= wsa_elt->len; + ++wsa_elt; + } while (cur_len > 0); + } + + return {num_vec, std::move(wsa_buf)}; +} + +LPFN_WSARECVMSG getFnPtrWSARecvMsg() { + LPFN_WSARECVMSG recvmsg_fn_ptr = NULL; + GUID recvmsg_guid = WSAID_WSARECVMSG; + SOCKET sock = INVALID_SOCKET; + DWORD bytes_received = 0; + + sock = socket(AF_INET6, SOCK_DGRAM, 0); + + RELEASE_ASSERT( + WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &recvmsg_guid, sizeof(recvmsg_guid), + &recvmsg_fn_ptr, sizeof(recvmsg_fn_ptr), &bytes_received, NULL, + NULL) != SOCKET_ERROR, + "WSAIoctl SIO_GET_EXTENSION_FUNCTION_POINTER for WSARecvMsg failed, not implemented?"); + + closesocket(sock); + + return recvmsg_fn_ptr; +} + +using WSAMSGPtr = std::unique_ptr; + +WSAMSGPtr msghdrToWSAMSG(const msghdr* msg) { + WSAMSGPtr wsa_msg(new WSAMSG); + + wsa_msg->name = reinterpret_cast(msg->msg_name); + wsa_msg->namelen = msg->msg_namelen; + wsabufResult wsabuf = iovecToWSABUF(msg->msg_iov, msg->msg_iovlen); + wsa_msg->lpBuffers = wsabuf.wsabuf_.get(); + wsa_msg->dwBufferCount = wsabuf.num_vec_; + WSABUF control; + control.buf = reinterpret_cast(msg->msg_control); + control.len = msg->msg_controllen; + wsa_msg->Control = control; + wsa_msg->dwFlags = msg->msg_flags; + + return wsa_msg; +} + +} // namespace + +SysCallIntResult OsSysCallsImpl::bind(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) { + const int rc = ::bind(sockfd, addr, addrlen); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallIntResult OsSysCallsImpl::chmod(const std::string& path, mode_t mode) { + const int rc = ::_chmod(path.c_str(), mode); + return {rc, rc != -1 ? 0 : errno}; +} + +SysCallIntResult OsSysCallsImpl::ioctl(os_fd_t sockfd, unsigned long int request, void* argp) { + const int rc = ::ioctlsocket(sockfd, request, static_cast(argp)); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallIntResult OsSysCallsImpl::close(os_fd_t fd) { + const int rc = ::closesocket(fd); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallSizeResult OsSysCallsImpl::writev(os_fd_t fd, const iovec* iov, int num_iov) { + DWORD bytes_sent; + wsabufResult wsabuf = iovecToWSABUF(iov, num_iov); + + const int rc = + ::WSASend(fd, wsabuf.wsabuf_.get(), wsabuf.num_vec_, &bytes_sent, 0, nullptr, nullptr); + if (SOCKET_FAILURE(rc)) { + return {-1, ::WSAGetLastError()}; + } + return {bytes_sent, 0}; +} + +SysCallSizeResult OsSysCallsImpl::readv(os_fd_t fd, const iovec* iov, int num_iov) { + DWORD bytes_received; + DWORD flags = 0; + wsabufResult wsabuf = iovecToWSABUF(iov, num_iov); + + const int rc = ::WSARecv(fd, wsabuf.wsabuf_.get(), wsabuf.num_vec_, &bytes_received, &flags, + nullptr, nullptr); + if (SOCKET_FAILURE(rc)) { + return {-1, ::WSAGetLastError()}; + } + return {bytes_received, 0}; +} + +SysCallSizeResult OsSysCallsImpl::recv(os_fd_t socket, void* buffer, size_t length, int flags) { + const ssize_t rc = ::recv(socket, static_cast(buffer), length, flags); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallSizeResult OsSysCallsImpl::recvmsg(os_fd_t sockfd, msghdr* msg, int flags) { + DWORD bytes_received; + LPFN_WSARECVMSG recvmsg_fn_ptr = getFnPtrWSARecvMsg(); + WSAMSGPtr wsa_msg = msghdrToWSAMSG(msg); + // Windows supports only a single flag on input to WSARecvMsg + wsa_msg->dwFlags = flags & MSG_PEEK; + const int rc = recvmsg_fn_ptr(sockfd, wsa_msg.get(), &bytes_received, nullptr, nullptr); + if (rc == SOCKET_ERROR) { + return {-1, ::WSAGetLastError()}; + } + msg->msg_namelen = wsa_msg->namelen; + msg->msg_flags = wsa_msg->dwFlags; + msg->msg_controllen = wsa_msg->Control.len; + return {bytes_received, 0}; +} + +SysCallIntResult OsSysCallsImpl::ftruncate(int fd, off_t length) { + const int rc = ::_chsize_s(fd, length); + return {rc, rc == 0 ? 0 : errno}; +} + +SysCallPtrResult OsSysCallsImpl::mmap(void* addr, size_t length, int prot, int flags, int fd, + off_t offset) { + PANIC("mmap not implemented on Windows"); +} + +SysCallIntResult OsSysCallsImpl::stat(const char* pathname, struct stat* buf) { + const int rc = ::stat(pathname, buf); + return {rc, rc != -1 ? 0 : errno}; +} + +SysCallIntResult OsSysCallsImpl::setsockopt(os_fd_t sockfd, int level, int optname, + const void* optval, socklen_t optlen) { + const int rc = ::setsockopt(sockfd, level, optname, static_cast(optval), optlen); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallIntResult OsSysCallsImpl::getsockopt(os_fd_t sockfd, int level, int optname, void* optval, + socklen_t* optlen) { + const int rc = ::getsockopt(sockfd, level, optname, static_cast(optval), optlen); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallSocketResult OsSysCallsImpl::socket(int domain, int type, int protocol) { + const os_fd_t rc = ::socket(domain, type, protocol); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallSizeResult OsSysCallsImpl::sendmsg(os_fd_t sockfd, const msghdr* msg, int flags) { + DWORD bytes_received; + // if overlapped and/or completion routines are supported adjust the arguments accordingly + const int rc = + ::WSASendMsg(sockfd, msghdrToWSAMSG(msg).get(), flags, &bytes_received, nullptr, nullptr); + if (rc == SOCKET_ERROR) { + return {-1, ::WSAGetLastError()}; + } + return {bytes_received, 0}; +} + +SysCallIntResult OsSysCallsImpl::getsockname(os_fd_t sockfd, sockaddr* addr, socklen_t* addrlen) { + const int rc = ::getsockname(sockfd, addr, addrlen); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallIntResult OsSysCallsImpl::gethostname(char* name, size_t length) { + const int rc = ::gethostname(name, length); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallIntResult OsSysCallsImpl::getpeername(os_fd_t sockfd, sockaddr* name, socklen_t* namelen) { + const int rc = ::getpeername(sockfd, name, namelen); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallIntResult OsSysCallsImpl::setsocketblocking(os_fd_t sockfd, bool blocking) { + u_long io_mode = blocking ? 0 : 1; + const int rc = ::ioctlsocket(sockfd, FIONBIO, &io_mode); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallIntResult OsSysCallsImpl::connect(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) { + const int rc = ::connect(sockfd, addr, addrlen); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallIntResult OsSysCallsImpl::shutdown(os_fd_t sockfd, int how) { + const int rc = ::shutdown(sockfd, how); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallIntResult OsSysCallsImpl::socketpair(int domain, int type, int protocol, os_fd_t sv[2]) { + if (sv == nullptr) { + return {SOCKET_ERROR, WSAEINVAL}; + } + + sv[0] = sv[1] = INVALID_SOCKET; + + SysCallSocketResult socket_result = socket(domain, type, protocol); + if (SOCKET_INVALID(socket_result.rc_)) { + return {SOCKET_ERROR, socket_result.errno_}; + } + + os_fd_t listener = socket_result.rc_; + + typedef union { + struct sockaddr_storage sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; + } sa_union; + sa_union a = {}; + socklen_t sa_size = sizeof(a); + + a.sa.ss_family = domain; + if (domain == AF_INET) { + a.in.sin_addr.s_addr = ::htonl(INADDR_LOOPBACK); + a.in.sin_port = 0; + } else if (domain == AF_INET6) { + a.in6.sin6_addr = in6addr_loopback; + a.in6.sin6_port = 0; + } else { + return {SOCKET_ERROR, WSAEINVAL}; + } + + auto onErr = [this, listener, sv]() -> void { + ::closesocket(listener); + ::closesocket(sv[0]); + ::closesocket(sv[1]); + sv[0] = INVALID_SOCKET; + sv[1] = INVALID_SOCKET; + }; + + SysCallIntResult int_result = bind(listener, reinterpret_cast(&a), sa_size); + if (int_result.rc_ == SOCKET_ERROR) { + onErr(); + return int_result; + } + + int_result = listen(listener, 1); + if (int_result.rc_ == SOCKET_ERROR) { + onErr(); + return int_result; + } + + socket_result = socket(domain, type, protocol); + if (SOCKET_INVALID(socket_result.rc_)) { + onErr(); + return {SOCKET_ERROR, socket_result.errno_}; + } + sv[0] = socket_result.rc_; + + a = {}; + int_result = getsockname(listener, reinterpret_cast(&a), &sa_size); + if (int_result.rc_ == SOCKET_ERROR) { + onErr(); + return int_result; + } + + int_result = connect(sv[0], reinterpret_cast(&a), sa_size); + if (int_result.rc_ == SOCKET_ERROR) { + onErr(); + return int_result; + } + + socket_result.rc_ = ::accept(listener, nullptr, nullptr); + if (SOCKET_INVALID(socket_result.rc_)) { + socket_result.errno_ = ::WSAGetLastError(); + onErr(); + return {SOCKET_ERROR, socket_result.errno_}; + } + sv[1] = socket_result.rc_; + + ::closesocket(listener); + return {0, 0}; +} + +SysCallIntResult OsSysCallsImpl::listen(os_fd_t sockfd, int backlog) { + const int rc = ::listen(sockfd, backlog); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +SysCallSizeResult OsSysCallsImpl::write(os_fd_t sockfd, const void* buffer, size_t length) { + const ssize_t rc = ::send(sockfd, static_cast(buffer), length, 0); + return {rc, rc != -1 ? 0 : ::WSAGetLastError()}; +} + +} // namespace Api +} // namespace Envoy diff --git a/source/common/api/win32/os_sys_calls_impl.h b/source/common/api/win32/os_sys_calls_impl.h new file mode 100644 index 0000000000..b39a8416fa --- /dev/null +++ b/source/common/api/win32/os_sys_calls_impl.h @@ -0,0 +1,48 @@ +#pragma once + +#include + +#include "envoy/api/os_sys_calls.h" + +#include "common/singleton/threadsafe_singleton.h" + +namespace Envoy { +namespace Api { + +class OsSysCallsImpl : public OsSysCalls { +public: + // Api::OsSysCalls + SysCallIntResult bind(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) override; + SysCallIntResult chmod(const std::string& path, mode_t mode) override; + SysCallIntResult ioctl(os_fd_t sockfd, unsigned long int request, void* argp) override; + SysCallSizeResult writev(os_fd_t fd, const iovec* iov, int num_iov) override; + SysCallSizeResult readv(os_fd_t fd, const iovec* iov, int num_iov) override; + SysCallSizeResult recv(os_fd_t socket, void* buffer, size_t length, int flags) override; + SysCallSizeResult recvmsg(os_fd_t sockfd, msghdr* msg, int flags) override; + SysCallIntResult close(os_fd_t fd) override; + SysCallIntResult ftruncate(int fd, off_t length) override; + SysCallPtrResult mmap(void* addr, size_t length, int prot, int flags, int fd, + off_t offset) override; + SysCallIntResult stat(const char* pathname, struct stat* buf) override; + SysCallIntResult setsockopt(os_fd_t sockfd, int level, int optname, const void* optval, + socklen_t optlen) override; + SysCallIntResult getsockopt(os_fd_t sockfd, int level, int optname, void* optval, + socklen_t* optlen) override; + SysCallSocketResult socket(int domain, int type, int protocol) override; + SysCallSizeResult sendmsg(os_fd_t fd, const msghdr* message, int flags) override; + SysCallIntResult getsockname(os_fd_t sockfd, sockaddr* addr, socklen_t* addrlen) override; + SysCallIntResult gethostname(char* name, size_t length) override; + + SysCallIntResult getpeername(os_fd_t sockfd, sockaddr* name, socklen_t* namelen) override; + SysCallIntResult setsocketblocking(os_fd_t sockfd, bool blocking) override; + SysCallIntResult connect(os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen) override; + SysCallIntResult shutdown(os_fd_t sockfd, int how) override; + SysCallIntResult socketpair(int domain, int type, int protocol, os_fd_t sv[2]) override; + SysCallIntResult listen(os_fd_t sockfd, int backlog) override; + SysCallSizeResult write(os_fd_t socket, const void* buffer, size_t length) override; +}; + +using OsSysCallsSingleton = ThreadSafeSingleton; + +} // namespace Api +} // namespace Envoy diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index 2ba07cf7a1..274c111e19 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -125,7 +125,7 @@ Network::DnsResolverSharedPtr DispatcherImpl::createDnsResolver( new Network::DnsResolverImpl(*this, resolvers, use_tcp_for_dns_lookups)}; } -FileEventPtr DispatcherImpl::createFileEvent(int fd, FileReadyCb cb, FileTriggerType trigger, +FileEventPtr DispatcherImpl::createFileEvent(os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events) { ASSERT(isThreadSafe()); return FileEventPtr{new FileEventImpl(*this, fd, cb, trigger, events)}; diff --git a/source/common/event/dispatcher_impl.h b/source/common/event/dispatcher_impl.h index 2cfa68f5ad..81800f01c0 100644 --- a/source/common/event/dispatcher_impl.h +++ b/source/common/event/dispatcher_impl.h @@ -55,7 +55,7 @@ class DispatcherImpl : Logger::Loggable, Network::DnsResolverSharedPtr createDnsResolver(const std::vector& resolvers, const bool use_tcp_for_dns_lookups) override; - FileEventPtr createFileEvent(int fd, FileReadyCb cb, FileTriggerType trigger, + FileEventPtr createFileEvent(os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events) override; Filesystem::WatcherPtr createFilesystemWatcher() override; Network::ListenerPtr createListener(Network::SocketSharedPtr&& socket, diff --git a/source/common/event/file_event_impl.cc b/source/common/event/file_event_impl.cc index 3d1883477f..e7ac463c83 100644 --- a/source/common/event/file_event_impl.cc +++ b/source/common/event/file_event_impl.cc @@ -10,7 +10,7 @@ namespace Envoy { namespace Event { -FileEventImpl::FileEventImpl(DispatcherImpl& dispatcher, int fd, FileReadyCb cb, +FileEventImpl::FileEventImpl(DispatcherImpl& dispatcher, os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events) : cb_(cb), fd_(fd), trigger_(trigger) { #ifdef WIN32 diff --git a/source/common/event/file_event_impl.h b/source/common/event/file_event_impl.h index ab9334ad7e..918b237fb6 100644 --- a/source/common/event/file_event_impl.h +++ b/source/common/event/file_event_impl.h @@ -16,7 +16,7 @@ namespace Event { */ class FileEventImpl : public FileEvent, ImplBase { public: - FileEventImpl(DispatcherImpl& dispatcher, int fd, FileReadyCb cb, FileTriggerType trigger, + FileEventImpl(DispatcherImpl& dispatcher, os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events); // Event::FileEvent @@ -27,7 +27,7 @@ class FileEventImpl : public FileEvent, ImplBase { void assignEvents(uint32_t events, event_base* base); FileReadyCb cb_; - int fd_; + os_fd_t fd_; FileTriggerType trigger_; }; diff --git a/source/common/filesystem/win32/watcher_impl.cc b/source/common/filesystem/win32/watcher_impl.cc index eba6809ace..5bc4006391 100644 --- a/source/common/filesystem/win32/watcher_impl.cc +++ b/source/common/filesystem/win32/watcher_impl.cc @@ -9,7 +9,7 @@ namespace Filesystem { WatcherImpl::WatcherImpl(Event::Dispatcher& dispatcher, Api::Api& api) : api_(api), os_sys_calls_(Api::OsSysCallsSingleton::get()) { - SOCKET_FD socks[2]; + os_fd_t socks[2]; Api::SysCallIntResult result = os_sys_calls_.socketpair(AF_INET, SOCK_STREAM, IPPROTO_TCP, socks); ASSERT(result.rc_ == 0); @@ -141,7 +141,7 @@ void WatcherImpl::issueFirstRead(ULONG_PTR param) { ASSERT(rc); } -void WatcherImpl::endDirectoryWatch(SOCKET_FD sock, HANDLE event_handle) { +void WatcherImpl::endDirectoryWatch(os_fd_t sock, HANDLE event_handle) { const BOOL rc = ::SetEvent(event_handle); ASSERT(rc); // let libevent know that a ReadDirectoryChangesW call returned diff --git a/source/common/filesystem/win32/watcher_impl.h b/source/common/filesystem/win32/watcher_impl.h index 5d96e50b45..f107f541ee 100644 --- a/source/common/filesystem/win32/watcher_impl.h +++ b/source/common/filesystem/win32/watcher_impl.h @@ -32,7 +32,7 @@ class WatcherImpl : public Watcher, Logger::Loggable { private: static void issueFirstRead(ULONG_PTR param); static void directoryChangeCompletion(DWORD err, DWORD num_bytes, LPOVERLAPPED overlapped); - static void endDirectoryWatch(SOCKET_FD sock, HANDLE hEvent); + static void endDirectoryWatch(os_fd_t sock, HANDLE hEvent); void watchLoop(); void onDirectoryEvent(); @@ -58,8 +58,8 @@ class WatcherImpl : public Watcher, Logger::Loggable { Api::Api& api_; std::unordered_map callback_map_; Event::FileEventPtr directory_event_; - SOCKET_FD event_write_; - SOCKET_FD event_read_; + os_fd_t event_write_; + os_fd_t event_read_; Thread::ThreadPtr watch_thread_; Thread::ThreadFactoryImplWin32 thread_factory_; HANDLE thread_exit_event_; diff --git a/source/common/network/address_impl.cc b/source/common/network/address_impl.cc index 522223c7c4..5c9c2f2bea 100644 --- a/source/common/network/address_impl.cc +++ b/source/common/network/address_impl.cc @@ -51,12 +51,12 @@ std::string friendlyNameFromAbstractPath(absl::string_view path) { // Check if an IP family is supported on this machine. bool ipFamilySupported(int domain) { Api::OsSysCalls& os_sys_calls = Api::OsSysCallsSingleton::get(); - const Api::SysCallIntResult result = os_sys_calls.socket(domain, SOCK_STREAM, 0); - if (result.rc_ >= 0) { + const Api::SysCallSocketResult result = os_sys_calls.socket(domain, SOCK_STREAM, 0); + if (SOCKET_VALID(result.rc_)) { RELEASE_ASSERT(os_sys_calls.close(result.rc_).rc_ == 0, absl::StrCat("Fail to close fd: response code ", result.rc_)); } - return result.rc_ != -1; + return SOCKET_VALID(result.rc_); } Address::InstanceConstSharedPtr addressFromSockAddr(const sockaddr_storage& ss, socklen_t ss_len, @@ -99,7 +99,7 @@ Address::InstanceConstSharedPtr addressFromSockAddr(const sockaddr_storage& ss, NOT_REACHED_GCOVR_EXCL_LINE; } -InstanceConstSharedPtr addressFromFd(int fd) { +InstanceConstSharedPtr addressFromFd(os_fd_t fd) { sockaddr_storage ss; socklen_t ss_len = sizeof ss; int rc = ::getsockname(fd, reinterpret_cast(&ss), &ss_len); @@ -115,7 +115,7 @@ InstanceConstSharedPtr addressFromFd(int fd) { return addressFromSockAddr(ss, ss_len, rc == 0 && socket_v6only); } -InstanceConstSharedPtr peerAddressFromFd(int fd) { +InstanceConstSharedPtr peerAddressFromFd(os_fd_t fd) { sockaddr_storage ss; socklen_t ss_len = sizeof ss; const int rc = ::getpeername(fd, reinterpret_cast(&ss), &ss_len); @@ -166,8 +166,8 @@ IoHandlePtr InstanceBase::socketFromSocketType(SocketType socket_type) const { domain = AF_UNIX; } - const Api::SysCallIntResult result = Api::OsSysCallsSingleton::get().socket(domain, flags, 0); - RELEASE_ASSERT(result.rc_ != -1, + const Api::SysCallSocketResult result = Api::OsSysCallsSingleton::get().socket(domain, flags, 0); + RELEASE_ASSERT(SOCKET_VALID(result.rc_), fmt::format("socket(2) failed, got error: {}", strerror(result.errno_))); IoHandlePtr io_handle = std::make_unique(result.rc_); @@ -224,12 +224,12 @@ bool Ipv4Instance::operator==(const Instance& rhs) const { (ip_.port() == rhs_casted->ip_.port())); } -Api::SysCallIntResult Ipv4Instance::bind(int fd) const { - auto& os_syscalls = Api::OsSysCallsSingleton::get(); - return os_syscalls.bind(fd, sockAddr(), sockAddrLen()); +Api::SysCallIntResult Ipv4Instance::bind(os_fd_t fd) const { + return Api::OsSysCallsSingleton::get().bind( + fd, reinterpret_cast(&ip_.ipv4_.address_), sizeof(ip_.ipv4_.address_)); } -Api::SysCallIntResult Ipv4Instance::connect(int fd) const { +Api::SysCallIntResult Ipv4Instance::connect(os_fd_t fd) const { const int rc = ::connect(fd, sockAddr(), sockAddrLen()); return {rc, errno}; } @@ -313,12 +313,12 @@ bool Ipv6Instance::operator==(const Instance& rhs) const { (ip_.port() == rhs_casted->ip_.port())); } -Api::SysCallIntResult Ipv6Instance::bind(int fd) const { - auto& os_syscalls = Api::OsSysCallsSingleton::get(); - return os_syscalls.bind(fd, sockAddr(), sockAddrLen()); +Api::SysCallIntResult Ipv6Instance::bind(os_fd_t fd) const { + return Api::OsSysCallsSingleton::get().bind( + fd, reinterpret_cast(&ip_.ipv6_.address_), sizeof(ip_.ipv6_.address_)); } -Api::SysCallIntResult Ipv6Instance::connect(int fd) const { +Api::SysCallIntResult Ipv6Instance::connect(os_fd_t fd) const { const int rc = ::connect(fd, sockAddr(), sockAddrLen()); return {rc, errno}; } @@ -397,7 +397,7 @@ PipeInstance::PipeInstance(const std::string& pipe_path, mode_t mode) : Instance bool PipeInstance::operator==(const Instance& rhs) const { return asString() == rhs.asString(); } -Api::SysCallIntResult PipeInstance::bind(int fd) const { +Api::SysCallIntResult PipeInstance::bind(os_fd_t fd) const { if (!abstract_namespace_) { // Try to unlink an existing filesystem object at the requested path. Ignore // errors -- it's fine if the path doesn't exist, and if it exists but can't @@ -415,7 +415,7 @@ Api::SysCallIntResult PipeInstance::bind(int fd) const { return bind_result; } -Api::SysCallIntResult PipeInstance::connect(int fd) const { +Api::SysCallIntResult PipeInstance::connect(os_fd_t fd) const { const int rc = ::connect(fd, sockAddr(), sockAddrLen()); return {rc, errno}; } diff --git a/source/common/network/address_impl.h b/source/common/network/address_impl.h index f14440b1d5..8a8916ce8c 100644 --- a/source/common/network/address_impl.h +++ b/source/common/network/address_impl.h @@ -37,7 +37,7 @@ InstanceConstSharedPtr addressFromSockAddr(const sockaddr_storage& ss, socklen_t * @param fd socket file descriptor * @return InstanceConstSharedPtr for bound address. */ -InstanceConstSharedPtr addressFromFd(int fd); +InstanceConstSharedPtr addressFromFd(os_fd_t fd); /** * Obtain the address of the peer of the socket with the specified file descriptor. @@ -45,7 +45,7 @@ InstanceConstSharedPtr addressFromFd(int fd); * @param fd socket file descriptor * @return InstanceConstSharedPtr for peer address. */ -InstanceConstSharedPtr peerAddressFromFd(int fd); +InstanceConstSharedPtr peerAddressFromFd(os_fd_t fd); /** * Base class for all address types. @@ -100,8 +100,8 @@ class Ipv4Instance : public InstanceBase { // Network::Address::Instance bool operator==(const Instance& rhs) const override; - Api::SysCallIntResult bind(int fd) const override; - Api::SysCallIntResult connect(int fd) const override; + Api::SysCallIntResult bind(os_fd_t fd) const override; + Api::SysCallIntResult connect(os_fd_t fd) const override; const Ip* ip() const override { return &ip_; } IoHandlePtr socket(SocketType type) const override; @@ -174,8 +174,8 @@ class Ipv6Instance : public InstanceBase { // Network::Address::Instance bool operator==(const Instance& rhs) const override; - Api::SysCallIntResult bind(int fd) const override; - Api::SysCallIntResult connect(int fd) const override; + Api::SysCallIntResult bind(os_fd_t fd) const override; + Api::SysCallIntResult connect(os_fd_t fd) const override; const Ip* ip() const override { return &ip_; } IoHandlePtr socket(SocketType type) const override; @@ -237,8 +237,8 @@ class PipeInstance : public InstanceBase { // Network::Address::Instance bool operator==(const Instance& rhs) const override; - Api::SysCallIntResult bind(int fd) const override; - Api::SysCallIntResult connect(int fd) const override; + Api::SysCallIntResult bind(os_fd_t fd) const override; + Api::SysCallIntResult connect(os_fd_t fd) const override; const Ip* ip() const override { return nullptr; } IoHandlePtr socket(SocketType type) const override; diff --git a/source/common/network/base_listener_impl.cc b/source/common/network/base_listener_impl.cc index d3b4d1cd3b..c096bfcfb5 100644 --- a/source/common/network/base_listener_impl.cc +++ b/source/common/network/base_listener_impl.cc @@ -14,7 +14,7 @@ namespace Envoy { namespace Network { -Address::InstanceConstSharedPtr BaseListenerImpl::getLocalAddress(int fd) { +Address::InstanceConstSharedPtr BaseListenerImpl::getLocalAddress(os_fd_t fd) { return Address::addressFromFd(fd); } diff --git a/source/common/network/base_listener_impl.h b/source/common/network/base_listener_impl.h index ef6578f14f..806789ad35 100644 --- a/source/common/network/base_listener_impl.h +++ b/source/common/network/base_listener_impl.h @@ -23,7 +23,7 @@ class BaseListenerImpl : public virtual Listener { BaseListenerImpl(Event::DispatcherImpl& dispatcher, SocketSharedPtr socket); protected: - virtual Address::InstanceConstSharedPtr getLocalAddress(int fd); + virtual Address::InstanceConstSharedPtr getLocalAddress(os_fd_t fd); Address::InstanceConstSharedPtr local_address_; Event::DispatcherImpl& dispatcher_; diff --git a/source/common/network/dns_impl.cc b/source/common/network/dns_impl.cc index b07a078042..fd4d126464 100644 --- a/source/common/network/dns_impl.cc +++ b/source/common/network/dns_impl.cc @@ -72,7 +72,7 @@ DnsResolverImpl::AresOptions DnsResolverImpl::defaultAresOptions() { } void DnsResolverImpl::initializeChannel(ares_options* options, int optmask) { - options->sock_state_cb = [](void* arg, int fd, int read, int write) { + options->sock_state_cb = [](void* arg, os_fd_t fd, int read, int write) { static_cast(arg)->onAresSocketStateChange(fd, read, write); }; options->sock_state_cb_data = this; @@ -196,14 +196,14 @@ void DnsResolverImpl::updateAresTimer() { } } -void DnsResolverImpl::onEventCallback(int fd, uint32_t events) { +void DnsResolverImpl::onEventCallback(os_fd_t fd, uint32_t events) { const ares_socket_t read_fd = events & Event::FileReadyType::Read ? fd : ARES_SOCKET_BAD; const ares_socket_t write_fd = events & Event::FileReadyType::Write ? fd : ARES_SOCKET_BAD; ares_process_fd(channel_, read_fd, write_fd); updateAresTimer(); } -void DnsResolverImpl::onAresSocketStateChange(int fd, int read, int write) { +void DnsResolverImpl::onAresSocketStateChange(os_fd_t fd, int read, int write) { updateAresTimer(); auto it = events_.find(fd); // Stop tracking events for fd if no more state change events. diff --git a/source/common/network/dns_impl.h b/source/common/network/dns_impl.h index 79a140dea6..44588fc4f5 100644 --- a/source/common/network/dns_impl.h +++ b/source/common/network/dns_impl.h @@ -88,10 +88,10 @@ class DnsResolverImpl : public DnsResolver, protected Logger::Loggable(sock_addr); message.msg_namelen = address_base->sockAddrLen(); message.msg_iov = iov.begin(); diff --git a/source/common/network/io_socket_handle_impl.h b/source/common/network/io_socket_handle_impl.h index 8b9d3e7e39..4ad18a56d0 100644 --- a/source/common/network/io_socket_handle_impl.h +++ b/source/common/network/io_socket_handle_impl.h @@ -15,13 +15,13 @@ namespace Network { */ class IoSocketHandleImpl : public IoHandle, protected Logger::Loggable { public: - explicit IoSocketHandleImpl(int fd = -1) : fd_(fd) {} + explicit IoSocketHandleImpl(os_fd_t fd = INVALID_SOCKET) : fd_(fd) {} // Close underlying socket if close() hasn't been call yet. ~IoSocketHandleImpl() override; // TODO(sbelair2) To be removed when the fd is fully abstracted from clients. - int fd() const override { return fd_; } + os_fd_t fd() const override { return fd_; } Api::IoCallUint64Result close() override; @@ -43,7 +43,7 @@ class IoSocketHandleImpl : public IoHandle, protected Logger::Loggable { public: - virtual Network::Address::InstanceConstSharedPtr getOriginalDst(int fd); + virtual Network::Address::InstanceConstSharedPtr getOriginalDst(os_fd_t fd); // Network::ListenerFilter Network::FilterStatus onAccept(Network::ListenerFilterCallbacks& cb) override; diff --git a/source/extensions/filters/listener/proxy_protocol/proxy_protocol.cc b/source/extensions/filters/listener/proxy_protocol/proxy_protocol.cc index ab4acf68d8..1c90e9c924 100644 --- a/source/extensions/filters/listener/proxy_protocol/proxy_protocol.cc +++ b/source/extensions/filters/listener/proxy_protocol/proxy_protocol.cc @@ -231,7 +231,7 @@ void Filter::parseV1Header(char* buf, size_t len) { } } -bool Filter::parseExtensions(int fd) { +bool Filter::parseExtensions(os_fd_t fd) { // If we ever implement extensions elsewhere, be sure to // continue to skip and ignore those for LOCAL. while (proxy_protocol_header_.value().extensions_length_) { @@ -255,7 +255,7 @@ bool Filter::parseExtensions(int fd) { return true; } -bool Filter::readProxyHeader(int fd) { +bool Filter::readProxyHeader(os_fd_t fd) { while (buf_off_ < MAX_PROXY_PROTO_LEN_V2) { int bytes_avail; auto& os_syscalls = Api::OsSysCallsSingleton::get(); diff --git a/source/extensions/filters/listener/proxy_protocol/proxy_protocol.h b/source/extensions/filters/listener/proxy_protocol/proxy_protocol.h index 1a4b41cde8..4b23d470dc 100644 --- a/source/extensions/filters/listener/proxy_protocol/proxy_protocol.h +++ b/source/extensions/filters/listener/proxy_protocol/proxy_protocol.h @@ -74,12 +74,12 @@ class Filter : public Network::ListenerFilter, Logger::Loggable 0); size_t bytes_read = iov.iov_len; diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc index 958efd02ae..e1c6397732 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc @@ -145,7 +145,7 @@ void EnvoyQuicServerStream::OnBodyAvailable() { // TODO(danzh): check Envoy per stream buffer limit. // Currently read out all the data. while (HasBytesToRead()) { - struct iovec iov; + iovec iov; int num_regions = GetReadableRegions(&iov, 1); ASSERT(num_regions > 0); size_t bytes_read = iov.iov_len; diff --git a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_storage_impl.cc b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_storage_impl.cc index 7522c91781..1c2c63b39e 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_storage_impl.cc +++ b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_storage_impl.cc @@ -17,7 +17,7 @@ namespace quic { // TODO(danzh)Note that |allocator| is not used to allocate memory currently, instead, // Buffer::OwnedImpl allocates memory on its own. Investigate if a customized // QuicBufferAllocator can improve cache hit. -QuicMemSliceStorageImpl::QuicMemSliceStorageImpl(const struct iovec* iov, int iov_count, +QuicMemSliceStorageImpl::QuicMemSliceStorageImpl(const iovec* iov, int iov_count, QuicBufferAllocator* /*allocator*/, const QuicByteCount max_slice_len) { if (iov == nullptr) { diff --git a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_storage_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_storage_impl.h index 3a43ec7316..c7a5e17e18 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_storage_impl.h +++ b/source/extensions/quic_listeners/quiche/platform/quic_mem_slice_storage_impl.h @@ -17,7 +17,7 @@ namespace quic { // QuicMemSliceStorageImpl wraps a MemSlice vector. class QuicMemSliceStorageImpl { public: - QuicMemSliceStorageImpl(const struct iovec* iov, int iov_count, QuicBufferAllocator* allocator, + QuicMemSliceStorageImpl(const iovec* iov, int iov_count, QuicBufferAllocator* allocator, const QuicByteCount max_slice_len); QuicMemSliceStorageImpl(const QuicMemSliceStorageImpl& other) { buffer_.add(other.buffer_); } diff --git a/source/extensions/quic_listeners/quiche/quic_io_handle_wrapper.h b/source/extensions/quic_listeners/quiche/quic_io_handle_wrapper.h index c7725d9880..364f30f8a0 100644 --- a/source/extensions/quic_listeners/quiche/quic_io_handle_wrapper.h +++ b/source/extensions/quic_listeners/quiche/quic_io_handle_wrapper.h @@ -12,7 +12,7 @@ class QuicIoHandleWrapper : public Network::IoHandle { QuicIoHandleWrapper(Network::IoHandle& io_handle) : io_handle_(io_handle) {} // Network::IoHandle - int fd() const override { return io_handle_.fd(); } + os_fd_t fd() const override { return io_handle_.fd(); } Api::IoCallUint64Result close() override { closed_ = true; return Api::ioCallUint64ResultNoError(); diff --git a/test/common/event/file_event_impl_test.cc b/test/common/event/file_event_impl_test.cc index 3794f06788..b7e11bc545 100644 --- a/test/common/event/file_event_impl_test.cc +++ b/test/common/event/file_event_impl_test.cc @@ -33,7 +33,7 @@ class FileEventImplTest : public testing::Test { } protected: - int fds_[2]; + os_fd_t fds_[2]; Api::ApiPtr api_; DispatcherPtr dispatcher_; }; @@ -45,7 +45,7 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, FileEventImplActivateTest, TestUtility::ipTestParamsToString); TEST_P(FileEventImplActivateTest, Activate) { - int fd; + os_fd_t fd; if (GetParam() == Network::Address::IpVersion::v4) { fd = socket(AF_INET, SOCK_STREAM, 0); } else { diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index 6884766987..d1238ed4cd 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -375,8 +375,8 @@ class CustomInstance : public Address::Instance { const std::string& asString() const override { return antagonistic_name_; } absl::string_view asStringView() const override { return antagonistic_name_; } const std::string& logicalName() const override { return antagonistic_name_; } - Api::SysCallIntResult bind(int fd) const override { return instance_.bind(fd); } - Api::SysCallIntResult connect(int fd) const override { return instance_.connect(fd); } + Api::SysCallIntResult bind(os_fd_t fd) const override { return instance_.bind(fd); } + Api::SysCallIntResult connect(os_fd_t fd) const override { return instance_.connect(fd); } const Address::Ip* ip() const override { return instance_.ip(); } IoHandlePtr socket(Address::SocketType type) const override { return instance_.socket(type); } Address::Type type() const override { return instance_.type(); } diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index a105e0806b..0ca9b283bf 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -65,7 +65,7 @@ class TestListenerImpl : public ListenerImpl { bool bind_to_port) : ListenerImpl(dispatcher, std::move(socket), cb, bind_to_port) {} - MOCK_METHOD(Address::InstanceConstSharedPtr, getLocalAddress, (int fd)); + MOCK_METHOD(Address::InstanceConstSharedPtr, getLocalAddress, (os_fd_t fd)); }; using ListenerImplTest = ListenerImplTestBase; @@ -197,8 +197,9 @@ TEST_P(ListenerImplTest, WildcardListenerIpv4Compat) { client_connection->connect(); EXPECT_CALL(listener, getLocalAddress(_)) - .WillOnce(Invoke( - [](int fd) -> Address::InstanceConstSharedPtr { return Address::addressFromFd(fd); })); + .WillOnce(Invoke([](os_fd_t fd) -> Address::InstanceConstSharedPtr { + return Address::addressFromFd(fd); + })); EXPECT_CALL(listener_callbacks, onAccept_(_)) .WillOnce(Invoke([&](Network::ConnectionSocketPtr& socket) -> void { @@ -245,8 +246,9 @@ TEST_P(ListenerImplTest, DisableAndEnableListener) { listener.enable(); EXPECT_CALL(listener, getLocalAddress(_)) - .WillOnce(Invoke( - [](int fd) -> Address::InstanceConstSharedPtr { return Address::addressFromFd(fd); })); + .WillOnce(Invoke([](os_fd_t fd) -> Address::InstanceConstSharedPtr { + return Address::addressFromFd(fd); + })); EXPECT_CALL(listener_callbacks, onAccept_(_)).WillOnce(Invoke([&](ConnectionSocketPtr&) -> void { client_connection->close(ConnectionCloseType::NoFlush); })); diff --git a/test/common/network/socket_option_factory_test.cc b/test/common/network/socket_option_factory_test.cc index 5246b14afc..4ec848f57c 100644 --- a/test/common/network/socket_option_factory_test.cc +++ b/test/common/network/socket_option_factory_test.cc @@ -60,7 +60,7 @@ TEST_F(SocketOptionFactoryTest, TestBuildSocketMarkOptions) { const int type = expected_option.level(); const int option = expected_option.option(); EXPECT_CALL(os_sys_calls_mock_, setsockopt_(_, _, _, _, sizeof(int))) - .WillOnce(Invoke([type, option](int, int input_type, int input_option, const void* optval, + .WillOnce(Invoke([type, option](os_fd_t, int input_type, int input_option, const void* optval, socklen_t) -> int { EXPECT_EQ(100, *static_cast(optval)); EXPECT_EQ(type, input_type); @@ -85,7 +85,7 @@ TEST_F(SocketOptionFactoryTest, TestBuildIpv4TransparentOptions) { const int option = expected_option.option(); EXPECT_CALL(os_sys_calls_mock_, setsockopt_(_, _, _, _, sizeof(int))) .Times(2) - .WillRepeatedly(Invoke([type, option](int, int input_type, int input_option, + .WillRepeatedly(Invoke([type, option](os_fd_t, int input_type, int input_option, const void* optval, socklen_t) -> int { EXPECT_EQ(type, input_type); EXPECT_EQ(option, input_option); @@ -112,7 +112,7 @@ TEST_F(SocketOptionFactoryTest, TestBuildIpv6TransparentOptions) { const int option = expected_option.option(); EXPECT_CALL(os_sys_calls_mock_, setsockopt_(_, _, _, _, sizeof(int))) .Times(2) - .WillRepeatedly(Invoke([type, option](int, int input_type, int input_option, + .WillRepeatedly(Invoke([type, option](os_fd_t, int input_type, int input_option, const void* optval, socklen_t) -> int { EXPECT_EQ(type, input_type); EXPECT_EQ(option, input_option); diff --git a/test/common/network/socket_option_impl_test.cc b/test/common/network/socket_option_impl_test.cc index fb964a1256..e0a6be83f7 100644 --- a/test/common/network/socket_option_impl_test.cc +++ b/test/common/network/socket_option_impl_test.cc @@ -33,7 +33,7 @@ TEST_F(SocketOptionImplTest, HasName) { // contains the option name so the operator can debug. SocketOptionImpl socket_option{envoy::config::core::v3::SocketOption::STATE_PREBIND, optname, 1}; EXPECT_CALL(os_sys_calls_, setsockopt_(_, _, _, _, _)) - .WillOnce(Invoke([](int, int, int, const void* optval, socklen_t) -> int { + .WillOnce(Invoke([](os_fd_t, int, int, const void* optval, socklen_t) -> int { EXPECT_EQ(1, *static_cast(optval)); return -1; })); @@ -47,7 +47,7 @@ TEST_F(SocketOptionImplTest, SetOptionSuccessTrue) { SocketOptionImpl socket_option{envoy::config::core::v3::SocketOption::STATE_PREBIND, ENVOY_MAKE_SOCKET_OPTION_NAME(5, 10), 1}; EXPECT_CALL(os_sys_calls_, setsockopt_(_, 5, 10, _, sizeof(int))) - .WillOnce(Invoke([](int, int, int, const void* optval, socklen_t) -> int { + .WillOnce(Invoke([](os_fd_t, int, int, const void* optval, socklen_t) -> int { EXPECT_EQ(1, *static_cast(optval)); return 0; })); diff --git a/test/common/upstream/cluster_manager_impl_test.cc b/test/common/upstream/cluster_manager_impl_test.cc index 3c84c25d55..ae2f7bbb74 100644 --- a/test/common/upstream/cluster_manager_impl_test.cc +++ b/test/common/upstream/cluster_manager_impl_test.cc @@ -2998,7 +2998,7 @@ class SockoptsTest : public ClusterManagerImplTest { } EXPECT_CALL(os_sys_calls, setsockopt_(_, name_val.first.level(), name_val.first.option(), _, sizeof(int))) - .WillOnce(Invoke([&name_val](int, int, int, const void* optval, socklen_t) -> int { + .WillOnce(Invoke([&name_val](os_fd_t, int, int, const void* optval, socklen_t) -> int { EXPECT_EQ(name_val.second, *static_cast(optval)); return 0; })); @@ -3276,7 +3276,7 @@ class TcpKeepaliveTest : public ClusterManagerImplTest { })); EXPECT_CALL(os_sys_calls, setsockopt_(_, ENVOY_SOCKET_SO_KEEPALIVE.level(), ENVOY_SOCKET_SO_KEEPALIVE.option(), _, sizeof(int))) - .WillOnce(Invoke([](int, int, int, const void* optval, socklen_t) -> int { + .WillOnce(Invoke([](os_fd_t, int, int, const void* optval, socklen_t) -> int { EXPECT_EQ(1, *static_cast(optval)); return 0; })); @@ -3284,7 +3284,7 @@ class TcpKeepaliveTest : public ClusterManagerImplTest { EXPECT_CALL(os_sys_calls, setsockopt_(_, ENVOY_SOCKET_TCP_KEEPCNT.level(), ENVOY_SOCKET_TCP_KEEPCNT.option(), _, sizeof(int))) .WillOnce( - Invoke([&keepalive_probes](int, int, int, const void* optval, socklen_t) -> int { + Invoke([&keepalive_probes](os_fd_t, int, int, const void* optval, socklen_t) -> int { EXPECT_EQ(keepalive_probes.value(), *static_cast(optval)); return 0; })); @@ -3292,16 +3292,17 @@ class TcpKeepaliveTest : public ClusterManagerImplTest { if (keepalive_time.has_value()) { EXPECT_CALL(os_sys_calls, setsockopt_(_, ENVOY_SOCKET_TCP_KEEPIDLE.level(), ENVOY_SOCKET_TCP_KEEPIDLE.option(), _, sizeof(int))) - .WillOnce(Invoke([&keepalive_time](int, int, int, const void* optval, socklen_t) -> int { - EXPECT_EQ(keepalive_time.value(), *static_cast(optval)); - return 0; - })); + .WillOnce( + Invoke([&keepalive_time](os_fd_t, int, int, const void* optval, socklen_t) -> int { + EXPECT_EQ(keepalive_time.value(), *static_cast(optval)); + return 0; + })); } if (keepalive_interval.has_value()) { EXPECT_CALL(os_sys_calls, setsockopt_(_, ENVOY_SOCKET_TCP_KEEPINTVL.level(), ENVOY_SOCKET_TCP_KEEPINTVL.option(), _, sizeof(int))) - .WillOnce( - Invoke([&keepalive_interval](int, int, int, const void* optval, socklen_t) -> int { + .WillOnce(Invoke( + [&keepalive_interval](os_fd_t, int, int, const void* optval, socklen_t) -> int { EXPECT_EQ(keepalive_interval.value(), *static_cast(optval)); return 0; })); diff --git a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc index 44fdd8d701..53b5f5c07f 100644 --- a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc +++ b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc @@ -291,23 +291,23 @@ TEST_P(ProxyProtocolTest, errorRecv_2) { .WillOnce(Return(Api::SysCallSizeResult{-1, 0})); EXPECT_CALL(os_sys_calls, ioctl(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, unsigned long int request, void* argp) { + .WillRepeatedly(Invoke([](os_fd_t fd, unsigned long int request, void* argp) { const int rc = ::ioctl(fd, request, argp); return Api::SysCallIntResult{rc, errno}; })); EXPECT_CALL(os_sys_calls, writev(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, const struct iovec* iov, int iovcnt) { + .WillRepeatedly(Invoke([](os_fd_t fd, const iovec* iov, int iovcnt) { const ssize_t rc = ::writev(fd, iov, iovcnt); return Api::SysCallSizeResult{rc, errno}; })); EXPECT_CALL(os_sys_calls, readv(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, const struct iovec* iov, int iovcnt) { + .WillRepeatedly(Invoke([](os_fd_t fd, const iovec* iov, int iovcnt) { const ssize_t rc = ::readv(fd, iov, iovcnt); return Api::SysCallSizeResult{rc, errno}; })); - EXPECT_CALL(os_sys_calls, close(_)).Times(AnyNumber()).WillRepeatedly(Invoke([](int fd) { + EXPECT_CALL(os_sys_calls, close(_)).Times(AnyNumber()).WillRepeatedly(Invoke([](os_fd_t fd) { const int rc = ::close(fd); return Api::SysCallIntResult{rc, errno}; })); @@ -329,17 +329,17 @@ TEST_P(ProxyProtocolTest, errorFIONREAD_1) { EXPECT_CALL(os_sys_calls, ioctl(_, FIONREAD, _)).WillOnce(Return(Api::SysCallIntResult{-1, 0})); EXPECT_CALL(os_sys_calls, writev(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, const struct iovec* iov, int iovcnt) { + .WillRepeatedly(Invoke([](os_fd_t fd, const iovec* iov, int iovcnt) { const ssize_t rc = ::writev(fd, iov, iovcnt); return Api::SysCallSizeResult{rc, errno}; })); EXPECT_CALL(os_sys_calls, readv(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, const struct iovec* iov, int iovcnt) { + .WillRepeatedly(Invoke([](os_fd_t fd, const iovec* iov, int iovcnt) { const ssize_t rc = ::readv(fd, iov, iovcnt); return Api::SysCallSizeResult{rc, errno}; })); - EXPECT_CALL(os_sys_calls, close(_)).Times(AnyNumber()).WillRepeatedly(Invoke([](int fd) { + EXPECT_CALL(os_sys_calls, close(_)).Times(AnyNumber()).WillRepeatedly(Invoke([](os_fd_t fd) { const int rc = ::close(fd); return Api::SysCallIntResult{rc, errno}; })); @@ -525,7 +525,7 @@ TEST_P(ProxyProtocolTest, v2ParseExtensionsIoctlError) { EXPECT_CALL(os_sys_calls, ioctl(_, FIONREAD, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, unsigned long int request, void* argp) { + .WillRepeatedly(Invoke([](os_fd_t fd, unsigned long int request, void* argp) { int x = ::ioctl(fd, request, argp); if (x == 0 && *static_cast(argp) == sizeof(tlv)) { return Api::SysCallIntResult{-1, errno}; @@ -536,24 +536,24 @@ TEST_P(ProxyProtocolTest, v2ParseExtensionsIoctlError) { EXPECT_CALL(os_sys_calls, recv(_, _, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, void* buf, size_t len, int flags) { + .WillRepeatedly(Invoke([](os_fd_t fd, void* buf, size_t len, int flags) { const ssize_t rc = ::recv(fd, buf, len, flags); return Api::SysCallSizeResult{rc, errno}; })); EXPECT_CALL(os_sys_calls, writev(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, const struct iovec* iov, int iovcnt) { + .WillRepeatedly(Invoke([](os_fd_t fd, const iovec* iov, int iovcnt) { const ssize_t rc = ::writev(fd, iov, iovcnt); return Api::SysCallSizeResult{rc, errno}; })); EXPECT_CALL(os_sys_calls, readv(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, const struct iovec* iov, int iovcnt) { + .WillRepeatedly(Invoke([](os_fd_t fd, const iovec* iov, int iovcnt) { const ssize_t rc = ::readv(fd, iov, iovcnt); return Api::SysCallSizeResult{rc, errno}; })); - EXPECT_CALL(os_sys_calls, close(_)).Times(AnyNumber()).WillRepeatedly(Invoke([](int fd) { + EXPECT_CALL(os_sys_calls, close(_)).Times(AnyNumber()).WillRepeatedly(Invoke([](os_fd_t fd) { const int rc = ::close(fd); return Api::SysCallIntResult{rc, errno}; })); @@ -659,7 +659,7 @@ TEST_P(ProxyProtocolTest, v2Fragmented3Error) { EXPECT_CALL(os_sys_calls, recv(_, _, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, void* buf, size_t len, int flags) { + .WillRepeatedly(Invoke([](os_fd_t fd, void* buf, size_t len, int flags) { const ssize_t rc = ::recv(fd, buf, len, flags); return Api::SysCallSizeResult{rc, errno}; })); @@ -669,23 +669,23 @@ TEST_P(ProxyProtocolTest, v2Fragmented3Error) { EXPECT_CALL(os_sys_calls, ioctl(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, unsigned long int request, void* argp) { + .WillRepeatedly(Invoke([](os_fd_t fd, unsigned long int request, void* argp) { const int rc = ::ioctl(fd, request, argp); return Api::SysCallIntResult{rc, errno}; })); EXPECT_CALL(os_sys_calls, writev(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, const struct iovec* iov, int iovcnt) { + .WillRepeatedly(Invoke([](os_fd_t fd, const iovec* iov, int iovcnt) { const ssize_t rc = ::writev(fd, iov, iovcnt); return Api::SysCallSizeResult{rc, errno}; })); EXPECT_CALL(os_sys_calls, readv(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, const struct iovec* iov, int iovcnt) { + .WillRepeatedly(Invoke([](os_fd_t fd, const iovec* iov, int iovcnt) { const ssize_t rc = ::readv(fd, iov, iovcnt); return Api::SysCallSizeResult{rc, errno}; })); - EXPECT_CALL(os_sys_calls, close(_)).Times(AnyNumber()).WillRepeatedly(Invoke([](int fd) { + EXPECT_CALL(os_sys_calls, close(_)).Times(AnyNumber()).WillRepeatedly(Invoke([](os_fd_t fd) { const int rc = ::close(fd); return Api::SysCallIntResult{rc, errno}; })); @@ -708,7 +708,7 @@ TEST_P(ProxyProtocolTest, v2Fragmented4Error) { EXPECT_CALL(os_sys_calls, recv(_, _, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, void* buf, size_t len, int flags) { + .WillRepeatedly(Invoke([](os_fd_t fd, void* buf, size_t len, int flags) { const ssize_t rc = ::recv(fd, buf, len, flags); return Api::SysCallSizeResult{rc, errno}; })); @@ -718,23 +718,23 @@ TEST_P(ProxyProtocolTest, v2Fragmented4Error) { EXPECT_CALL(os_sys_calls, ioctl(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, unsigned long int request, void* argp) { + .WillRepeatedly(Invoke([](os_fd_t fd, unsigned long int request, void* argp) { const int rc = ::ioctl(fd, request, argp); return Api::SysCallIntResult{rc, errno}; })); EXPECT_CALL(os_sys_calls, writev(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, const struct iovec* iov, int iovcnt) { + .WillRepeatedly(Invoke([](os_fd_t fd, const iovec* iov, int iovcnt) { const ssize_t rc = ::writev(fd, iov, iovcnt); return Api::SysCallSizeResult{rc, errno}; })); EXPECT_CALL(os_sys_calls, readv(_, _, _)) .Times(AnyNumber()) - .WillRepeatedly(Invoke([](int fd, const struct iovec* iov, int iovcnt) { + .WillRepeatedly(Invoke([](os_fd_t fd, const iovec* iov, int iovcnt) { const ssize_t rc = ::readv(fd, iov, iovcnt); return Api::SysCallSizeResult{rc, errno}; })); - EXPECT_CALL(os_sys_calls, close(_)).Times(AnyNumber()).WillRepeatedly(Invoke([](int fd) { + EXPECT_CALL(os_sys_calls, close(_)).Times(AnyNumber()).WillRepeatedly(Invoke([](os_fd_t fd) { const int rc = ::close(fd); return Api::SysCallIntResult{rc, errno}; })); diff --git a/test/extensions/filters/listener/tls_inspector/tls_inspector_test.cc b/test/extensions/filters/listener/tls_inspector/tls_inspector_test.cc index c0416e5282..be0fae3bf0 100644 --- a/test/extensions/filters/listener/tls_inspector/tls_inspector_test.cc +++ b/test/extensions/filters/listener/tls_inspector/tls_inspector_test.cc @@ -44,7 +44,7 @@ class TlsInspectorTest : public testing::Test { // Prepare the first recv attempt during EXPECT_CALL(os_sys_calls_, recv(42, _, _, MSG_PEEK)) .WillOnce( - Invoke([](int fd, void* buffer, size_t length, int flag) -> Api::SysCallSizeResult { + Invoke([](os_fd_t fd, void* buffer, size_t length, int flag) -> Api::SysCallSizeResult { ENVOY_LOG_MISC(error, "In mock syscall recv {} {} {} {}", fd, buffer, length, flag); return Api::SysCallSizeResult{static_cast(0), 0}; })); @@ -247,13 +247,13 @@ TEST_F(TlsInspectorTest, InlineReadSucceed) { std::vector client_hello = Tls::Test::generateClientHello(servername, "\x02h2"); EXPECT_CALL(os_sys_calls_, recv(42, _, _, MSG_PEEK)) - .WillOnce(Invoke( - [&client_hello](int fd, void* buffer, size_t length, int flag) -> Api::SysCallSizeResult { - ENVOY_LOG_MISC(trace, "In mock syscall recv {} {} {} {}", fd, buffer, length, flag); - ASSERT(length >= client_hello.size()); - memcpy(buffer, client_hello.data(), client_hello.size()); - return Api::SysCallSizeResult{ssize_t(client_hello.size()), 0}; - })); + .WillOnce(Invoke([&client_hello](os_fd_t fd, void* buffer, size_t length, + int flag) -> Api::SysCallSizeResult { + ENVOY_LOG_MISC(trace, "In mock syscall recv {} {} {} {}", fd, buffer, length, flag); + ASSERT(length >= client_hello.size()); + memcpy(buffer, client_hello.data(), client_hello.size()); + return Api::SysCallSizeResult{ssize_t(client_hello.size()), 0}; + })); // No event is created if the inline recv parse the hello. EXPECT_CALL(dispatcher_, diff --git a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc index feb101cbb8..1dfd5cc668 100644 --- a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc @@ -678,8 +678,8 @@ TEST_F(QuicPlatformTest, FailToPickUnsedPort) { Envoy::TestThreadsafeSingletonInjector os_calls(&os_sys_calls); // Actually create sockets. EXPECT_CALL(os_sys_calls, socket(_, _, _)).WillRepeatedly([](int domain, int type, int protocol) { - int fd = ::socket(domain, type, protocol); - return Envoy::Api::SysCallIntResult{fd, errno}; + os_fd_t fd = ::socket(domain, type, protocol); + return Envoy::Api::SysCallSocketResult{fd, errno}; }); // Fail bind call's to mimic port exhaustion. EXPECT_CALL(os_sys_calls, bind(_, _, _)) @@ -774,7 +774,7 @@ TEST(EnvoyQuicMemSliceTest, ConstructQuicMemSliceSpan) { TEST(EnvoyQuicMemSliceTest, QuicMemSliceStorage) { std::string str(512, 'a'); - struct iovec iov = {const_cast(str.data()), str.length()}; + iovec iov = {const_cast(str.data()), str.length()}; SimpleBufferAllocator allocator; QuicMemSliceStorage storage(&iov, 1, &allocator, 1024); // Test copy constructor. diff --git a/test/extensions/quic_listeners/quiche/quic_io_handle_wrapper_test.cc b/test/extensions/quic_listeners/quiche/quic_io_handle_wrapper_test.cc index ccf8caa930..512f54853d 100644 --- a/test/extensions/quic_listeners/quiche/quic_io_handle_wrapper_test.cc +++ b/test/extensions/quic_listeners/quiche/quic_io_handle_wrapper_test.cc @@ -39,7 +39,7 @@ TEST_F(QuicIoHandleWrapperTest, Close) { } TEST_F(QuicIoHandleWrapperTest, DelegateIoHandleCalls) { - int fd = socket_.ioHandle().fd(); + os_fd_t fd = socket_.ioHandle().fd(); char data[5]; Buffer::RawSlice slice{data, 5}; EXPECT_CALL(os_sys_calls_, readv(fd, _, 1)).WillOnce(Return(Api::SysCallSizeResult{5u, 0})); @@ -49,7 +49,7 @@ TEST_F(QuicIoHandleWrapperTest, DelegateIoHandleCalls) { wrapper_->writev(&slice, 1); EXPECT_CALL(os_sys_calls_, socket(AF_INET6, SOCK_STREAM, 0)) - .WillRepeatedly(Return(Api::SysCallIntResult{1, 0})); + .WillRepeatedly(Return(Api::SysCallSocketResult{1, 0})); EXPECT_CALL(os_sys_calls_, close(1)).WillRepeatedly(Return(Api::SysCallIntResult{0, 0})); Network::Address::InstanceConstSharedPtr addr(new Network::Address::Ipv4Instance(12345)); @@ -57,7 +57,7 @@ TEST_F(QuicIoHandleWrapperTest, DelegateIoHandleCalls) { wrapper_->sendmsg(&slice, 1, 0, /*self_ip=*/nullptr, *addr); Network::IoHandle::RecvMsgOutput output(nullptr); - EXPECT_CALL(os_sys_calls_, recvmsg(fd, _, 0)).WillOnce(Invoke([](int, struct msghdr* msg, int) { + EXPECT_CALL(os_sys_calls_, recvmsg(fd, _, 0)).WillOnce(Invoke([](os_fd_t, msghdr* msg, int) { sockaddr_storage ss; auto ipv6_addr = reinterpret_cast(&ss); memset(ipv6_addr, 0, sizeof(sockaddr_in6)); diff --git a/test/mocks/api/mocks.cc b/test/mocks/api/mocks.cc index 40204115f2..51747a7493 100644 --- a/test/mocks/api/mocks.cc +++ b/test/mocks/api/mocks.cc @@ -27,7 +27,7 @@ Event::DispatcherPtr MockApi::allocateDispatcher(Buffer::WatermarkFactoryPtr&& w } MockOsSysCalls::MockOsSysCalls() { - ON_CALL(*this, close(_)).WillByDefault(Invoke([](int fd) { + ON_CALL(*this, close(_)).WillByDefault(Invoke([](os_fd_t fd) { const int rc = ::close(fd); return SysCallIntResult{rc, errno}; })); @@ -35,8 +35,8 @@ MockOsSysCalls::MockOsSysCalls() { MockOsSysCalls::~MockOsSysCalls() = default; -SysCallIntResult MockOsSysCalls::setsockopt(int sockfd, int level, int optname, const void* optval, - socklen_t optlen) { +SysCallIntResult MockOsSysCalls::setsockopt(os_fd_t sockfd, int level, int optname, + const void* optval, socklen_t optlen) { ASSERT(optlen == sizeof(int)); // Allow mocking system call failure. @@ -48,7 +48,7 @@ SysCallIntResult MockOsSysCalls::setsockopt(int sockfd, int level, int optname, return SysCallIntResult{0, 0}; }; -SysCallIntResult MockOsSysCalls::getsockopt(int sockfd, int level, int optname, void* optval, +SysCallIntResult MockOsSysCalls::getsockopt(os_fd_t sockfd, int level, int optname, void* optval, socklen_t* optlen) { ASSERT(*optlen == sizeof(int)); int val = 0; diff --git a/test/mocks/api/mocks.h b/test/mocks/api/mocks.h index 4c8c627bf9..f1618d3702 100644 --- a/test/mocks/api/mocks.h +++ b/test/mocks/api/mocks.h @@ -52,33 +52,41 @@ class MockOsSysCalls : public OsSysCallsImpl { ~MockOsSysCalls() override; // Api::OsSysCalls - SysCallIntResult setsockopt(int sockfd, int level, int optname, const void* optval, + SysCallIntResult setsockopt(os_fd_t sockfd, int level, int optname, const void* optval, socklen_t optlen) override; - SysCallIntResult getsockopt(int sockfd, int level, int optname, void* optval, + SysCallIntResult getsockopt(os_fd_t sockfd, int level, int optname, void* optval, socklen_t* optlen) override; - MOCK_METHOD(SysCallIntResult, bind, (int sockfd, const sockaddr* addr, socklen_t addrlen)); - MOCK_METHOD(SysCallIntResult, ioctl, (int sockfd, unsigned long int request, void* argp)); - MOCK_METHOD(SysCallIntResult, close, (int)); - MOCK_METHOD(SysCallSizeResult, writev, (int, const iovec*, int)); - MOCK_METHOD(SysCallSizeResult, sendmsg, (int fd, const msghdr* message, int flags)); - MOCK_METHOD(SysCallSizeResult, readv, (int, const iovec*, int)); - MOCK_METHOD(SysCallSizeResult, recv, (int socket, void* buffer, size_t length, int flags)); - MOCK_METHOD(SysCallSizeResult, recvmsg, (int socket, struct msghdr* msg, int flags)); + MOCK_METHOD(SysCallIntResult, bind, (os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen)); + MOCK_METHOD(SysCallIntResult, ioctl, (os_fd_t sockfd, unsigned long int request, void* argp)); + MOCK_METHOD(SysCallIntResult, close, (os_fd_t)); + MOCK_METHOD(SysCallSizeResult, writev, (os_fd_t, const iovec*, int)); + MOCK_METHOD(SysCallSizeResult, sendmsg, (os_fd_t fd, const msghdr* msg, int flags)); + MOCK_METHOD(SysCallSizeResult, readv, (os_fd_t, const iovec*, int)); + MOCK_METHOD(SysCallSizeResult, recv, (os_fd_t socket, void* buffer, size_t length, int flags)); + MOCK_METHOD(SysCallSizeResult, recvmsg, (os_fd_t socket, msghdr* msg, int flags)); MOCK_METHOD(SysCallIntResult, ftruncate, (int fd, off_t length)); MOCK_METHOD(SysCallPtrResult, mmap, (void* addr, size_t length, int prot, int flags, int fd, off_t offset)); MOCK_METHOD(SysCallIntResult, stat, (const char* name, struct stat* stat)); MOCK_METHOD(SysCallIntResult, chmod, (const std::string& name, mode_t mode)); MOCK_METHOD(int, setsockopt_, - (int sockfd, int level, int optname, const void* optval, socklen_t optlen)); + (os_fd_t sockfd, int level, int optname, const void* optval, socklen_t optlen)); MOCK_METHOD(int, getsockopt_, - (int sockfd, int level, int optname, void* optval, socklen_t* optlen)); - MOCK_METHOD(SysCallIntResult, socket, (int domain, int type, int protocol)); + (os_fd_t sockfd, int level, int optname, void* optval, socklen_t* optlen)); + MOCK_METHOD(SysCallSocketResult, socket, (int domain, int type, int protocol)); MOCK_METHOD(SysCallIntResult, gethostname, (char* name, size_t length)); + MOCK_METHOD(SysCallIntResult, getsockname, (os_fd_t sockfd, sockaddr* name, socklen_t* namelen)); + MOCK_METHOD(SysCallIntResult, getpeername, (os_fd_t sockfd, sockaddr* name, socklen_t* namelen)); + MOCK_METHOD(SysCallIntResult, setsocketblocking, (os_fd_t sockfd, bool block)); + MOCK_METHOD(SysCallIntResult, connect, (os_fd_t sockfd, const sockaddr* addr, socklen_t addrlen)); + MOCK_METHOD(SysCallIntResult, shutdown, (os_fd_t sockfd, int how)); + MOCK_METHOD(SysCallIntResult, socketpair, (int domain, int type, int protocol, os_fd_t sv[2])); + MOCK_METHOD(SysCallIntResult, listen, (os_fd_t sockfd, int backlog)); + MOCK_METHOD(SysCallSizeResult, write, (os_fd_t sockfd, const void* buffer, size_t length)); // Map from (sockfd,level,optname) to boolean socket option. - using SockOptKey = std::tuple; + using SockOptKey = std::tuple; std::map boolsockopts_; }; diff --git a/test/mocks/event/mocks.h b/test/mocks/event/mocks.h index cf86b5ed09..08219ef98b 100644 --- a/test/mocks/event/mocks.h +++ b/test/mocks/event/mocks.h @@ -52,7 +52,7 @@ class MockDispatcher : public Dispatcher { createClientConnection_(address, source_address, transport_socket, options)}; } - FileEventPtr createFileEvent(int fd, FileReadyCb cb, FileTriggerType trigger, + FileEventPtr createFileEvent(os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events) override { return FileEventPtr{createFileEvent_(fd, cb, trigger, events)}; } @@ -99,7 +99,7 @@ class MockDispatcher : public Dispatcher { (const std::vector& resolvers, const bool use_tcp_for_dns_lookups)); MOCK_METHOD(FileEvent*, createFileEvent_, - (int fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events)); + (os_fd_t fd, FileReadyCb cb, FileTriggerType trigger, uint32_t events)); MOCK_METHOD(Filesystem::Watcher*, createFilesystemWatcher_, ()); MOCK_METHOD(Network::Listener*, createListener_, (Network::SocketSharedPtr && socket, Network::ListenerCallbacks& cb, diff --git a/test/mocks/network/mocks.h b/test/mocks/network/mocks.h index 897434dbc6..5e408d575c 100644 --- a/test/mocks/network/mocks.h +++ b/test/mocks/network/mocks.h @@ -377,8 +377,8 @@ class MockResolvedAddress : public Address::Instance { return asString() == other.asString(); } - MOCK_METHOD(Api::SysCallIntResult, bind, (int), (const)); - MOCK_METHOD(Api::SysCallIntResult, connect, (int), (const)); + MOCK_METHOD(Api::SysCallIntResult, bind, (os_fd_t), (const)); + MOCK_METHOD(Api::SysCallIntResult, connect, (os_fd_t), (const)); MOCK_METHOD(Address::Ip*, ip, (), (const)); MOCK_METHOD(IoHandlePtr, socket, (Address::SocketType), (const)); MOCK_METHOD(Address::Type, type, (), (const)); diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 4988b45767..5da246dade 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -555,9 +555,6 @@ drain_type: modify_only TEST_F(ListenerManagerImplTest, AddListenerOnIpv4OnlySetups) { InSequence s; - NiceMock os_sys_calls; - TestThreadsafeSingletonInjector os_calls(&os_sys_calls); - const std::string listener_foo_yaml = R"EOF( name: foo address: @@ -571,9 +568,11 @@ drain_type: default ListenerHandle* listener_foo = expectListenerCreate(false, true); - ON_CALL(os_sys_calls, socket(AF_INET, _, 0)).WillByDefault(Return(Api::SysCallIntResult{5, 0})); - ON_CALL(os_sys_calls, socket(AF_INET6, _, 0)).WillByDefault(Return(Api::SysCallIntResult{-1, 0})); - ON_CALL(os_sys_calls, close(_)).WillByDefault(Return(Api::SysCallIntResult{0, 0})); + ON_CALL(os_sys_calls_, socket(AF_INET, _, 0)) + .WillByDefault(Return(Api::SysCallSocketResult{5, 0})); + ON_CALL(os_sys_calls_, socket(AF_INET6, _, 0)) + .WillByDefault(Return(Api::SysCallSocketResult{INVALID_SOCKET, 0})); + ON_CALL(os_sys_calls_, close(_)).WillByDefault(Return(Api::SysCallIntResult{0, 0})); EXPECT_CALL(listener_factory_, createListenSocket(_, _, _, {true})); @@ -588,9 +587,6 @@ drain_type: default TEST_F(ListenerManagerImplTest, AddListenerOnIpv6OnlySetups) { InSequence s; - NiceMock os_sys_calls; - TestThreadsafeSingletonInjector os_calls(&os_sys_calls); - const std::string listener_foo_yaml = R"EOF( name: foo address: @@ -604,9 +600,11 @@ drain_type: default ListenerHandle* listener_foo = expectListenerCreate(false, true); - ON_CALL(os_sys_calls, socket(AF_INET, _, 0)).WillByDefault(Return(Api::SysCallIntResult{-1, 0})); - ON_CALL(os_sys_calls, socket(AF_INET6, _, 0)).WillByDefault(Return(Api::SysCallIntResult{5, 0})); - ON_CALL(os_sys_calls, close(_)).WillByDefault(Return(Api::SysCallIntResult{0, 0})); + ON_CALL(os_sys_calls_, socket(AF_INET, _, 0)) + .WillByDefault(Return(Api::SysCallSocketResult{INVALID_SOCKET, 0})); + ON_CALL(os_sys_calls_, socket(AF_INET6, _, 0)) + .WillByDefault(Return(Api::SysCallSocketResult{5, 0})); + ON_CALL(os_sys_calls_, close(_)).WillByDefault(Return(Api::SysCallIntResult{0, 0})); EXPECT_CALL(listener_factory_, createListenSocket(_, _, _, {true})); @@ -1108,9 +1106,11 @@ name: foo filter_chains: - filters: [] )EOF"; + Api::OsSysCallsImpl os_syscall; auto syscall_result = os_syscall.socket(AF_INET, SOCK_STREAM, 0); - ASSERT_GE(syscall_result.rc_, 0); + ASSERT_TRUE(SOCKET_VALID(syscall_result.rc_)); + ListenerHandle* listener_foo = expectListenerCreate(true, true); EXPECT_CALL(listener_factory_, createListenSocket(_, _, _, {false})) .WillOnce(Invoke([this, &syscall_result, &real_listener_factory]( @@ -1121,10 +1121,7 @@ name: foo EXPECT_CALL(server_, hotRestart).Times(0); // When bind_to_port is equal to false, create socket fd directly, and do not get socket // fd through hot restart. - NiceMock os_sys_calls; - TestThreadsafeSingletonInjector os_calls(&os_sys_calls); - ON_CALL(os_sys_calls, socket(AF_INET, _, 0)) - .WillByDefault(Return(Api::SysCallIntResult{syscall_result.rc_, 0})); + ON_CALL(os_sys_calls_, socket(AF_INET, _, 0)).WillByDefault(Return(syscall_result)); return real_listener_factory.createListenSocket(address, socket_type, options, params); })); EXPECT_CALL(listener_foo->target_, initialize()); @@ -1150,7 +1147,7 @@ reuse_port: true Api::OsSysCallsImpl os_syscall; auto syscall_result = os_syscall.socket(AF_INET, SOCK_STREAM, 0); - ASSERT_GE(syscall_result.rc_, 0); + ASSERT_TRUE(SOCKET_VALID(syscall_result.rc_)); ListenerHandle* listener_foo = expectListenerCreate(true, true); EXPECT_CALL(listener_factory_, createListenSocket(_, _, _, {{true, false}})) @@ -1160,10 +1157,7 @@ reuse_port: true const Network::Socket::OptionsSharedPtr& options, const ListenSocketCreationParams& params) -> Network::SocketSharedPtr { EXPECT_CALL(server_, hotRestart).Times(0); - NiceMock os_sys_calls; - TestThreadsafeSingletonInjector os_calls(&os_sys_calls); - ON_CALL(os_sys_calls, socket(AF_INET, _, 0)) - .WillByDefault(Return(Api::SysCallIntResult{syscall_result.rc_, 0})); + ON_CALL(os_sys_calls_, socket(AF_INET, _, 0)).WillByDefault(Return(syscall_result)); return real_listener_factory.createListenSocket(address, socket_type, options, params); })); EXPECT_CALL(listener_foo->target_, initialize()); diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt index 0629254396..8a2c0af5b2 100644 --- a/tools/spelling/spelling_dictionary.txt +++ b/tools/spelling/spelling_dictionary.txt @@ -568,6 +568,7 @@ failover fallbacks fastbuild favicon +fcntl fd fds filename @@ -749,6 +750,7 @@ mongo moveable msec msg +msghdr multi multicast multikill @@ -979,6 +981,7 @@ sizeof smatch snapshotted sockaddr +socketpair sockfd sockopt sockopts From a267a970523fc43d45c38f83d2f9c69ef86e20a4 Mon Sep 17 00:00:00 2001 From: Kuat Date: Tue, 18 Feb 2020 13:44:47 -0800 Subject: [PATCH 73/87] test: use semantic names for access log extensions (#10071) Signed-off-by: Kuat Yessenov --- .../common/access_log/access_log_impl_test.cc | 99 ++++++++++--------- .../common/router/router_upstream_log_test.cc | 4 +- test/config/integration/server.yaml | 2 +- test/config/utility.cc | 2 +- .../http_grpc_access_log_integration_test.cc | 2 +- .../tcp_grpc_access_log_integration_test.cc | 2 +- .../http_connection_manager/config_test.cc | 6 +- .../http2_upstream_integration_test.cc | 4 +- .../integration/tcp_proxy_integration_test.cc | 2 +- 9 files changed, 66 insertions(+), 57 deletions(-) diff --git a/test/common/access_log/access_log_impl_test.cc b/test/common/access_log/access_log_impl_test.cc index 4e31029700..e61b566c34 100644 --- a/test/common/access_log/access_log_impl_test.cc +++ b/test/common/access_log/access_log_impl_test.cc @@ -66,7 +66,7 @@ class AccessLogImplTest : public testing::Test { TEST_F(AccessLogImplTest, LogMoreData) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -89,7 +89,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, DownstreamDisconnect) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -111,7 +111,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, RouteName) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -138,7 +138,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, EnvoyUpstreamServiceTime) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -157,7 +157,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, NoFilter) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -177,7 +177,7 @@ TEST_F(AccessLogImplTest, UpstreamHost) { stream_info_.upstream_host_ = Upstream::makeTestHostDescription(cluster, "tcp://10.0.0.5:1234"); const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -194,7 +194,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, WithFilterMiss) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: or_filter: filters: @@ -226,7 +226,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, WithFilterHit) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: or_filter: filters: @@ -269,7 +269,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, RuntimeFilter) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: runtime_filter: runtime_key: access_log.test_key @@ -308,7 +308,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, RuntimeFilterV2) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: runtime_filter: runtime_key: access_log.test_key @@ -350,7 +350,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, RuntimeFilterV2IndependentRandomness) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: runtime_filter: runtime_key: access_log.test_key @@ -384,7 +384,7 @@ TEST_F(AccessLogImplTest, PathRewrite) { request_headers_ = {{":method", "GET"}, {":path", "/foo"}, {"x-envoy-original-path", "/bar"}}; const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null @@ -401,7 +401,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, HealthCheckTrue) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: not_health_check_filter: {} typed_config: @@ -420,7 +420,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, HealthCheckFalse) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: not_health_check_filter: {} typed_config: @@ -447,7 +447,7 @@ TEST_F(AccessLogImplTest, RequestTracing) { UuidUtils::setTraceableUuid(sample_tracing_guid, UuidTraceStatus::Sampled); const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: traceable_filter: {} typed_config: @@ -481,7 +481,7 @@ TEST(AccessLogImplTestCtor, FiltersMissingInOrAndFilter) { { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: or_filter: {} typed_config: @@ -495,7 +495,7 @@ name: envoy.access_loggers.file { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: and_filter: {} typed_config: @@ -510,7 +510,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, AndFilter) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: and_filter: filters: @@ -546,7 +546,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, OrFilter) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: or_filter: filters: @@ -581,7 +581,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, MultipleOperators) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: and_filter: filters: @@ -692,7 +692,7 @@ TEST(AccessLogFilterTest, StatusCodeWithRuntimeKey) { TEST_F(AccessLogImplTest, StatusCodeLessThan) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: status_code_filter: comparison: @@ -720,7 +720,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, HeaderPresence) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: header_filter: header: @@ -742,7 +742,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, HeaderExactMatch) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: header_filter: header: @@ -771,7 +771,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, HeaderRegexMatch) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: header_filter: header: @@ -806,7 +806,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, HeaderRangeMatch) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: header_filter: header: @@ -851,7 +851,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, ResponseFlagFilterAnyFlag) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: response_flag_filter: {} typed_config: @@ -871,7 +871,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, ResponseFlagFilterSpecificFlag) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: response_flag_filter: flags: @@ -897,7 +897,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, ResponseFlagFilterSeveralFlags) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: response_flag_filter: flags: @@ -924,7 +924,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, ResponseFlagFilterAllFlagsInPGV) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: response_flag_filter: flags: @@ -989,7 +989,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, ResponseFlagFilterUnsupportedFlag) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: response_flag_filter: flags: @@ -1007,7 +1007,7 @@ name: envoy.access_loggers.file "[\"embedded message failed validation\"] | caused by " "ResponseFlagFilterValidationError.Flags[i]: [\"value must be in list \" [\"LH\" \"UH\" " "\"UT\" \"LR\" \"UR\" \"UF\" \"UC\" \"UO\" \"NR\" \"DI\" \"FI\" \"RL\" \"UAEX\" \"RLSE\" " - "\"DC\" \"URX\" \"SI\" \"IH\" \"DPE\"]]): name: \"envoy.access_loggers.file\"\nfilter {\n " + "\"DC\" \"URX\" \"SI\" \"IH\" \"DPE\"]]): name: \"accesslog\"\nfilter {\n " "response_flag_filter {\n flags: \"UnsupportedFlag\"\n }\n}\ntyped_config {\n " "[type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog] {\n path: \"/dev/null\"\n " "}\n}\n"); @@ -1015,7 +1015,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, ValidateTypedConfig) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: response_flag_filter: flags: @@ -1033,7 +1033,7 @@ name: envoy.access_loggers.file "[\"embedded message failed validation\"] | caused by " "ResponseFlagFilterValidationError.Flags[i]: [\"value must be in list \" [\"LH\" \"UH\" " "\"UT\" \"LR\" \"UR\" \"UF\" \"UC\" \"UO\" \"NR\" \"DI\" \"FI\" \"RL\" \"UAEX\" \"RLSE\" " - "\"DC\" \"URX\" \"SI\" \"IH\" \"DPE\"]]): name: \"envoy.access_loggers.file\"\nfilter {\n " + "\"DC\" \"URX\" \"SI\" \"IH\" \"DPE\"]]): name: \"accesslog\"\nfilter {\n " "response_flag_filter {\n flags: \"UnsupportedFlag\"\n }\n}\ntyped_config {\n " "[type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog] {\n path: \"/dev/null\"\n " "}\n}\n"); @@ -1041,7 +1041,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, GrpcStatusFilterValues) { const std::string yaml_template = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: grpc_status_filter: statuses: @@ -1072,7 +1072,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, GrpcStatusFilterUnsupportedValue) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: grpc_status_filter: statuses: @@ -1088,7 +1088,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, GrpcStatusFilterBlock) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: grpc_status_filter: statuses: @@ -1109,7 +1109,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, GrpcStatusFilterHttpCodes) { const std::string yaml_template = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: grpc_status_filter: statuses: @@ -1141,7 +1141,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, GrpcStatusFilterNoCode) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: grpc_status_filter: statuses: @@ -1160,7 +1160,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, GrpcStatusFilterExclude) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: grpc_status_filter: exclude: true @@ -1185,7 +1185,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, GrpcStatusFilterExcludeFalse) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: grpc_status_filter: exclude: false @@ -1207,7 +1207,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, GrpcStatusFilterHeader) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: grpc_status_filter: statuses: @@ -1251,7 +1251,7 @@ TEST_F(AccessLogImplTest, TestHeaderFilterPresence) { Registry::RegisterFactory registered; const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: extension_filter: name: test_header_filter @@ -1327,7 +1327,7 @@ TEST_F(AccessLogImplTest, SampleExtensionFilter) { Registry::RegisterFactory registered; const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: extension_filter: name: sample_extension_filter @@ -1355,7 +1355,7 @@ name: envoy.access_loggers.file TEST_F(AccessLogImplTest, UnregisteredExtensionFilter) { { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: extension_filter: name: unregistered_extension_filter @@ -1374,7 +1374,7 @@ name: envoy.access_loggers.file { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog filter: extension_filter: name: bar @@ -1390,6 +1390,15 @@ name: envoy.access_loggers.file // Test that the deprecated extension names still function. TEST_F(AccessLogImplTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName)) { + { + envoy::config::accesslog::v3::AccessLog config; + config.set_name("envoy.access_loggers.file"); + + EXPECT_NO_THROW( + Config::Utility::getAndCheckFactory( + config)); + } + { envoy::config::accesslog::v3::AccessLog config; config.set_name("envoy.file_access_log"); diff --git a/test/common/router/router_upstream_log_test.cc b/test/common/router/router_upstream_log_test.cc index 8e57dae134..678b897c13 100644 --- a/test/common/router/router_upstream_log_test.cc +++ b/test/common/router/router_upstream_log_test.cc @@ -38,7 +38,7 @@ namespace { absl::optional testUpstreamLog() { // Custom format without timestamps or durations. const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog format: "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL% %RESPONSE_CODE% @@ -283,7 +283,7 @@ TEST_F(RouterUpstreamLogTest, LogHeaders) { // Test timestamps and durations are emitted. TEST_F(RouterUpstreamLogTest, LogTimestampsAndDurations) { const std::string yaml = R"EOF( -name: envoy.access_loggers.file +name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog format: "[%START_TIME%] %REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL% diff --git a/test/config/integration/server.yaml b/test/config/integration/server.yaml index 6ee86fb72f..ca066784b2 100644 --- a/test/config/integration/server.yaml +++ b/test/config/integration/server.yaml @@ -50,7 +50,7 @@ static_resources: typed_config: "@type": type.googleapis.com/envoy.config.filter.http.router.v2.Router access_log: - - name: envoy.access_loggers.file + - name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: /dev/null diff --git a/test/config/utility.cc b/test/config/utility.cc index cd6f6e0a28..00b7b6c546 100644 --- a/test/config/utility.cc +++ b/test/config/utility.cc @@ -117,7 +117,7 @@ const std::string ConfigHelper::HTTP_PROXY_CONFIG = BASE_CONFIG + R"EOF( name: envoy.router codec_type: HTTP1 access_log: - name: envoy.access_loggers.file + name: accesslog filter: not_health_check_filter: {} typed_config: diff --git a/test/extensions/access_loggers/grpc/http_grpc_access_log_integration_test.cc b/test/extensions/access_loggers/grpc/http_grpc_access_log_integration_test.cc index dfd048e506..e66655b92c 100644 --- a/test/extensions/access_loggers/grpc/http_grpc_access_log_integration_test.cc +++ b/test/extensions/access_loggers/grpc/http_grpc_access_log_integration_test.cc @@ -43,7 +43,7 @@ class AccessLogIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm) { auto* access_log = hcm.add_access_log(); - access_log->set_name("envoy.access_loggers.http_grpc"); + access_log->set_name("grpc_accesslog"); envoy::extensions::access_loggers::grpc::v3::HttpGrpcAccessLogConfig config; auto* common_config = config.mutable_common_config(); diff --git a/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc b/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc index ac006cff1b..45506b58da 100644 --- a/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc +++ b/test/extensions/access_loggers/grpc/tcp_grpc_access_log_integration_test.cc @@ -60,7 +60,7 @@ class TcpGrpcAccessLogIntegrationTest : public Grpc::GrpcClientIntegrationParamT MessageUtil::anyConvert( *config_blob); auto* access_log = tcp_proxy_config.add_access_log(); - access_log->set_name("envoy.access_loggers.tcp_grpc"); + access_log->set_name("grpc_accesslog"); envoy::extensions::access_loggers::grpc::v3::TcpGrpcAccessLogConfig access_log_config; auto* common_config = access_log_config.mutable_common_config(); common_config->set_log_name("foo"); diff --git a/test/extensions/filters/network/http_connection_manager/config_test.cc b/test/extensions/filters/network/http_connection_manager/config_test.cc index 6bec548d7f..285bce950f 100644 --- a/test/extensions/filters/network/http_connection_manager/config_test.cc +++ b/test/extensions/filters/network/http_connection_manager/config_test.cc @@ -877,7 +877,7 @@ stat_prefix: my_stat_prefix - name: envoy.http_dynamo_filter config: {} access_log: -- name: envoy.access_loggers.file +- name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/dev/null" @@ -906,7 +906,7 @@ stat_prefix: my_stat_prefix - name: envoy.http_dynamo_filter typed_config: {} access_log: -- name: envoy.access_loggers.file +- name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/dev/null" @@ -936,7 +936,7 @@ stat_prefix: my_stat_prefix - name: envoy.http_dynamo_filter typed_config: {} access_log: -- name: envoy.access_loggers.file +- name: accesslog typed_config: "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog path: "/dev/null" diff --git a/test/integration/http2_upstream_integration_test.cc b/test/integration/http2_upstream_integration_test.cc index 1285ffb6c9..825388c048 100644 --- a/test/integration/http2_upstream_integration_test.cc +++ b/test/integration/http2_upstream_integration_test.cc @@ -330,7 +330,7 @@ name: envoy.router typed_config: "@type": type.googleapis.com/envoy.config.filter.http.router.v2.Router upstream_log: - name: envoy.access_loggers.file + name: accesslog filter: not_health_check_filter: {} typed_config: @@ -455,7 +455,7 @@ name: envoy.router typed_config: "@type": type.googleapis.com/envoy.config.filter.http.router.v2.Router upstream_log: - name: envoy.access_loggers.http_grpc + name: grpc_accesslog filter: not_health_check_filter: {} typed_config: diff --git a/test/integration/tcp_proxy_integration_test.cc b/test/integration/tcp_proxy_integration_test.cc index 6520ed2a97..4ebaf52f50 100644 --- a/test/integration/tcp_proxy_integration_test.cc +++ b/test/integration/tcp_proxy_integration_test.cc @@ -248,7 +248,7 @@ TEST_P(TcpProxyIntegrationTest, AccessLog) { envoy::config::filter::network::tcp_proxy::v2::TcpProxy)>(*config_blob); auto* access_log = tcp_proxy_config.add_access_log(); - access_log->set_name("envoy.access_loggers.file"); + access_log->set_name("accesslog"); envoy::extensions::access_loggers::file::v3::FileAccessLog access_log_config; access_log_config.set_path(access_log_path); access_log_config.set_format( From a0d952048c536c2da29be79df480a046ccf2be89 Mon Sep 17 00:00:00 2001 From: Matt Klein Date: Tue, 18 Feb 2020 16:22:53 -0800 Subject: [PATCH 74/87] http: use typed headers in encoding path (#10081) This is "the big one" in the header map refactor. This commit uses typed headers all the way through the encoding path and thus requires an interface change in HTTP filters. Although the lines of code changed in this PR is huge, the regression risk is low as this change is almost entirely an extremely tedious fixup PR to use the correct types. Quite a few filter tests needed fixing as they were using the wrong header type for trailers, etc. Signed-off-by: Matt Klein --- .gitignore | 4 +- ci/filter_example_setup.sh | 2 +- include/envoy/grpc/async_client.h | 8 +- include/envoy/http/async_client.h | 12 +- include/envoy/http/codec.h | 14 +- include/envoy/http/filter.h | 18 +- include/envoy/http/message.h | 17 +- include/envoy/router/shadow_writer.h | 2 +- source/common/config/grpc_stream.h | 6 +- .../common/config/http_subscription_impl.cc | 4 +- source/common/config/http_subscription_impl.h | 4 +- source/common/config/remote_data_fetcher.cc | 4 +- source/common/config/remote_data_fetcher.h | 2 +- source/common/grpc/async_client_impl.cc | 24 +- source/common/grpc/async_client_impl.h | 12 +- source/common/grpc/common.cc | 14 +- source/common/grpc/common.h | 12 +- .../common/grpc/google_async_client_impl.cc | 20 +- source/common/grpc/google_async_client_impl.h | 10 +- source/common/http/BUILD | 1 - source/common/http/async_client_impl.cc | 17 +- source/common/http/async_client_impl.h | 28 +- source/common/http/codec_wrappers.h | 4 +- source/common/http/conn_manager_impl.cc | 43 +- source/common/http/conn_manager_impl.h | 42 +- source/common/http/header_map_impl.cc | 14 +- source/common/http/header_map_impl.h | 26 +- source/common/http/http1/codec_impl.cc | 10 +- source/common/http/http1/codec_impl.h | 10 +- source/common/http/http2/codec_impl.cc | 6 +- source/common/http/http2/codec_impl.h | 14 +- source/common/http/message_impl.cc | 25 - source/common/http/message_impl.h | 49 +- source/common/http/rest_api_fetcher.cc | 4 +- source/common/http/rest_api_fetcher.h | 6 +- source/common/http/utility.cc | 15 +- source/common/http/utility.h | 14 +- source/common/router/router.cc | 25 +- source/common/router/router.h | 18 +- source/common/router/shadow_writer_impl.cc | 2 +- source/common/router/shadow_writer_impl.h | 4 +- source/common/upstream/health_checker_impl.cc | 2 +- .../upstream/health_discovery_service.cc | 6 +- .../upstream/health_discovery_service.h | 6 +- source/common/upstream/load_stats_reporter.cc | 6 +- source/common/upstream/load_stats_reporter.h | 6 +- .../grpc/grpc_access_log_impl.h | 6 +- source/extensions/common/aws/signer.h | 4 +- source/extensions/common/aws/signer_impl.cc | 8 +- source/extensions/common/aws/signer_impl.h | 8 +- .../common/ext_authz/ext_authz_grpc_impl.h | 2 +- .../common/ext_authz/ext_authz_http_impl.cc | 17 +- .../common/ext_authz/ext_authz_http_impl.h | 4 +- .../filters/common/ratelimit/ratelimit_impl.h | 2 +- .../adaptive_concurrency_filter.cc | 2 +- .../adaptive_concurrency_filter.h | 2 +- .../aws_request_signing_filter.cc | 2 +- .../aws_request_signing_filter.h | 3 +- .../filters/http/buffer/buffer_filter.cc | 5 +- .../filters/http/buffer/buffer_filter.h | 5 +- .../simple_http_cache/simple_http_cache.cc | 9 +- .../filters/http/common/jwks_fetcher.cc | 4 +- .../filters/http/common/pass_through_filter.h | 10 +- .../filters/http/cors/cors_filter.cc | 6 +- .../filters/http/cors/cors_filter.h | 12 +- .../filters/http/csrf/csrf_filter.cc | 2 +- .../filters/http/csrf/csrf_filter.h | 5 +- .../dynamic_forward_proxy/proxy_filter.cc | 2 +- .../http/dynamic_forward_proxy/proxy_filter.h | 3 +- .../filters/http/dynamo/dynamo_filter.cc | 9 +- .../filters/http/dynamo/dynamo_filter.h | 11 +- .../filters/http/ext_authz/ext_authz.cc | 4 +- .../filters/http/ext_authz/ext_authz.h | 5 +- .../filters/http/fault/fault_filter.cc | 6 +- .../filters/http/fault/fault_filter.h | 11 +- .../grpc_http1_bridge/http1_bridge_filter.cc | 6 +- .../grpc_http1_bridge/http1_bridge_filter.h | 12 +- .../http/grpc_http1_reverse_bridge/filter.cc | 6 +- .../http/grpc_http1_reverse_bridge/filter.h | 8 +- .../json_transcoder_filter.cc | 28 +- .../json_transcoder_filter.h | 16 +- .../http/grpc_stats/grpc_stats_filter.cc | 7 +- .../filters/http/grpc_web/grpc_web_filter.cc | 6 +- .../filters/http/grpc_web/grpc_web_filter.h | 10 +- .../filters/http/gzip/gzip_filter.cc | 7 +- .../filters/http/gzip/gzip_filter.h | 12 +- .../header_to_metadata_filter.cc | 6 +- .../header_to_metadata_filter.h | 10 +- .../filters/http/health_check/health_check.cc | 6 +- .../filters/http/health_check/health_check.h | 12 +- .../http/ip_tagging/ip_tagging_filter.cc | 4 +- .../http/ip_tagging/ip_tagging_filter.h | 5 +- .../filters/http/jwt_authn/filter.cc | 4 +- .../filters/http/jwt_authn/filter.h | 4 +- .../extensions/filters/http/lua/lua_filter.cc | 32 +- .../extensions/filters/http/lua/lua_filter.h | 25 +- .../http/on_demand/on_demand_update.cc | 4 +- .../filters/http/on_demand/on_demand_update.h | 5 +- .../filters/http/original_src/original_src.cc | 4 +- .../filters/http/original_src/original_src.h | 5 +- .../filters/http/ratelimit/ratelimit.cc | 10 +- .../filters/http/ratelimit/ratelimit.h | 12 +- .../filters/http/rbac/rbac_filter.cc | 4 +- .../filters/http/rbac/rbac_filter.h | 5 +- .../filters/http/squash/squash_filter.cc | 14 +- .../filters/http/squash/squash_filter.h | 18 +- .../extensions/filters/http/tap/tap_filter.cc | 8 +- .../extensions/filters/http/tap/tap_filter.h | 12 +- .../client_ssl_auth/client_ssl_auth.cc | 4 +- .../network/client_ssl_auth/client_ssl_auth.h | 4 +- .../quiche/envoy_quic_client_stream.cc | 4 +- .../quiche/envoy_quic_client_stream.h | 4 +- .../quiche/envoy_quic_server_stream.cc | 6 +- .../quiche/envoy_quic_server_stream.h | 6 +- .../grpc_metrics_service_impl.h | 6 +- .../tracers/datadog/datadog_tracer_impl.cc | 4 +- .../tracers/datadog/datadog_tracer_impl.h | 2 +- .../lightstep/lightstep_tracer_impl.cc | 4 +- .../tracers/lightstep/lightstep_tracer_impl.h | 2 +- .../tracers/zipkin/zipkin_tracer_impl.cc | 4 +- .../tracers/zipkin/zipkin_tracer_impl.h | 2 +- .../server/config_validation/async_client.cc | 3 +- .../server/config_validation/async_client.h | 2 +- source/server/http/admin.cc | 9 +- source/server/http/admin.h | 5 +- .../access_log_formatter_fuzz_test.cc | 9 +- .../access_log_formatter_speed_test.cc | 18 +- .../common/access_log/access_log_impl_test.cc | 18 +- test/common/config/datasource_test.cc | 58 ++- test/common/config/grpc_stream_test.cc | 6 +- .../config/http_subscription_impl_test.cc | 5 +- .../config/http_subscription_test_harness.h | 7 +- .../config/subscription_factory_impl_test.cc | 2 +- test/common/grpc/common_test.cc | 58 ++- .../grpc_client_integration_test_harness.h | 2 +- test/common/http/async_client_impl_test.cc | 63 +-- test/common/http/codec_impl_fuzz_test.cc | 31 +- test/common/http/codec_wrappers_test.cc | 8 +- .../http/conn_manager_impl_fuzz_test.cc | 21 +- test/common/http/conn_manager_impl_test.cc | 149 +++--- test/common/http/conn_manager_utility_test.cc | 46 +- test/common/http/header_map_impl_fuzz_test.cc | 4 +- test/common/http/header_map_impl_test.cc | 33 +- test/common/http/http1/codec_impl_test.cc | 85 ++-- .../http/http1/conn_pool_legacy_test.cc | 40 +- test/common/http/http1/conn_pool_test.cc | 40 +- test/common/http/http2/codec_impl_test.cc | 151 +++--- .../http/http2/conn_pool_legacy_test.cc | 92 ++-- test/common/http/http2/conn_pool_test.cc | 124 ++--- test/common/http/http2/frame_replay_test.cc | 2 +- .../http/http2/response_header_fuzz_test.cc | 2 +- test/common/http/utility_test.cc | 45 +- test/common/router/config_impl_test.cc | 4 +- test/common/router/retry_state_impl_test.cc | 243 ++++----- test/common/router/route_fuzz_test.cc | 2 +- test/common/router/router_test.cc | 463 +++++++++--------- .../common/router/router_upstream_log_test.cc | 8 +- test/common/router/shadow_writer_impl_test.cc | 12 +- test/common/tracing/http_tracer_impl_test.cc | 134 ++--- .../grpc/http_grpc_access_log_impl_test.cc | 24 +- test/extensions/common/aws/mocks.h | 4 +- .../extensions/common/aws/signer_impl_test.cc | 2 +- test/extensions/common/tap/admin_test.cc | 2 +- .../common/expr/evaluator_fuzz_test.cc | 7 +- .../ext_authz/check_request_utils_test.cc | 11 +- .../ext_authz/ext_authz_grpc_impl_test.cc | 10 +- .../ext_authz/ext_authz_http_impl_test.cc | 22 +- .../filters/common/ext_authz/test_common.cc | 8 +- .../filters/common/ext_authz/test_common.h | 4 +- .../common/ratelimit/ratelimit_impl_test.cc | 4 +- .../adaptive_concurrency_filter_test.cc | 46 +- .../filters/http/aws_request_signing/BUILD | 1 + .../aws_request_signing_filter_test.cc | 15 +- .../buffer/buffer_filter_integration_test.cc | 54 +- .../filters/http/buffer/buffer_filter_test.cc | 20 +- .../filters/http/cache/http_cache_test.cc | 29 +- .../http/cache/http_cache_utils_test.cc | 2 +- .../simple_http_cache_test.cc | 38 +- .../filters/http/common/jwks_fetcher_test.cc | 2 +- test/extensions/filters/http/common/mock.cc | 9 +- .../http/cors/cors_filter_integration_test.cc | 12 +- .../filters/http/cors/cors_filter_test.cc | 263 +++++----- .../http/csrf/csrf_filter_integration_test.cc | 37 +- .../filters/http/csrf/csrf_filter_test.cc | 43 +- .../proxy_filter_integration_test.cc | 16 +- .../proxy_filter_test.cc | 4 +- .../filters/http/dynamo/dynamo_filter_test.cc | 90 ++-- .../ext_authz/ext_authz_integration_test.cc | 4 +- .../filters/http/ext_authz/ext_authz_test.cc | 67 +-- .../fault/fault_filter_integration_test.cc | 12 +- .../filters/http/fault/fault_filter_test.cc | 46 +- .../http1_bridge_filter_test.cc | 79 +-- .../reverse_bridge_integration_test.cc | 14 +- .../reverse_bridge_test.cc | 109 +++-- .../grpc_json_transcoder_integration_test.cc | 268 +++++----- .../json_transcoder_filter_test.cc | 135 ++--- .../filters/http/grpc_stats/config_test.cc | 36 +- .../grpc_web_filter_integration_test.cc | 18 +- .../http/grpc_web/grpc_web_filter_test.cc | 60 ++- .../http/gzip/gzip_filter_integration_test.cc | 166 +++---- .../filters/http/gzip/gzip_filter_test.cc | 179 +++---- .../header_to_metadata_filter_test.cc | 36 +- .../filters/http/health_check/config_test.cc | 16 +- .../http/health_check/health_check_test.cc | 60 +-- .../http/ip_tagging/ip_tagging_filter_test.cc | 43 +- .../http/jwt_authn/authenticator_test.cc | 4 +- .../http/jwt_authn/filter_integration_test.cc | 34 +- .../filters/http/jwt_authn/filter_test.cc | 41 +- test/extensions/filters/http/jwt_authn/mock.h | 7 +- .../filters/http/lua/lua_filter_test.cc | 188 +++---- .../filters/http/lua/lua_integration_test.cc | 58 +-- .../http/on_demand/on_demand_filter_test.cc | 8 +- .../http/original_src/original_src_test.cc | 7 +- .../filters/http/ratelimit/ratelimit_test.cc | 88 ++-- .../http/rbac/rbac_filter_integration_test.cc | 26 +- .../filters/http/rbac/rbac_filter_test.cc | 11 +- .../http/router/auto_sni_integration_test.cc | 12 +- .../squash/squash_filter_integration_test.cc | 12 +- .../filters/http/squash/squash_filter_test.cc | 34 +- .../filters/http/tap/tap_config_impl_test.cc | 8 +- .../http/tap/tap_filter_integration_test.cc | 30 +- .../filters/http/tap/tap_filter_test.cc | 16 +- .../client_ssl_auth/client_ssl_auth_test.cc | 17 +- .../filters/ratelimit/ratelimit_test.cc | 2 +- .../quiche/envoy_quic_client_session_test.cc | 2 +- .../quiche/envoy_quic_client_stream_test.cc | 2 +- .../quiche/envoy_quic_server_session_test.cc | 12 +- .../quiche/envoy_quic_server_stream_test.cc | 2 +- .../integration/quic_http_integration_test.cc | 18 +- .../metrics_service_integration_test.cc | 10 +- .../common/ot/opentracing_driver_impl_test.cc | 4 +- .../datadog/datadog_tracer_impl_test.cc | 10 +- .../dynamic_opentracing_driver_impl_test.cc | 2 +- .../lightstep/lightstep_tracer_impl_test.cc | 32 +- .../tracers/opencensus/tracer_test.cc | 4 +- .../tracers/xray/xray_tracer_impl_test.cc | 2 +- .../zipkin/span_context_extractor_test.cc | 82 ++-- .../tracers/zipkin/zipkin_tracer_impl_test.cc | 14 +- .../tls/integration/ssl_integration_test.cc | 4 +- test/fuzz/utility.h | 7 +- test/integration/eds_integration_test.cc | 12 +- test/integration/fake_upstream.cc | 13 +- test/integration/fake_upstream.h | 2 +- .../filter_manager_integration_test.cc | 4 +- .../filters/call_decodedata_once_filter.cc | 4 +- .../decode_headers_return_stop_all_filter.cc | 4 +- test/integration/filters/eds_ready_filter.cc | 2 +- .../encode_headers_return_stop_all_filter.cc | 4 +- .../filters/headers_only_filter.cc | 4 +- .../filters/metadata_stop_all_filter.cc | 4 +- .../filters/process_context_filter.cc | 2 +- .../filters/request_metadata_filter.cc | 4 +- .../filters/response_metadata_filter.cc | 6 +- .../stop_iteration_and_continue_filter.cc | 4 +- test/integration/hds_integration_test.cc | 20 +- test/integration/http2_integration_test.cc | 157 +++--- test/integration/http2_integration_test.h | 2 +- .../http2_upstream_integration_test.cc | 70 +-- test/integration/http_integration.cc | 145 +++--- test/integration/http_integration.h | 23 +- .../http_subset_lb_integration_test.cc | 18 +- .../http_timeout_integration_test.cc | 122 ++--- .../idle_timeout_integration_test.cc | 21 +- test/integration/integration_test.cc | 112 ++--- .../load_stats_integration_test.cc | 8 +- test/integration/overload_integration_test.cc | 6 +- test/integration/protocol_integration_test.cc | 304 ++++++------ .../integration/ratelimit_integration_test.cc | 14 +- .../scoped_rds_integration_test.cc | 103 ++-- .../sds_generic_secret_integration_test.cc | 6 +- ...transport_socket_match_integration_test.cc | 20 +- test/integration/uds_integration_test.cc | 4 +- test/integration/utility.cc | 2 +- test/integration/vhds_integration_test.cc | 50 +- .../integration/websocket_integration_test.cc | 28 +- test/integration/websocket_integration_test.h | 4 +- test/integration/xfcc_integration_test.cc | 22 +- test/mocks/grpc/mocks.h | 12 +- test/mocks/http/mocks.cc | 7 +- test/mocks/http/mocks.h | 55 ++- test/mocks/http/stream_decoder.cc | 4 - test/mocks/http/stream_encoder.h | 10 +- test/mocks/router/mocks.h | 4 +- .../config_validation/async_client_test.cc | 2 +- test/server/http/admin_test.cc | 7 +- test/server/server_test.cc | 2 +- 286 files changed, 3858 insertions(+), 3656 deletions(-) delete mode 100644 source/common/http/message_impl.cc diff --git a/.gitignore b/.gitignore index d8d75f8b9a..bace7094e1 100644 --- a/.gitignore +++ b/.gitignore @@ -24,11 +24,11 @@ SOURCE_VERSION tags TAGS /test/coverage/BUILD -/tools/.aspell.en.pws +/tools/spelling/.aspell.en.pws .vimrc .vs .vscode clang.bazelrc user.bazelrc CMakeLists.txt -cmake-build-debug \ No newline at end of file +cmake-build-debug diff --git a/ci/filter_example_setup.sh b/ci/filter_example_setup.sh index f718f85fa8..df1ec08366 100644 --- a/ci/filter_example_setup.sh +++ b/ci/filter_example_setup.sh @@ -5,7 +5,7 @@ set -e # This is the hash on https://github.com/envoyproxy/envoy-filter-example.git we pin to. -ENVOY_FILTER_EXAMPLE_GITSHA="25e1ad74e3efd18c794a022038a5077725df2f6b" +ENVOY_FILTER_EXAMPLE_GITSHA="c6c986cca7ad676cc1c33f2df7515cbbd2e02502" ENVOY_FILTER_EXAMPLE_SRCDIR="${BUILD_DIR}/envoy-filter-example" export ENVOY_FILTER_EXAMPLE_TESTS="//:echo2_integration_test //http-filter-example:http_filter_integration_test //:envoy_binary_test" diff --git a/include/envoy/grpc/async_client.h b/include/envoy/grpc/async_client.h index b27831b18f..c7ab0d219b 100644 --- a/include/envoy/grpc/async_client.h +++ b/include/envoy/grpc/async_client.h @@ -68,7 +68,7 @@ class RawAsyncRequestCallbacks { * Called when populating the headers to send with initial metadata. * @param metadata initial metadata reference. */ - virtual void onCreateInitialMetadata(Http::HeaderMap& metadata) PURE; + virtual void onCreateInitialMetadata(Http::RequestHeaderMap& metadata) PURE; /** * Called when the async gRPC request succeeds. No further callbacks will be invoked. @@ -102,14 +102,14 @@ class RawAsyncStreamCallbacks { * Called when populating the headers to send with initial metadata. * @param metadata initial metadata reference. */ - virtual void onCreateInitialMetadata(Http::HeaderMap& metadata) PURE; + virtual void onCreateInitialMetadata(Http::RequestHeaderMap& metadata) PURE; /** * Called when initial metadata is received. This will be called with empty metadata on a * trailers-only response, followed by onReceiveTrailingMetadata() with the trailing metadata. * @param metadata initial metadata reference. */ - virtual void onReceiveInitialMetadata(Http::HeaderMapPtr&& metadata) PURE; + virtual void onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&& metadata) PURE; /** * Called when an async gRPC message is received. @@ -124,7 +124,7 @@ class RawAsyncStreamCallbacks { * stream termination. * @param metadata trailing metadata reference. */ - virtual void onReceiveTrailingMetadata(Http::HeaderMapPtr&& metadata) PURE; + virtual void onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&& metadata) PURE; /** * Called when the remote closes or an error occurs on the gRPC stream. The stream is diff --git a/include/envoy/http/async_client.h b/include/envoy/http/async_client.h index 47a8fff72e..693f81a40e 100644 --- a/include/envoy/http/async_client.h +++ b/include/envoy/http/async_client.h @@ -39,7 +39,7 @@ class AsyncClient { * Called when the async HTTP request succeeds. * @param response the HTTP response */ - virtual void onSuccess(MessagePtr&& response) PURE; + virtual void onSuccess(ResponseMessagePtr&& response) PURE; /** * Called when the async HTTP request fails. @@ -63,7 +63,7 @@ class AsyncClient { * @param headers the headers received * @param end_stream whether the response is header only */ - virtual void onHeaders(HeaderMapPtr&& headers, bool end_stream) PURE; + virtual void onHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) PURE; /** * Called when a data frame get received on the async HTTP stream. @@ -77,7 +77,7 @@ class AsyncClient { * Called when all trailers get received on the async HTTP stream. * @param trailers the trailers received. */ - virtual void onTrailers(HeaderMapPtr&& trailers) PURE; + virtual void onTrailers(ResponseTrailerMapPtr&& trailers) PURE; /** * Called when both the local and remote have gracefully closed the stream. @@ -118,7 +118,7 @@ class AsyncClient { * @param headers supplies the headers to send. * @param end_stream supplies whether this is a header only request. */ - virtual void sendHeaders(HeaderMap& headers, bool end_stream) PURE; + virtual void sendHeaders(RequestHeaderMap& headers, bool end_stream) PURE; /*** * Send data to the stream. This method can be invoked multiple times if it get streamed. @@ -132,7 +132,7 @@ class AsyncClient { * Send trailers. This method cannot be invoked more than once, and implicitly ends the stream. * @param trailers supplies the trailers to send. */ - virtual void sendTrailers(HeaderMap& trailers) PURE; + virtual void sendTrailers(RequestTrailerMap& trailers) PURE; /*** * Reset the stream. @@ -250,7 +250,7 @@ class AsyncClient { * handle should just be used to cancel. */ - virtual Request* send(MessagePtr&& request, Callbacks& callbacks, + virtual Request* send(RequestMessagePtr&& request, Callbacks& callbacks, const RequestOptions& options) PURE; /** diff --git a/include/envoy/http/codec.h b/include/envoy/http/codec.h index 17b861cab2..9efa84abdb 100644 --- a/include/envoy/http/codec.h +++ b/include/envoy/http/codec.h @@ -58,8 +58,6 @@ class StreamEncoder { /** * Stream encoder used for sending a request (client to server). Virtual inheritance is required * due to a parallel implementation split between the shared base class and the derived class. - * TODO(mattklein123): In a future change the header types will be changed to differentiate from - * the response path. */ class RequestEncoder : public virtual StreamEncoder { public: @@ -69,20 +67,18 @@ class RequestEncoder : public virtual StreamEncoder { * @param headers supplies the header map to encode. * @param end_stream supplies whether this is a header only request. */ - virtual void encodeHeaders(const HeaderMap& headers, bool end_stream) PURE; + virtual void encodeHeaders(const RequestHeaderMap& headers, bool end_stream) PURE; /** * Encode trailers. This implicitly ends the stream. * @param trailers supplies the trailers to encode. */ - virtual void encodeTrailers(const HeaderMap& trailers) PURE; + virtual void encodeTrailers(const RequestTrailerMap& trailers) PURE; }; /** * Stream encoder used for sending a response (server to client). Virtual inheritance is required * due to a parallel implementation split between the shared base class and the derived class. - * TODO(mattklein123): In a future change the header types will be changed to differentiate from - * the request path. */ class ResponseEncoder : public virtual StreamEncoder { public: @@ -90,7 +86,7 @@ class ResponseEncoder : public virtual StreamEncoder { * Encode 100-Continue headers. * @param headers supplies the 100-Continue header map to encode. */ - virtual void encode100ContinueHeaders(const HeaderMap& headers) PURE; + virtual void encode100ContinueHeaders(const ResponseHeaderMap& headers) PURE; /** * Encode headers, optionally indicating end of stream. Response headers must @@ -98,13 +94,13 @@ class ResponseEncoder : public virtual StreamEncoder { * @param headers supplies the header map to encode. * @param end_stream supplies whether this is a header only response. */ - virtual void encodeHeaders(const HeaderMap& headers, bool end_stream) PURE; + virtual void encodeHeaders(const ResponseHeaderMap& headers, bool end_stream) PURE; /** * Encode trailers. This implicitly ends the stream. * @param trailers supplies the trailers to encode. */ - virtual void encodeTrailers(const HeaderMap& trailers) PURE; + virtual void encodeTrailers(const ResponseTrailerMap& trailers) PURE; }; /** diff --git a/include/envoy/http/filter.h b/include/envoy/http/filter.h index f2b5fb72c6..72d13f02b5 100644 --- a/include/envoy/http/filter.h +++ b/include/envoy/http/filter.h @@ -321,7 +321,7 @@ class StreamDecoderFilterCallbacks : public virtual StreamFilterCallbacks { * @param details a string detailing why this local reply was sent. */ virtual void sendLocalReply(Code response_code, absl::string_view body_text, - std::function modify_headers, + std::function modify_headers, const absl::optional grpc_status, absl::string_view details) PURE; @@ -343,7 +343,7 @@ class StreamDecoderFilterCallbacks : public virtual StreamFilterCallbacks { * * @param headers supplies the headers to be encoded. */ - virtual void encode100ContinueHeaders(HeaderMapPtr&& headers) PURE; + virtual void encode100ContinueHeaders(ResponseHeaderMapPtr&& headers) PURE; /** * Called with headers to be encoded, optionally indicating end of stream. @@ -354,7 +354,7 @@ class StreamDecoderFilterCallbacks : public virtual StreamFilterCallbacks { * @param headers supplies the headers to be encoded. * @param end_stream supplies whether this is a header only request/response. */ - virtual void encodeHeaders(HeaderMapPtr&& headers, bool end_stream) PURE; + virtual void encodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) PURE; /** * Called with data to be encoded, optionally indicating end of stream. @@ -367,7 +367,7 @@ class StreamDecoderFilterCallbacks : public virtual StreamFilterCallbacks { * Called with trailers to be encoded. This implicitly ends the stream. * @param trailers supplies the trailers to encode. */ - virtual void encodeTrailers(HeaderMapPtr&& trailers) PURE; + virtual void encodeTrailers(ResponseTrailerMapPtr&& trailers) PURE; /** * Called with metadata to be encoded. @@ -501,7 +501,7 @@ class StreamDecoderFilter : public StreamFilterBase { * @param end_stream supplies whether this is a header only request/response. * @return FilterHeadersStatus determines how filter chain iteration proceeds. */ - virtual FilterHeadersStatus decodeHeaders(HeaderMap& headers, bool end_stream) PURE; + virtual FilterHeadersStatus decodeHeaders(RequestHeaderMap& headers, bool end_stream) PURE; /** * Called with a decoded data frame. @@ -515,7 +515,7 @@ class StreamDecoderFilter : public StreamFilterBase { * Called with decoded trailers, implicitly ending the stream. * @param trailers supplies the decoded trailers. */ - virtual FilterTrailersStatus decodeTrailers(HeaderMap& trailers) PURE; + virtual FilterTrailersStatus decodeTrailers(RequestTrailerMap& trailers) PURE; /** * Called with decoded metadata. Add new metadata to metadata_map directly. Do not call @@ -694,7 +694,7 @@ class StreamEncoderFilter : public StreamFilterBase { * @return FilterHeadersStatus determines how filter chain iteration proceeds. * */ - virtual FilterHeadersStatus encode100ContinueHeaders(HeaderMap& headers) PURE; + virtual FilterHeadersStatus encode100ContinueHeaders(ResponseHeaderMap& headers) PURE; /** * Called with headers to be encoded, optionally indicating end of stream. @@ -702,7 +702,7 @@ class StreamEncoderFilter : public StreamFilterBase { * @param end_stream supplies whether this is a header only request/response. * @return FilterHeadersStatus determines how filter chain iteration proceeds. */ - virtual FilterHeadersStatus encodeHeaders(HeaderMap& headers, bool end_stream) PURE; + virtual FilterHeadersStatus encodeHeaders(ResponseHeaderMap& headers, bool end_stream) PURE; /** * Called with data to be encoded, optionally indicating end of stream. @@ -716,7 +716,7 @@ class StreamEncoderFilter : public StreamFilterBase { * Called with trailers to be encoded, implicitly ending the stream. * @param trailers supplies the trailers to be encoded. */ - virtual FilterTrailersStatus encodeTrailers(HeaderMap& trailers) PURE; + virtual FilterTrailersStatus encodeTrailers(ResponseTrailerMap& trailers) PURE; /** * Called with metadata to be encoded. New metadata should be added directly to metadata_map. DO diff --git a/include/envoy/http/message.h b/include/envoy/http/message.h index 3d36842e72..7fa0c8c910 100644 --- a/include/envoy/http/message.h +++ b/include/envoy/http/message.h @@ -12,14 +12,14 @@ namespace Http { /** * Wraps an HTTP message including its headers, body, and any trailers. */ -class Message { +template class Message { public: virtual ~Message() = default; /** - * @return HeaderMap& the message headers. + * @return HeaderType& the message headers. */ - virtual HeaderMap& headers() PURE; + virtual HeaderType& headers() PURE; /** * @return Buffer::InstancePtr& the message body, if any. Callers are free to reallocate, remove, @@ -28,15 +28,15 @@ class Message { virtual Buffer::InstancePtr& body() PURE; /** - * @return HeaderMap* the message trailers, if any. + * @return TrailerType* the message trailers, if any. */ - virtual HeaderMap* trailers() PURE; + virtual TrailerType* trailers() PURE; /** * Set the trailers. * @param trailers supplies the new trailers. */ - virtual void trailers(HeaderMapPtr&& trailers) PURE; + virtual void trailers(std::unique_ptr&& trailers) PURE; /** * @return std::string the message body as a std::string. @@ -44,7 +44,10 @@ class Message { virtual std::string bodyAsString() const PURE; }; -using MessagePtr = std::unique_ptr; +using RequestMessage = Message; +using RequestMessagePtr = std::unique_ptr; +using ResponseMessage = Message; +using ResponseMessagePtr = std::unique_ptr; } // namespace Http } // namespace Envoy diff --git a/include/envoy/router/shadow_writer.h b/include/envoy/router/shadow_writer.h index 3631ff5ec7..e4e60fc0cb 100644 --- a/include/envoy/router/shadow_writer.h +++ b/include/envoy/router/shadow_writer.h @@ -24,7 +24,7 @@ class ShadowWriter { * @param message supplies the complete request to shadow. * @param timeout supplies the shadowed request timeout. */ - virtual void shadow(const std::string& cluster, Http::MessagePtr&& request, + virtual void shadow(const std::string& cluster, Http::RequestMessagePtr&& request, std::chrono::milliseconds timeout) PURE; }; diff --git a/source/common/config/grpc_stream.h b/source/common/config/grpc_stream.h index b80457fa8b..d1b80ad6a3 100644 --- a/source/common/config/grpc_stream.h +++ b/source/common/config/grpc_stream.h @@ -65,11 +65,11 @@ class GrpcStream : public Grpc::AsyncStreamCallbacks, void sendMessage(const RequestProto& request) { stream_->sendMessage(request, false); } // Grpc::AsyncStreamCallbacks - void onCreateInitialMetadata(Http::HeaderMap& metadata) override { + void onCreateInitialMetadata(Http::RequestHeaderMap& metadata) override { UNREFERENCED_PARAMETER(metadata); } - void onReceiveInitialMetadata(Http::HeaderMapPtr&& metadata) override { + void onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&& metadata) override { UNREFERENCED_PARAMETER(metadata); } @@ -83,7 +83,7 @@ class GrpcStream : public Grpc::AsyncStreamCallbacks, callbacks_->onDiscoveryResponse(std::move(message)); } - void onReceiveTrailingMetadata(Http::HeaderMapPtr&& metadata) override { + void onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&& metadata) override { UNREFERENCED_PARAMETER(metadata); } diff --git a/source/common/config/http_subscription_impl.cc b/source/common/config/http_subscription_impl.cc index 9e87473834..5662d92bf2 100644 --- a/source/common/config/http_subscription_impl.cc +++ b/source/common/config/http_subscription_impl.cc @@ -63,7 +63,7 @@ void HttpSubscriptionImpl::updateResourceInterest( } // Http::RestApiFetcher -void HttpSubscriptionImpl::createRequest(Http::Message& request) { +void HttpSubscriptionImpl::createRequest(Http::RequestMessage& request) { ENVOY_LOG(debug, "Sending REST request for {}", path_); stats_.update_attempt_.inc(); request.headers().setReferenceMethod(Http::Headers::get().MethodValues.Post); @@ -74,7 +74,7 @@ void HttpSubscriptionImpl::createRequest(Http::Message& request) { request.headers().setContentLength(request.body()->length()); } -void HttpSubscriptionImpl::parseResponse(const Http::Message& response) { +void HttpSubscriptionImpl::parseResponse(const Http::ResponseMessage& response) { disableInitFetchTimeoutTimer(); envoy::service::discovery::v3::DiscoveryResponse message; try { diff --git a/source/common/config/http_subscription_impl.h b/source/common/config/http_subscription_impl.h index dae9915f78..b5e8b33e94 100644 --- a/source/common/config/http_subscription_impl.h +++ b/source/common/config/http_subscription_impl.h @@ -37,8 +37,8 @@ class HttpSubscriptionImpl : public Http::RestApiFetcher, void updateResourceInterest(const std::set& update_to_these_names) override; // Http::RestApiFetcher - void createRequest(Http::Message& request) override; - void parseResponse(const Http::Message& response) override; + void createRequest(Http::RequestMessage& request) override; + void parseResponse(const Http::ResponseMessage& response) override; void onFetchComplete() override; void onFetchFailure(Config::ConfigUpdateFailureReason reason, const EnvoyException* e) override; diff --git a/source/common/config/remote_data_fetcher.cc b/source/common/config/remote_data_fetcher.cc index 252f72cab5..1123581a53 100644 --- a/source/common/config/remote_data_fetcher.cc +++ b/source/common/config/remote_data_fetcher.cc @@ -30,7 +30,7 @@ void RemoteDataFetcher::cancel() { } void RemoteDataFetcher::fetch() { - Http::MessagePtr message = Http::Utility::prepareHeaders(uri_); + Http::RequestMessagePtr message = Http::Utility::prepareHeaders(uri_); message->headers().setReferenceMethod(Http::Headers::get().MethodValues.Get); ENVOY_LOG(debug, "fetch remote data from [uri = {}]: start", uri_.uri()); request_ = cm_.httpAsyncClientForCluster(uri_.cluster()) @@ -39,7 +39,7 @@ void RemoteDataFetcher::fetch() { DurationUtil::durationToMilliseconds(uri_.timeout())))); } -void RemoteDataFetcher::onSuccess(Http::MessagePtr&& response) { +void RemoteDataFetcher::onSuccess(Http::ResponseMessagePtr&& response) { const uint64_t status_code = Http::Utility::getResponseStatus(response->headers()); if (status_code == enumToInt(Http::Code::OK)) { ENVOY_LOG(debug, "fetch remote data [uri = {}]: success", uri_.uri()); diff --git a/source/common/config/remote_data_fetcher.h b/source/common/config/remote_data_fetcher.h index 5b7ecf5795..ced327a9fa 100644 --- a/source/common/config/remote_data_fetcher.h +++ b/source/common/config/remote_data_fetcher.h @@ -50,7 +50,7 @@ class RemoteDataFetcher : public Logger::Loggable, ~RemoteDataFetcher() override; // Http::AsyncClient::Callbacks - void onSuccess(Http::MessagePtr&& response) override; + void onSuccess(Http::ResponseMessagePtr&& response) override; void onFailure(Http::AsyncClient::FailureReason reason) override; /** diff --git a/source/common/grpc/async_client_impl.cc b/source/common/grpc/async_client_impl.cc index 192f933cb1..19aa96ed46 100644 --- a/source/common/grpc/async_client_impl.cc +++ b/source/common/grpc/async_client_impl.cc @@ -97,18 +97,18 @@ void AsyncStreamImpl::initialize(bool buffer_body_for_retry) { // TODO(htuch): match Google gRPC base64 encoding behavior for *-bin headers, see // https://github.com/envoyproxy/envoy/pull/2444#discussion_r163914459. -void AsyncStreamImpl::onHeaders(Http::HeaderMapPtr&& headers, bool end_stream) { +void AsyncStreamImpl::onHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) { const auto http_response_status = Http::Utility::getResponseStatus(*headers); const auto grpc_status = Common::getGrpcStatus(*headers); - callbacks_.onReceiveInitialMetadata(end_stream ? std::make_unique() + callbacks_.onReceiveInitialMetadata(end_stream ? std::make_unique() : std::move(headers)); if (http_response_status != enumToInt(Http::Code::OK)) { // https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md requires that // grpc-status be used if available. if (end_stream && grpc_status) { - // There is actually no use-after-move problem here, - // because it will only be executed when end_stream is equal to true. - onTrailers(std::move(headers)); // NOLINT(bugprone-use-after-move) + // Due to headers/trailers type differences we need to copy here. This is an uncommon case but + // we can potentially optimize in the future. + onTrailers(Http::createHeaderMap(*headers)); return; } // Technically this should be @@ -119,7 +119,9 @@ void AsyncStreamImpl::onHeaders(Http::HeaderMapPtr&& headers, bool end_stream) { return; } if (end_stream) { - onTrailers(std::move(headers)); + // Due to headers/trailers type differences we need to copy here. This is an uncommon case but + // we can potentially optimize in the future. + onTrailers(Http::createHeaderMap(*headers)); } } @@ -149,7 +151,7 @@ void AsyncStreamImpl::onData(Buffer::Instance& data, bool end_stream) { // TODO(htuch): match Google gRPC base64 encoding behavior for *-bin headers, see // https://github.com/envoyproxy/envoy/pull/2444#discussion_r163914459. -void AsyncStreamImpl::onTrailers(Http::HeaderMapPtr&& trailers) { +void AsyncStreamImpl::onTrailers(Http::ResponseTrailerMapPtr&& trailers) { auto grpc_status = Common::getGrpcStatus(*trailers); const std::string grpc_message = Common::getGrpcMessage(*trailers); callbacks_.onReceiveTrailingMetadata(std::move(trailers)); @@ -161,7 +163,7 @@ void AsyncStreamImpl::onTrailers(Http::HeaderMapPtr&& trailers) { } void AsyncStreamImpl::streamError(Status::GrpcStatus grpc_status, const std::string& message) { - callbacks_.onReceiveTrailingMetadata(std::make_unique()); + callbacks_.onReceiveTrailingMetadata(std::make_unique()); callbacks_.onRemoteClose(grpc_status, message); resetStream(); } @@ -237,19 +239,19 @@ void AsyncRequestImpl::cancel() { this->resetStream(); } -void AsyncRequestImpl::onCreateInitialMetadata(Http::HeaderMap& metadata) { +void AsyncRequestImpl::onCreateInitialMetadata(Http::RequestHeaderMap& metadata) { current_span_->injectContext(metadata); callbacks_.onCreateInitialMetadata(metadata); } -void AsyncRequestImpl::onReceiveInitialMetadata(Http::HeaderMapPtr&&) {} +void AsyncRequestImpl::onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&&) {} bool AsyncRequestImpl::onReceiveMessageRaw(Buffer::InstancePtr&& response) { response_ = std::move(response); return true; } -void AsyncRequestImpl::onReceiveTrailingMetadata(Http::HeaderMapPtr&&) {} +void AsyncRequestImpl::onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&&) {} void AsyncRequestImpl::onRemoteClose(Grpc::Status::GrpcStatus status, const std::string& message) { current_span_->setTag(Tracing::Tags::get().GrpcStatusCode, std::to_string(status)); diff --git a/source/common/grpc/async_client_impl.h b/source/common/grpc/async_client_impl.h index 889ce16ea3..f27cf84364 100644 --- a/source/common/grpc/async_client_impl.h +++ b/source/common/grpc/async_client_impl.h @@ -55,9 +55,9 @@ class AsyncStreamImpl : public RawAsyncStream, void sendMessage(const Protobuf::Message& request, bool end_stream); // Http::AsyncClient::StreamCallbacks - void onHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override; + void onHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) override; void onData(Buffer::Instance& data, bool end_stream) override; - void onTrailers(Http::HeaderMapPtr&& trailers) override; + void onTrailers(Http::ResponseTrailerMapPtr&& trailers) override; void onComplete() override; void onReset() override; @@ -77,7 +77,7 @@ class AsyncStreamImpl : public RawAsyncStream, const std::string& grpc_message); Event::Dispatcher* dispatcher_{}; - Http::MessagePtr headers_message_; + Http::RequestMessagePtr headers_message_; AsyncClientImpl& parent_; std::string service_full_name_; std::string method_name_; @@ -106,10 +106,10 @@ class AsyncRequestImpl : public AsyncRequest, public AsyncStreamImpl, RawAsyncSt private: // Grpc::AsyncStreamCallbacks - void onCreateInitialMetadata(Http::HeaderMap& metadata) override; - void onReceiveInitialMetadata(Http::HeaderMapPtr&&) override; + void onCreateInitialMetadata(Http::RequestHeaderMap& metadata) override; + void onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&&) override; bool onReceiveMessageRaw(Buffer::InstancePtr&& response) override; - void onReceiveTrailingMetadata(Http::HeaderMapPtr&&) override; + void onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&&) override; void onRemoteClose(Grpc::Status::GrpcStatus status, const std::string& message) override; Buffer::InstancePtr request_; diff --git a/source/common/grpc/common.cc b/source/common/grpc/common.cc index cefab2bf42..abb3406afa 100644 --- a/source/common/grpc/common.cc +++ b/source/common/grpc/common.cc @@ -218,11 +218,11 @@ void Common::toGrpcTimeout(const std::chrono::milliseconds& timeout, Http::Heade headers.setGrpcTimeout(absl::StrCat(time, absl::string_view(unit, 1))); } -Http::MessagePtr Common::prepareHeaders(const std::string& upstream_cluster, - const std::string& service_full_name, - const std::string& method_name, - const absl::optional& timeout) { - Http::MessagePtr message(new Http::RequestMessageImpl()); +Http::RequestMessagePtr +Common::prepareHeaders(const std::string& upstream_cluster, const std::string& service_full_name, + const std::string& method_name, + const absl::optional& timeout) { + Http::RequestMessagePtr message(new Http::RequestMessageImpl()); message->headers().setReferenceMethod(Http::Headers::get().MethodValues.Post); message->headers().setPath(absl::StrCat("/", service_full_name, "/", method_name)); message->headers().setHost(upstream_cluster); @@ -237,7 +237,7 @@ Http::MessagePtr Common::prepareHeaders(const std::string& upstream_cluster, return message; } -void Common::checkForHeaderOnlyError(Http::Message& http_response) { +void Common::checkForHeaderOnlyError(Http::ResponseMessage& http_response) { // First check for grpc-status in headers. If it is here, we have an error. absl::optional grpc_status_code = Common::getGrpcStatus(http_response.headers()); @@ -252,7 +252,7 @@ void Common::checkForHeaderOnlyError(Http::Message& http_response) { throw Exception(grpc_status_code.value(), Common::getGrpcMessage(http_response.headers())); } -void Common::validateResponse(Http::Message& http_response) { +void Common::validateResponse(Http::ResponseMessage& http_response) { if (Http::Utility::getResponseStatus(http_response.headers()) != enumToInt(Http::Code::OK)) { throw Exception(absl::optional(), "non-200 response code"); } diff --git a/source/common/grpc/common.h b/source/common/grpc/common.h index caa0bd1799..1c74235318 100644 --- a/source/common/grpc/common.h +++ b/source/common/grpc/common.h @@ -116,15 +116,15 @@ class Common { /** * Prepare headers for protobuf service. */ - static Http::MessagePtr prepareHeaders(const std::string& upstream_cluster, - const std::string& service_full_name, - const std::string& method_name, - const absl::optional& timeout); + static Http::RequestMessagePtr + prepareHeaders(const std::string& upstream_cluster, const std::string& service_full_name, + const std::string& method_name, + const absl::optional& timeout); /** * Basic validation of gRPC response, @throws Grpc::Exception in case of non successful response. */ - static void validateResponse(Http::Message& http_response); + static void validateResponse(Http::ResponseMessage& http_response); /** * @return const std::string& type URL prefix. @@ -153,7 +153,7 @@ class Common { static bool parseBufferInstance(Buffer::InstancePtr&& buffer, Protobuf::Message& proto); private: - static void checkForHeaderOnlyError(Http::Message& http_response); + static void checkForHeaderOnlyError(Http::ResponseMessage& http_response); }; } // namespace Grpc diff --git a/source/common/grpc/google_async_client_impl.cc b/source/common/grpc/google_async_client_impl.cc index cd212c0f1d..f459b935a3 100644 --- a/source/common/grpc/google_async_client_impl.cc +++ b/source/common/grpc/google_async_client_impl.cc @@ -163,7 +163,7 @@ void GoogleAsyncStreamImpl::initialize(bool /*buffer_body_for_retry*/) { } // Due to the different HTTP header implementations, we effectively double // copy headers here. - Http::HeaderMapImpl initial_metadata; + Http::RequestHeaderMapImpl initial_metadata; callbacks_.onCreateInitialMetadata(initial_metadata); initial_metadata.iterate( [](const Http::HeaderEntry& header, void* ctxt) { @@ -187,7 +187,7 @@ void GoogleAsyncStreamImpl::initialize(bool /*buffer_body_for_retry*/) { } void GoogleAsyncStreamImpl::notifyRemoteClose(Status::GrpcStatus grpc_status, - Http::HeaderMapPtr trailing_metadata, + Http::ResponseTrailerMapPtr trailing_metadata, const std::string& message) { if (grpc_status > Status::WellKnownGrpcStatus::MaximumKnown || grpc_status < 0) { ENVOY_LOG(error, "notifyRemoteClose invalid gRPC status code {}", grpc_status); @@ -199,8 +199,9 @@ void GoogleAsyncStreamImpl::notifyRemoteClose(Status::GrpcStatus grpc_status, parent_.stats_.streams_closed_[grpc_status]->inc(); } ENVOY_LOG(debug, "notifyRemoteClose {} {}", grpc_status, message); - callbacks_.onReceiveTrailingMetadata(trailing_metadata ? std::move(trailing_metadata) - : std::make_unique()); + callbacks_.onReceiveTrailingMetadata(trailing_metadata + ? std::move(trailing_metadata) + : std::make_unique()); callbacks_.onRemoteClose(grpc_status, message); } @@ -302,7 +303,7 @@ void GoogleAsyncStreamImpl::handleOpCompletion(GoogleAsyncTag::Operation op, boo ASSERT(call_initialized_); rw_->Read(&read_buf_, &read_tag_); ++inflight_tags_; - Http::HeaderMapPtr initial_metadata = std::make_unique(); + Http::ResponseHeaderMapPtr initial_metadata = std::make_unique(); metadataTranslate(ctxt_.GetServerInitialMetadata(), *initial_metadata); callbacks_.onReceiveInitialMetadata(std::move(initial_metadata)); break; @@ -335,7 +336,8 @@ void GoogleAsyncStreamImpl::handleOpCompletion(GoogleAsyncTag::Operation op, boo case GoogleAsyncTag::Operation::Finish: { ASSERT(finish_pending_); ENVOY_LOG(debug, "Finish with grpc-status code {}", status_.error_code()); - Http::HeaderMapPtr trailing_metadata = std::make_unique(); + Http::ResponseTrailerMapPtr trailing_metadata = + std::make_unique(); metadataTranslate(ctxt_.GetServerTrailingMetadata(), *trailing_metadata); notifyRemoteClose(static_cast(status_.error_code()), std::move(trailing_metadata), status_.error_message()); @@ -420,19 +422,19 @@ void GoogleAsyncRequestImpl::cancel() { this->resetStream(); } -void GoogleAsyncRequestImpl::onCreateInitialMetadata(Http::HeaderMap& metadata) { +void GoogleAsyncRequestImpl::onCreateInitialMetadata(Http::RequestHeaderMap& metadata) { current_span_->injectContext(metadata); callbacks_.onCreateInitialMetadata(metadata); } -void GoogleAsyncRequestImpl::onReceiveInitialMetadata(Http::HeaderMapPtr&&) {} +void GoogleAsyncRequestImpl::onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&&) {} bool GoogleAsyncRequestImpl::onReceiveMessageRaw(Buffer::InstancePtr&& response) { response_ = std::move(response); return true; } -void GoogleAsyncRequestImpl::onReceiveTrailingMetadata(Http::HeaderMapPtr&&) {} +void GoogleAsyncRequestImpl::onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&&) {} void GoogleAsyncRequestImpl::onRemoteClose(Grpc::Status::GrpcStatus status, const std::string& message) { diff --git a/source/common/grpc/google_async_client_impl.h b/source/common/grpc/google_async_client_impl.h index 3d1fb58ae8..cc0321283d 100644 --- a/source/common/grpc/google_async_client_impl.h +++ b/source/common/grpc/google_async_client_impl.h @@ -234,8 +234,8 @@ class GoogleAsyncStreamImpl : public RawAsyncStream, // Write the first PendingMessage in the write queue if non-empty. void writeQueued(); // Deliver notification and update stats when the connection closes. - void notifyRemoteClose(Status::GrpcStatus grpc_status, Http::HeaderMapPtr trailing_metadata, - const std::string& message); + void notifyRemoteClose(Status::GrpcStatus grpc_status, + Http::ResponseTrailerMapPtr trailing_metadata, const std::string& message); // Schedule stream for deferred deletion. void deferredDelete(); // Cleanup and schedule stream for deferred deletion if no inflight @@ -319,10 +319,10 @@ class GoogleAsyncRequestImpl : public AsyncRequest, private: // Grpc::RawAsyncStreamCallbacks - void onCreateInitialMetadata(Http::HeaderMap& metadata) override; - void onReceiveInitialMetadata(Http::HeaderMapPtr&&) override; + void onCreateInitialMetadata(Http::RequestHeaderMap& metadata) override; + void onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&&) override; bool onReceiveMessageRaw(Buffer::InstancePtr&& response) override; - void onReceiveTrailingMetadata(Http::HeaderMapPtr&&) override; + void onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&&) override; void onRemoteClose(Grpc::Status::GrpcStatus status, const std::string& message) override; Buffer::InstancePtr request_; diff --git a/source/common/http/BUILD b/source/common/http/BUILD index 9e8d0f9feb..1c4068178f 100644 --- a/source/common/http/BUILD +++ b/source/common/http/BUILD @@ -281,7 +281,6 @@ envoy_cc_library( envoy_cc_library( name = "message_lib", - srcs = ["message_impl.cc"], hdrs = ["message_impl.h"], deps = [ ":header_map_lib", diff --git a/source/common/http/async_client_impl.cc b/source/common/http/async_client_impl.cc index 22e47db538..e418273533 100644 --- a/source/common/http/async_client_impl.cc +++ b/source/common/http/async_client_impl.cc @@ -50,7 +50,8 @@ AsyncClientImpl::~AsyncClientImpl() { } } -AsyncClient::Request* AsyncClientImpl::send(MessagePtr&& request, AsyncClient::Callbacks& callbacks, +AsyncClient::Request* AsyncClientImpl::send(RequestMessagePtr&& request, + AsyncClient::Callbacks& callbacks, const AsyncClient::RequestOptions& options) { AsyncRequestImpl* async_request = new AsyncRequestImpl(std::move(request), *this, callbacks, options); @@ -90,7 +91,7 @@ AsyncStreamImpl::AsyncStreamImpl(AsyncClientImpl& parent, AsyncClient::StreamCal // TODO(mattklein123): Correctly set protocol in stream info when we support access logging. } -void AsyncStreamImpl::encodeHeaders(HeaderMapPtr&& headers, bool end_stream) { +void AsyncStreamImpl::encodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) { ENVOY_LOG(debug, "async http request response headers (end_stream={}):\n{}", end_stream, *headers); ASSERT(!remote_closed_); @@ -117,7 +118,7 @@ void AsyncStreamImpl::encodeData(Buffer::Instance& data, bool end_stream) { closeLocal(end_stream); } -void AsyncStreamImpl::encodeTrailers(HeaderMapPtr&& trailers) { +void AsyncStreamImpl::encodeTrailers(ResponseTrailerMapPtr&& trailers) { ENVOY_LOG(debug, "async http request response trailers:\n{}", *trailers); ASSERT(!remote_closed_); stream_callbacks_.onTrailers(std::move(trailers)); @@ -127,7 +128,7 @@ void AsyncStreamImpl::encodeTrailers(HeaderMapPtr&& trailers) { closeLocal(true); } -void AsyncStreamImpl::sendHeaders(HeaderMap& headers, bool end_stream) { +void AsyncStreamImpl::sendHeaders(RequestHeaderMap& headers, bool end_stream) { if (Http::Headers::get().MethodValues.Head == headers.Method()->value().getStringView()) { is_head_request_ = true; } @@ -161,7 +162,7 @@ void AsyncStreamImpl::sendData(Buffer::Instance& data, bool end_stream) { closeLocal(end_stream); } -void AsyncStreamImpl::sendTrailers(HeaderMap& trailers) { +void AsyncStreamImpl::sendTrailers(RequestTrailerMap& trailers) { // See explanation in sendData. if (local_closed_) { return; @@ -232,7 +233,7 @@ void AsyncStreamImpl::resetStream() { cleanup(); } -AsyncRequestImpl::AsyncRequestImpl(MessagePtr&& request, AsyncClientImpl& parent, +AsyncRequestImpl::AsyncRequestImpl(RequestMessagePtr&& request, AsyncClientImpl& parent, AsyncClient::Callbacks& callbacks, const AsyncClient::RequestOptions& options) : AsyncStreamImpl(parent, *this, options), request_(std::move(request)), callbacks_(callbacks) { @@ -267,7 +268,7 @@ void AsyncRequestImpl::onComplete() { callbacks_.onSuccess(std::move(response_)); } -void AsyncRequestImpl::onHeaders(HeaderMapPtr&& headers, bool) { +void AsyncRequestImpl::onHeaders(ResponseHeaderMapPtr&& headers, bool) { const uint64_t response_code = Http::Utility::getResponseStatus(*headers); streamInfo().response_code_ = response_code; response_ = std::make_unique(std::move(headers)); @@ -281,7 +282,7 @@ void AsyncRequestImpl::onData(Buffer::Instance& data, bool) { response_->body()->move(data); } -void AsyncRequestImpl::onTrailers(HeaderMapPtr&& trailers) { +void AsyncRequestImpl::onTrailers(ResponseTrailerMapPtr&& trailers) { response_->trailers(std::move(trailers)); } diff --git a/source/common/http/async_client_impl.h b/source/common/http/async_client_impl.h index 14de92fd73..ae6807bae2 100644 --- a/source/common/http/async_client_impl.h +++ b/source/common/http/async_client_impl.h @@ -52,7 +52,7 @@ class AsyncClientImpl final : public AsyncClient { ~AsyncClientImpl() override; // Http::AsyncClient - Request* send(MessagePtr&& request, Callbacks& callbacks, + Request* send(RequestMessagePtr&& request, Callbacks& callbacks, const AsyncClient::RequestOptions& options) override; Stream* start(StreamCallbacks& callbacks, const AsyncClient::StreamOptions& options) override; @@ -90,9 +90,9 @@ class AsyncStreamImpl : public AsyncClient::Stream, absl::optional routeConfig() override { return {}; } // Http::AsyncClient::Stream - void sendHeaders(HeaderMap& headers, bool end_stream) override; + void sendHeaders(RequestHeaderMap& headers, bool end_stream) override; void sendData(Buffer::Instance& data, bool end_stream) override; - void sendTrailers(HeaderMap& trailers) override; + void sendTrailers(RequestTrailerMap& trailers) override; void reset() override; protected: @@ -342,13 +342,13 @@ class AsyncStreamImpl : public AsyncClient::Stream, NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } void sendLocalReply(Code code, absl::string_view body, - std::function modify_headers, + std::function modify_headers, const absl::optional grpc_status, absl::string_view details) override { stream_info_.setResponseCodeDetails(details); Utility::sendLocalReply( is_grpc_request_, - [this, modify_headers](HeaderMapPtr&& headers, bool end_stream) -> void { + [this, modify_headers](ResponseHeaderMapPtr&& headers, bool end_stream) -> void { if (modify_headers != nullptr) { modify_headers(*headers); } @@ -359,10 +359,10 @@ class AsyncStreamImpl : public AsyncClient::Stream, } // The async client won't pause if sending an Expect: 100-Continue so simply // swallows any incoming encode100Continue. - void encode100ContinueHeaders(HeaderMapPtr&&) override {} - void encodeHeaders(HeaderMapPtr&& headers, bool end_stream) override; + void encode100ContinueHeaders(ResponseHeaderMapPtr&&) override {} + void encodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) override; void encodeData(Buffer::Instance& data, bool end_stream) override; - void encodeTrailers(HeaderMapPtr&& trailers) override; + void encodeTrailers(ResponseTrailerMapPtr&& trailers) override; void encodeMetadata(MetadataMapPtr&&) override {} void onDecoderFilterAboveWriteBufferHighWatermark() override {} void onDecoderFilterBelowWriteBufferLowWatermark() override {} @@ -404,8 +404,8 @@ class AsyncRequestImpl final : public AsyncClient::Request, AsyncStreamImpl, AsyncClient::StreamCallbacks { public: - AsyncRequestImpl(MessagePtr&& request, AsyncClientImpl& parent, AsyncClient::Callbacks& callbacks, - const AsyncClient::RequestOptions& options); + AsyncRequestImpl(RequestMessagePtr&& request, AsyncClientImpl& parent, + AsyncClient::Callbacks& callbacks, const AsyncClient::RequestOptions& options); // AsyncClient::Request void cancel() override; @@ -414,9 +414,9 @@ class AsyncRequestImpl final : public AsyncClient::Request, void initialize(); // AsyncClient::StreamCallbacks - void onHeaders(HeaderMapPtr&& headers, bool end_stream) override; + void onHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) override; void onData(Buffer::Instance& data, bool end_stream) override; - void onTrailers(HeaderMapPtr&& trailers) override; + void onTrailers(ResponseTrailerMapPtr&& trailers) override; void onComplete() override; void onReset() override; @@ -430,9 +430,9 @@ class AsyncRequestImpl final : public AsyncClient::Request, NOT_IMPLEMENTED_GCOVR_EXCL_LINE; } - MessagePtr request_; + RequestMessagePtr request_; AsyncClient::Callbacks& callbacks_; - std::unique_ptr response_; + std::unique_ptr response_; bool cancelled_{}; Tracing::SpanPtr child_span_; diff --git a/source/common/http/codec_wrappers.h b/source/common/http/codec_wrappers.h index da14021045..20ba1ae88c 100644 --- a/source/common/http/codec_wrappers.h +++ b/source/common/http/codec_wrappers.h @@ -68,7 +68,7 @@ class ResponseDecoderWrapper : public ResponseDecoder { class RequestEncoderWrapper : public RequestEncoder { public: // RequestEncoder - void encodeHeaders(const HeaderMap& headers, bool end_stream) override { + void encodeHeaders(const RequestHeaderMap& headers, bool end_stream) override { inner_.encodeHeaders(headers, end_stream); if (end_stream) { onEncodeComplete(); @@ -82,7 +82,7 @@ class RequestEncoderWrapper : public RequestEncoder { } } - void encodeTrailers(const HeaderMap& trailers) override { + void encodeTrailers(const RequestTrailerMap& trailers) override { inner_.encodeTrailers(trailers); onEncodeComplete(); } diff --git a/source/common/http/conn_manager_impl.cc b/source/common/http/conn_manager_impl.cc index 8e71f7b912..13b666d6bc 100644 --- a/source/common/http/conn_manager_impl.cc +++ b/source/common/http/conn_manager_impl.cc @@ -121,8 +121,8 @@ ConnectionManagerImpl::ConnectionManagerImpl(ConnectionManagerConfig& config, : Server::OverloadManager::getInactiveState()), time_source_(time_source) {} -const HeaderMapImpl& ConnectionManagerImpl::continueHeader() { - static const auto headers = HeaderMapImpl::create( +const ResponseHeaderMap& ConnectionManagerImpl::continueHeader() { + static const auto headers = createHeaderMap( {{Http::Headers::get().Status, std::to_string(enumToInt(Code::Continue))}}); return *headers; } @@ -974,7 +974,8 @@ void ConnectionManagerImpl::ActiveStream::traceRequest() { } void ConnectionManagerImpl::ActiveStream::decodeHeaders(ActiveStreamDecoderFilter* filter, - HeaderMap& headers, bool end_stream) { + RequestHeaderMap& headers, + bool end_stream) { // Headers filter iteration should always start with the next filter if available. std::list::iterator entry = commonDecodePrefix(filter, FilterIterationStartState::AlwaysStartFromNext); @@ -1165,7 +1166,7 @@ HeaderMap& ConnectionManagerImpl::ActiveStream::addDecodedTrailers() { // Trailers can only be added once. ASSERT(!request_trailers_); - request_trailers_ = std::make_unique(); + request_trailers_ = std::make_unique(); return *request_trailers_; } @@ -1205,7 +1206,7 @@ void ConnectionManagerImpl::ActiveStream::decodeTrailers(RequestTrailerMapPtr&& } void ConnectionManagerImpl::ActiveStream::decodeTrailers(ActiveStreamDecoderFilter* filter, - HeaderMap& trailers) { + RequestTrailerMap& trailers) { // If we previously decided to decode only the headers, do nothing here. if (state_.decoding_headers_only_) { return; @@ -1420,7 +1421,7 @@ absl::optional ConnectionManagerImpl::ActiveStream void ConnectionManagerImpl::ActiveStream::sendLocalReply( bool is_grpc_request, Code code, absl::string_view body, - const std::function& modify_headers, bool is_head_request, + const std::function& modify_headers, bool is_head_request, const absl::optional grpc_status, absl::string_view details) { ENVOY_STREAM_LOG(debug, "Sending local reply with details {}", *this, details); ASSERT(response_headers_ == nullptr); @@ -1432,7 +1433,7 @@ void ConnectionManagerImpl::ActiveStream::sendLocalReply( stream_info_.setResponseCodeDetails(details); Utility::sendLocalReply( is_grpc_request, - [this, modify_headers](HeaderMapPtr&& headers, bool end_stream) -> void { + [this, modify_headers](ResponseHeaderMapPtr&& headers, bool end_stream) -> void { if (modify_headers != nullptr) { modify_headers(*headers); } @@ -1450,7 +1451,7 @@ void ConnectionManagerImpl::ActiveStream::sendLocalReply( } void ConnectionManagerImpl::ActiveStream::encode100ContinueHeaders( - ActiveStreamEncoderFilter* filter, HeaderMap& headers) { + ActiveStreamEncoderFilter* filter, ResponseHeaderMap& headers) { resetIdleTimer(); ASSERT(connection_manager_.config_.proxy100Continue()); // Make sure commonContinue continues encode100ContinueHeaders. @@ -1489,7 +1490,8 @@ void ConnectionManagerImpl::ActiveStream::encode100ContinueHeaders( } void ConnectionManagerImpl::ActiveStream::encodeHeaders(ActiveStreamEncoderFilter* filter, - HeaderMap& headers, bool end_stream) { + ResponseHeaderMap& headers, + bool end_stream) { resetIdleTimer(); disarmRequestTimeout(); @@ -1547,7 +1549,7 @@ void ConnectionManagerImpl::ActiveStream::encodeHeaders(ActiveStreamEncoderFilte } } -void ConnectionManagerImpl::ActiveStream::encodeHeadersInternal(HeaderMap& headers, +void ConnectionManagerImpl::ActiveStream::encodeHeadersInternal(ResponseHeaderMap& headers, bool end_stream) { // Base headers. connection_manager_.config_.dateProvider().setDateHeader(headers); @@ -1695,7 +1697,7 @@ HeaderMap& ConnectionManagerImpl::ActiveStream::addEncodedTrailers() { // Trailers can only be added once. ASSERT(!response_trailers_); - response_trailers_ = std::make_unique(); + response_trailers_ = std::make_unique(); return *response_trailers_; } @@ -1803,7 +1805,7 @@ void ConnectionManagerImpl::ActiveStream::encodeDataInternal(Buffer::Instance& d } void ConnectionManagerImpl::ActiveStream::encodeTrailers(ActiveStreamEncoderFilter* filter, - HeaderMap& trailers) { + ResponseTrailerMap& trailers) { resetIdleTimer(); // If we previously decided to encode only the headers, do nothing here. @@ -2002,16 +2004,16 @@ void ConnectionManagerImpl::ActiveStreamFilterBase::commonContinue() { // future. if (!headers_continued_) { headers_continued_ = true; - doHeaders(complete() && !bufferedData() && !trailers()); + doHeaders(complete() && !bufferedData() && !hasTrailers()); } doMetadata(); if (bufferedData()) { - doData(complete() && !trailers()); + doData(complete() && !hasTrailers()); } - if (trailers()) { + if (hasTrailers()) { doTrailers(); } @@ -2098,7 +2100,7 @@ bool ConnectionManagerImpl::ActiveStreamFilterBase::commonHandleAfterDataCallbac status == FilterDataStatus::StopIterationAndWatermark) { buffer_was_streaming = status == FilterDataStatus::StopIterationAndWatermark; commonHandleBufferData(provided_data); - } else if (complete() && !trailers() && !bufferedData()) { + } else if (complete() && !hasTrailers() && !bufferedData()) { // If this filter is doing StopIterationNoBuffer and this stream is terminated with a zero // byte data frame, we need to create an empty buffer to make sure that when commonContinue // is called, the pipeline resumes with an empty data frame with end_stream = true @@ -2219,7 +2221,7 @@ void ConnectionManagerImpl::ActiveStreamDecoderFilter::injectDecodedDataToFilter void ConnectionManagerImpl::ActiveStreamDecoderFilter::continueDecoding() { commonContinue(); } void ConnectionManagerImpl::ActiveStreamDecoderFilter::encode100ContinueHeaders( - HeaderMapPtr&& headers) { + ResponseHeaderMapPtr&& headers) { // If Envoy is not configured to proxy 100-Continue responses, swallow the 100 Continue // here. This avoids the potential situation where Envoy strips Expect: 100-Continue and sends a // 100-Continue, then proxies a duplicate 100 Continue from upstream. @@ -2229,7 +2231,7 @@ void ConnectionManagerImpl::ActiveStreamDecoderFilter::encode100ContinueHeaders( } } -void ConnectionManagerImpl::ActiveStreamDecoderFilter::encodeHeaders(HeaderMapPtr&& headers, +void ConnectionManagerImpl::ActiveStreamDecoderFilter::encodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) { parent_.response_headers_ = std::move(headers); parent_.encodeHeaders(nullptr, *parent_.response_headers_, end_stream); @@ -2241,7 +2243,8 @@ void ConnectionManagerImpl::ActiveStreamDecoderFilter::encodeData(Buffer::Instan ActiveStream::FilterIterationStartState::CanStartFromCurrent); } -void ConnectionManagerImpl::ActiveStreamDecoderFilter::encodeTrailers(HeaderMapPtr&& trailers) { +void ConnectionManagerImpl::ActiveStreamDecoderFilter::encodeTrailers( + ResponseTrailerMapPtr&& trailers) { parent_.response_trailers_ = std::move(trailers); parent_.encodeTrailers(nullptr, *parent_.response_trailers_); } @@ -2418,7 +2421,7 @@ void ConnectionManagerImpl::ActiveStreamEncoderFilter::responseDataTooLarge() { // directly, which maximizes shared code with the normal response path. Http::Utility::sendLocalReply( Grpc::Common::hasGrpcContentType(*parent_.request_headers_), - [&](HeaderMapPtr&& response_headers, bool end_stream) -> void { + [&](ResponseHeaderMapPtr&& response_headers, bool end_stream) -> void { parent_.response_headers_ = std::move(response_headers); parent_.encodeHeadersInternal(*parent_.response_headers_, end_stream); }, diff --git a/source/common/http/conn_manager_impl.h b/source/common/http/conn_manager_impl.h index bfa35f788d..c10e489258 100644 --- a/source/common/http/conn_manager_impl.h +++ b/source/common/http/conn_manager_impl.h @@ -66,7 +66,7 @@ class ConnectionManagerImpl : Logger::Loggable, ConnectionManagerTracingStats& tracing_stats); static ConnectionManagerListenerStats generateListenerStats(const std::string& prefix, Stats::Scope& scope); - static const HeaderMapImpl& continueHeader(); + static const ResponseHeaderMap& continueHeader(); // Currently the ConnectionManager creates a codec lazily when either: // a) onConnection for H3. @@ -142,7 +142,7 @@ class ConnectionManagerImpl : Logger::Loggable, virtual void doHeaders(bool end_stream) PURE; virtual void doData(bool end_stream) PURE; virtual void doTrailers() PURE; - virtual const HeaderMapPtr& trailers() PURE; + virtual bool hasTrailers() PURE; virtual void doMetadata() PURE; // TODO(soya3129): make this pure when adding impl to encoder filter. virtual void handleMetadataAfterHeadersCallback() PURE; @@ -250,7 +250,7 @@ class ConnectionManagerImpl : Logger::Loggable, } } void doTrailers() override { parent_.decodeTrailers(this, *parent_.request_trailers_); } - const HeaderMapPtr& trailers() override { return parent_.request_trailers_; } + bool hasTrailers() override { return parent_.request_trailers_ != nullptr; } void drainSavedRequestMetadata() { ASSERT(saved_request_metadata_ != nullptr); @@ -278,17 +278,17 @@ class ConnectionManagerImpl : Logger::Loggable, } void sendLocalReply(Code code, absl::string_view body, - std::function modify_headers, + std::function modify_headers, const absl::optional grpc_status, absl::string_view details) override { parent_.stream_info_.setResponseCodeDetails(details); parent_.sendLocalReply(is_grpc_request_, code, body, modify_headers, parent_.state_.is_head_request_, grpc_status, details); } - void encode100ContinueHeaders(HeaderMapPtr&& headers) override; - void encodeHeaders(HeaderMapPtr&& headers, bool end_stream) override; + void encode100ContinueHeaders(ResponseHeaderMapPtr&& headers) override; + void encodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) override; void encodeData(Buffer::Instance& data, bool end_stream) override; - void encodeTrailers(HeaderMapPtr&& trailers) override; + void encodeTrailers(ResponseTrailerMapPtr&& trailers) override; void encodeMetadata(MetadataMapPtr&& metadata_map_ptr) override; void onDecoderFilterAboveWriteBufferHighWatermark() override; void onDecoderFilterBelowWriteBufferLowWatermark() override; @@ -311,7 +311,7 @@ class ConnectionManagerImpl : Logger::Loggable, // Each decoder filter instance checks if the request passed to the filter is gRPC // so that we can issue gRPC local responses to gRPC requests. Filter's decodeHeaders() // called here may change the content type, so we must check it before the call. - FilterHeadersStatus decodeHeaders(HeaderMap& headers, bool end_stream) { + FilterHeadersStatus decodeHeaders(RequestHeaderMap& headers, bool end_stream) { is_grpc_request_ = Grpc::Common::hasGrpcContentType(headers); FilterHeadersStatus status = handle_->decodeHeaders(headers, end_stream); if (end_stream) { @@ -373,7 +373,7 @@ class ConnectionManagerImpl : Logger::Loggable, } } void doTrailers() override { parent_.encodeTrailers(this, *parent_.response_trailers_); } - const HeaderMapPtr& trailers() override { return parent_.response_trailers_; } + bool hasTrailers() override { return parent_.response_trailers_ != nullptr; } // Http::StreamEncoderFilterCallbacks void addEncodedData(Buffer::Instance& data, bool streaming) override; @@ -463,39 +463,41 @@ class ConnectionManagerImpl : Logger::Loggable, void addDecodedData(ActiveStreamDecoderFilter& filter, Buffer::Instance& data, bool streaming); HeaderMap& addDecodedTrailers(); MetadataMapVector& addDecodedMetadata(); - void decodeHeaders(ActiveStreamDecoderFilter* filter, HeaderMap& headers, bool end_stream); + void decodeHeaders(ActiveStreamDecoderFilter* filter, RequestHeaderMap& headers, + bool end_stream); // Sends data through decoding filter chains. filter_iteration_start_state indicates which // filter to start the iteration with. void decodeData(ActiveStreamDecoderFilter* filter, Buffer::Instance& data, bool end_stream, FilterIterationStartState filter_iteration_start_state); - void decodeTrailers(ActiveStreamDecoderFilter* filter, HeaderMap& trailers); + void decodeTrailers(ActiveStreamDecoderFilter* filter, RequestTrailerMap& trailers); void decodeMetadata(ActiveStreamDecoderFilter* filter, MetadataMap& metadata_map); void disarmRequestTimeout(); void maybeEndDecode(bool end_stream); void addEncodedData(ActiveStreamEncoderFilter& filter, Buffer::Instance& data, bool streaming); HeaderMap& addEncodedTrailers(); void sendLocalReply(bool is_grpc_request, Code code, absl::string_view body, - const std::function& modify_headers, + const std::function& modify_headers, bool is_head_request, const absl::optional grpc_status, absl::string_view details); - void encode100ContinueHeaders(ActiveStreamEncoderFilter* filter, HeaderMap& headers); + void encode100ContinueHeaders(ActiveStreamEncoderFilter* filter, ResponseHeaderMap& headers); // As with most of the encode functions, this runs encodeHeaders on various // filters before calling encodeHeadersInternal which does final header munging and passes the // headers to the encoder. - void encodeHeaders(ActiveStreamEncoderFilter* filter, HeaderMap& headers, bool end_stream); + void encodeHeaders(ActiveStreamEncoderFilter* filter, ResponseHeaderMap& headers, + bool end_stream); // Sends data through encoding filter chains. filter_iteration_start_state indicates which // filter to start the iteration with, and finally calls encodeDataInternal // to update stats, do end stream bookkeeping, and send the data to encoder. void encodeData(ActiveStreamEncoderFilter* filter, Buffer::Instance& data, bool end_stream, FilterIterationStartState filter_iteration_start_state); - void encodeTrailers(ActiveStreamEncoderFilter* filter, HeaderMap& trailers); + void encodeTrailers(ActiveStreamEncoderFilter* filter, ResponseTrailerMap& trailers); void encodeMetadata(ActiveStreamEncoderFilter* filter, MetadataMapPtr&& metadata_map_ptr); // This is a helper function for encodeHeaders and responseDataTooLarge which allows for shared // code for the two headers encoding paths. It does header munging, updates timing stats, and // sends the headers to the encoder. - void encodeHeadersInternal(HeaderMap& headers, bool end_stream); + void encodeHeadersInternal(ResponseHeaderMap& headers, bool end_stream); // This is a helper function for encodeData and responseDataTooLarge which allows for shared // code for the two data encoding paths. It does stats updates and tracks potential end of // stream. @@ -684,13 +686,13 @@ class ConnectionManagerImpl : Logger::Loggable, Tracing::SpanPtr active_span_; const uint64_t stream_id_; ResponseEncoder* response_encoder_{}; - HeaderMapPtr continue_headers_; - HeaderMapPtr response_headers_; + ResponseHeaderMapPtr continue_headers_; + ResponseHeaderMapPtr response_headers_; Buffer::WatermarkBufferPtr buffered_response_data_; - HeaderMapPtr response_trailers_{}; + ResponseTrailerMapPtr response_trailers_{}; RequestHeaderMapPtr request_headers_; Buffer::WatermarkBufferPtr buffered_request_data_; - HeaderMapPtr request_trailers_; + RequestTrailerMapPtr request_trailers_; std::list decoder_filters_; std::list encoder_filters_; std::list access_log_handlers_; diff --git a/source/common/http/header_map_impl.cc b/source/common/http/header_map_impl.cc index f914f6709c..ec0afb2588 100644 --- a/source/common/http/header_map_impl.cc +++ b/source/common/http/header_map_impl.cc @@ -224,19 +224,6 @@ uint64_t HeaderMapImpl::appendToHeader(HeaderString& header, absl::string_view d HeaderMapImpl::HeaderMapImpl() { inline_headers_.clear(); } -HeaderMapImplPtr HeaderMapImpl::create( - const std::initializer_list>& values) { - auto new_header_map = std::make_unique(); - initFromInitList(*new_header_map, values); - return new_header_map; -} - -HeaderMapImplPtr HeaderMapImpl::create(const HeaderMap& rhs) { - auto new_header_map = std::make_unique(); - copyFrom(*new_header_map, rhs); - return new_header_map; -} - void HeaderMapImpl::initFromInitList( HeaderMapImpl& new_header_map, const std::initializer_list>& values) { @@ -282,6 +269,7 @@ void HeaderMapImpl::copyFrom(HeaderMapImpl& lhs, const HeaderMap& header_map) { namespace { +// This is currently only used in tests and is not optimized for performance. HeaderMap::Iterate collectAllHeaders(const HeaderEntry& header, void* headers) { static_cast>*>(headers)->push_back( std::make_pair(header.key().getStringView(), header.value().getStringView())); diff --git a/source/common/http/header_map_impl.h b/source/common/http/header_map_impl.h index 8c223602ca..634032e28f 100644 --- a/source/common/http/header_map_impl.h +++ b/source/common/http/header_map_impl.h @@ -50,9 +50,6 @@ public: #define DEFINE_INLINE_HEADER_STRUCT(name) HeaderEntryImpl* name##_; -class HeaderMapImpl; -using HeaderMapImplPtr = std::unique_ptr; - /** * Implementation of Http::HeaderMap. This is heavily optimized for performance. Roughly, when * headers are added to the map, we do a hash lookup to see if it's one of the O(1) headers. @@ -67,10 +64,10 @@ class HeaderMapImpl : public virtual HeaderMap, NonCopyable { HeaderMapImpl(); // The following "constructors" call virtual functions during construction and must use the // static factory pattern. - static HeaderMapImplPtr - create(const std::initializer_list>& values); - static HeaderMapImplPtr create(const HeaderMap& rhs); static void copyFrom(HeaderMapImpl& lhs, const HeaderMap& rhs); + static void + initFromInitList(HeaderMapImpl& new_header_map, + const std::initializer_list>& values); // Performs a manual byte size count for test verification. void verifyByteSizeInternalForTest() const; @@ -219,9 +216,6 @@ class HeaderMapImpl : public virtual HeaderMap, NonCopyable { void updateSize(uint64_t from_size, uint64_t to_size); void addSize(uint64_t size); void subtractSize(uint64_t size); - static void - initFromInitList(HeaderMapImpl& new_header_map, - const std::initializer_list>& values); AllInlineHeaders inline_headers_; HeaderList headers_; @@ -249,5 +243,19 @@ class RequestTrailerMapImpl : public HeaderMapImpl, public RequestTrailerMap {}; class ResponseHeaderMapImpl : public HeaderMapImpl, public ResponseHeaderMap {}; class ResponseTrailerMapImpl : public HeaderMapImpl, public ResponseTrailerMap {}; +template +std::unique_ptr +createHeaderMap(const std::initializer_list>& values) { + auto new_header_map = std::make_unique(); + HeaderMapImpl::initFromInitList(*new_header_map, values); + return new_header_map; +} + +template std::unique_ptr createHeaderMap(const HeaderMap& rhs) { + auto new_header_map = std::make_unique(); + HeaderMapImpl::copyFrom(*new_header_map, rhs); + return new_header_map; +} + } // namespace Http } // namespace Envoy diff --git a/source/common/http/http1/codec_impl.cc b/source/common/http/http1/codec_impl.cc index d53f567538..e5db3fc530 100644 --- a/source/common/http/http1/codec_impl.cc +++ b/source/common/http/http1/codec_impl.cc @@ -95,7 +95,7 @@ void StreamEncoderImpl::encodeFormattedHeader(absl::string_view key, absl::strin } } -void ResponseEncoderImpl::encode100ContinueHeaders(const HeaderMap& headers) { +void ResponseEncoderImpl::encode100ContinueHeaders(const ResponseHeaderMap& headers) { ASSERT(headers.Status()->value() == "100"); processing_100_continue_ = true; encodeHeaders(headers, false); @@ -275,7 +275,7 @@ const Network::Address::InstanceConstSharedPtr& StreamEncoderImpl::connectionLoc static const char RESPONSE_PREFIX[] = "HTTP/1.1 "; static const char HTTP_10_RESPONSE_PREFIX[] = "HTTP/1.0 "; -void ResponseEncoderImpl::encodeHeaders(const HeaderMap& headers, bool end_stream) { +void ResponseEncoderImpl::encodeHeaders(const ResponseHeaderMap& headers, bool end_stream) { started_response_ = true; // The contract is that client codecs must ensure that :status is present. @@ -311,7 +311,7 @@ void ResponseEncoderImpl::encodeHeaders(const HeaderMap& headers, bool end_strea static const char REQUEST_POSTFIX[] = " HTTP/1.1\r\n"; -void RequestEncoderImpl::encodeHeaders(const HeaderMap& headers, bool end_stream) { +void RequestEncoderImpl::encodeHeaders(const RequestHeaderMap& headers, bool end_stream) { const HeaderEntry* method = headers.Method(); const HeaderEntry* path = headers.Path(); if (!method || !path) { @@ -880,6 +880,10 @@ int ClientConnectionImpl::onHeadersComplete() { // Swallow the spurious onMessageComplete and continue processing. ignore_message_complete_for_100_continue_ = true; pending_responses_.front().decoder_->decode100ContinueHeaders(std::move(headers)); + + // Reset to ensure no information from the continue headers is used for the response headers + // in case the callee does not move the headers out. + headers_or_trailers_.emplace(nullptr); } else if (cannotHaveBody()) { deferred_end_stream_headers_ = true; } else { diff --git a/source/common/http/http1/codec_impl.h b/source/common/http/http1/codec_impl.h index bb7ee5d376..658800b871 100644 --- a/source/common/http/http1/codec_impl.h +++ b/source/common/http/http1/codec_impl.h @@ -116,9 +116,9 @@ class ResponseEncoderImpl : public StreamEncoderImpl, public ResponseEncoder { bool startedResponse() { return started_response_; } // Http::ResponseEncoder - void encode100ContinueHeaders(const HeaderMap& headers) override; - void encodeHeaders(const HeaderMap& headers, bool end_stream) override; - void encodeTrailers(const HeaderMap& trailers) override { encodeTrailersBase(trailers); } + void encode100ContinueHeaders(const ResponseHeaderMap& headers) override; + void encodeHeaders(const ResponseHeaderMap& headers, bool end_stream) override; + void encodeTrailers(const ResponseTrailerMap& trailers) override { encodeTrailersBase(trailers); } private: bool started_response_{}; @@ -134,8 +134,8 @@ class RequestEncoderImpl : public StreamEncoderImpl, public RequestEncoder { bool headRequest() { return head_request_; } // Http::RequestEncoder - void encodeHeaders(const HeaderMap& headers, bool end_stream) override; - void encodeTrailers(const HeaderMap& trailers) override { encodeTrailersBase(trailers); } + void encodeHeaders(const RequestHeaderMap& headers, bool end_stream) override; + void encodeTrailers(const RequestTrailerMap& trailers) override { encodeTrailersBase(trailers); } private: bool head_request_{}; diff --git a/source/common/http/http2/codec_impl.cc b/source/common/http/http2/codec_impl.cc index b9def982ba..c2e2dc0c52 100644 --- a/source/common/http/http2/codec_impl.cc +++ b/source/common/http/http2/codec_impl.cc @@ -87,7 +87,7 @@ void ConnectionImpl::StreamImpl::buildHeaders(std::vector& final_hea &final_headers); } -void ConnectionImpl::ServerStreamImpl::encode100ContinueHeaders(const HeaderMap& headers) { +void ConnectionImpl::ServerStreamImpl::encode100ContinueHeaders(const ResponseHeaderMap& headers) { ASSERT(headers.Status()->value() == "100"); encodeHeaders(headers, false); } @@ -99,7 +99,7 @@ void ConnectionImpl::StreamImpl::encodeHeadersBase(const HeaderMap& headers, boo // needed until submitHeaders has been called. Http::HeaderMapPtr modified_headers; if (Http::Utility::isUpgrade(headers)) { - modified_headers = Http::HeaderMapImpl::create(headers); + modified_headers = createHeaderMap(headers); transformUpgradeFromH1toH2(*modified_headers); buildHeaders(final_headers, *modified_headers); } else { @@ -128,7 +128,7 @@ void ConnectionImpl::StreamImpl::encodeTrailersBase(const HeaderMap& trailers) { // In this case we want trailers to come after we release all pending body data that is // waiting on window updates. We need to save the trailers so that we can emit them later. ASSERT(!pending_trailers_to_encode_); - pending_trailers_to_encode_ = HeaderMapImpl::create(trailers); + pending_trailers_to_encode_ = createHeaderMap(trailers); } else { submitTrailers(trailers); parent_.sendPendingFrames(); diff --git a/source/common/http/http2/codec_impl.h b/source/common/http/http2/codec_impl.h index f000997a4d..ab01f817f7 100644 --- a/source/common/http/http2/codec_impl.h +++ b/source/common/http/http2/codec_impl.h @@ -274,10 +274,12 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable headers_or_trailers_; @@ -315,13 +317,15 @@ class ConnectionImpl : public virtual Connection, protected Logger::Loggable headers_or_trailers_; diff --git a/source/common/http/message_impl.cc b/source/common/http/message_impl.cc deleted file mode 100644 index 8aca2ec92e..0000000000 --- a/source/common/http/message_impl.cc +++ /dev/null @@ -1,25 +0,0 @@ -#include "common/http/message_impl.h" - -#include -#include - -#include "absl/container/fixed_array.h" - -namespace Envoy { -namespace Http { - -std::string MessageImpl::bodyAsString() const { - std::string ret; - if (body_) { - uint64_t num_slices = body_->getRawSlices(nullptr, 0); - absl::FixedArray slices(num_slices); - body_->getRawSlices(slices.begin(), num_slices); - for (const Buffer::RawSlice& slice : slices) { - ret.append(reinterpret_cast(slice.mem_), slice.len_); - } - } - return ret; -} - -} // namespace Http -} // namespace Envoy diff --git a/source/common/http/message_impl.h b/source/common/http/message_impl.h index cda0a341af..ce33936dbd 100644 --- a/source/common/http/message_impl.h +++ b/source/common/http/message_impl.h @@ -15,34 +15,43 @@ namespace Http { /** * Implementation of Http::Message. This implementation does not support streaming. */ -class MessageImpl : public Http::Message { +template +class MessageImpl : public Message { public: + MessageImpl() : headers_(std::make_unique()) {} + MessageImpl(std::unique_ptr&& headers) : headers_(std::move(headers)) {} + // Http::Message - HeaderMap& headers() override { return *headers_; } + HeadersInterfaceType& headers() override { return *headers_; } Buffer::InstancePtr& body() override { return body_; } - HeaderMap* trailers() override { return trailers_.get(); } - void trailers(HeaderMapPtr&& trailers) override { trailers_ = std::move(trailers); } - std::string bodyAsString() const override; - -protected: - MessageImpl(HeaderMapPtr&& headers) : headers_(std::move(headers)) {} + TrailersInterfaceType* trailers() override { return trailers_.get(); } + void trailers(std::unique_ptr&& trailers) override { + trailers_ = std::move(trailers); + } + std::string bodyAsString() const override { + std::string ret; + if (body_) { + uint64_t num_slices = body_->getRawSlices(nullptr, 0); + absl::FixedArray slices(num_slices); + body_->getRawSlices(slices.begin(), num_slices); + for (const Buffer::RawSlice& slice : slices) { + ret.append(reinterpret_cast(slice.mem_), slice.len_); + } + } + return ret; + } private: - HeaderMapPtr headers_; + std::unique_ptr headers_; Buffer::InstancePtr body_; - HeaderMapPtr trailers_; + std::unique_ptr trailers_; }; -class RequestMessageImpl : public MessageImpl { -public: - RequestMessageImpl() : MessageImpl(HeaderMapPtr{new HeaderMapImpl()}) {} - RequestMessageImpl(HeaderMapPtr&& headers) : MessageImpl(std::move(headers)) {} -}; - -class ResponseMessageImpl : public MessageImpl { -public: - ResponseMessageImpl(HeaderMapPtr&& headers) : MessageImpl(std::move(headers)) {} -}; +using RequestMessageImpl = + MessageImpl; +using ResponseMessageImpl = MessageImpl; } // namespace Http } // namespace Envoy diff --git a/source/common/http/rest_api_fetcher.cc b/source/common/http/rest_api_fetcher.cc index d7ba4cd65a..15444aeb81 100644 --- a/source/common/http/rest_api_fetcher.cc +++ b/source/common/http/rest_api_fetcher.cc @@ -28,7 +28,7 @@ RestApiFetcher::~RestApiFetcher() { void RestApiFetcher::initialize() { refresh(); } -void RestApiFetcher::onSuccess(Http::MessagePtr&& response) { +void RestApiFetcher::onSuccess(Http::ResponseMessagePtr&& response) { uint64_t response_code = Http::Utility::getResponseStatus(response->headers()); if (response_code == enumToInt(Http::Code::NotModified)) { requestComplete(); @@ -55,7 +55,7 @@ void RestApiFetcher::onFailure(Http::AsyncClient::FailureReason reason) { } void RestApiFetcher::refresh() { - MessagePtr message(new RequestMessageImpl()); + RequestMessagePtr message(new RequestMessageImpl()); createRequest(*message); message->headers().setHost(remote_cluster_name_); active_request_ = cm_.httpAsyncClientForCluster(remote_cluster_name_) diff --git a/source/common/http/rest_api_fetcher.h b/source/common/http/rest_api_fetcher.h index 80ab2d3185..0be0f53a27 100644 --- a/source/common/http/rest_api_fetcher.h +++ b/source/common/http/rest_api_fetcher.h @@ -32,12 +32,12 @@ class RestApiFetcher : public Http::AsyncClient::Callbacks { * This will be called when a fetch is about to happen. It should be overridden to fill the * request message with a valid request. */ - virtual void createRequest(Message& request) PURE; + virtual void createRequest(RequestMessage& request) PURE; /** * This will be called when a 200 response is returned by the API with the response message. */ - virtual void parseResponse(const Message& response) PURE; + virtual void parseResponse(const ResponseMessage& response) PURE; /** * This will be called either in the success case or in the failure case for each fetch. It can @@ -62,7 +62,7 @@ class RestApiFetcher : public Http::AsyncClient::Callbacks { void requestComplete(); // Http::AsyncClient::Callbacks - void onSuccess(Http::MessagePtr&& response) override; + void onSuccess(Http::ResponseMessagePtr&& response) override; void onFailure(Http::AsyncClient::FailureReason reason) override; Runtime::RandomGenerator& random_; diff --git a/source/common/http/utility.cc b/source/common/http/utility.cc index 0740dfc621..7db302e6e0 100644 --- a/source/common/http/utility.cc +++ b/source/common/http/utility.cc @@ -295,7 +295,7 @@ void Utility::sendLocalReply(bool is_grpc, StreamDecoderFilterCallbacks& callbac bool is_head_request) { sendLocalReply( is_grpc, - [&](HeaderMapPtr&& headers, bool end_stream) -> void { + [&](ResponseHeaderMapPtr&& headers, bool end_stream) -> void { callbacks.encodeHeaders(std::move(headers), end_stream); }, [&](Buffer::Instance& data, bool end_stream) -> void { @@ -305,7 +305,8 @@ void Utility::sendLocalReply(bool is_grpc, StreamDecoderFilterCallbacks& callbac } void Utility::sendLocalReply( - bool is_grpc, std::function encode_headers, + bool is_grpc, + std::function encode_headers, std::function encode_data, const bool& is_reset, Code response_code, absl::string_view body_text, const absl::optional grpc_status, bool is_head_request) { @@ -313,7 +314,7 @@ void Utility::sendLocalReply( ASSERT(!is_reset); // Respond with a gRPC trailers-only response if the request is gRPC if (is_grpc) { - HeaderMapPtr response_headers{HeaderMapImpl::create( + ResponseHeaderMapPtr response_headers{createHeaderMap( {{Headers::get().Status, std::to_string(enumToInt(Code::OK))}, {Headers::get().ContentType, Headers::get().ContentTypeValues.Grpc}, {Headers::get().GrpcStatus, @@ -329,8 +330,8 @@ void Utility::sendLocalReply( return; } - HeaderMapPtr response_headers{ - HeaderMapImpl::create({{Headers::get().Status, std::to_string(enumToInt(response_code))}})}; + ResponseHeaderMapPtr response_headers{createHeaderMap( + {{Headers::get().Status, std::to_string(enumToInt(response_code))}})}; if (!body_text.empty()) { response_headers->setContentLength(body_text.size()); response_headers->setReferenceContentType(Headers::get().ContentTypeValues.Text); @@ -555,11 +556,11 @@ void Utility::extractHostPathFromUri(const absl::string_view& uri, absl::string_ } } -MessagePtr Utility::prepareHeaders(const envoy::config::core::v3::HttpUri& http_uri) { +RequestMessagePtr Utility::prepareHeaders(const envoy::config::core::v3::HttpUri& http_uri) { absl::string_view host, path; extractHostPathFromUri(http_uri.uri(), host, path); - MessagePtr message(new RequestMessageImpl()); + RequestMessagePtr message(new RequestMessageImpl()); message->headers().setPath(path); message->headers().setHost(host); diff --git a/source/common/http/utility.h b/source/common/http/utility.h index 9b6f9ecbcc..3d3f27001d 100644 --- a/source/common/http/utility.h +++ b/source/common/http/utility.h @@ -206,12 +206,12 @@ void sendLocalReply(bool is_grpc, StreamDecoderFilterCallbacks& callbacks, const * type. * @param grpc_status the gRPC status code to override the httpToGrpcStatus mapping with. */ -void sendLocalReply(bool is_grpc, - std::function encode_headers, - std::function encode_data, - const bool& is_reset, Code response_code, absl::string_view body_text, - const absl::optional grpc_status, - bool is_head_request = false); +void sendLocalReply( + bool is_grpc, + std::function encode_headers, + std::function encode_data, const bool& is_reset, + Code response_code, absl::string_view body_text, + const absl::optional grpc_status, bool is_head_request = false); struct GetLastAddressFromXffInfo { // Last valid address pulled from the XFF header. @@ -261,7 +261,7 @@ void extractHostPathFromUri(const absl::string_view& uri, absl::string_view& hos /** * Prepare headers for a HttpUri. */ -MessagePtr prepareHeaders(const envoy::config::core::v3::HttpUri& http_uri); +RequestMessagePtr prepareHeaders(const envoy::config::core::v3::HttpUri& http_uri); /** * Serialize query-params into a string. diff --git a/source/common/router/router.cc b/source/common/router/router.cc index 00144f32de..582c26398b 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -370,12 +370,12 @@ void Filter::chargeUpstreamCode(Http::Code code, Upstream::HostDescriptionConstSharedPtr upstream_host, bool dropped) { const uint64_t response_status_code = enumToInt(code); - const auto fake_response_headers = Http::HeaderMapImpl::create( + const auto fake_response_headers = Http::createHeaderMap( {{Http::Headers::get().Status, std::to_string(response_status_code)}}); chargeUpstreamCode(response_status_code, *fake_response_headers, upstream_host, dropped); } -Http::FilterHeadersStatus Filter::decodeHeaders(Http::HeaderMap& headers, bool end_stream) { +Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, bool end_stream) { // Do a common header check. We make sure that all outgoing requests have all HTTP/2 headers. // These get stripped by HTTP/1 codec where applicable. ASSERT(headers.Path()); @@ -686,7 +686,7 @@ Http::FilterDataStatus Filter::decodeData(Buffer::Instance& data, bool end_strea return Http::FilterDataStatus::StopIterationNoBuffer; } -Http::FilterTrailersStatus Filter::decodeTrailers(Http::HeaderMap& trailers) { +Http::FilterTrailersStatus Filter::decodeTrailers(Http::RequestTrailerMap& trailers) { ENVOY_STREAM_LOG(debug, "router decoding trailers:\n{}", *callbacks_, trailers); // upstream_requests_.size() cannot be 0 because we add to it unconditionally @@ -739,13 +739,13 @@ void Filter::maybeDoShadowing() { const auto& shadow_policy = shadow_policy_wrapper.get(); ASSERT(!shadow_policy.cluster().empty()); - Http::MessagePtr request( - new Http::RequestMessageImpl(Http::HeaderMapImpl::create(*downstream_headers_))); + Http::RequestMessagePtr request(new Http::RequestMessageImpl( + Http::createHeaderMap(*downstream_headers_))); if (callbacks_->decodingBuffer()) { request->body() = std::make_unique(*callbacks_->decodingBuffer()); } if (downstream_trailers_) { - request->trailers(Http::HeaderMapImpl::create(*downstream_trailers_)); + request->trailers(Http::createHeaderMap(*downstream_trailers_)); } config_.shadowWriter().shadow(shadow_policy.cluster(), std::move(request), @@ -1066,7 +1066,7 @@ void Filter::handleNon5xxResponseHeaders(absl::optionalmoveIntoList(std::move(final_upstream_request), upstream_requests_); } -void Filter::onUpstreamHeaders(uint64_t response_code, Http::HeaderMapPtr&& headers, +void Filter::onUpstreamHeaders(uint64_t response_code, Http::ResponseHeaderMapPtr&& headers, UpstreamRequest& upstream_request, bool end_stream) { ENVOY_STREAM_LOG(debug, "upstream headers complete: end_stream={}", *callbacks_, end_stream); @@ -1261,7 +1261,8 @@ void Filter::onUpstreamData(Buffer::Instance& data, UpstreamRequest& upstream_re callbacks_->encodeData(data, end_stream); } -void Filter::onUpstreamTrailers(Http::HeaderMapPtr&& trailers, UpstreamRequest& upstream_request) { +void Filter::onUpstreamTrailers(Http::ResponseTrailerMapPtr&& trailers, + UpstreamRequest& upstream_request) { // This should be true because when we saw headers we either reset the stream // (hence wouldn't have made it to onUpstreamTrailers) or all other in-flight // streams. @@ -1510,7 +1511,7 @@ void Filter::UpstreamRequest::decodeHeaders(Http::ResponseHeaderMapPtr&& headers awaiting_headers_ = false; if (!parent_.config_.upstream_logs_.empty()) { - upstream_headers_ = Http::HeaderMapImpl::create(*headers); + upstream_headers_ = Http::createHeaderMap(*headers); } const uint64_t response_code = Http::Utility::getResponseStatus(*headers); stream_info_.response_code_ = static_cast(response_code); @@ -1530,7 +1531,7 @@ void Filter::UpstreamRequest::decodeTrailers(Http::ResponseTrailerMapPtr&& trail maybeEndDecode(true); if (!parent_.config_.upstream_logs_.empty()) { - upstream_trailers_ = Http::HeaderMapImpl::create(*trailers); + upstream_trailers_ = Http::createHeaderMap(*trailers); } parent_.onUpstreamTrailers(std::move(trailers), *this); } @@ -1585,7 +1586,7 @@ void Filter::UpstreamRequest::encodeData(Buffer::Instance& data, bool end_stream } } -void Filter::UpstreamRequest::encodeTrailers(const Http::HeaderMap& trailers) { +void Filter::UpstreamRequest::encodeTrailers(const Http::RequestTrailerMap& trailers) { ASSERT(!encode_complete_); encode_complete_ = true; encode_trailers_ = true; diff --git a/source/common/router/router.h b/source/common/router/router.h index f45b4a378f..efb26a18f6 100644 --- a/source/common/router/router.h +++ b/source/common/router/router.h @@ -250,9 +250,10 @@ class Filter : Logger::Loggable, void onDestroy() override; // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; Http::FilterMetadataStatus decodeMetadata(Http::MetadataMap& metadata_map) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; @@ -375,7 +376,7 @@ class Filter : Logger::Loggable, void encodeHeaders(bool end_stream); void encodeData(Buffer::Instance& data, bool end_stream); - void encodeTrailers(const Http::HeaderMap& trailers); + void encodeTrailers(const Http::RequestTrailerMap& trailers); void encodeMetadata(Http::MetadataMapPtr&& metadata_map_ptr); void resetStream(); @@ -522,7 +523,7 @@ class Filter : Logger::Loggable, void onPerTryTimeout(UpstreamRequest& upstream_request); void onRequestComplete(); void onResponseTimeout(); - void onUpstream100ContinueHeaders(Http::HeaderMapPtr&& headers, + void onUpstream100ContinueHeaders(Http::ResponseHeaderMapPtr&& headers, UpstreamRequest& upstream_request); // Handle an upstream request aborted due to a local timeout. void onSoftPerTryTimeout(); @@ -533,10 +534,11 @@ class Filter : Logger::Loggable, // downstream if appropriate. void onUpstreamAbort(Http::Code code, StreamInfo::ResponseFlag response_flag, absl::string_view body, bool dropped, absl::string_view details); - void onUpstreamHeaders(uint64_t response_code, Http::HeaderMapPtr&& headers, + void onUpstreamHeaders(uint64_t response_code, Http::ResponseHeaderMapPtr&& headers, UpstreamRequest& upstream_request, bool end_stream); void onUpstreamData(Buffer::Instance& data, UpstreamRequest& upstream_request, bool end_stream); - void onUpstreamTrailers(Http::HeaderMapPtr&& trailers, UpstreamRequest& upstream_request); + void onUpstreamTrailers(Http::ResponseTrailerMapPtr&& trailers, + UpstreamRequest& upstream_request); void onUpstreamMetadata(Http::MetadataMapPtr&& metadata_map); void onUpstreamComplete(UpstreamRequest& upstream_request); void onUpstreamReset(Http::StreamResetReason reset_reason, absl::string_view transport_failure, @@ -578,8 +580,8 @@ class Filter : Logger::Loggable, // response forwarded downstream UpstreamRequest* final_upstream_request_; bool grpc_request_{}; - Http::HeaderMap* downstream_headers_{}; - Http::HeaderMap* downstream_trailers_{}; + Http::RequestHeaderMap* downstream_headers_{}; + Http::RequestTrailerMap* downstream_trailers_{}; MonotonicTime downstream_request_complete_time_; uint32_t retry_shadow_buffer_limit_{std::numeric_limits::max()}; MetadataMatchCriteriaConstPtr metadata_match_; diff --git a/source/common/router/shadow_writer_impl.cc b/source/common/router/shadow_writer_impl.cc index 73906beb91..bb27182d00 100644 --- a/source/common/router/shadow_writer_impl.cc +++ b/source/common/router/shadow_writer_impl.cc @@ -11,7 +11,7 @@ namespace Envoy { namespace Router { -void ShadowWriterImpl::shadow(const std::string& cluster, Http::MessagePtr&& request, +void ShadowWriterImpl::shadow(const std::string& cluster, Http::RequestMessagePtr&& request, std::chrono::milliseconds timeout) { // It's possible that the cluster specified in the route configuration no longer exists due // to a CDS removal. Check that it still exists before shadowing. diff --git a/source/common/router/shadow_writer_impl.h b/source/common/router/shadow_writer_impl.h index 72da4bc0a7..a5b193566d 100644 --- a/source/common/router/shadow_writer_impl.h +++ b/source/common/router/shadow_writer_impl.h @@ -20,11 +20,11 @@ class ShadowWriterImpl : Logger::Loggable, ShadowWriterImpl(Upstream::ClusterManager& cm) : cm_(cm) {} // Router::ShadowWriter - void shadow(const std::string& cluster, Http::MessagePtr&& request, + void shadow(const std::string& cluster, Http::RequestMessagePtr&& request, std::chrono::milliseconds timeout) override; // Http::AsyncClient::Callbacks - void onSuccess(Http::MessagePtr&&) override {} + void onSuccess(Http::ResponseMessagePtr&&) override {} void onFailure(Http::AsyncClient::FailureReason) override {} private: diff --git a/source/common/upstream/health_checker_impl.cc b/source/common/upstream/health_checker_impl.cc index 9bfd5536b1..d12be6acde 100644 --- a/source/common/upstream/health_checker_impl.cc +++ b/source/common/upstream/health_checker_impl.cc @@ -231,7 +231,7 @@ void HttpHealthCheckerImpl::HttpActiveHealthCheckSession::onInterval() { Http::RequestEncoder* request_encoder = &client_->newStream(*this); request_encoder->getStream().addCallbacks(*this); - const auto request_headers = Http::HeaderMapImpl::create( + const auto request_headers = Http::createHeaderMap( {{Http::Headers::get().Method, "GET"}, {Http::Headers::get().Host, hostname_}, {Http::Headers::get().Path, parent_.path_}, diff --git a/source/common/upstream/health_discovery_service.cc b/source/common/upstream/health_discovery_service.cc index 5e7c86d820..62964e84c1 100644 --- a/source/common/upstream/health_discovery_service.cc +++ b/source/common/upstream/health_discovery_service.cc @@ -127,11 +127,11 @@ envoy::service::health::v3::HealthCheckRequestOrEndpointHealthResponse HdsDelega return response; } -void HdsDelegate::onCreateInitialMetadata(Http::HeaderMap& metadata) { +void HdsDelegate::onCreateInitialMetadata(Http::RequestHeaderMap& metadata) { UNREFERENCED_PARAMETER(metadata); } -void HdsDelegate::onReceiveInitialMetadata(Http::HeaderMapPtr&& metadata) { +void HdsDelegate::onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&& metadata) { UNREFERENCED_PARAMETER(metadata); } @@ -201,7 +201,7 @@ void HdsDelegate::onReceiveMessage( } } -void HdsDelegate::onReceiveTrailingMetadata(Http::HeaderMapPtr&& metadata) { +void HdsDelegate::onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&& metadata) { UNREFERENCED_PARAMETER(metadata); } diff --git a/source/common/upstream/health_discovery_service.h b/source/common/upstream/health_discovery_service.h index c38bc4ea56..079c22448d 100644 --- a/source/common/upstream/health_discovery_service.h +++ b/source/common/upstream/health_discovery_service.h @@ -125,11 +125,11 @@ class HdsDelegate : Grpc::AsyncStreamCallbacks&& message) override; - void onReceiveTrailingMetadata(Http::HeaderMapPtr&& metadata) override; + void onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&& metadata) override; void onRemoteClose(Grpc::Status::GrpcStatus status, const std::string& message) override; envoy::service::health::v3::HealthCheckRequestOrEndpointHealthResponse sendResponse(); diff --git a/source/common/upstream/load_stats_reporter.cc b/source/common/upstream/load_stats_reporter.cc index 3fc194c360..14c707e1c6 100644 --- a/source/common/upstream/load_stats_reporter.cc +++ b/source/common/upstream/load_stats_reporter.cc @@ -112,11 +112,11 @@ void LoadStatsReporter::handleFailure() { setRetryTimer(); } -void LoadStatsReporter::onCreateInitialMetadata(Http::HeaderMap& metadata) { +void LoadStatsReporter::onCreateInitialMetadata(Http::RequestHeaderMap& metadata) { UNREFERENCED_PARAMETER(metadata); } -void LoadStatsReporter::onReceiveInitialMetadata(Http::HeaderMapPtr&& metadata) { +void LoadStatsReporter::onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&& metadata) { UNREFERENCED_PARAMETER(metadata); } @@ -170,7 +170,7 @@ void LoadStatsReporter::startLoadReportPeriod() { DurationUtil::durationToMilliseconds(message_->load_reporting_interval()))); } -void LoadStatsReporter::onReceiveTrailingMetadata(Http::HeaderMapPtr&& metadata) { +void LoadStatsReporter::onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&& metadata) { UNREFERENCED_PARAMETER(metadata); } diff --git a/source/common/upstream/load_stats_reporter.h b/source/common/upstream/load_stats_reporter.h index e1817ae998..3334abeec7 100644 --- a/source/common/upstream/load_stats_reporter.h +++ b/source/common/upstream/load_stats_reporter.h @@ -35,11 +35,11 @@ class LoadStatsReporter Event::Dispatcher& dispatcher); // Grpc::AsyncStreamCallbacks - void onCreateInitialMetadata(Http::HeaderMap& metadata) override; - void onReceiveInitialMetadata(Http::HeaderMapPtr&& metadata) override; + void onCreateInitialMetadata(Http::RequestHeaderMap& metadata) override; + void onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&& metadata) override; void onReceiveMessage( std::unique_ptr&& message) override; - void onReceiveTrailingMetadata(Http::HeaderMapPtr&& metadata) override; + void onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&& metadata) override; void onRemoteClose(Grpc::Status::GrpcStatus status, const std::string& message) override; // TODO(htuch): Make this configurable or some static. diff --git a/source/extensions/access_loggers/grpc/grpc_access_log_impl.h b/source/extensions/access_loggers/grpc/grpc_access_log_impl.h index 8ecbd7e2e0..4dd4b59485 100644 --- a/source/extensions/access_loggers/grpc/grpc_access_log_impl.h +++ b/source/extensions/access_loggers/grpc/grpc_access_log_impl.h @@ -85,11 +85,11 @@ class GrpcAccessLoggerImpl : public GrpcAccessLogger { LocalStream(GrpcAccessLoggerImpl& parent) : parent_(parent) {} // Grpc::AsyncStreamCallbacks - void onCreateInitialMetadata(Http::HeaderMap&) override {} - void onReceiveInitialMetadata(Http::HeaderMapPtr&&) override {} + void onCreateInitialMetadata(Http::RequestHeaderMap&) override {} + void onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&&) override {} void onReceiveMessage( std::unique_ptr&&) override {} - void onReceiveTrailingMetadata(Http::HeaderMapPtr&&) override {} + void onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&&) override {} void onRemoteClose(Grpc::Status::GrpcStatus status, const std::string& message) override; GrpcAccessLoggerImpl& parent_; diff --git a/source/extensions/common/aws/signer.h b/source/extensions/common/aws/signer.h index 1673a52972..02514833cd 100644 --- a/source/extensions/common/aws/signer.h +++ b/source/extensions/common/aws/signer.h @@ -18,14 +18,14 @@ class Signer { * @param sign_body include the message body in the signature. The body must be fully buffered. * @throws EnvoyException if the request cannot be signed. */ - virtual void sign(Http::Message& message, bool sign_body) PURE; + virtual void sign(Http::RequestMessage& message, bool sign_body) PURE; /** * Sign an AWS request. * @param headers AWS API request headers. * @throws EnvoyException if the request cannot be signed. */ - virtual void sign(Http::HeaderMap& headers) PURE; + virtual void sign(Http::RequestHeaderMap& headers) PURE; }; using SignerPtr = std::unique_ptr; diff --git a/source/extensions/common/aws/signer_impl.cc b/source/extensions/common/aws/signer_impl.cc index e2bae8da28..43d198f864 100644 --- a/source/extensions/common/aws/signer_impl.cc +++ b/source/extensions/common/aws/signer_impl.cc @@ -17,17 +17,17 @@ namespace Extensions { namespace Common { namespace Aws { -void SignerImpl::sign(Http::Message& message, bool sign_body) { +void SignerImpl::sign(Http::RequestMessage& message, bool sign_body) { const auto content_hash = createContentHash(message, sign_body); auto& headers = message.headers(); sign(headers, content_hash); } -void SignerImpl::sign(Http::HeaderMap& headers) { +void SignerImpl::sign(Http::RequestHeaderMap& headers) { sign(headers, SignatureConstants::get().HashedEmptyString); } -void SignerImpl::sign(Http::HeaderMap& headers, const std::string& content_hash) { +void SignerImpl::sign(Http::RequestHeaderMap& headers, const std::string& content_hash) { const auto& credentials = credentials_provider_->getCredentials(); if (!credentials.accessKeyId() || !credentials.secretAccessKey()) { // Empty or "anonymous" credentials are a valid use-case for non-production environments. @@ -68,7 +68,7 @@ void SignerImpl::sign(Http::HeaderMap& headers, const std::string& content_hash) headers.addCopy(Http::Headers::get().Authorization, authorization_header); } -std::string SignerImpl::createContentHash(Http::Message& message, bool sign_body) const { +std::string SignerImpl::createContentHash(Http::RequestMessage& message, bool sign_body) const { if (!sign_body) { return SignatureConstants::get().HashedEmptyString; } diff --git a/source/extensions/common/aws/signer_impl.h b/source/extensions/common/aws/signer_impl.h index 16064ff322..0fb56eef2d 100644 --- a/source/extensions/common/aws/signer_impl.h +++ b/source/extensions/common/aws/signer_impl.h @@ -50,11 +50,11 @@ class SignerImpl : public Signer, public Logger::Loggable { time_source_(time_source), long_date_formatter_(SignatureConstants::get().LongDateFormat), short_date_formatter_(SignatureConstants::get().ShortDateFormat) {} - void sign(Http::Message& message, bool sign_body = false) override; - void sign(Http::HeaderMap& headers) override; + void sign(Http::RequestMessage& message, bool sign_body = false) override; + void sign(Http::RequestHeaderMap& headers) override; private: - std::string createContentHash(Http::Message& message, bool sign_body) const; + std::string createContentHash(Http::RequestMessage& message, bool sign_body) const; std::string createCredentialScope(absl::string_view short_date) const; @@ -69,7 +69,7 @@ class SignerImpl : public Signer, public Logger::Loggable { const std::map& canonical_headers, absl::string_view signature) const; - void sign(Http::HeaderMap& headers, const std::string& content_hash); + void sign(Http::RequestHeaderMap& headers, const std::string& content_hash); const std::string service_name_; const std::string region_; diff --git a/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.h b/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.h index 8516c09942..cdd7deb026 100644 --- a/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.h +++ b/source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.h @@ -51,7 +51,7 @@ class GrpcClientImpl : public Client, public ExtAuthzAsyncCallbacks { Tracing::Span& parent_span) override; // Grpc::AsyncRequestCallbacks - void onCreateInitialMetadata(Http::HeaderMap&) override {} + void onCreateInitialMetadata(Http::RequestHeaderMap&) override {} void onSuccess(std::unique_ptr&& response, Tracing::Span& span) override; void onFailure(Grpc::Status::GrpcStatus status, const std::string& message, diff --git a/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc b/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc index 2d114ff099..18a2a5571d 100644 --- a/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc +++ b/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc @@ -22,8 +22,8 @@ namespace { // Static header map used for creating authorization requests. const Http::HeaderMap& lengthZeroHeader() { - static const auto headers = - Http::HeaderMapImpl::create({{Http::Headers::get().ContentLength, std::to_string(0)}}); + static const auto headers = Http::createHeaderMap( + {{Http::Headers::get().ContentLength, std::to_string(0)}}); return *headers; } @@ -188,13 +188,13 @@ void RawHttpClientImpl::check(RequestCallbacks& callbacks, time_source_.systemTime()); span_->setTag(Tracing::Tags::get().UpstreamCluster, config_->cluster()); - Http::HeaderMapPtr headers; + Http::RequestHeaderMapPtr headers; const uint64_t request_length = request.attributes().request().http().body().size(); if (request_length > 0) { - headers = Http::HeaderMapImpl::create( + headers = Http::createHeaderMap( {{Http::Headers::get().ContentLength, std::to_string(request_length)}}); } else { - headers = Http::HeaderMapImpl::create(lengthZeroHeader()); + headers = Http::createHeaderMap(lengthZeroHeader()); } for (const auto& header : request.attributes().request().http().headers()) { @@ -217,7 +217,8 @@ void RawHttpClientImpl::check(RequestCallbacks& callbacks, headers->setReference(header_to_add.first, header_to_add.second); } - Http::MessagePtr message = std::make_unique(std::move(headers)); + Http::RequestMessagePtr message = + std::make_unique(std::move(headers)); if (request_length > 0) { message->body() = std::make_unique(request.attributes().request().http().body()); @@ -243,7 +244,7 @@ void RawHttpClientImpl::check(RequestCallbacks& callbacks, } } -void RawHttpClientImpl::onSuccess(Http::MessagePtr&& message) { +void RawHttpClientImpl::onSuccess(Http::ResponseMessagePtr&& message) { callbacks_->onComplete(toResponse(std::move(message))); span_->finishSpan(); callbacks_ = nullptr; @@ -259,7 +260,7 @@ void RawHttpClientImpl::onFailure(Http::AsyncClient::FailureReason reason) { span_ = nullptr; } -ResponsePtr RawHttpClientImpl::toResponse(Http::MessagePtr message) { +ResponsePtr RawHttpClientImpl::toResponse(Http::ResponseMessagePtr message) { // Set an error status if parsing status code fails. A Forbidden response is sent to the client // if the filter has not been configured with failure_mode_allow. uint64_t status_code{}; diff --git a/source/extensions/filters/common/ext_authz/ext_authz_http_impl.h b/source/extensions/filters/common/ext_authz/ext_authz_http_impl.h index 79d89ef46f..9ad475179f 100644 --- a/source/extensions/filters/common/ext_authz/ext_authz_http_impl.h +++ b/source/extensions/filters/common/ext_authz/ext_authz_http_impl.h @@ -150,11 +150,11 @@ class RawHttpClientImpl : public Client, Tracing::Span&) override; // Http::AsyncClient::Callbacks - void onSuccess(Http::MessagePtr&& message) override; + void onSuccess(Http::ResponseMessagePtr&& message) override; void onFailure(Http::AsyncClient::FailureReason reason) override; private: - ResponsePtr toResponse(Http::MessagePtr message); + ResponsePtr toResponse(Http::ResponseMessagePtr message); Upstream::ClusterManager& cm_; ClientConfigSharedPtr config_; Http::AsyncClient::Request* request_{}; diff --git a/source/extensions/filters/common/ratelimit/ratelimit_impl.h b/source/extensions/filters/common/ratelimit/ratelimit_impl.h index fc1e32c969..f6daf85b14 100644 --- a/source/extensions/filters/common/ratelimit/ratelimit_impl.h +++ b/source/extensions/filters/common/ratelimit/ratelimit_impl.h @@ -60,7 +60,7 @@ class GrpcClientImpl : public Client, Tracing::Span& parent_span) override; // Grpc::AsyncRequestCallbacks - void onCreateInitialMetadata(Http::HeaderMap&) override {} + void onCreateInitialMetadata(Http::RequestHeaderMap&) override {} void onSuccess(std::unique_ptr&& response, Tracing::Span& span) override; void onFailure(Grpc::Status::GrpcStatus status, const std::string& message, diff --git a/source/extensions/filters/http/adaptive_concurrency/adaptive_concurrency_filter.cc b/source/extensions/filters/http/adaptive_concurrency/adaptive_concurrency_filter.cc index 30ace060dd..012f81e54d 100644 --- a/source/extensions/filters/http/adaptive_concurrency/adaptive_concurrency_filter.cc +++ b/source/extensions/filters/http/adaptive_concurrency/adaptive_concurrency_filter.cc @@ -29,7 +29,7 @@ AdaptiveConcurrencyFilter::AdaptiveConcurrencyFilter( AdaptiveConcurrencyFilterConfigSharedPtr config, ConcurrencyControllerSharedPtr controller) : config_(std::move(config)), controller_(std::move(controller)) {} -Http::FilterHeadersStatus AdaptiveConcurrencyFilter::decodeHeaders(Http::HeaderMap&, bool) { +Http::FilterHeadersStatus AdaptiveConcurrencyFilter::decodeHeaders(Http::RequestHeaderMap&, bool) { // In addition to not sampling if the filter is disabled, health checks should also not be sampled // by the concurrency controller since they may potentially bias the sample aggregate to lower // latency measurements. diff --git a/source/extensions/filters/http/adaptive_concurrency/adaptive_concurrency_filter.h b/source/extensions/filters/http/adaptive_concurrency/adaptive_concurrency_filter.h index c85ee6bf2c..dd375bf2d5 100644 --- a/source/extensions/filters/http/adaptive_concurrency/adaptive_concurrency_filter.h +++ b/source/extensions/filters/http/adaptive_concurrency/adaptive_concurrency_filter.h @@ -58,7 +58,7 @@ class AdaptiveConcurrencyFilter : public Http::PassThroughFilter, ConcurrencyControllerSharedPtr controller); // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap&, bool) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool) override; // Http::StreamEncoderFilter void encodeComplete() override; diff --git a/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.cc b/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.cc index 4ddcd094e5..ba95327171 100644 --- a/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.cc +++ b/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.cc @@ -22,7 +22,7 @@ FilterStats Filter::generateStats(const std::string& prefix, Stats::Scope& scope return {ALL_AWS_REQUEST_SIGNING_FILTER_STATS(POOL_COUNTER_PREFIX(scope, final_prefix))}; } -Http::FilterHeadersStatus Filter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { try { config_->signer().sign(headers); config_->stats().signing_added_.inc(); diff --git a/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h b/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h index eb0fe9f34d..a2c8c5a462 100644 --- a/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h +++ b/source/extensions/filters/http/aws_request_signing/aws_request_signing_filter.h @@ -74,7 +74,8 @@ class Filter : public Http::PassThroughDecoderFilter, Logger::Loggable config_; diff --git a/source/extensions/filters/http/buffer/buffer_filter.cc b/source/extensions/filters/http/buffer/buffer_filter.cc index 2417e53e61..eeb4c81304 100644 --- a/source/extensions/filters/http/buffer/buffer_filter.cc +++ b/source/extensions/filters/http/buffer/buffer_filter.cc @@ -56,7 +56,8 @@ void BufferFilter::initConfig() { settings_ = route_local ? route_local : settings_; } -Http::FilterHeadersStatus BufferFilter::decodeHeaders(Http::HeaderMap& headers, bool end_stream) { +Http::FilterHeadersStatus BufferFilter::decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) { if (end_stream) { // If this is a header-only request, we don't need to do any buffering. return Http::FilterHeadersStatus::Continue; @@ -86,7 +87,7 @@ Http::FilterDataStatus BufferFilter::decodeData(Buffer::Instance& data, bool end return Http::FilterDataStatus::StopIterationAndBuffer; } -Http::FilterTrailersStatus BufferFilter::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus BufferFilter::decodeTrailers(Http::RequestTrailerMap&) { maybeAddContentLength(); return Http::FilterTrailersStatus::Continue; diff --git a/source/extensions/filters/http/buffer/buffer_filter.h b/source/extensions/filters/http/buffer/buffer_filter.h index ab166b7ec0..53e30c228d 100644 --- a/source/extensions/filters/http/buffer/buffer_filter.h +++ b/source/extensions/filters/http/buffer/buffer_filter.h @@ -54,9 +54,10 @@ class BufferFilter : public Http::StreamDecoderFilter { void onDestroy() override {} // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; private: diff --git a/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc b/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc index 12c1bb807f..68457493a7 100644 --- a/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc +++ b/source/extensions/filters/http/cache/simple_http_cache/simple_http_cache.cc @@ -51,7 +51,7 @@ class SimpleInsertContext : public InsertContext { void insertHeaders(const Http::HeaderMap& response_headers, bool end_stream) override { ASSERT(!committed_); - response_headers_ = Http::HeaderMapImpl::create(response_headers); + response_headers_ = Http::createHeaderMap(response_headers); if (end_stream) { commit(); } @@ -81,7 +81,7 @@ class SimpleInsertContext : public InsertContext { } Key key_; - Http::HeaderMapImplPtr response_headers_; + Http::ResponseHeaderMapPtr response_headers_; SimpleHttpCache& cache_; Buffer::OwnedImpl body_; bool committed_ = false; @@ -107,8 +107,9 @@ SimpleHttpCache::Entry SimpleHttpCache::lookup(const LookupRequest& request) { return Entry{}; } ASSERT(iter->second.response_headers_); - return SimpleHttpCache::Entry{Http::HeaderMapImpl::create(*iter->second.response_headers_), - iter->second.body_}; + return SimpleHttpCache::Entry{ + Http::createHeaderMap(*iter->second.response_headers_), + iter->second.body_}; } void SimpleHttpCache::insert(const Key& key, Http::HeaderMapPtr&& response_headers, diff --git a/source/extensions/filters/http/common/jwks_fetcher.cc b/source/extensions/filters/http/common/jwks_fetcher.cc index 5693b3127f..90bf7cf617 100644 --- a/source/extensions/filters/http/common/jwks_fetcher.cc +++ b/source/extensions/filters/http/common/jwks_fetcher.cc @@ -50,7 +50,7 @@ class JwksFetcherImpl : public JwksFetcher, return; } - Http::MessagePtr message = Http::Utility::prepareHeaders(uri); + Http::RequestMessagePtr message = Http::Utility::prepareHeaders(uri); message->headers().setReferenceMethod(Http::Headers::get().MethodValues.Get); ENVOY_LOG(debug, "fetch pubkey from [uri = {}]: start", uri_->uri()); auto options = Http::AsyncClient::RequestOptions() @@ -63,7 +63,7 @@ class JwksFetcherImpl : public JwksFetcher, } // HTTP async receive methods - void onSuccess(Http::MessagePtr&& response) override { + void onSuccess(Http::ResponseMessagePtr&& response) override { ENVOY_LOG(trace, "{}", __func__); complete_ = true; const uint64_t status_code = Http::Utility::getResponseStatus(response->headers()); diff --git a/source/extensions/filters/http/common/pass_through_filter.h b/source/extensions/filters/http/common/pass_through_filter.h index 30d3e4e44d..027a73f8f1 100644 --- a/source/extensions/filters/http/common/pass_through_filter.h +++ b/source/extensions/filters/http/common/pass_through_filter.h @@ -12,13 +12,13 @@ class PassThroughDecoderFilter : public virtual StreamDecoderFilter { void onDestroy() override {} // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap&, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool) override { return Http::FilterHeadersStatus::Continue; } Http::FilterDataStatus decodeData(Buffer::Instance&, bool) override { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { return Http::FilterTrailersStatus::Continue; } void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override { @@ -36,16 +36,16 @@ class PassThroughEncoderFilter : public virtual StreamEncoderFilter { void onDestroy() override {} // Http::StreamEncoderFilter - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override { + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override { return Http::FilterHeadersStatus::Continue; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap&, bool) override { + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap&, bool) override { return Http::FilterHeadersStatus::Continue; } Http::FilterDataStatus encodeData(Buffer::Instance&, bool) override { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap&) override { return Http::FilterTrailersStatus::Continue; } Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override { diff --git a/source/extensions/filters/http/cors/cors_filter.cc b/source/extensions/filters/http/cors/cors_filter.cc index a6702c1e56..34f2576aab 100644 --- a/source/extensions/filters/http/cors/cors_filter.cc +++ b/source/extensions/filters/http/cors/cors_filter.cc @@ -21,7 +21,7 @@ CorsFilter::CorsFilter(CorsFilterConfigSharedPtr config) // This handles the CORS preflight request as described in // https://www.w3.org/TR/cors/#resource-preflight-requests -Http::FilterHeadersStatus CorsFilter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus CorsFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { if (decoder_callbacks_->route() == nullptr || decoder_callbacks_->route()->routeEntry() == nullptr) { return Http::FilterHeadersStatus::Continue; @@ -64,7 +64,7 @@ Http::FilterHeadersStatus CorsFilter::decodeHeaders(Http::HeaderMap& headers, bo return Http::FilterHeadersStatus::Continue; } - Http::HeaderMapPtr response_headers{Http::HeaderMapImpl::create( + auto response_headers{Http::createHeaderMap( {{Http::Headers::get().Status, std::to_string(enumToInt(Http::Code::OK))}})}; response_headers->setAccessControlAllowOrigin(origin_->value().getStringView()); @@ -93,7 +93,7 @@ Http::FilterHeadersStatus CorsFilter::decodeHeaders(Http::HeaderMap& headers, bo // This handles simple CORS requests as described in // https://www.w3.org/TR/cors/#resource-requests -Http::FilterHeadersStatus CorsFilter::encodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus CorsFilter::encodeHeaders(Http::ResponseHeaderMap& headers, bool) { if (!is_cors_request_) { return Http::FilterHeadersStatus::Continue; } diff --git a/source/extensions/filters/http/cors/cors_filter.h b/source/extensions/filters/http/cors/cors_filter.h index 042c1fb10c..6603469055 100644 --- a/source/extensions/filters/http/cors/cors_filter.h +++ b/source/extensions/filters/http/cors/cors_filter.h @@ -50,24 +50,26 @@ class CorsFilter : public Http::StreamFilter { void onDestroy() override {} // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance&, bool) override { return Http::FilterDataStatus::Continue; }; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { return Http::FilterTrailersStatus::Continue; }; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; // Http::StreamEncoderFilter - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override { + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override { return Http::FilterHeadersStatus::Continue; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus encodeData(Buffer::Instance&, bool) override { return Http::FilterDataStatus::Continue; }; - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap&) override { return Http::FilterTrailersStatus::Continue; }; Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override { diff --git a/source/extensions/filters/http/csrf/csrf_filter.cc b/source/extensions/filters/http/csrf/csrf_filter.cc index 1f113b60b3..e60fba08ad 100644 --- a/source/extensions/filters/http/csrf/csrf_filter.cc +++ b/source/extensions/filters/http/csrf/csrf_filter.cc @@ -74,7 +74,7 @@ CsrfFilterConfig::CsrfFilterConfig( CsrfFilter::CsrfFilter(const CsrfFilterConfigSharedPtr config) : config_(config) {} -Http::FilterHeadersStatus CsrfFilter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus CsrfFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { determinePolicy(); if (!policy_->enabled() && !policy_->shadowEnabled()) { diff --git a/source/extensions/filters/http/csrf/csrf_filter.h b/source/extensions/filters/http/csrf/csrf_filter.h index 452d45b96e..0c833e9330 100644 --- a/source/extensions/filters/http/csrf/csrf_filter.h +++ b/source/extensions/filters/http/csrf/csrf_filter.h @@ -96,11 +96,12 @@ class CsrfFilter : public Http::StreamDecoderFilter { void onDestroy() override {} // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance&, bool) override { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { return Http::FilterTrailersStatus::Continue; } void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override { diff --git a/source/extensions/filters/http/dynamic_forward_proxy/proxy_filter.cc b/source/extensions/filters/http/dynamic_forward_proxy/proxy_filter.cc index 5e8be35e58..1445d1ebb0 100644 --- a/source/extensions/filters/http/dynamic_forward_proxy/proxy_filter.cc +++ b/source/extensions/filters/http/dynamic_forward_proxy/proxy_filter.cc @@ -40,7 +40,7 @@ void ProxyFilter::onDestroy() { circuit_breaker_.reset(); } -Http::FilterHeadersStatus ProxyFilter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus ProxyFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { Router::RouteConstSharedPtr route = decoder_callbacks_->route(); const Router::RouteEntry* route_entry; if (!route || !(route_entry = route->routeEntry())) { diff --git a/source/extensions/filters/http/dynamic_forward_proxy/proxy_filter.h b/source/extensions/filters/http/dynamic_forward_proxy/proxy_filter.h index 9b5aa4232b..8a786d14d7 100644 --- a/source/extensions/filters/http/dynamic_forward_proxy/proxy_filter.h +++ b/source/extensions/filters/http/dynamic_forward_proxy/proxy_filter.h @@ -50,7 +50,8 @@ class ProxyFilter ProxyFilter(const ProxyFilterConfigSharedPtr& config) : config_(config) {} // Http::PassThroughDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; void onDestroy() override; // Extensions::Common::DynamicForwardProxy::DnsCache::LoadDnsCacheEntryCallbacks diff --git a/source/extensions/filters/http/dynamo/dynamo_filter.cc b/source/extensions/filters/http/dynamo/dynamo_filter.cc index aaaf211a7a..de95e9139f 100644 --- a/source/extensions/filters/http/dynamo/dynamo_filter.cc +++ b/source/extensions/filters/http/dynamo/dynamo_filter.cc @@ -23,7 +23,7 @@ namespace Extensions { namespace HttpFilters { namespace Dynamo { -Http::FilterHeadersStatus DynamoFilter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus DynamoFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { if (enabled_) { start_decode_ = time_source_.monotonicTime(); operation_ = RequestParser::parseOperation(headers); @@ -46,7 +46,7 @@ Http::FilterDataStatus DynamoFilter::decodeData(Buffer::Instance& data, bool end } } -Http::FilterTrailersStatus DynamoFilter::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus DynamoFilter::decodeTrailers(Http::RequestTrailerMap&) { if (enabled_) { Buffer::OwnedImpl empty; onDecodeComplete(empty); @@ -95,7 +95,8 @@ void DynamoFilter::onEncodeComplete(const Buffer::Instance& data) { } } -Http::FilterHeadersStatus DynamoFilter::encodeHeaders(Http::HeaderMap& headers, bool end_stream) { +Http::FilterHeadersStatus DynamoFilter::encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) { Http::FilterHeadersStatus status = Http::FilterHeadersStatus::Continue; if (enabled_) { response_headers_ = &headers; @@ -124,7 +125,7 @@ Http::FilterDataStatus DynamoFilter::encodeData(Buffer::Instance& data, bool end } } -Http::FilterTrailersStatus DynamoFilter::encodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus DynamoFilter::encodeTrailers(Http::ResponseTrailerMap&) { if (enabled_) { Buffer::OwnedImpl empty; onEncodeComplete(empty); diff --git a/source/extensions/filters/http/dynamo/dynamo_filter.h b/source/extensions/filters/http/dynamo/dynamo_filter.h index 8702444a11..ac5198c580 100644 --- a/source/extensions/filters/http/dynamo/dynamo_filter.h +++ b/source/extensions/filters/http/dynamo/dynamo_filter.h @@ -34,20 +34,21 @@ class DynamoFilter : public Http::StreamFilter { void onDestroy() override {} // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override { decoder_callbacks_ = &callbacks; } // Http::StreamEncoderFilter - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override { + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override { return Http::FilterHeadersStatus::Continue; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap&, bool) override; + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap&, bool) override; Http::FilterDataStatus encodeData(Buffer::Instance&, bool) override; - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap&) override; + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap&) override; Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override { return Http::FilterMetadataStatus::Continue; } diff --git a/source/extensions/filters/http/ext_authz/ext_authz.cc b/source/extensions/filters/http/ext_authz/ext_authz.cc index 8ee7c42fb7..2cc4f6e57b 100644 --- a/source/extensions/filters/http/ext_authz/ext_authz.cc +++ b/source/extensions/filters/http/ext_authz/ext_authz.cc @@ -88,7 +88,7 @@ void Filter::initiateCall(const Http::HeaderMap& headers) { initiating_call_ = false; } -Http::FilterHeadersStatus Filter::decodeHeaders(Http::HeaderMap& headers, bool end_stream) { +Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, bool end_stream) { if (!config_->filterEnabled()) { return Http::FilterHeadersStatus::Continue; } @@ -133,7 +133,7 @@ Http::FilterDataStatus Filter::decodeData(Buffer::Instance& data, bool end_strea return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus Filter::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus Filter::decodeTrailers(Http::RequestTrailerMap&) { if (buffer_data_) { if (filter_return_ != FilterReturn::StopDecoding) { ENVOY_STREAM_LOG(debug, "ext_authz filter finished buffering the request", *callbacks_); diff --git a/source/extensions/filters/http/ext_authz/ext_authz.h b/source/extensions/filters/http/ext_authz/ext_authz.h index e1e4ea3c36..823e45a098 100644 --- a/source/extensions/filters/http/ext_authz/ext_authz.h +++ b/source/extensions/filters/http/ext_authz/ext_authz.h @@ -209,9 +209,10 @@ class Filter : public Logger::Loggable, void onDestroy() override; // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; // ExtAuthz::RequestCallbacks diff --git a/source/extensions/filters/http/fault/fault_filter.cc b/source/extensions/filters/http/fault/fault_filter.cc index 25b405929a..5e921f2388 100644 --- a/source/extensions/filters/http/fault/fault_filter.cc +++ b/source/extensions/filters/http/fault/fault_filter.cc @@ -102,7 +102,7 @@ FaultFilter::~FaultFilter() { // followed by an abort or inject just a delay or abort. In this callback, // if we inject a delay, then we will inject the abort in the delay timer // callback. -Http::FilterHeadersStatus FaultFilter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus FaultFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { // Route-level configuration overrides filter-level configuration // NOTE: We should not use runtime when reading from route-level // faults. In other words, runtime is supported only when faults are @@ -318,7 +318,7 @@ Http::FilterDataStatus FaultFilter::decodeData(Buffer::Instance&, bool) { return Http::FilterDataStatus::StopIterationAndWatermark; } -Http::FilterTrailersStatus FaultFilter::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus FaultFilter::decodeTrailers(Http::RequestTrailerMap&) { return delay_timer_ == nullptr ? Http::FilterTrailersStatus::Continue : Http::FilterTrailersStatus::StopIteration; } @@ -413,7 +413,7 @@ Http::FilterDataStatus FaultFilter::encodeData(Buffer::Instance& data, bool end_ return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus FaultFilter::encodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus FaultFilter::encodeTrailers(Http::ResponseTrailerMap&) { if (response_limiter_ != nullptr) { return response_limiter_->onTrailers(); } diff --git a/source/extensions/filters/http/fault/fault_filter.h b/source/extensions/filters/http/fault/fault_filter.h index 142024441d..13f5ddf078 100644 --- a/source/extensions/filters/http/fault/fault_filter.h +++ b/source/extensions/filters/http/fault/fault_filter.h @@ -214,22 +214,23 @@ class FaultFilter : public Http::StreamFilter, Logger::Loggableserver_streaming()) { // When there is no body in a streaming response, a empty JSON array is // returned by default. Set the content type correctly. @@ -418,7 +417,7 @@ Http::FilterHeadersStatus JsonTranscoderFilter::encodeHeaders(Http::HeaderMap& h // In gRPC wire protocol, headers frame with end_stream is a trailers-only response. // The return value from encodeTrailers is ignored since it is always continue. - encodeTrailers(headers); + doTrailers(headers); return Http::FilterHeadersStatus::Continue; } @@ -461,17 +460,19 @@ Http::FilterDataStatus JsonTranscoderFilter::encodeData(Buffer::Instance& data, return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus JsonTranscoderFilter::encodeTrailers(Http::HeaderMap& trailers) { +// TODO(mattklein123): In future header refactor changes the HeaderMap interface will not have +// all of the O(1) headers so we will have to refactor this further. +void JsonTranscoderFilter::doTrailers(Http::HeaderMap& headers_or_trailers) { if (error_ || !transcoder_) { - return Http::FilterTrailersStatus::Continue; + return; } response_in_.finish(); const absl::optional grpc_status = - Grpc::Common::getGrpcStatus(trailers, true); - if (grpc_status && maybeConvertGrpcStatus(*grpc_status, trailers)) { - return Http::FilterTrailersStatus::Continue; + Grpc::Common::getGrpcStatus(headers_or_trailers, true); + if (grpc_status && maybeConvertGrpcStatus(*grpc_status, headers_or_trailers)) { + return; } Buffer::OwnedImpl data; @@ -483,12 +484,12 @@ Http::FilterTrailersStatus JsonTranscoderFilter::encodeTrailers(Http::HeaderMap& if (method_->server_streaming()) { // For streaming case, the headers are already sent, so just continue here. - return Http::FilterTrailersStatus::Continue; + return; } // If there was no previous headers frame, this |trailers| map is our |response_headers_|, // so there is no need to copy headers from one to the other. - bool is_trailers_only_response = response_headers_ == &trailers; + bool is_trailers_only_response = response_headers_ == &headers_or_trailers; if (!grpc_status || grpc_status.value() == Grpc::Status::WellKnownGrpcStatus::InvalidCode) { response_headers_->setStatus(enumToInt(Http::Code::ServiceUnavailable)); @@ -501,7 +502,7 @@ Http::FilterTrailersStatus JsonTranscoderFilter::encodeTrailers(Http::HeaderMap& if (!is_trailers_only_response) { // Copy the grpc-message header if it exists. - const Http::HeaderEntry* grpc_message_header = trailers.GrpcMessage(); + const Http::HeaderEntry* grpc_message_header = headers_or_trailers.GrpcMessage(); if (grpc_message_header) { response_headers_->setGrpcMessage(grpc_message_header->value().getStringView()); } @@ -514,7 +515,6 @@ Http::FilterTrailersStatus JsonTranscoderFilter::encodeTrailers(Http::HeaderMap& response_headers_->setContentLength( encoder_callbacks_->encodingBuffer() ? encoder_callbacks_->encodingBuffer()->length() : 0); - return Http::FilterTrailersStatus::Continue; } void JsonTranscoderFilter::setEncoderFilterCallbacks( diff --git a/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.h b/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.h index 3361f57592..455154e766 100644 --- a/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.h +++ b/source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.h @@ -119,18 +119,23 @@ class JsonTranscoderFilter : public Http::StreamFilter, public Logger::Loggable< JsonTranscoderFilter(JsonTranscoderConfig& config); // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; // Http::StreamEncoderFilter - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override { + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override { return Http::FilterHeadersStatus::Continue; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus encodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap& trailers) override { + doTrailers(trailers); + return Http::FilterTrailersStatus::Continue; + } Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override { return Http::FilterMetadataStatus::Continue; } @@ -144,6 +149,7 @@ class JsonTranscoderFilter : public Http::StreamFilter, public Logger::Loggable< void buildResponseFromHttpBodyOutput(Http::HeaderMap& response_headers, Buffer::Instance& data); bool maybeConvertGrpcStatus(Grpc::Status::GrpcStatus grpc_status, Http::HeaderMap& trailers); bool hasHttpBodyAsOutputType(); + void doTrailers(Http::HeaderMap& headers_or_trailers); JsonTranscoderConfig& config_; std::unique_ptr transcoder_; diff --git a/source/extensions/filters/http/grpc_stats/grpc_stats_filter.cc b/source/extensions/filters/http/grpc_stats/grpc_stats_filter.cc index 49bf996862..79f4477332 100644 --- a/source/extensions/filters/http/grpc_stats/grpc_stats_filter.cc +++ b/source/extensions/filters/http/grpc_stats/grpc_stats_filter.cc @@ -22,7 +22,7 @@ class GrpcStatsFilter : public Http::PassThroughFilter { explicit GrpcStatsFilter(Grpc::Context& context, bool emit_filter_state) : context_(context), emit_filter_state_(emit_filter_state) {} - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, bool) override { grpc_request_ = Grpc::Common::hasGrpcContentType(headers); if (grpc_request_) { cluster_ = decoder_callbacks_->clusterInfo(); @@ -44,7 +44,8 @@ class GrpcStatsFilter : public Http::PassThroughFilter { } return Http::FilterDataStatus::Continue; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap& headers, bool end_stream) override { + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) override { grpc_response_ = Grpc::Common::isGrpcResponseHeader(headers, end_stream); if (doStatTracking()) { context_.chargeStat(*cluster_, Grpc::Context::Protocol::Grpc, *request_names_, @@ -64,7 +65,7 @@ class GrpcStatsFilter : public Http::PassThroughFilter { } return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap& trailers) override { + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap& trailers) override { if (doStatTracking()) { context_.chargeStat(*cluster_, Grpc::Context::Protocol::Grpc, *request_names_, trailers.GrpcStatus()); diff --git a/source/extensions/filters/http/grpc_web/grpc_web_filter.cc b/source/extensions/filters/http/grpc_web/grpc_web_filter.cc index f032f9e250..dfec8ee5df 100644 --- a/source/extensions/filters/http/grpc_web/grpc_web_filter.cc +++ b/source/extensions/filters/http/grpc_web/grpc_web_filter.cc @@ -48,7 +48,7 @@ bool GrpcWebFilter::isGrpcWebRequest(const Http::HeaderMap& headers) { // Implements StreamDecoderFilter. // TODO(fengli): Implements the subtypes of gRPC-Web content-type other than proto, like +json, etc. -Http::FilterHeadersStatus GrpcWebFilter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus GrpcWebFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { const Http::HeaderEntry* content_type = headers.ContentType(); if (!isGrpcWebRequest(headers)) { return Http::FilterHeadersStatus::Continue; @@ -136,7 +136,7 @@ Http::FilterDataStatus GrpcWebFilter::decodeData(Buffer::Instance& data, bool en } // Implements StreamEncoderFilter. -Http::FilterHeadersStatus GrpcWebFilter::encodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus GrpcWebFilter::encodeHeaders(Http::ResponseHeaderMap& headers, bool) { if (!is_grpc_web_request_) { return Http::FilterHeadersStatus::Continue; } @@ -186,7 +186,7 @@ Http::FilterDataStatus GrpcWebFilter::encodeData(Buffer::Instance& data, bool) { return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus GrpcWebFilter::encodeTrailers(Http::HeaderMap& trailers) { +Http::FilterTrailersStatus GrpcWebFilter::encodeTrailers(Http::ResponseTrailerMap& trailers) { if (!is_grpc_web_request_) { return Http::FilterTrailersStatus::Continue; } diff --git a/source/extensions/filters/http/grpc_web/grpc_web_filter.h b/source/extensions/filters/http/grpc_web/grpc_web_filter.h index 3b2312006e..a20a690322 100644 --- a/source/extensions/filters/http/grpc_web/grpc_web_filter.h +++ b/source/extensions/filters/http/grpc_web/grpc_web_filter.h @@ -27,9 +27,9 @@ class GrpcWebFilter : public Http::StreamFilter, NonCopyable { void onDestroy() override {} // Implements StreamDecoderFilter. - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap&, bool) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool) override; Http::FilterDataStatus decodeData(Buffer::Instance&, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { return Http::FilterTrailersStatus::Continue; } void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override { @@ -37,12 +37,12 @@ class GrpcWebFilter : public Http::StreamFilter, NonCopyable { } // Implements StreamEncoderFilter. - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override { + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override { return Http::FilterHeadersStatus::Continue; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap&, bool) override; + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap&, bool) override; Http::FilterDataStatus encodeData(Buffer::Instance&, bool) override; - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap& trailers) override; Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override { return Http::FilterMetadataStatus::Continue; } diff --git a/source/extensions/filters/http/gzip/gzip_filter.cc b/source/extensions/filters/http/gzip/gzip_filter.cc index a6a6d4a503..c595345d76 100644 --- a/source/extensions/filters/http/gzip/gzip_filter.cc +++ b/source/extensions/filters/http/gzip/gzip_filter.cc @@ -101,7 +101,7 @@ uint64_t GzipFilterConfig::windowBitsUint(Protobuf::uint32 window_bits) { GzipFilter::GzipFilter(const GzipFilterConfigSharedPtr& config) : skip_compression_{true}, config_(config) {} -Http::FilterHeadersStatus GzipFilter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus GzipFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { if (config_->runtime().snapshot().featureEnabled("gzip.filter_enabled", 100) && isAcceptEncodingAllowed(headers)) { skip_compression_ = false; @@ -115,7 +115,8 @@ Http::FilterHeadersStatus GzipFilter::decodeHeaders(Http::HeaderMap& headers, bo return Http::FilterHeadersStatus::Continue; } -Http::FilterHeadersStatus GzipFilter::encodeHeaders(Http::HeaderMap& headers, bool end_stream) { +Http::FilterHeadersStatus GzipFilter::encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) { if (!end_stream && !skip_compression_ && isMinimumContentLength(headers) && isContentTypeAllowed(headers) && !hasCacheControlNoTransform(headers) && isEtagAllowed(headers) && isTransferEncodingAllowed(headers) && !headers.ContentEncoding()) { @@ -142,7 +143,7 @@ Http::FilterDataStatus GzipFilter::encodeData(Buffer::Instance& data, bool end_s return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus GzipFilter::encodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus GzipFilter::encodeTrailers(Http::ResponseTrailerMap&) { if (!skip_compression_) { Buffer::OwnedImpl empty_buffer; compressor_.compress(empty_buffer, Compressor::State::Finish); diff --git a/source/extensions/filters/http/gzip/gzip_filter.h b/source/extensions/filters/http/gzip/gzip_filter.h index 471d5196af..7fe7d9b160 100644 --- a/source/extensions/filters/http/gzip/gzip_filter.h +++ b/source/extensions/filters/http/gzip/gzip_filter.h @@ -115,11 +115,12 @@ class GzipFilter : public Http::StreamFilter { void onDestroy() override{}; // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance&, bool) override { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { return Http::FilterTrailersStatus::Continue; } void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override { @@ -127,12 +128,13 @@ class GzipFilter : public Http::StreamFilter { }; // Http::StreamEncoderFilter - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override { + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override { return Http::FilterHeadersStatus::Continue; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus encodeData(Buffer::Instance& buffer, bool end_stream) override; - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap&) override; + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap&) override; Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override { return Http::FilterMetadataStatus::Continue; } diff --git a/source/extensions/filters/http/header_to_metadata/header_to_metadata_filter.cc b/source/extensions/filters/http/header_to_metadata/header_to_metadata_filter.cc index 81a9394424..8986a570db 100644 --- a/source/extensions/filters/http/header_to_metadata/header_to_metadata_filter.cc +++ b/source/extensions/filters/http/header_to_metadata/header_to_metadata_filter.cc @@ -54,7 +54,8 @@ HeaderToMetadataFilter::HeaderToMetadataFilter(const ConfigSharedPtr config) : c HeaderToMetadataFilter::~HeaderToMetadataFilter() = default; -Http::FilterHeadersStatus HeaderToMetadataFilter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus HeaderToMetadataFilter::decodeHeaders(Http::RequestHeaderMap& headers, + bool) { if (config_->doRequest()) { writeHeaderToMetadata(headers, config_->requestRules(), *decoder_callbacks_); } @@ -67,7 +68,8 @@ void HeaderToMetadataFilter::setDecoderFilterCallbacks( decoder_callbacks_ = &callbacks; } -Http::FilterHeadersStatus HeaderToMetadataFilter::encodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus HeaderToMetadataFilter::encodeHeaders(Http::ResponseHeaderMap& headers, + bool) { if (config_->doResponse()) { writeHeaderToMetadata(headers, config_->responseRules(), *encoder_callbacks_); } diff --git a/source/extensions/filters/http/header_to_metadata/header_to_metadata_filter.h b/source/extensions/filters/http/header_to_metadata/header_to_metadata_filter.h index 18ec2d0ae0..bd1f122228 100644 --- a/source/extensions/filters/http/header_to_metadata/header_to_metadata_filter.h +++ b/source/extensions/filters/http/header_to_metadata/header_to_metadata_filter.h @@ -76,24 +76,24 @@ class HeaderToMetadataFilter : public Http::StreamFilter, void onDestroy() override {} // StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, bool) override; Http::FilterDataStatus decodeData(Buffer::Instance&, bool) override { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { return Http::FilterTrailersStatus::Continue; } void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; // StreamEncoderFilter - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override { + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override { return Http::FilterHeadersStatus::Continue; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap& headers, bool) override; + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& headers, bool) override; Http::FilterDataStatus encodeData(Buffer::Instance&, bool) override { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap&) override { return Http::FilterTrailersStatus::Continue; } Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override { diff --git a/source/extensions/filters/http/health_check/health_check.cc b/source/extensions/filters/http/health_check/health_check.cc index e66f82f8fe..6f1e3bf9c8 100644 --- a/source/extensions/filters/http/health_check/health_check.cc +++ b/source/extensions/filters/http/health_check/health_check.cc @@ -50,7 +50,7 @@ void HealthCheckCacheManager::onTimer() { clear_cache_timer_->enableTimer(timeout_); } -Http::FilterHeadersStatus HealthCheckFilter::decodeHeaders(Http::HeaderMap& headers, +Http::FilterHeadersStatus HealthCheckFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool end_stream) { if (Http::HeaderUtility::matchHeaders(headers, *header_match_data_)) { health_check_request_ = true; @@ -86,7 +86,7 @@ Http::FilterDataStatus HealthCheckFilter::decodeData(Buffer::Instance&, bool end : Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus HealthCheckFilter::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus HealthCheckFilter::decodeTrailers(Http::RequestTrailerMap&) { if (handling_) { onComplete(); } @@ -95,7 +95,7 @@ Http::FilterTrailersStatus HealthCheckFilter::decodeTrailers(Http::HeaderMap&) { : Http::FilterTrailersStatus::Continue; } -Http::FilterHeadersStatus HealthCheckFilter::encodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus HealthCheckFilter::encodeHeaders(Http::ResponseHeaderMap& headers, bool) { if (health_check_request_) { if (cache_manager_) { cache_manager_->setCachedResponse( diff --git a/source/extensions/filters/http/health_check/health_check.h b/source/extensions/filters/http/health_check/health_check.h index c000e41366..d11f0d3a80 100644 --- a/source/extensions/filters/http/health_check/health_check.h +++ b/source/extensions/filters/http/health_check/health_check.h @@ -72,22 +72,24 @@ class HealthCheckFilter : public Http::StreamFilter { void onDestroy() override {} // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override { callbacks_ = &callbacks; } // Http::StreamEncoderFilter - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override { + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override { return Http::FilterHeadersStatus::Continue; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus encodeData(Buffer::Instance&, bool) override { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap&) override { return Http::FilterTrailersStatus::Continue; } Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override { diff --git a/source/extensions/filters/http/ip_tagging/ip_tagging_filter.cc b/source/extensions/filters/http/ip_tagging/ip_tagging_filter.cc index d41a463437..e232f238f1 100644 --- a/source/extensions/filters/http/ip_tagging/ip_tagging_filter.cc +++ b/source/extensions/filters/http/ip_tagging/ip_tagging_filter.cc @@ -71,7 +71,7 @@ IpTaggingFilter::~IpTaggingFilter() = default; void IpTaggingFilter::onDestroy() {} -Http::FilterHeadersStatus IpTaggingFilter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus IpTaggingFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { const bool is_internal_request = headers.EnvoyInternalRequest() && (headers.EnvoyInternalRequest()->value() == Http::Headers::get().EnvoyInternalRequestValues.True.c_str()); @@ -109,7 +109,7 @@ Http::FilterDataStatus IpTaggingFilter::decodeData(Buffer::Instance&, bool) { return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus IpTaggingFilter::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus IpTaggingFilter::decodeTrailers(Http::RequestTrailerMap&) { return Http::FilterTrailersStatus::Continue; } diff --git a/source/extensions/filters/http/ip_tagging/ip_tagging_filter.h b/source/extensions/filters/http/ip_tagging/ip_tagging_filter.h index fe114a30c2..0773916129 100644 --- a/source/extensions/filters/http/ip_tagging/ip_tagging_filter.h +++ b/source/extensions/filters/http/ip_tagging/ip_tagging_filter.h @@ -87,9 +87,10 @@ class IpTaggingFilter : public Http::StreamDecoderFilter { void onDestroy() override; // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; private: diff --git a/source/extensions/filters/http/jwt_authn/filter.cc b/source/extensions/filters/http/jwt_authn/filter.cc index 117a8c62c2..8afd3d2f59 100644 --- a/source/extensions/filters/http/jwt_authn/filter.cc +++ b/source/extensions/filters/http/jwt_authn/filter.cc @@ -42,7 +42,7 @@ void Filter::onDestroy() { } } -Http::FilterHeadersStatus Filter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { ENVOY_LOG(debug, "Called Filter : {}", __func__); state_ = Calling; @@ -112,7 +112,7 @@ Http::FilterDataStatus Filter::decodeData(Buffer::Instance&, bool) { return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus Filter::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus Filter::decodeTrailers(Http::RequestTrailerMap&) { ENVOY_LOG(debug, "Called Filter : {}", __func__); if (state_ == Calling) { return Http::FilterTrailersStatus::StopIteration; diff --git a/source/extensions/filters/http/jwt_authn/filter.h b/source/extensions/filters/http/jwt_authn/filter.h index 6757211462..732eb1ca91 100644 --- a/source/extensions/filters/http/jwt_authn/filter.h +++ b/source/extensions/filters/http/jwt_authn/filter.h @@ -25,9 +25,9 @@ class Filter : public Http::StreamDecoderFilter, void onDestroy() override; // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, bool) override; Http::FilterDataStatus decodeData(Buffer::Instance&, bool) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; private: diff --git a/source/extensions/filters/http/lua/lua_filter.cc b/source/extensions/filters/http/lua/lua_filter.cc index f12958d42e..5c393af324 100644 --- a/source/extensions/filters/http/lua/lua_filter.cc +++ b/source/extensions/filters/http/lua/lua_filter.cc @@ -115,7 +115,8 @@ int StreamHandleWrapper::luaRespond(lua_State* state) { luaL_checktype(state, 2, LUA_TTABLE); size_t body_size; const char* raw_body = luaL_optlstring(state, 3, nullptr, &body_size); - Http::HeaderMapPtr headers = buildHeadersFromTable(state, 2); + auto headers = std::make_unique(); + buildHeadersFromTable(*headers, state, 2); uint64_t status; if (headers->Status() == nullptr || @@ -137,9 +138,8 @@ int StreamHandleWrapper::luaRespond(lua_State* state) { return lua_yield(state, 0); } -Http::HeaderMapPtr StreamHandleWrapper::buildHeadersFromTable(lua_State* state, int table_index) { - Http::HeaderMapPtr headers(new Http::HeaderMapImpl()); - +void StreamHandleWrapper::buildHeadersFromTable(Http::HeaderMap& headers, lua_State* state, + int table_index) { // Build a header map to make the request. We iterate through the provided table to do this and // check that we are getting strings. lua_pushnil(state); @@ -152,19 +152,17 @@ Http::HeaderMapPtr StreamHandleWrapper::buildHeadersFromTable(lua_State* state, lua_pushnil(state); while (lua_next(state, -2) != 0) { const char* value = luaL_checkstring(state, -1); - headers->addCopy(Http::LowerCaseString(key), value); + headers.addCopy(Http::LowerCaseString(key), value); lua_pop(state, 1); } } else { const char* value = luaL_checkstring(state, -1); - headers->addCopy(Http::LowerCaseString(key), value); + headers.addCopy(Http::LowerCaseString(key), value); } // Removes 'value'; keeps 'key' for next iteration. This is the input for lua_next() so that // it can push the next key/value pair onto the stack. lua_pop(state, 1); } - - return headers; } int StreamHandleWrapper::luaHttpCall(lua_State* state) { @@ -183,7 +181,9 @@ int StreamHandleWrapper::luaHttpCall(lua_State* state) { return luaL_error(state, "http call cluster invalid. Must be configured"); } - Http::MessagePtr message(new Http::RequestMessageImpl(buildHeadersFromTable(state, 3))); + auto headers = std::make_unique(); + buildHeadersFromTable(*headers, state, 3); + Http::RequestMessagePtr message(new Http::RequestMessageImpl(std::move(headers))); // Check that we were provided certain headers. if (message->headers().Path() == nullptr || message->headers().Method() == nullptr || @@ -213,7 +213,7 @@ int StreamHandleWrapper::luaHttpCall(lua_State* state) { } } -void StreamHandleWrapper::onSuccess(Http::MessagePtr&& response) { +void StreamHandleWrapper::onSuccess(Http::ResponseMessagePtr&& response) { ASSERT(state_ == State::HttpCall || state_ == State::Running); ENVOY_LOG(debug, "async HTTP response complete"); http_request_ = nullptr; @@ -264,9 +264,10 @@ void StreamHandleWrapper::onFailure(Http::AsyncClient::FailureReason) { ENVOY_LOG(debug, "async HTTP failure"); // Just fake a basic 503 response. - Http::MessagePtr response_message(new Http::ResponseMessageImpl(Http::HeaderMapPtr{ - Http::HeaderMapImpl::create({{Http::Headers::get().Status, - std::to_string(enumToInt(Http::Code::ServiceUnavailable))}})})); + Http::ResponseMessagePtr response_message( + new Http::ResponseMessageImpl(Http::createHeaderMap( + {{Http::Headers::get().Status, + std::to_string(enumToInt(Http::Code::ServiceUnavailable))}}))); response_message->body() = std::make_unique("upstream failure"); onSuccess(std::move(response_message)); } @@ -607,7 +608,7 @@ void Filter::scriptLog(spdlog::level::level_enum level, const char* message) { } } -void Filter::DecoderCallbacks::respond(Http::HeaderMapPtr&& headers, Buffer::Instance* body, +void Filter::DecoderCallbacks::respond(Http::ResponseHeaderMapPtr&& headers, Buffer::Instance* body, lua_State*) { callbacks_->encodeHeaders(std::move(headers), body == nullptr); if (body && !parent_.destroyed_) { @@ -615,7 +616,8 @@ void Filter::DecoderCallbacks::respond(Http::HeaderMapPtr&& headers, Buffer::Ins } } -void Filter::EncoderCallbacks::respond(Http::HeaderMapPtr&&, Buffer::Instance*, lua_State* state) { +void Filter::EncoderCallbacks::respond(Http::ResponseHeaderMapPtr&&, Buffer::Instance*, + lua_State* state) { // TODO(mattklein123): Support response in response path if nothing has been continued // yet. luaL_error(state, "respond not currently supported in the response path"); diff --git a/source/extensions/filters/http/lua/lua_filter.h b/source/extensions/filters/http/lua/lua_filter.h index 2b99219124..792a7becfe 100644 --- a/source/extensions/filters/http/lua/lua_filter.h +++ b/source/extensions/filters/http/lua/lua_filter.h @@ -63,7 +63,8 @@ class FilterCallbacks { * @param body supplies the optional response body. * @param state supplies the active Lua state. */ - virtual void respond(Http::HeaderMapPtr&& headers, Buffer::Instance* body, lua_State* state) PURE; + virtual void respond(Http::ResponseHeaderMapPtr&& headers, Buffer::Instance* body, + lua_State* state) PURE; /** * @return const ProtobufWkt::Struct& the value of metadata inside the lua filter scope of current @@ -246,7 +247,7 @@ class StreamHandleWrapper : public Filters::Common::Lua::BaseLuaObject { void onDestroy() override; // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override { return doHeaders(request_stream_wrapper_, request_coroutine_, decoder_callbacks_, config_->requestFunctionRef(), headers, end_stream); } Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override { return doData(request_stream_wrapper_, data, end_stream); } - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override { return doTrailers(request_stream_wrapper_, trailers); } void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override { @@ -341,17 +343,18 @@ class Filter : public Http::StreamFilter, Logger::Loggable { } // Http::StreamEncoderFilter - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override { + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override { return Http::FilterHeadersStatus::Continue; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap& headers, bool end_stream) override { + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) override { return doHeaders(response_stream_wrapper_, response_coroutine_, encoder_callbacks_, config_->responseFunctionRef(), headers, end_stream); } Http::FilterDataStatus encodeData(Buffer::Instance& data, bool end_stream) override { return doData(response_stream_wrapper_, data, end_stream); }; - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap& trailers) override { + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap& trailers) override { return doTrailers(response_stream_wrapper_, trailers); }; Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override { @@ -372,7 +375,8 @@ class Filter : public Http::StreamFilter, Logger::Loggable { const Buffer::Instance* bufferedBody() override { return callbacks_->decodingBuffer(); } void continueIteration() override { return callbacks_->continueDecoding(); } void onHeadersModified() override { callbacks_->clearRouteCache(); } - void respond(Http::HeaderMapPtr&& headers, Buffer::Instance* body, lua_State* state) override; + void respond(Http::ResponseHeaderMapPtr&& headers, Buffer::Instance* body, + lua_State* state) override; const ProtobufWkt::Struct& metadata() const override { return getMetadata(callbacks_); } StreamInfo::StreamInfo& streamInfo() override { return callbacks_->streamInfo(); } @@ -392,7 +396,8 @@ class Filter : public Http::StreamFilter, Logger::Loggable { const Buffer::Instance* bufferedBody() override { return callbacks_->encodingBuffer(); } void continueIteration() override { return callbacks_->continueEncoding(); } void onHeadersModified() override {} - void respond(Http::HeaderMapPtr&& headers, Buffer::Instance* body, lua_State* state) override; + void respond(Http::ResponseHeaderMapPtr&& headers, Buffer::Instance* body, + lua_State* state) override; const ProtobufWkt::Struct& metadata() const override { return getMetadata(callbacks_); } StreamInfo::StreamInfo& streamInfo() override { return callbacks_->streamInfo(); } diff --git a/source/extensions/filters/http/on_demand/on_demand_update.cc b/source/extensions/filters/http/on_demand/on_demand_update.cc index 55c56a875a..cf69080e66 100644 --- a/source/extensions/filters/http/on_demand/on_demand_update.cc +++ b/source/extensions/filters/http/on_demand/on_demand_update.cc @@ -9,7 +9,7 @@ namespace Extensions { namespace HttpFilters { namespace OnDemand { -Http::FilterHeadersStatus OnDemandRouteUpdate::decodeHeaders(Http::HeaderMap&, bool) { +Http::FilterHeadersStatus OnDemandRouteUpdate::decodeHeaders(Http::RequestHeaderMap&, bool) { if (callbacks_->route() != nullptr || !(callbacks_->routeConfig().has_value() && callbacks_->routeConfig().value()->usesVhds())) { filter_iteration_state_ = Http::FilterHeadersStatus::Continue; @@ -29,7 +29,7 @@ Http::FilterDataStatus OnDemandRouteUpdate::decodeData(Buffer::Instance&, bool) : Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus OnDemandRouteUpdate::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus OnDemandRouteUpdate::decodeTrailers(Http::RequestTrailerMap&) { return Http::FilterTrailersStatus::Continue; } diff --git a/source/extensions/filters/http/on_demand/on_demand_update.h b/source/extensions/filters/http/on_demand/on_demand_update.h index 3bfeff60db..a2cd51e07e 100644 --- a/source/extensions/filters/http/on_demand/on_demand_update.h +++ b/source/extensions/filters/http/on_demand/on_demand_update.h @@ -18,11 +18,12 @@ class OnDemandRouteUpdate : public Http::StreamDecoderFilter { } // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; diff --git a/source/extensions/filters/http/original_src/original_src.cc b/source/extensions/filters/http/original_src/original_src.cc index 18d71275fc..b604954396 100644 --- a/source/extensions/filters/http/original_src/original_src.cc +++ b/source/extensions/filters/http/original_src/original_src.cc @@ -13,7 +13,7 @@ OriginalSrcFilter::OriginalSrcFilter(const Config& config) : config_(config) {} void OriginalSrcFilter::onDestroy() {} -Http::FilterHeadersStatus OriginalSrcFilter::decodeHeaders(Http::HeaderMap&, bool) { +Http::FilterHeadersStatus OriginalSrcFilter::decodeHeaders(Http::RequestHeaderMap&, bool) { const auto downstream_address = callbacks_->streamInfo().downstreamRemoteAddress(); ASSERT(downstream_address); @@ -36,7 +36,7 @@ Http::FilterDataStatus OriginalSrcFilter::decodeData(Buffer::Instance&, bool) { return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus OriginalSrcFilter::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus OriginalSrcFilter::decodeTrailers(Http::RequestTrailerMap&) { return Http::FilterTrailersStatus::Continue; } diff --git a/source/extensions/filters/http/original_src/original_src.h b/source/extensions/filters/http/original_src/original_src.h index 1754a3bb00..032f93ee63 100644 --- a/source/extensions/filters/http/original_src/original_src.h +++ b/source/extensions/filters/http/original_src/original_src.h @@ -26,9 +26,10 @@ class OriginalSrcFilter : public Http::StreamDecoderFilter, Logger::Loggableruntime().snapshot().featureEnabled("ratelimit.http_filter_enabled", 100)) { return Http::FilterHeadersStatus::Continue; } @@ -84,7 +84,7 @@ Http::FilterDataStatus Filter::decodeData(Buffer::Instance&, bool) { return Http::FilterDataStatus::StopIterationAndWatermark; } -Http::FilterTrailersStatus Filter::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus Filter::decodeTrailers(Http::RequestTrailerMap&) { ASSERT(state_ != State::Responded); return state_ == State::Calling ? Http::FilterTrailersStatus::StopIteration : Http::FilterTrailersStatus::Continue; @@ -94,11 +94,11 @@ void Filter::setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callb callbacks_ = &callbacks; } -Http::FilterHeadersStatus Filter::encode100ContinueHeaders(Http::HeaderMap&) { +Http::FilterHeadersStatus Filter::encode100ContinueHeaders(Http::ResponseHeaderMap&) { return Http::FilterHeadersStatus::Continue; } -Http::FilterHeadersStatus Filter::encodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus Filter::encodeHeaders(Http::ResponseHeaderMap& headers, bool) { populateResponseHeaders(headers); return Http::FilterHeadersStatus::Continue; } @@ -107,7 +107,7 @@ Http::FilterDataStatus Filter::encodeData(Buffer::Instance&, bool) { return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus Filter::encodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus Filter::encodeTrailers(Http::ResponseTrailerMap&) { return Http::FilterTrailersStatus::Continue; } diff --git a/source/extensions/filters/http/ratelimit/ratelimit.h b/source/extensions/filters/http/ratelimit/ratelimit.h index 7d7b36aced..b2c5ed2a16 100644 --- a/source/extensions/filters/http/ratelimit/ratelimit.h +++ b/source/extensions/filters/http/ratelimit/ratelimit.h @@ -100,16 +100,18 @@ class Filter : public Http::StreamFilter, public Filters::Common::RateLimit::Req void onDestroy() override; // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; // Http::StreamEncoderFilter - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap& headers) override; - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap& headers) override; + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus encodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap& trailers) override; Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override; void setEncoderFilterCallbacks(Http::StreamEncoderFilterCallbacks& callbacks) override; diff --git a/source/extensions/filters/http/rbac/rbac_filter.cc b/source/extensions/filters/http/rbac/rbac_filter.cc index 861ad6dfca..6f9b703c8a 100644 --- a/source/extensions/filters/http/rbac/rbac_filter.cc +++ b/source/extensions/filters/http/rbac/rbac_filter.cc @@ -52,8 +52,8 @@ RoleBasedAccessControlRouteSpecificFilterConfig::RoleBasedAccessControlRouteSpec : engine_(Filters::Common::RBAC::createEngine(per_route_config.rbac())), shadow_engine_(Filters::Common::RBAC::createShadowEngine(per_route_config.rbac())) {} -Http::FilterHeadersStatus RoleBasedAccessControlFilter::decodeHeaders(Http::HeaderMap& headers, - bool) { +Http::FilterHeadersStatus +RoleBasedAccessControlFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { ENVOY_LOG( debug, "checking request: remoteAddress: {}, localAddress: {}, ssl: {}, headers: {}, " diff --git a/source/extensions/filters/http/rbac/rbac_filter.h b/source/extensions/filters/http/rbac/rbac_filter.h index ca363fc779..fe7369e34e 100644 --- a/source/extensions/filters/http/rbac/rbac_filter.h +++ b/source/extensions/filters/http/rbac/rbac_filter.h @@ -74,13 +74,14 @@ class RoleBasedAccessControlFilter : public Http::StreamDecoderFilter, : config_(config) {} // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance&, bool) override { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { return Http::FilterTrailersStatus::Continue; } diff --git a/source/extensions/filters/http/squash/squash_filter.cc b/source/extensions/filters/http/squash/squash_filter.cc index 0fa1d5bb98..7ad2f95b71 100644 --- a/source/extensions/filters/http/squash/squash_filter.cc +++ b/source/extensions/filters/http/squash/squash_filter.cc @@ -135,7 +135,7 @@ SquashFilter::~SquashFilter() = default; void SquashFilter::onDestroy() { cleanup(); } -Http::FilterHeadersStatus SquashFilter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus SquashFilter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { // Check for squash header if (!headers.get(Http::Headers::get().XSquashDebug)) { return Http::FilterHeadersStatus::Continue; @@ -143,7 +143,7 @@ Http::FilterHeadersStatus SquashFilter::decodeHeaders(Http::HeaderMap& headers, ENVOY_LOG(debug, "Squash: Holding request and requesting debug attachment"); - Http::MessagePtr request(new Http::RequestMessageImpl()); + Http::RequestMessagePtr request(new Http::RequestMessageImpl()); request->headers().setReferenceContentType(Http::Headers::get().ContentTypeValues.Json); request->headers().setReferencePath(POST_ATTACHMENT_PATH); request->headers().setReferenceHost(SERVER_AUTHORITY); @@ -181,7 +181,7 @@ Http::FilterDataStatus SquashFilter::decodeData(Buffer::Instance&, bool) { return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus SquashFilter::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus SquashFilter::decodeTrailers(Http::RequestTrailerMap&) { if (is_squashing_) { return Http::FilterTrailersStatus::StopIteration; } @@ -192,7 +192,7 @@ void SquashFilter::setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& decoder_callbacks_ = &callbacks; } -void SquashFilter::onCreateAttachmentSuccess(Http::MessagePtr&& m) { +void SquashFilter::onCreateAttachmentSuccess(Http::ResponseMessagePtr&& m) { in_flight_request_ = nullptr; // Get the config object that was created @@ -233,7 +233,7 @@ void SquashFilter::onCreateAttachmentFailure(Http::AsyncClient::FailureReason) { } } -void SquashFilter::onGetAttachmentSuccess(Http::MessagePtr&& m) { +void SquashFilter::onGetAttachmentSuccess(Http::ResponseMessagePtr&& m) { in_flight_request_ = nullptr; std::string attachmentstate; @@ -268,7 +268,7 @@ void SquashFilter::scheduleRetry() { } void SquashFilter::pollForAttachment() { - Http::MessagePtr request(new Http::RequestMessageImpl()); + Http::RequestMessagePtr request(new Http::RequestMessageImpl()); request->headers().setReferenceMethod(Http::Headers::get().MethodValues.Get); request->headers().setReferencePath(debug_attachment_path_); request->headers().setReferenceHost(SERVER_AUTHORITY); @@ -307,7 +307,7 @@ void SquashFilter::cleanup() { debug_attachment_path_ = EMPTY_STRING; } -Json::ObjectSharedPtr SquashFilter::getJsonBody(Http::MessagePtr&& m) { +Json::ObjectSharedPtr SquashFilter::getJsonBody(Http::ResponseMessagePtr&& m) { Buffer::InstancePtr& data = m->body(); uint64_t num_slices = data->getRawSlices(nullptr, 0); absl::FixedArray slices(num_slices); diff --git a/source/extensions/filters/http/squash/squash_filter.h b/source/extensions/filters/http/squash/squash_filter.h index fff27050d0..b2c582688b 100644 --- a/source/extensions/filters/http/squash/squash_filter.h +++ b/source/extensions/filters/http/squash/squash_filter.h @@ -58,15 +58,17 @@ using SquashFilterConfigSharedPtr = std::shared_ptr; class AsyncClientCallbackShim : public Http::AsyncClient::Callbacks { public: - AsyncClientCallbackShim(std::function&& on_success, + AsyncClientCallbackShim(std::function&& on_success, std::function&& on_fail) : on_success_(on_success), on_fail_(on_fail) {} // Http::AsyncClient::Callbacks - void onSuccess(Http::MessagePtr&& m) override { on_success_(std::forward(m)); } + void onSuccess(Http::ResponseMessagePtr&& m) override { + on_success_(std::forward(m)); + } void onFailure(Http::AsyncClient::FailureReason f) override { on_fail_(f); } private: - std::function on_success_; + std::function on_success_; std::function on_fail_; }; @@ -80,17 +82,17 @@ class SquashFilter : public Http::StreamDecoderFilter, void onDestroy() override; // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, bool) override; Http::FilterDataStatus decodeData(Buffer::Instance&, bool) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; private: // AsyncClient callbacks for create attachment request - void onCreateAttachmentSuccess(Http::MessagePtr&&); + void onCreateAttachmentSuccess(Http::ResponseMessagePtr&&); void onCreateAttachmentFailure(Http::AsyncClient::FailureReason); // AsyncClient callbacks for get attachment request - void onGetAttachmentSuccess(Http::MessagePtr&&); + void onGetAttachmentSuccess(Http::ResponseMessagePtr&&); void onGetAttachmentFailure(Http::AsyncClient::FailureReason); // Schedules a pollForAttachment @@ -101,7 +103,7 @@ class SquashFilter : public Http::StreamDecoderFilter, void doneSquashing(); void cleanup(); // Creates a JSON from the message body. - Json::ObjectSharedPtr getJsonBody(Http::MessagePtr&& m); + Json::ObjectSharedPtr getJsonBody(Http::ResponseMessagePtr&& m); const SquashFilterConfigSharedPtr config_; diff --git a/source/extensions/filters/http/tap/tap_filter.cc b/source/extensions/filters/http/tap/tap_filter.cc index 9dc447c9c4..e3ebd974f6 100644 --- a/source/extensions/filters/http/tap/tap_filter.cc +++ b/source/extensions/filters/http/tap/tap_filter.cc @@ -27,7 +27,7 @@ FilterStats Filter::generateStats(const std::string& prefix, Stats::Scope& scope return {ALL_TAP_FILTER_STATS(POOL_COUNTER_PREFIX(scope, final_prefix))}; } -Http::FilterHeadersStatus Filter::decodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, bool) { if (tapper_ != nullptr) { tapper_->onRequestHeaders(headers); } @@ -41,14 +41,14 @@ Http::FilterDataStatus Filter::decodeData(Buffer::Instance& data, bool) { return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus Filter::decodeTrailers(Http::HeaderMap& trailers) { +Http::FilterTrailersStatus Filter::decodeTrailers(Http::RequestTrailerMap& trailers) { if (tapper_ != nullptr) { tapper_->onRequestTrailers(trailers); } return Http::FilterTrailersStatus::Continue; } -Http::FilterHeadersStatus Filter::encodeHeaders(Http::HeaderMap& headers, bool) { +Http::FilterHeadersStatus Filter::encodeHeaders(Http::ResponseHeaderMap& headers, bool) { if (tapper_ != nullptr) { tapper_->onResponseHeaders(headers); } @@ -62,7 +62,7 @@ Http::FilterDataStatus Filter::encodeData(Buffer::Instance& data, bool) { return Http::FilterDataStatus::Continue; } -Http::FilterTrailersStatus Filter::encodeTrailers(Http::HeaderMap& trailers) { +Http::FilterTrailersStatus Filter::encodeTrailers(Http::ResponseTrailerMap& trailers) { if (tapper_ != nullptr) { tapper_->onResponseTrailers(trailers); } diff --git a/source/extensions/filters/http/tap/tap_filter.h b/source/extensions/filters/http/tap/tap_filter.h index b32005a433..e7edeec46d 100644 --- a/source/extensions/filters/http/tap/tap_filter.h +++ b/source/extensions/filters/http/tap/tap_filter.h @@ -83,21 +83,23 @@ class Filter : public Http::StreamFilter, public AccessLog::Instance { void onDestroy() override {} // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override { HttpTapConfigSharedPtr config = config_->currentConfig(); tapper_ = config ? config->createPerRequestTapper(callbacks.streamId()) : nullptr; } // Http::StreamEncoderFilter - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override { + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override { return Http::FilterHeadersStatus::Continue; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus encodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap& trailers) override; Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override { return Http::FilterMetadataStatus::Continue; } diff --git a/source/extensions/filters/network/client_ssl_auth/client_ssl_auth.cc b/source/extensions/filters/network/client_ssl_auth/client_ssl_auth.cc index 240d3ddc21..67af3ff10b 100644 --- a/source/extensions/filters/network/client_ssl_auth/client_ssl_auth.cc +++ b/source/extensions/filters/network/client_ssl_auth/client_ssl_auth.cc @@ -63,7 +63,7 @@ GlobalStats ClientSslAuthConfig::generateStats(Stats::Scope& scope, const std::s return stats; } -void ClientSslAuthConfig::parseResponse(const Http::Message& message) { +void ClientSslAuthConfig::parseResponse(const Http::ResponseMessage& message) { AllowedPrincipalsSharedPtr new_principals(new AllowedPrincipals()); Json::ObjectSharedPtr loader = Json::Factory::loadFromString(message.bodyAsString()); for (const Json::ObjectSharedPtr& certificate : loader->getObjectArray("certificates")) { @@ -84,7 +84,7 @@ void ClientSslAuthConfig::onFetchFailure(Config::ConfigUpdateFailureReason, cons static const std::string Path = "/v1/certs/list/approved"; -void ClientSslAuthConfig::createRequest(Http::Message& request) { +void ClientSslAuthConfig::createRequest(Http::RequestMessage& request) { request.headers().setReferenceMethod(Http::Headers::get().MethodValues.Get); request.headers().setPath(Path); } diff --git a/source/extensions/filters/network/client_ssl_auth/client_ssl_auth.h b/source/extensions/filters/network/client_ssl_auth/client_ssl_auth.h index 723db8baec..967a0903e9 100644 --- a/source/extensions/filters/network/client_ssl_auth/client_ssl_auth.h +++ b/source/extensions/filters/network/client_ssl_auth/client_ssl_auth.h @@ -92,8 +92,8 @@ class ClientSslAuthConfig : public Http::RestApiFetcher { static GlobalStats generateStats(Stats::Scope& scope, const std::string& prefix); // Http::RestApiFetcher - void createRequest(Http::Message& request) override; - void parseResponse(const Http::Message& response) override; + void createRequest(Http::RequestMessage& request) override; + void parseResponse(const Http::ResponseMessage& response) override; void onFetchComplete() override {} void onFetchFailure(Config::ConfigUpdateFailureReason reason, const EnvoyException* e) override; diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc index ae8ddc18a7..aa604d3409 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.cc @@ -44,7 +44,7 @@ EnvoyQuicClientStream::EnvoyQuicClientStream(quic::PendingStream* pending, 16 * 1024, [this]() { runLowWatermarkCallbacks(); }, [this]() { runHighWatermarkCallbacks(); }) {} -void EnvoyQuicClientStream::encodeHeaders(const Http::HeaderMap& headers, bool end_stream) { +void EnvoyQuicClientStream::encodeHeaders(const Http::RequestHeaderMap& headers, bool end_stream) { ENVOY_STREAM_LOG(debug, "encodeHeaders: (end_stream={}) {}.", *this, end_stream, headers); WriteHeaders(envoyHeadersToSpdyHeaderBlock(headers), end_stream, nullptr); local_end_stream_ = end_stream; @@ -69,7 +69,7 @@ void EnvoyQuicClientStream::encodeData(Buffer::Instance& data, bool end_stream) maybeCheckWatermark(bytes_to_send_old, bytes_to_send_new, *filterManagerConnection()); } -void EnvoyQuicClientStream::encodeTrailers(const Http::HeaderMap& trailers) { +void EnvoyQuicClientStream::encodeTrailers(const Http::RequestTrailerMap& trailers) { ASSERT(!local_end_stream_); local_end_stream_ = true; ENVOY_STREAM_LOG(debug, "encodeTrailers: {}.", *this, trailers); diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h index b2f420c41c..cabb3197c1 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_client_stream.h @@ -31,8 +31,8 @@ class EnvoyQuicClientStream : public quic::QuicSpdyClientStream, void encodeMetadata(const Http::MetadataMapVector& metadata_map_vector) override; // Http::RequestEncoder - void encodeHeaders(const Http::HeaderMap& headers, bool end_stream) override; - void encodeTrailers(const Http::HeaderMap& trailers) override; + void encodeHeaders(const Http::RequestHeaderMap& headers, bool end_stream) override; + void encodeTrailers(const Http::RequestTrailerMap& trailers) override; // Http::Stream void resetStream(Http::StreamResetReason reason) override; diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc index e1c6397732..12d93227bb 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.cc @@ -49,12 +49,12 @@ EnvoyQuicServerStream::EnvoyQuicServerStream(quic::PendingStream* pending, 16 * 1024, [this]() { runLowWatermarkCallbacks(); }, [this]() { runHighWatermarkCallbacks(); }) {} -void EnvoyQuicServerStream::encode100ContinueHeaders(const Http::HeaderMap& headers) { +void EnvoyQuicServerStream::encode100ContinueHeaders(const Http::ResponseHeaderMap& headers) { ASSERT(headers.Status()->value() == "100"); encodeHeaders(headers, false); } -void EnvoyQuicServerStream::encodeHeaders(const Http::HeaderMap& headers, bool end_stream) { +void EnvoyQuicServerStream::encodeHeaders(const Http::ResponseHeaderMap& headers, bool end_stream) { ENVOY_STREAM_LOG(debug, "encodeHeaders (end_stream={}) {}.", *this, end_stream, headers); // QUICHE guarantees to take all the headers. This could cause infinite data to // be buffered on headers stream in Google QUIC implementation because @@ -87,7 +87,7 @@ void EnvoyQuicServerStream::encodeData(Buffer::Instance& data, bool end_stream) maybeCheckWatermark(bytes_to_send_old, bytes_to_send_new, *filterManagerConnection()); } -void EnvoyQuicServerStream::encodeTrailers(const Http::HeaderMap& trailers) { +void EnvoyQuicServerStream::encodeTrailers(const Http::ResponseTrailerMap& trailers) { ASSERT(!local_end_stream_); local_end_stream_ = true; ENVOY_STREAM_LOG(debug, "encodeTrailers: {}.", *this, trailers); diff --git a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h index 80353f2cd1..88ce264d02 100644 --- a/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h +++ b/source/extensions/quic_listeners/quiche/envoy_quic_server_stream.h @@ -28,10 +28,10 @@ class EnvoyQuicServerStream : public quic::QuicSpdyServerStreamBase, void setRequestDecoder(Http::RequestDecoder& decoder) { request_decoder_ = &decoder; } // Http::StreamEncoder - void encode100ContinueHeaders(const Http::HeaderMap& headers) override; - void encodeHeaders(const Http::HeaderMap& headers, bool end_stream) override; + void encode100ContinueHeaders(const Http::ResponseHeaderMap& headers) override; + void encodeHeaders(const Http::ResponseHeaderMap& headers, bool end_stream) override; void encodeData(Buffer::Instance& data, bool end_stream) override; - void encodeTrailers(const Http::HeaderMap& trailers) override; + void encodeTrailers(const Http::ResponseTrailerMap& trailers) override; void encodeMetadata(const Http::MetadataMapVector& metadata_map_vector) override; // Http::Stream diff --git a/source/extensions/stat_sinks/metrics_service/grpc_metrics_service_impl.h b/source/extensions/stat_sinks/metrics_service/grpc_metrics_service_impl.h index 86f081008b..f8d500a058 100644 --- a/source/extensions/stat_sinks/metrics_service/grpc_metrics_service_impl.h +++ b/source/extensions/stat_sinks/metrics_service/grpc_metrics_service_impl.h @@ -33,12 +33,12 @@ class GrpcMetricsStreamer virtual void send(envoy::service::metrics::v3::StreamMetricsMessage& message) PURE; // Grpc::AsyncStreamCallbacks - void onCreateInitialMetadata(Http::HeaderMap&) override {} - void onReceiveInitialMetadata(Http::HeaderMapPtr&&) override {} + void onCreateInitialMetadata(Http::RequestHeaderMap&) override {} + void onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&&) override {} void onReceiveMessage(std::unique_ptr&&) override { } - void onReceiveTrailingMetadata(Http::HeaderMapPtr&&) override {} + void onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&&) override {} void onRemoteClose(Grpc::Status::GrpcStatus, const std::string&) override{}; }; diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.cc b/source/extensions/tracers/datadog/datadog_tracer_impl.cc index d131da6967..66c53290c4 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.cc +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.cc @@ -86,7 +86,7 @@ void TraceReporter::flushTraces() { ENVOY_LOG(debug, "flushing traces: {} traces", pendingTraces); driver_.tracerStats().traces_sent_.add(pendingTraces); - Http::MessagePtr message(new Http::RequestMessageImpl()); + Http::RequestMessagePtr message(new Http::RequestMessageImpl()); message->headers().setReferenceMethod(Http::Headers::get().MethodValues.Post); message->headers().setReferencePath(encoder_->path()); message->headers().setReferenceHost(driver_.cluster()->name()); @@ -114,7 +114,7 @@ void TraceReporter::onFailure(Http::AsyncClient::FailureReason) { driver_.tracerStats().reports_failed_.inc(); } -void TraceReporter::onSuccess(Http::MessagePtr&& http_response) { +void TraceReporter::onSuccess(Http::ResponseMessagePtr&& http_response) { uint64_t responseStatus = Http::Utility::getResponseStatus(http_response->headers()); if (responseStatus != enumToInt(Http::Code::OK)) { // TODO: Consider adding retries for failed submissions. diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.h b/source/extensions/tracers/datadog/datadog_tracer_impl.h index 826167beb6..eaeacc46b2 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.h +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.h @@ -107,7 +107,7 @@ class TraceReporter : public Http::AsyncClient::Callbacks, TraceReporter(TraceEncoderSharedPtr encoder, Driver& driver, Event::Dispatcher& dispatcher); // Http::AsyncClient::Callbacks. - void onSuccess(Http::MessagePtr&&) override; + void onSuccess(Http::ResponseMessagePtr&&) override; void onFailure(Http::AsyncClient::FailureReason) override; private: diff --git a/source/extensions/tracers/lightstep/lightstep_tracer_impl.cc b/source/extensions/tracers/lightstep/lightstep_tracer_impl.cc index 3e70f00a0b..b1584ce684 100644 --- a/source/extensions/tracers/lightstep/lightstep_tracer_impl.cc +++ b/source/extensions/tracers/lightstep/lightstep_tracer_impl.cc @@ -63,7 +63,7 @@ void LightStepDriver::LightStepTransporter::Send(const Protobuf::Message& reques const uint64_t timeout = driver_.runtime().snapshot().getInteger("tracing.lightstep.request_timeout", 5000U); - Http::MessagePtr message = Grpc::Common::prepareHeaders( + Http::RequestMessagePtr message = Grpc::Common::prepareHeaders( driver_.cluster()->name(), lightstep::CollectorServiceFullName(), lightstep::CollectorMethodName(), absl::optional(timeout)); message->body() = Grpc::Common::serializeToGrpcFrame(request); @@ -75,7 +75,7 @@ void LightStepDriver::LightStepTransporter::Send(const Protobuf::Message& reques Http::AsyncClient::RequestOptions().setTimeout(std::chrono::milliseconds(timeout))); } -void LightStepDriver::LightStepTransporter::onSuccess(Http::MessagePtr&& response) { +void LightStepDriver::LightStepTransporter::onSuccess(Http::ResponseMessagePtr&& response) { try { active_request_ = nullptr; Grpc::Common::validateResponse(*response); diff --git a/source/extensions/tracers/lightstep/lightstep_tracer_impl.h b/source/extensions/tracers/lightstep/lightstep_tracer_impl.h index 40491dc57f..1a3249cd2f 100644 --- a/source/extensions/tracers/lightstep/lightstep_tracer_impl.h +++ b/source/extensions/tracers/lightstep/lightstep_tracer_impl.h @@ -82,7 +82,7 @@ class LightStepDriver : public Common::Ot::OpenTracingDriver { lightstep::AsyncTransporter::Callback& callback) override; // Http::AsyncClient::Callbacks - void onSuccess(Http::MessagePtr&& response) override; + void onSuccess(Http::ResponseMessagePtr&& response) override; void onFailure(Http::AsyncClient::FailureReason) override; private: diff --git a/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc b/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc index 1f8915ea68..b5b776dfcf 100644 --- a/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc +++ b/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc @@ -172,7 +172,7 @@ void ReporterImpl::flushSpans() { if (span_buffer_->pendingSpans()) { driver_.tracerStats().spans_sent_.add(span_buffer_->pendingSpans()); const std::string request_body = span_buffer_->serialize(); - Http::MessagePtr message = std::make_unique(); + Http::RequestMessagePtr message = std::make_unique(); message->headers().setReferenceMethod(Http::Headers::get().MethodValues.Post); message->headers().setPath(collector_.endpoint_); message->headers().setHost(driver_.cluster()->name()); @@ -200,7 +200,7 @@ void ReporterImpl::onFailure(Http::AsyncClient::FailureReason) { driver_.tracerStats().reports_failed_.inc(); } -void ReporterImpl::onSuccess(Http::MessagePtr&& http_response) { +void ReporterImpl::onSuccess(Http::ResponseMessagePtr&& http_response) { if (Http::Utility::getResponseStatus(http_response->headers()) != enumToInt(Http::Code::Accepted)) { driver_.tracerStats().reports_dropped_.inc(); diff --git a/source/extensions/tracers/zipkin/zipkin_tracer_impl.h b/source/extensions/tracers/zipkin/zipkin_tracer_impl.h index 94cfd137e4..5e7dca9188 100644 --- a/source/extensions/tracers/zipkin/zipkin_tracer_impl.h +++ b/source/extensions/tracers/zipkin/zipkin_tracer_impl.h @@ -194,7 +194,7 @@ class ReporterImpl : public Reporter, Http::AsyncClient::Callbacks { // Http::AsyncClient::Callbacks. // The callbacks below record Zipkin-span-related stats. - void onSuccess(Http::MessagePtr&&) override; + void onSuccess(Http::ResponseMessagePtr&&) override; void onFailure(Http::AsyncClient::FailureReason) override; /** diff --git a/source/server/config_validation/async_client.cc b/source/server/config_validation/async_client.cc index 7015ab179a..913b679fa2 100644 --- a/source/server/config_validation/async_client.cc +++ b/source/server/config_validation/async_client.cc @@ -6,7 +6,8 @@ namespace Http { ValidationAsyncClient::ValidationAsyncClient(Api::Api& api, Event::TimeSystem& time_system) : dispatcher_(api, time_system) {} -AsyncClient::Request* ValidationAsyncClient::send(MessagePtr&&, Callbacks&, const RequestOptions&) { +AsyncClient::Request* ValidationAsyncClient::send(RequestMessagePtr&&, Callbacks&, + const RequestOptions&) { return nullptr; } diff --git a/source/server/config_validation/async_client.h b/source/server/config_validation/async_client.h index c027638947..c665dc49d1 100644 --- a/source/server/config_validation/async_client.h +++ b/source/server/config_validation/async_client.h @@ -22,7 +22,7 @@ class ValidationAsyncClient : public AsyncClient { ValidationAsyncClient(Api::Api& api, Event::TimeSystem& time_system); // Http::AsyncClient - AsyncClient::Request* send(MessagePtr&& request, Callbacks& callbacks, + AsyncClient::Request* send(RequestMessagePtr&& request, Callbacks& callbacks, const RequestOptions&) override; AsyncClient::Stream* start(StreamCallbacks& callbacks, const StreamOptions&) override; diff --git a/source/server/http/admin.cc b/source/server/http/admin.cc index 0b16a19678..caf563ac90 100644 --- a/source/server/http/admin.cc +++ b/source/server/http/admin.cc @@ -318,7 +318,8 @@ void trimResourceMessage(const Protobuf::FieldMask& field_mask, Protobuf::Messag AdminFilter::AdminFilter(AdminImpl& parent) : parent_(parent) {} -Http::FilterHeadersStatus AdminFilter::decodeHeaders(Http::HeaderMap& headers, bool end_stream) { +Http::FilterHeadersStatus AdminFilter::decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) { request_headers_ = &headers; if (end_stream) { onComplete(); @@ -341,7 +342,7 @@ Http::FilterDataStatus AdminFilter::decodeData(Buffer::Instance& data, bool end_ return Http::FilterDataStatus::StopIterationNoBuffer; } -Http::FilterTrailersStatus AdminFilter::decodeTrailers(Http::HeaderMap&) { +Http::FilterTrailersStatus AdminFilter::decodeTrailers(Http::RequestTrailerMap&) { onComplete(); return Http::FilterTrailersStatus::StopIteration; } @@ -1342,7 +1343,7 @@ void AdminFilter::onComplete() { ENVOY_STREAM_LOG(debug, "request complete: path: {}", *callbacks_, path); Buffer::OwnedImpl response; - Http::HeaderMapPtr header_map{new Http::HeaderMapImpl}; + Http::ResponseHeaderMapPtr header_map{new Http::ResponseHeaderMapImpl}; RELEASE_ASSERT(request_headers_, ""); Http::Code code = parent_.runCallback(path, *header_map, response, *this); populateFallbackResponseHeaders(code, *header_map); @@ -1618,7 +1619,7 @@ bool AdminImpl::removeHandler(const std::string& prefix) { Http::Code AdminImpl::request(absl::string_view path_and_query, absl::string_view method, Http::HeaderMap& response_headers, std::string& body) { AdminFilter filter(*this); - Http::HeaderMapImpl request_headers; + Http::RequestHeaderMapImpl request_headers; request_headers.setMethod(method); filter.decodeHeaders(request_headers, false); Buffer::OwnedImpl response; diff --git a/source/server/http/admin.h b/source/server/http/admin.h index b29dd23420..453650162c 100644 --- a/source/server/http/admin.h +++ b/source/server/http/admin.h @@ -467,9 +467,10 @@ class AdminFilter : public Http::StreamDecoderFilter, void onDestroy() override; // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override { callbacks_ = &callbacks; } diff --git a/test/common/access_log/access_log_formatter_fuzz_test.cc b/test/common/access_log/access_log_formatter_fuzz_test.cc index 4c3bb266b5..2c9dbd233e 100644 --- a/test/common/access_log/access_log_formatter_fuzz_test.cc +++ b/test/common/access_log/access_log_formatter_fuzz_test.cc @@ -12,9 +12,12 @@ DEFINE_PROTO_FUZZER(const test::common::access_log::TestCase& input) { try { std::vector formatters = AccessLog::AccessLogFormatParser::parse(input.format()); - const auto& request_headers = Fuzz::fromHeaders(input.request_headers()); - const auto& response_headers = Fuzz::fromHeaders(input.response_headers()); - const auto& response_trailers = Fuzz::fromHeaders(input.response_trailers()); + const auto& request_headers = + Fuzz::fromHeaders(input.request_headers()); + const auto& response_headers = + Fuzz::fromHeaders(input.response_headers()); + const auto& response_trailers = + Fuzz::fromHeaders(input.response_trailers()); const auto& stream_info = Fuzz::fromStreamInfo(input.stream_info()); for (const auto& it : formatters) { it->format(request_headers, response_headers, response_trailers, stream_info); diff --git a/test/common/access_log/access_log_formatter_speed_test.cc b/test/common/access_log/access_log_formatter_speed_test.cc index a0c3611be5..fecc7f35cf 100644 --- a/test/common/access_log/access_log_formatter_speed_test.cc +++ b/test/common/access_log/access_log_formatter_speed_test.cc @@ -19,9 +19,9 @@ namespace Envoy { static void BM_AccessLogFormatter(benchmark::State& state) { size_t output_bytes = 0; - Http::TestHeaderMapImpl request_headers; - Http::TestHeaderMapImpl response_headers; - Http::TestHeaderMapImpl response_trailers; + Http::TestRequestHeaderMapImpl request_headers; + Http::TestResponseHeaderMapImpl response_headers; + Http::TestResponseTrailerMapImpl response_trailers; for (auto _ : state) { output_bytes += formatter->format(request_headers, response_headers, response_trailers, *stream_info) @@ -33,9 +33,9 @@ BENCHMARK(BM_AccessLogFormatter); static void BM_JsonAccessLogFormatter(benchmark::State& state) { size_t output_bytes = 0; - Http::TestHeaderMapImpl request_headers; - Http::TestHeaderMapImpl response_headers; - Http::TestHeaderMapImpl response_trailers; + Http::TestRequestHeaderMapImpl request_headers; + Http::TestResponseHeaderMapImpl response_headers; + Http::TestResponseTrailerMapImpl response_trailers; for (auto _ : state) { output_bytes += json_formatter->format(request_headers, response_headers, response_trailers, *stream_info) @@ -47,9 +47,9 @@ BENCHMARK(BM_JsonAccessLogFormatter); static void BM_TypedJsonAccessLogFormatter(benchmark::State& state) { size_t output_bytes = 0; - Http::TestHeaderMapImpl request_headers; - Http::TestHeaderMapImpl response_headers; - Http::TestHeaderMapImpl response_trailers; + Http::TestRequestHeaderMapImpl request_headers; + Http::TestResponseHeaderMapImpl response_headers; + Http::TestResponseTrailerMapImpl response_trailers; for (auto _ : state) { output_bytes += typed_json_formatter ->format(request_headers, response_headers, response_trailers, *stream_info) diff --git a/test/common/access_log/access_log_impl_test.cc b/test/common/access_log/access_log_impl_test.cc index e61b566c34..21142ef315 100644 --- a/test/common/access_log/access_log_impl_test.cc +++ b/test/common/access_log/access_log_impl_test.cc @@ -52,9 +52,9 @@ class AccessLogImplTest : public testing::Test { ON_CALL(*file_, write(_)).WillByDefault(SaveArg<0>(&output_)); } - Http::TestHeaderMapImpl request_headers_{{":method", "GET"}, {":path", "/"}}; - Http::TestHeaderMapImpl response_headers_; - Http::TestHeaderMapImpl response_trailers_; + Http::TestRequestHeaderMapImpl request_headers_{{":method", "GET"}, {":path", "/"}}; + Http::TestResponseHeaderMapImpl response_headers_; + Http::TestResponseTrailerMapImpl response_trailers_; TestStreamInfo stream_info_; std::shared_ptr file_; StringViewSaver output_; @@ -639,9 +639,9 @@ TEST(AccessLogFilterTest, DurationWithRuntimeKey) { envoy::config::accesslog::v3::AccessLogFilter config; TestUtility::loadFromYaml(filter_yaml, config); DurationFilter filter(config.duration_filter(), runtime); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, {":path", "/"}}; - Http::TestHeaderMapImpl response_headers; - Http::TestHeaderMapImpl response_trailers; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, {":path", "/"}}; + Http::TestResponseHeaderMapImpl response_headers; + Http::TestResponseTrailerMapImpl response_trailers; TestStreamInfo stream_info; stream_info.end_time_ = stream_info.startTimeMonotonic() + std::chrono::microseconds(100000); @@ -677,9 +677,9 @@ TEST(AccessLogFilterTest, StatusCodeWithRuntimeKey) { TestUtility::loadFromYaml(filter_yaml, config); StatusCodeFilter filter(config.status_code_filter(), runtime); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, {":path", "/"}}; - Http::TestHeaderMapImpl response_headers; - Http::TestHeaderMapImpl response_trailers; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, {":path", "/"}}; + Http::TestResponseHeaderMapImpl response_headers; + Http::TestResponseTrailerMapImpl response_trailers; TestStreamInfo info; info.response_code_ = 400; diff --git a/test/common/config/datasource_test.cc b/test/common/config/datasource_test.cc index ecfd917ef9..c871434742 100644 --- a/test/common/config/datasource_test.cc +++ b/test/common/config/datasource_test.cc @@ -80,7 +80,7 @@ TEST_F(AsyncDataSourceTest, loadRemoteDataSourceReturnFailure) { EXPECT_CALL(cm_, httpAsyncClientForCluster("cluster_1")).WillOnce(ReturnRef(cm_.async_client_)); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callbacks.onFailure(Envoy::Http::AsyncClient::FailureReason::Reset); return nullptr; @@ -124,10 +124,11 @@ TEST_F(AsyncDataSourceTest, loadRemoteDataSourceSuccessWith503) { EXPECT_CALL(cm_, httpAsyncClientForCluster("cluster_1")).WillOnce(ReturnRef(cm_.async_client_)); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - callbacks.onSuccess(Http::MessagePtr{new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "503"}}})}); + callbacks.onSuccess( + Http::ResponseMessagePtr{new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "503"}}})}); return nullptr; })); @@ -168,10 +169,11 @@ TEST_F(AsyncDataSourceTest, loadRemoteDataSourceSuccessWithEmptyBody) { EXPECT_CALL(cm_, httpAsyncClientForCluster("cluster_1")).WillOnce(ReturnRef(cm_.async_client_)); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - callbacks.onSuccess(Http::MessagePtr{new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})}); + callbacks.onSuccess( + Http::ResponseMessagePtr{new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}}})}); return nullptr; })); @@ -215,10 +217,11 @@ TEST_F(AsyncDataSourceTest, loadRemoteDataSourceSuccessIncorrectSha256) { EXPECT_CALL(cm_, httpAsyncClientForCluster("cluster_1")).WillOnce(ReturnRef(cm_.async_client_)); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - Http::MessagePtr response(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response( + new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response->body() = std::make_unique(body); callbacks.onSuccess(std::move(response)); @@ -264,10 +267,11 @@ TEST_F(AsyncDataSourceTest, loadRemoteDataSourceSuccess) { EXPECT_CALL(cm_, httpAsyncClientForCluster("cluster_1")).WillOnce(ReturnRef(cm_.async_client_)); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - Http::MessagePtr response(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response( + new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response->body() = std::make_unique(body); callbacks.onSuccess(std::move(response)); @@ -311,10 +315,11 @@ TEST_F(AsyncDataSourceTest, loadRemoteDataSourceExpectNetworkFailure) { EXPECT_CALL(cm_, httpAsyncClientForCluster("cluster_1")).WillOnce(ReturnRef(cm_.async_client_)); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - callbacks.onSuccess(Http::MessagePtr{new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "503"}}})}); + callbacks.onSuccess( + Http::ResponseMessagePtr{new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "503"}}})}); return nullptr; })); @@ -350,10 +355,11 @@ TEST_F(AsyncDataSourceTest, loadRemoteDataSourceDoNotAllowEmptyExpectNetworkFail EXPECT_CALL(cm_, httpAsyncClientForCluster("cluster_1")).WillOnce(ReturnRef(cm_.async_client_)); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - callbacks.onSuccess(Http::MessagePtr{new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "503"}}})}); + callbacks.onSuccess( + Http::ResponseMessagePtr{new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "503"}}})}); return nullptr; })); @@ -388,10 +394,11 @@ TEST_F(AsyncDataSourceTest, loadRemoteDataSourceExpectInvalidData) { EXPECT_CALL(cm_, httpAsyncClientForCluster("cluster_1")).WillOnce(ReturnRef(cm_.async_client_)); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - Http::MessagePtr response(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response( + new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response->body() = std::make_unique(body); callbacks.onSuccess(std::move(response)); @@ -432,10 +439,11 @@ TEST_F(AsyncDataSourceTest, datasourceReleasedBeforeFetchingData) { EXPECT_CALL(cm_, httpAsyncClientForCluster("cluster_1")).WillOnce(ReturnRef(cm_.async_client_)); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - Http::MessagePtr response(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response( + new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response->body() = std::make_unique(body); callbacks.onSuccess(std::move(response)); diff --git a/test/common/config/grpc_stream_test.cc b/test/common/config/grpc_stream_test.cc index 3629aecee0..0b0eb8e50c 100644 --- a/test/common/config/grpc_stream_test.cc +++ b/test/common/config/grpc_stream_test.cc @@ -125,11 +125,11 @@ TEST_F(GrpcStreamTest, QueueSizeStat) { // Just to add coverage to the no-op implementations of these callbacks (without exposing us to // crashes from a badly behaved peer like NOT_IMPLEMENTED_GCOVR_EXCL_LINE would). TEST_F(GrpcStreamTest, HeaderTrailerJustForCodeCoverage) { - Http::HeaderMapPtr response_headers{new Http::TestHeaderMapImpl{}}; + Http::ResponseHeaderMapPtr response_headers{new Http::TestResponseHeaderMapImpl{}}; grpc_stream_.onReceiveInitialMetadata(std::move(response_headers)); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; grpc_stream_.onCreateInitialMetadata(request_headers); - Http::HeaderMapPtr trailers{new Http::TestHeaderMapImpl{}}; + Http::ResponseTrailerMapPtr trailers{new Http::TestResponseTrailerMapImpl{}}; grpc_stream_.onReceiveTrailingMetadata(std::move(trailers)); } diff --git a/test/common/config/http_subscription_impl_test.cc b/test/common/config/http_subscription_impl_test.cc index 8726589890..98af34d6d4 100644 --- a/test/common/config/http_subscription_impl_test.cc +++ b/test/common/config/http_subscription_impl_test.cc @@ -29,8 +29,9 @@ TEST_F(HttpSubscriptionImplTest, OnRequestReset) { // Validate that the client can recover from bad JSON responses. TEST_F(HttpSubscriptionImplTest, BadJsonRecovery) { startSubscription({"cluster0", "cluster1"}); - Http::HeaderMapPtr response_headers{new Http::TestHeaderMapImpl{{":status", "200"}}}; - Http::MessagePtr message{new Http::ResponseMessageImpl(std::move(response_headers))}; + Http::ResponseHeaderMapPtr response_headers{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}}}; + Http::ResponseMessagePtr message{new Http::ResponseMessageImpl(std::move(response_headers))}; message->body() = std::make_unique(";!@#badjso n"); EXPECT_CALL(random_gen_, random()).WillOnce(Return(0)); EXPECT_CALL(*timer_, enableTimer(_, _)); diff --git a/test/common/config/http_subscription_test_harness.h b/test/common/config/http_subscription_test_harness.h index 42e13aed78..c570086fa6 100644 --- a/test/common/config/http_subscription_test_harness.h +++ b/test/common/config/http_subscription_test_harness.h @@ -66,7 +66,7 @@ class HttpSubscriptionTestHarness : public SubscriptionTestHarness { UNREFERENCED_PARAMETER(expect_node); EXPECT_CALL(cm_, httpAsyncClientForCluster("eds_cluster")); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) - .WillOnce(Invoke([this, cluster_names, version](Http::MessagePtr& request, + .WillOnce(Invoke([this, cluster_names, version](Http::RequestMessagePtr& request, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) { http_callbacks_ = &callbacks; @@ -136,8 +136,9 @@ class HttpSubscriptionTestHarness : public SubscriptionTestHarness { response_json += "]}"; envoy::service::discovery::v3::DiscoveryResponse response_pb; TestUtility::loadFromJson(response_json, response_pb); - Http::HeaderMapPtr response_headers{new Http::TestHeaderMapImpl{{":status", response_code}}}; - Http::MessagePtr message{new Http::ResponseMessageImpl(std::move(response_headers))}; + Http::ResponseHeaderMapPtr response_headers{ + new Http::TestResponseHeaderMapImpl{{":status", response_code}}}; + Http::ResponseMessagePtr message{new Http::ResponseMessageImpl(std::move(response_headers))}; message->body() = std::make_unique(response_json); if (modify) { diff --git a/test/common/config/subscription_factory_impl_test.cc b/test/common/config/subscription_factory_impl_test.cc index 9f48b2060c..fe3e4c665f 100644 --- a/test/common/config/subscription_factory_impl_test.cc +++ b/test/common/config/subscription_factory_impl_test.cc @@ -256,7 +256,7 @@ TEST_F(SubscriptionFactoryTest, HttpSubscription) { EXPECT_CALL(dispatcher_, createTimer_(_)).Times(2); EXPECT_CALL(cm_, httpAsyncClientForCluster("static_cluster")); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) - .WillOnce(Invoke([this](Http::MessagePtr& request, Http::AsyncClient::Callbacks&, + .WillOnce(Invoke([this](Http::RequestMessagePtr& request, Http::AsyncClient::Callbacks&, const Http::AsyncClient::RequestOptions&) { EXPECT_EQ("POST", std::string(request->headers().Method()->value().getStringView())); EXPECT_EQ("static_cluster", diff --git a/test/common/grpc/common_test.cc b/test/common/grpc/common_test.cc index 312707a693..caecff21fb 100644 --- a/test/common/grpc/common_test.cc +++ b/test/common/grpc/common_test.cc @@ -149,7 +149,7 @@ TEST(GrpcContextTest, ToGrpcTimeout) { TEST(GrpcContextTest, PrepareHeaders) { { - Http::MessagePtr message = + Http::RequestMessagePtr message = Common::prepareHeaders("cluster", "service_name", "method_name", absl::nullopt); EXPECT_EQ("POST", message->headers().Method()->value().getStringView()); @@ -158,8 +158,8 @@ TEST(GrpcContextTest, PrepareHeaders) { EXPECT_EQ("application/grpc", message->headers().ContentType()->value().getStringView()); } { - Http::MessagePtr message = Common::prepareHeaders("cluster", "service_name", "method_name", - absl::optional(1)); + Http::RequestMessagePtr message = Common::prepareHeaders( + "cluster", "service_name", "method_name", absl::optional(1)); EXPECT_EQ("POST", message->headers().Method()->value().getStringView()); EXPECT_EQ("/service_name/method_name", message->headers().Path()->value().getStringView()); @@ -168,8 +168,8 @@ TEST(GrpcContextTest, PrepareHeaders) { EXPECT_EQ("1m", message->headers().GrpcTimeout()->value().getStringView()); } { - Http::MessagePtr message = Common::prepareHeaders("cluster", "service_name", "method_name", - absl::optional(1)); + Http::RequestMessagePtr message = Common::prepareHeaders( + "cluster", "service_name", "method_name", absl::optional(1)); EXPECT_EQ("POST", message->headers().Method()->value().getStringView()); EXPECT_EQ("/service_name/method_name", message->headers().Path()->value().getStringView()); @@ -178,8 +178,8 @@ TEST(GrpcContextTest, PrepareHeaders) { EXPECT_EQ("1000m", message->headers().GrpcTimeout()->value().getStringView()); } { - Http::MessagePtr message = Common::prepareHeaders("cluster", "service_name", "method_name", - absl::optional(1)); + Http::RequestMessagePtr message = Common::prepareHeaders( + "cluster", "service_name", "method_name", absl::optional(1)); EXPECT_EQ("POST", message->headers().Method()->value().getStringView()); EXPECT_EQ("/service_name/method_name", message->headers().Path()->value().getStringView()); @@ -188,8 +188,8 @@ TEST(GrpcContextTest, PrepareHeaders) { EXPECT_EQ("60000m", message->headers().GrpcTimeout()->value().getStringView()); } { - Http::MessagePtr message = Common::prepareHeaders("cluster", "service_name", "method_name", - absl::optional(1)); + Http::RequestMessagePtr message = Common::prepareHeaders( + "cluster", "service_name", "method_name", absl::optional(1)); EXPECT_EQ("POST", message->headers().Method()->value().getStringView()); EXPECT_EQ("/service_name/method_name", message->headers().Path()->value().getStringView()); @@ -198,7 +198,7 @@ TEST(GrpcContextTest, PrepareHeaders) { EXPECT_EQ("3600000m", message->headers().GrpcTimeout()->value().getStringView()); } { - Http::MessagePtr message = Common::prepareHeaders( + Http::RequestMessagePtr message = Common::prepareHeaders( "cluster", "service_name", "method_name", absl::optional(100000000)); EXPECT_EQ("POST", message->headers().Method()->value().getStringView()); @@ -208,7 +208,7 @@ TEST(GrpcContextTest, PrepareHeaders) { EXPECT_EQ("99999999H", message->headers().GrpcTimeout()->value().getStringView()); } { - Http::MessagePtr message = + Http::RequestMessagePtr message = Common::prepareHeaders("cluster", "service_name", "method_name", absl::optional(100000000000)); @@ -301,50 +301,54 @@ TEST(GrpcContextTest, IsGrpcResponseHeader) { TEST(GrpcContextTest, ValidateResponse) { { Http::ResponseMessageImpl response( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}}); - response.trailers(Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{"grpc-status", "0"}}}); + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}}); + response.trailers( + Http::ResponseTrailerMapPtr{new Http::TestResponseTrailerMapImpl{{"grpc-status", "0"}}}); EXPECT_NO_THROW(Common::validateResponse(response)); } { Http::ResponseMessageImpl response( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "503"}}}); + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "503"}}}); EXPECT_THROW_WITH_MESSAGE(Common::validateResponse(response), Exception, "non-200 response code"); } { Http::ResponseMessageImpl response( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}}); - response.trailers(Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{"grpc-status", "100"}}}); + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}}); + response.trailers( + Http::ResponseTrailerMapPtr{new Http::TestResponseTrailerMapImpl{{"grpc-status", "100"}}}); EXPECT_THROW_WITH_MESSAGE(Common::validateResponse(response), Exception, "bad grpc-status trailer"); } { Http::ResponseMessageImpl response( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}}); - response.trailers(Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{"grpc-status", "4"}}}); + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}}); + response.trailers( + Http::ResponseTrailerMapPtr{new Http::TestResponseTrailerMapImpl{{"grpc-status", "4"}}}); EXPECT_THROW_WITH_MESSAGE(Common::validateResponse(response), Exception, ""); } { Http::ResponseMessageImpl response( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}}); - response.trailers(Http::HeaderMapPtr{ - new Http::TestHeaderMapImpl{{"grpc-status", "4"}, {"grpc-message", "custom error"}}}); + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}}); + response.trailers(Http::ResponseTrailerMapPtr{new Http::TestResponseTrailerMapImpl{ + {"grpc-status", "4"}, {"grpc-message", "custom error"}}}); EXPECT_THROW_WITH_MESSAGE(Common::validateResponse(response), Exception, "custom error"); } { - Http::ResponseMessageImpl response(Http::HeaderMapPtr{ - new Http::TestHeaderMapImpl{{":status", "200"}, {"grpc-status", "100"}}}); + Http::ResponseMessageImpl response(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "100"}}}); EXPECT_THROW_WITH_MESSAGE(Common::validateResponse(response), Exception, "bad grpc-status header"); } { - Http::ResponseMessageImpl response( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}, {"grpc-status", "4"}}}); + Http::ResponseMessageImpl response(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "4"}}}); EXPECT_THROW_WITH_MESSAGE(Common::validateResponse(response), Exception, ""); } { - Http::ResponseMessageImpl response(Http::HeaderMapPtr{new Http::TestHeaderMapImpl{ - {":status", "200"}, {"grpc-status", "4"}, {"grpc-message", "custom error"}}}); + Http::ResponseMessageImpl response( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{ + {":status", "200"}, {"grpc-status", "4"}, {"grpc-message", "custom error"}}}); EXPECT_THROW_WITH_MESSAGE(Common::validateResponse(response), Exception, "custom error"); } } diff --git a/test/common/grpc/grpc_client_integration_test_harness.h b/test/common/grpc/grpc_client_integration_test_harness.h index 837538af95..5dff4a7f6d 100644 --- a/test/common/grpc/grpc_client_integration_test_harness.h +++ b/test/common/grpc/grpc_client_integration_test_harness.h @@ -134,7 +134,7 @@ class HelloworldStream : public MockAsyncStreamCallbacks } void sendServerInitialMetadata(const TestMetadata& metadata) { - Http::HeaderMapPtr reply_headers{new Http::TestHeaderMapImpl{{":status", "200"}}}; + Http::HeaderMapPtr reply_headers{new Http::TestResponseHeaderMapImpl{{":status", "200"}}}; for (auto& value : metadata) { reply_headers->addReference(value.first, value.second); } diff --git a/test/common/http/async_client_impl_test.cc b/test/common/http/async_client_impl_test.cc index c45d31faca..c0b8c680e3 100644 --- a/test/common/http/async_client_impl_test.cc +++ b/test/common/http/async_client_impl_test.cc @@ -53,9 +53,10 @@ class AsyncClientImplTest : public testing::Test { } void expectSuccess(uint64_t code) { - EXPECT_CALL(callbacks_, onSuccess_(_)).WillOnce(Invoke([code](Message* response) -> void { - EXPECT_EQ(code, Utility::getResponseStatus(response->headers())); - })); + EXPECT_CALL(callbacks_, onSuccess_(_)) + .WillOnce(Invoke([code](ResponseMessage* response) -> void { + EXPECT_EQ(code, Utility::getResponseStatus(response->headers())); + })); } void expectResponseHeaders(MockAsyncClientStreamCallbacks& callbacks, uint64_t code, @@ -66,7 +67,7 @@ class AsyncClientImplTest : public testing::Test { })); } - MessagePtr message_{new RequestMessageImpl()}; + RequestMessagePtr message_{new RequestMessageImpl()}; Stats::MockIsolatedStatsStore stats_store_; MockAsyncClientCallbacks callbacks_; MockAsyncClientStreamCallbacks stream_callbacks_; @@ -100,7 +101,7 @@ TEST_F(AsyncClientImplTest, BasicStream) { return nullptr; })); - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); headers.addCopy("x-envoy-internal", "true"); headers.addCopy("x-forwarded-for", "127.0.0.1"); @@ -288,7 +289,7 @@ TEST_F(AsyncClientImplTest, BasicHashPolicy) { TEST_F(AsyncClientImplTest, Retry) { ON_CALL(runtime_.snapshot_, featureEnabled("upstream.use_retry", 100)) .WillByDefault(Return(true)); - Message* message_copy = message_.get(); + RequestMessage* message_copy = message_.get(); message_->body() = std::make_unique("test body"); Buffer::Instance& data = *message_->body(); @@ -344,7 +345,7 @@ TEST_F(AsyncClientImplTest, RetryWithStream) { return nullptr; })); - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(stream_encoder_, encodeHeaders(HeaderMapEqualRef(&headers), false)); EXPECT_CALL(stream_encoder_, encodeData(BufferEqual(body.get()), true)); @@ -392,7 +393,7 @@ TEST_F(AsyncClientImplTest, MultipleStreams) { return nullptr; })); - TestHeaderMapImpl headers(message_->headers()); + TestRequestHeaderMapImpl headers(message_->headers()); EXPECT_CALL(stream_encoder_, encodeHeaders(HeaderMapEqualRef(&headers), false)); EXPECT_CALL(stream_encoder_, encodeData(BufferEqual(body.get()), true)); @@ -418,7 +419,7 @@ TEST_F(AsyncClientImplTest, MultipleStreams) { return nullptr; })); - TestHeaderMapImpl headers2(message_->headers()); + TestRequestHeaderMapImpl headers2(message_->headers()); EXPECT_CALL(stream_encoder2, encodeHeaders(HeaderMapEqualRef(&headers2), false)); EXPECT_CALL(stream_encoder2, encodeData(BufferEqual(body2.get()), true)); @@ -458,7 +459,7 @@ TEST_F(AsyncClientImplTest, MultipleRequests) { client_.send(std::move(message_), callbacks_, AsyncClient::RequestOptions()); // Send request 2. - MessagePtr message2{new RequestMessageImpl()}; + RequestMessagePtr message2{new RequestMessageImpl()}; HttpTestUtility::addDefaultHeaders(message2->headers()); NiceMock stream_encoder2; ResponseDecoder* response_decoder2{}; @@ -516,7 +517,7 @@ TEST_F(AsyncClientImplTest, StreamAndRequest) { return nullptr; })); - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(stream_encoder2, encodeHeaders(HeaderMapEqualRef(&headers), false)); EXPECT_CALL(stream_encoder2, encodeData(BufferEqual(body.get()), true)); @@ -543,9 +544,9 @@ TEST_F(AsyncClientImplTest, StreamAndRequest) { TEST_F(AsyncClientImplTest, StreamWithTrailers) { Buffer::InstancePtr body{new Buffer::OwnedImpl("test body")}; - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); - TestHeaderMapImpl trailers{{"some", "request_trailer"}}; + TestRequestTrailerMapImpl trailers{{"some", "request_trailer"}}; EXPECT_CALL(cm_.conn_pool_, newStream(_, _)) .WillOnce(Invoke([&](ResponseDecoder& decoder, @@ -561,7 +562,7 @@ TEST_F(AsyncClientImplTest, StreamWithTrailers) { expectResponseHeaders(stream_callbacks_, 200, false); EXPECT_CALL(stream_callbacks_, onData(BufferEqual(body.get()), false)); - TestHeaderMapImpl expected_trailers{{"some", "trailer"}}; + TestResponseTrailerMapImpl expected_trailers{{"some", "trailer"}}; EXPECT_CALL(stream_callbacks_, onTrailers_(HeaderMapEqualRef(&expected_trailers))); EXPECT_CALL(stream_callbacks_, onComplete()); @@ -631,7 +632,7 @@ TEST_F(AsyncClientImplTest, LocalResetAfterStreamStart) { return nullptr; })); - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); headers.addCopy("x-envoy-internal", "true"); headers.addCopy("x-forwarded-for", "127.0.0.1"); @@ -640,7 +641,7 @@ TEST_F(AsyncClientImplTest, LocalResetAfterStreamStart) { EXPECT_CALL(stream_encoder_, encodeHeaders(HeaderMapEqualRef(&headers), false)); EXPECT_CALL(stream_encoder_, encodeData(BufferEqual(body.get()), false)); - TestHeaderMapImpl expected_headers{{":status", "200"}}; + TestResponseHeaderMapImpl expected_headers{{":status", "200"}}; EXPECT_CALL(stream_callbacks_, onHeaders_(HeaderMapEqualRef(&expected_headers), false)); EXPECT_CALL(stream_callbacks_, onData(BufferEqual(body.get()), false)); EXPECT_CALL(stream_callbacks_, onReset()); @@ -667,7 +668,7 @@ TEST_F(AsyncClientImplTest, SendDataAfterRemoteClosure) { return nullptr; })); - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); headers.addCopy("x-envoy-internal", "true"); headers.addCopy("x-forwarded-for", "127.0.0.1"); @@ -675,7 +676,7 @@ TEST_F(AsyncClientImplTest, SendDataAfterRemoteClosure) { EXPECT_CALL(stream_encoder_, encodeHeaders(HeaderMapEqualRef(&headers), false)); - TestHeaderMapImpl expected_headers{{":status", "200"}}; + TestResponseHeaderMapImpl expected_headers{{":status", "200"}}; EXPECT_CALL(stream_callbacks_, onHeaders_(HeaderMapEqualRef(&expected_headers), false)); EXPECT_CALL(stream_callbacks_, onData(BufferEqual(body.get()), true)); EXPECT_CALL(stream_callbacks_, onComplete()); @@ -702,18 +703,18 @@ TEST_F(AsyncClientImplTest, SendTrailersRemoteClosure) { return nullptr; })); - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); headers.addCopy("x-envoy-internal", "true"); headers.addCopy("x-forwarded-for", "127.0.0.1"); headers.addCopy(":scheme", "http"); - TestHeaderMapImpl trailers; + TestRequestTrailerMapImpl trailers; trailers.addCopy("x-test-trailer", "1"); EXPECT_CALL(stream_encoder_, encodeHeaders(HeaderMapEqualRef(&headers), false)); - TestHeaderMapImpl expected_headers{{":status", "200"}}; + TestResponseHeaderMapImpl expected_headers{{":status", "200"}}; EXPECT_CALL(stream_callbacks_, onHeaders_(HeaderMapEqualRef(&expected_headers), false)); EXPECT_CALL(stream_callbacks_, onData(BufferEqual(body.get()), true)); EXPECT_CALL(stream_callbacks_, onComplete()); @@ -741,7 +742,7 @@ TEST_F(AsyncClientImplTest, ResetInOnHeaders) { return nullptr; })); - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); headers.addCopy("x-envoy-internal", "true"); headers.addCopy("x-forwarded-for", "127.0.0.1"); @@ -752,7 +753,7 @@ TEST_F(AsyncClientImplTest, ResetInOnHeaders) { AsyncClient::Stream* stream = client_.start(stream_callbacks_, AsyncClient::StreamOptions()); - TestHeaderMapImpl expected_headers{{":status", "200"}}; + TestResponseHeaderMapImpl expected_headers{{":status", "200"}}; EXPECT_CALL(stream_callbacks_, onHeaders_(HeaderMapEqualRef(&expected_headers), false)) .WillOnce(Invoke([&stream](HeaderMap&, bool) { stream->reset(); })); EXPECT_CALL(stream_callbacks_, onData(_, _)).Times(0); @@ -778,7 +779,7 @@ TEST_F(AsyncClientImplTest, RemoteResetAfterStreamStart) { return nullptr; })); - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); headers.addCopy("x-envoy-internal", "true"); headers.addCopy("x-forwarded-for", "127.0.0.1"); @@ -787,7 +788,7 @@ TEST_F(AsyncClientImplTest, RemoteResetAfterStreamStart) { EXPECT_CALL(stream_encoder_, encodeHeaders(HeaderMapEqualRef(&headers), false)); EXPECT_CALL(stream_encoder_, encodeData(BufferEqual(body.get()), false)); - TestHeaderMapImpl expected_headers{{":status", "200"}}; + TestResponseHeaderMapImpl expected_headers{{":status", "200"}}; EXPECT_CALL(stream_callbacks_, onHeaders_(HeaderMapEqualRef(&expected_headers), false)); EXPECT_CALL(stream_callbacks_, onData(BufferEqual(body.get()), false)); EXPECT_CALL(stream_callbacks_, onReset()); @@ -1018,7 +1019,7 @@ TEST_F(AsyncClientImplTest, StreamTimeoutHeadReply) { return nullptr; })); - MessagePtr message{new RequestMessageImpl()}; + RequestMessagePtr message{new RequestMessageImpl()}; HttpTestUtility::addDefaultHeaders(message->headers(), "HEAD"); EXPECT_CALL(stream_encoder_, encodeHeaders(HeaderMapEqualRef(&message->headers()), true)); timer_ = new NiceMock(&dispatcher_); @@ -1150,7 +1151,7 @@ TEST_F(AsyncClientImplTest, MultipleDataStream) { return nullptr; })); - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); headers.addCopy("x-envoy-internal", "true"); headers.addCopy("x-forwarded-for", "127.0.0.1"); @@ -1159,7 +1160,7 @@ TEST_F(AsyncClientImplTest, MultipleDataStream) { EXPECT_CALL(stream_encoder_, encodeHeaders(HeaderMapEqualRef(&headers), false)); EXPECT_CALL(stream_encoder_, encodeData(BufferEqual(body.get()), false)); - TestHeaderMapImpl expected_headers{{":status", "200"}}; + TestResponseHeaderMapImpl expected_headers{{":status", "200"}}; EXPECT_CALL(stream_callbacks_, onHeaders_(HeaderMapEqualRef(&expected_headers), false)); EXPECT_CALL(stream_callbacks_, onData(BufferEqual(body.get()), false)); @@ -1187,7 +1188,7 @@ TEST_F(AsyncClientImplTest, MultipleDataStream) { } TEST_F(AsyncClientImplTest, WatermarkCallbacks) { - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); AsyncClient::Stream* stream = client_.start(stream_callbacks_, AsyncClient::StreamOptions()); stream->sendHeaders(headers, false); @@ -1199,7 +1200,7 @@ TEST_F(AsyncClientImplTest, WatermarkCallbacks) { } TEST_F(AsyncClientImplTest, RdsGettersTest) { - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); AsyncClient::Stream* stream = client_.start(stream_callbacks_, AsyncClient::StreamOptions()); stream->sendHeaders(headers, false); @@ -1223,7 +1224,7 @@ TEST_F(AsyncClientImplTest, RdsGettersTest) { } TEST_F(AsyncClientImplTest, DumpState) { - TestHeaderMapImpl headers; + TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); AsyncClient::Stream* stream = client_.start(stream_callbacks_, AsyncClient::StreamOptions()); Http::StreamDecoderFilterCallbacks* filter_callbacks = diff --git a/test/common/http/codec_impl_fuzz_test.cc b/test/common/http/codec_impl_fuzz_test.cc index 428d253322..260c886058 100644 --- a/test/common/http/codec_impl_fuzz_test.cc +++ b/test/common/http/codec_impl_fuzz_test.cc @@ -36,8 +36,8 @@ namespace Http { // debugging. constexpr bool DebugMode = false; -Http::TestHeaderMapImpl fromSanitizedHeaders(const test::fuzz::Headers& headers) { - return Fuzz::fromHeaders(headers, {"transfer-encoding"}); +template T fromSanitizedHeaders(const test::fuzz::Headers& headers) { + return Fuzz::fromHeaders(headers, {"transfer-encoding"}); } // Convert from test proto Http1ServerSettings to Http1Settings. @@ -115,7 +115,8 @@ class HttpStream : public LinkedObject { } } request_, response_; - HttpStream(ClientConnection& client, const TestHeaderMapImpl& request_headers, bool end_stream) { + HttpStream(ClientConnection& client, const TestRequestHeaderMapImpl& request_headers, + bool end_stream) { request_.request_encoder_ = &client.newStream(response_.response_decoder_); ON_CALL(request_.stream_callbacks_, onResetStream(_, _)) .WillByDefault(InvokeWithoutArgs([this] { @@ -172,8 +173,8 @@ class HttpStream : public LinkedObject { switch (directional_action.directional_action_selector_case()) { case test::common::http::DirectionalAction::kContinueHeaders: { if (state.isLocalOpen() && state.stream_state_ == StreamState::PendingHeaders) { - Http::TestHeaderMapImpl headers = - fromSanitizedHeaders(directional_action.continue_headers()); + auto headers = + fromSanitizedHeaders(directional_action.continue_headers()); headers.setReferenceKey(Headers::get().Status, "100"); state.response_encoder_->encode100ContinueHeaders(headers); } @@ -181,14 +182,17 @@ class HttpStream : public LinkedObject { } case test::common::http::DirectionalAction::kHeaders: { if (state.isLocalOpen() && state.stream_state_ == StreamState::PendingHeaders) { - auto headers = fromSanitizedHeaders(directional_action.headers()); - if (response && headers.Status() == nullptr) { - headers.setReferenceKey(Headers::get().Status, "200"); - } if (response) { + auto headers = + fromSanitizedHeaders(directional_action.headers()); + if (headers.Status() == nullptr) { + headers.setReferenceKey(Headers::get().Status, "200"); + } state.response_encoder_->encodeHeaders(headers, end_stream); } else { - state.request_encoder_->encodeHeaders(headers, end_stream); + state.request_encoder_->encodeHeaders( + fromSanitizedHeaders(directional_action.headers()), + end_stream); } if (end_stream) { state.closeLocal(); @@ -230,10 +234,10 @@ class HttpStream : public LinkedObject { if (state.isLocalOpen() && state.stream_state_ == StreamState::PendingDataOrTrailers) { if (response) { state.response_encoder_->encodeTrailers( - fromSanitizedHeaders(directional_action.trailers())); + fromSanitizedHeaders(directional_action.trailers())); } else { state.request_encoder_->encodeTrailers( - fromSanitizedHeaders(directional_action.trailers())); + fromSanitizedHeaders(directional_action.trailers())); } state.stream_state_ = StreamState::Closed; state.closeLocal(); @@ -471,7 +475,8 @@ void codecFuzz(const test::common::http::CodecImplFuzzTestCase& input, HttpVersi } } HttpStreamPtr stream = std::make_unique( - *client, fromSanitizedHeaders(action.new_stream().request_headers()), + *client, + fromSanitizedHeaders(action.new_stream().request_headers()), action.new_stream().end_stream()); stream->moveIntoListBack(std::move(stream), pending_streams); break; diff --git a/test/common/http/codec_wrappers_test.cc b/test/common/http/codec_wrappers_test.cc index 6f690cdbb5..ea481bfa22 100644 --- a/test/common/http/codec_wrappers_test.cc +++ b/test/common/http/codec_wrappers_test.cc @@ -26,7 +26,7 @@ TEST(RequestEncoderWrapper, HeaderOnlyEncode) { EXPECT_CALL(wrapper.innerEncoder(), encodeHeaders(_, true)); wrapper.encodeHeaders( - TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}, {":authority", "foo"}}, true); + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}, {":authority", "foo"}}, true); EXPECT_TRUE(wrapper.encodeComplete()); } @@ -35,7 +35,7 @@ TEST(RequestEncoderWrapper, HeaderAndBodyEncode) { EXPECT_CALL(wrapper.innerEncoder(), encodeHeaders(_, false)); wrapper.encodeHeaders( - TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}, {":authority", "foo"}}, false); + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}, {":authority", "foo"}}, false); EXPECT_FALSE(wrapper.encodeComplete()); Buffer::OwnedImpl data; @@ -49,7 +49,7 @@ TEST(RequestEncoderWrapper, HeaderAndBodyAndTrailersEncode) { EXPECT_CALL(wrapper.innerEncoder(), encodeHeaders(_, false)); wrapper.encodeHeaders( - TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}, {":authority", "foo"}}, false); + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}, {":authority", "foo"}}, false); EXPECT_FALSE(wrapper.encodeComplete()); Buffer::OwnedImpl data; @@ -58,7 +58,7 @@ TEST(RequestEncoderWrapper, HeaderAndBodyAndTrailersEncode) { EXPECT_FALSE(wrapper.encodeComplete()); EXPECT_CALL(wrapper.innerEncoder(), encodeTrailers(_)); - wrapper.encodeTrailers(TestHeaderMapImpl{{"trailing", "header"}}); + wrapper.encodeTrailers(TestRequestTrailerMapImpl{{"trailing", "header"}}); EXPECT_TRUE(wrapper.encodeComplete()); } diff --git a/test/common/http/conn_manager_impl_fuzz_test.cc b/test/common/http/conn_manager_impl_fuzz_test.cc index 3ba02f3618..46a0564e9e 100644 --- a/test/common/http/conn_manager_impl_fuzz_test.cc +++ b/test/common/http/conn_manager_impl_fuzz_test.cc @@ -313,7 +313,7 @@ class FuzzStream { EXPECT_CALL(*config_.codec_, dispatch(_)) .WillOnce(InvokeWithoutArgs([this, &trailers_action] { decoder_->decodeTrailers(std::make_unique( - Fuzz::fromHeaders(trailers_action.headers()))); + Fuzz::fromHeaders(trailers_action.headers()))); })); fakeOnData(); state = StreamState::Closed; @@ -346,8 +346,8 @@ class FuzzStream { switch (response_action.response_action_selector_case()) { case test::common::http::ResponseAction::kContinueHeaders: { if (state == StreamState::PendingHeaders) { - auto headers = std::make_unique( - Fuzz::fromHeaders(response_action.continue_headers())); + auto headers = std::make_unique( + Fuzz::fromHeaders(response_action.continue_headers())); headers->setReferenceKey(Headers::get().Status, "100"); decoder_filter_->callbacks_->encode100ContinueHeaders(std::move(headers)); } @@ -355,8 +355,8 @@ class FuzzStream { } case test::common::http::ResponseAction::kHeaders: { if (state == StreamState::PendingHeaders) { - auto headers = - std::make_unique(Fuzz::fromHeaders(response_action.headers())); + auto headers = std::make_unique( + Fuzz::fromHeaders(response_action.headers())); // The client codec will ensure we always have a valid :status. // Similarly, local replies should always contain this. try { @@ -379,8 +379,8 @@ class FuzzStream { } case test::common::http::ResponseAction::kTrailers: { if (state == StreamState::PendingDataOrTrailers) { - decoder_filter_->callbacks_->encodeTrailers( - std::make_unique(Fuzz::fromHeaders(response_action.trailers()))); + decoder_filter_->callbacks_->encodeTrailers(std::make_unique( + Fuzz::fromHeaders(response_action.trailers()))); state = StreamState::Closed; } break; @@ -456,9 +456,10 @@ DEFINE_PROTO_FUZZER(const test::common::http::ConnManagerImplTestCase& input) { switch (action.action_selector_case()) { case test::common::http::Action::kNewStream: { - streams.emplace_back(new FuzzStream(conn_manager, config, - Fuzz::fromHeaders(action.new_stream().request_headers()), - action.new_stream().end_stream())); + streams.emplace_back(new FuzzStream( + conn_manager, config, + Fuzz::fromHeaders(action.new_stream().request_headers()), + action.new_stream().end_stream())); break; } case test::common::http::Action::kStreamAction: { diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc index 31c6c5315a..e6c10931ff 100644 --- a/test/common/http/conn_manager_impl_test.cc +++ b/test/common/http/conn_manager_impl_test.cc @@ -255,7 +255,7 @@ class HttpConnectionManagerImplTest : public testing::Test, public ConnectionMan conn_manager_->onData(fake_input, false); } - HeaderMap* sendResponseHeaders(HeaderMapPtr&& response_headers) { + HeaderMap* sendResponseHeaders(ResponseHeaderMapPtr&& response_headers) { HeaderMap* altered_response_headers = nullptr; EXPECT_CALL(*encoder_filters_[0], encodeHeaders(_, _)) @@ -454,7 +454,7 @@ TEST_F(HttpConnectionManagerImplTest, HeaderOnlyRequestAndResponse) { decoder->decodeHeaders(std::move(headers), true); } - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); // Drain 2 so that on the 2nd iteration we will hit zero. @@ -506,9 +506,9 @@ TEST_F(HttpConnectionManagerImplTest, 100ContinueResponse) { new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr continue_headers{new TestHeaderMapImpl{{":status", "100"}}}; + ResponseHeaderMapPtr continue_headers{new TestResponseHeaderMapImpl{{":status", "100"}}}; filter->callbacks_->encode100ContinueHeaders(std::move(continue_headers)); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); data.drain(4); @@ -538,7 +538,7 @@ TEST_F(HttpConnectionManagerImplTest, 100ContinueResponseWithEncoderFiltersProxy EXPECT_CALL(*encoder_filters_[0], encode100ContinueHeaders(_)).Times(0); EXPECT_CALL(*encoder_filters_[1], encode100ContinueHeaders(_)).Times(0); EXPECT_CALL(response_encoder_, encode100ContinueHeaders(_)).Times(0); - HeaderMapPtr continue_headers{new TestHeaderMapImpl{{":status", "100"}}}; + ResponseHeaderMapPtr continue_headers{new TestResponseHeaderMapImpl{{":status", "100"}}}; decoder_filters_[0]->callbacks_->encode100ContinueHeaders(std::move(continue_headers)); EXPECT_CALL(*encoder_filters_[0], encodeHeaders(_, false)) @@ -546,7 +546,7 @@ TEST_F(HttpConnectionManagerImplTest, 100ContinueResponseWithEncoderFiltersProxy EXPECT_CALL(*encoder_filters_[1], encodeHeaders(_, false)) .WillOnce(Return(FilterHeadersStatus::Continue)); EXPECT_CALL(response_encoder_, encodeHeaders(_, false)); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; decoder_filters_[0]->callbacks_->encodeHeaders(std::move(response_headers), false); } @@ -561,7 +561,7 @@ TEST_F(HttpConnectionManagerImplTest, 100ContinueResponseWithEncoderFilters) { EXPECT_CALL(*encoder_filters_[1], encode100ContinueHeaders(_)) .WillOnce(Return(FilterHeadersStatus::Continue)); EXPECT_CALL(response_encoder_, encode100ContinueHeaders(_)); - HeaderMapPtr continue_headers{new TestHeaderMapImpl{{":status", "100"}}}; + ResponseHeaderMapPtr continue_headers{new TestResponseHeaderMapImpl{{":status", "100"}}}; decoder_filters_[0]->callbacks_->encode100ContinueHeaders(std::move(continue_headers)); EXPECT_CALL(*encoder_filters_[0], encodeHeaders(_, false)) @@ -569,7 +569,7 @@ TEST_F(HttpConnectionManagerImplTest, 100ContinueResponseWithEncoderFilters) { EXPECT_CALL(*encoder_filters_[1], encodeHeaders(_, false)) .WillOnce(Return(FilterHeadersStatus::Continue)); EXPECT_CALL(response_encoder_, encodeHeaders(_, false)); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; decoder_filters_[0]->callbacks_->encodeHeaders(std::move(response_headers), false); } @@ -585,7 +585,7 @@ TEST_F(HttpConnectionManagerImplTest, PauseResume100Continue) { .WillOnce(Return(FilterHeadersStatus::StopIteration)); EXPECT_CALL(*encoder_filters_[0], encode100ContinueHeaders(_)).Times(0); EXPECT_CALL(response_encoder_, encode100ContinueHeaders(_)).Times(0); - HeaderMapPtr continue_headers{new TestHeaderMapImpl{{":status", "100"}}}; + ResponseHeaderMapPtr continue_headers{new TestResponseHeaderMapImpl{{":status", "100"}}}; decoder_filters_[1]->callbacks_->encode100ContinueHeaders(std::move(continue_headers)); // Have the encoder filter 1 continue. Make sure the 100-Continue is resumed as expected. @@ -599,7 +599,7 @@ TEST_F(HttpConnectionManagerImplTest, PauseResume100Continue) { EXPECT_CALL(*encoder_filters_[0], encodeHeaders(_, false)) .WillOnce(Return(FilterHeadersStatus::Continue)); EXPECT_CALL(response_encoder_, encodeHeaders(_, false)); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; decoder_filters_[1]->callbacks_->encodeHeaders(std::move(response_headers), false); } @@ -610,7 +610,7 @@ TEST_F(HttpConnectionManagerImplTest, ServerHeaderOverwritten) { sendRequestHeadersAndData(); const HeaderMap* altered_headers = sendResponseHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}, {"server", "foo"}}}); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}, {"server", "foo"}}}); EXPECT_EQ("custom-value", altered_headers->Server()->value().getStringView()); } @@ -622,7 +622,7 @@ TEST_F(HttpConnectionManagerImplTest, ServerHeaderAppendPresent) { sendRequestHeadersAndData(); const HeaderMap* altered_headers = sendResponseHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}, {"server", "foo"}}}); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}, {"server", "foo"}}}); EXPECT_EQ("foo", altered_headers->Server()->value().getStringView()); } @@ -634,7 +634,7 @@ TEST_F(HttpConnectionManagerImplTest, ServerHeaderAppendAbsent) { sendRequestHeadersAndData(); const HeaderMap* altered_headers = - sendResponseHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}); + sendResponseHeaders(ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}); EXPECT_EQ("custom-value", altered_headers->Server()->value().getStringView()); } @@ -646,7 +646,7 @@ TEST_F(HttpConnectionManagerImplTest, ServerHeaderPassthroughPresent) { sendRequestHeadersAndData(); const HeaderMap* altered_headers = sendResponseHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}, {"server", "foo"}}}); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}, {"server", "foo"}}}); EXPECT_EQ("foo", altered_headers->Server()->value().getStringView()); } @@ -658,7 +658,7 @@ TEST_F(HttpConnectionManagerImplTest, ServerHeaderPassthroughAbsent) { sendRequestHeadersAndData(); const HeaderMap* altered_headers = - sendResponseHeaders(HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}); + sendResponseHeaders(ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}); EXPECT_TRUE(altered_headers->Server() == nullptr); } @@ -946,7 +946,7 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlow) { {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); filter->callbacks_->activeSpan().setTag("service-cluster", "scoobydoo"); data.drain(4); @@ -1014,7 +1014,7 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecorat {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); filter->callbacks_->activeSpan().setTag("service-cluster", "scoobydoo"); data.drain(4); @@ -1080,7 +1080,7 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecorat {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); filter->callbacks_->activeSpan().setTag("service-cluster", "scoobydoo"); data.drain(4); @@ -1145,7 +1145,7 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowIngressDecorat {"x-envoy-decorator-operation", "testOp"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); filter->callbacks_->activeSpan().setTag("service-cluster", "scoobydoo"); @@ -1225,7 +1225,7 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecorato {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); filter->callbacks_->activeSpan().setTag("service-cluster", "scoobydoo"); @@ -1307,7 +1307,7 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecorato {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); filter->callbacks_->activeSpan().setTag("service-cluster", "scoobydoo"); @@ -1387,8 +1387,8 @@ TEST_F(HttpConnectionManagerImplTest, StartAndFinishSpanNormalFlowEgressDecorato {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{ - new TestHeaderMapImpl{{":status", "200"}, {"x-envoy-decorator-operation", "testOp"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{ + {":status", "200"}, {"x-envoy-decorator-operation", "testOp"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); filter->callbacks_->activeSpan().setTag("service-cluster", "scoobydoo"); @@ -1443,8 +1443,8 @@ TEST_F(HttpConnectionManagerImplTest, {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{ - new TestHeaderMapImpl{{":status", "200"}, {"x-envoy-decorator-operation", "testOp"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{ + {":status", "200"}, {"x-envoy-decorator-operation", "testOp"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); data.drain(4); @@ -1500,7 +1500,7 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLog) { {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); data.drain(4); @@ -1582,10 +1582,10 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLogWithTrailers) { {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), false); - HeaderMapPtr response_trailers{new TestHeaderMapImpl{{"x-trailer", "1"}}}; + ResponseTrailerMapPtr response_trailers{new TestResponseTrailerMapImpl{{"x-trailer", "1"}}}; filter->callbacks_->encodeTrailers(std::move(response_trailers)); data.drain(4); @@ -1670,10 +1670,10 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLogSsl) { {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), false); - HeaderMapPtr response_trailers{new TestHeaderMapImpl{{"x-trailer", "1"}}}; + ResponseTrailerMapPtr response_trailers{new TestResponseTrailerMapImpl{{"x-trailer", "1"}}}; filter->callbacks_->encodeTrailers(std::move(response_trailers)); data.drain(4); @@ -1713,7 +1713,7 @@ TEST_F(HttpConnectionManagerImplTest, DoNotStartSpanIfTracingIsNotEnabled) { {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); data.drain(4); @@ -2088,7 +2088,7 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutAfterUpstreamHeaders) EXPECT_CALL(*idle_timer, enableTimer(_, _)); decoder->decodeHeaders(std::move(headers), false); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; EXPECT_CALL(*idle_timer, enableTimer(_, _)); filter->callbacks_->encodeHeaders(std::move(response_headers), false); @@ -2137,11 +2137,12 @@ TEST_F(HttpConnectionManagerImplTest, PerStreamIdleTimeoutAfterBidiData) { EXPECT_CALL(*idle_timer, enableTimer(_, _)); decoder->decodeHeaders(std::move(headers), false); - HeaderMapPtr response_continue_headers{new TestHeaderMapImpl{{":status", "100"}}}; + ResponseHeaderMapPtr response_continue_headers{ + new TestResponseHeaderMapImpl{{":status", "100"}}}; EXPECT_CALL(*idle_timer, enableTimer(_, _)); filter->callbacks_->encode100ContinueHeaders(std::move(response_continue_headers)); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; EXPECT_CALL(*idle_timer, enableTimer(_, _)); filter->callbacks_->encodeHeaders(std::move(response_headers), false); @@ -2363,7 +2364,7 @@ TEST_F(HttpConnectionManagerImplTest, RequestTimeoutIsDisarmedOnEncodeHeaders) { decoder->decodeHeaders(std::move(headers), false); EXPECT_CALL(*request_timer, disableTimer()).Times(1); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), false); })); @@ -2470,8 +2471,8 @@ TEST_F(HttpConnectionManagerImplTest, FooUpgradeDrainClose) { {"upgrade", "foo"}}}; decoder->decodeHeaders(std::move(headers), false); - HeaderMapPtr response_headers{ - new TestHeaderMapImpl{{":status", "101"}, {"Connection", "upgrade"}, {"upgrade", "foo"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{ + {":status", "101"}, {"Connection", "upgrade"}, {"upgrade", "foo"}}}; filter->decoder_callbacks_->encodeHeaders(std::move(response_headers), false); data.drain(4); @@ -2510,7 +2511,7 @@ TEST_F(HttpConnectionManagerImplTest, DrainClose) { Buffer::OwnedImpl fake_input; conn_manager_->onData(fake_input, false); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "300"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "300"}}}; Event::MockTimer* drain_timer = setUpTimer(); EXPECT_CALL(*drain_timer, enableTimer(_, _)); EXPECT_CALL(drain_close_, drainClose()).WillOnce(Return(true)); @@ -2559,7 +2560,7 @@ TEST_F(HttpConnectionManagerImplTest, ResponseBeforeRequestComplete) { EXPECT_CALL(filter_callbacks_.connection_, close(Network::ConnectionCloseType::FlushWriteAndDelay)); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; decoder_filters_[0]->callbacks_->encodeHeaders(std::move(response_headers), true); } @@ -2592,7 +2593,7 @@ TEST_F(HttpConnectionManagerImplTest, DisconnectOnProxyConnectionDisconnect) { EXPECT_CALL(filter_callbacks_.connection_, close(Network::ConnectionCloseType::FlushWriteAndDelay)); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; decoder_filters_[0]->callbacks_->encodeHeaders(std::move(response_headers), true); } @@ -2624,7 +2625,7 @@ TEST_F(HttpConnectionManagerImplTest, ResponseStartBeforeRequestComplete) { conn_manager_->onData(fake_input, false); // Start the response - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; EXPECT_CALL(encoder, encodeHeaders(_, false)) .WillOnce(Invoke([](const HeaderMap& headers, bool) -> void { EXPECT_NE(nullptr, headers.Server()); @@ -2856,7 +2857,7 @@ TEST_F(HttpConnectionManagerImplTest, IdleTimeout) { conn_manager_->onData(fake_input, false); EXPECT_CALL(*idle_timer, enableTimer(_, _)); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); Event::MockTimer* drain_timer = setUpTimer(); @@ -2923,7 +2924,7 @@ TEST_F(HttpConnectionManagerImplTest, ConnectionDuration) { Buffer::OwnedImpl fake_input("1234"); conn_manager_->onData(fake_input, false); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); Event::MockTimer* drain_timer = setUpTimer(); @@ -2970,7 +2971,7 @@ TEST_F(HttpConnectionManagerImplTest, IntermediateBufferingEarlyResponse) { EXPECT_CALL(*decoder_filters_[1], decodeHeaders(_, false)) .WillOnce(Invoke([&](HeaderMap&, bool) -> FilterHeadersStatus { // Now filter 2 will send a complete response. - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; decoder_filters_[1]->callbacks_->encodeHeaders(std::move(response_headers), true); return FilterHeadersStatus::StopIteration; })); @@ -3121,7 +3122,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddTrailersInTrailersCallback) { // invoke encodeHeaders decoder_filters_[0]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); // set up encodeData expectations EXPECT_CALL(*encoder_filters_[1], encodeData(_, false)) @@ -3151,7 +3152,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddTrailersInTrailersCallback) { // invoke encodeTrailers decoder_filters_[0]->callbacks_->encodeTrailers( - HeaderMapPtr{new TestHeaderMapImpl{{"some", "trailer"}}}); + ResponseTrailerMapPtr{new TestResponseTrailerMapImpl{{"some", "trailer"}}}); } TEST_F(HttpConnectionManagerImplTest, FilterAddTrailersInDataCallbackNoTrailers) { @@ -3211,7 +3212,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddTrailersInDataCallbackNoTrailers) // invoke encodeHeaders decoder_filters_[0]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); // set up encodeData expectations EXPECT_CALL(*encoder_filters_[1], encodeData(_, true)) @@ -3296,7 +3297,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback) { EXPECT_CALL(response_encoder_, encodeHeaders(_, false)); decoder_filters_[1]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); EXPECT_CALL(*encoder_filters_[1], encodeData(_, false)) .WillOnce(Return(FilterDataStatus::Continue)); @@ -3322,7 +3323,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback) { expectOnDestroy(); decoder_filters_[1]->callbacks_->encodeTrailers( - HeaderMapPtr{new TestHeaderMapImpl{{"some", "trailer"}}}); + ResponseTrailerMapPtr{new TestResponseTrailerMapImpl{{"some", "trailer"}}}); } // Don't send data frames, only headers and trailers. @@ -3367,7 +3368,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback_NoDataFram EXPECT_CALL(*encoder_filters_[0], encodeHeaders(_, false)) .WillOnce(Return(FilterHeadersStatus::StopIteration)); decoder_filters_[0]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); EXPECT_CALL(*encoder_filters_[0], encodeTrailers(_)) .WillOnce(InvokeWithoutArgs([&]() -> FilterTrailersStatus { @@ -3381,7 +3382,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback_NoDataFram expectOnDestroy(); decoder_filters_[0]->callbacks_->encodeTrailers( - HeaderMapPtr{new TestHeaderMapImpl{{"some", "trailer"}}}); + ResponseTrailerMapPtr{new TestResponseTrailerMapImpl{{"some", "trailer"}}}); } // Don't send data frames, only headers and trailers. @@ -3429,7 +3430,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback_ContinueAf EXPECT_CALL(*encoder_filters_[0], encodeHeaders(_, false)) .WillOnce(Return(FilterHeadersStatus::StopIteration)); decoder_filters_[0]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); EXPECT_CALL(*encoder_filters_[0], encodeTrailers(_)) .WillOnce(InvokeWithoutArgs([&]() -> FilterTrailersStatus { @@ -3439,7 +3440,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInTrailersCallback_ContinueAf EXPECT_CALL(*encoder_filters_[0], encodeComplete()); decoder_filters_[0]->callbacks_->encodeTrailers( - HeaderMapPtr{new TestHeaderMapImpl{{"some", "trailer"}}}); + ResponseTrailerMapPtr{new TestResponseTrailerMapImpl{{"some", "trailer"}}}); EXPECT_CALL(response_encoder_, encodeHeaders(_, false)); EXPECT_CALL(response_encoder_, encodeData(_, false)); @@ -3511,7 +3512,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyDuringDecodeData) { expectOnDestroy(); decoder_filters_[1]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); Buffer::OwnedImpl data1("good"); decoder_filters_[1]->callbacks_->encodeData(data1, false); Buffer::OwnedImpl data2("bye"); @@ -3566,7 +3567,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyInline) { expectOnDestroy(); decoder_filters_[1]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); } TEST_F(HttpConnectionManagerImplTest, FilterClearRouteCache) { @@ -3677,7 +3678,7 @@ TEST_F(HttpConnectionManagerImplTest, UpstreamWatermarkCallbacks) { EXPECT_CALL(filter_callbacks_.connection_, readDisable(false)); expectOnDestroy(); decoder_filters_[1]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); } TEST_F(HttpConnectionManagerImplTest, UnderlyingConnectionWatermarksPassedOnWithLazyCreation) { @@ -3848,7 +3849,7 @@ TEST_F(HttpConnectionManagerImplTest, HitFilterWatermarkLimits) { decoder_filters_[0]->callbacks_->setDecoderBufferLimit((buffer_len + 1) * 2); // Start the response - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; EXPECT_CALL(*encoder_filters_[1], encodeHeaders(_, false)) .WillOnce(Return(FilterHeadersStatus::StopIteration)); decoder_filters_[0]->callbacks_->encodeHeaders(std::move(response_headers), false); @@ -3886,7 +3887,7 @@ TEST_F(HttpConnectionManagerImplTest, HitRequestBufferLimits) { // Set the filter to be a buffering filter. Sending any data will hit the // watermark limit and result in a 413 being sent to the user. - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "413"}, {"content-length", "17"}, {"content-type", "text/plain"}}; EXPECT_CALL(*encoder_filters_[1], encodeHeaders(HeaderMapEqualRef(&response_headers), false)) .WillOnce(Return(FilterHeadersStatus::StopIteration)); @@ -3928,7 +3929,7 @@ TEST_F(HttpConnectionManagerImplTest, HitRequestBufferLimitsIntermediateFilter) EXPECT_CALL(*decoder_filters_[0], decodeData(_, true)) .WillOnce(Return(FilterDataStatus::Continue)); EXPECT_CALL(*decoder_filters_[0], decodeComplete()); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "413"}, {"content-length", "17"}, {"content-type", "text/plain"}}; EXPECT_CALL(*encoder_filters_[0], encodeHeaders(HeaderMapEqualRef(&response_headers), false)) .WillOnce(Return(FilterHeadersStatus::StopIteration)); @@ -3949,7 +3950,7 @@ TEST_F(HttpConnectionManagerImplTest, HitResponseBufferLimitsBeforeHeaders) { // Start the response without processing the request headers through all // filters. - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; EXPECT_CALL(*encoder_filters_[1], encodeHeaders(_, false)) .WillOnce(Return(FilterHeadersStatus::StopIteration)); decoder_filters_[0]->callbacks_->encodeHeaders(std::move(response_headers), false); @@ -3986,7 +3987,7 @@ TEST_F(HttpConnectionManagerImplTest, HitResponseBufferLimitsAfterHeaders) { sendRequestHeadersAndData(); // Start the response, and make sure the request headers are fully processed. - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; EXPECT_CALL(*encoder_filters_[1], encodeHeaders(_, false)) .WillOnce(Return(FilterHeadersStatus::Continue)); EXPECT_CALL(*encoder_filters_[0], encodeHeaders(_, false)) @@ -4258,7 +4259,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterAddBodyContinuation) { EXPECT_CALL(*encoder_filters_[1], encodeComplete()); decoder_filters_[1]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*encoder_filters_[0], encodeHeaders(_, false)) .WillOnce(Return(FilterHeadersStatus::Continue)); @@ -4371,7 +4372,7 @@ TEST_F(HttpConnectionManagerImplTest, AddDataWithAllContinue) { EXPECT_CALL(*encoder_filters_[1], encodeData(_, true)).Times(0); decoder_filters_[2]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); } // This test verifies proper sequences of decodeData() and encodeData() are called @@ -4457,7 +4458,7 @@ TEST_F(HttpConnectionManagerImplTest, AddDataWithStopAndContinue) { EXPECT_CALL(*encoder_filters_[2], encodeComplete()); decoder_filters_[2]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, true); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); EXPECT_CALL(*encoder_filters_[1], encodeHeaders(_, true)) .WillOnce(InvokeWithoutArgs([&]() -> FilterHeadersStatus { @@ -4545,7 +4546,7 @@ TEST_F(HttpConnectionManagerImplTest, FilterDirectDecodeEncodeDataNoTrailers) { EXPECT_CALL(*encoder_filters_[1], encodeComplete()); decoder_filters_[1]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); Buffer::OwnedImpl response_body("response"); decoder_filters_[1]->callbacks_->encodeData(response_body, true); @@ -4634,11 +4635,11 @@ TEST_F(HttpConnectionManagerImplTest, FilterDirectDecodeEncodeDataTrailers) { EXPECT_CALL(*encoder_filters_[1], encodeComplete()); decoder_filters_[1]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); Buffer::OwnedImpl response_body("response"); decoder_filters_[1]->callbacks_->encodeData(response_body, false); decoder_filters_[1]->callbacks_->encodeTrailers( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}); + ResponseTrailerMapPtr{new TestResponseTrailerMapImpl{{"some", "trailer"}}}); Buffer::OwnedImpl encoded_data_to_forward; encoded_data_to_forward.move(encoder_buffer, 3); @@ -4726,11 +4727,11 @@ TEST_F(HttpConnectionManagerImplTest, MultipleFilters) { EXPECT_CALL(*encoder_filters_[1], encodeComplete()); EXPECT_EQ(ssl_connection_.get(), encoder_filters_[1]->callbacks_->connection()->ssl().get()); decoder_filters_[2]->callbacks_->encodeHeaders( - HeaderMapPtr{new TestHeaderMapImpl{{":status", "200"}}}, false); + ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); Buffer::OwnedImpl response_body("response"); decoder_filters_[2]->callbacks_->encodeData(response_body, false); decoder_filters_[2]->callbacks_->encodeTrailers( - HeaderMapPtr{new TestHeaderMapImpl{{"some", "trailer"}}}); + ResponseTrailerMapPtr{new TestResponseTrailerMapImpl{{"some", "trailer"}}}); EXPECT_EQ(ssl_connection_.get(), decoder_filters_[2]->callbacks_->connection()->ssl().get()); // Now finish the encode. @@ -4812,7 +4813,7 @@ TEST_F(HttpConnectionManagerImplTest, DisableKeepAliveWhenOverloaded) { {":authority", "host"}, {":path", "/"}, {":method", "GET"}, {"connection", "keep-alive"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); data.drain(4); @@ -4883,7 +4884,7 @@ TEST_F(HttpConnectionManagerImplTest, TestStopAllIterationAndBufferOnEncodingPat .WillOnce(Invoke([&](HeaderMap&, bool) -> FilterHeadersStatus { return FilterHeadersStatus::StopAllIterationAndBuffer; })); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; decoder_filters_[0]->callbacks_->encodeHeaders(std::move(response_headers), false); // Invoke encodeData while all iteration is stopped and make sure the filters do not have @@ -4893,7 +4894,7 @@ TEST_F(HttpConnectionManagerImplTest, TestStopAllIterationAndBufferOnEncodingPat Buffer::OwnedImpl response_body("response"); decoder_filters_[0]->callbacks_->encodeData(response_body, false); decoder_filters_[0]->callbacks_->encodeTrailers( - HeaderMapPtr{new TestHeaderMapImpl{{"some", "trailer"}}}); + ResponseTrailerMapPtr{new TestResponseTrailerMapImpl{{"some", "trailer"}}}); // Verify that once encoder_filters_[1]'s continueEncoding() is called, encoder_filters_[0]'s // encodeHeaders() is called, and both filters receive data and trailers consequently. @@ -4931,7 +4932,7 @@ TEST_F(HttpConnectionManagerImplTest, DisableKeepAliveWhenDraining) { {":authority", "host"}, {":path", "/"}, {":method", "GET"}, {"connection", "keep-alive"}}}; decoder->decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); data.drain(4); @@ -5235,7 +5236,7 @@ TEST_F(HttpConnectionManagerImplTest, HeaderOnlyRequestAndResponseUsingHttp3) { new TestRequestHeaderMapImpl{{":authority", "host"}, {":path", "/"}, {":method", "GET"}}}; decoder.decodeHeaders(std::move(headers), true); - HeaderMapPtr response_headers{new TestHeaderMapImpl{{":status", "200"}}}; + ResponseHeaderMapPtr response_headers{new TestResponseHeaderMapImpl{{":status", "200"}}}; filter->callbacks_->encodeHeaders(std::move(response_headers), true); EXPECT_EQ(1U, stats_.named_.downstream_rq_2xx_.value()); diff --git a/test/common/http/conn_manager_utility_test.cc b/test/common/http/conn_manager_utility_test.cc index 0a0dcf569f..685dfc32f8 100644 --- a/test/common/http/conn_manager_utility_test.cc +++ b/test/common/http/conn_manager_utility_test.cc @@ -329,7 +329,7 @@ TEST_F(ConnectionManagerUtilityTest, ViaEmpty) { connection_.remote_address_ = std::make_shared("10.0.0.1"); ON_CALL(config_, useRemoteAddress()).WillByDefault(Return(true)); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; EXPECT_EQ((MutateRequestRet{"10.0.0.1:0", true}), callMutateRequestHeaders(request_headers, Protocol::Http2)); EXPECT_FALSE(request_headers.has(Headers::get().Via)); @@ -345,7 +345,7 @@ TEST_F(ConnectionManagerUtilityTest, ViaAppend) { connection_.remote_address_ = std::make_shared("10.0.0.1"); ON_CALL(config_, useRemoteAddress()).WillByDefault(Return(true)); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; EXPECT_EQ((MutateRequestRet{"10.0.0.1:0", true}), callMutateRequestHeaders(request_headers, Protocol::Http2)); EXPECT_EQ("foo", request_headers.get_(Headers::get().Via)); @@ -697,7 +697,7 @@ TEST_F(ConnectionManagerUtilityTest, RemoveConnectionUpgradeForNonWebSocketReque TEST_F(ConnectionManagerUtilityTest, MutateResponseHeaders) { TestHeaderMapImpl response_headers{ {"connection", "foo"}, {"transfer-encoding", "foo"}, {"custom_header", "custom_value"}}; - TestHeaderMapImpl request_headers{{"x-request-id", "request-id"}}; + TestRequestHeaderMapImpl request_headers{{"x-request-id", "request-id"}}; ConnectionManagerUtility::mutateResponseHeaders(response_headers, &request_headers, ""); @@ -709,7 +709,7 @@ TEST_F(ConnectionManagerUtilityTest, MutateResponseHeaders) { // Make sure we don't remove connection headers on all Upgrade responses. TEST_F(ConnectionManagerUtilityTest, DoNotRemoveConnectionUpgradeForWebSocketResponses) { - TestHeaderMapImpl request_headers{{"connection", "UpGrAdE"}, {"upgrade", "foo"}}; + TestRequestHeaderMapImpl request_headers{{"connection", "UpGrAdE"}, {"upgrade", "foo"}}; TestHeaderMapImpl response_headers{ {"connection", "upgrade"}, {"transfer-encoding", "foo"}, {"upgrade", "bar"}}; EXPECT_TRUE(Utility::isUpgrade(request_headers)); @@ -724,7 +724,7 @@ TEST_F(ConnectionManagerUtilityTest, DoNotRemoveConnectionUpgradeForWebSocketRes TEST_F(ConnectionManagerUtilityTest, ClearUpgradeHeadersForNonUpgradeRequests) { // Test clearing non-upgrade request and response headers { - TestHeaderMapImpl request_headers{{"x-request-id", "request-id"}}; + TestRequestHeaderMapImpl request_headers{{"x-request-id", "request-id"}}; TestHeaderMapImpl response_headers{ {"connection", "foo"}, {"transfer-encoding", "bar"}, {"custom_header", "custom_value"}}; EXPECT_FALSE(Utility::isUpgrade(request_headers)); @@ -737,7 +737,7 @@ TEST_F(ConnectionManagerUtilityTest, ClearUpgradeHeadersForNonUpgradeRequests) { // Test with the request headers not valid upgrade headers { - TestHeaderMapImpl request_headers{{"upgrade", "foo"}}; + TestRequestHeaderMapImpl request_headers{{"upgrade", "foo"}}; TestHeaderMapImpl response_headers{{"connection", "upgrade"}, {"transfer-encoding", "eep"}, {"upgrade", "foo"}, @@ -753,7 +753,7 @@ TEST_F(ConnectionManagerUtilityTest, ClearUpgradeHeadersForNonUpgradeRequests) { // Test with the response headers not valid upgrade headers { - TestHeaderMapImpl request_headers{{"connection", "UpGrAdE"}, {"upgrade", "foo"}}; + TestRequestHeaderMapImpl request_headers{{"connection", "UpGrAdE"}, {"upgrade", "foo"}}; TestHeaderMapImpl response_headers{{"transfer-encoding", "foo"}, {"upgrade", "bar"}}; EXPECT_TRUE(Utility::isUpgrade(request_headers)); EXPECT_FALSE(Utility::isUpgrade(response_headers)); @@ -767,8 +767,8 @@ TEST_F(ConnectionManagerUtilityTest, ClearUpgradeHeadersForNonUpgradeRequests) { // Test that we correctly return x-request-id if we were requested to force a trace. TEST_F(ConnectionManagerUtilityTest, MutateResponseHeadersReturnXRequestId) { TestHeaderMapImpl response_headers; - TestHeaderMapImpl request_headers{{"x-request-id", "request-id"}, - {"x-envoy-force-trace", "true"}}; + TestRequestHeaderMapImpl request_headers{{"x-request-id", "request-id"}, + {"x-envoy-force-trace", "true"}}; ConnectionManagerUtility::mutateResponseHeaders(response_headers, &request_headers, ""); EXPECT_EQ("request-id", response_headers.get_("x-request-id")); @@ -1069,7 +1069,8 @@ TEST_F(ConnectionManagerUtilityTest, RandomSamplingWhenGlobalSet) { featureEnabled("tracing.global_enabled", An(), _)) .WillOnce(Return(true)); - Http::TestHeaderMapImpl request_headers{{"x-request-id", "125a4afb-6f55-44ba-ad80-413f09f48a28"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"x-request-id", "125a4afb-6f55-44ba-ad80-413f09f48a28"}}; callMutateRequestHeaders(request_headers, Protocol::Http2); EXPECT_EQ(UuidTraceStatus::Sampled, @@ -1086,7 +1087,8 @@ TEST_F(ConnectionManagerUtilityTest, SamplingWithoutRouteOverride) { featureEnabled("tracing.global_enabled", An(), _)) .WillOnce(Return(true)); - Http::TestHeaderMapImpl request_headers{{"x-request-id", "125a4afb-6f55-44ba-ad80-413f09f48a28"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"x-request-id", "125a4afb-6f55-44ba-ad80-413f09f48a28"}}; callMutateRequestHeaders(request_headers, Protocol::Http2); EXPECT_EQ(UuidTraceStatus::Sampled, @@ -1110,7 +1112,8 @@ TEST_F(ConnectionManagerUtilityTest, SamplingWithRouteOverride) { EXPECT_CALL(tracingConfig, getRandomSampling()).WillRepeatedly(ReturnRef(percent)); EXPECT_CALL(tracingConfig, getOverallSampling()).WillRepeatedly(ReturnRef(percent)); - Http::TestHeaderMapImpl request_headers{{"x-request-id", "125a4afb-6f55-44ba-ad80-413f09f48a28"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"x-request-id", "125a4afb-6f55-44ba-ad80-413f09f48a28"}}; callMutateRequestHeaders(request_headers, Protocol::Http2); EXPECT_EQ(UuidTraceStatus::NoTrace, @@ -1129,7 +1132,8 @@ TEST_F(ConnectionManagerUtilityTest, SamplingMustNotBeDoneOnClientTraced) { .WillOnce(Return(true)); // The x_request_id has TRACE_FORCED(a) set in the TRACE_BYTE_POSITION(14) character. - Http::TestHeaderMapImpl request_headers{{"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"x-request-id", "125a4afb-6f55-a4ba-ad80-413f09f48a28"}}; callMutateRequestHeaders(request_headers, Protocol::Http2); EXPECT_EQ(UuidTraceStatus::Forced, @@ -1147,7 +1151,8 @@ TEST_F(ConnectionManagerUtilityTest, NoTraceWhenSamplingSetButGlobalNotSet) { featureEnabled("tracing.global_enabled", An(), _)) .WillOnce(Return(false)); - Http::TestHeaderMapImpl request_headers{{"x-request-id", "125a4afb-6f55-44ba-ad80-413f09f48a28"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"x-request-id", "125a4afb-6f55-44ba-ad80-413f09f48a28"}}; callMutateRequestHeaders(request_headers, Protocol::Http2); EXPECT_EQ(UuidTraceStatus::NoTrace, @@ -1164,7 +1169,7 @@ TEST_F(ConnectionManagerUtilityTest, ClientSamplingWhenGlobalSet) { featureEnabled("tracing.global_enabled", An(), _)) .WillOnce(Return(true)); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"x-client-trace-id", "f4dca0a9-12c7-4307-8002-969403baf480"}, {"x-request-id", "125a4afb-6f55-44ba-ad80-413f09f48a28"}}; callMutateRequestHeaders(request_headers, Protocol::Http2); @@ -1187,7 +1192,7 @@ TEST_F(ConnectionManagerUtilityTest, NoTraceWhenClientSamplingNotSetAndGlobalSet featureEnabled("tracing.global_enabled", An(), _)) .WillOnce(Return(true)); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"x-client-trace-id", "f4dca0a9-12c7-4307-8002-969403baf480"}, {"x-request-id", "125a4afb-6f55-44ba-ad80-413f09f48a28"}}; callMutateRequestHeaders(request_headers, Protocol::Http2); @@ -1234,7 +1239,8 @@ TEST_F(ConnectionManagerUtilityTest, NoTraceWhenForcedTracedButGlobalNotSet) { // Forced, global on, broken uuid. TEST_F(ConnectionManagerUtilityTest, NoTraceOnBrokenUuid) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-force-trace", "true"}, {"x-request-id", "bb"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-force-trace", "true"}, + {"x-request-id", "bb"}}; callMutateRequestHeaders(request_headers, Protocol::Http2); EXPECT_EQ(UuidTraceStatus::NoTrace, @@ -1242,9 +1248,9 @@ TEST_F(ConnectionManagerUtilityTest, NoTraceOnBrokenUuid) { } TEST_F(ConnectionManagerUtilityTest, RemovesProxyResponseHeaders) { - Http::TestHeaderMapImpl request_headers{{}}; - Http::TestHeaderMapImpl response_headers{{"keep-alive", "timeout=60"}, - {"proxy-connection", "proxy-header"}}; + Http::TestRequestHeaderMapImpl request_headers{{}}; + Http::TestResponseHeaderMapImpl response_headers{{"keep-alive", "timeout=60"}, + {"proxy-connection", "proxy-header"}}; ConnectionManagerUtility::mutateResponseHeaders(response_headers, &request_headers, ""); EXPECT_EQ(UuidTraceStatus::NoTrace, diff --git a/test/common/http/header_map_impl_fuzz_test.cc b/test/common/http/header_map_impl_fuzz_test.cc index 5c3cc0f5ed..d6b9d7a05a 100644 --- a/test/common/http/header_map_impl_fuzz_test.cc +++ b/test/common/http/header_map_impl_fuzz_test.cc @@ -16,7 +16,7 @@ namespace Envoy { // Fuzz the header map implementation. DEFINE_PROTO_FUZZER(const test::common::http::HeaderMapImplFuzzTestCase& input) { - Http::HeaderMapImplPtr header_map = std::make_unique(); + auto header_map = std::make_unique(); std::vector> lower_case_strings; std::vector> strings; uint64_t set_integer; @@ -149,7 +149,7 @@ DEFINE_PROTO_FUZZER(const test::common::http::HeaderMapImplFuzzTestCase& input) break; } case test::common::http::Action::kCopy: { - header_map = Http::HeaderMapImpl::create(*static_cast(header_map.get())); + header_map = Http::createHeaderMap(*header_map); break; } case test::common::http::Action::kLookup: { diff --git a/test/common/http/header_map_impl_test.cc b/test/common/http/header_map_impl_test.cc index 179b78573a..a986064a0e 100644 --- a/test/common/http/header_map_impl_test.cc +++ b/test/common/http/header_map_impl_test.cc @@ -16,13 +16,6 @@ namespace Http { class VerifiedHeaderMapImpl : public HeaderMapImpl { public: - static HeaderMapImplPtr - create(const std::initializer_list>& values) { - auto new_header_map = std::make_unique(); - new_header_map->initFromInitList(*new_header_map, values); - return new_header_map; - } - void verifyByteSize() override { verifyByteSizeInternalForTest(); } }; @@ -861,7 +854,7 @@ TEST(HeaderMapImplTest, Lookup) { TEST(HeaderMapImplTest, Get) { { - auto headers = VerifiedHeaderMapImpl::create( + auto headers = createHeaderMap( {{Headers::get().Path, "/"}, {LowerCaseString("hello"), "world"}}); EXPECT_EQ("/", headers->get(LowerCaseString(":path"))->value().getStringView()); EXPECT_EQ("world", headers->get(LowerCaseString("hello"))->value().getStringView()); @@ -869,7 +862,7 @@ TEST(HeaderMapImplTest, Get) { } { - auto headers = VerifiedHeaderMapImpl::create( + auto headers = createHeaderMap( {{Headers::get().Path, "/"}, {LowerCaseString("hello"), "world"}}); // There is not HeaderMap method to set a header and copy both the key and value. headers->setReferenceKey(LowerCaseString(":path"), "/new_path"); @@ -1105,11 +1098,12 @@ TEST(HeaderMapImplTest, PseudoHeaderOrder) { // Starting with a normal header { - auto headers = VerifiedHeaderMapImpl::create({{Headers::get().ContentType, "text/plain"}, - {Headers::get().Method, "GET"}, - {Headers::get().Path, "/"}, - {LowerCaseString("hello"), "world"}, - {Headers::get().Host, "host"}}); + auto headers = + createHeaderMap({{Headers::get().ContentType, "text/plain"}, + {Headers::get().Method, "GET"}, + {Headers::get().Path, "/"}, + {LowerCaseString("hello"), "world"}, + {Headers::get().Host, "host"}}); InSequence seq; EXPECT_CALL(cb, Call(":method", "GET")); @@ -1129,11 +1123,12 @@ TEST(HeaderMapImplTest, PseudoHeaderOrder) { // Starting with a pseudo-header { - auto headers = VerifiedHeaderMapImpl::create({{Headers::get().Path, "/"}, - {Headers::get().ContentType, "text/plain"}, - {Headers::get().Method, "GET"}, - {LowerCaseString("hello"), "world"}, - {Headers::get().Host, "host"}}); + auto headers = + createHeaderMap({{Headers::get().Path, "/"}, + {Headers::get().ContentType, "text/plain"}, + {Headers::get().Method, "GET"}, + {LowerCaseString("hello"), "world"}, + {Headers::get().Host, "host"}}); InSequence seq; EXPECT_CALL(cb, Call(":path", "/")); diff --git a/test/common/http/http1/codec_impl_test.cc b/test/common/http/http1/codec_impl_test.cc index 88f8c9a1f4..98214a6de3 100644 --- a/test/common/http/http1/codec_impl_test.cc +++ b/test/common/http/http1/codec_impl_test.cc @@ -82,7 +82,7 @@ class Http1ServerConnectionImplTest : public testing::Test { Buffer::OwnedImpl buffer(raw_request); codec_->dispatch(buffer); EXPECT_EQ(0U, buffer.length()); - response_encoder->encodeHeaders(TestHeaderMapImpl{{":status", "200"}}, true); + response_encoder->encodeHeaders(TestResponseHeaderMapImpl{{":status", "200"}}, true); } protected: @@ -401,7 +401,7 @@ TEST_F(Http1ServerConnectionImplTest, Http10MultipleResponses) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":status", "200"}}; + TestResponseHeaderMapImpl headers{{":status", "200"}}; response_encoder->encodeHeaders(headers, true); EXPECT_EQ("HTTP/1.1 200 OK\r\ncontent-length: 0\r\n\r\n", output); EXPECT_EQ(Protocol::Http10, codec_->protocol()); @@ -806,7 +806,7 @@ TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponse) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":status", "200"}}; + TestResponseHeaderMapImpl headers{{":status", "200"}}; response_encoder->encodeHeaders(headers, true); EXPECT_EQ("HTTP/1.1 200 OK\r\ncontent-length: 0\r\n\r\n", output); } @@ -832,7 +832,7 @@ TEST_F(Http1ServerConnectionImplTest, LargeHeaderResponseEncode) { ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); const std::string long_header_value = std::string(79 * 1024, 'a'); - TestHeaderMapImpl headers{{":status", "200"}, {"foo", long_header_value}}; + TestResponseHeaderMapImpl headers{{":status", "200"}, {"foo", long_header_value}}; response_encoder->encodeHeaders(headers, true); EXPECT_EQ("HTTP/1.1 200 OK\r\nfoo: " + long_header_value + "\r\ncontent-length: 0\r\n\r\n", output); @@ -857,7 +857,8 @@ TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponseTrainProperHeaders) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":status", "200"}, {"some-header", "foo"}, {"some#header", "baz"}}; + TestResponseHeaderMapImpl headers{ + {":status", "200"}, {"some-header", "foo"}, {"some#header", "baz"}}; response_encoder->encodeHeaders(headers, true); EXPECT_EQ("HTTP/1.1 200 OK\r\nSome-Header: foo\r\nSome#Header: baz\r\nContent-Length: 0\r\n\r\n", output); @@ -881,7 +882,7 @@ TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponseWith204) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":status", "204"}}; + TestResponseHeaderMapImpl headers{{":status", "204"}}; response_encoder->encodeHeaders(headers, true); EXPECT_EQ("HTTP/1.1 204 No Content\r\n\r\n", output); } @@ -904,14 +905,14 @@ TEST_F(Http1ServerConnectionImplTest, HeaderOnlyResponseWith100Then200) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl continue_headers{{":status", "100"}}; + TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; response_encoder->encode100ContinueHeaders(continue_headers); EXPECT_EQ("HTTP/1.1 100 Continue\r\n\r\n", output); output.clear(); // Test the special case where we encode 100 headers (no content length may be // appended) then 200 headers (content length 0 will be appended). - TestHeaderMapImpl headers{{":status", "200"}}; + TestResponseHeaderMapImpl headers{{":status", "200"}}; response_encoder->encodeHeaders(headers, true); EXPECT_EQ("HTTP/1.1 200 OK\r\ncontent-length: 0\r\n\r\n", output); } @@ -956,7 +957,7 @@ TEST_F(Http1ServerConnectionImplTest, ChunkedResponse) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":status", "200"}}; + TestResponseHeaderMapImpl headers{{":status", "200"}}; response_encoder->encodeHeaders(headers, false); Buffer::OwnedImpl data("Hello World"); @@ -985,13 +986,13 @@ TEST_F(Http1ServerConnectionImplTest, ChunkedResponseWithTrailers) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":status", "200"}}; + TestResponseHeaderMapImpl headers{{":status", "200"}}; response_encoder->encodeHeaders(headers, false); Buffer::OwnedImpl data("Hello World"); response_encoder->encodeData(data, false); - TestHeaderMapImpl trailers{{"foo", "bar"}, {"foo", "baz"}}; + TestResponseTrailerMapImpl trailers{{"foo", "bar"}, {"foo", "baz"}}; response_encoder->encodeTrailers(trailers); EXPECT_EQ("HTTP/1.1 200 OK\r\ntransfer-encoding: chunked\r\n\r\nb\r\nHello " @@ -1017,7 +1018,7 @@ TEST_F(Http1ServerConnectionImplTest, ContentLengthResponse) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":status", "200"}, {"content-length", "11"}}; + TestResponseHeaderMapImpl headers{{":status", "200"}, {"content-length", "11"}}; response_encoder->encodeHeaders(headers, false); Buffer::OwnedImpl data("Hello World"); @@ -1043,7 +1044,7 @@ TEST_F(Http1ServerConnectionImplTest, HeadRequestResponse) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":status", "200"}, {"content-length", "5"}}; + TestResponseHeaderMapImpl headers{{":status", "200"}, {"content-length", "5"}}; response_encoder->encodeHeaders(headers, true); EXPECT_EQ("HTTP/1.1 200 OK\r\ncontent-length: 5\r\n\r\n", output); } @@ -1066,7 +1067,7 @@ TEST_F(Http1ServerConnectionImplTest, HeadChunkedRequestResponse) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":status", "200"}}; + TestResponseHeaderMapImpl headers{{":status", "200"}}; response_encoder->encodeHeaders(headers, true); EXPECT_EQ("HTTP/1.1 200 OK\r\ntransfer-encoding: chunked\r\n\r\n", output); } @@ -1090,7 +1091,7 @@ TEST_F(Http1ServerConnectionImplTest, DoubleRequest) { codec_->dispatch(buffer); EXPECT_EQ(request.size(), buffer.length()); - response_encoder->encodeHeaders(TestHeaderMapImpl{{":status", "200"}}, true); + response_encoder->encodeHeaders(TestResponseHeaderMapImpl{{":status", "200"}}, true); codec_->dispatch(buffer); EXPECT_EQ(0U, buffer.length()); @@ -1234,7 +1235,7 @@ TEST_F(Http1ServerConnectionImplTest, WatermarkTest) { EXPECT_CALL(stream_callbacks, onAboveWriteBufferHighWatermark()); EXPECT_CALL(stream_callbacks, onBelowWriteBufferLowWatermark()); - TestHeaderMapImpl headers{{":status", "200"}}; + TestResponseHeaderMapImpl headers{{":status", "200"}}; response_encoder->encodeHeaders(headers, false); // Fake out the underlying Network::Connection buffer being drained. @@ -1269,7 +1270,7 @@ TEST_F(Http1ClientConnectionImplTest, SimpleGet) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}}; request_encoder.encodeHeaders(headers, true); EXPECT_EQ("GET / HTTP/1.1\r\ncontent-length: 0\r\n\r\n", output); } @@ -1285,7 +1286,7 @@ TEST_F(Http1ClientConnectionImplTest, SimpleGetWithHeaderCasing) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {"my-custom-header", "hey"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {"my-custom-header", "hey"}}; request_encoder.encodeHeaders(headers, true); EXPECT_EQ("GET / HTTP/1.1\r\nMy-Custom-Header: hey\r\nContent-Length: 0\r\n\r\n", output); } @@ -1299,7 +1300,7 @@ TEST_F(Http1ClientConnectionImplTest, HostHeaderTranslate) { std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); EXPECT_EQ("GET / HTTP/1.1\r\nhost: host\r\ncontent-length: 0\r\n\r\n", output); } @@ -1328,7 +1329,7 @@ TEST_F(Http1ClientConnectionImplTest, FlowControlReadDisabledReenable) { ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); // 1st pipeline request. - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder->encodeHeaders(headers, true); EXPECT_EQ("GET / HTTP/1.1\r\nhost: host\r\ncontent-length: 0\r\n\r\n", output); output.clear(); @@ -1371,7 +1372,7 @@ TEST_F(Http1ClientConnectionImplTest, EmptyBodyResponse503) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); EXPECT_CALL(response_decoder, decodeHeaders_(_, true)); @@ -1384,7 +1385,7 @@ TEST_F(Http1ClientConnectionImplTest, EmptyBodyResponse200) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); EXPECT_CALL(response_decoder, decodeHeaders_(_, true)); @@ -1397,7 +1398,7 @@ TEST_F(Http1ClientConnectionImplTest, HeadRequest) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "HEAD"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "HEAD"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); EXPECT_CALL(response_decoder, decodeHeaders_(_, true)); @@ -1410,7 +1411,7 @@ TEST_F(Http1ClientConnectionImplTest, 204Response) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); EXPECT_CALL(response_decoder, decodeHeaders_(_, true)); @@ -1423,7 +1424,7 @@ TEST_F(Http1ClientConnectionImplTest, 100Response) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); EXPECT_CALL(response_decoder, decode100ContinueHeaders_(_)); @@ -1444,9 +1445,9 @@ TEST_F(Http1ClientConnectionImplTest, BadEncodeParams) { // Need to set :method and :path Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - EXPECT_THROW(request_encoder.encodeHeaders(TestHeaderMapImpl{{":path", "/"}}, true), + EXPECT_THROW(request_encoder.encodeHeaders(TestRequestHeaderMapImpl{{":path", "/"}}, true), CodecClientException); - EXPECT_THROW(request_encoder.encodeHeaders(TestHeaderMapImpl{{":method", "GET"}}, true), + EXPECT_THROW(request_encoder.encodeHeaders(TestRequestHeaderMapImpl{{":method", "GET"}}, true), CodecClientException); } @@ -1455,7 +1456,7 @@ TEST_F(Http1ClientConnectionImplTest, NoContentLengthResponse) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); Buffer::OwnedImpl expected_data1("Hello World"); @@ -1476,7 +1477,7 @@ TEST_F(Http1ClientConnectionImplTest, ResponseWithTrailers) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); Buffer::OwnedImpl response("HTTP/1.1 200 OK\r\n\r\ntransfer-encoding: chunked\r\n\r\nb\r\nHello " @@ -1490,7 +1491,7 @@ TEST_F(Http1ClientConnectionImplTest, GiantPath) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{ + TestRequestHeaderMapImpl headers{ {":method", "GET"}, {":path", "/" + std::string(16384, 'a')}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); @@ -1506,7 +1507,7 @@ TEST_F(Http1ClientConnectionImplTest, UpgradeResponse) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); // Send upgrade headers @@ -1537,7 +1538,7 @@ TEST_F(Http1ClientConnectionImplTest, UpgradeResponseWithEarlyData) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); // Send upgrade headers @@ -1569,7 +1570,7 @@ TEST_F(Http1ClientConnectionImplTest, WatermarkTest) { // high watermark and then draining. EXPECT_CALL(stream_callbacks, onAboveWriteBufferHighWatermark()); EXPECT_CALL(stream_callbacks, onBelowWriteBufferLowWatermark()); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); // Fake out the underlying Network::Connection buffer being drained. @@ -1594,7 +1595,7 @@ TEST_F(Http1ClientConnectionImplTest, HighwatermarkMultipleResponses) { Http::MockStreamCallbacks stream_callbacks; request_encoder.getStream().addCallbacks(stream_callbacks); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); // Fake a call from the underlying Network::Connection and verify the stream is notified. @@ -1728,7 +1729,7 @@ TEST_F(Http1ClientConnectionImplTest, LargeResponseHeadersRejected) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); Buffer::OwnedImpl buffer("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n"); @@ -1744,7 +1745,7 @@ TEST_F(Http1ClientConnectionImplTest, LargeResponseHeadersAccepted) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); Buffer::OwnedImpl buffer("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n"); @@ -1762,7 +1763,8 @@ TEST_F(Http1ClientConnectionImplTest, LargeMethodRequestEncode) { NiceMock response_decoder; const std::string long_method = std::string(79 * 1024, 'a'); Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", long_method}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{ + {":method", long_method}, {":path", "/"}, {":authority", "host"}}; std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); request_encoder.encodeHeaders(headers, true); @@ -1779,7 +1781,8 @@ TEST_F(Http1ClientConnectionImplTest, LargePathRequestEncode) { NiceMock response_decoder; const std::string long_path = std::string(79 * 1024, '/'); Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", long_path}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{ + {":method", "GET"}, {":path", long_path}, {":authority", "host"}}; std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); request_encoder.encodeHeaders(headers, true); @@ -1794,7 +1797,7 @@ TEST_F(Http1ClientConnectionImplTest, LargeHeaderRequestEncode) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); const std::string long_header_value = std::string(79 * 1024, 'a'); - TestHeaderMapImpl headers{ + TestRequestHeaderMapImpl headers{ {":method", "GET"}, {"foo", long_header_value}, {":path", "/"}, {":authority", "host"}}; std::string output; ON_CALL(connection_, write(_, _)).WillByDefault(AddBufferToString(&output)); @@ -1810,7 +1813,7 @@ TEST_F(Http1ClientConnectionImplTest, ManyResponseHeadersRejected) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); Buffer::OwnedImpl buffer("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n"); @@ -1827,7 +1830,7 @@ TEST_F(Http1ClientConnectionImplTest, ManyResponseHeadersAccepted) { NiceMock response_decoder; Http::RequestEncoder& request_encoder = codec_->newStream(response_decoder); - TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; + TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/"}, {":authority", "host"}}; request_encoder.encodeHeaders(headers, true); Buffer::OwnedImpl buffer("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n"); diff --git a/test/common/http/http1/conn_pool_legacy_test.cc b/test/common/http/http1/conn_pool_legacy_test.cc index 89b9f4602f..47ebbec941 100644 --- a/test/common/http/http1/conn_pool_legacy_test.cc +++ b/test/common/http/http1/conn_pool_legacy_test.cc @@ -204,8 +204,8 @@ struct ActiveTestRequest { } void startRequest() { - callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); } Http1ConnPoolImplLegacyTest& parent_; @@ -579,14 +579,14 @@ TEST_F(Http1ConnPoolImplLegacyTest, MaxConnections) { .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks2.pool_ready_, ready()); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); Http::ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); conn_pool_.expectAndRunUpstreamReady(); - callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks2.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); @@ -633,8 +633,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseWithoutHeader) { // Finishing request 1 will schedule binding the connection to request 2. conn_pool_.expectEnableUpstreamReady(); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); Http::ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); @@ -651,8 +651,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseWithoutHeader) { EXPECT_CALL(callbacks2.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks2.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); @@ -684,8 +684,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, ConnectionCloseHeader) { EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -718,8 +718,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, ProxyConnectionCloseHeader) { EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Response with 'proxy-connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -752,8 +752,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, Http10NoConnectionKeepAlive) { EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Response without 'connection: keep-alive' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -788,8 +788,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, MaxRequestsPerConnection) { EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -894,8 +894,8 @@ TEST_F(Http1ConnPoolImplLegacyTest, RemoteCloseToCompleteResponse) { EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); inner_decoder->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); diff --git a/test/common/http/http1/conn_pool_test.cc b/test/common/http/http1/conn_pool_test.cc index 7c7f509809..b1a116af82 100644 --- a/test/common/http/http1/conn_pool_test.cc +++ b/test/common/http/http1/conn_pool_test.cc @@ -203,8 +203,8 @@ struct ActiveTestRequest { } void startRequest() { - callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); } Http1ConnPoolImplTest& parent_; @@ -576,14 +576,14 @@ TEST_F(Http1ConnPoolImplTest, MaxConnections) { .WillOnce(DoAll(SaveArgAddress(&inner_decoder), ReturnRef(request_encoder))); EXPECT_CALL(callbacks2.pool_ready_, ready()); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); Http::ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); conn_pool_.expectAndRunUpstreamReady(); - callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks2.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); @@ -630,8 +630,8 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseWithoutHeader) { // Finishing request 1 will schedule binding the connection to request 2. conn_pool_.expectEnableUpstreamReady(); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); Http::ResponseHeaderMapPtr response_headers(new TestResponseHeaderMapImpl{{":status", "200"}}); inner_decoder->decodeHeaders(std::move(response_headers), true); @@ -648,8 +648,8 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseWithoutHeader) { EXPECT_CALL(callbacks2.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks2.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks2.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // N.B. clang_tidy insists that we use std::make_unique which can not infer std::initialize_list. response_headers = std::make_unique( std::initializer_list>{{":status", "200"}}); @@ -681,8 +681,8 @@ TEST_F(Http1ConnPoolImplTest, ConnectionCloseHeader) { EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -715,8 +715,8 @@ TEST_F(Http1ConnPoolImplTest, ProxyConnectionCloseHeader) { EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Response with 'proxy-connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -749,8 +749,8 @@ TEST_F(Http1ConnPoolImplTest, Http10NoConnectionKeepAlive) { EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Response without 'connection: keep-alive' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -785,8 +785,8 @@ TEST_F(Http1ConnPoolImplTest, MaxRequestsPerConnection) { EXPECT_CALL(callbacks.pool_ready_, ready()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Response with 'connection: close' which should cause the connection to go away. EXPECT_CALL(conn_pool_, onClientDestroy()); @@ -890,8 +890,8 @@ TEST_F(Http1ConnPoolImplTest, RemoteCloseToCompleteResponse) { EXPECT_CALL(*conn_pool_.test_clients_[0].connect_timer_, disableTimer()); conn_pool_.test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::Connected); - callbacks.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + callbacks.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); inner_decoder->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, false); diff --git a/test/common/http/http2/codec_impl_test.cc b/test/common/http/http2/codec_impl_test.cc index 9c049d2734..7b0a72bce9 100644 --- a/test/common/http/http2/codec_impl_test.cc +++ b/test/common/http/http2/codec_impl_test.cc @@ -177,7 +177,7 @@ class Http2CodecImplTest : public ::testing::TestWithParamencodeHeaders(request_headers, false); @@ -194,7 +194,7 @@ class Http2CodecImplTest : public ::testing::TestWithParamencodeHeaders(request_headers, true); @@ -202,7 +202,7 @@ class Http2CodecImplTest : public ::testing::TestWithParamencodeHeaders(response_headers, false); Buffer::OwnedImpl data("0"); EXPECT_NO_THROW(response_encoder_->encodeData(data, false)); @@ -219,7 +219,7 @@ class Http2CodecImplTest : public ::testing::TestWithParamencodeHeaders(request_headers, false); @@ -238,7 +238,7 @@ class Http2CodecImplTest : public ::testing::TestWithParamencodeHeaders(request_headers, true); @@ -247,7 +247,7 @@ TEST_P(Http2CodecImplTest, ShutdownNotice) { server_->shutdownNotice(); server_->goAway(); - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(response_decoder_, decodeHeaders_(_, true)); response_encoder_->encodeHeaders(response_headers, true); } @@ -255,16 +255,16 @@ TEST_P(Http2CodecImplTest, ShutdownNotice) { TEST_P(Http2CodecImplTest, ContinueHeaders) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); - TestHeaderMapImpl continue_headers{{":status", "100"}}; + TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; EXPECT_CALL(response_decoder_, decode100ContinueHeaders_(_)); response_encoder_->encode100ContinueHeaders(continue_headers); - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(response_decoder_, decodeHeaders_(_, true)); response_encoder_->encodeHeaders(response_headers, true); }; @@ -272,12 +272,12 @@ TEST_P(Http2CodecImplTest, ContinueHeaders) { TEST_P(Http2CodecImplTest, InvalidContinueWithFin) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); - TestHeaderMapImpl continue_headers{{":status", "100"}}; + TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; EXPECT_THROW(response_encoder_->encodeHeaders(continue_headers, true), CodecProtocolException); EXPECT_EQ(1, stats_store_.counter("http2.rx_messaging_error").value()); } @@ -289,7 +289,7 @@ TEST_P(Http2CodecImplTest, InvalidContinueWithFinAllowed) { MockStreamCallbacks request_callbacks; request_encoder_->getStream().addCallbacks(request_callbacks); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); @@ -299,7 +299,7 @@ TEST_P(Http2CodecImplTest, InvalidContinueWithFinAllowed) { .WillByDefault( Invoke([&](Buffer::Instance& data, bool) -> void { client_wrapper_.buffer_.add(data); })); - TestHeaderMapImpl continue_headers{{":status", "100"}}; + TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; response_encoder_->encodeHeaders(continue_headers, true); // Flush pending data. @@ -313,12 +313,12 @@ TEST_P(Http2CodecImplTest, InvalidContinueWithFinAllowed) { TEST_P(Http2CodecImplTest, InvalidRepeatContinue) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); - TestHeaderMapImpl continue_headers{{":status", "100"}}; + TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; EXPECT_CALL(response_decoder_, decode100ContinueHeaders_(_)); response_encoder_->encode100ContinueHeaders(continue_headers); @@ -333,12 +333,12 @@ TEST_P(Http2CodecImplTest, InvalidRepeatContinueAllowed) { MockStreamCallbacks request_callbacks; request_encoder_->getStream().addCallbacks(request_callbacks); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); - TestHeaderMapImpl continue_headers{{":status", "100"}}; + TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; EXPECT_CALL(response_decoder_, decode100ContinueHeaders_(_)); response_encoder_->encode100ContinueHeaders(continue_headers); @@ -360,16 +360,16 @@ TEST_P(Http2CodecImplTest, InvalidRepeatContinueAllowed) { TEST_P(Http2CodecImplTest, Invalid103) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); - TestHeaderMapImpl continue_headers{{":status", "100"}}; + TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; EXPECT_CALL(response_decoder_, decode100ContinueHeaders_(_)); response_encoder_->encode100ContinueHeaders(continue_headers); - TestHeaderMapImpl early_hint_headers{{":status", "103"}}; + TestResponseHeaderMapImpl early_hint_headers{{":status", "103"}}; EXPECT_CALL(response_decoder_, decodeHeaders_(_, false)); response_encoder_->encodeHeaders(early_hint_headers, false); @@ -381,12 +381,12 @@ TEST_P(Http2CodecImplTest, Invalid103) { TEST_P(Http2CodecImplTest, Invalid204WithContentLength) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); - TestHeaderMapImpl response_headers{{":status", "204"}, {"content-length", "3"}}; + TestResponseHeaderMapImpl response_headers{{":status", "204"}, {"content-length", "3"}}; // What follows is a hack to get headers that should span into continuation frames. The default // maximum frame size is 16K. We will add 3,000 headers that will take us above this size and // not easily compress with HPACK. (I confirmed this generates 26,468 bytes of header data @@ -406,7 +406,7 @@ TEST_P(Http2CodecImplTest, Invalid204WithContentLengthAllowed) { MockStreamCallbacks request_callbacks; request_encoder_->getStream().addCallbacks(request_callbacks); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); @@ -416,7 +416,7 @@ TEST_P(Http2CodecImplTest, Invalid204WithContentLengthAllowed) { .WillByDefault( Invoke([&](Buffer::Instance& data, bool) -> void { client_wrapper_.buffer_.add(data); })); - TestHeaderMapImpl response_headers{{":status", "204"}, {"content-length", "3"}}; + TestResponseHeaderMapImpl response_headers{{":status", "204"}, {"content-length", "3"}}; // What follows is a hack to get headers that should span into continuation frames. The default // maximum frame size is 16K. We will add 3,000 headers that will take us above this size and // not easily compress with HPACK. (I confirmed this generates 26,468 bytes of header data @@ -439,7 +439,7 @@ TEST_P(Http2CodecImplTest, Invalid204WithContentLengthAllowed) { TEST_P(Http2CodecImplTest, RefusedStreamReset) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -455,7 +455,8 @@ TEST_P(Http2CodecImplTest, RefusedStreamReset) { TEST_P(Http2CodecImplTest, InvalidHeadersFrame) { initialize(); - EXPECT_THROW(request_encoder_->encodeHeaders(TestHeaderMapImpl{}, true), CodecProtocolException); + EXPECT_THROW(request_encoder_->encodeHeaders(TestRequestHeaderMapImpl{}, true), + CodecProtocolException); EXPECT_EQ(1, stats_store_.counter("http2.rx_messaging_error").value()); } @@ -470,7 +471,7 @@ TEST_P(Http2CodecImplTest, InvalidHeadersFrameAllowed) { .WillByDefault( Invoke([&](Buffer::Instance& data, bool) -> void { server_wrapper_.buffer_.add(data); })); - request_encoder_->encodeHeaders(TestHeaderMapImpl{}, true); + request_encoder_->encodeHeaders(TestRequestHeaderMapImpl{}, true); EXPECT_CALL(server_stream_callbacks_, onResetStream(StreamResetReason::LocalReset, _)); EXPECT_CALL(request_callbacks, onResetStream(StreamResetReason::RemoteReset, _)); server_wrapper_.dispatch(Buffer::OwnedImpl(), *server_); @@ -479,7 +480,7 @@ TEST_P(Http2CodecImplTest, InvalidHeadersFrameAllowed) { TEST_P(Http2CodecImplTest, TrailingHeaders) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -487,16 +488,16 @@ TEST_P(Http2CodecImplTest, TrailingHeaders) { Buffer::OwnedImpl hello("hello"); request_encoder_->encodeData(hello, false); EXPECT_CALL(request_decoder_, decodeTrailers_(_)); - request_encoder_->encodeTrailers(TestHeaderMapImpl{{"trailing", "header"}}); + request_encoder_->encodeTrailers(TestRequestTrailerMapImpl{{"trailing", "header"}}); - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(response_decoder_, decodeHeaders_(_, false)); response_encoder_->encodeHeaders(response_headers, false); EXPECT_CALL(response_decoder_, decodeData(_, false)); Buffer::OwnedImpl world("world"); response_encoder_->encodeData(world, false); EXPECT_CALL(response_decoder_, decodeTrailers_(_)); - response_encoder_->encodeTrailers(TestHeaderMapImpl{{"trailing", "header"}}); + response_encoder_->encodeTrailers(TestResponseTrailerMapImpl{{"trailing", "header"}}); } TEST_P(Http2CodecImplTest, TrailingHeadersLargeBody) { @@ -507,7 +508,7 @@ TEST_P(Http2CodecImplTest, TrailingHeadersLargeBody) { .WillByDefault( Invoke([&](Buffer::Instance& data, bool) -> void { server_wrapper_.buffer_.add(data); })); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -515,20 +516,20 @@ TEST_P(Http2CodecImplTest, TrailingHeadersLargeBody) { Buffer::OwnedImpl body(std::string(1024 * 1024, 'a')); request_encoder_->encodeData(body, false); EXPECT_CALL(request_decoder_, decodeTrailers_(_)); - request_encoder_->encodeTrailers(TestHeaderMapImpl{{"trailing", "header"}}); + request_encoder_->encodeTrailers(TestRequestTrailerMapImpl{{"trailing", "header"}}); // Flush pending data. setupDefaultConnectionMocks(); server_wrapper_.dispatch(Buffer::OwnedImpl(), *server_); - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(response_decoder_, decodeHeaders_(_, false)); response_encoder_->encodeHeaders(response_headers, false); EXPECT_CALL(response_decoder_, decodeData(_, false)); Buffer::OwnedImpl world("world"); response_encoder_->encodeData(world, false); EXPECT_CALL(response_decoder_, decodeTrailers_(_)); - response_encoder_->encodeTrailers(TestHeaderMapImpl{{"trailing", "header"}}); + response_encoder_->encodeTrailers(TestResponseTrailerMapImpl{{"trailing", "header"}}); } TEST_P(Http2CodecImplTest, SmallMetadataVecTest) { @@ -536,7 +537,7 @@ TEST_P(Http2CodecImplTest, SmallMetadataVecTest) { initialize(); // Generates a valid stream_id by sending a request header. - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); @@ -566,7 +567,7 @@ TEST_P(Http2CodecImplTest, LargeMetadataVecTest) { initialize(); // Generates a valid stream_id by sending a request header. - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); @@ -593,7 +594,7 @@ TEST_P(Http2CodecImplTest, BadMetadataVecReceivedTest) { initialize(); // Generates a valid stream_id by sending a request header. - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); @@ -628,7 +629,7 @@ TEST_P(Http2CodecImplDeferredResetTest, DeferredResetClient) { ON_CALL(client_connection_, write(_, _)) .WillByDefault( Invoke([&](Buffer::Instance& data, bool) -> void { server_wrapper_.buffer_.add(data); })); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); request_encoder_->encodeHeaders(request_headers, false); Buffer::OwnedImpl body(std::string(1024 * 1024, 'a')); @@ -643,7 +644,7 @@ TEST_P(Http2CodecImplDeferredResetTest, DeferredResetClient) { // Start a response inside the headers callback. This should not result in the client // seeing any headers as the stream should already be reset on the other side, even though // we don't know about it yet. - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; response_encoder_->encodeHeaders(response_headers, false); })); EXPECT_CALL(request_decoder_, decodeData(_, false)).Times(AtLeast(1)); @@ -658,7 +659,7 @@ TEST_P(Http2CodecImplDeferredResetTest, DeferredResetServer) { InSequence s; - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -667,7 +668,7 @@ TEST_P(Http2CodecImplDeferredResetTest, DeferredResetServer) { ON_CALL(server_connection_, write(_, _)) .WillByDefault( Invoke([&](Buffer::Instance& data, bool) -> void { client_wrapper_.buffer_.add(data); })); - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; response_encoder_->encodeHeaders(response_headers, false); Buffer::OwnedImpl body(std::string(1024 * 1024, 'a')); EXPECT_CALL(server_stream_callbacks_, onAboveWriteBufferHighWatermark()).Times(AnyNumber()); @@ -696,7 +697,7 @@ TEST_P(Http2CodecImplFlowControlTest, TestFlowControlInPendingSendData) { MockStreamCallbacks callbacks; request_encoder_->getStream().addCallbacks(callbacks); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); TestHeaderMapImpl expected_headers; HttpTestUtility::addDefaultHeaders(expected_headers); @@ -796,7 +797,7 @@ TEST_P(Http2CodecImplFlowControlTest, EarlyResetRestoresWindow) { MockStreamCallbacks callbacks; request_encoder_->getStream().addCallbacks(callbacks); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); TestHeaderMapImpl expected_headers; HttpTestUtility::addDefaultHeaders(expected_headers); @@ -855,7 +856,7 @@ TEST_P(Http2CodecImplFlowControlTest, FlowControlPendingRecvData) { initialize(); MockStreamCallbacks callbacks; - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); TestHeaderMapImpl expected_headers; HttpTestUtility::addDefaultHeaders(expected_headers); @@ -878,7 +879,7 @@ TEST_P(Http2CodecImplTest, WatermarkUnderEndStream) { MockStreamCallbacks callbacks; request_encoder_->getStream().addCallbacks(callbacks); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -906,7 +907,7 @@ TEST_P(Http2CodecImplTest, WatermarkUnderEndStream) { EXPECT_CALL(callbacks, onBelowWriteBufferLowWatermark()).Times(0); EXPECT_CALL(server_stream_callbacks_, onAboveWriteBufferHighWatermark()).Times(0); EXPECT_CALL(server_stream_callbacks_, onBelowWriteBufferLowWatermark()).Times(0); - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(response_decoder_, decodeHeaders_(HeaderMapEqual(&response_headers), true)) .WillOnce(InvokeWithoutArgs([&]() -> void { client_->onUnderlyingConnectionAboveWriteBufferHighWatermark(); @@ -943,7 +944,7 @@ TEST_P(Http2CodecImplStreamLimitTest, MaxClientStreams) { return request_decoder_; })); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); @@ -1043,7 +1044,7 @@ TEST(Http2CodecUtility, reconstituteCrumbledCookies) { TEST_P(Http2CodecImplTest, LargeRequestHeadersInvokeResetStream) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); std::string long_string = std::string(63 * 1024, 'q'); request_headers.addCopy("big", long_string); @@ -1056,7 +1057,7 @@ TEST_P(Http2CodecImplTest, LargeRequestHeadersAccepted) { max_request_headers_kb_ = 64; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); std::string long_string = std::string(63 * 1024, 'q'); request_headers.addCopy("big", long_string); @@ -1077,7 +1078,7 @@ TEST_P(Http2CodecImplTest, LargeMethodRequestEncode) { initialize(); const std::string long_method = std::string(79 * 1024, 'a'); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); request_headers.setReferenceKey(Headers::get().Method, long_method); EXPECT_CALL(request_decoder_, decodeHeaders_(HeaderMapEqual(&request_headers), false)); @@ -1089,7 +1090,7 @@ TEST_P(Http2CodecImplTest, LargeMethodRequestEncode) { TEST_P(Http2CodecImplTest, ManyRequestHeadersInvokeResetStream) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); for (int i = 0; i < 100; i++) { request_headers.addCopy(std::to_string(i), ""); @@ -1103,7 +1104,7 @@ TEST_P(Http2CodecImplTest, ManyRequestHeadersAccepted) { max_request_headers_count_ = 150; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); for (int i = 0; i < 145; i++) { request_headers.addCopy(std::to_string(i), ""); @@ -1118,12 +1119,12 @@ TEST_P(Http2CodecImplTest, ManyResponseHeadersAccepted) { max_response_headers_count_ = 110; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); - TestHeaderMapImpl response_headers{{":status", "200"}, {"compression", "test"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"compression", "test"}}; for (int i = 0; i < 105; i++) { response_headers.addCopy(std::to_string(i), ""); } @@ -1136,7 +1137,7 @@ TEST_P(Http2CodecImplTest, LargeRequestHeadersAtLimitAccepted) { max_request_headers_kb_ = codec_limit_kb; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); std::string key = "big"; uint32_t head_room = 77; @@ -1158,7 +1159,7 @@ TEST_P(Http2CodecImplTest, LargeRequestHeadersOverDefaultCodecLibraryLimit) { max_request_headers_kb_ = 66; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); std::string long_string = std::string(65 * 1024, 'q'); request_headers.addCopy("big", long_string); @@ -1176,7 +1177,7 @@ TEST_P(Http2CodecImplTest, LargeRequestHeadersExceedPerHeaderLimit) { max_request_headers_kb_ = 81; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); std::string long_string = std::string(80 * 1024, 'q'); request_headers.addCopy("big", long_string); @@ -1192,7 +1193,7 @@ TEST_P(Http2CodecImplTest, ManyLargeRequestHeadersUnderPerHeaderLimit) { max_request_headers_kb_ = 81; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); std::string long_string = std::string(1024, 'q'); for (int i = 0; i < 80; i++) { @@ -1210,7 +1211,7 @@ TEST_P(Http2CodecImplTest, LargeRequestHeadersAtMaxConfigurable) { max_request_headers_kb_ = 96; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); std::string long_string = std::string(1024, 'q'); for (int i = 0; i < 95; i++) { @@ -1227,12 +1228,12 @@ TEST_P(Http2CodecImplTest, LargeRequestHeadersAtMaxConfigurable) { TEST_P(Http2CodecImplTestAll, TestCodecHeaderCompression) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, true)); request_encoder_->encodeHeaders(request_headers, true); - TestHeaderMapImpl response_headers{{":status", "200"}, {"compression", "test"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"compression", "test"}}; EXPECT_CALL(response_decoder_, decodeHeaders_(_, true)); response_encoder_->encodeHeaders(response_headers, true); @@ -1256,7 +1257,7 @@ TEST_P(Http2CodecImplTestAll, TestCodecHeaderCompression) { TEST_P(Http2CodecImplTest, PingFlood) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -1284,7 +1285,7 @@ TEST_P(Http2CodecImplTest, PingFloodMitigationDisabled) { max_outbound_control_frames_ = 2147483647; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -1305,7 +1306,7 @@ TEST_P(Http2CodecImplTest, PingFloodCounterReset) { max_outbound_control_frames_ = kMaxOutboundControlFrames; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -1345,7 +1346,7 @@ TEST_P(Http2CodecImplTest, PingFloodCounterReset) { TEST_P(Http2CodecImplTest, ResponseHeadersFlood) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -1358,7 +1359,7 @@ TEST_P(Http2CodecImplTest, ResponseHeadersFlood) { buffer.move(frame); })); - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; for (uint32_t i = 0; i < Http2Settings::DEFAULT_MAX_OUTBOUND_FRAMES + 1; ++i) { EXPECT_NO_THROW(response_encoder_->encodeHeaders(response_headers, false)); } @@ -1375,7 +1376,7 @@ TEST_P(Http2CodecImplTest, ResponseHeadersFlood) { TEST_P(Http2CodecImplTest, ResponseDataFlood) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -1388,7 +1389,7 @@ TEST_P(Http2CodecImplTest, ResponseDataFlood) { buffer.move(frame); })); - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; response_encoder_->encodeHeaders(response_headers, false); // Account for the single HEADERS frame above for (uint32_t i = 0; i < Http2Settings::DEFAULT_MAX_OUTBOUND_FRAMES; ++i) { @@ -1409,7 +1410,7 @@ TEST_P(Http2CodecImplTest, ResponseDataFloodMitigationDisabled) { max_outbound_control_frames_ = 2147483647; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -1420,7 +1421,7 @@ TEST_P(Http2CodecImplTest, ResponseDataFloodMitigationDisabled) { EXPECT_CALL(response_decoder_, decodeHeaders_(_, false)).Times(1); EXPECT_CALL(response_decoder_, decodeData(_, false)) .Times(Http2Settings::DEFAULT_MAX_OUTBOUND_FRAMES); - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; response_encoder_->encodeHeaders(response_headers, false); // Account for the single HEADERS frame above for (uint32_t i = 0; i < Http2Settings::DEFAULT_MAX_OUTBOUND_FRAMES; ++i) { @@ -1439,7 +1440,7 @@ TEST_P(Http2CodecImplTest, ResponseDataFloodCounterReset) { max_outbound_frames_ = kMaxOutboundFrames; initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -1452,7 +1453,7 @@ TEST_P(Http2CodecImplTest, ResponseDataFloodCounterReset) { buffer.move(frame); })); - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; response_encoder_->encodeHeaders(response_headers, false); // Account for the single HEADERS frame above for (uint32_t i = 0; i < kMaxOutboundFrames - 1; ++i) { @@ -1479,7 +1480,7 @@ TEST_P(Http2CodecImplTest, ResponseDataFloodCounterReset) { TEST_P(Http2CodecImplTest, PingStacksWithDataFlood) { initialize(); - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); EXPECT_CALL(request_decoder_, decodeHeaders_(_, false)); request_encoder_->encodeHeaders(request_headers, false); @@ -1492,7 +1493,7 @@ TEST_P(Http2CodecImplTest, PingStacksWithDataFlood) { buffer.move(frame); })); - TestHeaderMapImpl response_headers{{":status", "200"}}; + TestResponseHeaderMapImpl response_headers{{":status", "200"}}; response_encoder_->encodeHeaders(response_headers, false); // Account for the single HEADERS frame above for (uint32_t i = 0; i < Http2Settings::DEFAULT_MAX_OUTBOUND_FRAMES - 1; ++i) { diff --git a/test/common/http/http2/conn_pool_legacy_test.cc b/test/common/http/http2/conn_pool_legacy_test.cc index b99cd98b74..300bbf00b5 100644 --- a/test/common/http/http2/conn_pool_legacy_test.cc +++ b/test/common/http/http2/conn_pool_legacy_test.cc @@ -188,8 +188,8 @@ void Http2ConnPoolImplLegacyTest::closeClient(size_t index) { void Http2ConnPoolImplLegacyTest::completeRequest(ActiveTestRequest& r) { EXPECT_CALL(r.inner_encoder_, encodeHeaders(_, true)); - r.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r.decoder_, decodeHeaders_(_, true)); r.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -219,15 +219,15 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainConnections) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // This will move primary to draining and destroy draining. pool_.drainConnections(); @@ -260,16 +260,16 @@ TEST_F(Http2ConnPoolImplLegacyTest, PendingRequests) { // Send a request through each stream. EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r3.inner_encoder_, encodeHeaders(_, true)); - r3.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r3.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Since we now have an active connection, subsequent requests should connect immediately. ActiveTestRequest r4(*this, 0, true); @@ -398,8 +398,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, VerifyConnectionTimingStats) { deliverHistogramToSinks(Property(&Stats::Metric::name, "upstream_cx_connect_ms"), _)); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); r1.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -424,8 +424,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, VerifyBufferLimits) { expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); r1.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -445,16 +445,16 @@ TEST_F(Http2ConnPoolImplLegacyTest, RequestAndResponse) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); r1.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); ActiveTestRequest r2(*this, 0, true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); r2.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -474,8 +474,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, LocalReset) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, false)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - false); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, false); r1.callbacks_.outer_encoder_->getStream().resetStream(Http::StreamResetReason::LocalReset); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -494,8 +494,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, RemoteReset) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, false)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - false); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, false); r1.inner_encoder_.stream_.resetStream(Http::StreamResetReason::RemoteReset); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -515,8 +515,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainDisconnectWithActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); @@ -539,15 +539,15 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainDisconnectDrainingWithActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); @@ -577,15 +577,15 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainPrimary) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); @@ -615,8 +615,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainPrimaryNoActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); r1.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -628,8 +628,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, DrainPrimaryNoActiveRequest) { EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); r2.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -662,8 +662,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, ConnectTimeout) { ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); r2.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -689,8 +689,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, MaxGlobalRequests) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); ConnPoolCallbacks callbacks; MockResponseDecoder decoder; @@ -712,8 +712,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, GoAway) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); r1.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -724,8 +724,8 @@ TEST_F(Http2ConnPoolImplLegacyTest, GoAway) { ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); r2.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index 23fb0efc57..03abccfcf2 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -189,8 +189,8 @@ void Http2ConnPoolImplTest::closeClient(size_t index) { void Http2ConnPoolImplTest::completeRequest(ActiveTestRequest& r) { EXPECT_CALL(r.inner_encoder_, encodeHeaders(_, true)); - r.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r.decoder_, decodeHeaders_(_, true)); r.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -232,8 +232,8 @@ TEST_F(Http2ConnPoolImplTest, DrainConnectionReadyWithRequest) { ActiveTestRequest r(*this, 0, false); expectClientConnect(0, r); EXPECT_CALL(r.inner_encoder_, encodeHeaders(_, true)); - r.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); pool_.drainConnections(); @@ -255,8 +255,8 @@ TEST_F(Http2ConnPoolImplTest, DrainConnectionBusy) { ActiveTestRequest r(*this, 0, false); expectClientConnect(0, r); EXPECT_CALL(r.inner_encoder_, encodeHeaders(_, true)); - r.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); pool_.drainConnections(); @@ -302,8 +302,8 @@ TEST_F(Http2ConnPoolImplTest, DrainConnections) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // With max_streams == 1, the second request moves the first connection // to draining. @@ -311,8 +311,8 @@ TEST_F(Http2ConnPoolImplTest, DrainConnections) { ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // This will move the second connection to draining. pool_.drainConnections(); @@ -397,16 +397,16 @@ TEST_F(Http2ConnPoolImplTest, PendingRequests) { // Send a request through each stream. EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r3.inner_encoder_, encodeHeaders(_, true)); - r3.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r3.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Since we now have an active connection, subsequent requests should connect immediately. ActiveTestRequest r4(*this, 0, true); @@ -441,16 +441,16 @@ TEST_F(Http2ConnPoolImplTest, PendingRequestsNumberConnectingTotalRequestsPerCon // Send a request through each stream. EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r3.inner_encoder_, encodeHeaders(_, true)); - r3.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r3.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Clean up everything. test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -480,16 +480,16 @@ TEST_F(Http2ConnPoolImplTest, PendingRequestsNumberConnectingConcurrentRequestsP // Send a request through each stream. EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r3.inner_encoder_, encodeHeaders(_, true)); - r3.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r3.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); // Clean up everything. test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -613,8 +613,8 @@ TEST_F(Http2ConnPoolImplTest, VerifyConnectionTimingStats) { deliverHistogramToSinks(Property(&Stats::Metric::name, "upstream_cx_connect_ms"), _)); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); r1.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -639,8 +639,8 @@ TEST_F(Http2ConnPoolImplTest, VerifyBufferLimits) { expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); r1.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -660,8 +660,8 @@ TEST_F(Http2ConnPoolImplTest, RequestAndResponse) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_EQ(1U, cluster_->stats_.upstream_cx_active_.value()); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); r1.inner_decoder_->decodeHeaders( @@ -669,8 +669,8 @@ TEST_F(Http2ConnPoolImplTest, RequestAndResponse) { ActiveTestRequest r2(*this, 0, true); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); r2.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -691,8 +691,8 @@ TEST_F(Http2ConnPoolImplTest, LocalReset) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, false)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - false); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, false); r1.callbacks_.outer_encoder_->getStream().resetStream(Http::StreamResetReason::LocalReset); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -712,8 +712,8 @@ TEST_F(Http2ConnPoolImplTest, RemoteReset) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, false)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - false); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, false); r1.inner_encoder_.stream_.resetStream(Http::StreamResetReason::RemoteReset); test_clients_[0].connection_->raiseEvent(Network::ConnectionEvent::RemoteClose); @@ -734,8 +734,8 @@ TEST_F(Http2ConnPoolImplTest, DrainDisconnectWithActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); @@ -760,15 +760,15 @@ TEST_F(Http2ConnPoolImplTest, DrainDisconnectDrainingWithActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); @@ -800,15 +800,15 @@ TEST_F(Http2ConnPoolImplTest, DrainPrimary) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); expectClientCreate(); ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); ReadyWatcher drained; pool_.addDrainedCallback([&]() -> void { drained.ready(); }); @@ -840,8 +840,8 @@ TEST_F(Http2ConnPoolImplTest, DrainPrimaryNoActiveRequest) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); r1.inner_decoder_->decodeHeaders( @@ -853,8 +853,8 @@ TEST_F(Http2ConnPoolImplTest, DrainPrimaryNoActiveRequest) { EXPECT_CALL(*this, onClientDestroy()); dispatcher_.clearDeferredDeleteList(); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(dispatcher_, deferredDelete_(_)); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); r2.inner_decoder_->decodeHeaders( @@ -887,8 +887,8 @@ TEST_F(Http2ConnPoolImplTest, ConnectTimeout) { ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); r2.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -914,8 +914,8 @@ TEST_F(Http2ConnPoolImplTest, MaxGlobalRequests) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); ConnPoolCallbacks callbacks; MockResponseDecoder decoder; @@ -937,8 +937,8 @@ TEST_F(Http2ConnPoolImplTest, GoAway) { ActiveTestRequest r1(*this, 0, false); expectClientConnect(0, r1); EXPECT_CALL(r1.inner_encoder_, encodeHeaders(_, true)); - r1.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r1.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r1.decoder_, decodeHeaders_(_, true)); r1.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); @@ -949,8 +949,8 @@ TEST_F(Http2ConnPoolImplTest, GoAway) { ActiveTestRequest r2(*this, 1, false); expectClientConnect(1, r2); EXPECT_CALL(r2.inner_encoder_, encodeHeaders(_, true)); - r2.callbacks_.outer_encoder_->encodeHeaders(TestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, - true); + r2.callbacks_.outer_encoder_->encodeHeaders( + TestRequestHeaderMapImpl{{":path", "/"}, {":method", "GET"}}, true); EXPECT_CALL(r2.decoder_, decodeHeaders_(_, true)); r2.inner_decoder_->decodeHeaders( ResponseHeaderMapPtr{new TestResponseHeaderMapImpl{{":status", "200"}}}, true); diff --git a/test/common/http/http2/frame_replay_test.cc b/test/common/http/http2/frame_replay_test.cc index e9869b2963..db48d56031 100644 --- a/test/common/http/http2/frame_replay_test.cc +++ b/test/common/http/http2/frame_replay_test.cc @@ -30,7 +30,7 @@ void setupStream(ClientCodecFrameInjector& codec, TestClientConnectionImpl& conn codec.request_encoder_ = &connection.newStream(codec.response_decoder_); codec.request_encoder_->getStream().addCallbacks(codec.client_stream_callbacks_); // Setup a single stream to inject frames as a reply to. - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); codec.request_encoder_->encodeHeaders(request_headers, true); } diff --git a/test/common/http/http2/response_header_fuzz_test.cc b/test/common/http/http2/response_header_fuzz_test.cc index f1f3ff57e4..60586dc81e 100644 --- a/test/common/http/http2/response_header_fuzz_test.cc +++ b/test/common/http/http2/response_header_fuzz_test.cc @@ -24,7 +24,7 @@ void Replay(const Frame& frame, ClientCodecFrameInjector& codec) { codec.request_encoder_ = &connection.newStream(codec.response_decoder_); codec.request_encoder_->getStream().addCallbacks(codec.client_stream_callbacks_); // Setup a single stream to inject frames as a reply to. - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; HttpTestUtility::addDefaultHeaders(request_headers); codec.request_encoder_->encodeHeaders(request_headers, true); diff --git a/test/common/http/utility_test.cc b/test/common/http/utility_test.cc index b967bdb90b..586a721a81 100644 --- a/test/common/http/utility_test.cc +++ b/test/common/http/utility_test.cc @@ -167,7 +167,7 @@ TEST(HttpUtility, MethodNotPreserved) { TEST(HttpUtility, ContentLengthMangling) { // Content-Length of 0 is removed on the request path. { - TestHeaderMapImpl request_headers = { + TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {"Upgrade", "foo"}, {"Connection", "upgrade"}, {"content-length", "0"}}; Utility::transformUpgradeRequestFromH1toH2(request_headers); EXPECT_TRUE(request_headers.ContentLength() == nullptr); @@ -175,7 +175,7 @@ TEST(HttpUtility, ContentLengthMangling) { // Non-zero Content-Length is not removed on the request path. { - TestHeaderMapImpl request_headers = { + TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {"Upgrade", "foo"}, {"Connection", "upgrade"}, {"content-length", "1"}}; Utility::transformUpgradeRequestFromH1toH2(request_headers); EXPECT_FALSE(request_headers.ContentLength() == nullptr); @@ -297,7 +297,8 @@ TEST(HttpUtility, getLastAddressFromXFF) { const std::string first_address = "192.0.2.10"; const std::string second_address = "192.0.2.1"; const std::string third_address = "10.0.0.1"; - TestHeaderMapImpl request_headers{{"x-forwarded-for", "192.0.2.10, 192.0.2.1, 10.0.0.1"}}; + TestRequestHeaderMapImpl request_headers{ + {"x-forwarded-for", "192.0.2.10, 192.0.2.1, 10.0.0.1"}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(third_address, ret.address_->ip()->addressAsString()); EXPECT_FALSE(ret.single_address_); @@ -316,7 +317,7 @@ TEST(HttpUtility, getLastAddressFromXFF) { const std::string second_address = "192.0.2.1"; const std::string third_address = "10.0.0.1"; const std::string fourth_address = "10.0.0.2"; - TestHeaderMapImpl request_headers{ + TestRequestHeaderMapImpl request_headers{ {"x-forwarded-for", "192.0.2.10, 192.0.2.1 ,10.0.0.1,10.0.0.2"}}; // No space on the left. @@ -345,38 +346,38 @@ TEST(HttpUtility, getLastAddressFromXFF) { EXPECT_FALSE(ret.single_address_); } { - TestHeaderMapImpl request_headers{{"x-forwarded-for", ""}}; + TestRequestHeaderMapImpl request_headers{{"x-forwarded-for", ""}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(nullptr, ret.address_); EXPECT_FALSE(ret.single_address_); } { - TestHeaderMapImpl request_headers{{"x-forwarded-for", ","}}; + TestRequestHeaderMapImpl request_headers{{"x-forwarded-for", ","}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(nullptr, ret.address_); EXPECT_FALSE(ret.single_address_); } { - TestHeaderMapImpl request_headers{{"x-forwarded-for", ", "}}; + TestRequestHeaderMapImpl request_headers{{"x-forwarded-for", ", "}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(nullptr, ret.address_); EXPECT_FALSE(ret.single_address_); } { - TestHeaderMapImpl request_headers{{"x-forwarded-for", ", bad"}}; + TestRequestHeaderMapImpl request_headers{{"x-forwarded-for", ", bad"}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(nullptr, ret.address_); EXPECT_FALSE(ret.single_address_); } { - TestHeaderMapImpl request_headers; + TestRequestHeaderMapImpl request_headers; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(nullptr, ret.address_); EXPECT_FALSE(ret.single_address_); } { const std::string first_address = "34.0.0.1"; - TestHeaderMapImpl request_headers{{"x-forwarded-for", first_address}}; + TestRequestHeaderMapImpl request_headers{{"x-forwarded-for", first_address}}; auto ret = Utility::getLastAddressFromXFF(request_headers); EXPECT_EQ(first_address, ret.address_->ip()->addressAsString()); EXPECT_TRUE(ret.single_address_); @@ -583,7 +584,7 @@ TEST(HttpUtility, TestPrepareHeaders) { envoy::config::core::v3::HttpUri http_uri; http_uri.set_uri("scheme://dns.name/x/y/z"); - Http::MessagePtr message = Utility::prepareHeaders(http_uri); + Http::RequestMessagePtr message = Utility::prepareHeaders(http_uri); EXPECT_EQ("/x/y/z", message->headers().Path()->value().getStringView()); EXPECT_EQ("dns.name", message->headers().Host()->value().getStringView()); @@ -790,7 +791,7 @@ TEST(HttpUtility, CheckIsIpAddress) { // Validates TE header is stripped if it contains an unsupported value // Also validate the behavior if a nominated header does not exist TEST(HttpUtility, TestTeHeaderGzipTrailersSanitized) { - TestHeaderMapImpl request_headers = { + TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -820,7 +821,7 @@ TEST(HttpUtility, TestTeHeaderGzipTrailersSanitized) { // Validates that if the connection header is nominated, the // true connection header is not removed TEST(HttpUtility, TestNominatedConnectionHeader) { - TestHeaderMapImpl request_headers = { + TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -848,7 +849,7 @@ TEST(HttpUtility, TestNominatedConnectionHeader) { // sanitize correctly preserving other nominated headers with // supported values TEST(HttpUtility, TestNominatedConnectionHeader2) { - Http::TestHeaderMapImpl request_headers = { + Http::TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -877,7 +878,7 @@ TEST(HttpUtility, TestNominatedConnectionHeader2) { // This includes an extra comma to ensure that the resulting // header is still correct TEST(HttpUtility, TestNominatedPseudoHeader) { - Http::TestHeaderMapImpl request_headers = { + Http::TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -897,7 +898,7 @@ TEST(HttpUtility, TestNominatedPseudoHeader) { // Validate that we can sanitize the headers when splitting // the Connection header results in empty tokens TEST(HttpUtility, TestSanitizeEmptyTokensFromHeaders) { - Http::TestHeaderMapImpl request_headers = { + Http::TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -925,7 +926,7 @@ TEST(HttpUtility, TestSanitizeEmptyTokensFromHeaders) { // Validate that we fail the request if there are too many // nominated headers TEST(HttpUtility, TestTooManyNominatedHeaders) { - Http::TestHeaderMapImpl request_headers = { + Http::TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -944,7 +945,7 @@ TEST(HttpUtility, TestTooManyNominatedHeaders) { } TEST(HttpUtility, TestRejectNominatedXForwardedFor) { - Http::TestHeaderMapImpl request_headers = { + Http::TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -962,7 +963,7 @@ TEST(HttpUtility, TestRejectNominatedXForwardedFor) { } TEST(HttpUtility, TestRejectNominatedXForwardedHost) { - Http::TestHeaderMapImpl request_headers = { + Http::TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -980,7 +981,7 @@ TEST(HttpUtility, TestRejectNominatedXForwardedHost) { } TEST(HttpUtility, TestRejectNominatedXForwardedProto) { - Http::TestHeaderMapImpl request_headers = { + Http::TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -1006,7 +1007,7 @@ TEST(HttpUtility, TestRejectNominatedXForwardedProto) { } TEST(HttpUtility, TestRejectTrailersSubString) { - Http::TestHeaderMapImpl request_headers = { + Http::TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -1029,7 +1030,7 @@ TEST(HttpUtility, TestRejectTrailersSubString) { } TEST(HttpUtility, TestRejectTeHeaderTooLong) { - Http::TestHeaderMapImpl request_headers = { + Http::TestRequestHeaderMapImpl request_headers = { {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, diff --git a/test/common/router/config_impl_test.cc b/test/common/router/config_impl_test.cc index cbbe09b060..aac1322384 100644 --- a/test/common/router/config_impl_test.cc +++ b/test/common/router/config_impl_test.cc @@ -3508,7 +3508,7 @@ TEST_F(RouteMatcherTest, NoProtocolInHeadersWhenTlsIsRequired) { TestConfigImpl config(parseRouteConfigurationFromV2Yaml(yaml), factory_context_, true); // route may be called early in some edge cases and "x-forwarded-proto" will not be set. - Http::TestHeaderMapImpl headers{{":authority", "www.lyft.com"}, {":path", "/"}}; + Http::TestRequestHeaderMapImpl headers{{":authority", "www.lyft.com"}, {":path", "/"}}; EXPECT_EQ(nullptr, config.route(headers, 0)); } @@ -4183,7 +4183,7 @@ TEST_F(RouteMatcherTest, WeightedClusters) { EXPECT_EQ("meh", route_entry->typedMetadata().get(baz_factory.name())->name); EXPECT_EQ("hello", route->decorator()->getOperation()); - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; StreamInfo::MockStreamInfo stream_info; route_entry->finalizeResponseHeaders(response_headers, stream_info); EXPECT_EQ(response_headers, Http::TestHeaderMapImpl{}); diff --git a/test/common/router/retry_state_impl_test.cc b/test/common/router/retry_state_impl_test.cc index 785781981d..706521faf1 100644 --- a/test/common/router/retry_state_impl_test.cc +++ b/test/common/router/retry_state_impl_test.cc @@ -108,13 +108,13 @@ class RouterRetryStateImplTest : public testing::Test { }; TEST_F(RouterRetryStateImplTest, PolicyNoneRemoteReset) { - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; setup(request_headers); EXPECT_EQ(nullptr, state_); } TEST_F(RouterRetryStateImplTest, PolicyRefusedStream) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "refused-stream"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "refused-stream"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -128,14 +128,14 @@ TEST_F(RouterRetryStateImplTest, PolicyRefusedStream) { } TEST_F(RouterRetryStateImplTest, Policy5xxResetOverflow) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); EXPECT_EQ(RetryStatus::No, state_->shouldRetryReset(overflow_reset_, callback_)); } TEST_F(RouterRetryStateImplTest, Policy5xxRemoteReset) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -148,11 +148,11 @@ TEST_F(RouterRetryStateImplTest, Policy5xxRemoteReset) { } TEST_F(RouterRetryStateImplTest, Policy5xxRemote503) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "503"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "503"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); EXPECT_CALL(callback_ready_, ready()); @@ -163,30 +163,31 @@ TEST_F(RouterRetryStateImplTest, Policy5xxRemote503) { } TEST_F(RouterRetryStateImplTest, Policy5xxRemote503Overloaded) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "503"}, {"x-envoy-overloaded", "true"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "503"}, + {"x-envoy-overloaded", "true"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } TEST_F(RouterRetryStateImplTest, PolicyResourceExhaustedRemoteRateLimited) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "resource-exhausted"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "resource-exhausted"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"grpc-status", "8"}, {"x-envoy-ratelimited", "true"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } TEST_F(RouterRetryStateImplTest, PolicyGatewayErrorRemote502) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "gateway-error"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "gateway-error"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "502"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "502"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); EXPECT_CALL(callback_ready_, ready()); @@ -197,11 +198,11 @@ TEST_F(RouterRetryStateImplTest, PolicyGatewayErrorRemote502) { } TEST_F(RouterRetryStateImplTest, PolicyGatewayErrorRemote503) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "gateway-error"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "gateway-error"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "503"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "503"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); EXPECT_CALL(callback_ready_, ready()); @@ -212,11 +213,11 @@ TEST_F(RouterRetryStateImplTest, PolicyGatewayErrorRemote503) { } TEST_F(RouterRetryStateImplTest, PolicyGatewayErrorRemote504) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "gateway-error"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "gateway-error"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "504"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "504"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); EXPECT_CALL(callback_ready_, ready()); @@ -227,14 +228,14 @@ TEST_F(RouterRetryStateImplTest, PolicyGatewayErrorRemote504) { } TEST_F(RouterRetryStateImplTest, PolicyGatewayErrorResetOverflow) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "gateway-error"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "gateway-error"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); EXPECT_EQ(RetryStatus::No, state_->shouldRetryReset(overflow_reset_, callback_)); } TEST_F(RouterRetryStateImplTest, PolicyGatewayErrorRemoteReset) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "gateway-error"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "gateway-error"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -247,11 +248,11 @@ TEST_F(RouterRetryStateImplTest, PolicyGatewayErrorRemoteReset) { } TEST_F(RouterRetryStateImplTest, PolicyGrpcCancelled) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "cancelled"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "cancelled"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "1"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "1"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); EXPECT_CALL(callback_ready_, ready()); @@ -262,11 +263,11 @@ TEST_F(RouterRetryStateImplTest, PolicyGrpcCancelled) { } TEST_F(RouterRetryStateImplTest, PolicyGrpcDeadlineExceeded) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "deadline-exceeded"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "deadline-exceeded"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "4"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "4"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); EXPECT_CALL(callback_ready_, ready()); @@ -277,11 +278,11 @@ TEST_F(RouterRetryStateImplTest, PolicyGrpcDeadlineExceeded) { } TEST_F(RouterRetryStateImplTest, PolicyGrpcResourceExhausted) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "resource-exhausted"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "resource-exhausted"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "8"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "8"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); EXPECT_CALL(callback_ready_, ready()); @@ -292,11 +293,11 @@ TEST_F(RouterRetryStateImplTest, PolicyGrpcResourceExhausted) { } TEST_F(RouterRetryStateImplTest, PolicyGrpcUnavilable) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "unavailable"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "unavailable"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "14"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "14"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); EXPECT_CALL(callback_ready_, ready()); @@ -307,11 +308,11 @@ TEST_F(RouterRetryStateImplTest, PolicyGrpcUnavilable) { } TEST_F(RouterRetryStateImplTest, PolicyGrpcInternal) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "internal"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "internal"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "13"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "13"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); EXPECT_CALL(callback_ready_, ready()); @@ -323,10 +324,10 @@ TEST_F(RouterRetryStateImplTest, PolicyGrpcInternal) { TEST_F(RouterRetryStateImplTest, Policy5xxRemote200RemoteReset) { // Don't retry after reply start. - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryReset(remote_reset_, callback_)); @@ -337,21 +338,21 @@ TEST_F(RouterRetryStateImplTest, RuntimeGuard) { EXPECT_CALL(runtime_.snapshot_, featureEnabled("upstream.use_retry", 100)) .WillOnce(Return(false)); - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); EXPECT_EQ(RetryStatus::No, state_->shouldRetryReset(remote_reset_, callback_)); } TEST_F(RouterRetryStateImplTest, PolicyConnectFailureOtherReset) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); EXPECT_EQ(RetryStatus::No, state_->shouldRetryReset(remote_reset_, callback_)); } TEST_F(RouterRetryStateImplTest, PolicyConnectFailureResetConnectFailure) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -362,11 +363,11 @@ TEST_F(RouterRetryStateImplTest, PolicyConnectFailureResetConnectFailure) { } TEST_F(RouterRetryStateImplTest, PolicyRetriable4xxRetry) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-4xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-4xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "409"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "409"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); EXPECT_CALL(callback_ready_, ready()); @@ -374,16 +375,16 @@ TEST_F(RouterRetryStateImplTest, PolicyRetriable4xxRetry) { } TEST_F(RouterRetryStateImplTest, PolicyRetriable4xxNoRetry) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-4xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-4xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "400"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "400"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } TEST_F(RouterRetryStateImplTest, PolicyRetriable4xxReset) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-4xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-4xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -392,19 +393,19 @@ TEST_F(RouterRetryStateImplTest, PolicyRetriable4xxReset) { TEST_F(RouterRetryStateImplTest, RetriableStatusCodes) { policy_.retriable_status_codes_.push_back(409); - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-status-codes"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-status-codes"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{":status", "409"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "409"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } TEST_F(RouterRetryStateImplTest, RetriableStatusCodesUpstreamReset) { policy_.retriable_status_codes_.push_back(409); - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-status-codes"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-status-codes"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); EXPECT_EQ(RetryStatus::No, state_->shouldRetryReset(remote_reset_, callback_)); @@ -412,46 +413,47 @@ TEST_F(RouterRetryStateImplTest, RetriableStatusCodesUpstreamReset) { TEST_F(RouterRetryStateImplTest, RetriableStatusCodesHeader) { { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-status-codes"}, - {"x-envoy-retriable-status-codes", "200"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-status-codes"}, + {"x-envoy-retriable-status-codes", "200"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-status-codes"}, - {"x-envoy-retriable-status-codes", "418,200"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-status-codes"}, + {"x-envoy-retriable-status-codes", "418,200"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-status-codes"}, - {"x-envoy-retriable-status-codes", " 418 junk,200"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"x-envoy-retry-on", "retriable-status-codes"}, + {"x-envoy-retriable-status-codes", " 418 junk,200"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"x-envoy-retry-on", "retriable-status-codes"}, {"x-envoy-retriable-status-codes", " 418 junk,xxx200"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } } @@ -469,22 +471,24 @@ TEST_F(RouterRetryStateImplTest, RetriableHeadersPolicySetViaRequestHeader) { // No retries based on response headers: retry mode isn't enabled. { - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"x-upstream-pushback", "true"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"x-upstream-pushback", "true"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } // Retries based on response headers: retry mode enabled via request header. { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-headers"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "retriable-headers"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"x-upstream-pushback", "true"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"x-upstream-pushback", "true"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } } @@ -515,7 +519,7 @@ TEST_F(RouterRetryStateImplTest, RetriableHeadersPolicyViaRetryPolicyConfigurati policy_.retriable_headers_ = Http::HeaderUtility::buildHeaderMatcherVector(matchers); auto setup_request = [this]() { - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; setup(request_headers); EXPECT_TRUE(state_->enabled()); }; @@ -523,19 +527,21 @@ TEST_F(RouterRetryStateImplTest, RetriableHeadersPolicyViaRetryPolicyConfigurati // matcher1: header presence (any value). { setup_request(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } { setup_request(); expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"x-upstream-pushback", "true"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"x-upstream-pushback", "true"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { setup_request(); expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"x-upstream-pushback", "false"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"x-upstream-pushback", "false"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } @@ -543,56 +549,57 @@ TEST_F(RouterRetryStateImplTest, RetriableHeadersPolicyViaRetryPolicyConfigurati { setup_request(); expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"should-retry", "yes"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"should-retry", "yes"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { setup_request(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"should-retry", "no"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"should-retry", "no"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } // matcher3: prefix match. { setup_request(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"x-verdict", "retry-please"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"x-verdict", "retry-please"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { setup_request(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, - {"x-verdict", "dont-retry-please"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"x-verdict", "dont-retry-please"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } // matcher4: status code range (note half-open semantics: [start, end)). { setup_request(); - Http::TestHeaderMapImpl response_headers{{":status", "499"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "499"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } { setup_request(); - Http::TestHeaderMapImpl response_headers{{":status", "500"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "500"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { setup_request(); - Http::TestHeaderMapImpl response_headers{{":status", "503"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "503"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { setup_request(); - Http::TestHeaderMapImpl response_headers{{":status", "504"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "504"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { setup_request(); - Http::TestHeaderMapImpl response_headers{{":status", "505"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "505"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } } @@ -600,7 +607,7 @@ TEST_F(RouterRetryStateImplTest, RetriableHeadersPolicyViaRetryPolicyConfigurati // Test various combinations of retry headers set via request headers. TEST_F(RouterRetryStateImplTest, RetriableHeadersSetViaRequestHeader) { { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"x-envoy-retry-on", "retriable-headers"}, {"x-envoy-retriable-header-names", "X-Upstream-Pushback,FOOBAR"}}; setup(request_headers); @@ -608,11 +615,11 @@ TEST_F(RouterRetryStateImplTest, RetriableHeadersSetViaRequestHeader) { expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{"x-upstream-pushback", "yes"}}; + Http::TestResponseHeaderMapImpl response_headers{{"x-upstream-pushback", "yes"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"x-envoy-retry-on", "retriable-headers"}, {"x-envoy-retriable-header-names", "X-Upstream-Pushback, FOOBAR "}}; setup(request_headers); @@ -620,17 +627,17 @@ TEST_F(RouterRetryStateImplTest, RetriableHeadersSetViaRequestHeader) { expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{"foobar", "false"}}; + Http::TestResponseHeaderMapImpl response_headers{{"foobar", "false"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"x-envoy-retry-on", "retriable-headers"}, {"x-envoy-retriable-header-names", "X-Upstream-Pushback,,FOOBAR"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } } @@ -651,30 +658,30 @@ TEST_F(RouterRetryStateImplTest, RetriableHeadersMergedConfigAndRequestHeaders) // No retries according to config. { - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } // Request header supplements the config: as a result we retry on 200. { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"x-envoy-retriable-header-names", " :status, FOOBAR "}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } } TEST_F(RouterRetryStateImplTest, PolicyResetRemoteReset) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "reset"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "reset"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -699,51 +706,53 @@ TEST_F(RouterRetryStateImplTest, PolicyLimitedByRequestHeaders) { policy_.retriable_request_headers_ = Http::HeaderUtility::buildHeaderMatcherVector(matchers); { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_FALSE(state_->enabled()); } { - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {"x-envoy-retry-on", "retriable-4xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {"x-envoy-retry-on", "retriable-4xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "409"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "409"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, {"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, {"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "500"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "500"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } { - Http::TestHeaderMapImpl request_headers{{":method", "HEAD"}, {"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "HEAD"}, + {"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "500"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "500"}}; expectTimerCreateAndEnable(); EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } // Sanity check that we're only enabling retries for the configured retry-on. { - Http::TestHeaderMapImpl request_headers{{":method", "HEAD"}, - {"x-envoy-retry-on", "retriable-4xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "HEAD"}, + {"x-envoy-retry-on", "retriable-4xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "500"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "500"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); } { - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, {"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, + {"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_FALSE(state_->enabled()); } @@ -762,7 +771,7 @@ TEST_F(RouterRetryStateImplTest, RouteConfigNoRetriesAllowed) { TEST_F(RouterRetryStateImplTest, RouteConfigNoHeaderConfig) { policy_.num_retries_ = 1; policy_.retry_on_ = RetryPolicy::RETRY_ON_CONNECT_FAILURE; - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -775,7 +784,7 @@ TEST_F(RouterRetryStateImplTest, RouteConfigNoHeaderConfig) { TEST_F(RouterRetryStateImplTest, NoAvailableRetries) { cluster_.resetResourceManager(0, 0, 0, 0, 0); - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -786,9 +795,9 @@ TEST_F(RouterRetryStateImplTest, NoAvailableRetries) { TEST_F(RouterRetryStateImplTest, MaxRetriesHeader) { // The max retries header will take precedence over the policy policy_.num_retries_ = 4; - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}, - {"x-envoy-retry-grpc-on", "cancelled"}, - {"x-envoy-max-retries", "3"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}, + {"x-envoy-retry-grpc-on", "cancelled"}, + {"x-envoy-max-retries", "3"}}; setup(request_headers); EXPECT_FALSE(request_headers.has("x-envoy-retry-on")); EXPECT_FALSE(request_headers.has("x-envoy-retry-grpc-on")); @@ -821,7 +830,7 @@ TEST_F(RouterRetryStateImplTest, MaxRetriesHeader) { TEST_F(RouterRetryStateImplTest, Backoff) { policy_.num_retries_ = 3; policy_.retry_on_ = RetryPolicy::RETRY_ON_CONNECT_FAILURE; - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -844,7 +853,7 @@ TEST_F(RouterRetryStateImplTest, Backoff) { EXPECT_CALL(callback_ready_, ready()); retry_timer_->invokeCallback(); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(RetryStatus::No, state_->shouldRetryHeaders(response_headers, callback_)); EXPECT_EQ(3UL, cluster_.stats().upstream_rq_retry_.value()); @@ -858,7 +867,7 @@ TEST_F(RouterRetryStateImplTest, CustomBackOffInterval) { policy_.retry_on_ = RetryPolicy::RETRY_ON_CONNECT_FAILURE; policy_.base_interval_ = std::chrono::milliseconds(100); policy_.max_interval_ = std::chrono::milliseconds(1200); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -893,7 +902,7 @@ TEST_F(RouterRetryStateImplTest, CustomBackOffIntervalDefaultMax) { policy_.num_retries_ = 10; policy_.retry_on_ = RetryPolicy::RETRY_ON_CONNECT_FAILURE; policy_.base_interval_ = std::chrono::milliseconds(100); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -935,7 +944,7 @@ TEST_F(RouterRetryStateImplTest, HostSelectionAttempts) { TEST_F(RouterRetryStateImplTest, Cancel) { // Cover the case where we start a retry, and then we get destructed. This is how the router // uses the implementation in the cancel case. - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -944,9 +953,9 @@ TEST_F(RouterRetryStateImplTest, Cancel) { } TEST_F(RouterRetryStateImplTest, ZeroMaxRetriesHeader) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}, - {"x-envoy-retry-grpc-on", "cancelled"}, - {"x-envoy-max-retries", "0"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "connect-failure"}, + {"x-envoy-retry-grpc-on", "cancelled"}, + {"x-envoy-max-retries", "0"}}; setup(request_headers); EXPECT_FALSE(request_headers.has("x-envoy-retry-on")); EXPECT_FALSE(request_headers.has("x-envoy-retry-grpc-on")); @@ -960,8 +969,8 @@ TEST_F(RouterRetryStateImplTest, ZeroMaxRetriesHeader) { // Check that if there are 0 remaining retries available but we get // non-retriable headers, we return No rather than NoRetryLimitExceeded. TEST_F(RouterRetryStateImplTest, NoPreferredOverLimitExceeded) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}, - {"x-envoy-max-retries", "1"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}, + {"x-envoy-max-retries", "1"}}; setup(request_headers); Http::TestHeaderMapImpl bad_response_headers{{":status", "503"}}; @@ -979,13 +988,13 @@ TEST_F(RouterRetryStateImplTest, BudgetAvailableRetries) { 0 /* cx */, 0 /* rq_pending */, 0 /* rq */, 0 /* rq_retry */, 0 /* conn_pool */, 20.0 /* budget_percent */, 3 /* min_retry_concurrency */); - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{":status", "500"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "500"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } @@ -997,12 +1006,12 @@ TEST_F(RouterRetryStateImplTest, BudgetNoAvailableRetries) { 0 /* cx */, 0 /* rq_pending */, 20 /* rq */, 5 /* rq_retry */, 0 /* conn_pool */, 0 /* budget_percent */, 0 /* min_retry_concurrency */); - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); - Http::TestHeaderMapImpl response_headers{{":status", "500"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "500"}}; EXPECT_EQ(RetryStatus::NoOverflow, state_->shouldRetryHeaders(response_headers, callback_)); } @@ -1012,9 +1021,9 @@ TEST_F(RouterRetryStateImplTest, BudgetVerifyMinimumConcurrency) { 0 /* cx */, 0 /* rq_pending */, 0 /* rq */, 0 /* rq_retry */, 0 /* conn_pool */, 20.0 /* budget_percent */, 3 /* min_retry_concurrency */); - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}, - {"x-envoy-max-retries", "42"}}; - Http::TestHeaderMapImpl response_headers{{":status", "500"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}, + {"x-envoy-max-retries", "42"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "500"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -1065,7 +1074,7 @@ TEST_F(RouterRetryStateImplTest, BudgetRuntimeSetOnly) { EXPECT_CALL(cluster_.runtime_.snapshot_, getDouble("fake_clusterretry_budget.budget_percent", _)) .WillRepeatedly(Return(20.0)); - Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}}; setup(request_headers); EXPECT_TRUE(state_->enabled()); @@ -1073,7 +1082,7 @@ TEST_F(RouterRetryStateImplTest, BudgetRuntimeSetOnly) { incrOutstandingResource(TestResourceType::Retry, 2); expectTimerCreateAndEnable(); - Http::TestHeaderMapImpl response_headers{{":status", "500"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "500"}}; EXPECT_EQ(RetryStatus::Yes, state_->shouldRetryHeaders(response_headers, callback_)); } diff --git a/test/common/router/route_fuzz_test.cc b/test/common/router/route_fuzz_test.cc index 8a10c6f7aa..324a9c150e 100644 --- a/test/common/router/route_fuzz_test.cc +++ b/test/common/router/route_fuzz_test.cc @@ -86,7 +86,7 @@ DEFINE_PROTO_FUZZER(const test::common::router::RouteTestCase& input) { TestUtility::validate(input.config()); ConfigImpl config(cleanRouteConfig(input.config()), factory_context, ProtobufMessage::getNullValidationVisitor(), true); - Http::TestHeaderMapImpl headers = Fuzz::fromHeaders(input.headers()); + auto headers = Fuzz::fromHeaders(input.headers()); auto route = config.route(headers, stream_info, input.random_value()); if (route != nullptr && route->routeEntry() != nullptr) { route->routeEntry()->finalizeRequestHeaders(headers, stream_info, true); diff --git a/test/common/router/router_test.cc b/test/common/router/router_test.cc index 036c66470c..bb84738556 100644 --- a/test/common/router/router_test.cc +++ b/test/common/router/router_test.cc @@ -195,7 +195,7 @@ class RouterTestBase : public testing::Test { EXPECT_CALL(cm_.conn_pool_, newStream(_, _)).WillOnce(Return(&cancellable_)); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -277,7 +277,7 @@ class RouterTestBase : public testing::Test { NiceMock second_encoder_; NiceMock connection_; Http::ResponseDecoder* response_decoder_ = nullptr; - Http::TestHeaderMapImpl default_request_headers_{}; + Http::TestRequestHeaderMapImpl default_request_headers_; Http::ResponseHeaderMapPtr redirect_headers_{ new Http::TestResponseHeaderMapImpl{{":status", "302"}, {"location", "http://www.foo.com"}}}; NiceMock span_; @@ -311,7 +311,7 @@ TEST_F(RouterTest, UpdateServerNameFilterState) { StreamInfo::FilterState::StateType::Mutable); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -335,7 +335,7 @@ TEST_F(RouterTest, UpdateSubjectAltNamesFilterState) { EXPECT_CALL(cm_.conn_pool_, newStream(_, _)).WillOnce(Return(&cancellable_)); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -351,7 +351,7 @@ TEST_F(RouterTest, UpdateSubjectAltNamesFilterState) { TEST_F(RouterTest, RouteNotFound) { EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::NoRouteFound)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(callbacks_, route()).WillOnce(Return(nullptr)); @@ -364,7 +364,7 @@ TEST_F(RouterTest, RouteNotFound) { TEST_F(RouterTest, ClusterNotFound) { EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::NoRouteFound)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); ON_CALL(cm_, get(_)).WillByDefault(Return(nullptr)); router_.decodeHeaders(headers, true); @@ -385,7 +385,7 @@ TEST_F(RouterTest, PoolFailureWithPriority) { return nullptr; })); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "503"}, {"content-length", "91"}, {"content-type", "text/plain"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); @@ -396,7 +396,7 @@ TEST_F(RouterTest, PoolFailureWithPriority) { EXPECT_EQ(host_address_, host->address()); })); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -411,7 +411,7 @@ TEST_F(RouterTest, Http1Upstream) { EXPECT_CALL(cm_.conn_pool_, newStream(_, _)).WillOnce(Return(&cancellable_)); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(callbacks_.route_->route_entry_, finalizeRequestHeaders(_, _, true)); EXPECT_CALL(span_, injectContext(_)); @@ -435,7 +435,7 @@ TEST_F(RouterTestSuppressEnvoyHeaders, Http1Upstream) { EXPECT_CALL(cm_.conn_pool_, newStream(_, _)).WillOnce(Return(&cancellable_)); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(callbacks_.route_->route_entry_, finalizeRequestHeaders(_, _, false)); router_.decodeHeaders(headers, true); @@ -455,7 +455,7 @@ TEST_F(RouterTest, Http2Upstream) { EXPECT_CALL(cm_.conn_pool_, newStream(_, _)).WillOnce(Return(&cancellable_)); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(span_, injectContext(_)); router_.decodeHeaders(headers, true); @@ -481,7 +481,7 @@ TEST_F(RouterTest, HashPolicy) { EXPECT_CALL(cm_.conn_pool_, newStream(_, _)).WillOnce(Return(&cancellable_)); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -506,7 +506,7 @@ TEST_F(RouterTest, HashPolicyNoHash) { EXPECT_CALL(cm_.conn_pool_, newStream(_, _)).WillOnce(Return(&cancellable_)); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -559,7 +559,7 @@ TEST_F(RouterTest, AddCookie) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -609,7 +609,7 @@ TEST_F(RouterTest, AddCookieNoDuplicate) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -670,7 +670,7 @@ TEST_F(RouterTest, AddMultipleCookies) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -696,7 +696,7 @@ TEST_F(RouterTest, MetadataMatchCriteria) { EXPECT_CALL(cm_.conn_pool_, newStream(_, _)).WillOnce(Return(&cancellable_)); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -725,7 +725,7 @@ TEST_F(RouterTest, NoMetadataMatchCriteria) { EXPECT_CALL(cm_.conn_pool_, newStream(_, _)).WillOnce(Return(&cancellable_)); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -738,7 +738,7 @@ TEST_F(RouterTest, CancelBeforeBoundToPool) { EXPECT_CALL(cm_.conn_pool_, newStream(_, _)).WillOnce(Return(&cancellable_)); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -751,14 +751,14 @@ TEST_F(RouterTest, CancelBeforeBoundToPool) { TEST_F(RouterTest, NoHost) { EXPECT_CALL(cm_, httpConnPoolForCluster(_, _, _, _)).WillOnce(Return(nullptr)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "503"}, {"content-length", "19"}, {"content-type", "text/plain"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::NoHealthyUpstream)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); EXPECT_EQ(0U, cm_.thread_local_cluster_.cluster_.info_->stats_store_ @@ -771,16 +771,16 @@ TEST_F(RouterTest, NoHost) { TEST_F(RouterTest, MaintenanceMode) { EXPECT_CALL(*cm_.thread_local_cluster_.cluster_.info_, maintenanceMode()).WillOnce(Return(true)); - Http::TestHeaderMapImpl response_headers{{":status", "503"}, - {"content-length", "16"}, - {"content-type", "text/plain"}, - {"x-envoy-overloaded", "true"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "503"}, + {"content-length", "16"}, + {"content-type", "text/plain"}, + {"x-envoy-overloaded", "true"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::UpstreamOverflow)); EXPECT_CALL(span_, injectContext(_)).Times(0); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_ @@ -798,13 +798,13 @@ TEST_F(RouterTest, MaintenanceMode) { TEST_F(RouterTestSuppressEnvoyHeaders, MaintenanceMode) { EXPECT_CALL(*cm_.thread_local_cluster_.cluster_.info_, maintenanceMode()).WillOnce(Return(true)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "503"}, {"content-length", "16"}, {"content-type", "text/plain"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::UpstreamOverflow)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); } @@ -822,7 +822,7 @@ TEST_F(RouterTest, ResponseCodeDetailsSetByUpstream) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -849,7 +849,7 @@ TEST_F(RouterTest, EnvoyUpstreamServiceTime) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -890,7 +890,7 @@ void RouterTestBase::testAppendCluster(absl::optional clu })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -945,7 +945,7 @@ void RouterTestBase::testAppendUpstreamHost( })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -1006,12 +1006,12 @@ void RouterTestBase::testDoNotForward( StreamInfo::FilterState::StateType::ReadOnly, StreamInfo::FilterState::LifeSpan::FilterChain); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "204"}, {not_forwarded_header_name.value_or(Http::Headers::get().EnvoyNotForwarded).get(), "true"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -1040,14 +1040,15 @@ TEST_F(RouterTest, AllDebugConfig) { StreamInfo::FilterState::LifeSpan::FilterChain); cm_.conn_pool_.host_->hostname_ = "scooby.doo"; - Http::TestHeaderMapImpl response_headers{{":status", "204"}, - {"x-envoy-cluster", "fake_cluster"}, - {"x-envoy-upstream-hostname", "scooby.doo"}, - {"x-envoy-upstream-host-address", "10.0.0.5:9211"}, - {"x-envoy-not-forwarded", "true"}}; + Http::TestResponseHeaderMapImpl response_headers{ + {":status", "204"}, + {"x-envoy-cluster", "fake_cluster"}, + {"x-envoy-upstream-hostname", "scooby.doo"}, + {"x-envoy-upstream-host-address", "10.0.0.5:9211"}, + {"x-envoy-not-forwarded", "true"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -1070,7 +1071,7 @@ TEST_F(RouterTestSuppressEnvoyHeaders, EnvoyUpstreamServiceTime) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -1100,7 +1101,7 @@ TEST_F(RouterTest, NoRetriesOverflow) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -1156,7 +1157,7 @@ TEST_F(RouterTest, ResetDuringEncodeHeaders) { encoder.stream_.resetStream(Http::StreamResetReason::RemoteReset); })); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); // First connection is successful and reset happens later on. EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, @@ -1186,7 +1187,7 @@ TEST_F(RouterTest, UpstreamTimeout) { expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); Buffer::OwnedImpl data; @@ -1195,7 +1196,7 @@ TEST_F(RouterTest, UpstreamTimeout) { EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::UpstreamRequestTimeout)); EXPECT_CALL(encoder.stream_, resetStream(Http::StreamResetReason::LocalReset)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "504"}, {"content-length", "24"}, {"content-type", "text/plain"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); @@ -1227,8 +1228,8 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStat) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "400"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "200"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "400"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "200"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); Buffer::OwnedImpl data; @@ -1268,8 +1269,8 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatFailure) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "400"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "200"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "400"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "200"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); Buffer::OwnedImpl data; @@ -1307,7 +1308,7 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatOnlyGlobal) { })); expectPerTryTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "200"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "200"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); Buffer::OwnedImpl data; @@ -1346,9 +1347,9 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringRetries) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, - {"x-envoy-upstream-rq-timeout-ms", "400"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "100"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, + {"x-envoy-upstream-rq-timeout-ms", "400"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "100"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); Buffer::OwnedImpl data; @@ -1404,7 +1405,7 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringRetries) { EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::UpstreamRequestTimeout)); EXPECT_CALL(encoder2.stream_, resetStream(Http::StreamResetReason::LocalReset)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "504"}, {"content-length", "24"}, {"content-type", "text/plain"}}; test_time_.sleep(std::chrono::milliseconds(100)); EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); @@ -1437,9 +1438,9 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringGlobalTimeout) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, - {"x-envoy-upstream-rq-timeout-ms", "400"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "320"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, + {"x-envoy-upstream-rq-timeout-ms", "400"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "320"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); Buffer::OwnedImpl data; @@ -1496,7 +1497,7 @@ TEST_F(RouterTest, TimeoutBudgetHistogramStatDuringGlobalTimeout) { EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::UpstreamRequestTimeout)); EXPECT_CALL(encoder2.stream_, resetStream(Http::StreamResetReason::LocalReset)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "504"}, {"content-length", "24"}, {"content-type", "text/plain"}}; test_time_.sleep(std::chrono::milliseconds(240)); EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); @@ -1527,7 +1528,8 @@ TEST_F(RouterTest, GrpcOkTrailersOnly) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "20S"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -1552,7 +1554,8 @@ TEST_F(RouterTest, GrpcAlreadyExistsTrailersOnly) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "20S"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -1577,7 +1580,8 @@ TEST_F(RouterTest, GrpcOutlierDetectionUnavailableStatusCode) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "20S"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -1603,7 +1607,8 @@ TEST_F(RouterTest, GrpcInternalTrailersOnly) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "20S"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -1629,7 +1634,8 @@ TEST_F(RouterTest, GrpcDataEndStream) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "20S"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -1658,7 +1664,8 @@ TEST_F(RouterTest, GrpcReset) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "20S"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -1688,7 +1695,8 @@ TEST_F(RouterTest, GrpcOk) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "20S"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -1720,7 +1728,8 @@ TEST_F(RouterTest, GrpcInternal) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "20S"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "20S"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -1753,8 +1762,8 @@ TEST_F(RouterTest, UpstreamTimeoutWithAltResponse) { expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-alt-response", "204"}, - {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-alt-response", "204"}, + {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); Buffer::OwnedImpl data; @@ -1763,7 +1772,7 @@ TEST_F(RouterTest, UpstreamTimeoutWithAltResponse) { EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::UpstreamRequestTimeout)); EXPECT_CALL(encoder.stream_, resetStream(Http::StreamResetReason::LocalReset)); - Http::TestHeaderMapImpl response_headers{{":status", "204"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "204"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); EXPECT_CALL(*router_.retry_state_, shouldRetryReset(_, _)).Times(0); EXPECT_CALL( @@ -1795,8 +1804,8 @@ TEST_F(RouterTest, UpstreamPerTryTimeout) { EXPECT_EQ(host_address_, host->address()); })); - Http::TestHeaderMapImpl headers{{"x-envoy-internal", "true"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-internal", "true"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); @@ -1811,7 +1820,7 @@ TEST_F(RouterTest, UpstreamPerTryTimeout) { EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::UpstreamRequestTimeout)); EXPECT_CALL(encoder.stream_, resetStream(Http::StreamResetReason::LocalReset)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "504"}, {"content-length", "24"}, {"content-type", "text/plain"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); @@ -1842,8 +1851,8 @@ TEST_F(RouterTest, UpstreamPerTryTimeoutDelayedPoolReady) { return nullptr; })); - Http::TestHeaderMapImpl headers{{"x-envoy-internal", "true"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-internal", "true"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); @@ -1864,7 +1873,7 @@ TEST_F(RouterTest, UpstreamPerTryTimeoutDelayedPoolReady) { EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::UpstreamRequestTimeout)); EXPECT_CALL(encoder.stream_, resetStream(Http::StreamResetReason::LocalReset)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "504"}, {"content-length", "24"}, {"content-type", "text/plain"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); @@ -1903,8 +1912,8 @@ TEST_F(RouterTest, UpstreamPerTryTimeoutExcludesNewStream) { EXPECT_EQ(host_address_, host->address()); })); - Http::TestHeaderMapImpl headers{{"x-envoy-internal", "true"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-internal", "true"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); Buffer::OwnedImpl data; @@ -1922,7 +1931,7 @@ TEST_F(RouterTest, UpstreamPerTryTimeoutExcludesNewStream) { EXPECT_CALL(*response_timeout_, disableTimer()); EXPECT_CALL(callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::UpstreamRequestTimeout)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "504"}, {"content-length", "24"}, {"content-type", "text/plain"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); @@ -1959,7 +1968,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutFirstRequestSucceeds) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2035,7 +2044,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutResetsOnBadHeaders) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2113,7 +2122,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutThirdRequestSucceeds) { expectResponseTimerCreate(); expectPerTryTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2215,7 +2224,7 @@ TEST_F(RouterTest, RetryOnlyOnceForSameUpstreamRequest) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2282,7 +2291,7 @@ TEST_F(RouterTest, BadHeadersDroppedIfPreviousRetryScheduled) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2350,7 +2359,7 @@ TEST_F(RouterTest, RetryRequestNotComplete) { EXPECT_EQ(host_address_, host->address()); })); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); @@ -2385,7 +2394,7 @@ TEST_F(RouterTest, HedgedPerTryTimeoutGlobalTimeout) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2453,7 +2462,7 @@ TEST_F(RouterTest, HedgingRetriesExhaustedBadResponse) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2541,7 +2550,7 @@ TEST_F(RouterTest, HedgingRetriesProceedAfterReset) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2617,7 +2626,7 @@ TEST_F(RouterTest, HedgingRetryImmediatelyReset) { absl::optional(absl::nullopt))) .Times(1); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); @@ -2689,7 +2698,7 @@ TEST_F(RouterTest, RetryNoneHealthy) { EXPECT_EQ(host_address_, host->address()); })); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2699,7 +2708,7 @@ TEST_F(RouterTest, RetryNoneHealthy) { encoder1.stream_.resetStream(Http::StreamResetReason::LocalReset); EXPECT_CALL(cm_, httpConnPoolForCluster(_, _, _, _)).WillOnce(Return(nullptr)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "503"}, {"content-length", "19"}, {"content-type", "text/plain"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); @@ -2722,7 +2731,7 @@ TEST_F(RouterTest, RetryUpstreamReset) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); EXPECT_CALL(*router_.retry_state_, enabled()).WillOnce(Return(true)); @@ -2774,7 +2783,7 @@ TEST_F(RouterTest, NoRetryWithBodyLimit) { // Set a per route body limit which disallows any buffering. EXPECT_CALL(callbacks_.route_->route_entry_, retryShadowBufferLimit()).WillOnce(Return(0)); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); // Unlike RetryUpstreamReset above the data won't be buffered as the body exceeds the buffer limit @@ -2806,9 +2815,9 @@ TEST_F(RouterTest, RetryUpstreamPerTryTimeout) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, - {"x-envoy-internal", "true"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, + {"x-envoy-internal", "true"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2856,7 +2865,7 @@ TEST_F(RouterTest, RetryUpstreamConnectionFailure) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2904,8 +2913,8 @@ TEST_F(RouterTest, DontResetStartedResponseOnUpstreamPerTryTimeout) { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-internal", "true"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-internal", "true"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2939,7 +2948,7 @@ TEST_F(RouterTest, RetryUpstreamResetResponseStarted) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -2973,7 +2982,7 @@ TEST_F(RouterTest, RetryUpstreamReset100ContinueResponseStarted) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -3006,7 +3015,7 @@ TEST_F(RouterTest, RetryUpstream5xx) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -3054,7 +3063,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelay) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -3071,7 +3080,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelay) { setResponseFlag(StreamInfo::ResponseFlag::UpstreamRequestTimeout)); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResponseTime(_)).Times(0); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "504"}, {"content-length", "24"}, {"content-type", "text/plain"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); @@ -3092,7 +3101,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHost) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -3119,7 +3128,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHost) { setResponseFlag(StreamInfo::ResponseFlag::UpstreamRequestTimeout)); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResponseTime(_)).Times(0); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "504"}, {"content-length", "24"}, {"content-type", "text/plain"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); @@ -3141,9 +3150,9 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHostAltRespo })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, - {"x-envoy-internal", "true"}, - {"x-envoy-upstream-rq-timeout-alt-response", "204"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, + {"x-envoy-internal", "true"}, + {"x-envoy-upstream-rq-timeout-alt-response", "204"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -3170,7 +3179,7 @@ TEST_F(RouterTest, RetryTimeoutDuringRetryDelayWithUpstreamRequestNoHostAltRespo setResponseFlag(StreamInfo::ResponseFlag::UpstreamRequestTimeout)); EXPECT_CALL(cm_.conn_pool_.host_->outlier_detector_, putResponseTime(_)).Times(0); - Http::TestHeaderMapImpl response_headers{{":status", "204"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "204"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); response_timeout_->invokeCallback(); EXPECT_TRUE(verifyHostUpstreamStats(0, 1)); @@ -3189,7 +3198,7 @@ TEST_F(RouterTest, RetryUpstream5xxNotComplete) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); @@ -3198,7 +3207,7 @@ TEST_F(RouterTest, RetryUpstream5xxNotComplete) { EXPECT_CALL(callbacks_, addDecodedData(_, true)); EXPECT_EQ(Http::FilterDataStatus::StopIterationNoBuffer, router_.decodeData(*body_data, false)); - Http::TestHeaderMapImpl trailers{{"some", "trailer"}}; + Http::TestRequestTrailerMapImpl trailers{{"some", "trailer"}}; router_.decodeTrailers(trailers); // 5xx response. @@ -3264,10 +3273,10 @@ TEST_F(RouterTest, RetryUpstreamGrpcCancelled) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-grpc-on", "cancelled"}, - {"x-envoy-internal", "true"}, - {"content-type", "application/grpc"}, - {"grpc-timeout", "20S"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-grpc-on", "cancelled"}, + {"x-envoy-internal", "true"}, + {"content-type", "application/grpc"}, + {"grpc-timeout", "20S"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -3318,7 +3327,7 @@ TEST_F(RouterTest, RetryRespsectsMaxHostSelectionCount) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); @@ -3331,7 +3340,7 @@ TEST_F(RouterTest, RetryRespsectsMaxHostSelectionCount) { EXPECT_CALL(callbacks_, addDecodedData(_, true)); EXPECT_EQ(Http::FilterDataStatus::StopIterationNoBuffer, router_.decodeData(*body_data, false)); - Http::TestHeaderMapImpl trailers{{"some", "trailer"}}; + Http::TestRequestTrailerMapImpl trailers{{"some", "trailer"}}; router_.decodeTrailers(trailers); // 5xx response. @@ -3389,7 +3398,7 @@ TEST_F(RouterTest, RetryRespectsRetryHostPredicate) { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); @@ -3402,7 +3411,7 @@ TEST_F(RouterTest, RetryRespectsRetryHostPredicate) { EXPECT_CALL(callbacks_, addDecodedData(_, true)); EXPECT_EQ(Http::FilterDataStatus::StopIterationNoBuffer, router_.decodeData(*body_data, false)); - Http::TestHeaderMapImpl trailers{{"some", "trailer"}}; + Http::TestRequestTrailerMapImpl trailers{{"some", "trailer"}}; router_.decodeTrailers(trailers); // 5xx response. @@ -3605,7 +3614,7 @@ TEST_F(RouterTest, Shadow) { EXPECT_CALL(runtime_.snapshot_, featureEnabled("bar", 0, 43, 10000)).WillOnce(Return(true)); EXPECT_CALL(runtime_.snapshot_, featureEnabled("buzz", 0, 43, 10000)).WillOnce(Return(true)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); @@ -3613,22 +3622,22 @@ TEST_F(RouterTest, Shadow) { EXPECT_CALL(callbacks_, addDecodedData(_, true)); EXPECT_EQ(Http::FilterDataStatus::StopIterationNoBuffer, router_.decodeData(*body_data, false)); - Http::TestHeaderMapImpl trailers{{"some", "trailer"}}; + Http::TestRequestTrailerMapImpl trailers{{"some", "trailer"}}; EXPECT_CALL(callbacks_, decodingBuffer()) .Times(AtLeast(2)) .WillRepeatedly(Return(body_data.get())); EXPECT_CALL(*shadow_writer_, shadow_("foo", _, std::chrono::milliseconds(10))) - .WillOnce(Invoke( - [](const std::string&, Http::MessagePtr& request, std::chrono::milliseconds) -> void { - EXPECT_NE(nullptr, request->body()); - EXPECT_NE(nullptr, request->trailers()); - })); + .WillOnce(Invoke([](const std::string&, Http::RequestMessagePtr& request, + std::chrono::milliseconds) -> void { + EXPECT_NE(nullptr, request->body()); + EXPECT_NE(nullptr, request->trailers()); + })); EXPECT_CALL(*shadow_writer_, shadow_("fizz", _, std::chrono::milliseconds(10))) - .WillOnce(Invoke( - [](const std::string&, Http::MessagePtr& request, std::chrono::milliseconds) -> void { - EXPECT_NE(nullptr, request->body()); - EXPECT_NE(nullptr, request->trailers()); - })); + .WillOnce(Invoke([](const std::string&, Http::RequestMessagePtr& request, + std::chrono::milliseconds) -> void { + EXPECT_NE(nullptr, request->body()); + EXPECT_NE(nullptr, request->trailers()); + })); router_.decodeTrailers(trailers); Http::ResponseHeaderMapPtr response_headers( @@ -3654,8 +3663,8 @@ TEST_F(RouterTest, AltStatName) { return nullptr; })); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-alt-stat-name", "alt_stat"}, - {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-alt-stat-name", "alt_stat"}, + {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -3699,9 +3708,9 @@ TEST_F(RouterTest, Redirect) { absl::string_view route_name_view(route_name); EXPECT_CALL(callbacks_.stream_info_, setRouteName(route_name_view)); - Http::TestHeaderMapImpl response_headers{{":status", "301"}, {"location", "hello"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "301"}, {"location", "hello"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -3720,9 +3729,9 @@ TEST_F(RouterTest, RedirectFound) { absl::string_view route_name_view(route_name); EXPECT_CALL(callbacks_.stream_info_, setRouteName(route_name_view)); - Http::TestHeaderMapImpl response_headers{{":status", "302"}, {"location", "hello"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "302"}, {"location", "hello"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -3738,10 +3747,10 @@ TEST_F(RouterTest, DirectResponse) { absl::string_view route_name_view(route_name); EXPECT_CALL(callbacks_.stream_info_, setRouteName(route_name_view)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); EXPECT_CALL(span_, injectContext(_)).Times(0); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -3759,11 +3768,11 @@ TEST_F(RouterTest, DirectResponseWithBody) { absl::string_view route_name_view(route_name); EXPECT_CALL(callbacks_.stream_info_, setRouteName(route_name_view)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"content-length", "15"}, {"content-type", "text/plain"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); EXPECT_CALL(callbacks_, encodeData(_, true)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -3781,10 +3790,11 @@ TEST_F(RouterTest, DirectResponseWithLocation) { absl::string_view route_name_view(route_name); EXPECT_CALL(callbacks_.stream_info_, setRouteName(route_name_view)); - Http::TestHeaderMapImpl response_headers{{":status", "201"}, {"location", "http://host/"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "201"}, + {"location", "http://host/"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); EXPECT_CALL(span_, injectContext(_)).Times(0); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -3802,10 +3812,10 @@ TEST_F(RouterTest, DirectResponseWithoutLocation) { absl::string_view route_name_view(route_name); EXPECT_CALL(callbacks_.stream_info_, setRouteName(route_name_view)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); EXPECT_CALL(span_, injectContext(_)).Times(0); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); EXPECT_TRUE(verifyHostUpstreamStats(0, 0)); @@ -3831,7 +3841,7 @@ TEST_F(RouterTest, UpstreamSSLConnection) { return nullptr; })); - Http::TestHeaderMapImpl headers{}; + Http::TestRequestHeaderMapImpl headers{}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -3866,7 +3876,7 @@ TEST_F(RouterTest, UpstreamTimingSingleRequest) { EXPECT_FALSE(stream_info.firstUpstreamRxByteReceived().has_value()); EXPECT_FALSE(stream_info.lastUpstreamRxByteReceived().has_value()); - Http::TestHeaderMapImpl headers{}; + Http::TestRequestHeaderMapImpl headers{}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); @@ -3922,7 +3932,7 @@ TEST_F(RouterTest, UpstreamTimingRetry) { ON_CALL(callbacks_, streamInfo()).WillByDefault(ReturnRef(stream_info)); // Check that upstream timing is updated after the first request. - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); @@ -4008,7 +4018,7 @@ TEST_F(RouterTest, UpstreamTimingTimeout) { test_time_.sleep(std::chrono::milliseconds(10)); // Check that upstream timing is updated after the first request. - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "50"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "50"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); EXPECT_FALSE(stream_info.lastUpstreamRxByteReceived().has_value()); @@ -4055,7 +4065,7 @@ TEST(RouterFilterUtilityTest, FinalHedgingParamsHedgeOnPerTryTimeout) { EXPECT_FALSE(hedgingParams.hedge_on_per_try_timeout_); } { // route says false, header says true, expect true. - Http::TestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "true"}}; NiceMock route; route.hedge_policy_.hedge_on_per_try_timeout_ = false; EXPECT_CALL(route, hedgePolicy).WillRepeatedly(ReturnRef(route.hedge_policy_)); @@ -4063,7 +4073,7 @@ TEST(RouterFilterUtilityTest, FinalHedgingParamsHedgeOnPerTryTimeout) { EXPECT_TRUE(hedgingParams.hedge_on_per_try_timeout_); } { // route says false, header says false, expect false. - Http::TestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "false"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "false"}}; NiceMock route; route.hedge_policy_.hedge_on_per_try_timeout_ = false; EXPECT_CALL(route, hedgePolicy).WillRepeatedly(ReturnRef(route.hedge_policy_)); @@ -4071,7 +4081,7 @@ TEST(RouterFilterUtilityTest, FinalHedgingParamsHedgeOnPerTryTimeout) { EXPECT_FALSE(hedgingParams.hedge_on_per_try_timeout_); } { // route says true, header says false, expect false. - Http::TestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "false"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "false"}}; NiceMock route; route.hedge_policy_.hedge_on_per_try_timeout_ = true; EXPECT_CALL(route, hedgePolicy).WillRepeatedly(ReturnRef(route.hedge_policy_)); @@ -4079,7 +4089,7 @@ TEST(RouterFilterUtilityTest, FinalHedgingParamsHedgeOnPerTryTimeout) { EXPECT_FALSE(hedgingParams.hedge_on_per_try_timeout_); } { // route says true, header says true, expect true. - Http::TestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "true"}}; NiceMock route; route.hedge_policy_.hedge_on_per_try_timeout_ = true; EXPECT_CALL(route, hedgePolicy).WillRepeatedly(ReturnRef(route.hedge_policy_)); @@ -4087,7 +4097,7 @@ TEST(RouterFilterUtilityTest, FinalHedgingParamsHedgeOnPerTryTimeout) { EXPECT_TRUE(hedgingParams.hedge_on_per_try_timeout_); } { // route says true, header is invalid, expect true. - Http::TestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "bad"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "bad"}}; NiceMock route; route.hedge_policy_.hedge_on_per_try_timeout_ = true; EXPECT_CALL(route, hedgePolicy).WillRepeatedly(ReturnRef(route.hedge_policy_)); @@ -4095,7 +4105,7 @@ TEST(RouterFilterUtilityTest, FinalHedgingParamsHedgeOnPerTryTimeout) { EXPECT_TRUE(hedgingParams.hedge_on_per_try_timeout_); } { // route says false, header is invalid, expect false. - Http::TestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "bad"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-hedge-on-per-try-timeout", "bad"}}; NiceMock route; route.hedge_policy_.hedge_on_per_try_timeout_ = false; EXPECT_CALL(route, hedgePolicy).WillRepeatedly(ReturnRef(route.hedge_policy_)); @@ -4108,7 +4118,7 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { { NiceMock route; EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, false, false, false); EXPECT_EQ(std::chrono::milliseconds(10), timeout.global_timeout_); @@ -4117,7 +4127,7 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { { NiceMock route; EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, false, false, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4129,7 +4139,7 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { { NiceMock route; EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "bad"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "bad"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, false, false, false); EXPECT_EQ(std::chrono::milliseconds(10), timeout.global_timeout_); @@ -4141,8 +4151,8 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { { NiceMock route; EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "15"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "15"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, false, false, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4155,8 +4165,8 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { { NiceMock route; EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, false, false, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4169,8 +4179,8 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { { NiceMock route; EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, false, true, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4184,8 +4194,8 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; EXPECT_CALL(route, maxGrpcTimeout()) .WillRepeatedly(Return(absl::optional(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, true, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4199,7 +4209,7 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; route.retry_policy_.per_try_timeout_ = std::chrono::milliseconds(7); EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, false, false, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4213,8 +4223,8 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; route.retry_policy_.per_try_timeout_ = std::chrono::milliseconds(7); EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, false, false, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4228,7 +4238,7 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; EXPECT_CALL(route, maxGrpcTimeout()) .WillRepeatedly(Return(absl::optional(0))); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(0), timeout.global_timeout_); @@ -4239,7 +4249,7 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; EXPECT_CALL(route, maxGrpcTimeout()).WillRepeatedly(Return(absl::nullopt)); EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(10), timeout.global_timeout_); @@ -4250,8 +4260,8 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; EXPECT_CALL(route, maxGrpcTimeout()) .WillRepeatedly(Return(absl::optional(0))); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, - {"grpc-timeout", "1000m"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "1000m"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(1000), timeout.global_timeout_); @@ -4262,8 +4272,8 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; EXPECT_CALL(route, maxGrpcTimeout()) .WillRepeatedly(Return(absl::optional(999))); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, - {"grpc-timeout", "1000m"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "1000m"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(999), timeout.global_timeout_); @@ -4274,7 +4284,8 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; EXPECT_CALL(route, maxGrpcTimeout()) .WillRepeatedly(Return(absl::optional(999))); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "0m"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "0m"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(999), timeout.global_timeout_); @@ -4287,7 +4298,8 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { .WillRepeatedly(Return(absl::optional(999))); EXPECT_CALL(route, grpcTimeoutOffset()) .WillRepeatedly(Return(absl::optional(10))); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "100m"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "100m"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(90), timeout.global_timeout_); @@ -4299,7 +4311,8 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { .WillRepeatedly(Return(absl::optional(999))); EXPECT_CALL(route, grpcTimeoutOffset()) .WillRepeatedly(Return(absl::optional(10))); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, {"grpc-timeout", "1m"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "1m"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(1), timeout.global_timeout_); @@ -4309,9 +4322,9 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; EXPECT_CALL(route, maxGrpcTimeout()) .WillRepeatedly(Return(absl::optional(0))); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, - {"grpc-timeout", "1000m"}, - {"x-envoy-upstream-rq-timeout-ms", "15"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "1000m"}, + {"x-envoy-upstream-rq-timeout-ms", "15"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4324,9 +4337,9 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; EXPECT_CALL(route, maxGrpcTimeout()) .WillRepeatedly(Return(absl::optional(0))); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, - {"grpc-timeout", "1000m"}, - {"x-envoy-upstream-rq-timeout-ms", "bad"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "1000m"}, + {"x-envoy-upstream-rq-timeout-ms", "bad"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(1000), timeout.global_timeout_); @@ -4339,10 +4352,10 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; EXPECT_CALL(route, maxGrpcTimeout()) .WillRepeatedly(Return(absl::optional(0))); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, - {"grpc-timeout", "1000m"}, - {"x-envoy-upstream-rq-timeout-ms", "15"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "15"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "1000m"}, + {"x-envoy-upstream-rq-timeout-ms", "15"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "15"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4356,10 +4369,10 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { NiceMock route; EXPECT_CALL(route, maxGrpcTimeout()) .WillRepeatedly(Return(absl::optional(0))); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, - {"grpc-timeout", "1000m"}, - {"x-envoy-upstream-rq-timeout-ms", "15"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "1000m"}, + {"x-envoy-upstream-rq-timeout-ms", "15"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4374,9 +4387,9 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { EXPECT_CALL(route, maxGrpcTimeout()) .WillRepeatedly(Return(absl::optional(0))); route.retry_policy_.per_try_timeout_ = std::chrono::milliseconds(7); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, - {"grpc-timeout", "1000m"}, - {"x-envoy-upstream-rq-timeout-ms", "15"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "1000m"}, + {"x-envoy-upstream-rq-timeout-ms", "15"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4391,10 +4404,10 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { EXPECT_CALL(route, maxGrpcTimeout()) .WillRepeatedly(Return(absl::optional(0))); route.retry_policy_.per_try_timeout_ = std::chrono::milliseconds(7); - Http::TestHeaderMapImpl headers{{"content-type", "application/grpc"}, - {"grpc-timeout", "1000m"}, - {"x-envoy-upstream-rq-timeout-ms", "15"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"content-type", "application/grpc"}, + {"grpc-timeout", "1000m"}, + {"x-envoy-upstream-rq-timeout-ms", "15"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, true, false, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4407,7 +4420,7 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { { NiceMock route; EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-expected-rq-timeout-ms", "8"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-expected-rq-timeout-ms", "8"}}; // Make ingress envoy respect `x-envoy-expected-rq-timeout-ms` header. bool respect_expected_rq_timeout = true; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout( @@ -4420,8 +4433,8 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { { NiceMock route; EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-expected-rq-timeout-ms", "8"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "4"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-expected-rq-timeout-ms", "8"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "4"}}; // Make ingress envoy respect `x-envoy-expected-rq-timeout-ms` header. bool respect_expected_rq_timeout = true; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout( @@ -4434,7 +4447,7 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { { NiceMock route; EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "8"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "8"}}; // Test that ingress envoy populates `x-envoy-expected-rq-timeout-ms` header if it has not been // set by egress envoy. bool respect_expected_rq_timeout = true; @@ -4450,7 +4463,7 @@ TEST(RouterFilterUtilityTest, FinalTimeout) { { NiceMock route; EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "8"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "8"}}; // Make envoy override `x-envoy-expected-rq-timeout-ms` header. // Test that ingress envoy sets `x-envoy-expected-rq-timeout-ms` header. bool respect_expected_rq_timeout = false; @@ -4469,7 +4482,7 @@ TEST(RouterFilterUtilityTest, FinalTimeoutSupressEnvoyHeaders) { { NiceMock route; EXPECT_CALL(route, timeout()).WillOnce(Return(std::chrono::milliseconds(10))); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-rq-timeout-ms", "15"}}; FilterUtility::TimeoutData timeout = FilterUtility::finalTimeout(route, headers, true, false, false, false); EXPECT_EQ(std::chrono::milliseconds(15), timeout.global_timeout_); @@ -4480,12 +4493,12 @@ TEST(RouterFilterUtilityTest, FinalTimeoutSupressEnvoyHeaders) { TEST(RouterFilterUtilityTest, SetUpstreamScheme) { { - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; FilterUtility::setUpstreamScheme(headers, false); EXPECT_EQ("http", headers.get_(":scheme")); } { - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; FilterUtility::setUpstreamScheme(headers, true); EXPECT_EQ("https", headers.get_(":scheme")); } @@ -4546,8 +4559,8 @@ TEST_F(RouterTest, CanaryStatusTrue) { return nullptr; })); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-alt-stat-name", "alt_stat"}, - {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-alt-stat-name", "alt_stat"}, + {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -4580,8 +4593,8 @@ TEST_F(RouterTest, CanaryStatusFalse) { return nullptr; })); - Http::TestHeaderMapImpl headers{{"x-envoy-upstream-alt-stat-name", "alt_stat"}, - {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-alt-stat-name", "alt_stat"}, + {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, true); @@ -4601,12 +4614,12 @@ TEST_F(RouterTest, AutoHostRewriteEnabled) { NiceMock encoder; std::string req_host{"foo.bar.com"}; - Http::TestHeaderMapImpl incoming_headers; + Http::TestRequestHeaderMapImpl incoming_headers; HttpTestUtility::addDefaultHeaders(incoming_headers); incoming_headers.setHost(req_host); cm_.conn_pool_.host_->hostname_ = "scooby.doo"; - Http::TestHeaderMapImpl outgoing_headers; + Http::TestRequestHeaderMapImpl outgoing_headers; HttpTestUtility::addDefaultHeaders(outgoing_headers); outgoing_headers.setHost(cm_.conn_pool_.host_->hostname_); @@ -4639,7 +4652,7 @@ TEST_F(RouterTest, AutoHostRewriteDisabled) { NiceMock encoder; std::string req_host{"foo.bar.com"}; - Http::TestHeaderMapImpl incoming_headers; + Http::TestRequestHeaderMapImpl incoming_headers; HttpTestUtility::addDefaultHeaders(incoming_headers); incoming_headers.setHost(req_host); @@ -4712,7 +4725,7 @@ TEST_F(RouterTest, ApplicationProtocols) { expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(span_, injectContext(_)); router_.decodeHeaders(headers, true); @@ -4757,7 +4770,7 @@ class WatermarkTest : public RouterTest { NiceMock stream_; Http::StreamCallbacks* stream_callbacks_; Http::ResponseDecoder* response_decoder_ = nullptr; - Http::TestHeaderMapImpl headers_; + Http::TestRequestHeaderMapImpl headers_; Http::ConnectionPool::Callbacks* pool_callbacks_{nullptr}; }; @@ -4862,7 +4875,7 @@ TEST_F(WatermarkTest, RetryRequestNotComplete) { EXPECT_EQ(host_address_, host->address()); })); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); router_.decodeHeaders(headers, false); Buffer::OwnedImpl data("1234567890123"); @@ -4904,7 +4917,7 @@ TEST_F(RouterTestChildSpan, BasicFlow) { return nullptr; })); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router fake_cluster egress", _)) .WillOnce(Return(child_span)); @@ -4945,7 +4958,7 @@ TEST_F(RouterTestChildSpan, ResetFlow) { return nullptr; })); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router fake_cluster egress", _)) .WillOnce(Return(child_span)); @@ -4990,7 +5003,7 @@ TEST_F(RouterTestChildSpan, CancelFlow) { return nullptr; })); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router fake_cluster egress", _)) .WillOnce(Return(child_span)); @@ -5032,7 +5045,7 @@ TEST_F(RouterTestChildSpan, ResetRetryFlow) { expectResponseTimerCreate(); // Upstream responds back to envoy simulating an upstream reset. - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}}; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router fake_cluster egress", _)) .WillOnce(Return(child_span_1)); @@ -5115,7 +5128,7 @@ INSTANTIATE_TEST_SUITE_P(StrictHeaderCheck, RouterTestStrictCheckOneHeader, // This test decodes a set of headers with invalid values and asserts that the // strict header check only fails for the single header specified by the test param TEST_P(RouterTestStrictCheckOneHeader, SingleInvalidHeader) { - Http::TestHeaderMapImpl req_headers{ + Http::TestRequestHeaderMapImpl req_headers{ {"X-envoy-Upstream-rq-timeout-ms", "10.0"}, {"x-envoy-upstream-rq-per-try-timeout-ms", "1.0"}, {"x-envoy-max-retries", "2.0"}, @@ -5163,7 +5176,7 @@ INSTANTIATE_TEST_SUITE_P(StrictHeaderCheck, RouterTestStrictCheckSomeHeaders, // set to which strict-checks apply. Assert that these headers are not rejected. TEST_P(RouterTestStrictCheckSomeHeaders, IgnoreOmittedHeaders) { // Invalid, but excluded from the configured set of headers to strictly-check - Http::TestHeaderMapImpl headers{ + Http::TestRequestHeaderMapImpl headers{ {"x-envoy-upstream-rq-per-try-timeout-ms", "1.0"}, {"x-envoy-upstream-rq-timeout-ms", "5000"}, {"x-envoy-retry-on", "5xx,cancelled"}, @@ -5197,7 +5210,7 @@ INSTANTIATE_TEST_SUITE_P(StrictHeaderCheck, RouterTestStrictCheckAllHeaders, TEST_P(RouterTestStrictCheckAllHeaders, MultipleInvalidHeaders) { const auto& header1 = std::get<0>(GetParam()); const auto& header2 = std::get<1>(GetParam()); - Http::TestHeaderMapImpl headers{{header1, "invalid"}, {header2, "invalid"}}; + Http::TestRequestHeaderMapImpl headers{{header1, "invalid"}, {header2, "invalid"}}; HttpTestUtility::addDefaultHeaders(headers); EXPECT_CALL(callbacks_.stream_info_, @@ -5219,7 +5232,7 @@ TEST_P(RouterTestStrictCheckAllHeaders, MultipleInvalidHeaders) { // Request has headers with invalid values, but headers are *excluded* from the // set to which strict-checks apply. Assert that these headers are not rejected. TEST(RouterFilterUtilityTest, StrictCheckValidHeaders) { - Http::TestHeaderMapImpl headers{ + Http::TestRequestHeaderMapImpl headers{ {"X-envoy-Upstream-rq-timeout-ms", "100"}, {"x-envoy-upstream-rq-per-try-timeout-ms", "100"}, {"x-envoy-max-retries", "2"}, diff --git a/test/common/router/router_upstream_log_test.cc b/test/common/router/router_upstream_log_test.cc index 678b897c13..0bc1afbba3 100644 --- a/test/common/router/router_upstream_log_test.cc +++ b/test/common/router/router_upstream_log_test.cc @@ -141,7 +141,7 @@ class RouterUpstreamLogTest : public testing::Test { })); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers(request_headers_init); + Http::TestRequestHeaderMapImpl headers(request_headers_init); HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); @@ -180,9 +180,9 @@ class RouterUpstreamLogTest : public testing::Test { expectPerTryTimerCreate(); expectResponseTimerCreate(); - Http::TestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, - {"x-envoy-internal", "true"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; + Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, + {"x-envoy-internal", "true"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "5"}}; HttpTestUtility::addDefaultHeaders(headers); router_->decodeHeaders(headers, true); diff --git a/test/common/router/shadow_writer_impl_test.cc b/test/common/router/shadow_writer_impl_test.cc index 29d4092acb..afe0e48268 100644 --- a/test/common/router/shadow_writer_impl_test.cc +++ b/test/common/router/shadow_writer_impl_test.cc @@ -23,7 +23,7 @@ namespace { class ShadowWriterImplTest : public testing::Test { public: void expectShadowWriter(absl::string_view host, absl::string_view shadowed_host) { - Http::MessagePtr message(new Http::RequestMessageImpl()); + Http::RequestMessagePtr message(new Http::RequestMessageImpl()); message->headers().setHost(host); EXPECT_CALL(cm_, get(Eq("foo"))); EXPECT_CALL(cm_, httpAsyncClientForCluster("foo")).WillOnce(ReturnRef(cm_.async_client_)); @@ -31,9 +31,9 @@ class ShadowWriterImplTest : public testing::Test { EXPECT_CALL( cm_.async_client_, send_(_, _, Http::AsyncClient::RequestOptions().setTimeout(std::chrono::milliseconds(5)))) - .WillOnce( - Invoke([&](Http::MessagePtr& inner_message, Http::AsyncClient::Callbacks& callbacks, - const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { + .WillOnce(Invoke( + [&](Http::RequestMessagePtr& inner_message, Http::AsyncClient::Callbacks& callbacks, + const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { EXPECT_EQ(message, inner_message); EXPECT_EQ(shadowed_host, message->headers().Host()->value().getStringView()); callback_ = &callbacks; @@ -51,7 +51,7 @@ TEST_F(ShadowWriterImplTest, Success) { InSequence s; expectShadowWriter("cluster1", "cluster1-shadow"); - Http::MessagePtr response(new Http::RequestMessageImpl()); + Http::ResponseMessagePtr response(new Http::ResponseMessageImpl()); callback_->onSuccess(std::move(response)); } @@ -65,7 +65,7 @@ TEST_F(ShadowWriterImplTest, Failure) { TEST_F(ShadowWriterImplTest, NoCluster) { InSequence s; - Http::MessagePtr message(new Http::RequestMessageImpl()); + Http::RequestMessagePtr message(new Http::RequestMessageImpl()); EXPECT_CALL(cm_, get(Eq("foo"))).WillOnce(Return(nullptr)); EXPECT_CALL(cm_, httpAsyncClientForCluster("foo")).Times(0); writer_.shadow("foo", std::move(message), std::chrono::milliseconds(5)); diff --git a/test/common/tracing/http_tracer_impl_test.cc b/test/common/tracing/http_tracer_impl_test.cc index 8c3df62178..951ea5ab07 100644 --- a/test/common/tracing/http_tracer_impl_test.cc +++ b/test/common/tracing/http_tracer_impl_test.cc @@ -151,12 +151,12 @@ TEST_F(HttpConnManFinalizerImplTest, OriginalAndLongPath) { const auto remote_address = Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; - Http::TestHeaderMapImpl request_headers{{"x-request-id", "id"}, - {"x-envoy-original-path", path}, - {":method", "GET"}, - {"x-forwarded-proto", "http"}}; - Http::TestHeaderMapImpl response_headers; - Http::TestHeaderMapImpl response_trailers; + Http::TestRequestHeaderMapImpl request_headers{{"x-request-id", "id"}, + {"x-envoy-original-path", path}, + {":method", "GET"}, + {"x-forwarded-proto", "http"}}; + Http::TestResponseHeaderMapImpl response_headers; + Http::TestResponseTrailerMapImpl response_trailers; absl::optional protocol = Http::Protocol::Http2; EXPECT_CALL(stream_info, bytesReceived()).WillOnce(Return(10)); @@ -185,10 +185,10 @@ TEST_F(HttpConnManFinalizerImplTest, NoGeneratedId) { const auto remote_address = Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"x-envoy-original-path", path}, {":method", "GET"}, {"x-forwarded-proto", "http"}}; - Http::TestHeaderMapImpl response_headers; - Http::TestHeaderMapImpl response_trailers; + Http::TestResponseHeaderMapImpl response_headers; + Http::TestResponseTrailerMapImpl response_trailers; absl::optional protocol = Http::Protocol::Http2; EXPECT_CALL(stream_info, bytesReceived()).WillOnce(Return(10)); @@ -306,12 +306,12 @@ TEST_F(HttpConnManFinalizerImplTest, UpstreamClusterTagSet) { } TEST_F(HttpConnManFinalizerImplTest, SpanOptionalHeaders) { - Http::TestHeaderMapImpl request_headers{{"x-request-id", "id"}, - {":path", "/test"}, - {":method", "GET"}, - {"x-forwarded-proto", "https"}}; - Http::TestHeaderMapImpl response_headers; - Http::TestHeaderMapImpl response_trailers; + Http::TestRequestHeaderMapImpl request_headers{{"x-request-id", "id"}, + {":path", "/test"}, + {":method", "GET"}, + {"x-forwarded-proto", "https"}}; + Http::TestResponseHeaderMapImpl response_headers; + Http::TestResponseTrailerMapImpl response_trailers; const std::string expected_ip = "10.0.0.100"; const auto remote_address = Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; @@ -374,11 +374,11 @@ TEST_F(HttpConnManFinalizerImplTest, UnixDomainSocketPeerAddressTag) { TEST_F(HttpConnManFinalizerImplTest, SpanCustomTags) { TestEnvironment::setEnvVar("E_CC", "c", 1); - Http::TestHeaderMapImpl request_headers{{"x-request-id", "id"}, - {":path", "/test"}, - {":method", "GET"}, - {"x-forwarded-proto", "https"}, - {"x-bb", "b"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-request-id", "id"}, + {":path", "/test"}, + {":method", "GET"}, + {"x-forwarded-proto", "https"}, + {"x-bb", "b"}}; ProtobufWkt::Struct fake_struct; std::string yaml = R"EOF( @@ -491,12 +491,12 @@ tag: dd-10, } TEST_F(HttpConnManFinalizerImplTest, SpanPopulatedFailureResponse) { - Http::TestHeaderMapImpl request_headers{{"x-request-id", "id"}, - {":path", "/test"}, - {":method", "GET"}, - {"x-forwarded-proto", "http"}}; - Http::TestHeaderMapImpl response_headers; - Http::TestHeaderMapImpl response_trailers; + Http::TestRequestHeaderMapImpl request_headers{{"x-request-id", "id"}, + {":path", "/test"}, + {":method", "GET"}, + {"x-forwarded-proto", "http"}}; + Http::TestResponseHeaderMapImpl response_headers; + Http::TestResponseTrailerMapImpl response_trailers; const std::string expected_ip = "10.0.0.100"; const auto remote_address = Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; @@ -551,17 +551,17 @@ TEST_F(HttpConnManFinalizerImplTest, GrpcOkStatus) { const auto remote_address = Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, - {":scheme", "http"}, - {":path", "/pb.Foo/Bar"}, - {":authority", "example.com:80"}, - {"content-type", "application/grpc"}, - {"x-forwarded-proto", "http"}, - {"te", "trailers"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, + {":scheme", "http"}, + {":path", "/pb.Foo/Bar"}, + {":authority", "example.com:80"}, + {"content-type", "application/grpc"}, + {"x-forwarded-proto", "http"}, + {"te", "trailers"}}; - Http::TestHeaderMapImpl response_headers{{":status", "200"}, - {"content-type", "application/grpc"}}; - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}, {"grpc-message", ""}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"content-type", "application/grpc"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "0"}, {"grpc-message", ""}}; absl::optional protocol = Http::Protocol::Http2; absl::optional response_code(200); @@ -601,19 +601,19 @@ TEST_F(HttpConnManFinalizerImplTest, GrpcErrorTag) { const auto remote_address = Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, - {":scheme", "http"}, - {":path", "/pb.Foo/Bar"}, - {":authority", "example.com:80"}, - {"content-type", "application/grpc"}, - {"grpc-timeout", "10s"}, - {"x-forwarded-proto", "http"}, - {"te", "trailers"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, + {":scheme", "http"}, + {":path", "/pb.Foo/Bar"}, + {":authority", "example.com:80"}, + {"content-type", "application/grpc"}, + {"grpc-timeout", "10s"}, + {"x-forwarded-proto", "http"}, + {"te", "trailers"}}; - Http::TestHeaderMapImpl response_headers{{":status", "200"}, - {"content-type", "application/grpc"}}; - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "7"}, - {"grpc-message", "permission denied"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"content-type", "application/grpc"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "7"}, + {"grpc-message", "permission denied"}}; absl::optional protocol = Http::Protocol::Http2; absl::optional response_code(200); @@ -647,19 +647,19 @@ TEST_F(HttpConnManFinalizerImplTest, GrpcTrailersOnly) { const auto remote_address = Network::Address::InstanceConstSharedPtr{new Network::Address::Ipv4Instance(expected_ip, 0)}; - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, - {":scheme", "http"}, - {":path", "/pb.Foo/Bar"}, - {":authority", "example.com:80"}, - {"content-type", "application/grpc"}, - {"x-forwarded-proto", "http"}, - {"te", "trailers"}}; - - Http::TestHeaderMapImpl response_headers{{":status", "200"}, - {"content-type", "application/grpc"}, - {"grpc-status", "7"}, - {"grpc-message", "permission denied"}}; - Http::TestHeaderMapImpl response_trailers; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, + {":scheme", "http"}, + {":path", "/pb.Foo/Bar"}, + {":authority", "example.com:80"}, + {"content-type", "application/grpc"}, + {"x-forwarded-proto", "http"}, + {"te", "trailers"}}; + + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"content-type", "application/grpc"}, + {"grpc-status", "7"}, + {"grpc-message", "permission denied"}}; + Http::TestResponseTrailerMapImpl response_trailers; absl::optional protocol = Http::Protocol::Http2; absl::optional response_code(200); @@ -695,9 +695,9 @@ TEST(HttpNullTracerTest, BasicFunctionality) { HttpNullTracer null_tracer; MockConfig config; StreamInfo::MockStreamInfo stream_info; - Http::TestHeaderMapImpl request_headers; - Http::TestHeaderMapImpl response_headers; - Http::TestHeaderMapImpl response_trailers; + Http::TestRequestHeaderMapImpl request_headers; + Http::TestResponseHeaderMapImpl response_headers; + Http::TestResponseTrailerMapImpl response_trailers; SpanPtr span_ptr = null_tracer.startSpan(config, request_headers, stream_info, {Reason::Sampling, true}); @@ -718,10 +718,10 @@ class HttpTracerImplTest : public testing::Test { tracer_ = std::make_unique(std::move(driver_ptr), local_info_); } - Http::TestHeaderMapImpl request_headers_{ + Http::TestRequestHeaderMapImpl request_headers_{ {":path", "/"}, {":method", "GET"}, {"x-request-id", "foo"}, {":authority", "test"}}; - Http::TestHeaderMapImpl response_headers; - Http::TestHeaderMapImpl response_trailers; + Http::TestResponseHeaderMapImpl response_headers; + Http::TestResponseTrailerMapImpl response_trailers; StreamInfo::MockStreamInfo stream_info_; NiceMock local_info_; MockConfig config_; diff --git a/test/extensions/access_loggers/grpc/http_grpc_access_log_impl_test.cc b/test/extensions/access_loggers/grpc/http_grpc_access_log_impl_test.cc index 31d506ae55..13e0b1641c 100644 --- a/test/extensions/access_loggers/grpc/http_grpc_access_log_impl_test.cc +++ b/test/extensions/access_loggers/grpc/http_grpc_access_log_impl_test.cc @@ -87,7 +87,7 @@ class HttpGrpcAccessLogTest : public testing::Test { stream_info.host_ = nullptr; stream_info.start_time_ = SystemTime(1h); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", request_method}, }; @@ -241,7 +241,7 @@ response: {} ON_CALL(stream_info, hasResponseFlag(StreamInfo::ResponseFlag::FaultInjected)) .WillByDefault(Return(true)); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":scheme", "scheme_value"}, {":authority", "authority_value"}, {":path", "path_value"}, @@ -252,7 +252,7 @@ response: {} {"x-request-id", "x-request-id_value"}, {"x-envoy-original-path", "x-envoy-original-path_value"}, }; - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; expectLog(R"EOF( common_properties: @@ -325,7 +325,7 @@ protocol_version: HTTP10 stream_info.start_time_ = SystemTime(1h); stream_info.upstream_transport_failure_reason_ = "TLS error"; - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "WHACKADOO"}, }; @@ -377,7 +377,7 @@ response: {} stream_info.setDownstreamSslConnection(connection_info); stream_info.requested_server_name_ = "sni"; - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "WHACKADOO"}, }; @@ -437,7 +437,7 @@ response: {} stream_info.setDownstreamSslConnection(connection_info); stream_info.requested_server_name_ = "sni"; - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "WHACKADOO"}, }; @@ -487,7 +487,7 @@ response: {} stream_info.setDownstreamSslConnection(connection_info); stream_info.requested_server_name_ = "sni"; - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "WHACKADOO"}, }; @@ -537,7 +537,7 @@ response: {} stream_info.setDownstreamSslConnection(connection_info); stream_info.requested_server_name_ = "sni"; - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "WHACKADOO"}, }; @@ -587,7 +587,7 @@ response: {} stream_info.setDownstreamSslConnection(connection_info); stream_info.requested_server_name_ = "sni"; - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "WHACKADOO"}, }; @@ -646,7 +646,7 @@ TEST_F(HttpGrpcAccessLogTest, MarshallingAdditionalHeaders) { stream_info.host_ = nullptr; stream_info.start_time_ = SystemTime(1h); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":scheme", "scheme_value"}, {":authority", "authority_value"}, {":path", "path_value"}, @@ -655,14 +655,14 @@ TEST_F(HttpGrpcAccessLogTest, MarshallingAdditionalHeaders) { {"x-custom-request", "custom_value"}, {"x-custom-empty", ""}, }; - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"x-envoy-immediate-health-check-fail", "true"}, // test inline header not otherwise logged {"x-custom-response", "custom_value"}, {"x-custom-empty", ""}, }; - Http::TestHeaderMapImpl response_trailers{ + Http::TestResponseTrailerMapImpl response_trailers{ {"x-logged-trailer", "value"}, {"x-empty-trailer", ""}, {"x-unlogged-trailer", "2"}, diff --git a/test/extensions/common/aws/mocks.h b/test/extensions/common/aws/mocks.h index 8e483ebe13..ecdcd8827b 100644 --- a/test/extensions/common/aws/mocks.h +++ b/test/extensions/common/aws/mocks.h @@ -23,8 +23,8 @@ class MockSigner : public Signer { MockSigner(); ~MockSigner() override; - MOCK_METHOD(void, sign, (Http::Message&, bool)); - MOCK_METHOD(void, sign, (Http::HeaderMap&)); + MOCK_METHOD(void, sign, (Http::RequestMessage&, bool)); + MOCK_METHOD(void, sign, (Http::RequestHeaderMap&)); }; class MockMetadataFetcher { diff --git a/test/extensions/common/aws/signer_impl_test.cc b/test/extensions/common/aws/signer_impl_test.cc index fc93649eea..2d12dc00b7 100644 --- a/test/extensions/common/aws/signer_impl_test.cc +++ b/test/extensions/common/aws/signer_impl_test.cc @@ -43,7 +43,7 @@ class SignerImplTest : public testing::Test { NiceMock* credentials_provider_; Event::SimulatedTimeSystem time_system_; - Http::MessagePtr message_; + Http::RequestMessagePtr message_; SignerImpl signer_; Credentials credentials_; Credentials token_credentials_; diff --git a/test/extensions/common/tap/admin_test.cc b/test/extensions/common/tap/admin_test.cc index c5a66fc4fe..95c7d7e507 100644 --- a/test/extensions/common/tap/admin_test.cc +++ b/test/extensions/common/tap/admin_test.cc @@ -40,7 +40,7 @@ class AdminHandlerTest : public testing::Test { Event::MockDispatcher main_thread_dispatcher_; std::unique_ptr handler_; Server::Admin::HandlerCb cb_; - Http::TestHeaderMapImpl response_headers_; + Http::TestResponseHeaderMapImpl response_headers_; Buffer::OwnedImpl response_; Server::MockAdminStream admin_stream_; diff --git a/test/extensions/filters/common/expr/evaluator_fuzz_test.cc b/test/extensions/filters/common/expr/evaluator_fuzz_test.cc index 09e43f8531..89a63a373a 100644 --- a/test/extensions/filters/common/expr/evaluator_fuzz_test.cc +++ b/test/extensions/filters/common/expr/evaluator_fuzz_test.cc @@ -33,9 +33,10 @@ DEFINE_PROTO_FUZZER(const test::extensions::filters::common::expr::EvaluatorTest return; } - Http::TestHeaderMapImpl request_headers = Fuzz::fromHeaders(input.request_headers()); - Http::TestHeaderMapImpl response_headers = Fuzz::fromHeaders(input.response_headers()); - Http::TestHeaderMapImpl response_trailers = Fuzz::fromHeaders(input.trailers()); + auto request_headers = Fuzz::fromHeaders(input.request_headers()); + auto response_headers = + Fuzz::fromHeaders(input.response_headers()); + auto response_trailers = Fuzz::fromHeaders(input.trailers()); try { // Create the CEL expression. diff --git a/test/extensions/filters/common/ext_authz/check_request_utils_test.cc b/test/extensions/filters/common/ext_authz/check_request_utils_test.cc index d53fc964b9..9a50e34271 100644 --- a/test/extensions/filters/common/ext_authz/check_request_utils_test.cc +++ b/test/extensions/filters/common/ext_authz/check_request_utils_test.cc @@ -47,8 +47,8 @@ class CheckRequestUtilsTest : public testing::Test { } void callHttpCheckAndValidateRequestAttributes(bool include_peer_certificate) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-downstream-service-cluster", "foo"}, - {":path", "/bar"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-downstream-service-cluster", "foo"}, + {":path", "/bar"}}; envoy::service::auth::v3::CheckRequest request; Protobuf::Map context_extensions; context_extensions["key"] = "value"; @@ -146,7 +146,8 @@ TEST_F(CheckRequestUtilsTest, BasicHttp) { envoy::service::auth::v3::CheckRequest request_; // A client supplied EnvoyAuthPartialBody header should be ignored. - Http::TestHeaderMapImpl request_headers{{Http::Headers::get().EnvoyAuthPartialBody.get(), "1"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {Http::Headers::get().EnvoyAuthPartialBody.get(), "1"}}; EXPECT_CALL(*ssl_, uriSanPeerCertificate()).WillOnce(Return(std::vector{"source"})); EXPECT_CALL(*ssl_, uriSanLocalCertificate()) @@ -205,8 +206,8 @@ TEST_F(CheckRequestUtilsTest, BasicHttpWithFullBody) { // proto object. // Verify that the source certificate is not set by default. TEST_F(CheckRequestUtilsTest, CheckAttrContextPeer) { - Http::TestHeaderMapImpl request_headers{{"x-envoy-downstream-service-cluster", "foo"}, - {":path", "/bar"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-downstream-service-cluster", "foo"}, + {":path", "/bar"}}; envoy::service::auth::v3::CheckRequest request; EXPECT_CALL(callbacks_, connection()).WillRepeatedly(Return(&connection_)); EXPECT_CALL(connection_, remoteAddress()).WillRepeatedly(ReturnRef(addr_)); 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 f839da9f44..93d7d07401 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 @@ -82,7 +82,7 @@ TEST_P(ExtAuthzGrpcClientTest, AuthorizationOk) { expectCallSend(request); client_->check(request_callbacks_, request, Tracing::NullSpan::instance()); - Http::HeaderMapImpl headers; + Http::RequestHeaderMapImpl headers; client_->onCreateInitialMetadata(headers); EXPECT_CALL(span_, setTag(Eq("ext_authz_status"), Eq("ext_authz_ok"))); @@ -106,7 +106,7 @@ TEST_P(ExtAuthzGrpcClientTest, AuthorizationOkWithAllAtributes) { expectCallSend(request); client_->check(request_callbacks_, request, Tracing::NullSpan::instance()); - Http::HeaderMapImpl headers; + Http::RequestHeaderMapImpl headers; client_->onCreateInitialMetadata(headers); EXPECT_CALL(span_, setTag(Eq("ext_authz_status"), Eq("ext_authz_ok"))); @@ -129,7 +129,7 @@ TEST_P(ExtAuthzGrpcClientTest, AuthorizationDenied) { expectCallSend(request); client_->check(request_callbacks_, request, Tracing::NullSpan::instance()); - Http::HeaderMapImpl headers; + Http::RequestHeaderMapImpl headers; client_->onCreateInitialMetadata(headers); EXPECT_EQ(nullptr, headers.RequestId()); EXPECT_CALL(span_, setTag(Eq("ext_authz_status"), Eq("ext_authz_unauthorized"))); @@ -153,7 +153,7 @@ TEST_P(ExtAuthzGrpcClientTest, AuthorizationDeniedGrpcUnknownStatus) { expectCallSend(request); client_->check(request_callbacks_, request, Tracing::NullSpan::instance()); - Http::HeaderMapImpl headers; + Http::RequestHeaderMapImpl headers; client_->onCreateInitialMetadata(headers); EXPECT_EQ(nullptr, headers.RequestId()); EXPECT_CALL(span_, setTag(Eq("ext_authz_status"), Eq("ext_authz_unauthorized"))); @@ -180,7 +180,7 @@ TEST_P(ExtAuthzGrpcClientTest, AuthorizationDeniedWithAllAttributes) { expectCallSend(request); client_->check(request_callbacks_, request, Tracing::NullSpan::instance()); - Http::HeaderMapImpl headers; + Http::RequestHeaderMapImpl headers; client_->onCreateInitialMetadata(headers); EXPECT_EQ(nullptr, headers.RequestId()); EXPECT_CALL(span_, setTag(Eq("ext_authz_status"), Eq("ext_authz_unauthorized"))); diff --git a/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc b/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc index 4551a8110e..945826b996 100644 --- a/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc +++ b/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc @@ -87,7 +87,7 @@ class ExtAuthzHttpClientTest : public testing::Test { return std::make_shared(ClientConfig{proto_config, timeout, path_prefix}); } - Http::MessagePtr sendRequest(std::unordered_map&& headers) { + Http::RequestMessagePtr sendRequest(std::unordered_map&& headers) { envoy::service::auth::v3::CheckRequest request{}; auto mutable_headers = request.mutable_attributes()->mutable_request()->mutable_http()->mutable_headers(); @@ -95,10 +95,10 @@ class ExtAuthzHttpClientTest : public testing::Test { (*mutable_headers)[header.first] = header.second; } - Http::MessagePtr message_ptr; + Http::RequestMessagePtr message_ptr; EXPECT_CALL(async_client_, send_(_, _, _)) .WillOnce(Invoke( - [&](Http::MessagePtr& message, Http::AsyncClient::Callbacks&, + [&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks&, const Envoy::Http::AsyncClient::RequestOptions) -> Http::AsyncClient::Request* { message_ptr = std::move(message); return nullptr; @@ -189,7 +189,7 @@ TEST_F(ExtAuthzHttpClientTest, TestDefaultAllowedHeaders) { // Verify client response when the authorization server returns a 200 OK and path_prefix is // configured. TEST_F(ExtAuthzHttpClientTest, AuthorizationOkWithPathRewrite) { - Http::MessagePtr message_ptr = sendRequest({{":path", "/foo"}, {"foo", "bar"}}); + Http::RequestMessagePtr message_ptr = sendRequest({{":path", "/foo"}, {"foo", "bar"}}); const auto* path = message_ptr->headers().get(Http::Headers::get().Path); ASSERT_NE(path, nullptr); @@ -198,7 +198,7 @@ TEST_F(ExtAuthzHttpClientTest, AuthorizationOkWithPathRewrite) { // Test the client when a request contains Content-Length greater than 0. TEST_F(ExtAuthzHttpClientTest, ContentLengthEqualZero) { - Http::MessagePtr message_ptr = + Http::RequestMessagePtr message_ptr = sendRequest({{Http::Headers::get().ContentLength.get(), std::string{"47"}}, {Http::Headers::get().Method.get(), std::string{"POST"}}}); @@ -230,7 +230,7 @@ TEST_F(ExtAuthzHttpClientTest, ContentLengthEqualZeroWithAllowedHeaders) { EXPECT_TRUE(config_->requestHeaderMatchers()->matches(Http::Headers::get().Method.get())); EXPECT_TRUE(config_->requestHeaderMatchers()->matches(Http::Headers::get().ContentLength.get())); - Http::MessagePtr message_ptr = + Http::RequestMessagePtr message_ptr = sendRequest({{Http::Headers::get().ContentLength.get(), std::string{"47"}}, {Http::Headers::get().Method.get(), std::string{"POST"}}}); @@ -245,7 +245,7 @@ TEST_F(ExtAuthzHttpClientTest, ContentLengthEqualZeroWithAllowedHeaders) { // Test the client when a request contains headers in the prefix matchers. TEST_F(ExtAuthzHttpClientTest, AllowedRequestHeadersPrefix) { - Http::MessagePtr message_ptr = + Http::RequestMessagePtr message_ptr = sendRequest({{Http::Headers::get().XContentTypeOptions.get(), "foobar"}, {Http::Headers::get().XSquashDebug.get(), "foo"}, {Http::Headers::get().ContentType.get(), "bar"}}); @@ -443,8 +443,8 @@ TEST_F(ExtAuthzHttpClientTest, AuthorizationRequestError) { // Test the client when a call to authorization server returns a 5xx error status. TEST_F(ExtAuthzHttpClientTest, AuthorizationRequest5xxError) { - Http::MessagePtr check_response(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "503"}}})); + Http::ResponseMessagePtr check_response(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "503"}}})); Tracing::MockSpan* child_span{new Tracing::MockSpan()}; envoy::service::auth::v3::CheckRequest request; @@ -465,8 +465,8 @@ TEST_F(ExtAuthzHttpClientTest, AuthorizationRequest5xxError) { // Test the client when a call to authorization server returns a status code that cannot be // parsed. TEST_F(ExtAuthzHttpClientTest, AuthorizationRequestErrorParsingStatusCode) { - Http::MessagePtr check_response(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "foo"}}})); + Http::ResponseMessagePtr check_response(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "foo"}}})); Tracing::MockSpan* child_span{new Tracing::MockSpan()}; envoy::service::auth::v3::CheckRequest request; diff --git a/test/extensions/filters/common/ext_authz/test_common.cc b/test/extensions/filters/common/ext_authz/test_common.cc index 618c11c3dc..9e8af02f38 100644 --- a/test/extensions/filters/common/ext_authz/test_common.cc +++ b/test/extensions/filters/common/ext_authz/test_common.cc @@ -86,10 +86,10 @@ HeaderValueOptionVector TestCommon::makeHeaderValueOption(KeyValueOptionVector&& return header_option_vector; } -Http::MessagePtr TestCommon::makeMessageResponse(const HeaderValueOptionVector& headers, - const std::string& body) { - Http::MessagePtr response( - new Http::ResponseMessageImpl(Http::HeaderMapPtr{new Http::TestHeaderMapImpl{}})); +Http::ResponseMessagePtr TestCommon::makeMessageResponse(const HeaderValueOptionVector& headers, + const std::string& body) { + Http::ResponseMessagePtr response(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{}})); for (auto& header : headers) { response->headers().addCopy(Http::LowerCaseString(header.header().key()), header.header().value()); diff --git a/test/extensions/filters/common/ext_authz/test_common.h b/test/extensions/filters/common/ext_authz/test_common.h index ae32c901e4..47a4ad6e3b 100644 --- a/test/extensions/filters/common/ext_authz/test_common.h +++ b/test/extensions/filters/common/ext_authz/test_common.h @@ -28,8 +28,8 @@ using CheckResponsePtr = std::unique_ptrdecodeData(request_body, false)); - Http::TestHeaderMapImpl request_trailers; + Http::TestRequestTrailerMapImpl request_trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, true)); filter_->encodeComplete(); } @@ -143,23 +143,23 @@ TEST_F(AdaptiveConcurrencyFilterTest, TestEnableConfiguredInProto) { // We expect no calls to the concurrency controller. - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); Buffer::OwnedImpl request_body; EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(request_body, false)); - Http::TestHeaderMapImpl request_trailers; + Http::TestRequestTrailerMapImpl request_trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, true)); filter_->encodeComplete(); } TEST_F(AdaptiveConcurrencyFilterTest, DecodeHeadersTestForwarding) { - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_CALL(*controller_, forwardingDecision()) .WillOnce(Return(RequestForwardingAction::Forward)); @@ -170,12 +170,12 @@ TEST_F(AdaptiveConcurrencyFilterTest, DecodeHeadersTestForwarding) { Buffer::OwnedImpl request_body; EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(request_body, false)); - Http::TestHeaderMapImpl request_trailers; + Http::TestRequestTrailerMapImpl request_trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } TEST_F(AdaptiveConcurrencyFilterTest, DecodeHeadersTestBlock) { - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_CALL(*controller_, forwardingDecision()).WillOnce(Return(RequestForwardingAction::Block)); EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::ServiceUnavailable, _, _, _, _)); @@ -187,7 +187,7 @@ TEST_F(AdaptiveConcurrencyFilterTest, RecordSampleInDestructor) { // Verify that the request latency is always sampled even if encodeComplete() is never called. EXPECT_CALL(*controller_, forwardingDecision()) .WillOnce(Return(RequestForwardingAction::Forward)); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; filter_->decodeHeaders(request_headers, true); EXPECT_CALL(*controller_, recordLatencySample(_)); @@ -197,7 +197,7 @@ TEST_F(AdaptiveConcurrencyFilterTest, RecordSampleInDestructor) { TEST_F(AdaptiveConcurrencyFilterTest, RecordSampleOmission) { // Verify that the request latency is not sampled if forwardingDecision blocks the request. EXPECT_CALL(*controller_, forwardingDecision()).WillOnce(Return(RequestForwardingAction::Block)); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; filter_->decodeHeaders(request_headers, true); filter_.reset(); @@ -205,7 +205,7 @@ TEST_F(AdaptiveConcurrencyFilterTest, RecordSampleOmission) { TEST_F(AdaptiveConcurrencyFilterTest, OnDestroyCleanupResetTest) { // Get the filter to record the request start time via decode. - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_CALL(*controller_, forwardingDecision()) .WillOnce(Return(RequestForwardingAction::Forward)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); @@ -218,7 +218,7 @@ TEST_F(AdaptiveConcurrencyFilterTest, OnDestroyCleanupResetTest) { TEST_F(AdaptiveConcurrencyFilterTest, OnDestroyCleanupTest) { // Get the filter to record the request start time via decode. - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_CALL(*controller_, forwardingDecision()) .WillOnce(Return(RequestForwardingAction::Forward)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); @@ -226,7 +226,7 @@ TEST_F(AdaptiveConcurrencyFilterTest, OnDestroyCleanupTest) { const auto advance_time = std::chrono::nanoseconds(42); time_system_.sleep(advance_time); - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, true)); EXPECT_CALL(*controller_, recordLatencySample(advance_time)); filter_->encodeComplete(); @@ -239,22 +239,24 @@ TEST_F(AdaptiveConcurrencyFilterTest, EncodeHeadersValidTestWithBody) { time_system_.setMonotonicTime(mt + std::chrono::nanoseconds(123)); // Get the filter to record the request start time via decode. - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_CALL(*controller_, forwardingDecision()) .WillOnce(Return(RequestForwardingAction::Forward)); Buffer::OwnedImpl data; 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_headers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); const auto advance_time = std::chrono::nanoseconds(42); mt = time_system_.monotonicTime(); time_system_.setMonotonicTime(mt + advance_time); - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers)); + Http::TestResponseTrailerMapImpl response_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers)); EXPECT_CALL(*controller_, recordLatencySample(advance_time)); filter_->encodeComplete(); } @@ -264,7 +266,7 @@ TEST_F(AdaptiveConcurrencyFilterTest, EncodeHeadersValidTest) { time_system_.setMonotonicTime(mt + std::chrono::nanoseconds(123)); // Get the filter to record the request start time via decode. - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_CALL(*controller_, forwardingDecision()) .WillOnce(Return(RequestForwardingAction::Forward)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); @@ -273,7 +275,7 @@ TEST_F(AdaptiveConcurrencyFilterTest, EncodeHeadersValidTest) { mt = time_system_.monotonicTime(); time_system_.setMonotonicTime(mt + advance_time); - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, true)); EXPECT_CALL(*controller_, recordLatencySample(advance_time)); filter_->encodeComplete(); @@ -284,13 +286,13 @@ TEST_F(AdaptiveConcurrencyFilterTest, DisregardHealthChecks) { EXPECT_CALL(decoder_callbacks_, streamInfo()).WillOnce(ReturnRef(stream_info)); EXPECT_CALL(stream_info, healthCheck()).WillOnce(Return(true)); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; // We do not expect a call to forwardingDecision() during decode. EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, true)); // We do not expect a call to recordLatencySample() as well. diff --git a/test/extensions/filters/http/aws_request_signing/BUILD b/test/extensions/filters/http/aws_request_signing/BUILD index 729cd9b459..5a3194877b 100644 --- a/test/extensions/filters/http/aws_request_signing/BUILD +++ b/test/extensions/filters/http/aws_request_signing/BUILD @@ -17,6 +17,7 @@ envoy_extension_cc_test( extension_name = "envoy.filters.http.aws_request_signing", deps = [ "//source/extensions/filters/http/aws_request_signing:aws_request_signing_filter_lib", + "//test/extensions/common/aws:aws_mocks", "//test/mocks/http:http_mocks", ], ) diff --git a/test/extensions/filters/http/aws_request_signing/aws_request_signing_filter_test.cc b/test/extensions/filters/http/aws_request_signing/aws_request_signing_filter_test.cc index 15d8b748c2..74a2520b1f 100644 --- a/test/extensions/filters/http/aws_request_signing/aws_request_signing_filter_test.cc +++ b/test/extensions/filters/http/aws_request_signing/aws_request_signing_filter_test.cc @@ -1,6 +1,7 @@ #include "extensions/common/aws/signer.h" #include "extensions/filters/http/aws_request_signing/aws_request_signing_filter.h" +#include "test/extensions/common/aws/mocks.h" #include "test/mocks/http/mocks.h" #include "gmock/gmock.h" @@ -12,20 +13,14 @@ namespace HttpFilters { namespace AwsRequestSigningFilter { namespace { -class MockSigner : public Common::Aws::Signer { -public: - MOCK_METHOD(void, sign, (Http::HeaderMap&)); - MOCK_METHOD(void, sign, (Http::Message&, bool)); -}; - class MockFilterConfig : public FilterConfig { public: - MockFilterConfig() { signer_ = std::make_shared(); } + MockFilterConfig() { signer_ = std::make_shared(); } Common::Aws::Signer& signer() override { return *signer_; } FilterStats& stats() override { return stats_; } - std::shared_ptr signer_; + std::shared_ptr signer_; Stats::IsolatedStoreImpl stats_store_; FilterStats stats_{Filter::generateStats("test", stats_store_)}; }; @@ -46,7 +41,7 @@ TEST_F(AwsRequestSigningFilterTest, SignSucceeds) { setup(); EXPECT_CALL(*(filter_config_->signer_), sign(_)).Times(1); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_EQ(1UL, filter_config_->stats_.signing_added_.value()); } @@ -58,7 +53,7 @@ TEST_F(AwsRequestSigningFilterTest, SignFails) { throw EnvoyException("failed"); })); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_EQ(1UL, filter_config_->stats_.signing_failed_.value()); } diff --git a/test/extensions/filters/http/buffer/buffer_filter_integration_test.cc b/test/extensions/filters/http/buffer/buffer_filter_integration_test.cc index 49ffa9446d..80f1ed31c6 100644 --- a/test/extensions/filters/http/buffer/buffer_filter_integration_test.cc +++ b/test/extensions/filters/http/buffer/buffer_filter_integration_test.cc @@ -44,7 +44,7 @@ TEST_P(BufferIntegrationTest, RouterRequestPopulateContentLength) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto encoder_decoder = codec_client_->startRequest(Http::TestHeaderMapImpl{ + auto encoder_decoder = codec_client_->startRequest(Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":scheme", "http"}, {":path", "/shelf"}, {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; IntegrationStreamDecoderPtr response = std::move(encoder_decoder.second); @@ -71,14 +71,14 @@ TEST_P(BufferIntegrationTest, RouterRequestPopulateContentLengthOnTrailers) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto encoder_decoder = codec_client_->startRequest(Http::TestHeaderMapImpl{ + auto encoder_decoder = codec_client_->startRequest(Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":scheme", "http"}, {":path", "/shelf"}, {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; IntegrationStreamDecoderPtr response = std::move(encoder_decoder.second); codec_client_->sendData(*request_encoder_, "0123", false); codec_client_->sendData(*request_encoder_, "456", false); codec_client_->sendData(*request_encoder_, "789", false); - Http::TestHeaderMapImpl request_trailers{{"request", "trailer"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"request", "trailer"}}; codec_client_->sendTrailers(*request_encoder_, request_trailers); ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_)); @@ -101,14 +101,14 @@ TEST_P(BufferIntegrationTest, RouterRequestBufferLimitExceeded) { codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/dynamo/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}}, - 1024 * 65); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/dynamo/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}}, + 1024 * 65); response->waitForEndStream(); ASSERT_TRUE(response->complete()); @@ -141,16 +141,16 @@ TEST_P(BufferIntegrationTest, RouteDisabled) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}}, - 1024 * 65); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}}, + 1024 * 65); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); ASSERT_TRUE(response->complete()); @@ -167,16 +167,16 @@ TEST_P(BufferIntegrationTest, RouteOverride) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}}, - 1024 * 65); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}}, + 1024 * 65); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); ASSERT_TRUE(response->complete()); diff --git a/test/extensions/filters/http/buffer/buffer_filter_test.cc b/test/extensions/filters/http/buffer/buffer_filter_test.cc index 51a8528d2f..11f85e138f 100644 --- a/test/extensions/filters/http/buffer/buffer_filter_test.cc +++ b/test/extensions/filters/http/buffer/buffer_filter_test.cc @@ -56,7 +56,7 @@ class BufferFilterTest : public testing::Test { }; TEST_F(BufferFilterTest, HeaderOnlyRequest) { - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(headers, true)); } @@ -68,7 +68,7 @@ TEST_F(BufferFilterTest, TestMetadata) { TEST_F(BufferFilterTest, RequestWithData) { InSequence s; - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(headers, false)); Buffer::OwnedImpl data1("hello"); @@ -81,7 +81,7 @@ TEST_F(BufferFilterTest, RequestWithData) { TEST_F(BufferFilterTest, TxResetAfterEndStream) { InSequence s; - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(headers, false)); Buffer::OwnedImpl data1("hello"); @@ -98,7 +98,7 @@ TEST_F(BufferFilterTest, TxResetAfterEndStream) { TEST_F(BufferFilterTest, ContentLengthPopulation) { InSequence s; - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(headers, false)); Buffer::OwnedImpl data1("hello"); @@ -113,14 +113,14 @@ TEST_F(BufferFilterTest, ContentLengthPopulation) { TEST_F(BufferFilterTest, ContentLengthPopulationInTrailers) { InSequence s; - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(headers, false)); Buffer::OwnedImpl data1("hello"); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_.decodeData(data1, false)); ASSERT_EQ(headers.ContentLength(), nullptr); - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(trailers)); ASSERT_NE(headers.ContentLength(), nullptr); EXPECT_EQ(headers.ContentLength()->value().getStringView(), "5"); @@ -129,7 +129,7 @@ TEST_F(BufferFilterTest, ContentLengthPopulationInTrailers) { TEST_F(BufferFilterTest, ContentLengthPopulationAlreadyPresent) { InSequence s; - Http::TestHeaderMapImpl headers{{"content-length", "3"}}; + Http::TestRequestHeaderMapImpl headers{{"content-length", "3"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(headers, false)); Buffer::OwnedImpl data("foo"); @@ -150,7 +150,7 @@ TEST_F(BufferFilterTest, RouteConfigOverride) { EXPECT_CALL(callbacks_, setDecoderBufferLimit(123ULL)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(headers, false)); filter_.onDestroy(); @@ -165,7 +165,7 @@ TEST_F(BufferFilterTest, VHostConfigOverride) { EXPECT_CALL(callbacks_, setDecoderBufferLimit(789ULL)); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(headers, false)); filter_.onDestroy(); } @@ -176,7 +176,7 @@ TEST_F(BufferFilterTest, RouteDisabledConfigOverride) { BufferFilterSettings vhost_settings(vhost_cfg); routeLocalConfig(nullptr, &vhost_settings); - Http::TestHeaderMapImpl headers; + Http::TestRequestHeaderMapImpl headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(headers, false)); Buffer::OwnedImpl data1("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data1, false)); diff --git a/test/extensions/filters/http/cache/http_cache_test.cc b/test/extensions/filters/http/cache/http_cache_test.cc index 5eee698cf0..a641b659a7 100644 --- a/test/extensions/filters/http/cache/http_cache_test.cc +++ b/test/extensions/filters/http/cache/http_cache_test.cc @@ -66,7 +66,7 @@ class LookupRequestTest : public testing::Test { Event::SimulatedTimeSystem time_source_; SystemTime current_time_ = time_source_.systemTime(); DateFormatter formatter_{"%a, %d %b %Y %H:%M:%S GMT"}; - Http::TestHeaderMapImpl request_headers_{ + Http::TestRequestHeaderMapImpl request_headers_{ {":path", "/"}, {"x-forwarded-proto", "https"}, {":authority", "example.com"}}; }; @@ -79,7 +79,7 @@ LookupResult makeLookupResult(const LookupRequest& lookup_request, TEST_F(LookupRequestTest, MakeLookupResultNoBody) { const LookupRequest lookup_request(request_headers_, current_time_); - const Http::TestHeaderMapImpl response_headers( + const Http::TestResponseHeaderMapImpl response_headers( {{"date", formatter_.fromTime(current_time_)}, {"cache-control", "public, max-age=3600"}}); const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); ASSERT_EQ(CacheEntryStatus::Ok, lookup_response.cache_entry_status_); @@ -92,7 +92,7 @@ TEST_F(LookupRequestTest, MakeLookupResultNoBody) { TEST_F(LookupRequestTest, MakeLookupResultBody) { const LookupRequest lookup_request(request_headers_, current_time_); - const Http::TestHeaderMapImpl response_headers( + const Http::TestResponseHeaderMapImpl response_headers( {{"date", formatter_.fromTime(current_time_)}, {"cache-control", "public, max-age=3600"}}); const uint64_t content_length = 5; const LookupResult lookup_response = @@ -107,7 +107,8 @@ TEST_F(LookupRequestTest, MakeLookupResultBody) { TEST_F(LookupRequestTest, MakeLookupResultNoDate) { const LookupRequest lookup_request(request_headers_, current_time_); - const Http::TestHeaderMapImpl response_headers({{"cache-control", "public, max-age=3600"}}); + const Http::TestResponseHeaderMapImpl response_headers( + {{"cache-control", "public, max-age=3600"}}); const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); EXPECT_EQ(CacheEntryStatus::RequiresValidation, lookup_response.cache_entry_status_); ASSERT_TRUE(lookup_response.headers_); @@ -119,9 +120,10 @@ TEST_F(LookupRequestTest, MakeLookupResultNoDate) { TEST_F(LookupRequestTest, PrivateResponse) { const LookupRequest lookup_request(request_headers_, current_time_); - const Http::TestHeaderMapImpl response_headers({{"age", "2"}, - {"cache-control", "private, max-age=3600"}, - {"date", formatter_.fromTime(current_time_)}}); + const Http::TestResponseHeaderMapImpl response_headers( + {{"age", "2"}, + {"cache-control", "private, max-age=3600"}, + {"date", formatter_.fromTime(current_time_)}}); const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); // We must make sure at cache insertion time, private responses must not be @@ -137,7 +139,7 @@ TEST_F(LookupRequestTest, PrivateResponse) { TEST_F(LookupRequestTest, Expired) { const LookupRequest lookup_request(request_headers_, current_time_); - const Http::TestHeaderMapImpl response_headers( + const Http::TestResponseHeaderMapImpl response_headers( {{"cache-control", "public, max-age=3600"}, {"date", "Thu, 01 Jan 2019 00:00:00 GMT"}}); const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); @@ -151,7 +153,7 @@ TEST_F(LookupRequestTest, Expired) { TEST_F(LookupRequestTest, ExpiredViaFallbackheader) { const LookupRequest lookup_request(request_headers_, current_time_); - const Http::TestHeaderMapImpl response_headers( + const Http::TestResponseHeaderMapImpl response_headers( {{"expires", formatter_.fromTime(current_time_ - std::chrono::seconds(5))}, {"date", formatter_.fromTime(current_time_)}}); const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); @@ -161,7 +163,7 @@ TEST_F(LookupRequestTest, ExpiredViaFallbackheader) { TEST_F(LookupRequestTest, NotExpiredViaFallbackheader) { const LookupRequest lookup_request(request_headers_, current_time_); - const Http::TestHeaderMapImpl response_headers( + const Http::TestResponseHeaderMapImpl response_headers( {{"expires", formatter_.fromTime(current_time_ + std::chrono::seconds(5))}, {"date", formatter_.fromTime(current_time_)}}); const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers); @@ -171,9 +173,10 @@ TEST_F(LookupRequestTest, NotExpiredViaFallbackheader) { TEST_F(LookupRequestTest, FullRange) { request_headers_.addCopy("Range", "0-99"); const LookupRequest lookup_request(request_headers_, current_time_); - const Http::TestHeaderMapImpl response_headers({{"date", formatter_.fromTime(current_time_)}, - {"cache-control", "public, max-age=3600"}, - {"content-length", "4"}}); + const Http::TestResponseHeaderMapImpl response_headers( + {{"date", formatter_.fromTime(current_time_)}, + {"cache-control", "public, max-age=3600"}, + {"content-length", "4"}}); const uint64_t content_length = 4; const LookupResult lookup_response = makeLookupResult(lookup_request, response_headers, content_length); diff --git a/test/extensions/filters/http/cache/http_cache_utils_test.cc b/test/extensions/filters/http/cache/http_cache_utils_test.cc index 6a25808a55..09a8256622 100644 --- a/test/extensions/filters/http/cache/http_cache_utils_test.cc +++ b/test/extensions/filters/http/cache/http_cache_utils_test.cc @@ -28,7 +28,7 @@ const char* const ok_times[] = { INSTANTIATE_TEST_SUITE_P(Ok, HttpTimeTest, testing::ValuesIn(ok_times)); TEST_P(HttpTimeTest, Ok) { - Http::TestHeaderMapImpl response_headers{{"date", GetParam()}}; + Http::TestResponseHeaderMapImpl response_headers{{"date", GetParam()}}; // Manually confirmed that 784111777 is 11/6/94, 8:46:37. EXPECT_EQ(784111777, SystemTime::clock::to_time_t(Utils::httpTime(response_headers.Date()))); } diff --git a/test/extensions/filters/http/cache/simple_http_cache/simple_http_cache_test.cc b/test/extensions/filters/http/cache/simple_http_cache/simple_http_cache_test.cc index 323da092cf..e45d621aba 100644 --- a/test/extensions/filters/http/cache/simple_http_cache/simple_http_cache_test.cc +++ b/test/extensions/filters/http/cache/simple_http_cache/simple_http_cache_test.cc @@ -87,7 +87,7 @@ class SimpleHttpCacheTest : public testing::Test { SimpleHttpCache cache_; LookupResult lookup_result_; - Http::TestHeaderMapImpl request_headers_; + Http::TestRequestHeaderMapImpl request_headers_; Event::SimulatedTimeSystem time_source_; SystemTime current_time_ = time_source_.systemTime(); DateFormatter formatter_{"%a, %d %b %Y %H:%M:%S GMT"}; @@ -99,8 +99,8 @@ TEST_F(SimpleHttpCacheTest, PutGet) { LookupContextPtr name_lookup_context = lookup(RequestPath1); EXPECT_EQ(CacheEntryStatus::Unusable, lookup_result_.cache_entry_status_); - Http::TestHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, - {"cache-control", "public,max-age=3600"}}; + Http::TestResponseHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, + {"cache-control", "public,max-age=3600"}}; const std::string Body1("Value"); insert(move(name_lookup_context), response_headers, Body1); @@ -117,9 +117,9 @@ TEST_F(SimpleHttpCacheTest, PutGet) { } TEST_F(SimpleHttpCacheTest, PrivateResponse) { - Http::TestHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, - {"age", "2"}, - {"cache-control", "private,max-age=3600"}}; + Http::TestResponseHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, + {"age", "2"}, + {"cache-control", "private,max-age=3600"}}; const std::string request_path("Name"); LookupContextPtr name_lookup_context = lookup(request_path); @@ -139,8 +139,8 @@ TEST_F(SimpleHttpCacheTest, Miss) { } TEST_F(SimpleHttpCacheTest, Fresh) { - const Http::TestHeaderMapImpl response_headers = {{"date", formatter_.fromTime(current_time_)}, - {"cache-control", "public, max-age=3600"}}; + const Http::TestResponseHeaderMapImpl response_headers = { + {"date", formatter_.fromTime(current_time_)}, {"cache-control", "public, max-age=3600"}}; // TODO(toddmgreer): Test with various date headers. insert("/", response_headers, ""); time_source_.sleep(std::chrono::seconds(3600)); @@ -149,8 +149,8 @@ TEST_F(SimpleHttpCacheTest, Fresh) { } TEST_F(SimpleHttpCacheTest, Stale) { - const Http::TestHeaderMapImpl response_headers = {{"date", formatter_.fromTime(current_time_)}, - {"cache-control", "public, max-age=3600"}}; + const Http::TestResponseHeaderMapImpl response_headers = { + {"date", formatter_.fromTime(current_time_)}, {"cache-control", "public, max-age=3600"}}; // TODO(toddmgreer): Test with various date headers. insert("/", response_headers, ""); time_source_.sleep(std::chrono::seconds(3601)); @@ -164,9 +164,9 @@ TEST_F(SimpleHttpCacheTest, RequestSmallMinFresh) { LookupContextPtr name_lookup_context = lookup(request_path); EXPECT_EQ(CacheEntryStatus::Unusable, lookup_result_.cache_entry_status_); - Http::TestHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, - {"age", "6000"}, - {"cache-control", "public, max-age=9000"}}; + Http::TestResponseHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, + {"age", "6000"}, + {"cache-control", "public, max-age=9000"}}; const std::string Body("Value"); insert(move(name_lookup_context), response_headers, Body); EXPECT_TRUE(expectLookupSuccessWithBody(lookup(request_path).get(), Body)); @@ -179,9 +179,9 @@ TEST_F(SimpleHttpCacheTest, ResponseStaleWithRequestLargeMaxStale) { LookupContextPtr name_lookup_context = lookup(request_path); EXPECT_EQ(CacheEntryStatus::Unusable, lookup_result_.cache_entry_status_); - Http::TestHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, - {"age", "7200"}, - {"cache-control", "public, max-age=3600"}}; + Http::TestResponseHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, + {"age", "7200"}, + {"cache-control", "public, max-age=3600"}}; const std::string Body("Value"); insert(move(name_lookup_context), response_headers, Body); @@ -189,9 +189,9 @@ TEST_F(SimpleHttpCacheTest, ResponseStaleWithRequestLargeMaxStale) { } TEST_F(SimpleHttpCacheTest, StreamingPut) { - Http::TestHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, - {"age", "2"}, - {"cache-control", "public, max-age=3600"}}; + Http::TestResponseHeaderMapImpl response_headers{{"date", formatter_.fromTime(current_time_)}, + {"age", "2"}, + {"cache-control", "public, max-age=3600"}}; InsertContextPtr inserter = cache_.makeInsertContext(lookup("request_path")); inserter->insertHeaders(response_headers, false); inserter->insertBody( diff --git a/test/extensions/filters/http/common/jwks_fetcher_test.cc b/test/extensions/filters/http/common/jwks_fetcher_test.cc index a109045860..6cfcd8f14a 100644 --- a/test/extensions/filters/http/common/jwks_fetcher_test.cc +++ b/test/extensions/filters/http/common/jwks_fetcher_test.cc @@ -153,7 +153,7 @@ TEST_F(JwksFetcherTest, TestSpanPassedDown) { // Expectations for span EXPECT_CALL(mock_factory_ctx_.cluster_manager_.async_client_, send_(_, _, _)) .WillOnce(Invoke( - [this](Http::MessagePtr&, Http::AsyncClient::Callbacks&, + [this](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks&, const Http::AsyncClient::RequestOptions& options) -> Http::AsyncClient::Request* { EXPECT_TRUE(options.parent_span_ == &this->parent_span_); EXPECT_TRUE(options.child_span_name_ == "JWT Remote PubKey Fetch"); diff --git a/test/extensions/filters/http/common/mock.cc b/test/extensions/filters/http/common/mock.cc index 1f566187a8..8244cbd51b 100644 --- a/test/extensions/filters/http/common/mock.cc +++ b/test/extensions/filters/http/common/mock.cc @@ -11,10 +11,11 @@ MockUpstream::MockUpstream(Upstream::MockClusterManager& mock_cm, const std::str : request_(&mock_cm.async_client_), status_(status), response_body_(response_body) { ON_CALL(mock_cm.async_client_, send_(testing::_, testing::_, testing::_)) .WillByDefault(testing::Invoke( - [this](Http::MessagePtr&, Http::AsyncClient::Callbacks& cb, + [this](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - Http::MessagePtr response_message(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", status_}}})); + Http::ResponseMessagePtr response_message( + new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", status_}}})); if (response_body_.length()) { response_message->body() = std::make_unique(response_body_); } else { @@ -30,7 +31,7 @@ MockUpstream::MockUpstream(Upstream::MockClusterManager& mock_cm, : request_(&mock_cm.async_client_) { ON_CALL(mock_cm.async_client_, send_(testing::_, testing::_, testing::_)) .WillByDefault(testing::Invoke( - [this, reason](Http::MessagePtr&, Http::AsyncClient::Callbacks& cb, + [this, reason](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { cb.onFailure(reason); return &request_; diff --git a/test/extensions/filters/http/cors/cors_filter_integration_test.cc b/test/extensions/filters/http/cors/cors_filter_integration_test.cc index a60495a91c..b0d6fbb522 100644 --- a/test/extensions/filters/http/cors/cors_filter_integration_test.cc +++ b/test/extensions/filters/http/cors/cors_filter_integration_test.cc @@ -93,8 +93,8 @@ class CorsFilterIntegrationTest : public testing::TestWithParammakeHeaderOnlyRequest(request_headers); @@ -103,8 +103,8 @@ class CorsFilterIntegrationTest : public testing::TestWithParamheaders(), expected_response_headers); } - void testNormalRequest(Http::TestHeaderMapImpl&& request_headers, - Http::TestHeaderMapImpl&& expected_response_headers) { + void testNormalRequest(Http::TestRequestHeaderMapImpl&& request_headers, + Http::TestResponseHeaderMapImpl&& expected_response_headers) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); auto response = sendRequestAndWaitForResponse(request_headers, 0, expected_response_headers, 0); @@ -113,8 +113,8 @@ class CorsFilterIntegrationTest : public testing::TestWithParamheaders(), expected_response_headers); } - void compareHeaders(Http::TestHeaderMapImpl&& response_headers, - Http::TestHeaderMapImpl& expected_response_headers) { + void compareHeaders(Http::TestResponseHeaderMapImpl&& response_headers, + Http::TestResponseHeaderMapImpl& expected_response_headers) { response_headers.remove(Envoy::Http::LowerCaseString{"date"}); response_headers.remove(Envoy::Http::LowerCaseString{"x-envoy-upstream-service-time"}); EXPECT_EQ(expected_response_headers, response_headers); diff --git a/test/extensions/filters/http/cors/cors_filter_test.cc b/test/extensions/filters/http/cors/cors_filter_test.cc index dca81a5720..1c6e059d44 100644 --- a/test/extensions/filters/http/cors/cors_filter_test.cc +++ b/test/extensions/filters/http/cors/cors_filter_test.cc @@ -68,13 +68,16 @@ class CorsFilterTest : public testing::Test { CorsFilterConfigSharedPtr config_; CorsFilter filter_; Buffer::OwnedImpl data_; - Http::TestHeaderMapImpl request_headers_; + Http::TestRequestHeaderMapImpl request_headers_; + Http::TestRequestTrailerMapImpl request_trailers_; + Http::TestResponseHeaderMapImpl response_headers_; + Http::TestResponseTrailerMapImpl response_trailers_; std::unique_ptr cors_policy_; Router::MockDirectResponseEntry direct_response_entry_; }; TEST_F(CorsFilterTest, RequestWithoutOrigin) { - Http::TestHeaderMapImpl request_headers{{":method", "get"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "get"}}; EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, false)).Times(0); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); @@ -82,17 +85,17 @@ TEST_F(CorsFilterTest, RequestWithoutOrigin) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(0, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_.decodeMetadata(metadata_map)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, RequestWithOrigin) { - Http::TestHeaderMapImpl request_headers{{":method", "get"}, {"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "get"}, {"origin", "localhost"}}; EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, false)).Times(0); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); @@ -100,15 +103,15 @@ TEST_F(CorsFilterTest, RequestWithOrigin) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestWithoutOrigin) { - Http::TestHeaderMapImpl request_headers{{":method", "OPTIONS"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "OPTIONS"}}; EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, false)).Times(0); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); @@ -116,15 +119,15 @@ TEST_F(CorsFilterTest, OptionsRequestWithoutOrigin) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(0, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestWithOrigin) { - Http::TestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, false)).Times(0); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); @@ -132,51 +135,51 @@ TEST_F(CorsFilterTest, OptionsRequestWithOrigin) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestWithOriginCorsDisabled) { - Http::TestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; cors_policy_->enabled_ = false; EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, false)).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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(0, stats_.counter("test.cors.origin_valid").value()); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestWithOriginCorsDisabledShadowDisabled) { - Http::TestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; cors_policy_->enabled_ = false; EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, false)).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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(0, stats_.counter("test.cors.origin_valid").value()); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestWithOriginCorsDisabledShadowEnabled) { - Http::TestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; cors_policy_->enabled_ = false; cors_policy_->shadow_enabled_ = true; @@ -184,18 +187,18 @@ TEST_F(CorsFilterTest, OptionsRequestWithOriginCorsDisabledShadowEnabled) { EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, false)).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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestWithOriginCorsEnabled) { - Http::TestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, false)).Times(0); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); @@ -203,15 +206,15 @@ TEST_F(CorsFilterTest, OptionsRequestWithOriginCorsEnabled) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestWithoutAccessRequestMethod) { - Http::TestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "OPTIONS"}, {"origin", "localhost"}}; EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, false)).Times(0); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); @@ -219,18 +222,18 @@ TEST_F(CorsFilterTest, OptionsRequestWithoutAccessRequestMethod) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestMatchingOriginByWildcard) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "OPTIONS"}, {"origin", "test-host"}, {"access-control-request-method", "GET"}}; - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"access-control-allow-origin", "test-host"}, {"access-control-allow-methods", "GET"}, @@ -245,20 +248,20 @@ TEST_F(CorsFilterTest, OptionsRequestMatchingOriginByWildcard) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestWithOriginCorsEnabledShadowDisabled) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "OPTIONS"}, {"origin", "test-host"}, {"access-control-request-method", "GET"}}; cors_policy_->enabled_ = true; - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"access-control-allow-origin", "test-host"}, {"access-control-allow-methods", "GET"}, @@ -273,20 +276,20 @@ TEST_F(CorsFilterTest, OptionsRequestWithOriginCorsEnabledShadowDisabled) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestWithOriginCorsEnabledShadowEnabled) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "OPTIONS"}, {"origin", "test-host"}, {"access-control-request-method", "GET"}}; cors_policy_->shadow_enabled_ = true; - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"access-control-allow-origin", "test-host"}, {"access-control-allow-methods", "GET"}, @@ -301,15 +304,15 @@ TEST_F(CorsFilterTest, OptionsRequestWithOriginCorsEnabledShadowEnabled) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestNotMatchingOrigin) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "OPTIONS"}, {"origin", "test-host"}, {"access-control-request-method", "GET"}}; cors_policy_->allow_origins_.clear(); @@ -321,15 +324,15 @@ TEST_F(CorsFilterTest, OptionsRequestNotMatchingOrigin) { EXPECT_EQ(1, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(0, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestEmptyOriginList) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "OPTIONS"}, {"origin", "test-host"}, {"access-control-request-method", "GET"}}; cors_policy_->allow_origins_.clear(); @@ -340,22 +343,22 @@ TEST_F(CorsFilterTest, OptionsRequestEmptyOriginList) { EXPECT_EQ(1, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(0, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, ValidOptionsRequestWithAllowCredentialsTrue) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "OPTIONS"}, {"origin", "localhost"}, {"access-control-request-method", "GET"}}; cors_policy_->allow_credentials_ = true; cors_policy_->allow_origins_.clear(); cors_policy_->allow_origins_.emplace_back(makeExactStringMatcher("localhost")); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"access-control-allow-origin", "localhost"}, {"access-control-allow-credentials", "true"}, @@ -371,18 +374,18 @@ TEST_F(CorsFilterTest, ValidOptionsRequestWithAllowCredentialsTrue) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, ValidOptionsRequestWithAllowCredentialsFalse) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "OPTIONS"}, {"origin", "localhost"}, {"access-control-request-method", "GET"}}; - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"access-control-allow-origin", "localhost"}, {"access-control-allow-methods", "GET"}, @@ -397,11 +400,11 @@ TEST_F(CorsFilterTest, ValidOptionsRequestWithAllowCredentialsFalse) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, EncodeWithCorsDisabled) { @@ -410,108 +413,108 @@ TEST_F(CorsFilterTest, EncodeWithCorsDisabled) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{}; + Http::TestResponseHeaderMapImpl response_headers{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("", response_headers.get_("access-control-allow-origin")); EXPECT_EQ("", response_headers.get_("access-control-allow-credentials")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, EncodeNonCorsRequest) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{}; + Http::TestResponseHeaderMapImpl response_headers{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("", response_headers.get_("access-control-allow-origin")); EXPECT_EQ("", response_headers.get_("access-control-allow-credentials")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, EncodeWithAllowCredentialsTrue) { - Http::TestHeaderMapImpl request_headers{{"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{"origin", "localhost"}}; cors_policy_->allow_credentials_ = true; 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl continue_headers{{":status", "100"}}; + Http::TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encode100ContinueHeaders(continue_headers)); - Http::TestHeaderMapImpl response_headers{}; + Http::TestResponseHeaderMapImpl response_headers{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("localhost", response_headers.get_("access-control-allow-origin")); EXPECT_EQ("true", response_headers.get_("access-control-allow-credentials")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, EncodeWithExposeHeaders) { - Http::TestHeaderMapImpl request_headers{{"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{"origin", "localhost"}}; cors_policy_->expose_headers_ = "custom-header-1"; 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl continue_headers{{":status", "100"}}; + Http::TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encode100ContinueHeaders(continue_headers)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_.encodeMetadata(metadata_map)); - Http::TestHeaderMapImpl response_headers{}; + Http::TestResponseHeaderMapImpl response_headers{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("localhost", response_headers.get_("access-control-allow-origin")); EXPECT_EQ("custom-header-1", response_headers.get_("access-control-expose-headers")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, EncodeWithAllowCredentialsFalse) { - Http::TestHeaderMapImpl request_headers{{"origin", "localhost"}}; + Http::TestRequestHeaderMapImpl request_headers{{"origin", "localhost"}}; 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{}; + Http::TestResponseHeaderMapImpl response_headers{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("localhost", response_headers.get_("access-control-allow-origin")); EXPECT_EQ("", response_headers.get_("access-control-allow-credentials")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, EncodeWithNonMatchingOrigin) { - Http::TestHeaderMapImpl request_headers{{"origin", "test-host"}}; + Http::TestRequestHeaderMapImpl request_headers{{"origin", "test-host"}}; cors_policy_->allow_origins_.clear(); cors_policy_->allow_origins_.emplace_back(makeExactStringMatcher("localhost")); 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{}; + Http::TestResponseHeaderMapImpl response_headers{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("", response_headers.get_("access-control-allow-origin")); EXPECT_EQ("", response_headers.get_("access-control-allow-credentials")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, RedirectRoute) { @@ -521,15 +524,15 @@ TEST_F(CorsFilterTest, RedirectRoute) { EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers_, false)); EXPECT_EQ(false, IsCorsRequest()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{}; + Http::TestResponseHeaderMapImpl response_headers{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("", response_headers.get_("access-control-allow-origin")); EXPECT_EQ("", response_headers.get_("access-control-allow-credentials")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, EmptyRoute) { @@ -537,15 +540,15 @@ TEST_F(CorsFilterTest, EmptyRoute) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{}; + Http::TestResponseHeaderMapImpl response_headers{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("", response_headers.get_("access-control-allow-origin")); EXPECT_EQ("", response_headers.get_("access-control-allow-credentials")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, EmptyRouteEntry) { @@ -553,19 +556,19 @@ TEST_F(CorsFilterTest, EmptyRouteEntry) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{}; + Http::TestResponseHeaderMapImpl response_headers{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("", response_headers.get_("access-control-allow-origin")); EXPECT_EQ("", response_headers.get_("access-control-allow-credentials")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, NoCorsEntry) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "OPTIONS"}, {"origin", "localhost"}, {"access-control-request-method", "GET"}}; ON_CALL(decoder_callbacks_.route_->route_entry_, corsPolicy()).WillByDefault(Return(nullptr)); @@ -578,24 +581,24 @@ TEST_F(CorsFilterTest, NoCorsEntry) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(0, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{}; + Http::TestResponseHeaderMapImpl response_headers{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("", response_headers.get_("access-control-allow-origin")); EXPECT_EQ("", response_headers.get_("access-control-allow-credentials")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, NoRouteCorsEntry) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "OPTIONS"}, {"origin", "localhost"}, {"access-control-request-method", "GET"}}; ON_CALL(decoder_callbacks_.route_->route_entry_, corsPolicy()).WillByDefault(Return(nullptr)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"access-control-allow-origin", "localhost"}, {"access-control-allow-methods", "GET"}, @@ -610,15 +613,15 @@ TEST_F(CorsFilterTest, NoRouteCorsEntry) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, NoVHostCorsEntry) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "OPTIONS"}, {"origin", "localhost"}, {"access-control-request-method", "GET"}}; cors_policy_->allow_methods_ = ""; @@ -626,7 +629,7 @@ TEST_F(CorsFilterTest, NoVHostCorsEntry) { ON_CALL(decoder_callbacks_.route_->route_entry_.virtual_host_, corsPolicy()) .WillByDefault(Return(nullptr)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"access-control-allow-origin", "localhost"}, {"access-control-allow-headers", "content-type"}, @@ -640,19 +643,19 @@ TEST_F(CorsFilterTest, NoVHostCorsEntry) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestMatchingOriginByRegex) { - Http::TestHeaderMapImpl request_headers{{":method", "OPTIONS"}, - {"origin", "www.envoyproxy.io"}, - {"access-control-request-method", "GET"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "OPTIONS"}, + {"origin", "www.envoyproxy.io"}, + {"access-control-request-method", "GET"}}; - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"access-control-allow-origin", "www.envoyproxy.io"}, {"access-control-allow-methods", "GET"}, @@ -671,17 +674,17 @@ TEST_F(CorsFilterTest, OptionsRequestMatchingOriginByRegex) { EXPECT_EQ(0, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(1, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(CorsFilterTest, OptionsRequestNotMatchingOriginByRegex) { - Http::TestHeaderMapImpl request_headers{{":method", "OPTIONS"}, - {"origin", "www.envoyproxy.com"}, - {"access-control-request-method", "GET"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "OPTIONS"}, + {"origin", "www.envoyproxy.com"}, + {"access-control-request-method", "GET"}}; cors_policy_->allow_origins_.clear(); cors_policy_->allow_origins_.emplace_back(makeStdRegexStringMatcher(".*.envoyproxy.io")); @@ -692,11 +695,11 @@ TEST_F(CorsFilterTest, OptionsRequestNotMatchingOriginByRegex) { EXPECT_EQ(1, stats_.counter("test.cors.origin_invalid").value()); EXPECT_EQ(0, stats_.counter("test.cors.origin_valid").value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers_, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } } // namespace Cors diff --git a/test/extensions/filters/http/csrf/csrf_filter_integration_test.cc b/test/extensions/filters/http/csrf/csrf_filter_integration_test.cc index 5caf55d444..eb456c2a14 100644 --- a/test/extensions/filters/http/csrf/csrf_filter_integration_test.cc +++ b/test/extensions/filters/http/csrf/csrf_filter_integration_test.cc @@ -52,18 +52,19 @@ name: envoy.csrf class CsrfFilterIntegrationTest : public HttpProtocolIntegrationTest { protected: - IntegrationStreamDecoderPtr sendRequestAndWaitForResponse(Http::HeaderMap& request_headers) { + IntegrationStreamDecoderPtr + sendRequestAndWaitForResponse(Http::RequestHeaderMap& request_headers) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); auto response = codec_client_->makeRequestWithBody(request_headers, 1024); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); return response; } - IntegrationStreamDecoderPtr sendRequest(Http::TestHeaderMapImpl& request_headers) { + IntegrationStreamDecoderPtr sendRequest(Http::TestRequestHeaderMapImpl& request_headers) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); auto response = codec_client_->makeRequestWithBody(request_headers, 1024); @@ -79,7 +80,7 @@ INSTANTIATE_TEST_SUITE_P(Protocols, CsrfFilterIntegrationTest, TEST_P(CsrfFilterIntegrationTest, TestCsrfSuccess) { config_helper_.addFilter(CSRF_FILTER_ENABLED_CONFIG); - Http::TestHeaderMapImpl headers = {{ + Http::TestRequestHeaderMapImpl headers = {{ {":method", "PUT"}, {":path", "/"}, {":scheme", "http"}, @@ -93,7 +94,7 @@ TEST_P(CsrfFilterIntegrationTest, TestCsrfSuccess) { TEST_P(CsrfFilterIntegrationTest, TestCsrfDisabled) { config_helper_.addFilter(CSRF_DISABLED_CONFIG); - Http::TestHeaderMapImpl headers = {{ + Http::TestRequestHeaderMapImpl headers = {{ {":method", "PUT"}, {":path", "/"}, {":scheme", "http"}, @@ -107,7 +108,7 @@ TEST_P(CsrfFilterIntegrationTest, TestCsrfDisabled) { TEST_P(CsrfFilterIntegrationTest, TestNonMutationMethod) { config_helper_.addFilter(CSRF_FILTER_ENABLED_CONFIG); - Http::TestHeaderMapImpl headers = {{ + Http::TestRequestHeaderMapImpl headers = {{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -121,7 +122,7 @@ TEST_P(CsrfFilterIntegrationTest, TestNonMutationMethod) { TEST_P(CsrfFilterIntegrationTest, TestOriginMismatch) { config_helper_.addFilter(CSRF_FILTER_ENABLED_CONFIG); - Http::TestHeaderMapImpl headers = {{ + Http::TestRequestHeaderMapImpl headers = {{ {":method", "PUT"}, {":path", "/"}, {":scheme", "http"}, @@ -135,7 +136,7 @@ TEST_P(CsrfFilterIntegrationTest, TestOriginMismatch) { TEST_P(CsrfFilterIntegrationTest, TestEnforcesPost) { config_helper_.addFilter(CSRF_FILTER_ENABLED_CONFIG); - Http::TestHeaderMapImpl headers = {{ + Http::TestRequestHeaderMapImpl headers = {{ {":method", "POST"}, {":path", "/"}, {":scheme", "http"}, @@ -149,7 +150,7 @@ TEST_P(CsrfFilterIntegrationTest, TestEnforcesPost) { TEST_P(CsrfFilterIntegrationTest, TestEnforcesDelete) { config_helper_.addFilter(CSRF_FILTER_ENABLED_CONFIG); - Http::TestHeaderMapImpl headers = {{ + Http::TestRequestHeaderMapImpl headers = {{ {":method", "DELETE"}, {":path", "/"}, {":scheme", "http"}, @@ -163,7 +164,7 @@ TEST_P(CsrfFilterIntegrationTest, TestEnforcesDelete) { TEST_P(CsrfFilterIntegrationTest, TestEnforcesPatch) { config_helper_.addFilter(CSRF_FILTER_ENABLED_CONFIG); - Http::TestHeaderMapImpl headers = {{ + Http::TestRequestHeaderMapImpl headers = {{ {":method", "PATCH"}, {":path", "/"}, {":scheme", "http"}, @@ -177,11 +178,11 @@ TEST_P(CsrfFilterIntegrationTest, TestEnforcesPatch) { TEST_P(CsrfFilterIntegrationTest, TestRefererFallback) { config_helper_.addFilter(CSRF_FILTER_ENABLED_CONFIG); - Http::TestHeaderMapImpl headers = {{":method", "DELETE"}, - {":path", "/"}, - {":scheme", "http"}, - {"referer", "test-origin"}, - {"host", "test-origin"}}; + Http::TestRequestHeaderMapImpl headers = {{":method", "DELETE"}, + {":path", "/"}, + {":scheme", "http"}, + {"referer", "test-origin"}, + {"host", "test-origin"}}; const auto& response = sendRequestAndWaitForResponse(headers); EXPECT_TRUE(response->complete()); EXPECT_EQ(response->headers().Status()->value().getStringView(), "200"); @@ -189,7 +190,7 @@ TEST_P(CsrfFilterIntegrationTest, TestRefererFallback) { TEST_P(CsrfFilterIntegrationTest, TestMissingOrigin) { config_helper_.addFilter(CSRF_FILTER_ENABLED_CONFIG); - Http::TestHeaderMapImpl headers = { + Http::TestRequestHeaderMapImpl headers = { {{":method", "DELETE"}, {":path", "/"}, {":scheme", "http"}, {"host", "test-origin"}}}; const auto& response = sendRequest(headers); EXPECT_TRUE(response->complete()); @@ -198,7 +199,7 @@ TEST_P(CsrfFilterIntegrationTest, TestMissingOrigin) { TEST_P(CsrfFilterIntegrationTest, TestShadowOnlyMode) { config_helper_.addFilter(CSRF_SHADOW_ENABLED_CONFIG); - Http::TestHeaderMapImpl headers = {{ + Http::TestRequestHeaderMapImpl headers = {{ {":method", "PUT"}, {":path", "/"}, {":scheme", "http"}, @@ -212,7 +213,7 @@ TEST_P(CsrfFilterIntegrationTest, TestShadowOnlyMode) { TEST_P(CsrfFilterIntegrationTest, TestFilterAndShadowEnabled) { config_helper_.addFilter(CSRF_ENABLED_CONFIG); - Http::TestHeaderMapImpl headers = {{ + Http::TestRequestHeaderMapImpl headers = {{ {":method", "PUT"}, {":path", "/"}, {":scheme", "http"}, diff --git a/test/extensions/filters/http/csrf/csrf_filter_test.cc b/test/extensions/filters/http/csrf/csrf_filter_test.cc index ab90793909..970e94684e 100644 --- a/test/extensions/filters/http/csrf/csrf_filter_test.cc +++ b/test/extensions/filters/http/csrf/csrf_filter_test.cc @@ -93,6 +93,7 @@ class CsrfFilterTest : public testing::Test { CsrfFilter filter_; Http::TestRequestHeaderMapImpl request_headers_; + Http::TestRequestTrailerMapImpl request_trailers_; }; TEST_F(CsrfFilterTest, RequestWithNonMutableMethod) { @@ -102,7 +103,7 @@ TEST_F(CsrfFilterTest, RequestWithNonMutableMethod) { EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_.decodeMetadata(metadata_map)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(0U, config_->stats().request_invalid_.value()); @@ -115,7 +116,7 @@ TEST_F(CsrfFilterTest, RequestWithoutOrigin) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(1U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(0U, config_->stats().request_invalid_.value()); @@ -128,7 +129,7 @@ TEST_F(CsrfFilterTest, RequestWithoutDestination) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(1U, config_->stats().request_invalid_.value()); @@ -139,7 +140,7 @@ TEST_F(CsrfFilterTest, RequestWithInvalidOrigin) { Http::TestRequestHeaderMapImpl request_headers{ {":method", "PUT"}, {"origin", "cross-origin"}, {":authority", "localhost"}}; - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "403"}, {"content-length", "14"}, {"content-type", "text/plain"}, @@ -149,7 +150,7 @@ TEST_F(CsrfFilterTest, RequestWithInvalidOrigin) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(1U, config_->stats().request_invalid_.value()); @@ -163,7 +164,7 @@ TEST_F(CsrfFilterTest, RequestWithValidOrigin) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(0U, config_->stats().request_invalid_.value()); @@ -179,7 +180,7 @@ TEST_F(CsrfFilterTest, RequestWithInvalidOriginCsrfDisabledShadowDisabled) { EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(0U, config_->stats().request_invalid_.value()); @@ -195,7 +196,7 @@ TEST_F(CsrfFilterTest, RequestWithInvalidOriginCsrfDisabledShadowEnabled) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(1U, config_->stats().request_invalid_.value()); @@ -211,7 +212,7 @@ TEST_F(CsrfFilterTest, RequestWithValidOriginCsrfDisabledShadowEnabled) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(0U, config_->stats().request_invalid_.value()); @@ -224,7 +225,7 @@ TEST_F(CsrfFilterTest, RequestWithInvalidOriginCsrfEnabledShadowEnabled) { setShadowEnabled(true); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "403"}, {"content-length", "14"}, {"content-type", "text/plain"}, @@ -234,7 +235,7 @@ TEST_F(CsrfFilterTest, RequestWithInvalidOriginCsrfEnabledShadowEnabled) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(1U, config_->stats().request_invalid_.value()); @@ -249,7 +250,7 @@ TEST_F(CsrfFilterTest, RequestWithValidOriginCsrfEnabledShadowEnabled) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(0U, config_->stats().request_invalid_.value()); @@ -262,7 +263,7 @@ TEST_F(CsrfFilterTest, RedirectRoute) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(0U, config_->stats().request_invalid_.value()); @@ -274,7 +275,7 @@ TEST_F(CsrfFilterTest, EmptyRoute) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(0U, config_->stats().request_invalid_.value()); @@ -286,7 +287,7 @@ TEST_F(CsrfFilterTest, EmptyRouteEntry) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(0U, config_->stats().request_invalid_.value()); @@ -303,7 +304,7 @@ TEST_F(CsrfFilterTest, NoCsrfEntry) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(1U, config_->stats().request_invalid_.value()); EXPECT_EQ(0U, config_->stats().request_valid_.value()); @@ -317,7 +318,7 @@ TEST_F(CsrfFilterTest, NoRouteCsrfEntry) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(1U, config_->stats().request_invalid_.value()); @@ -332,7 +333,7 @@ TEST_F(CsrfFilterTest, NoVHostCsrfEntry) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(1U, config_->stats().request_invalid_.value()); @@ -344,7 +345,7 @@ TEST_F(CsrfFilterTest, RequestFromAdditionalExactOrigin) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(0U, config_->stats().request_invalid_.value()); @@ -356,7 +357,7 @@ TEST_F(CsrfFilterTest, RequestFromAdditionalRegexOrigin) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(0U, config_->stats().request_invalid_.value()); @@ -369,7 +370,7 @@ TEST_F(CsrfFilterTest, RequestFromInvalidAdditionalRegexOrigin) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ(0U, config_->stats().missing_source_origin_.value()); EXPECT_EQ(1U, config_->stats().request_invalid_.value()); diff --git a/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc b/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc index 91d06ed17c..34929ab5fa 100644 --- a/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc +++ b/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_integration_test.cc @@ -134,7 +134,7 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, ProxyFilterIntegrationTest, TEST_P(ProxyFilterIntegrationTest, RequestWithBody) { setup(); codec_client_ = makeHttpConnection(lookupPort("http")); - const Http::TestHeaderMapImpl request_headers{ + const Http::TestRequestHeaderMapImpl request_headers{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, @@ -159,7 +159,7 @@ TEST_P(ProxyFilterIntegrationTest, RequestWithBody) { TEST_P(ProxyFilterIntegrationTest, ReloadClusterAndAttachToCache) { setup(); codec_client_ = makeHttpConnection(lookupPort("http")); - const Http::TestHeaderMapImpl request_headers{ + const Http::TestRequestHeaderMapImpl request_headers{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, @@ -195,7 +195,7 @@ TEST_P(ProxyFilterIntegrationTest, ReloadClusterAndAttachToCache) { TEST_P(ProxyFilterIntegrationTest, RemoveHostViaTTL) { setup(); codec_client_ = makeHttpConnection(lookupPort("http")); - const Http::TestHeaderMapImpl request_headers{ + const Http::TestRequestHeaderMapImpl request_headers{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, @@ -221,7 +221,7 @@ TEST_P(ProxyFilterIntegrationTest, DNSCacheHostOverflow) { setup(1); codec_client_ = makeHttpConnection(lookupPort("http")); - const Http::TestHeaderMapImpl request_headers{ + const Http::TestRequestHeaderMapImpl request_headers{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, @@ -233,7 +233,7 @@ TEST_P(ProxyFilterIntegrationTest, DNSCacheHostOverflow) { checkSimpleRequestSuccess(1024, 1024, response.get()); // Send another request, this should lead to a response directly from the filter. - const Http::TestHeaderMapImpl request_headers2{ + const Http::TestRequestHeaderMapImpl request_headers2{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, @@ -249,7 +249,7 @@ TEST_P(ProxyFilterIntegrationTest, UpstreamTls) { upstream_tls_ = true; setup(); codec_client_ = makeHttpConnection(lookupPort("http")); - const Http::TestHeaderMapImpl request_headers{ + const Http::TestRequestHeaderMapImpl request_headers{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, @@ -274,7 +274,7 @@ TEST_P(ProxyFilterIntegrationTest, UpstreamTlsWithIpHost) { upstream_tls_ = true; setup(); codec_client_ = makeHttpConnection(lookupPort("http")); - const Http::TestHeaderMapImpl request_headers{ + const Http::TestRequestHeaderMapImpl request_headers{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, @@ -306,7 +306,7 @@ TEST_P(ProxyFilterIntegrationTest, UpstreamTlsInvalidSAN) { fake_upstreams_[0]->setReadDisableOnNewConnection(false); codec_client_ = makeHttpConnection(lookupPort("http")); - const Http::TestHeaderMapImpl request_headers{ + const Http::TestRequestHeaderMapImpl request_headers{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, diff --git a/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_test.cc b/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_test.cc index 7c0e69f312..17dd35d8cd 100644 --- a/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_test.cc +++ b/test/extensions/filters/http/dynamic_forward_proxy/proxy_filter_test.cc @@ -64,7 +64,7 @@ class ProxyFilterTest : public testing::Test, ProxyFilterConfigSharedPtr filter_config_; std::unique_ptr filter_; Http::MockStreamDecoderFilterCallbacks callbacks_; - Http::TestHeaderMapImpl request_headers_{{":authority", "foo"}}; + Http::TestRequestHeaderMapImpl request_headers_{{":authority", "foo"}}; }; // Default port 80 if upstream TLS not configured. @@ -215,7 +215,7 @@ TEST_F(ProxyFilterTest, HostRewriteViaHeader) { EXPECT_CALL(*dns_cache_manager_->dns_cache_, loadDnsCacheEntry_(Eq("bar:82"), 80, _)) .WillOnce(Return(MockLoadDnsCacheEntryResult{LoadDnsCacheEntryStatus::Loading, handle})); - Http::TestHeaderMapImpl headers{{":authority", "foo"}, {"x-set-header", "bar:82"}}; + Http::TestRequestHeaderMapImpl headers{{":authority", "foo"}, {"x-set-header", "bar:82"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, filter_->decodeHeaders(headers, false)); diff --git a/test/extensions/filters/http/dynamo/dynamo_filter_test.cc b/test/extensions/filters/http/dynamo/dynamo_filter_test.cc index c6db226c64..b3a07ed7f6 100644 --- a/test/extensions/filters/http/dynamo/dynamo_filter_test.cc +++ b/test/extensions/filters/http/dynamo/dynamo_filter_test.cc @@ -49,12 +49,14 @@ class DynamoFilterTest : public testing::Test { std::string stat_prefix_{"prefix."}; NiceMock decoder_callbacks_; NiceMock encoder_callbacks_; + Http::TestRequestTrailerMapImpl request_trailers_; }; TEST_F(DynamoFilterTest, operatorPresent) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.Get"}, {"random", "random"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.Get"}, + {"random", "random"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, true)); @@ -62,11 +64,11 @@ TEST_F(DynamoFilterTest, operatorPresent) { EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->decodeMetadata(metadata_map)); EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->encodeMetadata(metadata_map)); - Http::TestHeaderMapImpl continue_headers{{":status", "100"}}; + Http::TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(continue_headers)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(stats_, counter("prefix.dynamodb.operation_missing")).Times(0); EXPECT_CALL(stats_, counter("prefix.dynamodb.table_missing")); @@ -99,8 +101,8 @@ TEST_F(DynamoFilterTest, operatorPresent) { TEST_F(DynamoFilterTest, jsonBodyNotWellFormed) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.GetItem"}, - {"random", "random"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.GetItem"}, + {"random", "random"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -115,28 +117,28 @@ TEST_F(DynamoFilterTest, jsonBodyNotWellFormed) { TEST_F(DynamoFilterTest, bothOperationAndTableIncorrect) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version"}, {"random", "random"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version"}, {"random", "random"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, true)); EXPECT_CALL(stats_, counter("prefix.dynamodb.operation_missing")); EXPECT_CALL(stats_, counter("prefix.dynamodb.table_missing")); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, true)); } TEST_F(DynamoFilterTest, handleErrorTypeTableMissing) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version"}, {"random", "random"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version"}, {"random", "random"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, true)); EXPECT_CALL(stats_, counter("prefix.dynamodb.operation_missing")); EXPECT_CALL(stats_, counter("prefix.dynamodb.table_missing")); - Http::TestHeaderMapImpl response_headers{{":status", "400"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "400"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->encodeHeaders(response_headers, false)); @@ -154,14 +156,15 @@ TEST_F(DynamoFilterTest, handleErrorTypeTableMissing) { EXPECT_CALL(stats_, counter("prefix.dynamodb.invalid_resp_body")); EXPECT_CALL(stats_, counter("prefix.dynamodb.operation_missing")); EXPECT_CALL(stats_, counter("prefix.dynamodb.table_missing")); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(request_headers)); + Http::TestResponseTrailerMapImpl response_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers)); } TEST_F(DynamoFilterTest, HandleErrorTypeTablePresent) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.GetItem"}, - {"random", "random"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.GetItem"}, + {"random", "random"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -170,7 +173,7 @@ TEST_F(DynamoFilterTest, HandleErrorTypeTablePresent) { buffer.add(buffer_content); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(buffer, true)); - Http::TestHeaderMapImpl response_headers{{":status", "400"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "400"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->encodeHeaders(response_headers, false)); @@ -232,8 +235,8 @@ TEST_F(DynamoFilterTest, HandleErrorTypeTablePresent) { TEST_F(DynamoFilterTest, BatchMultipleTables) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}, - {"random", "random"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}, + {"random", "random"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -250,9 +253,9 @@ TEST_F(DynamoFilterTest, BatchMultipleTables) { EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(*buffer, false)); EXPECT_CALL(decoder_callbacks_, decodingBuffer()).WillRepeatedly(Return(buffer.get())); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(stats_, counter("prefix.dynamodb.multiple_tables")); EXPECT_CALL(stats_, counter("prefix.dynamodb.operation.BatchGetItem.upstream_rq_total")); @@ -284,8 +287,8 @@ TEST_F(DynamoFilterTest, BatchMultipleTables) { TEST_F(DynamoFilterTest, BatchMultipleTablesUnprocessedKeys) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}, - {"random", "random"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}, + {"random", "random"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -302,9 +305,9 @@ TEST_F(DynamoFilterTest, BatchMultipleTablesUnprocessedKeys) { EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(*buffer, false)); EXPECT_CALL(decoder_callbacks_, decodingBuffer()).WillRepeatedly(Return(buffer.get())); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(stats_, counter("prefix.dynamodb.multiple_tables")); EXPECT_CALL(stats_, counter("prefix.dynamodb.operation.BatchGetItem.upstream_rq_total")); @@ -354,8 +357,8 @@ TEST_F(DynamoFilterTest, BatchMultipleTablesUnprocessedKeys) { TEST_F(DynamoFilterTest, BatchMultipleTablesNoUnprocessedKeys) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}, - {"random", "random"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}, + {"random", "random"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -372,9 +375,9 @@ TEST_F(DynamoFilterTest, BatchMultipleTablesNoUnprocessedKeys) { EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(*buffer, false)); EXPECT_CALL(decoder_callbacks_, decodingBuffer()).WillRepeatedly(Return(buffer.get())); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(stats_, counter("prefix.dynamodb.multiple_tables")); EXPECT_CALL(stats_, counter("prefix.dynamodb.operation.BatchGetItem.upstream_rq_total")); @@ -420,8 +423,8 @@ TEST_F(DynamoFilterTest, BatchMultipleTablesNoUnprocessedKeys) { TEST_F(DynamoFilterTest, BatchMultipleTablesInvalidResponseBody) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}, - {"random", "random"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}, + {"random", "random"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -438,9 +441,9 @@ TEST_F(DynamoFilterTest, BatchMultipleTablesInvalidResponseBody) { EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(*buffer, false)); EXPECT_CALL(decoder_callbacks_, decodingBuffer()).WillRepeatedly(Return(buffer.get())); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(stats_, counter("prefix.dynamodb.multiple_tables")); EXPECT_CALL(stats_, counter("prefix.dynamodb.operation.BatchGetItem.upstream_rq_total")); @@ -490,7 +493,7 @@ TEST_F(DynamoFilterTest, BatchMultipleTablesInvalidResponseBody) { TEST_F(DynamoFilterTest, bothOperationAndTableCorrect) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.GetItem"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.GetItem"}}; Buffer::InstancePtr buffer(new Buffer::OwnedImpl()); std::string buffer_content = "{\"TableName\":\"locations\""; buffer->add(buffer_content); @@ -549,7 +552,7 @@ TEST_F(DynamoFilterTest, bothOperationAndTableCorrect) { deliverHistogramToSinks( Property(&Stats::Metric::name, "prefix.dynamodb.table.locations.upstream_rq_time"), _)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, true)); } @@ -559,19 +562,20 @@ TEST_F(DynamoFilterTest, operatorPresentRuntimeDisabled) { EXPECT_CALL(stats_, counter(_)).Times(0); EXPECT_CALL(stats_, deliverHistogramToSinks(_, _)).Times(0); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.operator"}, - {"random", "random"}}; - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.operator"}, + {"random", "random"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, true)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers)); + Http::TestResponseTrailerMapImpl response_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers)); } TEST_F(DynamoFilterTest, PartitionIdStats) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.GetItem"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.GetItem"}}; Buffer::InstancePtr buffer(new Buffer::OwnedImpl()); std::string buffer_content = "{\"TableName\":\"locations\""; buffer->add(buffer_content); @@ -637,7 +641,7 @@ TEST_F(DynamoFilterTest, PartitionIdStats) { counter("prefix.dynamodb.table.locations.capacity.GetItem.__partition_id=ition_2")) .Times(1); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->encodeHeaders(response_headers, false)); @@ -663,7 +667,7 @@ TEST_F(DynamoFilterTest, PartitionIdStats) { TEST_F(DynamoFilterTest, NoPartitionIdStatsForMultipleTables) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}}; Buffer::InstancePtr buffer(new Buffer::OwnedImpl()); std::string buffer_content = R"EOF( { @@ -679,7 +683,7 @@ TEST_F(DynamoFilterTest, NoPartitionIdStatsForMultipleTables) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(*buffer, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_CALL(stats_, counter("prefix.dynamodb.multiple_tables")); @@ -715,7 +719,7 @@ TEST_F(DynamoFilterTest, NoPartitionIdStatsForMultipleTables) { counter("prefix.dynamodb.table.locations.capacity.BatchGetItem.__partition_id=ition_2")) .Times(0); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->encodeHeaders(response_headers, false)); @@ -741,7 +745,7 @@ TEST_F(DynamoFilterTest, NoPartitionIdStatsForMultipleTables) { TEST_F(DynamoFilterTest, PartitionIdStatsForSingleTableBatchOperation) { setup(true); - Http::TestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-amz-target", "version.BatchGetItem"}}; Buffer::InstancePtr buffer(new Buffer::OwnedImpl()); std::string buffer_content = R"EOF( { @@ -756,7 +760,7 @@ TEST_F(DynamoFilterTest, PartitionIdStatsForSingleTableBatchOperation) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(*buffer, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_CALL(stats_, counter("prefix.dynamodb.multiple_tables")).Times(0); @@ -815,7 +819,7 @@ TEST_F(DynamoFilterTest, PartitionIdStatsForSingleTableBatchOperation) { counter("prefix.dynamodb.table.locations.capacity.BatchGetItem.__partition_id=ition_2")) .Times(1); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->encodeHeaders(response_headers, false)); diff --git a/test/extensions/filters/http/ext_authz/ext_authz_integration_test.cc b/test/extensions/filters/http/ext_authz/ext_authz_integration_test.cc index 38f45af9d6..0caf78bdf1 100644 --- a/test/extensions/filters/http/ext_authz/ext_authz_integration_test.cc +++ b/test/extensions/filters/http/ext_authz/ext_authz_integration_test.cc @@ -53,7 +53,7 @@ class ExtAuthzGrpcIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, void initiateClientConnection(uint64_t request_body_length) { auto conn = makeClientConnection(lookupPort("http")); codec_client_ = makeHttpConnection(std::move(conn)); - Http::TestHeaderMapImpl headers{ + Http::TestRequestHeaderMapImpl headers{ {":method", "POST"}, {":path", "/test"}, {":scheme", "http"}, {":authority", "host"}}; TestUtility::feedBufferWithRandomCharacters(request_body_, request_body_length); response_ = codec_client_->makeRequestWithBody(headers, request_body_.toString()); @@ -109,7 +109,7 @@ class ExtAuthzGrpcIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, result = upstream_request_->waitForEndStream(*dispatcher_); RELEASE_ASSERT(result, result.message()); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_request_->encodeData(response_size_, true); response_->waitForEndStream(); 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 3d9e9f61f7..7aa8ed4200 100644 --- a/test/extensions/filters/http/ext_authz/ext_authz_test.cc +++ b/test/extensions/filters/http/ext_authz/ext_authz_test.cc @@ -73,7 +73,8 @@ template class HttpFilterTestBase : public T { std::unique_ptr filter_; NiceMock filter_callbacks_; Filters::Common::ExtAuthz::RequestCallbacks* request_callbacks_; - Http::TestHeaderMapImpl request_headers_; + Http::TestRequestHeaderMapImpl request_headers_; + Http::TestRequestTrailerMapImpl request_trailers_; Buffer::OwnedImpl data_; NiceMock runtime_; NiceMock cm_; @@ -295,7 +296,7 @@ TEST_F(HttpFilterTest, ImmediateErrorOpen) { EXPECT_CALL(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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(1U, filter_callbacks_.clusterInfo()->statsScope().counter("ext_authz.error").value()); EXPECT_EQ(1U, filter_callbacks_.clusterInfo() ->statsScope() @@ -387,7 +388,7 @@ TEST_F(HttpFilterTest, RequestDataWithPartialMessage) { data_.add("more data after watermark is set is possible"); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndWatermark, filter_->decodeData(data_, true)); - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers_)); } // Checks that the filter initiates the authorization process only when the filter decode trailers @@ -417,7 +418,7 @@ TEST_F(HttpFilterTest, RequestDataWithSmallBuffer) { data_.add("foo"); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers_)); } // Checks that the filter buffers the data and initiates the authorization request. @@ -445,7 +446,7 @@ TEST_F(HttpFilterTest, AuthWithRequestData) { EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data_, false)); data_.add("bar"); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndWatermark, filter_->decodeData(data_, true)); - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers_)); } // Checks that filter does not buffer data on header-only request. @@ -553,7 +554,7 @@ TEST_F(HttpFilterTest, HeaderOnlyRequestWithStream) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers_)); } // Verifies that the filter clears the route cache when an authorization response: @@ -581,7 +582,7 @@ TEST_F(HttpFilterTest, ClearCache) { EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, filter_->decodeHeaders(request_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_CALL(filter_callbacks_, continueDecoding()); EXPECT_CALL(filter_callbacks_.stream_info_, setResponseFlag(Envoy::StreamInfo::ResponseFlag::UnauthorizedExternalService)) @@ -621,7 +622,7 @@ TEST_F(HttpFilterTest, ClearCacheRouteHeadersToAppendOnly) { EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, filter_->decodeHeaders(request_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_CALL(filter_callbacks_, continueDecoding()); EXPECT_CALL(filter_callbacks_.stream_info_, setResponseFlag(Envoy::StreamInfo::ResponseFlag::UnauthorizedExternalService)) @@ -660,7 +661,7 @@ TEST_F(HttpFilterTest, ClearCacheRouteHeadersToAddOnly) { EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, filter_->decodeHeaders(request_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_CALL(filter_callbacks_, continueDecoding()); EXPECT_CALL(filter_callbacks_.stream_info_, setResponseFlag(Envoy::StreamInfo::ResponseFlag::UnauthorizedExternalService)) @@ -698,7 +699,7 @@ TEST_F(HttpFilterTest, NoClearCacheRoute) { EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, filter_->decodeHeaders(request_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_CALL(filter_callbacks_, continueDecoding()); EXPECT_CALL(filter_callbacks_.stream_info_, setResponseFlag(Envoy::StreamInfo::ResponseFlag::UnauthorizedExternalService)) @@ -732,7 +733,7 @@ TEST_F(HttpFilterTest, NoClearCacheRouteConfig) { EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, filter_->decodeHeaders(request_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_CALL(filter_callbacks_, continueDecoding()); EXPECT_CALL(filter_callbacks_.stream_info_, setResponseFlag(Envoy::StreamInfo::ResponseFlag::UnauthorizedExternalService)) @@ -776,7 +777,7 @@ TEST_F(HttpFilterTest, NoClearCacheRouteDeniedResponse) { EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, filter_->decodeHeaders(request_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(1U, config_->stats().denied_.value()); EXPECT_EQ(1U, filter_callbacks_.clusterInfo()->statsScope().counter("ext_authz.denied").value()); EXPECT_EQ("ext_authz_denied", filter_callbacks_.details_); @@ -979,7 +980,7 @@ TEST_F(HttpFilterTestParam, NoRoute) { EXPECT_CALL(*filter_callbacks_.route_, routeEntry()).WillOnce(Return(nullptr)); 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); } // Test that the request is stopped till there is an OK response back after which it continues on. @@ -1008,7 +1009,7 @@ TEST_F(HttpFilterTestParam, OkResponse) { EXPECT_EQ(1U, config_->stats().ok_.value()); // decodeData() and decodeTrailers() are called after continueDecoding(). EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); } // Test that an synchronous OK response from the authorization service, on the call stack, results @@ -1029,7 +1030,7 @@ TEST_F(HttpFilterTestParam, ImmediateOkResponse) { EXPECT_CALL(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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(1U, filter_callbacks_.clusterInfo()->statsScope().counter("ext_authz.ok").value()); EXPECT_EQ(1U, config_->stats().ok_.value()); } @@ -1096,8 +1097,8 @@ TEST_F(HttpFilterTestParam, ImmediateOkResponseWithHttpAttributes) { EXPECT_CALL(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_headers_)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(request_headers_.get_(request_header_key), "foo,bar"); EXPECT_EQ(request_headers_.get_(key_to_add), "foo"); EXPECT_EQ(request_headers_.get_(key_to_override), "bar"); @@ -1139,7 +1140,7 @@ TEST_F(HttpFilterTestParam, DeniedResponseWith401) { EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, filter_->decodeHeaders(request_headers_, false)); - Http::TestHeaderMapImpl response_headers{{":status", "401"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "401"}}; EXPECT_CALL(filter_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); EXPECT_CALL(filter_callbacks_, continueDecoding()).Times(0); EXPECT_CALL(filter_callbacks_.stream_info_, @@ -1167,7 +1168,7 @@ TEST_F(HttpFilterTestParam, DeniedResponseWith403) { EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, filter_->decodeHeaders(request_headers_, false)); - Http::TestHeaderMapImpl response_headers{{":status", "403"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "403"}}; EXPECT_CALL(filter_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); EXPECT_CALL(filter_callbacks_, continueDecoding()).Times(0); EXPECT_CALL(filter_callbacks_.stream_info_, @@ -1205,11 +1206,11 @@ TEST_F(HttpFilterTestParam, DestroyResponseBeforeSendLocalReply) { EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, filter_->decodeHeaders(request_headers_, false)); - Http::TestHeaderMapImpl response_headers{{":status", "403"}, - {"content-length", "3"}, - {"content-type", "text/plain"}, - {"foo", "bar"}, - {"bar", "foo"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "403"}, + {"content-length", "3"}, + {"content-type", "text/plain"}, + {"foo", "bar"}, + {"bar", "foo"}}; Http::HeaderMap* saved_headers; EXPECT_CALL(filter_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)) .WillOnce(Invoke([&](Http::HeaderMap& headers, bool) { saved_headers = &headers; })); @@ -1258,15 +1259,15 @@ TEST_F(HttpFilterTestParam, OverrideEncodingHeaders) { EXPECT_EQ(Http::FilterHeadersStatus::StopAllIterationAndWatermark, filter_->decodeHeaders(request_headers_, false)); - Http::TestHeaderMapImpl response_headers{{":status", "403"}, - {"content-length", "3"}, - {"content-type", "text/plain"}, - {"foo", "bar"}, - {"bar", "foo"}, - {"set-cookie", "cookie1=value"}, - {"set-cookie", "cookie2=value"}, - {"accept-encoding", "gzip"}, - {"accept-encoding", "deflate"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "403"}, + {"content-length", "3"}, + {"content-type", "text/plain"}, + {"foo", "bar"}, + {"bar", "foo"}, + {"set-cookie", "cookie1=value"}, + {"set-cookie", "cookie2=value"}, + {"accept-encoding", "gzip"}, + {"accept-encoding", "deflate"}}; Http::HeaderMap* saved_headers; EXPECT_CALL(filter_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)) .WillOnce(Invoke([&](Http::HeaderMap& headers, bool) { diff --git a/test/extensions/filters/http/fault/fault_filter_integration_test.cc b/test/extensions/filters/http/fault/fault_filter_integration_test.cc index d60e36bb8f..addece0930 100644 --- a/test/extensions/filters/http/fault/fault_filter_integration_test.cc +++ b/test/extensions/filters/http/fault/fault_filter_integration_test.cc @@ -96,12 +96,12 @@ TEST_P(FaultIntegrationTestAllProtocols, ResponseRateLimitNoTrailers) { TEST_P(FaultIntegrationTestAllProtocols, HeaderFaultConfig) { initializeFilter(header_fault_config_); codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-envoy-fault-delay-request", "200"}, - {"x-envoy-fault-throughput-response", "1"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-envoy-fault-delay-request", "200"}, + {"x-envoy-fault-throughput-response", "1"}}; const auto current_time = simTime().monotonicTime(); IntegrationStreamDecoderPtr decoder = codec_client_->makeHeaderOnlyRequest(request_headers); waitForNextUpstreamRequest(); diff --git a/test/extensions/filters/http/fault/fault_filter_test.cc b/test/extensions/filters/http/fault/fault_filter_test.cc index 6efe195e60..8d2f25904d 100644 --- a/test/extensions/filters/http/fault/fault_filter_test.cc +++ b/test/extensions/filters/http/fault/fault_filter_test.cc @@ -144,8 +144,10 @@ class FaultFilterTest : public testing::Test { std::unique_ptr filter_; NiceMock decoder_filter_callbacks_; NiceMock encoder_filter_callbacks_; - Http::TestHeaderMapImpl request_headers_; - Http::TestHeaderMapImpl response_headers_; + Http::TestRequestHeaderMapImpl request_headers_; + Http::TestRequestTrailerMapImpl request_trailers_; + Http::TestResponseHeaderMapImpl response_headers_; + Http::TestResponseTrailerMapImpl response_trailers_; Buffer::OwnedImpl data_; NiceMock runtime_; Event::MockTimer* timer_{}; @@ -246,7 +248,7 @@ TEST_F(FaultFilterTest, AbortWithHttpStatus) { EXPECT_CALL(runtime_.snapshot_, getInteger("fault.http.abort.http_status", 429)) .WillOnce(Return(429)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "429"}, {"content-length", "18"}, {"content-type", "text/plain"}}; EXPECT_CALL(decoder_filter_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); @@ -261,7 +263,7 @@ TEST_F(FaultFilterTest, AbortWithHttpStatus) { EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->decodeMetadata(metadata_map)); EXPECT_EQ(1UL, config_->stats().active_faults_.value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); filter_->onDestroy(); EXPECT_EQ(0UL, config_->stats().delays_injected_.value()); @@ -301,7 +303,7 @@ TEST_F(FaultFilterTest, FixedDelayZeroDuration) { // Expect filter to continue execution when delay is 0ms 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(0UL, config_->stats().delays_injected_.value()); EXPECT_EQ(0UL, config_->stats().aborts_injected_.value()); @@ -363,7 +365,7 @@ TEST_F(FaultFilterTest, FixedDelayDeprecatedPercentAndNonZeroDuration) { .Times(0); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndWatermark, filter_->decodeData(data_, false)); EXPECT_EQ(1UL, config_->stats().active_faults_.value()); - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers_)); EXPECT_CALL(decoder_filter_callbacks_, continueDecoding()); timer_->invokeCallback(); filter_->onDestroy(); @@ -418,7 +420,7 @@ TEST_F(FaultFilterTest, DelayForDownstreamCluster) { EXPECT_CALL(decoder_filter_callbacks_.dispatcher_, setTrackedObject(_)).Times(2); timer_->invokeCallback(); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(1UL, config_->stats().delays_injected_.value()); EXPECT_EQ(0UL, config_->stats().aborts_injected_.value()); @@ -466,7 +468,7 @@ TEST_F(FaultFilterTest, FixedDelayAndAbortDownstream) { EXPECT_CALL(runtime_.snapshot_, getInteger("fault.http.cluster.abort.http_status", 503)) .WillOnce(Return(500)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "500"}, {"content-length", "18"}, {"content-type", "text/plain"}}; EXPECT_CALL(decoder_filter_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); @@ -479,7 +481,7 @@ TEST_F(FaultFilterTest, FixedDelayAndAbortDownstream) { timer_->invokeCallback(); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(1UL, config_->stats().active_faults_.value()); filter_->onDestroy(); @@ -524,7 +526,7 @@ TEST_F(FaultFilterTest, FixedDelayAndAbort) { EXPECT_CALL(runtime_.snapshot_, getInteger("fault.http.abort.http_status", 503)) .WillOnce(Return(503)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "503"}, {"content-length", "18"}, {"content-type", "text/plain"}}; EXPECT_CALL(decoder_filter_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); @@ -538,7 +540,7 @@ TEST_F(FaultFilterTest, FixedDelayAndAbort) { timer_->invokeCallback(); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(1UL, config_->stats().delays_injected_.value()); EXPECT_EQ(1UL, config_->stats().aborts_injected_.value()); @@ -576,7 +578,7 @@ TEST_F(FaultFilterTest, FixedDelayAndAbortDownstreamNodes) { EXPECT_CALL(runtime_.snapshot_, getInteger("fault.http.abort.http_status", 503)) .WillOnce(Return(503)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "503"}, {"content-length", "18"}, {"content-type", "text/plain"}}; EXPECT_CALL(decoder_filter_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); @@ -590,7 +592,7 @@ TEST_F(FaultFilterTest, FixedDelayAndAbortDownstreamNodes) { timer_->invokeCallback(); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(1UL, config_->stats().delays_injected_.value()); EXPECT_EQ(1UL, config_->stats().aborts_injected_.value()); @@ -642,7 +644,7 @@ TEST_F(FaultFilterTest, FixedDelayAndAbortHeaderMatchSuccess) { EXPECT_CALL(runtime_.snapshot_, getInteger("fault.http.abort.http_status", 503)) .WillOnce(Return(503)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "503"}, {"content-length", "18"}, {"content-type", "text/plain"}}; EXPECT_CALL(decoder_filter_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), false)); @@ -655,7 +657,7 @@ TEST_F(FaultFilterTest, FixedDelayAndAbortHeaderMatchSuccess) { timer_->invokeCallback(); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(1UL, config_->stats().delays_injected_.value()); EXPECT_EQ(1UL, config_->stats().aborts_injected_.value()); @@ -687,7 +689,7 @@ TEST_F(FaultFilterTest, FixedDelayAndAbortHeaderMatchFail) { // Expect filter to continue execution when headers don't match 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(0UL, config_->stats().delays_injected_.value()); EXPECT_EQ(0UL, config_->stats().aborts_injected_.value()); @@ -787,7 +789,7 @@ TEST_F(FaultFilterTest, FaultWithTargetClusterMatchSuccess) { timer_->invokeCallback(); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(1UL, config_->stats().delays_injected_.value()); EXPECT_EQ(0UL, config_->stats().aborts_injected_.value()); @@ -818,7 +820,7 @@ TEST_F(FaultFilterTest, FaultWithTargetClusterMatchFail) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(0UL, config_->stats().delays_injected_.value()); EXPECT_EQ(0UL, config_->stats().aborts_injected_.value()); @@ -848,7 +850,7 @@ TEST_F(FaultFilterTest, FaultWithTargetClusterNullRoute) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(0UL, config_->stats().delays_injected_.value()); EXPECT_EQ(0UL, config_->stats().aborts_injected_.value()); @@ -901,7 +903,7 @@ void FaultFilterTest::TestPerFilterConfigFault( timer_->invokeCallback(); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(1UL, config_->stats().delays_injected_.value()); EXPECT_EQ(0UL, config_->stats().aborts_injected_.value()); @@ -960,11 +962,11 @@ TEST_F(FaultFilterRateLimitTest, ResponseRateLimitDisabled) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); } // Make sure we destroy the rate limiter if we are reset. diff --git a/test/extensions/filters/http/grpc_http1_bridge/http1_bridge_filter_test.cc b/test/extensions/filters/http/grpc_http1_bridge/http1_bridge_filter_test.cc index 644157a15f..1784186168 100644 --- a/test/extensions/filters/http/grpc_http1_bridge/http1_bridge_filter_test.cc +++ b/test/extensions/filters/http/grpc_http1_bridge/http1_bridge_filter_test.cc @@ -46,43 +46,46 @@ TEST_F(GrpcHttp1BridgeFilterTest, NoRoute) { protocol_ = Http::Protocol::Http2; ON_CALL(decoder_callbacks_, route()).WillByDefault(Return(nullptr)); - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc"}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "application/grpc"}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, true)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_.decodeMetadata(metadata_map)); - Http::TestHeaderMapImpl response_headers{{":status", "404"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "404"}}; } TEST_F(GrpcHttp1BridgeFilterTest, NoCluster) { protocol_ = Http::Protocol::Http2; ON_CALL(decoder_callbacks_, clusterInfo()).WillByDefault(Return(nullptr)); - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc"}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "application/grpc"}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, true)); - Http::TestHeaderMapImpl response_headers{{":status", "404"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "404"}}; } TEST_F(GrpcHttp1BridgeFilterTest, StatsHttp2HeaderOnlyResponse) { protocol_ = Http::Protocol::Http2; - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc"}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "application/grpc"}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, true)); - Http::TestHeaderMapImpl continue_headers{{":status", "100"}}; + Http::TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encode100ContinueHeaders(continue_headers)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_.encodeMetadata(metadata_map)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "1"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "1"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, true)); EXPECT_EQ(1UL, decoder_callbacks_.clusterInfo() ->statsScope() @@ -97,16 +100,17 @@ TEST_F(GrpcHttp1BridgeFilterTest, StatsHttp2HeaderOnlyResponse) { TEST_F(GrpcHttp1BridgeFilterTest, StatsHttp2NormalResponse) { protocol_ = Http::Protocol::Http2; - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc"}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "application/grpc"}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data, false)); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "0"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers)); EXPECT_EQ(1UL, decoder_callbacks_.clusterInfo() ->statsScope() @@ -121,14 +125,15 @@ TEST_F(GrpcHttp1BridgeFilterTest, StatsHttp2NormalResponse) { TEST_F(GrpcHttp1BridgeFilterTest, StatsHttp2ContentTypeGrpcPlusProto) { protocol_ = Http::Protocol::Http2; - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc+proto"}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "application/grpc+proto"}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "0"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers)); EXPECT_EQ(1UL, decoder_callbacks_.clusterInfo() ->statsScope() @@ -143,54 +148,55 @@ TEST_F(GrpcHttp1BridgeFilterTest, StatsHttp2ContentTypeGrpcPlusProto) { TEST_F(GrpcHttp1BridgeFilterTest, NotHandlingHttp2) { protocol_ = Http::Protocol::Http2; - Http::TestHeaderMapImpl request_headers{{"content-type", "application/foo"}}; + Http::TestRequestHeaderMapImpl request_headers{{"content-type", "application/foo"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"hello", "world"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"hello", "world"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data, false)); - Http::TestHeaderMapImpl response_trailers{{"hello", "world"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"hello", "world"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers)); EXPECT_EQ("200", response_headers.get_(":status")); } TEST_F(GrpcHttp1BridgeFilterTest, NotHandlingHttp1) { - Http::TestHeaderMapImpl request_headers{{"content-type", "application/foo"}}; + Http::TestRequestHeaderMapImpl request_headers{{"content-type", "application/foo"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"hello", "world"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"hello", "world"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data, false)); - Http::TestHeaderMapImpl response_trailers{{"hello", "world"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"hello", "world"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers)); EXPECT_EQ("200", response_headers.get_(":status")); } TEST_F(GrpcHttp1BridgeFilterTest, HandlingNormalResponse) { - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc"}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "application/grpc"}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"hello", "world"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"hello", "world"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); Buffer::InstancePtr buffer(new Buffer::OwnedImpl("hello")); ON_CALL(encoder_callbacks_, encodingBuffer()).WillByDefault(Return(buffer.get())); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_.encodeData(data, false)); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "0"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers)); EXPECT_EQ("200", response_headers.get_(":status")); EXPECT_EQ("5", response_headers.get_("content-length")); @@ -198,19 +204,20 @@ TEST_F(GrpcHttp1BridgeFilterTest, HandlingNormalResponse) { } TEST_F(GrpcHttp1BridgeFilterTest, HandlingBadGrpcStatus) { - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc"}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "application/grpc"}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"hello", "world"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"hello", "world"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_.encodeData(data, false)); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "1"}, {"grpc-message", "foo"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "1"}, {"grpc-message", "foo"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers)); EXPECT_EQ("503", response_headers.get_(":status")); EXPECT_EQ("0", response_headers.get_("content-length")); diff --git a/test/extensions/filters/http/grpc_http1_reverse_bridge/reverse_bridge_integration_test.cc b/test/extensions/filters/http/grpc_http1_reverse_bridge/reverse_bridge_integration_test.cc index 4c9e6c2f14..f412906d67 100644 --- a/test/extensions/filters/http/grpc_http1_reverse_bridge/reverse_bridge_integration_test.cc +++ b/test/extensions/filters/http/grpc_http1_reverse_bridge/reverse_bridge_integration_test.cc @@ -56,11 +56,11 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, ReverseBridgeIntegrationTest, TEST_P(ReverseBridgeIntegrationTest, EnabledRoute) { codec_client_ = makeHttpConnection(lookupPort("http")); - Http::TestHeaderMapImpl request_headers({{":scheme", "http"}, - {":method", "POST"}, - {":authority", "foo"}, - {":path", "/testing.ExampleService/Print"}, - {"content-type", "application/grpc"}}); + Http::TestRequestHeaderMapImpl request_headers({{":scheme", "http"}, + {":method", "POST"}, + {":authority", "foo"}, + {":path", "/testing.ExampleService/Print"}, + {"content-type", "application/grpc"}}); auto encoder_decoder = codec_client_->startRequest(request_headers); request_encoder_ = &encoder_decoder.first; IntegrationStreamDecoderPtr response = std::move(encoder_decoder.second); @@ -82,7 +82,7 @@ TEST_P(ReverseBridgeIntegrationTest, EnabledRoute) { HeaderValueOf(Http::Headers::get().Accept, "application/x-protobuf")); // Respond to the request. - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; response_headers.setStatus(200); response_headers.setContentType("application/x-protobuf"); upstream_request_->encodeHeaders(response_headers, false); @@ -90,7 +90,7 @@ TEST_P(ReverseBridgeIntegrationTest, EnabledRoute) { Buffer::OwnedImpl response_data{"defgh"}; upstream_request_->encodeData(response_data, false); - Http::TestHeaderMapImpl response_trailers; + Http::TestResponseTrailerMapImpl response_trailers; response_trailers.setGrpcStatus(std::string("0")); upstream_request_->encodeTrailers(response_trailers); diff --git a/test/extensions/filters/http/grpc_http1_reverse_bridge/reverse_bridge_test.cc b/test/extensions/filters/http/grpc_http1_reverse_bridge/reverse_bridge_test.cc index 4774d9433b..46114c48c9 100644 --- a/test/extensions/filters/http/grpc_http1_reverse_bridge/reverse_bridge_test.cc +++ b/test/extensions/filters/http/grpc_http1_reverse_bridge/reverse_bridge_test.cc @@ -53,9 +53,9 @@ TEST_F(ReverseBridgeTest, InvalidGrpcRequest) { { EXPECT_CALL(decoder_callbacks_, route()).WillRepeatedly(testing::Return(nullptr)); EXPECT_CALL(decoder_callbacks_, clearRouteCache()); - Http::TestHeaderMapImpl headers({{"content-type", "application/grpc"}, - {"content-length", "25"}, - {":path", "/testing.ExampleService/SendData"}}); + Http::TestRequestHeaderMapImpl headers({{"content-type", "application/grpc"}, + {"content-length", "25"}, + {":path", "/testing.ExampleService/SendData"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/x-protobuf")); @@ -86,9 +86,9 @@ TEST_F(ReverseBridgeTest, HeaderOnlyGrpcRequest) { decoder_callbacks_.is_grpc_request_ = true; { - Http::TestHeaderMapImpl headers({{"content-type", "application/grpc"}, - {"content-length", "25"}, - {":path", "/testing.ExampleService/SendData"}}); + Http::TestRequestHeaderMapImpl headers({{"content-type", "application/grpc"}, + {"content-length", "25"}, + {":path", "/testing.ExampleService/SendData"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, true)); // Verify that headers are unmodified. @@ -97,7 +97,8 @@ TEST_F(ReverseBridgeTest, HeaderOnlyGrpcRequest) { } // Verify no modification on encoding path as well. - Http::TestHeaderMapImpl headers({{"content-type", "application/grpc"}, {"content-length", "20"}}); + Http::TestResponseHeaderMapImpl headers( + {{"content-type", "application/grpc"}, {"content-length", "20"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, true)); // Ensure we didn't mutate content type or length. EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/grpc")); @@ -116,7 +117,7 @@ TEST_F(ReverseBridgeTest, NoGrpcRequest) { { EXPECT_CALL(decoder_callbacks_, route()).WillRepeatedly(testing::Return(nullptr)); - Http::TestHeaderMapImpl headers( + Http::TestRequestHeaderMapImpl headers( {{"content-type", "application/json"}, {"content-length", "10"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); // Ensure we didn't mutate content type or length. @@ -131,11 +132,11 @@ TEST_F(ReverseBridgeTest, NoGrpcRequest) { EXPECT_EQ(4, buffer.length()); } - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); { - Http::TestHeaderMapImpl headers( + Http::TestResponseHeaderMapImpl headers( {{"content-type", "application/json"}, {"content-length", "20"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); // Ensure we didn't mutate content type or length. @@ -149,7 +150,8 @@ TEST_F(ReverseBridgeTest, NoGrpcRequest) { EXPECT_EQ(4, buffer.length()); // Verify no modification on encoding path as well. - Http::TestHeaderMapImpl headers({{"content-type", "application/grpc"}, {"content-length", "20"}}); + Http::TestResponseHeaderMapImpl headers( + {{"content-type", "application/grpc"}, {"content-length", "20"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, true)); // Ensure we didn't mutate content type or length. EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/grpc")); @@ -165,9 +167,9 @@ TEST_F(ReverseBridgeTest, GrpcRequestNoManageFrameHeader) { { EXPECT_CALL(decoder_callbacks_, route()).WillRepeatedly(testing::Return(nullptr)); EXPECT_CALL(decoder_callbacks_, clearRouteCache()); - Http::TestHeaderMapImpl headers({{"content-type", "application/grpc"}, - {"content-length", "25"}, - {":path", "/testing.ExampleService/SendData"}}); + Http::TestRequestHeaderMapImpl headers({{"content-type", "application/grpc"}, + {"content-length", "25"}, + {":path", "/testing.ExampleService/SendData"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/x-protobuf")); @@ -184,12 +186,12 @@ TEST_F(ReverseBridgeTest, GrpcRequestNoManageFrameHeader) { } { - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); } // We should not modify the content-length. - Http::TestHeaderMapImpl headers( + Http::TestResponseHeaderMapImpl headers( {{":status", "200"}, {"content-length", "30"}, {"content-type", "application/x-protobuf"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/grpc")); @@ -205,7 +207,7 @@ TEST_F(ReverseBridgeTest, GrpcRequestNoManageFrameHeader) { { // Last call should also not modify the buffer. - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_CALL(encoder_callbacks_, addEncodedTrailers()).WillOnce(ReturnRef(trailers)); Envoy::Buffer::OwnedImpl buffer; @@ -225,9 +227,9 @@ TEST_F(ReverseBridgeTest, GrpcRequest) { { EXPECT_CALL(decoder_callbacks_, route()).WillRepeatedly(testing::Return(nullptr)); EXPECT_CALL(decoder_callbacks_, clearRouteCache()); - Http::TestHeaderMapImpl headers({{"content-type", "application/grpc"}, - {"content-length", "25"}, - {":path", "/testing.ExampleService/SendData"}}); + Http::TestRequestHeaderMapImpl headers({{"content-type", "application/grpc"}, + {"content-length", "25"}, + {":path", "/testing.ExampleService/SendData"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/x-protobuf")); @@ -252,11 +254,11 @@ TEST_F(ReverseBridgeTest, GrpcRequest) { } { - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); } - Http::TestHeaderMapImpl headers( + Http::TestResponseHeaderMapImpl headers( {{":status", "200"}, {"content-length", "30"}, {"content-type", "application/x-protobuf"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/grpc")); @@ -278,7 +280,7 @@ TEST_F(ReverseBridgeTest, GrpcRequest) { } { // Last call should prefix the buffer with the size and insert the gRPC status into trailers. - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_CALL(encoder_callbacks_, addEncodedTrailers()).WillOnce(ReturnRef(trailers)); Envoy::Buffer::OwnedImpl buffer; @@ -306,7 +308,7 @@ TEST_F(ReverseBridgeTest, GrpcRequestNoContentLength) { { EXPECT_CALL(decoder_callbacks_, route()).WillRepeatedly(testing::Return(nullptr)); EXPECT_CALL(decoder_callbacks_, clearRouteCache()); - Http::TestHeaderMapImpl headers( + Http::TestRequestHeaderMapImpl headers( {{"content-type", "application/grpc"}, {":path", "/testing.ExampleService/SendData"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); @@ -333,11 +335,12 @@ TEST_F(ReverseBridgeTest, GrpcRequestNoContentLength) { } { - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); } - Http::TestHeaderMapImpl headers({{":status", "200"}, {"content-type", "application/x-protobuf"}}); + Http::TestResponseHeaderMapImpl headers( + {{":status", "200"}, {"content-type", "application/x-protobuf"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/grpc")); // Ensure that we don't insert a content-length header. @@ -359,7 +362,7 @@ TEST_F(ReverseBridgeTest, GrpcRequestNoContentLength) { } { // Last call should prefix the buffer with the size and insert the gRPC status into trailers. - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_CALL(encoder_callbacks_, addEncodedTrailers()).WillOnce(ReturnRef(trailers)); Envoy::Buffer::OwnedImpl buffer; @@ -386,7 +389,7 @@ TEST_F(ReverseBridgeTest, GrpcRequestInternalError) { { EXPECT_CALL(decoder_callbacks_, route()).WillRepeatedly(testing::Return(nullptr)); EXPECT_CALL(decoder_callbacks_, clearRouteCache()); - Http::TestHeaderMapImpl headers( + Http::TestRequestHeaderMapImpl headers( {{"content-type", "application/grpc"}, {":path", "/testing.ExampleService/SendData"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/x-protobuf")); @@ -410,11 +413,12 @@ TEST_F(ReverseBridgeTest, GrpcRequestInternalError) { } { - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); } - Http::TestHeaderMapImpl headers({{":status", "400"}, {"content-type", "application/x-protobuf"}}); + Http::TestResponseHeaderMapImpl headers( + {{":status", "400"}, {"content-type", "application/x-protobuf"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/grpc")); @@ -434,7 +438,7 @@ TEST_F(ReverseBridgeTest, GrpcRequestInternalError) { } { // Last call should prefix the buffer with the size and insert the appropriate gRPC status. - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_CALL(encoder_callbacks_, addEncodedTrailers()).WillOnce(ReturnRef(trailers)); Envoy::Buffer::OwnedImpl buffer; @@ -460,7 +464,7 @@ TEST_F(ReverseBridgeTest, GrpcRequestBadResponseNoContentType) { { EXPECT_CALL(decoder_callbacks_, route()).WillRepeatedly(testing::Return(nullptr)); EXPECT_CALL(decoder_callbacks_, clearRouteCache()); - Http::TestHeaderMapImpl headers( + Http::TestRequestHeaderMapImpl headers( {{"content-type", "application/grpc"}, {":path", "/testing.ExampleService/SendData"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/x-protobuf")); @@ -486,10 +490,10 @@ TEST_F(ReverseBridgeTest, GrpcRequestBadResponseNoContentType) { EXPECT_EQ("abcdefgh", buffer.toString()); } - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); - Http::TestHeaderMapImpl headers({{":status", "400"}}); + Http::TestResponseHeaderMapImpl headers({{":status", "400"}}); EXPECT_EQ(Http::FilterHeadersStatus::ContinueAndEndStream, filter_->encodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().Status, "200")); @@ -510,7 +514,7 @@ TEST_F(ReverseBridgeTest, GrpcRequestBadResponse) { { EXPECT_CALL(decoder_callbacks_, route()).WillRepeatedly(testing::Return(nullptr)); EXPECT_CALL(decoder_callbacks_, clearRouteCache()); - Http::TestHeaderMapImpl headers( + Http::TestRequestHeaderMapImpl headers( {{"content-type", "application/grpc"}, {":path", "/testing.ExampleService/SendData"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/x-protobuf")); @@ -536,10 +540,11 @@ TEST_F(ReverseBridgeTest, GrpcRequestBadResponse) { EXPECT_EQ("abcdefgh", buffer.toString()); } - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); - Http::TestHeaderMapImpl headers({{":status", "400"}, {"content-type", "application/json"}}); + Http::TestResponseHeaderMapImpl headers( + {{":status", "400"}, {"content-type", "application/json"}}); EXPECT_EQ(Http::FilterHeadersStatus::ContinueAndEndStream, filter_->encodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().Status, "200")); @@ -566,9 +571,9 @@ TEST_F(ReverseBridgeTest, FilterConfigPerRouteDisabled) { EXPECT_CALL(decoder_callbacks_, route()).Times(2); - Http::TestHeaderMapImpl headers({{"content-type", "application/grpc"}, - {"content-length", "25"}, - {":path", "/testing.ExampleService/SendData"}}); + Http::TestRequestHeaderMapImpl headers({{"content-type", "application/grpc"}, + {"content-length", "25"}, + {":path", "/testing.ExampleService/SendData"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); // Verify that headers are unmodified. @@ -596,9 +601,9 @@ TEST_F(ReverseBridgeTest, FilterConfigPerRouteEnabled) { { EXPECT_CALL(decoder_callbacks_, route()).Times(2); EXPECT_CALL(decoder_callbacks_, clearRouteCache()); - Http::TestHeaderMapImpl headers({{"content-type", "application/grpc"}, - {"content-length", "25"}, - {":path", "/testing.ExampleService/SendData"}}); + Http::TestRequestHeaderMapImpl headers({{"content-type", "application/grpc"}, + {"content-length", "25"}, + {":path", "/testing.ExampleService/SendData"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/x-protobuf")); @@ -623,11 +628,11 @@ TEST_F(ReverseBridgeTest, FilterConfigPerRouteEnabled) { } { - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); } - Http::TestHeaderMapImpl headers( + Http::TestResponseHeaderMapImpl headers( {{":status", "200"}, {"content-length", "30"}, {"content-type", "application/x-protobuf"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/grpc")); @@ -649,7 +654,7 @@ TEST_F(ReverseBridgeTest, FilterConfigPerRouteEnabled) { } { // Last call should prefix the buffer with the size and insert the gRPC status into trailers. - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_CALL(encoder_callbacks_, addEncodedTrailers()).WillOnce(ReturnRef(trailers)); Envoy::Buffer::OwnedImpl buffer; @@ -683,9 +688,9 @@ TEST_F(ReverseBridgeTest, RouteWithTrailers) { { EXPECT_CALL(decoder_callbacks_, route()).Times(2); EXPECT_CALL(decoder_callbacks_, clearRouteCache()); - Http::TestHeaderMapImpl headers({{"content-type", "application/grpc"}, - {"content-length", "25"}, - {":path", "/testing.ExampleService/SendData"}}); + Http::TestRequestHeaderMapImpl headers({{"content-type", "application/grpc"}, + {"content-length", "25"}, + {":path", "/testing.ExampleService/SendData"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/x-protobuf")); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentLength, "20")); @@ -701,11 +706,11 @@ TEST_F(ReverseBridgeTest, RouteWithTrailers) { } { - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); } - Http::TestHeaderMapImpl headers( + Http::TestResponseHeaderMapImpl headers( {{":status", "200"}, {"content-length", "30"}, {"content-type", "application/x-protobuf"}}); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); EXPECT_THAT(headers, HeaderValueOf(Http::Headers::get().ContentType, "application/grpc")); @@ -731,7 +736,7 @@ TEST_F(ReverseBridgeTest, RouteWithTrailers) { Envoy::Buffer::OwnedImpl buffer; EXPECT_CALL(encoder_callbacks_, addEncodedData(_, false)) .WillOnce(Invoke([&](Envoy::Buffer::Instance& buf, bool) -> void { buffer.move(buf); })); - Http::TestHeaderMapImpl trailers({{"foo", "bar"}, {"one", "two"}, {"three", "four"}}); + Http::TestResponseTrailerMapImpl trailers({{"foo", "bar"}, {"one", "two"}, {"three", "four"}}); EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(trailers)); EXPECT_THAT(trailers, HeaderValueOf(Http::Headers::get().GrpcStatus, "0")); diff --git a/test/extensions/filters/http/grpc_json_transcoder/grpc_json_transcoder_integration_test.cc b/test/extensions/filters/http/grpc_json_transcoder/grpc_json_transcoder_integration_test.cc index 767cf6494d..959a3c280c 100644 --- a/test/extensions/filters/http/grpc_json_transcoder/grpc_json_transcoder_integration_test.cc +++ b/test/extensions/filters/http/grpc_json_transcoder/grpc_json_transcoder_integration_test.cc @@ -57,7 +57,7 @@ class GrpcJsonTranscoderIntegrationTest protected: template - void testTranscoding(Http::HeaderMap&& request_headers, const std::string& request_body, + void testTranscoding(Http::RequestHeaderMap&& request_headers, const std::string& request_body, const std::vector& grpc_request_messages, const std::vector& grpc_response_messages, const Status& grpc_status, Http::HeaderMap&& response_headers, @@ -97,7 +97,7 @@ class GrpcJsonTranscoderIntegrationTest EXPECT_TRUE(MessageDifferencer::Equivalent(expected_message, actual_message)); } - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; response_headers.setStatus(200); response_headers.setContentType("application/grpc"); if (grpc_response_messages.empty() && !always_send_trailers) { @@ -115,7 +115,7 @@ class GrpcJsonTranscoderIntegrationTest auto buffer = Grpc::Common::serializeToGrpcFrame(response_message); upstream_request_->encodeData(*buffer, false); } - Http::TestHeaderMapImpl response_trailers; + Http::TestResponseTrailerMapImpl response_trailers; response_trailers.setGrpcStatus(static_cast(grpc_status.error_code())); response_trailers.setGrpcMessage(absl::string_view(grpc_status.error_message().data(), grpc_status.error_message().size())); @@ -170,16 +170,16 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, GrpcJsonTranscoderIntegrationTest, TEST_P(GrpcJsonTranscoderIntegrationTest, UnaryPost) { HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/shelf"}, - {":authority", "host"}, - {"content-type", "application/json"}}, + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/shelf"}, + {":authority", "host"}, + {"content-type", "application/json"}}, R"({"theme": "Children"})", {R"(shelf { theme: "Children" })"}, {R"(id: 20 theme: "Children" )"}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-type", "application/json"}, - {"content-length", "30"}, - {"grpc-status", "0"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-type", "application/json"}, + {"content-length", "30"}, + {"grpc-status", "0"}}, R"({"id":"20","theme":"Children"})"); } @@ -190,12 +190,12 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, QueryParams) { // POST /shelves // body: shelf testTranscoding( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/shelf?shelf.theme=Children"}, - {":authority", "host"}, - {"content-type", "application/json"}}, + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/shelf?shelf.theme=Children"}, + {":authority", "host"}, + {"content-type", "application/json"}}, "", {R"(shelf { theme: "Children" })"}, {R"(id: 20 theme: "Children" )"}, Status(), - Http::TestHeaderMapImpl{ + Http::TestResponseHeaderMapImpl{ {":status", "200"}, {"content-type", "application/json"}, }, @@ -203,12 +203,12 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, QueryParams) { // 2. Binding theme='Children' and id='999' in CreateShelfRequest testTranscoding( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/shelf?shelf.id=999&shelf.theme=Children"}, - {":authority", "host"}, - {"content-type", "application/json"}}, + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/shelf?shelf.id=999&shelf.theme=Children"}, + {":authority", "host"}, + {"content-type", "application/json"}}, "", {R"(shelf { id: 999 theme: "Children" })"}, {R"(id: 999 theme: "Children" )"}, Status(), - Http::TestHeaderMapImpl{ + Http::TestResponseHeaderMapImpl{ {":status", "200"}, {"content-type", "application/json"}, }, @@ -219,13 +219,13 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, QueryParams) { // POST /shelves/{shelf}/books // body: book testTranscoding( - Http::TestHeaderMapImpl{{":method", "PUT"}, - {":path", "/shelves/1/books?book.title=War%20and%20Peace"}, - {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{{":method", "PUT"}, + {":path", "/shelves/1/books?book.title=War%20and%20Peace"}, + {":authority", "host"}}, R"({"author" : "Leo Tolstoy"})", {R"(shelf: 1 book { author: "Leo Tolstoy" title: "War and Peace" })"}, {R"(id: 3 author: "Leo Tolstoy" title: "War and Peace")"}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, R"({"id":"3","author":"Leo Tolstoy","title":"War and Peace"})"); // 4. Binding shelf=1, book.author='Leo Tolstoy' and book.title='War and Peace' in @@ -234,36 +234,36 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, QueryParams) { // POST /shelves/{shelf}/books // body: book testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "PUT"}, {":path", "/shelves/1/books?book.author=Leo%20Tolstoy&book.title=War%20and%20Peace"}, {":authority", "host"}}, "", {R"(shelf: 1 book { author: "Leo Tolstoy" title: "War and Peace" })"}, {R"(id: 3 author: "Leo Tolstoy" title: "War and Peace")"}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, R"({"id":"3","author":"Leo Tolstoy","title":"War and Peace"})"); // 5. Test URL decoding. testTranscoding( - Http::TestHeaderMapImpl{{":method", "PUT"}, - {":path", "/shelves/1/books?book.title=War%20%26%20Peace"}, - {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{{":method", "PUT"}, + {":path", "/shelves/1/books?book.title=War%20%26%20Peace"}, + {":authority", "host"}}, R"({"author" : "Leo Tolstoy"})", {R"(shelf: 1 book { author: "Leo Tolstoy" title: "War & Peace" })"}, {R"(id: 3 author: "Leo Tolstoy" title: "War & Peace")"}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, R"({"id":"3","author":"Leo Tolstoy","title":"War & Peace"})"); // 6. Binding all book fields through query params. testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "PUT"}, {":path", "/shelves/1/books?book.id=999&book.author=Leo%20Tolstoy&book.title=War%20and%20Peace"}, {":authority", "host"}}, "", {R"(shelf: 1 book { id : 999 author: "Leo Tolstoy" title: "War and Peace" })"}, {R"(id: 999 author: "Leo Tolstoy" title: "War and Peace")"}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, R"({"id":"999","author":"Leo Tolstoy","title":"War and Peace"})"); // 7. Binding shelf=3, book= and the repeated field book.quote with @@ -285,48 +285,51 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, QueryParams) { R"(,"A very small man can cast a very large shadow","Winter is coming","Hold the door"]})"; testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "PUT"}, {":path", "/shelves/1/books?book.quotes=Winter%20is%20coming&book.quotes=Hold%20the%20door"}, {":authority", "host"}}, reqBody, {expectGrpcRequest}, {grpcResp}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, respBody); + Http::TestResponseHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, + respBody); } TEST_P(GrpcJsonTranscoderIntegrationTest, UnaryGet) { HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{{":method", "GET"}, {":path", "/shelves"}, {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{ + {":method", "GET"}, {":path", "/shelves"}, {":authority", "host"}}, "", {""}, {R"(shelves { id: 20 theme: "Children" } shelves { id: 1 theme: "Foo" } )"}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-type", "application/json"}, - {"content-length", "69"}, - {"grpc-status", "0"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-type", "application/json"}, + {"content-length", "69"}, + {"grpc-status", "0"}}, R"({"shelves":[{"id":"20","theme":"Children"},{"id":"1","theme":"Foo"}]})"); } TEST_P(GrpcJsonTranscoderIntegrationTest, UnaryGetHttpBody) { HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{{":method", "GET"}, {":path", "/index"}, {":authority", "host"}}, "", - {""}, {R"(content_type: "text/html" data: "

Hello!

" )"}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-type", "text/html"}, - {"content-length", "15"}, - {"grpc-status", "0"}}, + Http::TestRequestHeaderMapImpl{ + {":method", "GET"}, {":path", "/index"}, {":authority", "host"}}, + "", {""}, {R"(content_type: "text/html" data: "

Hello!

" )"}, Status(), + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-type", "text/html"}, + {"content-length", "15"}, + {"grpc-status", "0"}}, R"(

Hello!

)"); } TEST_P(GrpcJsonTranscoderIntegrationTest, UnaryGetError) { HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/shelves/100?"}, {":authority", "host"}}, "", {"shelf: 100"}, {}, Status(Code::NOT_FOUND, "Shelf 100 Not Found"), - Http::TestHeaderMapImpl{ + Http::TestResponseHeaderMapImpl{ {":status", "404"}, {"grpc-status", "5"}, {"grpc-message", "Shelf 100 Not Found"}}, ""); } @@ -345,11 +348,11 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, UnaryGetError1) { fmt::format(filter, TestEnvironment::runfilesPath("test/proto/bookstore.descriptor"))); HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/shelves/100?unknown=1&shelf=9999"}, - {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/shelves/100?unknown=1&shelf=9999"}, + {":authority", "host"}}, "", {"shelf: 9999"}, {}, Status(Code::NOT_FOUND, "Shelf 9999 Not Found"), - Http::TestHeaderMapImpl{ + Http::TestResponseHeaderMapImpl{ {":status", "404"}, {"grpc-status", "5"}, {"grpc-message", "Shelf 9999 Not Found"}}, ""); } @@ -369,13 +372,13 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, UnaryErrorConvertedToJson) { fmt::format(filter, TestEnvironment::runfilesPath("test/proto/bookstore.descriptor"))); HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/shelves/100"}, {":authority", "host"}}, "", {"shelf: 100"}, {}, Status(Code::NOT_FOUND, "Shelf 100 Not Found"), - Http::TestHeaderMapImpl{{":status", "404"}, - {"content-type", "application/json"}, - {"grpc-status", UnexpectedHeaderValue}, - {"grpc-message", UnexpectedHeaderValue}}, + Http::TestResponseHeaderMapImpl{{":status", "404"}, + {"content-type", "application/json"}, + {"grpc-status", UnexpectedHeaderValue}, + {"grpc-message", UnexpectedHeaderValue}}, R"({"code":5,"message":"Shelf 100 Not Found"})"); } @@ -394,13 +397,13 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, UnaryErrorInTrailerConvertedToJson) { fmt::format(filter, TestEnvironment::runfilesPath("test/proto/bookstore.descriptor"))); HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/shelves/100"}, {":authority", "host"}}, "", {"shelf: 100"}, {}, Status(Code::NOT_FOUND, "Shelf 100 Not Found"), - Http::TestHeaderMapImpl{{":status", "404"}, - {"content-type", "application/json"}, - {"grpc-status", UnexpectedHeaderValue}, - {"grpc-message", UnexpectedHeaderValue}}, + Http::TestResponseHeaderMapImpl{{":status", "404"}, + {"content-type", "application/json"}, + {"grpc-status", UnexpectedHeaderValue}, + {"grpc-message", UnexpectedHeaderValue}}, R"({"code":5,"message":"Shelf 100 Not Found"})", true, true); } @@ -419,66 +422,66 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, StreamingErrorConvertedToJson) { fmt::format(filter, TestEnvironment::runfilesPath("test/proto/bookstore.descriptor"))); HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/shelves/37/books"}, {":authority", "host"}}, "", {"shelf: 37"}, {}, Status(Code::NOT_FOUND, "Shelf 37 Not Found"), - Http::TestHeaderMapImpl{{":status", "404"}, - {"content-type", "application/json"}, - {"grpc-status", UnexpectedHeaderValue}, - {"grpc-message", UnexpectedHeaderValue}}, + Http::TestResponseHeaderMapImpl{{":status", "404"}, + {"content-type", "application/json"}, + {"grpc-status", UnexpectedHeaderValue}, + {"grpc-message", UnexpectedHeaderValue}}, R"({"code":5,"message":"Shelf 37 Not Found"})"); } TEST_P(GrpcJsonTranscoderIntegrationTest, UnaryDelete) { HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "DELETE"}, {":path", "/shelves/456/books/123"}, {":authority", "host"}}, "", {"shelf: 456 book: 123"}, {""}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-type", "application/json"}, - {"content-length", "2"}, - {"grpc-status", "0"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-type", "application/json"}, + {"content-length", "2"}, + {"grpc-status", "0"}}, "{}"); } TEST_P(GrpcJsonTranscoderIntegrationTest, UnaryPatch) { HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "PATCH"}, {":path", "/shelves/456/books/123"}, {":authority", "host"}}, R"({"author" : "Leo Tolstoy", "title" : "War and Peace"})", {R"(shelf: 456 book { id: 123 author: "Leo Tolstoy" title: "War and Peace" })"}, {R"(id: 123 author: "Leo Tolstoy" title: "War and Peace")"}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-type", "application/json"}, - {"content-length", "59"}, - {"grpc-status", "0"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-type", "application/json"}, + {"content-length", "59"}, + {"grpc-status", "0"}}, R"({"id":"123","author":"Leo Tolstoy","title":"War and Peace"})"); } TEST_P(GrpcJsonTranscoderIntegrationTest, UnaryCustom) { HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "OPTIONS"}, {":path", "/shelves/456"}, {":authority", "host"}}, "", {"shelf: 456"}, {""}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-type", "application/json"}, - {"content-length", "2"}, - {"grpc-status", "0"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-type", "application/json"}, + {"content-length", "2"}, + {"grpc-status", "0"}}, "{}"); } TEST_P(GrpcJsonTranscoderIntegrationTest, BindingAndBody) { HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "PUT"}, {":path", "/shelves/1/books"}, {":authority", "host"}}, R"({"author" : "Leo Tolstoy", "title" : "War and Peace"})", {R"(shelf: 1 book { author: "Leo Tolstoy" title: "War and Peace" })"}, {R"(id: 3 author: "Leo Tolstoy" title: "War and Peace")"}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, R"({"id":"3","author":"Leo Tolstoy","title":"War and Peace"})"); } @@ -487,12 +490,13 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, ServerStreamingGet) { // 1: Normal streaming get testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/shelves/1/books"}, {":authority", "host"}}, "", {"shelf: 1"}, {R"(id: 1 author: "Neal Stephenson" title: "Readme")", R"(id: 2 author: "George R.R. Martin" title: "A Game of Thrones")"}, - Status(), Http::TestHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, + Status(), + Http::TestResponseHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, R"([{"id":"1","author":"Neal Stephenson","title":"Readme"})" R"(,{"id":"2","author":"George R.R. Martin","title":"A Game of Thrones"}])"); @@ -500,23 +504,25 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, ServerStreamingGet) { // Response type is a valid JSON, so content type should be application/json. // Regression test for github.com/envoyproxy/envoy#5011 testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/shelves/2/books"}, {":authority", "host"}}, "", {"shelf: 2"}, {}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, "[]"); + Http::TestResponseHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, + "[]"); // 3: Empty response (trailers only) from streaming backend, with a gRPC error. testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/shelves/37/books"}, {":authority", "host"}}, "", {"shelf: 37"}, {}, Status(Code::NOT_FOUND, "Shelf 37 not found"), - Http::TestHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, "[]"); + Http::TestResponseHeaderMapImpl{{":status", "200"}, {"content-type", "application/json"}}, + "[]"); } TEST_P(GrpcJsonTranscoderIntegrationTest, StreamingPost) { HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", "/bulk/shelves"}, {":authority", "host"}}, R"([ { "theme" : "Classics" }, @@ -532,9 +538,9 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, StreamingPost) { {R"(id: 3 theme: "Classics")", R"(id: 4 theme: "Satire")", R"(id: 5 theme: "Russian")", R"(id: 6 theme: "Children")", R"(id: 7 theme: "Documentary")", R"(id: 8 theme: "Mystery")"}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-type", "application/json"}, - {"transfer-encoding", "chunked"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-type", "application/json"}, + {"transfer-encoding", "chunked"}}, R"([{"id":"3","theme":"Classics"})" R"(,{"id":"4","theme":"Satire"})" R"(,{"id":"5","theme":"Russian"})" @@ -552,15 +558,17 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, InvalidJson) { // If Envoy does a short read of the upstream connection, it may only read part of the // string "INVALID_JSON". Envoy will note "Unexpected token [whatever substring is read] testTranscoding( - Http::TestHeaderMapImpl{{":method", "POST"}, {":path", "/shelf"}, {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{ + {":method", "POST"}, {":path", "/shelf"}, {":authority", "host"}}, R"(INVALID_JSON)", {}, {}, Status(), - Http::TestHeaderMapImpl{{":status", "400"}, {"content-type", "text/plain"}}, + Http::TestResponseHeaderMapImpl{{":status", "400"}, {"content-type", "text/plain"}}, "Unexpected token.\nI", false); testTranscoding( - Http::TestHeaderMapImpl{{":method", "POST"}, {":path", "/shelf"}, {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{ + {":method", "POST"}, {":path", "/shelf"}, {":authority", "host"}}, R"({ "theme" : "Children")", {}, {}, Status(), - Http::TestHeaderMapImpl{{":status", "400"}, {"content-type", "text/plain"}}, + Http::TestResponseHeaderMapImpl{{":status", "400"}, {"content-type", "text/plain"}}, "Unexpected end of string. Expected , or } after key:value pair.\n" "\n" "^"); @@ -572,15 +580,17 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, InvalidJson) { // But as with INVALID_JSON Envoy may not read the full string from the upstream connection so may // generate its error based on a partial upstream response. testTranscoding( - Http::TestHeaderMapImpl{{":method", "POST"}, {":path", "/shelf"}, {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{ + {":method", "POST"}, {":path", "/shelf"}, {":authority", "host"}}, R"({ "theme" "Children" })", {}, {}, Status(), - Http::TestHeaderMapImpl{{":status", "400"}, {"content-type", "text/plain"}}, + Http::TestResponseHeaderMapImpl{{":status", "400"}, {"content-type", "text/plain"}}, "Expected : between key:value pair.\n", false); testTranscoding( - Http::TestHeaderMapImpl{{":method", "POST"}, {":path", "/shelf"}, {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{ + {":method", "POST"}, {":path", "/shelf"}, {":authority", "host"}}, R"({ "theme" : "Children" }EXTRA)", {}, {}, Status(), - Http::TestHeaderMapImpl{{":status", "400"}, {"content-type", "text/plain"}}, + Http::TestResponseHeaderMapImpl{{":status", "400"}, {"content-type", "text/plain"}}, "Parsing terminated before end of input.\n", false); } @@ -616,10 +626,10 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, DeepStruct) { std::string deepJson = createDeepJson(32, true); std::string deepProto = "content {" + jsonStrToPbStrucStr(deepJson) + "}"; testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", "/echoStruct"}, {":authority", "host"}}, deepJson, {deepProto}, {deepProto}, Status(), - Http::TestHeaderMapImpl{ + Http::TestResponseHeaderMapImpl{ {":status", "200"}, {"content-type", "application/json"}, {"grpc-status", "0"}}, R"({"content":)" + deepJson + R"(})"); @@ -627,17 +637,18 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, DeepStruct) { // Since we didn't set the response, it return 503. // Response body is empty (not a valid JSON), so content type should be application/grpc. testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", "/echoStruct"}, {":authority", "host"}}, createDeepJson(100, true), {}, {}, Status(), - Http::TestHeaderMapImpl{{":status", "503"}, {"content-type", "application/grpc"}}, ""); + Http::TestResponseHeaderMapImpl{{":status", "503"}, {"content-type", "application/grpc"}}, + ""); // The invalid deep struct is detected. testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", "/echoStruct"}, {":authority", "host"}}, createDeepJson(100, false), {}, {}, Status(), - Http::TestHeaderMapImpl{{":status", "400"}, {"content-type", "text/plain"}}, + Http::TestResponseHeaderMapImpl{{":status", "400"}, {"content-type", "text/plain"}}, "Unexpected token.\n", false); } @@ -663,10 +674,10 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, LargeStruct) { std::string largeJson = createLargeJson(12); std::string largeProto = "content {" + jsonStrToPbStrucStr(largeJson) + "}"; testTranscoding( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", "/echoStruct"}, {":authority", "host"}}, largeJson, {largeProto}, {largeProto}, Status(), - Http::TestHeaderMapImpl{ + Http::TestResponseHeaderMapImpl{ {":status", "200"}, {"content-type", "application/json"}, {"grpc-status", "0"}}, R"({"content":)" + largeJson + R"(})"); } @@ -674,39 +685,40 @@ TEST_P(GrpcJsonTranscoderIntegrationTest, LargeStruct) { TEST_P(GrpcJsonTranscoderIntegrationTest, UnknownField) { HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/shelf"}, - {":authority", "host"}, - {"content-type", "application/json"}}, + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/shelf"}, + {":authority", "host"}, + {"content-type", "application/json"}}, R"({"theme": "Children", "unknown1": "a", "unknown2" : {"a" : "b"}, "unknown3" : ["a", "b", "c"]})", {R"(shelf { theme: "Children" })"}, {R"(id: 20 theme: "Children" )"}, Status(), - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-type", "application/json"}, - {"content-length", "30"}, - {"grpc-status", "0"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-type", "application/json"}, + {"content-length", "30"}, + {"grpc-status", "0"}}, R"({"id":"20","theme":"Children"})"); } TEST_P(GrpcJsonTranscoderIntegrationTest, UTF8) { HttpIntegrationTest::initialize(); testTranscoding( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/shelf"}, - {":authority", "host"}, - {"content-type", "application/json"}}, + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/shelf"}, + {":authority", "host"}, + {"content-type", "application/json"}}, "{\"id\":\"20\",\"theme\":\"\xC2\xAE\"}", {"shelf {id : 20 theme: \"®\" }"}, {"id: 20 theme: \"\xC2\xAE\""}, Status(), - Http::TestHeaderMapImpl{ + Http::TestResponseHeaderMapImpl{ {":status", "200"}, {"content-type", "application/json"}, {"grpc-status", "0"}}, R"({"id":"20","theme":"®"})"); testTranscoding( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/shelf"}, - {":authority", "host"}, - {"content-type", "application/json"}}, + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/shelf"}, + {":authority", "host"}, + {"content-type", "application/json"}}, "{\"id\":\"20\",\"theme\":\"\xC3\x28\"}", {}, {""}, Status(), - Http::TestHeaderMapImpl{{":status", "400"}}, R"(Encountered non UTF-8 code points)", false); + Http::TestResponseHeaderMapImpl{{":status", "400"}}, R"(Encountered non UTF-8 code points)", + false); } } // namespace diff --git a/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc b/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc index 94c08257b4..89e1fe7198 100644 --- a/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc +++ b/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc @@ -191,7 +191,7 @@ TEST_F(GrpcJsonTranscoderConfigTest, CreateTranscoder) { "bookstore.Bookstore"), *api_); - Http::TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/shelves"}}; + Http::TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/shelves"}}; TranscoderInputStreamImpl request_in, response_in; std::unique_ptr transcoder; @@ -211,8 +211,8 @@ TEST_F(GrpcJsonTranscoderConfigTest, CreateTranscoderAutoMap) { JsonTranscoderConfig config(proto_config, *api_); - Http::TestHeaderMapImpl headers{{":method", "POST"}, - {":path", "/bookstore.Bookstore/DeleteShelf"}}; + Http::TestRequestHeaderMapImpl headers{{":method", "POST"}, + {":path", "/bookstore.Bookstore/DeleteShelf"}}; TranscoderInputStreamImpl request_in, response_in; std::unique_ptr transcoder; @@ -231,7 +231,7 @@ TEST_F(GrpcJsonTranscoderConfigTest, InvalidQueryParameter) { "bookstore.Bookstore"), *api_); - Http::TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/shelves?foo=bar"}}; + Http::TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/shelves?foo=bar"}}; TranscoderInputStreamImpl request_in, response_in; std::unique_ptr transcoder; @@ -251,7 +251,7 @@ TEST_F(GrpcJsonTranscoderConfigTest, UnknownQueryParameterIsIgnored) { proto_config.set_ignore_unknown_query_parameters(true); JsonTranscoderConfig config(proto_config, *api_); - Http::TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/shelves?foo=bar"}}; + Http::TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/shelves?foo=bar"}}; TranscoderInputStreamImpl request_in, response_in; std::unique_ptr transcoder; @@ -270,7 +270,7 @@ TEST_F(GrpcJsonTranscoderConfigTest, IgnoredQueryParameter) { "bookstore.Bookstore", false, ignored_query_parameters), *api_); - Http::TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/shelves?key=API_KEY"}}; + Http::TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/shelves?key=API_KEY"}}; TranscoderInputStreamImpl request_in, response_in; std::unique_ptr transcoder; @@ -292,7 +292,7 @@ TEST_F(GrpcJsonTranscoderConfigTest, InvalidVariableBinding) { "bookstore.Bookstore"), *api_); - Http::TestHeaderMapImpl headers{{":method", "GET"}, {":path", "/book/1"}}; + Http::TestRequestHeaderMapImpl headers{{":method", "GET"}, {":path", "/book/1"}}; TranscoderInputStreamImpl request_in, response_in; std::unique_ptr transcoder; @@ -337,9 +337,9 @@ class GrpcJsonTranscoderFilterTest : public testing::Test, public GrpcJsonTransc }; TEST_F(GrpcJsonTranscoderFilterTest, NoTranscoding) { - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc"}, - {":method", "POST"}, - {":path", "/grpc.service/UnknownGrpcMethod"}}; + Http::TestRequestHeaderMapImpl request_headers{{"content-type", "application/grpc"}, + {":method", "POST"}, + {":path", "/grpc.service/UnknownGrpcMethod"}}; Http::TestHeaderMapImpl expected_request_headers{{"content-type", "application/grpc"}, {":method", "POST"}, @@ -356,11 +356,11 @@ TEST_F(GrpcJsonTranscoderFilterTest, NoTranscoding) { EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(request_data, false)); EXPECT_EQ(2, request_data.length()); - Http::TestHeaderMapImpl request_trailers; + Http::TestRequestTrailerMapImpl request_trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); - Http::TestHeaderMapImpl response_headers{{"content-type", "application/grpc"}, - {":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{"content-type", "application/grpc"}, + {":status", "200"}}; Http::TestHeaderMapImpl expected_response_headers{{"content-type", "application/grpc"}, {":status", "200"}}; @@ -372,14 +372,14 @@ TEST_F(GrpcJsonTranscoderFilterTest, NoTranscoding) { EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(response_data, false)); EXPECT_EQ(2, response_data.length()); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "0"}}; Http::TestHeaderMapImpl expected_response_trailers{{"grpc-status", "0"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers)); EXPECT_EQ(expected_response_trailers, response_trailers); } TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryPost) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"content-type", "application/json"}, {":method", "POST"}, {":path", "/shelf"}}; EXPECT_CALL(decoder_callbacks_, clearRouteCache()); @@ -409,15 +409,15 @@ TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryPost) { EXPECT_EQ(expected_request.ByteSize(), frames[0].length_); EXPECT_TRUE(MessageDifferencer::Equals(expected_request, request)); - Http::TestHeaderMapImpl continue_headers{{":status", "000"}}; + Http::TestResponseHeaderMapImpl continue_headers{{":status", "000"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encode100ContinueHeaders(continue_headers)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_.encodeMetadata(metadata_map)); - Http::TestHeaderMapImpl response_headers{{"content-type", "application/grpc"}, - {":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{"content-type", "application/grpc"}, + {":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.encodeHeaders(response_headers, false)); @@ -436,13 +436,13 @@ TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryPost) { EXPECT_EQ("{\"id\":\"20\",\"theme\":\"Children\"}", response_json); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}, {"grpc-message", ""}}; + Http::TestRequestTrailerMapImpl request_trailers; - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(response_trailers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); } TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryPostWithPackageServiceMethodPath) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"content-type", "application/json"}, {":method", "POST"}, {":path", "/bookstore.Bookstore/CreateShelfWithPackageServiceAndMethod"}}; @@ -476,12 +476,12 @@ TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryPostWithPackageServiceMetho EXPECT_EQ(expected_request.ByteSize(), frames[0].length_); EXPECT_TRUE(MessageDifferencer::Equals(expected_request, request)); - Http::TestHeaderMapImpl continue_headers{{":status", "000"}}; + Http::TestResponseHeaderMapImpl continue_headers{{":status", "000"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encode100ContinueHeaders(continue_headers)); - Http::TestHeaderMapImpl response_headers{{"content-type", "application/grpc"}, - {":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{"content-type", "application/grpc"}, + {":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.encodeHeaders(response_headers, false)); @@ -500,13 +500,13 @@ TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryPostWithPackageServiceMetho EXPECT_EQ("{\"id\":\"20\",\"theme\":\"Children\"}", response_json); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}, {"grpc-message", ""}}; + Http::TestRequestTrailerMapImpl request_trailers; - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(response_trailers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); } TEST_F(GrpcJsonTranscoderFilterTest, ForwardUnaryPostGrpc) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"content-type", "application/grpc"}, {":method", "POST"}, {":path", "/bookstore.Bookstore/CreateShelfWithPackageServiceAndMethod"}}; @@ -537,12 +537,12 @@ TEST_F(GrpcJsonTranscoderFilterTest, ForwardUnaryPostGrpc) { EXPECT_EQ(expected_request.ByteSize(), frames[0].length_); EXPECT_TRUE(MessageDifferencer::Equals(expected_request, forwarded_request)); - Http::TestHeaderMapImpl continue_headers{{":status", "000"}}; + Http::TestResponseHeaderMapImpl continue_headers{{":status", "000"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encode100ContinueHeaders(continue_headers)); - Http::TestHeaderMapImpl response_headers{{"content-type", "application/grpc"}, - {":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{"content-type", "application/grpc"}, + {":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("application/grpc", response_headers.get_("content-type")); @@ -568,8 +568,8 @@ TEST_F(GrpcJsonTranscoderFilterTest, ForwardUnaryPostGrpc) { EXPECT_EQ(expected_response.ByteSize(), frames[0].length_); EXPECT_TRUE(MessageDifferencer::Equals(expected_response, forwarded_response)); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}, {"grpc-message", ""}}; - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(response_trailers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); } class GrpcJsonTranscoderFilterSkipRecalculatingTest : public GrpcJsonTranscoderFilterTest { @@ -587,7 +587,7 @@ class GrpcJsonTranscoderFilterSkipRecalculatingTest : public GrpcJsonTranscoderF }; TEST_F(GrpcJsonTranscoderFilterSkipRecalculatingTest, TranscodingUnaryPostSkipRecalculate) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"content-type", "application/json"}, {":method", "POST"}, {":path", "/shelf"}}; EXPECT_CALL(decoder_callbacks_, clearRouteCache()).Times(0); @@ -605,7 +605,7 @@ TEST_F(GrpcJsonTranscoderFilterSkipRecalculatingTest, TranscodingUnaryPostSkipRe } TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryError) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"content-type", "application/json"}, {":method", "POST"}, {":path", "/shelf"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); @@ -628,7 +628,7 @@ TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryError) { } TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryTimeout) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"content-type", "application/json"}, {":method", "POST"}, {":path", "/shelf"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); @@ -640,14 +640,14 @@ TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryTimeout) { EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(request_data, true)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "504"}, {"content-length", "24"}, {"content-type", "text/plain"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(request_data, true)); } TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryNotGrpcResponse) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"content-type", "application/json"}, {":method", "POST"}, {":path", "/shelf"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); @@ -659,14 +659,14 @@ TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryNotGrpcResponse) { EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(request_data, true)); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"content-length", "24"}, {"content-type", "text/plain"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(request_data, true)); } TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryWithHttpBodyAsOutput) { - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, {":path", "/index"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, {":path", "/index"}}; EXPECT_CALL(decoder_callbacks_, clearRouteCache()); @@ -676,8 +676,8 @@ TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryWithHttpBodyAsOutput) { EXPECT_EQ("/bookstore.Bookstore/GetIndex", request_headers.get_(":path")); EXPECT_EQ("trailers", request_headers.get_("te")); - Http::TestHeaderMapImpl response_headers{{"content-type", "application/grpc"}, - {":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{"content-type", "application/grpc"}, + {":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.encodeHeaders(response_headers, false)); @@ -695,12 +695,12 @@ TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryWithHttpBodyAsOutput) { EXPECT_EQ(response.content_type(), response_headers.get_("content-type")); EXPECT_EQ(response.data(), response_data->toString()); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}, {"grpc-message", ""}}; - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(response_trailers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); } TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryWithHttpBodyAsOutputAndSplitTwoEncodeData) { - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, {":path", "/index"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, {":path", "/index"}}; EXPECT_CALL(decoder_callbacks_, clearRouteCache()); @@ -710,8 +710,8 @@ TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryWithHttpBodyAsOutputAndSpli EXPECT_EQ("/bookstore.Bookstore/GetIndex", request_headers.get_(":path")); EXPECT_EQ("trailers", request_headers.get_("te")); - Http::TestHeaderMapImpl response_headers{{"content-type", "application/grpc"}, - {":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{"content-type", "application/grpc"}, + {":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.encodeHeaders(response_headers, false)); @@ -739,8 +739,8 @@ TEST_F(GrpcJsonTranscoderFilterTest, TranscodingUnaryWithHttpBodyAsOutputAndSpli EXPECT_EQ(response.content_type(), response_headers.get_("content-type")); EXPECT_EQ(response.data(), response_data->toString()); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}, {"grpc-message", ""}}; - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(response_trailers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); } class GrpcJsonTranscoderFilterGrpcStatusTest : public GrpcJsonTranscoderFilterTest { @@ -753,14 +753,14 @@ class GrpcJsonTranscoderFilterGrpcStatusTest : public GrpcJsonTranscoderFilterTe void SetUp() override { EXPECT_CALL(decoder_callbacks_, clearRouteCache()); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"content-type", "application/json"}, {":method", "POST"}, {":path", "/shelf"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); Buffer::OwnedImpl request_data{R"({"theme": "Children"})"}; EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(request_data, true)); - Http::TestHeaderMapImpl continue_headers{{":status", "000"}}; + Http::TestResponseHeaderMapImpl continue_headers{{":status", "000"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encode100ContinueHeaders(continue_headers)); } @@ -796,10 +796,10 @@ TEST_F(GrpcJsonTranscoderFilterConvertGrpcStatusTest, TranscodingTextHeadersInTr EXPECT_EQ(expected_response, data.toString()); })); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, - {"content-type", "application/grpc"}, - {"grpc-status", "5"}, - {"grpc-message", "Resource not found"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"content-type", "application/grpc"}, + {"grpc-status", "5"}, + {"grpc-message", "Resource not found"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, true)); EXPECT_EQ("404", response_headers.get_(":status")); EXPECT_EQ("application/json", response_headers.get_("content-type")); @@ -816,7 +816,7 @@ TEST_F(GrpcJsonTranscoderFilterConvertGrpcStatusTest, EXPECT_EQ(expected_response, data.toString()); })); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"content-type", "application/grpc"}, {"grpc-status", "5"}, @@ -842,7 +842,7 @@ TEST_F(GrpcJsonTranscoderFilterConvertGrpcStatusTest, EXPECT_EQ(expected_response, data.toString()); })); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"content-type", "application/grpc"}, {"grpc-status", "5"}, @@ -855,8 +855,8 @@ TEST_F(GrpcJsonTranscoderFilterConvertGrpcStatusTest, // Response with a header frame and a trailer frame. // (E.g. a gRPC server sends metadata and then it sends an error.) TEST_F(GrpcJsonTranscoderFilterConvertGrpcStatusTest, TranscodingStatusFromTrailer) { - Http::TestHeaderMapImpl response_headers{{"content-type", "application/grpc"}, - {":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{"content-type", "application/grpc"}, + {":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.encodeHeaders(response_headers, false)); @@ -866,7 +866,7 @@ TEST_F(GrpcJsonTranscoderFilterConvertGrpcStatusTest, TranscodingStatusFromTrail .WillOnce(Invoke([&expected_response](Buffer::Instance& data, bool) { EXPECT_EQ(expected_response, data.toString()); })); - Http::TestHeaderMapImpl response_trailers{ + Http::TestResponseTrailerMapImpl response_trailers{ {"grpc-status", "5"}, {"grpc-message", "unused"}, {"grpc-status-details-bin", "CAUSElJlc291cmNlIG5vdCBmb3VuZA"}}; @@ -879,12 +879,13 @@ TEST_F(GrpcJsonTranscoderFilterConvertGrpcStatusTest, TranscodingStatusFromTrail } TEST_F(GrpcJsonTranscoderFilterGrpcStatusTest, TranscodingInvalidGrpcStatusFromTrailer) { - Http::TestHeaderMapImpl response_headers{{"content-type", "application/grpc"}, - {":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{"content-type", "application/grpc"}, + {":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("application/json", response_headers.get_("content-type")); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "1024"}, {"grpc-message", "message"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "1024"}, + {"grpc-message", "message"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers)); EXPECT_EQ("500", response_headers.get_(":status")); EXPECT_EQ("application/json", response_headers.get_("content-type")); @@ -894,8 +895,8 @@ TEST_F(GrpcJsonTranscoderFilterGrpcStatusTest, TranscodingInvalidGrpcStatusFromT // Server sends a response body, don't replace it. TEST_F(GrpcJsonTranscoderFilterConvertGrpcStatusTest, SkipTranscodingStatusIfBodyIsPresent) { - Http::TestHeaderMapImpl response_headers{{"content-type", "application/grpc"}, - {":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{"content-type", "application/grpc"}, + {":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.encodeHeaders(response_headers, false)); @@ -914,8 +915,8 @@ TEST_F(GrpcJsonTranscoderFilterConvertGrpcStatusTest, SkipTranscodingStatusIfBod EXPECT_CALL(encoder_callbacks_, addEncodedData(_, _)).Times(0); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "2"}, {"grpc-message", "not good"}}; - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(response_trailers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); } struct GrpcJsonTranscoderFilterPrintTestParam { @@ -948,7 +949,7 @@ class GrpcJsonTranscoderFilterPrintTest }; TEST_P(GrpcJsonTranscoderFilterPrintTest, PrintOptions) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"content-type", "application/json"}, {":method", "GET"}, {":path", "/authors/101"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); diff --git a/test/extensions/filters/http/grpc_stats/config_test.cc b/test/extensions/filters/http/grpc_stats/config_test.cc index 34389c2c6e..f170badb49 100644 --- a/test/extensions/filters/http/grpc_stats/config_test.cc +++ b/test/extensions/filters/http/grpc_stats/config_test.cc @@ -45,18 +45,19 @@ class GrpcStatsFilterConfigTest : public testing::Test { TEST_F(GrpcStatsFilterConfigTest, StatsHttp2HeaderOnlyResponse) { initialize(false); - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc"}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "application/grpc"}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); - Http::TestHeaderMapImpl continue_headers{{":status", "100"}}; + Http::TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(continue_headers)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->encodeMetadata(metadata_map)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "1"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "1"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, true)); EXPECT_EQ(1UL, decoder_callbacks_.clusterInfo() ->statsScope() @@ -71,16 +72,17 @@ TEST_F(GrpcStatsFilterConfigTest, StatsHttp2HeaderOnlyResponse) { TEST_F(GrpcStatsFilterConfigTest, StatsHttp2NormalResponse) { initialize(false); - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc"}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "application/grpc"}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(data, false)); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "0"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers)); EXPECT_EQ(1UL, decoder_callbacks_.clusterInfo() ->statsScope() @@ -95,14 +97,15 @@ TEST_F(GrpcStatsFilterConfigTest, StatsHttp2NormalResponse) { TEST_F(GrpcStatsFilterConfigTest, StatsHttp2ContentTypeGrpcPlusProto) { initialize(false); - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc+proto"}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "application/grpc+proto"}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, false)); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "0"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers)); EXPECT_EQ(1UL, decoder_callbacks_.clusterInfo() ->statsScope() @@ -117,8 +120,9 @@ TEST_F(GrpcStatsFilterConfigTest, StatsHttp2ContentTypeGrpcPlusProto) { TEST_F(GrpcStatsFilterConfigTest, MessageCounts) { initialize(true); - Http::TestHeaderMapImpl request_headers{{"content-type", "application/grpc+proto"}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", "application/grpc+proto"}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); ProtobufWkt::Value v1; @@ -144,8 +148,8 @@ TEST_F(GrpcStatsFilterConfigTest, MessageCounts) { EXPECT_EQ(2U, data.request_message_count); EXPECT_EQ(0U, data.response_message_count); - Http::TestHeaderMapImpl response_headers{{"content-type", "application/grpc+proto"}, - {":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{"content-type", "application/grpc+proto"}, + {":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, false)); Buffer::OwnedImpl buffer; diff --git a/test/extensions/filters/http/grpc_web/grpc_web_filter_integration_test.cc b/test/extensions/filters/http/grpc_web/grpc_web_filter_integration_test.cc index ae8bfbd477..486661767b 100644 --- a/test/extensions/filters/http/grpc_web/grpc_web_filter_integration_test.cc +++ b/test/extensions/filters/http/grpc_web/grpc_web_filter_integration_test.cc @@ -25,17 +25,19 @@ TEST_P(GrpcWebFilterIntegrationTest, GRPCWebTrailersNotDuplicated) { config_helper_.addConfigModifier(setEnableDownstreamTrailersHttp1()); setUpstreamProtocol(FakeHttpConnection::Type::HTTP2); - Http::TestHeaderMapImpl request_trailers{{"request1", "trailer1"}, {"request2", "trailer2"}}; - Http::TestHeaderMapImpl response_trailers{{"response1", "trailer1"}, {"response2", "trailer2"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"request1", "trailer1"}, + {"request2", "trailer2"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"response1", "trailer1"}, + {"response2", "trailer2"}}; initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {"content-type", "application/grpc-web"}, - {":authority", "host"}}); + auto encoder_decoder = codec_client_->startRequest( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {"content-type", "application/grpc-web"}, + {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); codec_client_->sendData(*request_encoder_, 1, false); diff --git a/test/extensions/filters/http/grpc_web/grpc_web_filter_test.cc b/test/extensions/filters/http/grpc_web/grpc_web_filter_test.cc index 538716f554..0e3f029f94 100644 --- a/test/extensions/filters/http/grpc_web/grpc_web_filter_test.cc +++ b/test/extensions/filters/http/grpc_web/grpc_web_filter_test.cc @@ -111,6 +111,9 @@ class GrpcWebFilterTest : public testing::TestWithParam decoder_callbacks_; NiceMock encoder_callbacks_; + Http::TestRequestTrailerMapImpl request_trailers_; + Http::TestResponseHeaderMapImpl response_headers_; + Http::TestResponseTrailerMapImpl response_trailers_; }; TEST_F(GrpcWebFilterTest, SupportedContentTypes) { @@ -120,7 +123,7 @@ TEST_F(GrpcWebFilterTest, SupportedContentTypes) { Http::Headers::get().ContentTypeValues.GrpcWebText, Http::Headers::get().ContentTypeValues.GrpcWebTextProto}; for (auto& content_type : supported_content_types) { - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; request_headers.addCopy(Http::Headers::get().ContentType, content_type); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; @@ -132,31 +135,31 @@ TEST_F(GrpcWebFilterTest, SupportedContentTypes) { TEST_F(GrpcWebFilterTest, UnsupportedContentType) { Buffer::OwnedImpl data; - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; request_headers.addCopy(Http::Headers::get().ContentType, "unsupported"); 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_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(GrpcWebFilterTest, NoContentType) { Buffer::OwnedImpl data; - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; 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_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(request_headers, false)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(request_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_)); } TEST_F(GrpcWebFilterTest, InvalidBase64) { - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; request_headers.addCopy(Http::Headers::get().ContentType, Http::Headers::get().ContentTypeValues.GrpcWebText); expectErrorResponse(Http::Code::BadRequest, "Bad gRPC-web request, invalid base64 data."); @@ -172,7 +175,7 @@ TEST_F(GrpcWebFilterTest, InvalidBase64) { } TEST_F(GrpcWebFilterTest, Base64NoPadding) { - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; request_headers.addCopy(Http::Headers::get().ContentType, Http::Headers::get().ContentTypeValues.GrpcWebText); expectErrorResponse(Http::Code::BadRequest, "Bad gRPC-web request, invalid base64 data."); @@ -188,8 +191,9 @@ TEST_F(GrpcWebFilterTest, Base64NoPadding) { } TEST_P(GrpcWebFilterTest, StatsNoCluster) { - Http::TestHeaderMapImpl request_headers{{"content-type", request_content_type()}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", request_content_type()}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_CALL(decoder_callbacks_, clusterInfo()).WillOnce(Return(nullptr)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); @@ -197,22 +201,23 @@ TEST_P(GrpcWebFilterTest, StatsNoCluster) { } TEST_P(GrpcWebFilterTest, StatsNormalResponse) { - Http::TestHeaderMapImpl request_headers{{"content-type", request_content_type()}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", request_content_type()}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); - Http::TestHeaderMapImpl continue_headers{{":status", "100"}}; + Http::TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encode100ContinueHeaders(continue_headers)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_.encodeMetadata(metadata_map)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data, false)); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "0"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "0"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers)); EXPECT_EQ(1UL, decoder_callbacks_.clusterInfo() ->statsScope() @@ -225,14 +230,15 @@ TEST_P(GrpcWebFilterTest, StatsNormalResponse) { } TEST_P(GrpcWebFilterTest, StatsErrorResponse) { - Http::TestHeaderMapImpl request_headers{{"content-type", request_content_type()}, - {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"content-type", request_content_type()}, + {":path", "/lyft.users.BadCompanions/GetBadCompanions"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(request_headers, false)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data, false)); - Http::TestHeaderMapImpl response_trailers{{"grpc-status", "1"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"grpc-status", "1"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers)); EXPECT_EQ(1UL, decoder_callbacks_.clusterInfo() ->statsScope() @@ -246,7 +252,7 @@ TEST_P(GrpcWebFilterTest, StatsErrorResponse) { TEST_P(GrpcWebFilterTest, Unary) { // Tests request headers. - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; request_headers.addCopy(Http::Headers::get().ContentType, request_content_type()); request_headers.addCopy(Http::Headers::get().Accept, request_accept()); request_headers.addCopy(Http::Headers::get().ContentLength, uint64_t(8)); @@ -288,15 +294,15 @@ TEST_P(GrpcWebFilterTest, Unary) { } // Tests request trailers, they are passed through. - Http::TestHeaderMapImpl request_trailers; + Http::TestRequestTrailerMapImpl request_trailers; request_trailers.addCopy(Http::Headers::get().GrpcStatus, "0"); request_trailers.addCopy(Http::Headers::get().GrpcMessage, "ok"); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_)); EXPECT_EQ("0", request_trailers.GrpcStatus()->value().getStringView()); EXPECT_EQ("ok", request_trailers.GrpcMessage()->value().getStringView()); // Tests response headers. - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; response_headers.addCopy(Http::Headers::get().Status, "200"); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers, false)); EXPECT_EQ("200", response_headers.get_(Http::Headers::get().Status.get())); @@ -343,7 +349,7 @@ TEST_P(GrpcWebFilterTest, Unary) { Buffer::OwnedImpl trailers_buffer; EXPECT_CALL(encoder_callbacks_, addEncodedData(_, true)) .WillOnce(Invoke([&](Buffer::Instance& data, bool) { trailers_buffer.move(data); })); - Http::TestHeaderMapImpl response_trailers; + Http::TestResponseTrailerMapImpl response_trailers; response_trailers.addCopy(Http::Headers::get().GrpcStatus, "0"); response_trailers.addCopy(Http::Headers::get().GrpcMessage, "ok"); EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers)); diff --git a/test/extensions/filters/http/gzip/gzip_filter_integration_test.cc b/test/extensions/filters/http/gzip/gzip_filter_integration_test.cc index 424356e2dc..09df3cab4d 100644 --- a/test/extensions/filters/http/gzip/gzip_filter_integration_test.cc +++ b/test/extensions/filters/http/gzip/gzip_filter_integration_test.cc @@ -96,14 +96,14 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, GzipIntegrationTest, */ TEST_P(GzipIntegrationTest, AcceptanceDefaultConfigTest) { initializeFilter(default_config); - doRequestAndCompression(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"accept-encoding", "deflate, gzip"}}, - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-length", "4400"}, - {"content-type", "text/xml"}}); + doRequestAndCompression(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"accept-encoding", "deflate, gzip"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-length", "4400"}, + {"content-type", "text/xml"}}); } /** @@ -111,14 +111,14 @@ TEST_P(GzipIntegrationTest, AcceptanceDefaultConfigTest) { */ TEST_P(GzipIntegrationTest, AcceptanceFullConfigTest) { initializeFilter(full_config); - doRequestAndCompression(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"accept-encoding", "deflate, gzip"}}, - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-length", "4400"}, - {"content-type", "application/json"}}); + doRequestAndCompression(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"accept-encoding", "deflate, gzip"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-length", "4400"}, + {"content-type", "application/json"}}); } /** @@ -126,14 +126,14 @@ TEST_P(GzipIntegrationTest, AcceptanceFullConfigTest) { */ TEST_P(GzipIntegrationTest, IdentityAcceptEncoding) { initializeFilter(default_config); - doRequestAndNoCompression(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"accept-encoding", "identity"}}, - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-length", "128"}, - {"content-type", "text/plain"}}); + doRequestAndNoCompression(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"accept-encoding", "identity"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-length", "128"}, + {"content-type", "text/plain"}}); } /** @@ -141,14 +141,14 @@ TEST_P(GzipIntegrationTest, IdentityAcceptEncoding) { */ TEST_P(GzipIntegrationTest, NotSupportedAcceptEncoding) { initializeFilter(default_config); - doRequestAndNoCompression(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"accept-encoding", "deflate, br"}}, - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-length", "128"}, - {"content-type", "text/plain"}}); + doRequestAndNoCompression(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"accept-encoding", "deflate, br"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-length", "128"}, + {"content-type", "text/plain"}}); } /** @@ -156,16 +156,16 @@ TEST_P(GzipIntegrationTest, NotSupportedAcceptEncoding) { */ TEST_P(GzipIntegrationTest, UpstreamResponseAlreadyEncoded) { initializeFilter(default_config); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"accept-encoding", "deflate, gzip"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"accept-encoding", "deflate, gzip"}}; - Http::TestHeaderMapImpl response_headers{{":status", "200"}, - {"content-encoding", "br"}, - {"content-length", "128"}, - {"content-type", "application/json"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"content-encoding", "br"}, + {"content-length", "128"}, + {"content-type", "application/json"}}; auto response = sendRequestAndWaitForResponse(request_headers, 0, response_headers, 128); @@ -182,13 +182,13 @@ TEST_P(GzipIntegrationTest, UpstreamResponseAlreadyEncoded) { */ TEST_P(GzipIntegrationTest, NotEnoughContentLength) { initializeFilter(default_config); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"accept-encoding", "deflate, gzip"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"accept-encoding", "deflate, gzip"}}; - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"content-length", "10"}, {"content-type", "application/json"}}; auto response = sendRequestAndWaitForResponse(request_headers, 0, response_headers, 10); @@ -206,13 +206,13 @@ TEST_P(GzipIntegrationTest, NotEnoughContentLength) { */ TEST_P(GzipIntegrationTest, EmptyResponse) { initializeFilter(default_config); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"accept-encoding", "deflate, gzip"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"accept-encoding", "deflate, gzip"}}; - Http::TestHeaderMapImpl response_headers{{":status", "204"}, {"content-length", "0"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "204"}, {"content-length", "0"}}; auto response = sendRequestAndWaitForResponse(request_headers, 0, response_headers, 0); @@ -229,14 +229,14 @@ TEST_P(GzipIntegrationTest, EmptyResponse) { */ TEST_P(GzipIntegrationTest, SkipOnContentType) { initializeFilter(full_config); - doRequestAndNoCompression(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"accept-encoding", "deflate, gzip"}}, - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-length", "128"}, - {"content-type", "application/xml"}}); + doRequestAndNoCompression(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"accept-encoding", "deflate, gzip"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-length", "128"}, + {"content-type", "application/xml"}}); } /** @@ -244,15 +244,15 @@ TEST_P(GzipIntegrationTest, SkipOnContentType) { */ TEST_P(GzipIntegrationTest, SkipOnCacheControl) { initializeFilter(full_config); - doRequestAndNoCompression(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"accept-encoding", "deflate, gzip"}}, - Http::TestHeaderMapImpl{{":status", "200"}, - {"content-length", "128"}, - {"cache-control", "no-transform"}, - {"content-type", "application/json"}}); + doRequestAndNoCompression(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"accept-encoding", "deflate, gzip"}}, + Http::TestResponseHeaderMapImpl{{":status", "200"}, + {"content-length", "128"}, + {"cache-control", "no-transform"}, + {"content-type", "application/json"}}); } /** @@ -260,14 +260,14 @@ TEST_P(GzipIntegrationTest, SkipOnCacheControl) { */ TEST_P(GzipIntegrationTest, AcceptanceFullConfigChunkedResponse) { initializeFilter(full_config); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"accept-encoding", "deflate, gzip"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"accept-encoding", "deflate, gzip"}}; - Http::TestHeaderMapImpl response_headers{{":status", "200"}, - {"content-type", "application/json"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {"content-type", "application/json"}}; auto response = sendRequestAndWaitForResponse(request_headers, 0, response_headers, 1024); @@ -284,13 +284,13 @@ TEST_P(GzipIntegrationTest, AcceptanceFullConfigChunkedResponse) { */ TEST_P(GzipIntegrationTest, AcceptanceFullConfigVeryHeader) { initializeFilter(default_config); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"accept-encoding", "deflate, gzip"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"accept-encoding", "deflate, gzip"}}; - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"content-type", "application/json"}, {"vary", "Cookie"}}; auto response = sendRequestAndWaitForResponse(request_headers, 0, response_headers, 1024); diff --git a/test/extensions/filters/http/gzip/gzip_filter_test.cc b/test/extensions/filters/http/gzip/gzip_filter_test.cc index 07ec8e7082..f814e5354d 100644 --- a/test/extensions/filters/http/gzip/gzip_filter_test.cc +++ b/test/extensions/filters/http/gzip/gzip_filter_test.cc @@ -94,11 +94,11 @@ class GzipFilterTest : public testing::Test { data_.drain(data_len); } - void doRequest(Http::TestHeaderMapImpl&& headers, bool end_stream) { + void doRequest(Http::TestRequestHeaderMapImpl&& headers, bool end_stream) { EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, end_stream)); } - void doResponseCompression(Http::TestHeaderMapImpl&& headers, bool with_trailers) { + void doResponseCompression(Http::TestResponseHeaderMapImpl&& headers, bool with_trailers) { uint64_t content_length; ASSERT_TRUE(absl::SimpleAtoi(headers.get_("content-length"), &content_length)); feedBuffer(content_length); @@ -110,7 +110,8 @@ class GzipFilterTest : public testing::Test { Buffer::OwnedImpl trailers_buffer; EXPECT_CALL(encoder_callbacks_, addEncodedData(_, true)) .WillOnce(Invoke([&](Buffer::Instance& data, bool) { data_.move(data); })); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(headers)); + Http::TestResponseTrailerMapImpl trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(trailers)); } verifyCompressedData(content_length); drainBuffer(); @@ -160,11 +161,11 @@ class GzipFilterTest : public testing::Test { EXPECT_EQ(8, config_->contentTypeValues().size()); } - void doResponseNoCompression(Http::TestHeaderMapImpl&& headers) { + void doResponseNoCompression(Http::TestResponseHeaderMapImpl&& headers) { uint64_t content_length; ASSERT_TRUE(absl::SimpleAtoi(headers.get_("content-length"), &content_length)); feedBuffer(content_length); - Http::TestHeaderMapImpl continue_headers; + Http::TestResponseHeaderMapImpl continue_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(continue_headers)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; @@ -172,7 +173,7 @@ class GzipFilterTest : public testing::Test { EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); EXPECT_EQ("", headers.get_("content-encoding")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(data_, false)); - Http::TestHeaderMapImpl trailers; + Http::TestResponseTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(trailers)); EXPECT_EQ(1, stats_.counter("test.gzip.not_compressed").value()); } @@ -232,7 +233,7 @@ TEST_F(GzipFilterTest, AcceptanceGzipEncoding) { EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->decodeMetadata(metadata_map)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); doResponseCompression({{":method", "get"}, {"content-length", "256"}}, false); } @@ -241,7 +242,7 @@ TEST_F(GzipFilterTest, AcceptanceGzipEncodingWithTrailers) { doRequest({{":method", "get"}, {"accept-encoding", "deflate, gzip"}}, false); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl trailers; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); doResponseCompression({{":method", "get"}, {"content-length", "256"}}, true); } @@ -249,15 +250,15 @@ TEST_F(GzipFilterTest, AcceptanceGzipEncodingWithTrailers) { // Verifies isAcceptEncodingAllowed function. TEST_F(GzipFilterTest, hasCacheControlNoTransform) { { - Http::TestHeaderMapImpl headers = {{"cache-control", "no-cache"}}; + Http::TestRequestHeaderMapImpl headers = {{"cache-control", "no-cache"}}; EXPECT_FALSE(hasCacheControlNoTransform(headers)); } { - Http::TestHeaderMapImpl headers = {{"cache-control", "no-transform"}}; + Http::TestRequestHeaderMapImpl headers = {{"cache-control", "no-transform"}}; EXPECT_TRUE(hasCacheControlNoTransform(headers)); } { - Http::TestHeaderMapImpl headers = {{"cache-control", "No-Transform"}}; + Http::TestRequestHeaderMapImpl headers = {{"cache-control", "No-Transform"}}; EXPECT_TRUE(hasCacheControlNoTransform(headers)); } } @@ -280,113 +281,113 @@ TEST_F(GzipFilterTest, hasCacheControlNoTransformCompression) { // Verifies isAcceptEncodingAllowed function. TEST_F(GzipFilterTest, isAcceptEncodingAllowed) { { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip, br"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip, br"}}; EXPECT_TRUE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(1, stats_.counter("test.gzip.header_gzip").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip;q=1.0, *;q=0.5"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip;q=1.0, *;q=0.5"}}; EXPECT_TRUE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(2, stats_.counter("test.gzip.header_gzip").value()); } { - Http::TestHeaderMapImpl headers = { + Http::TestRequestHeaderMapImpl headers = { {"accept-encoding", "\tdeflate\t, gzip\t ; q\t =\t 1.0,\t * ;q=0.5"}}; EXPECT_TRUE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(3, stats_.counter("test.gzip.header_gzip").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "deflate,gzip;q=1.0,*;q=0"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "deflate,gzip;q=1.0,*;q=0"}}; EXPECT_TRUE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(4, stats_.counter("test.gzip.header_gzip").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip;q=0.2, br;q=1"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip;q=0.2, br;q=1"}}; EXPECT_TRUE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(5, stats_.counter("test.gzip.header_gzip").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "*"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "*"}}; EXPECT_TRUE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(1, stats_.counter("test.gzip.header_wildcard").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "*;q=1"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "*;q=1"}}; EXPECT_TRUE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(2, stats_.counter("test.gzip.header_wildcard").value()); } { // gzip header is not valid due to q=0. - Http::TestHeaderMapImpl headers = {{"accept-encoding", "gzip;q=0,*;q=1"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "gzip;q=0,*;q=1"}}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(5, stats_.counter("test.gzip.header_gzip").value()); EXPECT_EQ(1, stats_.counter("test.gzip.header_not_valid").value()); } { - Http::TestHeaderMapImpl headers = {}; + Http::TestRequestHeaderMapImpl headers = {}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(1, stats_.counter("test.gzip.no_accept_header").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "identity, *;q=0"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "identity, *;q=0"}}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(1, stats_.counter("test.gzip.header_identity").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "identity;q=0.5, *;q=0"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "identity;q=0.5, *;q=0"}}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(2, stats_.counter("test.gzip.header_identity").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "identity;q=0, *;q=0"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "identity;q=0, *;q=0"}}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(3, stats_.counter("test.gzip.header_identity").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "xyz;q=1, br;q=0.2, *"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "xyz;q=1, br;q=0.2, *"}}; EXPECT_TRUE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(3, stats_.counter("test.gzip.header_wildcard").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "xyz;q=1, br;q=0.2, *;q=0"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "xyz;q=1, br;q=0.2, *;q=0"}}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(3, stats_.counter("test.gzip.header_wildcard").value()); EXPECT_EQ(2, stats_.counter("test.gzip.header_not_valid").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "xyz;q=1, br;q=0.2"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "xyz;q=1, br;q=0.2"}}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(3, stats_.counter("test.gzip.header_not_valid").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "identity"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "identity"}}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(4, stats_.counter("test.gzip.header_identity").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "identity;q=1"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "identity;q=1"}}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(5, stats_.counter("test.gzip.header_identity").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "identity;q=0"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "identity;q=0"}}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(6, stats_.counter("test.gzip.header_identity").value()); } { // Test that we return identity and ignore the invalid wildcard. - Http::TestHeaderMapImpl headers = {{"accept-encoding", "identity, *;q=0"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "identity, *;q=0"}}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(7, stats_.counter("test.gzip.header_identity").value()); EXPECT_EQ(3, stats_.counter("test.gzip.header_not_valid").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip;Q=.5, br"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip;Q=.5, br"}}; EXPECT_TRUE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(6, stats_.counter("test.gzip.header_gzip").value()); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "identity;Q=0"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "identity;Q=0"}}; EXPECT_FALSE(isAcceptEncodingAllowed(headers)); EXPECT_EQ(8, stats_.counter("test.gzip.header_identity").value()); } @@ -407,33 +408,33 @@ TEST_F(GzipFilterTest, AcceptEncodingCompression) { // Verifies isMinimumContentLength function. TEST_F(GzipFilterTest, isMinimumContentLength) { { - Http::TestHeaderMapImpl headers = {{"content-length", "31"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-length", "31"}}; EXPECT_TRUE(isMinimumContentLength(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-length", "29"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-length", "29"}}; EXPECT_FALSE(isMinimumContentLength(headers)); } { - Http::TestHeaderMapImpl headers = {{"transfer-encoding", "chunked"}}; + Http::TestRequestHeaderMapImpl headers = {{"transfer-encoding", "chunked"}}; EXPECT_TRUE(isMinimumContentLength(headers)); } { - Http::TestHeaderMapImpl headers = {{"transfer-encoding", "Chunked"}}; + Http::TestRequestHeaderMapImpl headers = {{"transfer-encoding", "Chunked"}}; EXPECT_TRUE(isMinimumContentLength(headers)); } setUpFilter(R"EOF({"content_length": 500})EOF"); { - Http::TestHeaderMapImpl headers = {{"content-length", "501"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-length", "501"}}; EXPECT_TRUE(isMinimumContentLength(headers)); } { - Http::TestHeaderMapImpl headers = {{"transfer-encoding", "chunked"}}; + Http::TestRequestHeaderMapImpl headers = {{"transfer-encoding", "chunked"}}; EXPECT_TRUE(isMinimumContentLength(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-length", "499"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-length", "499"}}; EXPECT_FALSE(isMinimumContentLength(headers)); } } @@ -455,51 +456,51 @@ TEST_F(GzipFilterTest, ContentLengthCompression) { TEST_F(GzipFilterTest, isContentTypeAllowed) { { - Http::TestHeaderMapImpl headers = {{"content-type", "text/html"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "text/html"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "text/xml"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "text/xml"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "text/plain"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "text/plain"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "application/javascript"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "application/javascript"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "image/svg+xml"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "image/svg+xml"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "application/json;charset=utf-8"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "application/json;charset=utf-8"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "application/json"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "application/json"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "application/xhtml+xml"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "application/xhtml+xml"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "Application/XHTML+XML"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "Application/XHTML+XML"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "image/jpeg"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "image/jpeg"}}; EXPECT_FALSE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {}; + Http::TestRequestHeaderMapImpl headers = {}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "\ttext/html\t"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "\ttext/html\t"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } @@ -514,23 +515,23 @@ TEST_F(GzipFilterTest, isContentTypeAllowed) { )EOF"); { - Http::TestHeaderMapImpl headers = {{"content-type", "xyz/svg+xml"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "xyz/svg+xml"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {}; + Http::TestRequestHeaderMapImpl headers = {}; EXPECT_TRUE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "xyz/false"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "xyz/false"}}; EXPECT_FALSE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "image/jpeg"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "image/jpeg"}}; EXPECT_FALSE(isContentTypeAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"content-type", "test/insensitive"}}; + Http::TestRequestHeaderMapImpl headers = {{"content-type", "test/insensitive"}}; EXPECT_TRUE(isContentTypeAllowed(headers)); } } @@ -568,18 +569,18 @@ TEST_F(GzipFilterTest, ContentTypeCompression) { TEST_F(GzipFilterTest, sanitizeEtagHeader) { { std::string etag_header{R"EOF(W/"686897696a7c876b7e")EOF"}; - Http::TestHeaderMapImpl headers = {{"etag", etag_header}}; + Http::TestRequestHeaderMapImpl headers = {{"etag", etag_header}}; sanitizeEtagHeader(headers); EXPECT_EQ(etag_header, headers.get_("etag")); } { std::string etag_header{R"EOF(w/"686897696a7c876b7e")EOF"}; - Http::TestHeaderMapImpl headers = {{"etag", etag_header}}; + Http::TestRequestHeaderMapImpl headers = {{"etag", etag_header}}; sanitizeEtagHeader(headers); EXPECT_EQ(etag_header, headers.get_("etag")); } { - Http::TestHeaderMapImpl headers = {{"etag", "686897696a7c876b7e"}}; + Http::TestRequestHeaderMapImpl headers = {{"etag", "686897696a7c876b7e"}}; sanitizeEtagHeader(headers); EXPECT_FALSE(headers.has("etag")); } @@ -588,34 +589,34 @@ TEST_F(GzipFilterTest, sanitizeEtagHeader) { // Verifies isEtagAllowed function. TEST_F(GzipFilterTest, isEtagAllowed) { { - Http::TestHeaderMapImpl headers = {{"etag", R"EOF(W/"686897696a7c876b7e")EOF"}}; + Http::TestRequestHeaderMapImpl headers = {{"etag", R"EOF(W/"686897696a7c876b7e")EOF"}}; EXPECT_TRUE(isEtagAllowed(headers)); EXPECT_EQ(0, stats_.counter("test.gzip.not_compressed_etag").value()); } { - Http::TestHeaderMapImpl headers = {{"etag", "686897696a7c876b7e"}}; + Http::TestRequestHeaderMapImpl headers = {{"etag", "686897696a7c876b7e"}}; EXPECT_TRUE(isEtagAllowed(headers)); EXPECT_EQ(0, stats_.counter("test.gzip.not_compressed_etag").value()); } { - Http::TestHeaderMapImpl headers = {}; + Http::TestRequestHeaderMapImpl headers = {}; EXPECT_TRUE(isEtagAllowed(headers)); EXPECT_EQ(0, stats_.counter("test.gzip.not_compressed_etag").value()); } setUpFilter(R"EOF({ "disable_on_etag_header": true })EOF"); { - Http::TestHeaderMapImpl headers = {{"etag", R"EOF(W/"686897696a7c876b7e")EOF"}}; + Http::TestRequestHeaderMapImpl headers = {{"etag", R"EOF(W/"686897696a7c876b7e")EOF"}}; EXPECT_FALSE(isEtagAllowed(headers)); EXPECT_EQ(1, stats_.counter("test.gzip.not_compressed_etag").value()); } { - Http::TestHeaderMapImpl headers = {{"etag", "686897696a7c876b7e"}}; + Http::TestRequestHeaderMapImpl headers = {{"etag", "686897696a7c876b7e"}}; EXPECT_FALSE(isEtagAllowed(headers)); EXPECT_EQ(2, stats_.counter("test.gzip.not_compressed_etag").value()); } { - Http::TestHeaderMapImpl headers = {}; + Http::TestRequestHeaderMapImpl headers = {}; EXPECT_TRUE(isEtagAllowed(headers)); EXPECT_EQ(2, stats_.counter("test.gzip.not_compressed_etag").value()); } @@ -633,8 +634,8 @@ TEST_F(GzipFilterTest, EtagNoCompression) { // Verifies that compression is skipped when etag header is NOT allowed. TEST_F(GzipFilterTest, EtagCompression) { doRequest({{":method", "get"}, {"accept-encoding", "gzip"}}, true); - Http::TestHeaderMapImpl headers{ - {":method", "get"}, {"content-length", "256"}, {"etag", "686897696a7c876b7e"}}; + Http::TestResponseHeaderMapImpl headers{ + {":status", "200"}, {"content-length", "256"}, {"etag", "686897696a7c876b7e"}}; feedBuffer(256); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); EXPECT_FALSE(headers.has("etag")); @@ -644,35 +645,35 @@ TEST_F(GzipFilterTest, EtagCompression) { // Verifies isTransferEncodingAllowed function. TEST_F(GzipFilterTest, isTransferEncodingAllowed) { { - Http::TestHeaderMapImpl headers = {}; + Http::TestRequestHeaderMapImpl headers = {}; EXPECT_TRUE(isTransferEncodingAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"transfer-encoding", "chunked"}}; + Http::TestRequestHeaderMapImpl headers = {{"transfer-encoding", "chunked"}}; EXPECT_TRUE(isTransferEncodingAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"transfer-encoding", "Chunked"}}; + Http::TestRequestHeaderMapImpl headers = {{"transfer-encoding", "Chunked"}}; EXPECT_TRUE(isTransferEncodingAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"transfer-encoding", "deflate"}}; + Http::TestRequestHeaderMapImpl headers = {{"transfer-encoding", "deflate"}}; EXPECT_FALSE(isTransferEncodingAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"transfer-encoding", "Deflate"}}; + Http::TestRequestHeaderMapImpl headers = {{"transfer-encoding", "Deflate"}}; EXPECT_FALSE(isTransferEncodingAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"transfer-encoding", "gzip"}}; + Http::TestRequestHeaderMapImpl headers = {{"transfer-encoding", "gzip"}}; EXPECT_FALSE(isTransferEncodingAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"transfer-encoding", "gzip, chunked"}}; + Http::TestRequestHeaderMapImpl headers = {{"transfer-encoding", "gzip, chunked"}}; EXPECT_FALSE(isTransferEncodingAllowed(headers)); } { - Http::TestHeaderMapImpl headers = {{"transfer-encoding", " gzip\t, chunked\t"}}; + Http::TestRequestHeaderMapImpl headers = {{"transfer-encoding", " gzip\t, chunked\t"}}; EXPECT_FALSE(isTransferEncodingAllowed(headers)); } } @@ -695,7 +696,7 @@ TEST_F(GzipFilterTest, AcceptanceTransferEncodingGzip) { // Content-Encoding: upstream response is already encoded. TEST_F(GzipFilterTest, ContentEncodingAlreadyEncoded) { doRequest({{":method", "get"}, {"accept-encoding", "gzip"}}, true); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":method", "get"}, {"content-length", "256"}, {"content-encoding", "deflate, gzip"}}; feedBuffer(256); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, false)); @@ -707,7 +708,7 @@ TEST_F(GzipFilterTest, ContentEncodingAlreadyEncoded) { // No compression when upstream response is empty. TEST_F(GzipFilterTest, EmptyResponse) { - Http::TestHeaderMapImpl headers{{":method", "get"}, {":status", "204"}}; + Http::TestResponseHeaderMapImpl headers{{":status", "204"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, true)); EXPECT_EQ("", headers.get_("content-length")); EXPECT_EQ("", headers.get_("content-encoding")); @@ -717,27 +718,27 @@ TEST_F(GzipFilterTest, EmptyResponse) { // Verifies insertVaryHeader function. TEST_F(GzipFilterTest, insertVaryHeader) { { - Http::TestHeaderMapImpl headers = {}; + Http::TestRequestHeaderMapImpl headers = {}; insertVaryHeader(headers); EXPECT_EQ("Accept-Encoding", headers.get_("vary")); } { - Http::TestHeaderMapImpl headers = {{"vary", "Cookie"}}; + Http::TestRequestHeaderMapImpl headers = {{"vary", "Cookie"}}; insertVaryHeader(headers); EXPECT_EQ("Cookie, Accept-Encoding", headers.get_("vary")); } { - Http::TestHeaderMapImpl headers = {{"vary", "accept-encoding"}}; + Http::TestRequestHeaderMapImpl headers = {{"vary", "accept-encoding"}}; insertVaryHeader(headers); EXPECT_EQ("accept-encoding, Accept-Encoding", headers.get_("vary")); } { - Http::TestHeaderMapImpl headers = {{"vary", "Accept-Encoding, Cookie"}}; + Http::TestRequestHeaderMapImpl headers = {{"vary", "Accept-Encoding, Cookie"}}; insertVaryHeader(headers); EXPECT_EQ("Accept-Encoding, Cookie", headers.get_("vary")); } { - Http::TestHeaderMapImpl headers = {{"vary", "Accept-Encoding"}}; + Http::TestRequestHeaderMapImpl headers = {{"vary", "Accept-Encoding"}}; insertVaryHeader(headers); EXPECT_EQ("Accept-Encoding", headers.get_("vary")); } @@ -746,7 +747,7 @@ TEST_F(GzipFilterTest, insertVaryHeader) { // Filter should set Vary header value with `accept-encoding`. TEST_F(GzipFilterTest, NoVaryHeader) { doRequest({{":method", "get"}, {"accept-encoding", "gzip"}}, true); - Http::TestHeaderMapImpl headers{{":method", "get"}, {"content-length", "256"}}; + Http::TestResponseHeaderMapImpl headers{{":status", "200"}, {"content-length", "256"}}; feedBuffer(256); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); EXPECT_TRUE(headers.has("vary")); @@ -756,8 +757,8 @@ TEST_F(GzipFilterTest, NoVaryHeader) { // Filter should set Vary header value with `accept-encoding` and preserve other values. TEST_F(GzipFilterTest, VaryOtherValues) { doRequest({{":method", "get"}, {"accept-encoding", "gzip"}}, true); - Http::TestHeaderMapImpl headers{ - {":method", "get"}, {"content-length", "256"}, {"vary", "User-Agent, Cookie"}}; + Http::TestResponseHeaderMapImpl headers{ + {":status", "200"}, {"content-length", "256"}, {"vary", "User-Agent, Cookie"}}; feedBuffer(256); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); EXPECT_TRUE(headers.has("vary")); @@ -767,8 +768,8 @@ TEST_F(GzipFilterTest, VaryOtherValues) { // Vary header should have only one `accept-encoding`value. TEST_F(GzipFilterTest, VaryAlreadyHasAcceptEncoding) { doRequest({{":method", "get"}, {"accept-encoding", "gzip"}}, true); - Http::TestHeaderMapImpl headers{ - {":method", "get"}, {"content-length", "256"}, {"vary", "accept-encoding"}}; + Http::TestResponseHeaderMapImpl headers{ + {":status", "200"}, {"content-length", "256"}, {"vary", "accept-encoding"}}; feedBuffer(256); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(headers, false)); EXPECT_TRUE(headers.has("vary")); @@ -778,13 +779,13 @@ TEST_F(GzipFilterTest, VaryAlreadyHasAcceptEncoding) { // Verify removeAcceptEncoding header. TEST_F(GzipFilterTest, RemoveAcceptEncodingHeader) { { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip, br"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip, br"}}; setUpFilter(R"EOF({"remove_accept_encoding_header": true})EOF"); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, true)); EXPECT_FALSE(headers.has("accept-encoding")); } { - Http::TestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip, br"}}; + Http::TestRequestHeaderMapImpl headers = {{"accept-encoding", "deflate, gzip, br"}}; setUpFilter("{}"); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, true)); EXPECT_TRUE(headers.has("accept-encoding")); diff --git a/test/extensions/filters/http/header_to_metadata/header_to_metadata_filter_test.cc b/test/extensions/filters/http/header_to_metadata/header_to_metadata_filter_test.cc index abfb361a8f..3ac11b3e98 100644 --- a/test/extensions/filters/http/header_to_metadata/header_to_metadata_filter_test.cc +++ b/test/extensions/filters/http/header_to_metadata/header_to_metadata_filter_test.cc @@ -86,7 +86,7 @@ MATCHER_P(MapEqValue, rhs, "") { */ TEST_F(HeaderToMetadataTest, BasicRequestTest) { initializeFilter(request_config_yaml); - Http::TestHeaderMapImpl incoming_headers{{"X-VERSION", "0xdeadbeef"}}; + Http::TestRequestHeaderMapImpl incoming_headers{{"X-VERSION", "0xdeadbeef"}}; std::map expected = {{"version", "0xdeadbeef"}}; EXPECT_CALL(decoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(req_info_)); @@ -96,7 +96,8 @@ TEST_F(HeaderToMetadataTest, BasicRequestTest) { EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->decodeMetadata(metadata_map)); Buffer::OwnedImpl data("data"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(incoming_headers)); + Http::TestRequestTrailerMapImpl incoming_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(incoming_trailers)); filter_->onDestroy(); } @@ -105,7 +106,7 @@ TEST_F(HeaderToMetadataTest, BasicRequestTest) { */ TEST_F(HeaderToMetadataTest, DefaultEndpointsTest) { initializeFilter(request_config_yaml); - Http::TestHeaderMapImpl incoming_headers{{"X-FOO", "bar"}}; + Http::TestRequestHeaderMapImpl incoming_headers{{"X-FOO", "bar"}}; std::map expected = {{"default", "true"}}; EXPECT_CALL(decoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(req_info_)); @@ -126,14 +127,14 @@ TEST_F(HeaderToMetadataTest, HeaderRemovedTest) { remove: true )EOF"; initializeFilter(response_config_yaml); - Http::TestHeaderMapImpl incoming_headers{{"x-authenticated", "1"}}; + Http::TestResponseHeaderMapImpl incoming_headers{{"x-authenticated", "1"}}; std::map expected = {{"auth", "1"}}; Http::TestHeaderMapImpl empty_headers; EXPECT_CALL(encoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(req_info_)); EXPECT_CALL(req_info_, setDynamicMetadata("envoy.filters.http.header_to_metadata", MapEq(expected))); - Http::TestHeaderMapImpl continue_response{{":status", "100"}}; + Http::TestResponseHeaderMapImpl continue_response{{":status", "100"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(continue_response)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(incoming_headers, false)); @@ -142,7 +143,8 @@ TEST_F(HeaderToMetadataTest, HeaderRemovedTest) { EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->encodeMetadata(metadata_map)); Buffer::OwnedImpl data("data"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(incoming_headers)); + Http::TestResponseTrailerMapImpl incoming_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(incoming_trailers)); } /** @@ -157,7 +159,7 @@ TEST_F(HeaderToMetadataTest, NumberTypeTest) { type: NUMBER )EOF"; initializeFilter(response_config_yaml); - Http::TestHeaderMapImpl incoming_headers{{"x-authenticated", "1"}}; + Http::TestResponseHeaderMapImpl incoming_headers{{"x-authenticated", "1"}}; std::map expected = {{"auth", 1}}; Http::TestHeaderMapImpl empty_headers; @@ -182,7 +184,7 @@ TEST_F(HeaderToMetadataTest, StringTypeInBase64UrlTest) { initializeFilter(response_config_yaml); std::string data = "Non-ascii-characters"; const auto encoded = Base64::encode(data.c_str(), data.size()); - Http::TestHeaderMapImpl incoming_headers{{"x-authenticated", encoded}}; + Http::TestResponseHeaderMapImpl incoming_headers{{"x-authenticated", encoded}}; std::map expected = {{"auth", data}}; Http::TestHeaderMapImpl empty_headers; @@ -220,7 +222,7 @@ TEST_F(HeaderToMetadataTest, ProtobufValueTypeInBase64UrlTest) { std::string data; ASSERT_TRUE(value.SerializeToString(&data)); const auto encoded = Base64::encode(data.c_str(), data.size()); - Http::TestHeaderMapImpl incoming_headers{{"x-authenticated", encoded}}; + Http::TestResponseHeaderMapImpl incoming_headers{{"x-authenticated", encoded}}; std::map expected = {{"auth", value}}; EXPECT_CALL(encoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(req_info_)); @@ -242,7 +244,7 @@ TEST_F(HeaderToMetadataTest, ProtobufValueTypeInBadBase64UrlTest) { encode: BASE64 )EOF"; initializeFilter(response_config_yaml); - Http::TestHeaderMapImpl incoming_headers{{"x-authenticated", "invalid"}}; + Http::TestResponseHeaderMapImpl incoming_headers{{"x-authenticated", "invalid"}}; EXPECT_CALL(encoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(req_info_)); EXPECT_CALL(req_info_, setDynamicMetadata(_, _)).Times(0); @@ -264,7 +266,7 @@ TEST_F(HeaderToMetadataTest, BadProtobufValueTypeInBase64UrlTest) { initializeFilter(response_config_yaml); std::string data = "invalid"; const auto encoded = Base64::encode(data.c_str(), data.size()); - Http::TestHeaderMapImpl incoming_headers{{"x-authenticated", encoded}}; + Http::TestResponseHeaderMapImpl incoming_headers{{"x-authenticated", encoded}}; EXPECT_CALL(encoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(req_info_)); EXPECT_CALL(req_info_, setDynamicMetadata(_, _)).Times(0); @@ -284,7 +286,7 @@ TEST_F(HeaderToMetadataTest, HeaderNotPresent) { type: STRING )EOF"; initializeFilter(config); - Http::TestHeaderMapImpl incoming_headers{}; + Http::TestRequestHeaderMapImpl incoming_headers; EXPECT_CALL(decoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(req_info_)); EXPECT_CALL(req_info_, setDynamicMetadata(_, _)).Times(0); @@ -309,7 +311,7 @@ TEST_F(HeaderToMetadataTest, MultipleHeadersMatch) { type: STRING )EOF"; initializeFilter(python_yaml); - Http::TestHeaderMapImpl incoming_headers{ + Http::TestRequestHeaderMapImpl incoming_headers{ {"X-VERSION", "v4.0"}, {"X-PYTHON-VERSION", "3.7"}, {"X-IGNORE", "nothing"}, @@ -326,7 +328,7 @@ TEST_F(HeaderToMetadataTest, MultipleHeadersMatch) { */ TEST_F(HeaderToMetadataTest, EmptyHeaderValue) { initializeFilter(request_config_yaml); - Http::TestHeaderMapImpl incoming_headers{{"X-VERSION", ""}}; + Http::TestRequestHeaderMapImpl incoming_headers{{"X-VERSION", ""}}; EXPECT_CALL(decoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(req_info_)); EXPECT_CALL(req_info_, setDynamicMetadata(_, _)).Times(0); @@ -339,7 +341,7 @@ TEST_F(HeaderToMetadataTest, EmptyHeaderValue) { TEST_F(HeaderToMetadataTest, HeaderValueTooLong) { initializeFilter(request_config_yaml); auto length = Envoy::Extensions::HttpFilters::HeaderToMetadataFilter::MAX_HEADER_VALUE_LEN + 1; - Http::TestHeaderMapImpl incoming_headers{{"X-VERSION", std::string(length, 'x')}}; + Http::TestRequestHeaderMapImpl incoming_headers{{"X-VERSION", std::string(length, 'x')}}; EXPECT_CALL(decoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(req_info_)); EXPECT_CALL(req_info_, setDynamicMetadata(_, _)).Times(0); @@ -360,7 +362,7 @@ TEST_F(HeaderToMetadataTest, IgnoreHeaderValueUseConstant) { remove: true )EOF"; initializeFilter(response_config_yaml); - Http::TestHeaderMapImpl incoming_headers{{"x-something", "thing"}}; + Http::TestResponseHeaderMapImpl incoming_headers{{"x-something", "thing"}}; std::map expected = {{"something", "else"}}; Http::TestHeaderMapImpl empty_headers; @@ -397,7 +399,7 @@ TEST_F(HeaderToMetadataTest, NoEmptyValues) { type: STRING )EOF"; initializeFilter(config); - Http::TestHeaderMapImpl headers{{"x-version", ""}}; + Http::TestRequestHeaderMapImpl headers{{"x-version", ""}}; EXPECT_CALL(decoder_callbacks_, streamInfo()).WillRepeatedly(ReturnRef(req_info_)); EXPECT_CALL(req_info_, setDynamicMetadata(_, _)).Times(0); diff --git a/test/extensions/filters/http/health_check/config_test.cc b/test/extensions/filters/http/health_check/config_test.cc index 87df8d3cbc..eb3c3bfd67 100644 --- a/test/extensions/filters/http/health_check/config_test.cc +++ b/test/extensions/filters/http/health_check/config_test.cc @@ -135,7 +135,7 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterWithEmptyProto) { void testHealthCheckHeaderMatch( const envoy::extensions::filters::http::health_check::v3::HealthCheck& input_config, - Http::TestHeaderMapImpl& input_headers, bool expect_health_check_response) { + Http::TestRequestHeaderMapImpl& input_headers, bool expect_health_check_response) { HealthCheckFilterConfig healthCheckFilterConfig; NiceMock context; ProtobufTypes::MessagePtr config_msg = healthCheckFilterConfig.createEmptyConfigProto(); @@ -163,7 +163,7 @@ void testHealthCheckHeaderMatch( if (expect_health_check_response) { // Expect that the filter intercepts this request because all headers match. - Http::TestHeaderMapImpl health_check_response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "200"}}; EXPECT_CALL(decoder_callbacks, encodeHeaders_(HeaderMapEqualRef(&health_check_response), true)); EXPECT_EQ(health_check_filter->decodeHeaders(input_headers, true), Http::FilterHeadersStatus::StopIteration); @@ -186,7 +186,8 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterHeaderMatch) { yheader.set_name("y-healthcheck"); yheader.set_exact_match("foo"); - Http::TestHeaderMapImpl headers{{"x-healthcheck", "arbitrary_value"}, {"y-healthcheck", "foo"}}; + Http::TestRequestHeaderMapImpl headers{{"x-healthcheck", "arbitrary_value"}, + {"y-healthcheck", "foo"}}; testHealthCheckHeaderMatch(config, headers, true); } @@ -204,7 +205,8 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterHeaderMatchWrongValue) { yheader.set_name("y-healthcheck"); yheader.set_exact_match("foo"); - Http::TestHeaderMapImpl headers{{"x-healthcheck", "arbitrary_value"}, {"y-healthcheck", "bar"}}; + Http::TestRequestHeaderMapImpl headers{{"x-healthcheck", "arbitrary_value"}, + {"y-healthcheck", "bar"}}; testHealthCheckHeaderMatch(config, headers, false); } @@ -222,7 +224,7 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterHeaderMatchMissingHeader) { yheader.set_name("y-healthcheck"); yheader.set_exact_match("foo"); - Http::TestHeaderMapImpl headers{{"y-healthcheck", "foo"}}; + Http::TestRequestHeaderMapImpl headers{{"y-healthcheck", "foo"}}; testHealthCheckHeaderMatch(config, headers, false); } @@ -240,7 +242,7 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterDuplicateMatch) { envoy::config::route::v3::HeaderMatcher& dup_header = *config.add_headers(); dup_header.set_name("x-healthcheck"); - Http::TestHeaderMapImpl headers{{"x-healthcheck", "foo"}}; + Http::TestRequestHeaderMapImpl headers{{"x-healthcheck", "foo"}}; testHealthCheckHeaderMatch(config, headers, true); } @@ -259,7 +261,7 @@ TEST(HealthCheckFilterConfig, HealthCheckFilterDuplicateNoMatch) { dup_header.set_name("x-healthcheck"); dup_header.set_exact_match("bar"); - Http::TestHeaderMapImpl headers{{"x-healthcheck", "foo"}}; + Http::TestRequestHeaderMapImpl headers{{"x-healthcheck", "foo"}}; testHealthCheckHeaderMatch(config, headers, false); } diff --git a/test/extensions/filters/http/health_check/health_check_test.cc b/test/extensions/filters/http/health_check/health_check_test.cc index 9263729302..c24e3a418c 100644 --- a/test/extensions/filters/http/health_check/health_check_test.cc +++ b/test/extensions/filters/http/health_check/health_check_test.cc @@ -62,8 +62,8 @@ class HealthCheckFilterTest : public testing::Test { HealthCheckCacheManagerSharedPtr cache_manager_; std::unique_ptr filter_; NiceMock callbacks_; - Http::TestHeaderMapImpl request_headers_; - Http::TestHeaderMapImpl request_headers_no_hc_; + Http::TestRequestHeaderMapImpl request_headers_; + Http::TestRequestHeaderMapImpl request_headers_no_hc_; HeaderDataVectorSharedPtr header_data_; class MockHealthCheckCluster : public NiceMock { @@ -107,12 +107,13 @@ TEST_F(HealthCheckFilterNoPassThroughTest, NotHcRequest) { EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers_no_hc_, true)); - Http::TestHeaderMapImpl service_response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl service_response{{":status", "200"}}; EXPECT_CALL(context_, healthCheckFailed()).WillOnce(Return(true)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(service_response, false)); Buffer::OwnedImpl body; EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(body, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(service_response)); + Http::TestResponseTrailerMapImpl response_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers)); EXPECT_EQ("true", service_response.EnvoyImmediateHealthCheckFail()->value().getStringView()); } @@ -120,7 +121,7 @@ TEST_F(HealthCheckFilterNoPassThroughTest, ComputedHealth) { // Test non-pass-through health checks without upstream cluster minimum health specified. prepareFilter(false); { - Http::TestHeaderMapImpl health_check_response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "200"}}; EXPECT_CALL(context_, healthCheckFailed()).WillOnce(Return(false)); EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&health_check_response), true)); EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, @@ -128,7 +129,7 @@ TEST_F(HealthCheckFilterNoPassThroughTest, ComputedHealth) { EXPECT_EQ("health_check_ok", callbacks_.details_); } { - Http::TestHeaderMapImpl health_check_response{{":status", "503"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "503"}}; EXPECT_CALL(context_, healthCheckFailed()).WillOnce(Return(true)); EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&health_check_response), true)); EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, @@ -142,7 +143,7 @@ TEST_F(HealthCheckFilterNoPassThroughTest, ComputedHealth) { { // This should pass, because each upstream cluster has at least the // minimum percentage of healthy servers. - Http::TestHeaderMapImpl health_check_response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "200"}}; MockHealthCheckCluster cluster_www1(100, 50); MockHealthCheckCluster cluster_www2(1000, 800); EXPECT_CALL(context_, healthCheckFailed()).WillOnce(Return(false)); @@ -156,7 +157,7 @@ TEST_F(HealthCheckFilterNoPassThroughTest, ComputedHealth) { } { // This should fail, because one upstream cluster has too few healthy servers. - Http::TestHeaderMapImpl health_check_response{{":status", "503"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "503"}}; MockHealthCheckCluster cluster_www1(100, 49); MockHealthCheckCluster cluster_www2(1000, 800); EXPECT_CALL(context_, healthCheckFailed()).WillOnce(Return(false)); @@ -170,7 +171,7 @@ TEST_F(HealthCheckFilterNoPassThroughTest, ComputedHealth) { } { // This should fail, because one upstream cluster has no servers at all. - Http::TestHeaderMapImpl health_check_response{{":status", "503"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "503"}}; MockHealthCheckCluster cluster_www1(0, 0); MockHealthCheckCluster cluster_www2(1000, 800); EXPECT_CALL(context_, healthCheckFailed()).WillOnce(Return(false)); @@ -187,7 +188,7 @@ TEST_F(HealthCheckFilterNoPassThroughTest, ComputedHealth) { prepareFilter(false, ClusterMinHealthyPercentagesConstSharedPtr( new ClusterMinHealthyPercentages{{"www1", 0.0}, {"www2", 0.0}})); { - Http::TestHeaderMapImpl health_check_response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "200"}}; MockHealthCheckCluster cluster_www1(0, 0); MockHealthCheckCluster cluster_www2(1000, 0); EXPECT_CALL(context_, healthCheckFailed()).WillOnce(Return(false)); @@ -202,7 +203,7 @@ TEST_F(HealthCheckFilterNoPassThroughTest, ComputedHealth) { { // This should succeed, because each cluster has degraded + healthy hosts greater than the // threshold. - Http::TestHeaderMapImpl health_check_response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "200"}}; MockHealthCheckCluster cluster_www1(100, 40, 20); MockHealthCheckCluster cluster_www2(1000, 0, 800); EXPECT_CALL(context_, healthCheckFailed()).WillOnce(Return(false)); @@ -220,10 +221,10 @@ TEST_F(HealthCheckFilterNoPassThroughTest, HealthCheckFailedCallbackCalled) { EXPECT_CALL(context_, healthCheckFailed()).WillOnce(Return(true)); EXPECT_CALL(callbacks_.stream_info_, healthCheck(true)); EXPECT_CALL(callbacks_.active_span_, setSampled(false)); - Http::TestHeaderMapImpl health_check_response{{":status", "503"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "503"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&health_check_response), true)) .Times(1) - .WillRepeatedly(Invoke([&](Http::HeaderMap& headers, bool end_stream) { + .WillRepeatedly(Invoke([&](Http::ResponseHeaderMap& headers, bool end_stream) { filter_->encodeHeaders(headers, end_stream); EXPECT_EQ("cluster_name", headers.EnvoyUpstreamHealthCheckedCluster()->value().getStringView()); @@ -237,8 +238,8 @@ TEST_F(HealthCheckFilterNoPassThroughTest, HealthCheckFailedCallbackCalled) { filter_->decodeHeaders(request_headers_, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::StopIterationNoBuffer, filter_->decodeData(data, false)); - - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_headers_)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); } TEST_F(HealthCheckFilterPassThroughTest, Ok) { @@ -248,7 +249,7 @@ TEST_F(HealthCheckFilterPassThroughTest, Ok) { EXPECT_CALL(callbacks_, encodeHeaders_(_, _)).Times(0); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers_, false)); - Http::TestHeaderMapImpl service_hc_respnose{{":status", "200"}}; + Http::TestResponseHeaderMapImpl service_hc_respnose{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(service_hc_respnose, true)); EXPECT_EQ("cluster_name", service_hc_respnose.EnvoyUpstreamHealthCheckedCluster()->value().getStringView()); @@ -263,12 +264,12 @@ TEST_F(HealthCheckFilterPassThroughTest, OkWithContinue) { // Goodness only knows why there would be a 100-Continue response in health // checks but we can still verify Envoy handles it. - Http::TestHeaderMapImpl continue_response{{":status", "100"}}; + Http::TestResponseHeaderMapImpl continue_response{{":status", "100"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(continue_response)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->encodeMetadata(metadata_map)); - Http::TestHeaderMapImpl service_hc_respnose{{":status", "200"}}; + Http::TestResponseHeaderMapImpl service_hc_respnose{{":status", "200"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(service_hc_respnose, true)); EXPECT_EQ("cluster_name", service_hc_respnose.EnvoyUpstreamHealthCheckedCluster()->value().getStringView()); @@ -295,10 +296,10 @@ TEST_F(HealthCheckFilterCachingTest, CachedServiceUnavailableCallbackCalled) { EXPECT_CALL(callbacks_.active_span_, setSampled(false)); cache_manager_->setCachedResponse(Http::Code::ServiceUnavailable, false); - Http::TestHeaderMapImpl health_check_response{{":status", "503"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "503"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&health_check_response), true)) .Times(1) - .WillRepeatedly(Invoke([&](Http::HeaderMap& headers, bool end_stream) { + .WillRepeatedly(Invoke([&](Http::ResponseHeaderMap& headers, bool end_stream) { filter_->encodeHeaders(headers, end_stream); EXPECT_EQ("cluster_name", headers.EnvoyUpstreamHealthCheckedCluster()->value().getStringView()); @@ -317,10 +318,10 @@ TEST_F(HealthCheckFilterCachingTest, CachedOkCallbackNotCalled) { EXPECT_CALL(callbacks_.active_span_, setSampled(false)); cache_manager_->setCachedResponse(Http::Code::OK, false); - Http::TestHeaderMapImpl health_check_response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "200"}}; EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&health_check_response), true)) .Times(1) - .WillRepeatedly(Invoke([&](Http::HeaderMap& headers, bool end_stream) { + .WillRepeatedly(Invoke([&](Http::ResponseHeaderMap& headers, bool end_stream) { filter_->encodeHeaders(headers, end_stream); EXPECT_EQ("cluster_name", headers.EnvoyUpstreamHealthCheckedCluster()->value().getStringView()); @@ -337,8 +338,8 @@ TEST_F(HealthCheckFilterCachingTest, All) { // Verify that the first request goes through. EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers_, true)); - Http::TestHeaderMapImpl service_response_headers{{":status", "503"}}; - Http::TestHeaderMapImpl health_check_response{{":status", "503"}}; + Http::TestResponseHeaderMapImpl service_response_headers{{":status", "503"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "503"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(service_response_headers, true)); @@ -349,7 +350,7 @@ TEST_F(HealthCheckFilterCachingTest, All) { setResponseFlag(StreamInfo::ResponseFlag::FailedLocalHealthCheck)); EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&health_check_response), true)) .Times(1) - .WillRepeatedly(Invoke([&](Http::HeaderMap& headers, bool end_stream) { + .WillRepeatedly(Invoke([&](Http::ResponseHeaderMap& headers, bool end_stream) { filter_->encodeHeaders(headers, end_stream); EXPECT_EQ("cluster_name", headers.EnvoyUpstreamHealthCheckedCluster()->value().getStringView()); @@ -370,9 +371,10 @@ TEST_F(HealthCheckFilterCachingTest, DegradedHeader) { // Verify that the first request goes through. EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers_, true)); - Http::TestHeaderMapImpl service_response_headers{{":status", "503"}, - {"x-envoy-degraded", "true"}}; - Http::TestHeaderMapImpl health_check_response{{":status", "503"}, {"x-envoy-degraded", ""}}; + Http::TestResponseHeaderMapImpl service_response_headers{{":status", "503"}, + {"x-envoy-degraded", "true"}}; + Http::TestResponseHeaderMapImpl health_check_response{{":status", "503"}, + {"x-envoy-degraded", ""}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(service_response_headers, true)); @@ -383,7 +385,7 @@ TEST_F(HealthCheckFilterCachingTest, DegradedHeader) { setResponseFlag(StreamInfo::ResponseFlag::FailedLocalHealthCheck)); EXPECT_CALL(callbacks_, encodeHeaders_(HeaderMapEqualRef(&health_check_response), true)) .Times(1) - .WillRepeatedly(Invoke([&](Http::HeaderMap& headers, bool end_stream) { + .WillRepeatedly(Invoke([&](Http::ResponseHeaderMap& headers, bool end_stream) { filter_->encodeHeaders(headers, end_stream); EXPECT_EQ("cluster_name", headers.EnvoyUpstreamHealthCheckedCluster()->value().getStringView()); diff --git a/test/extensions/filters/http/ip_tagging/ip_tagging_filter_test.cc b/test/extensions/filters/http/ip_tagging/ip_tagging_filter_test.cc index de8f65f73f..2507f48fb0 100644 --- a/test/extensions/filters/http/ip_tagging/ip_tagging_filter_test.cc +++ b/test/extensions/filters/http/ip_tagging/ip_tagging_filter_test.cc @@ -63,7 +63,7 @@ request_type: internal TEST_F(IpTaggingFilterTest, InternalRequest) { initializeFilter(internal_request_yaml); EXPECT_EQ(FilterRequestType::INTERNAL, config_->requestType()); - Http::TestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; Network::Address::InstanceConstSharedPtr remote_address = Network::Utility::parseInternetAddress("1.2.3.5"); @@ -77,7 +77,8 @@ TEST_F(IpTaggingFilterTest, InternalRequest) { EXPECT_EQ("internal_request", request_headers.get_(Http::Headers::get().EnvoyIpTags)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); // Check external requests don't get a tag. request_headers = {}; @@ -95,7 +96,7 @@ request_type: external )EOF"; initializeFilter(external_request_yaml); EXPECT_EQ(FilterRequestType::EXTERNAL, config_->requestType()); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_CALL(stats_, counter("prefix.ip_tagging.total")).Times(1); EXPECT_CALL(stats_, counter("prefix.ip_tagging.external_request.hit")).Times(1); @@ -109,7 +110,8 @@ request_type: external EXPECT_EQ("external_request", request_headers.get_(Http::Headers::get().EnvoyIpTags)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); // Check internal requests don't get a tag. request_headers = {{"x-envoy-internal", "true"}}; @@ -131,7 +133,7 @@ request_type: both initializeFilter(both_request_yaml); EXPECT_EQ(FilterRequestType::BOTH, config_->requestType()); - Http::TestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; EXPECT_CALL(stats_, counter("prefix.ip_tagging.total")).Times(2); EXPECT_CALL(stats_, counter("prefix.ip_tagging.internal_request.hit")).Times(1); @@ -156,7 +158,7 @@ request_type: both TEST_F(IpTaggingFilterTest, NoHits) { initializeFilter(internal_request_yaml); - Http::TestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; Network::Address::InstanceConstSharedPtr remote_address = Network::Utility::parseInternetAddress("10.2.3.5"); @@ -169,13 +171,14 @@ TEST_F(IpTaggingFilterTest, NoHits) { EXPECT_FALSE(request_headers.has(Http::Headers::get().EnvoyIpTags)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } TEST_F(IpTaggingFilterTest, AppendEntry) { initializeFilter(internal_request_yaml); - Http::TestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}, - {"x-envoy-ip-tags", "test"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}, + {"x-envoy-ip-tags", "test"}}; Network::Address::InstanceConstSharedPtr remote_address = Network::Utility::parseInternetAddress("1.2.3.5"); @@ -186,7 +189,8 @@ TEST_F(IpTaggingFilterTest, AppendEntry) { EXPECT_EQ("test,internal_request", request_headers.get_(Http::Headers::get().EnvoyIpTags)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } TEST_F(IpTaggingFilterTest, NestedPrefixes) { @@ -202,8 +206,8 @@ request_type: both )EOF"; initializeFilter(duplicate_request_yaml); - Http::TestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}, - {"x-envoy-ip-tags", "test"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}, + {"x-envoy-ip-tags", "test"}}; Network::Address::InstanceConstSharedPtr remote_address = Network::Utility::parseInternetAddress("1.2.3.4"); @@ -223,7 +227,8 @@ request_type: both EXPECT_NE(std::string::npos, header_tag_data.find("duplicate_request")); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } TEST_F(IpTaggingFilterTest, Ipv6Address) { @@ -234,7 +239,7 @@ TEST_F(IpTaggingFilterTest, Ipv6Address) { - {address_prefix: 2001:abcd:ef01:2345:6789:abcd:ef01:234, prefix_len: 64} )EOF"; initializeFilter(ipv6_addresses_yaml); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; Network::Address::InstanceConstSharedPtr remote_address = Network::Utility::parseInternetAddress("2001:abcd:ef01:2345::1"); @@ -245,12 +250,13 @@ TEST_F(IpTaggingFilterTest, Ipv6Address) { EXPECT_EQ("ipv6_request", request_headers.get_(Http::Headers::get().EnvoyIpTags)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } TEST_F(IpTaggingFilterTest, RuntimeDisabled) { initializeFilter(internal_request_yaml); - Http::TestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; EXPECT_CALL(runtime_.snapshot_, featureEnabled("ip_tagging.http_filter_enabled", 100)) .WillOnce(Return(false)); @@ -258,12 +264,13 @@ TEST_F(IpTaggingFilterTest, RuntimeDisabled) { EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); EXPECT_FALSE(request_headers.has(Http::Headers::get().EnvoyIpTags)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } TEST_F(IpTaggingFilterTest, ClearRouteCache) { initializeFilter(internal_request_yaml); - Http::TestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; Network::Address::InstanceConstSharedPtr remote_address = Network::Utility::parseInternetAddress("1.2.3.5"); diff --git a/test/extensions/filters/http/jwt_authn/authenticator_test.cc b/test/extensions/filters/http/jwt_authn/authenticator_test.cc index 8fb34c4dfe..3818da291c 100644 --- a/test/extensions/filters/http/jwt_authn/authenticator_test.cc +++ b/test/extensions/filters/http/jwt_authn/authenticator_test.cc @@ -271,8 +271,8 @@ TEST_F(AuthenticatorTest, TestPubkeyFetchFail) { auto headers = Http::TestHeaderMapImpl{{"Authorization", "Bearer " + std::string(GoodToken)}}; expectVerifyStatus(Status::JwksFetchFail, headers); - Http::MessagePtr response_message(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "401"}}})); + Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "401"}}})); } // This test verifies when a Jwks fetching is not completed yet, but onDestroy() is called, diff --git a/test/extensions/filters/http/jwt_authn/filter_integration_test.cc b/test/extensions/filters/http/jwt_authn/filter_integration_test.cc index 36aeeabe48..8a2a98d126 100644 --- a/test/extensions/filters/http/jwt_authn/filter_integration_test.cc +++ b/test/extensions/filters/http/jwt_authn/filter_integration_test.cc @@ -29,7 +29,7 @@ class HeaderToFilterStateFilter : public Http::PassThroughDecoderFilter { HeaderToFilterStateFilter(const std::string& header, const std::string& state) : header_(header), state_(state) {} - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, bool) override { const Http::HeaderEntry* entry = headers.get(header_); if (entry) { decoder_callbacks_->streamInfo().filterState()->setData( @@ -97,7 +97,7 @@ TEST_P(LocalJwksIntegrationTest, WithGoodToken) { codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{ + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -112,7 +112,7 @@ TEST_P(LocalJwksIntegrationTest, WithGoodToken) { EXPECT_EQ(payload_entry->value().getStringView(), ExpectedPayloadValue); // Verify the token is removed. EXPECT_FALSE(upstream_request_->headers().Authorization()); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); ASSERT_TRUE(response->complete()); EXPECT_EQ("200", response->headers().Status()->value().getStringView()); @@ -125,7 +125,7 @@ TEST_P(LocalJwksIntegrationTest, ExpiredToken) { codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{ + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -144,7 +144,7 @@ TEST_P(LocalJwksIntegrationTest, MissingToken) { codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{ + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -162,7 +162,7 @@ TEST_P(LocalJwksIntegrationTest, ExpiredTokenHeadReply) { codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{ + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ {":method", "HEAD"}, {":path", "/"}, {":scheme", "http"}, @@ -184,7 +184,7 @@ TEST_P(LocalJwksIntegrationTest, NoRequiresPath) { codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{ + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/foo"}, {":scheme", "http"}, @@ -192,7 +192,7 @@ TEST_P(LocalJwksIntegrationTest, NoRequiresPath) { }); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); ASSERT_TRUE(response->complete()); @@ -206,7 +206,7 @@ TEST_P(LocalJwksIntegrationTest, CorsPreflight) { codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{ + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ {":method", "OPTIONS"}, {":path", "/"}, {":scheme", "http"}, @@ -216,7 +216,7 @@ TEST_P(LocalJwksIntegrationTest, CorsPreflight) { }); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); ASSERT_TRUE(response->complete()); EXPECT_EQ("200", response->headers().Status()->value().getStringView()); @@ -278,7 +278,7 @@ TEST_P(LocalJwksIntegrationTest, FilterStateRequirement) { }; for (const auto& test : test_cases) { - Http::TestHeaderMapImpl headers{ + Http::TestRequestHeaderMapImpl headers{ {":method", "GET"}, {":path", "/foo"}, {":scheme", "http"}, @@ -291,7 +291,7 @@ TEST_P(LocalJwksIntegrationTest, FilterStateRequirement) { if (test.expected_status == "200") { waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); } response->waitForEndStream(); @@ -335,7 +335,7 @@ class RemoteJwksIntegrationTest : public HttpProtocolIntegrationTest { result = jwks_request_->waitForEndStream(*dispatcher_); RELEASE_ASSERT(result, result.message()); - Http::TestHeaderMapImpl response_headers{{":status", status}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", status}}; jwks_request_->encodeHeaders(response_headers, false); Buffer::OwnedImpl response_data1(jwks_body); jwks_request_->encodeData(response_data1, true); @@ -372,7 +372,7 @@ TEST_P(RemoteJwksIntegrationTest, WithGoodToken) { codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{ + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -391,7 +391,7 @@ TEST_P(RemoteJwksIntegrationTest, WithGoodToken) { // Verify the token is removed. EXPECT_FALSE(upstream_request_->headers().Authorization()); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); ASSERT_TRUE(response->complete()); @@ -407,7 +407,7 @@ TEST_P(RemoteJwksIntegrationTest, FetchFailedJwks) { codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{ + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -430,7 +430,7 @@ TEST_P(RemoteJwksIntegrationTest, FetchFailedMissingCluster) { codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{ + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, diff --git a/test/extensions/filters/http/jwt_authn/filter_test.cc b/test/extensions/filters/http/jwt_authn/filter_test.cc index bf1c799d47..a7af4b8417 100644 --- a/test/extensions/filters/http/jwt_authn/filter_test.cc +++ b/test/extensions/filters/http/jwt_authn/filter_test.cc @@ -70,6 +70,7 @@ class FilterTest : public testing::Test { std::unique_ptr filter_; std::unique_ptr mock_verifier_; NiceMock verifier_callback_; + Http::TestRequestTrailerMapImpl trailers_; }; // This test verifies Verifier::Callback is called inline with OK status. @@ -81,7 +82,7 @@ TEST_F(FilterTest, InlineOK) { context->callback()->onComplete(Status::Ok); })); - auto headers = Http::TestHeaderMapImpl{}; + auto headers = Http::TestRequestHeaderMapImpl{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->decodeMetadata(metadata_map)); @@ -89,12 +90,12 @@ TEST_F(FilterTest, InlineOK) { Buffer::OwnedImpl data(""); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers_)); } // This test verifies Verifier::Callback is not called for CORS preflight request. TEST_F(FilterTest, CorsPreflight) { - auto headers = Http::TestHeaderMapImpl{ + auto headers = Http::TestRequestHeaderMapImpl{ {":method", "OPTIONS"}, {":path", "/"}, {":scheme", "http"}, @@ -126,13 +127,13 @@ TEST_F(FilterTest, TestSetPayloadCall) { EXPECT_TRUE(TestUtility::protoEqual(out_payload, payload)); })); - auto headers = Http::TestHeaderMapImpl{}; + auto headers = Http::TestRequestHeaderMapImpl{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_EQ(1U, mock_config_->stats().allowed_.value()); Buffer::OwnedImpl data(""); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers_)); } // This test verifies Verifier::Callback is called inline with a failure(401 Unauthorized) status. @@ -146,13 +147,13 @@ TEST_F(FilterTest, InlineUnauthorizedFailure) { context->callback()->onComplete(Status::JwtBadFormat); })); - auto headers = Http::TestHeaderMapImpl{}; + auto headers = Http::TestRequestHeaderMapImpl{}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(headers, false)); EXPECT_EQ(1U, mock_config_->stats().denied_.value()); Buffer::OwnedImpl data(""); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers_)); EXPECT_EQ("jwt_authn_access_denied", filter_callbacks_.details_); } @@ -167,13 +168,13 @@ TEST_F(FilterTest, InlineForbiddenFailure) { context->callback()->onComplete(Status::JwtAudienceNotAllowed); })); - auto headers = Http::TestHeaderMapImpl{}; + auto headers = Http::TestRequestHeaderMapImpl{}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(headers, false)); EXPECT_EQ(1U, mock_config_->stats().denied_.value()); Buffer::OwnedImpl data(""); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers_)); EXPECT_EQ("jwt_authn_access_denied", filter_callbacks_.details_); } @@ -186,19 +187,19 @@ TEST_F(FilterTest, OutBoundOK) { m_cb = context->callback(); })); - auto headers = Http::TestHeaderMapImpl{}; + auto headers = Http::TestRequestHeaderMapImpl{}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(headers, false)); Buffer::OwnedImpl data(""); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndWatermark, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(headers)); + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(trailers_)); // Callback is called now with OK status. m_cb->onComplete(Status::Ok); EXPECT_EQ(1U, mock_config_->stats().allowed_.value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers_)); } // This test verifies Verifier::Callback is called with a failure(401 Unauthorized) after verify() @@ -211,12 +212,12 @@ TEST_F(FilterTest, OutBoundUnauthorizedFailure) { m_cb = context->callback(); })); - auto headers = Http::TestHeaderMapImpl{}; + auto headers = Http::TestRequestHeaderMapImpl{}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(headers, false)); Buffer::OwnedImpl data(""); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndWatermark, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(headers)); + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(trailers_)); // Callback is called now with a failure status. EXPECT_CALL(filter_callbacks_, sendLocalReply(Http::Code::Unauthorized, _, _, _, _)); @@ -224,7 +225,7 @@ TEST_F(FilterTest, OutBoundUnauthorizedFailure) { EXPECT_EQ(1U, mock_config_->stats().denied_.value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers_)); // Should be OK to call the onComplete() again. m_cb->onComplete(Status::JwtBadFormat); @@ -240,12 +241,12 @@ TEST_F(FilterTest, OutBoundForbiddenFailure) { m_cb = context->callback(); })); - auto headers = Http::TestHeaderMapImpl{}; + auto headers = Http::TestRequestHeaderMapImpl{}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(headers, false)); Buffer::OwnedImpl data(""); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndWatermark, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(headers)); + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(trailers_)); // Callback is called now with a failure status. EXPECT_CALL(filter_callbacks_, sendLocalReply(Http::Code::Forbidden, _, _, _, _)); @@ -253,7 +254,7 @@ TEST_F(FilterTest, OutBoundForbiddenFailure) { EXPECT_EQ(1U, mock_config_->stats().denied_.value()); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers_)); // Should be OK to call the onComplete() again. m_cb->onComplete(Status::JwtAudienceNotAllowed); @@ -263,13 +264,13 @@ TEST_F(FilterTest, OutBoundForbiddenFailure) { TEST_F(FilterTest, TestNoRouteMatched) { EXPECT_CALL(*mock_config_.get(), findVerifier(_, _)).WillOnce(Return(nullptr)); - auto headers = Http::TestHeaderMapImpl{}; + auto headers = Http::TestRequestHeaderMapImpl{}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_EQ(1U, mock_config_->stats().allowed_.value()); Buffer::OwnedImpl data(""); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers_)); } } // namespace diff --git a/test/extensions/filters/http/jwt_authn/mock.h b/test/extensions/filters/http/jwt_authn/mock.h index 71f2021c38..337132e771 100644 --- a/test/extensions/filters/http/jwt_authn/mock.h +++ b/test/extensions/filters/http/jwt_authn/mock.h @@ -64,10 +64,11 @@ class MockUpstream { : request_(&mock_cm.async_client_), response_body_(response_body) { ON_CALL(mock_cm.async_client_, send_(_, _, _)) .WillByDefault( - Invoke([this](Http::MessagePtr&, Http::AsyncClient::Callbacks& cb, + Invoke([this](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - Http::MessagePtr response_message(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response_message( + new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response_message->body() = std::make_unique(response_body_); cb.onSuccess(std::move(response_message)); called_count_++; diff --git a/test/extensions/filters/http/lua/lua_filter_test.cc b/test/extensions/filters/http/lua/lua_filter_test.cc index 5262528193..5cbcfaa7ae 100644 --- a/test/extensions/filters/http/lua/lua_filter_test.cc +++ b/test/extensions/filters/http/lua/lua_filter_test.cc @@ -199,7 +199,7 @@ TEST_F(LuaHttpFilterTest, ScriptHeadersOnlyRequestHeadersOnly) { InSequence s; setup(HEADER_ONLY_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); } @@ -209,7 +209,7 @@ TEST_F(LuaHttpFilterTest, ScriptHeadersOnlyRequestBody) { InSequence s; setup(HEADER_ONLY_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); @@ -222,14 +222,14 @@ TEST_F(LuaHttpFilterTest, ScriptHeadersOnlyRequestBodyTrailers) { InSequence s; setup(HEADER_ONLY_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } @@ -238,7 +238,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyChunksRequestHeadersOnly) { InSequence s; setup(BODY_CHUNK_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("done"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); @@ -249,7 +249,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyChunksRequestBody) { InSequence s; setup(BODY_CHUNK_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; @@ -266,7 +266,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyChunksRequestBodyTrailers) { InSequence s; setup(BODY_CHUNK_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); @@ -274,7 +274,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyChunksRequestBodyTrailers) { EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("5"))); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("done"))); EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } @@ -284,7 +284,7 @@ TEST_F(LuaHttpFilterTest, ScriptTrailersRequestHeadersOnly) { InSequence s; setup(TRAILERS_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("no trailers"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); @@ -295,7 +295,7 @@ TEST_F(LuaHttpFilterTest, ScriptTrailersRequestBody) { InSequence s; setup(TRAILERS_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); @@ -310,7 +310,7 @@ TEST_F(LuaHttpFilterTest, ScriptTrailersRequestBodyTrailers) { InSequence s; setup(TRAILERS_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); @@ -318,7 +318,7 @@ TEST_F(LuaHttpFilterTest, ScriptTrailersRequestBodyTrailers) { EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("5"))); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("bar"))); EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } @@ -328,7 +328,7 @@ TEST_F(LuaHttpFilterTest, ScriptTrailersNoBodyRequestHeadersOnly) { InSequence s; setup(TRAILERS_NO_BODY_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("no trailers"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); @@ -339,7 +339,7 @@ TEST_F(LuaHttpFilterTest, ScriptTrailersNoBodyRequestBody) { InSequence s; setup(TRAILERS_NO_BODY_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); @@ -353,14 +353,14 @@ TEST_F(LuaHttpFilterTest, ScriptTrailersNoBodyRequestBodyTrailers) { InSequence s; setup(TRAILERS_NO_BODY_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("bar"))); EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } @@ -370,7 +370,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyRequestHeadersOnly) { InSequence s; setup(BODY_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("no body"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); @@ -381,7 +381,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyRequestBody) { InSequence s; setup(BODY_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -396,7 +396,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyRequestBodyTwoFrames) { InSequence s; setup(BODY_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -416,7 +416,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyRequestBodyTwoFramesTrailers) { InSequence s; setup(BODY_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -429,7 +429,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyRequestBodyTwoFramesTrailers) { EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data2, false)); decoder_callbacks_.addDecodedData(data2, false); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("10"))); EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } @@ -439,7 +439,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyTrailersRequestHeadersOnly) { InSequence s; setup(BODY_TRAILERS_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("no body"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("no trailers"))); @@ -451,7 +451,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyTrailersRequestBody) { InSequence s; setup(BODY_TRAILERS_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -467,7 +467,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyTrailersRequestBodyTrailers) { InSequence s; setup(BODY_TRAILERS_SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -476,7 +476,7 @@ TEST_F(LuaHttpFilterTest, ScriptBodyTrailersRequestBodyTrailers) { EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data, false)); decoder_callbacks_.addDecodedData(data, false); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("5"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("bar"))); EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); @@ -499,7 +499,7 @@ TEST_F(LuaHttpFilterTest, BodyChunkOutsideOfLoop) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); Buffer::OwnedImpl data1("hello"); @@ -523,13 +523,13 @@ TEST_F(LuaHttpFilterTest, ScriptRandomRequestBodyTrailers) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } @@ -545,7 +545,7 @@ TEST_F(LuaHttpFilterTest, ScriptErrorHeadersRequestBodyTrailers) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::err, StrEq("[string \"...\"]:4: attempt to index local 'foo' (a nil value)"))); @@ -554,7 +554,7 @@ TEST_F(LuaHttpFilterTest, ScriptErrorHeadersRequestBodyTrailers) { Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } @@ -573,7 +573,7 @@ TEST_F(LuaHttpFilterTest, ThreadEnvironments) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); TestFilter filter2(config_); @@ -593,7 +593,7 @@ TEST_F(LuaHttpFilterTest, UnexpectedYield) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::err, StrEq("script performed an unexpected yield"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); @@ -613,7 +613,7 @@ TEST_F(LuaHttpFilterTest, ErrorDuringCallback) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::err, StrEq("[string \"...\"]:5: attempt to index local 'foo' (a nil value)"))); @@ -633,7 +633,7 @@ TEST_F(LuaHttpFilterTest, HeadersIteratorAcrossYield) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -673,7 +673,7 @@ TEST_F(LuaHttpFilterTest, RequestAndResponse) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("/"))); EXPECT_CALL(decoder_callbacks_, clearRouteCache()); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); @@ -682,11 +682,11 @@ TEST_F(LuaHttpFilterTest, RequestAndResponse) { EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("5"))); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("bar"))); EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); - Http::TestHeaderMapImpl continue_headers{{":status", "100"}}; + Http::TestResponseHeaderMapImpl continue_headers{{":status", "100"}}; // No lua hooks for 100-continue EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("100"))).Times(0); EXPECT_EQ(Http::FilterHeadersStatus::Continue, @@ -695,7 +695,7 @@ TEST_F(LuaHttpFilterTest, RequestAndResponse) { Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->encodeMetadata(metadata_map)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("200"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, false)); @@ -703,7 +703,7 @@ TEST_F(LuaHttpFilterTest, RequestAndResponse) { EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("10"))); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(data2, false)); - Http::TestHeaderMapImpl response_trailers{{"hello", "world"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"hello", "world"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("world"))); EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers)); } @@ -723,10 +723,10 @@ TEST_F(LuaHttpFilterTest, ResponseBlockingBody) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("200"))); EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->encodeHeaders(response_headers, false)); @@ -761,14 +761,14 @@ TEST_F(LuaHttpFilterTest, HttpCall) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Http::MockAsyncClientRequest request(&cluster_manager_.async_client_); Http::AsyncClient::Callbacks* callbacks; EXPECT_CALL(cluster_manager_, get(Eq("cluster"))); EXPECT_CALL(cluster_manager_, httpAsyncClientForCluster("cluster")); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& cb, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { EXPECT_EQ((Http::TestHeaderMapImpl{{":path", "/"}, {":method", "POST"}, @@ -787,11 +787,11 @@ TEST_F(LuaHttpFilterTest, HttpCall) { Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); - Http::MessagePtr response_message(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response_message->body() = std::make_unique("response"); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq(":status 200"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("response"))); @@ -838,14 +838,14 @@ TEST_F(LuaHttpFilterTest, DoubleHttpCall) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Http::MockAsyncClientRequest request(&cluster_manager_.async_client_); Http::AsyncClient::Callbacks* callbacks; EXPECT_CALL(cluster_manager_, get(Eq("cluster"))); EXPECT_CALL(cluster_manager_, httpAsyncClientForCluster("cluster")); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& cb, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { EXPECT_EQ((Http::TestHeaderMapImpl{{":path", "/"}, {":method", "POST"}, @@ -859,8 +859,8 @@ TEST_F(LuaHttpFilterTest, DoubleHttpCall) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); - Http::MessagePtr response_message(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response_message->body() = std::make_unique("response"); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq(":status 200"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("response"))); @@ -868,7 +868,7 @@ TEST_F(LuaHttpFilterTest, DoubleHttpCall) { EXPECT_CALL(cluster_manager_, httpAsyncClientForCluster("cluster2")); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& cb, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { EXPECT_EQ((Http::TestHeaderMapImpl{ {":path", "/bar"}, {":method", "GET"}, {":authority", "foo"}}), @@ -879,7 +879,7 @@ TEST_F(LuaHttpFilterTest, DoubleHttpCall) { callbacks->onSuccess(std::move(response_message)); response_message = std::make_unique( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "403"}}}); + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "403"}}}); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq(":status 403"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("no body"))); EXPECT_CALL(decoder_callbacks_, continueDecoding()); @@ -888,7 +888,7 @@ TEST_F(LuaHttpFilterTest, DoubleHttpCall) { Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); } @@ -917,14 +917,14 @@ TEST_F(LuaHttpFilterTest, HttpCallNoBody) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Http::MockAsyncClientRequest request(&cluster_manager_.async_client_); Http::AsyncClient::Callbacks* callbacks; EXPECT_CALL(cluster_manager_, get(Eq("cluster"))); EXPECT_CALL(cluster_manager_, httpAsyncClientForCluster("cluster")); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& cb, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { EXPECT_EQ((Http::TestHeaderMapImpl{ {":path", "/"}, {":method", "GET"}, {":authority", "foo"}}), @@ -939,11 +939,11 @@ TEST_F(LuaHttpFilterTest, HttpCallNoBody) { Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndBuffer, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers)); - Http::MessagePtr response_message(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + 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()); @@ -975,14 +975,14 @@ TEST_F(LuaHttpFilterTest, HttpCallImmediateResponse) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Http::MockAsyncClientRequest request(&cluster_manager_.async_client_); Http::AsyncClient::Callbacks* callbacks; EXPECT_CALL(cluster_manager_, get(Eq("cluster"))); EXPECT_CALL(cluster_manager_, httpAsyncClientForCluster("cluster")); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& cb, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { EXPECT_EQ((Http::TestHeaderMapImpl{ {":path", "/"}, {":method", "GET"}, {":authority", "foo"}}), @@ -994,8 +994,8 @@ TEST_F(LuaHttpFilterTest, HttpCallImmediateResponse) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); - Http::MessagePtr response_message(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); Http::TestHeaderMapImpl expected_headers{{":status", "403"}, {"set-cookie", "flavor=chocolate; Path=/"}, {"set-cookie", "variant=chewy; Path=/"}}; @@ -1025,14 +1025,14 @@ TEST_F(LuaHttpFilterTest, HttpCallErrorAfterResumeSuccess) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Http::MockAsyncClientRequest request(&cluster_manager_.async_client_); Http::AsyncClient::Callbacks* callbacks; EXPECT_CALL(cluster_manager_, get(Eq("cluster"))); EXPECT_CALL(cluster_manager_, httpAsyncClientForCluster("cluster")); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& cb, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callbacks = &cb; return &request; @@ -1041,8 +1041,8 @@ TEST_F(LuaHttpFilterTest, HttpCallErrorAfterResumeSuccess) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, true)); - Http::MessagePtr response_message(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); EXPECT_CALL(*filter_, scriptLog(spdlog::level::err, @@ -1075,14 +1075,14 @@ TEST_F(LuaHttpFilterTest, HttpCallFailure) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Http::MockAsyncClientRequest request(&cluster_manager_.async_client_); Http::AsyncClient::Callbacks* callbacks; EXPECT_CALL(cluster_manager_, get(Eq("cluster"))); EXPECT_CALL(cluster_manager_, httpAsyncClientForCluster("cluster")); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& cb, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callbacks = &cb; return &request; @@ -1117,14 +1117,14 @@ TEST_F(LuaHttpFilterTest, HttpCallReset) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Http::MockAsyncClientRequest request(&cluster_manager_.async_client_); Http::AsyncClient::Callbacks* callbacks; EXPECT_CALL(cluster_manager_, get(Eq("cluster"))); EXPECT_CALL(cluster_manager_, httpAsyncClientForCluster("cluster")); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& cb, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callbacks = &cb; return &request; @@ -1161,13 +1161,13 @@ TEST_F(LuaHttpFilterTest, HttpCallImmediateFailure) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Http::MockAsyncClientRequest request(&cluster_manager_.async_client_); EXPECT_CALL(cluster_manager_, get(Eq("cluster"))); EXPECT_CALL(cluster_manager_, httpAsyncClientForCluster("cluster")); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& cb, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { cb.onFailure(Http::AsyncClient::FailureReason::Reset); return nullptr; @@ -1193,7 +1193,7 @@ TEST_F(LuaHttpFilterTest, HttpCallInvalidTimeout) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::err, StrEq("[string \"...\"]:3: http call timeout must be >= 0"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); @@ -1214,7 +1214,7 @@ TEST_F(LuaHttpFilterTest, HttpCallInvalidCluster) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(cluster_manager_, get(Eq("cluster"))).WillOnce(Return(nullptr)); EXPECT_CALL( *filter_, @@ -1238,7 +1238,7 @@ TEST_F(LuaHttpFilterTest, HttpCallInvalidHeaders) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(cluster_manager_, get(Eq("cluster"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::err, StrEq("[string \"...\"]:3: http call headers must include " @@ -1277,7 +1277,7 @@ TEST_F(LuaHttpFilterTest, ImmediateResponse) { #endif for (uint64_t i = 0; i < num_loops; i++) { - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Http::TestHeaderMapImpl expected_headers{{":status", "503"}, {"content-length", "4"}}; EXPECT_CALL(decoder_callbacks_, encodeHeaders_(HeaderMapEqualRef(&expected_headers), false)); EXPECT_CALL(decoder_callbacks_, encodeData(_, true)); @@ -1312,7 +1312,7 @@ TEST_F(LuaHttpFilterTest, ImmediateResponseBadStatus) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::err, StrEq("[string \"...\"]:3: :status must be between 200-599"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); @@ -1333,7 +1333,7 @@ TEST_F(LuaHttpFilterTest, RespondAfterHeadersContinued) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); EXPECT_CALL( @@ -1358,15 +1358,15 @@ TEST_F(LuaHttpFilterTest, RespondInResponsePath) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; EXPECT_CALL( *filter_, scriptLog(spdlog::level::err, StrEq("[string \"...\"]:3: respond not currently supported in the response path"))); - EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(request_headers, true)); + EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, true)); } // bodyChunks() after body continued. @@ -1381,7 +1381,7 @@ TEST_F(LuaHttpFilterTest, BodyChunksAfterBodyContinued) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -1406,13 +1406,13 @@ TEST_F(LuaHttpFilterTest, BodyAfterTrailers) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Http::TestHeaderMapImpl request_trailers{{"foo", "bar"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"foo", "bar"}}; EXPECT_CALL( *filter_, scriptLog(spdlog::level::err, @@ -1433,7 +1433,7 @@ TEST_F(LuaHttpFilterTest, BodyAfterStreamingHasStarted) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); Buffer::OwnedImpl data("hello"); @@ -1470,7 +1470,7 @@ TEST_F(LuaHttpFilterTest, GetMetadataFromHandle) { setup(SCRIPT); setupMetadata(METADATA); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("foo"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("bar"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("baz"))); @@ -1492,7 +1492,7 @@ TEST_F(LuaHttpFilterTest, GetMetadataFromHandleNoRoute) { ON_CALL(decoder_callbacks_, route()).WillByDefault(Return(nullptr)); setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("ok"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); } @@ -1519,7 +1519,7 @@ TEST_F(LuaHttpFilterTest, GetMetadataFromHandleNoLuaMetadata) { setup(SCRIPT); setupMetadata(METADATA); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("ok"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); } @@ -1538,7 +1538,7 @@ TEST_F(LuaHttpFilterTest, GetCurrentProtocol) { EXPECT_CALL(decoder_callbacks_, streamInfo()).WillOnce(ReturnRef(stream_info_)); EXPECT_CALL(stream_info_, protocol()).WillOnce(Return(Http::Protocol::Http11)); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("HTTP/1.1"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); } @@ -1557,7 +1557,7 @@ TEST_F(LuaHttpFilterTest, SetGetDynamicMetadata) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Event::SimulatedTimeSystem test_time; StreamInfo::StreamInfoImpl stream_info(Http::Protocol::Http2, test_time.timeSystem()); EXPECT_EQ(0, stream_info.dynamicMetadata().filter_metadata_size()); @@ -1598,7 +1598,7 @@ TEST_F(LuaHttpFilterTest, CheckConnection) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; setupSecureConnection(false); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("plain"))); @@ -1632,7 +1632,7 @@ TEST_F(LuaHttpFilterTest, ImportPublicKey) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("succeeded to import public key"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); @@ -1661,7 +1661,7 @@ TEST_F(LuaHttpFilterTest, InvalidPublicKey) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("failed to import public key"))); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); @@ -1723,7 +1723,7 @@ TEST_F(LuaHttpFilterTest, SignatureVerify) { InSequence s; setup(SCRIPT); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("signature is valid"))); EXPECT_CALL(*filter_, scriptLog(spdlog::level::trace, StrEq("unknown is not supported."))); diff --git a/test/extensions/filters/http/lua/lua_integration_test.cc b/test/extensions/filters/http/lua/lua_integration_test.cc index 303e37b3ee..f2d3c0662b 100644 --- a/test/extensions/filters/http/lua/lua_integration_test.cc +++ b/test/extensions/filters/http/lua/lua_integration_test.cc @@ -174,11 +174,11 @@ name: envoy.lua initializeFilter(FILTER_AND_CODE); codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}}; auto encoder_decoder = codec_client_->startRequest(request_headers); Http::StreamEncoder& encoder = encoder_decoder.first; @@ -218,7 +218,7 @@ name: envoy.lua ->value() .getStringView()); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"foo", "bar"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"foo", "bar"}}; upstream_request_->encodeHeaders(response_headers, false); Buffer::OwnedImpl response_data1("good"); upstream_request_->encodeData(response_data1, false); @@ -274,17 +274,17 @@ name: envoy.lua initializeFilter(FILTER_AND_CODE); codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}}; auto response = codec_client_->makeHeaderOnlyRequest(request_headers); ASSERT_TRUE(fake_upstreams_[1]->waitForHttpConnection(*dispatcher_, fake_lua_connection_)); ASSERT_TRUE(fake_lua_connection_->waitForNewStream(*dispatcher_, lua_request_)); ASSERT_TRUE(lua_request_->waitForEndStream(*dispatcher_)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"foo", "bar"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"foo", "bar"}}; lua_request_->encodeHeaders(response_headers, false); Buffer::OwnedImpl response_data1("good"); lua_request_->encodeData(response_data1, true); @@ -334,17 +334,17 @@ name: envoy.lua initializeFilter(FILTER_AND_CODE); codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}}; auto response = codec_client_->makeHeaderOnlyRequest(request_headers); ASSERT_TRUE(fake_upstreams_[1]->waitForHttpConnection(*dispatcher_, fake_lua_connection_)); ASSERT_TRUE(fake_lua_connection_->waitForNewStream(*dispatcher_, lua_request_)); ASSERT_TRUE(lua_request_->waitForEndStream(*dispatcher_)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"foo", "bar"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, {"foo", "bar"}}; lua_request_->encodeHeaders(response_headers, true); response->waitForEndStream(); @@ -372,11 +372,11 @@ name: envoy.lua initializeFilter(FILTER_AND_CODE); codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}}; auto response = codec_client_->makeHeaderOnlyRequest(request_headers); waitForNextUpstreamRequest(2); @@ -405,11 +405,11 @@ name: envoy.lua initializeFilter(FILTER_AND_CODE); codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}}; for (uint32_t i = 0; i < 30; ++i) { auto response = codec_client_->makeHeaderOnlyRequest(request_headers); @@ -497,7 +497,7 @@ name: envoy.lua "295234f7c14fa46303b7e977d2c89ba8a39a46a35f33eb07a332"; codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "https"}, {":authority", "host"}, {"x-forwarded-for", "10.0.0.1"}, {"message", "hello"}, {"keyid", "foo"}, {"signature", signature}, {"hash", "sha256"}}; diff --git a/test/extensions/filters/http/on_demand/on_demand_filter_test.cc b/test/extensions/filters/http/on_demand/on_demand_filter_test.cc index a457266d73..d9fc12ee65 100644 --- a/test/extensions/filters/http/on_demand/on_demand_filter_test.cc +++ b/test/extensions/filters/http/on_demand/on_demand_filter_test.cc @@ -31,7 +31,7 @@ class OnDemandFilterTest : public testing::Test { // tests decodeHeaders() when no cached route is available and vhds is configured TEST_F(OnDemandFilterTest, TestDecodeHeaders) { - Http::HeaderMapImpl headers; + Http::RequestHeaderMapImpl headers; std::shared_ptr route_config_ptr{new NiceMock()}; EXPECT_CALL(decoder_callbacks_, route()).WillOnce(Return(nullptr)); EXPECT_CALL(decoder_callbacks_, routeConfig()).Times(2).WillRepeatedly(Return(route_config_ptr)); @@ -42,13 +42,13 @@ TEST_F(OnDemandFilterTest, TestDecodeHeaders) { // tests decodeHeaders() when no cached route is available TEST_F(OnDemandFilterTest, TestDecodeHeadersWhenRouteAvailable) { - Http::HeaderMapImpl headers; + Http::RequestHeaderMapImpl headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, true)); } // tests decodeHeaders() when no route configuration is available TEST_F(OnDemandFilterTest, TestDecodeHeadersWhenRouteConfigIsNotAvailable) { - Http::HeaderMapImpl headers; + Http::RequestHeaderMapImpl headers; std::shared_ptr route_config_ptr{new NiceMock()}; EXPECT_CALL(decoder_callbacks_, route()).WillOnce(Return(nullptr)); EXPECT_CALL(decoder_callbacks_, routeConfig()).WillOnce(Return(absl::nullopt)); @@ -56,7 +56,7 @@ TEST_F(OnDemandFilterTest, TestDecodeHeadersWhenRouteConfigIsNotAvailable) { } TEST_F(OnDemandFilterTest, TestDecodeTrailers) { - Http::HeaderMapImpl headers; + Http::RequestTrailerMapImpl headers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(headers)); } diff --git a/test/extensions/filters/http/original_src/original_src_test.cc b/test/extensions/filters/http/original_src/original_src_test.cc index 026360a049..33b3ba002f 100644 --- a/test/extensions/filters/http/original_src/original_src_test.cc +++ b/test/extensions/filters/http/original_src/original_src_test.cc @@ -58,7 +58,8 @@ class OriginalSrcHttpTest : public testing::Test { StrictMock buffer_; NiceMock callbacks_; NiceMock socket_; - Http::TestHeaderMapImpl headers_; + Http::TestRequestHeaderMapImpl headers_; + Http::TestRequestTrailerMapImpl trailers_; absl::optional findOptionDetails(const Network::Socket::Options& options, Network::SocketOptionName name, @@ -206,7 +207,7 @@ TEST_F(OriginalSrcHttpTest, TrailersAndDataEndStreamDoNothing) { // No new expectations => no side effects from calling these. EXPECT_EQ(Http::FilterDataStatus::Continue, filter->decodeData(buffer_, true)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter->decodeTrailers(headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter->decodeTrailers(trailers_)); } TEST_F(OriginalSrcHttpTest, TrailersAndDataNotEndStreamDoNothing) { @@ -223,7 +224,7 @@ TEST_F(OriginalSrcHttpTest, TrailersAndDataNotEndStreamDoNothing) { // No new expectations => no side effects from calling these. EXPECT_EQ(Http::FilterDataStatus::Continue, filter->decodeData(buffer_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter->decodeTrailers(headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter->decodeTrailers(trailers_)); } } // namespace } // namespace OriginalSrc diff --git a/test/extensions/filters/http/ratelimit/ratelimit_test.cc b/test/extensions/filters/http/ratelimit/ratelimit_test.cc index 640e5322cd..62c49f66c3 100644 --- a/test/extensions/filters/http/ratelimit/ratelimit_test.cc +++ b/test/extensions/filters/http/ratelimit/ratelimit_test.cc @@ -81,8 +81,10 @@ class HttpRateLimitFilterTest : public testing::Test { Filters::Common::RateLimit::MockClient* client_; NiceMock filter_callbacks_; Filters::Common::RateLimit::RequestCallbacks* request_callbacks_{}; - Http::TestHeaderMapImpl request_headers_; - Http::TestHeaderMapImpl response_headers_; + Http::TestRequestHeaderMapImpl request_headers_; + Http::TestRequestTrailerMapImpl request_trailers_; + Http::TestResponseHeaderMapImpl response_headers_; + Http::TestResponseTrailerMapImpl response_trailers_; Buffer::OwnedImpl data_; Buffer::OwnedImpl response_data_; NiceMock stats_store_; @@ -103,14 +105,14 @@ TEST_F(HttpRateLimitFilterTest, NoRoute) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->encodeMetadata(metadata_map)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); } TEST_F(HttpRateLimitFilterTest, NoCluster) { @@ -120,12 +122,12 @@ TEST_F(HttpRateLimitFilterTest, NoCluster) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); } TEST_F(HttpRateLimitFilterTest, NoApplicableRateLimit) { @@ -135,12 +137,12 @@ TEST_F(HttpRateLimitFilterTest, NoApplicableRateLimit) { EXPECT_CALL(*client_, limit(_, _, _, _)).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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); } TEST_F(HttpRateLimitFilterTest, NoDescriptor) { @@ -151,12 +153,12 @@ TEST_F(HttpRateLimitFilterTest, NoDescriptor) { EXPECT_CALL(*client_, limit(_, _, _, _)).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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); } TEST_F(HttpRateLimitFilterTest, RuntimeDisabled) { @@ -166,12 +168,12 @@ TEST_F(HttpRateLimitFilterTest, RuntimeDisabled) { .WillOnce(Return(false)); 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); } TEST_F(HttpRateLimitFilterTest, OkResponse) { @@ -203,12 +205,12 @@ TEST_F(HttpRateLimitFilterTest, OkResponse) { Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->decodeMetadata(metadata_map)); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndWatermark, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); EXPECT_CALL(filter_callbacks_, continueDecoding()); EXPECT_CALL(filter_callbacks_.stream_info_, @@ -246,12 +248,12 @@ TEST_F(HttpRateLimitFilterTest, OkResponseWithHeaders) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::StopIterationAndWatermark, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); EXPECT_CALL(filter_callbacks_, continueDecoding()); EXPECT_CALL(filter_callbacks_.stream_info_, @@ -268,7 +270,7 @@ TEST_F(HttpRateLimitFilterTest, OkResponseWithHeaders) { Http::HeaderMapPtr{new Http::TestHeaderMapImpl(*rl_headers)}, Http::HeaderMapPtr{new Http::TestHeaderMapImpl(*request_headers_to_add)}); Http::TestHeaderMapImpl expected_headers(*rl_headers); - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, false)); EXPECT_EQ(true, (expected_headers == response_headers)); @@ -295,12 +297,12 @@ TEST_F(HttpRateLimitFilterTest, ImmediateOkResponse) { EXPECT_CALL(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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); EXPECT_EQ(1U, filter_callbacks_.clusterInfo()->statsScope().counter("ratelimit.ok").value()); } @@ -324,12 +326,12 @@ TEST_F(HttpRateLimitFilterTest, ImmediateErrorResponse) { EXPECT_CALL(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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); EXPECT_EQ(1U, filter_callbacks_.clusterInfo()->statsScope().counter("ratelimit.error").value()); EXPECT_EQ(1U, filter_callbacks_.clusterInfo() @@ -357,7 +359,7 @@ TEST_F(HttpRateLimitFilterTest, ErrorResponse) { request_callbacks_->complete(Filters::Common::RateLimit::LimitStatus::Error, nullptr, nullptr); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_CALL(filter_callbacks_.stream_info_, setResponseFlag(StreamInfo::ResponseFlag::RateLimited)) .Times(0); @@ -414,7 +416,7 @@ TEST_F(HttpRateLimitFilterTest, LimitResponse) { filter_->decodeHeaders(request_headers_, false)); Http::HeaderMapPtr h{new Http::TestHeaderMapImpl()}; - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "429"}, {"x-envoy-ratelimited", Http::Headers::get().EnvoyRateLimitedValues.True}}; EXPECT_CALL(filter_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true)); @@ -450,7 +452,7 @@ TEST_F(HttpRateLimitFilterTest, LimitResponseWithHeaders) { filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); Http::HeaderMapPtr rl_headers{new Http::TestHeaderMapImpl{ {"x-ratelimit-limit", "1000"}, {"x-ratelimit-remaining", "0"}, {"retry-after", "33"}}}; @@ -501,12 +503,12 @@ TEST_F(HttpRateLimitFilterTest, LimitResponseRuntimeDisabled) { nullptr); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); EXPECT_EQ(1U, filter_callbacks_.clusterInfo()->statsScope().counter("ratelimit.over_limit").value()); @@ -545,12 +547,12 @@ TEST_F(HttpRateLimitFilterTest, RouteRateLimitDisabledForRouteKey) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); } TEST_F(HttpRateLimitFilterTest, VirtualHostRateLimitDisabledForRouteKey) { @@ -565,12 +567,12 @@ TEST_F(HttpRateLimitFilterTest, VirtualHostRateLimitDisabledForRouteKey) { 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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); } TEST_F(HttpRateLimitFilterTest, IncorrectRequestType) { @@ -587,12 +589,12 @@ TEST_F(HttpRateLimitFilterTest, IncorrectRequestType) { EXPECT_CALL(*client_, limit(_, _, _, _)).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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); std::string external_filter_config = R"EOF( { @@ -601,19 +603,19 @@ TEST_F(HttpRateLimitFilterTest, IncorrectRequestType) { } )EOF"; SetUpTest(external_filter_config); - Http::TestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; EXPECT_CALL(route_rate_limit_, populateDescriptors(_, _, _, _, _)).Times(0); EXPECT_CALL(vh_rate_limit_, populateDescriptors(_, _, _, _, _)).Times(0); EXPECT_CALL(*client_, limit(_, _, _, _)).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_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); } TEST_F(HttpRateLimitFilterTest, InternalRequestType) { @@ -624,7 +626,7 @@ TEST_F(HttpRateLimitFilterTest, InternalRequestType) { } )EOF"; SetUpTest(internal_filter_config); - Http::TestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-internal", "true"}}; InSequence s; EXPECT_CALL(filter_callbacks_.route_->route_entry_.rate_limit_policy_, getApplicableRateLimit(0)) @@ -649,12 +651,12 @@ TEST_F(HttpRateLimitFilterTest, InternalRequestType) { EXPECT_CALL(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_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); EXPECT_EQ(1U, filter_callbacks_.clusterInfo()->statsScope().counter("ratelimit.ok").value()); } @@ -668,7 +670,7 @@ TEST_F(HttpRateLimitFilterTest, ExternalRequestType) { } )EOF"; SetUpTest(external_filter_config); - Http::TestHeaderMapImpl request_headers{{"x-envoy-internal", "false"}}; + Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-internal", "false"}}; InSequence s; EXPECT_CALL(filter_callbacks_.route_->route_entry_.rate_limit_policy_, getApplicableRateLimit(0)) @@ -693,12 +695,12 @@ TEST_F(HttpRateLimitFilterTest, ExternalRequestType) { EXPECT_CALL(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_headers)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); EXPECT_EQ(1U, filter_callbacks_.clusterInfo()->statsScope().counter("ratelimit.ok").value()); } @@ -734,12 +736,12 @@ TEST_F(HttpRateLimitFilterTest, ExcludeVirtualHost) { EXPECT_CALL(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_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers_, false)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_data_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers_)); EXPECT_EQ(1U, filter_callbacks_.clusterInfo()->statsScope().counter("ratelimit.ok").value()); } diff --git a/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc b/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc index 23a4609ab4..afb057de8f 100644 --- a/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc +++ b/test/extensions/filters/http/rbac/rbac_filter_integration_test.cc @@ -77,7 +77,7 @@ TEST_P(RBACIntegrationTest, Allowed) { codec_client_ = makeHttpConnection(lookupPort("http")); auto response = codec_client_->makeRequestWithBody( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, @@ -86,7 +86,7 @@ TEST_P(RBACIntegrationTest, Allowed) { }, 1024); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); ASSERT_TRUE(response->complete()); @@ -100,7 +100,7 @@ TEST_P(RBACIntegrationTest, Denied) { codec_client_ = makeHttpConnection(lookupPort("http")); auto response = codec_client_->makeRequestWithBody( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", "/"}, {":scheme", "http"}, @@ -123,7 +123,7 @@ TEST_P(RBACIntegrationTest, DeniedWithPrefixRule) { codec_client_ = makeHttpConnection(lookupPort("http")); auto response = codec_client_->makeRequestWithBody( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", "/foo/../bar"}, {":scheme", "http"}, @@ -132,7 +132,7 @@ TEST_P(RBACIntegrationTest, DeniedWithPrefixRule) { }, 1024); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); ASSERT_TRUE(response->complete()); @@ -149,7 +149,7 @@ TEST_P(RBACIntegrationTest, RbacPrefixRuleUseNormalizePath) { codec_client_ = makeHttpConnection(lookupPort("http")); auto response = codec_client_->makeRequestWithBody( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", "/foo/../bar"}, {":scheme", "http"}, @@ -170,7 +170,7 @@ TEST_P(RBACIntegrationTest, DeniedHeadReply) { codec_client_ = makeHttpConnection(lookupPort("http")); auto response = codec_client_->makeRequestWithBody( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "HEAD"}, {":path", "/"}, {":scheme", "http"}, @@ -206,7 +206,7 @@ TEST_P(RBACIntegrationTest, RouteOverride) { codec_client_ = makeHttpConnection(lookupPort("http")); auto response = codec_client_->makeRequestWithBody( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", "/"}, {":scheme", "http"}, @@ -216,7 +216,7 @@ TEST_P(RBACIntegrationTest, RouteOverride) { 1024); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); ASSERT_TRUE(response->complete()); @@ -233,7 +233,7 @@ TEST_P(RBACIntegrationTest, PathWithQueryAndFragment) { for (const auto& path : paths) { auto response = codec_client_->makeRequestWithBody( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", path}, {":scheme", "http"}, @@ -242,7 +242,7 @@ TEST_P(RBACIntegrationTest, PathWithQueryAndFragment) { }, 1024); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); ASSERT_TRUE(response->complete()); @@ -260,7 +260,7 @@ TEST_P(RBACIntegrationTest, PathIgnoreCase) { for (const auto& path : paths) { auto response = codec_client_->makeRequestWithBody( - Http::TestHeaderMapImpl{ + Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", path}, {":scheme", "http"}, @@ -269,7 +269,7 @@ TEST_P(RBACIntegrationTest, PathIgnoreCase) { }, 1024); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); ASSERT_TRUE(response->complete()); diff --git a/test/extensions/filters/http/rbac/rbac_filter_test.cc b/test/extensions/filters/http/rbac/rbac_filter_test.cc index 1e27049cc6..e5047c569a 100644 --- a/test/extensions/filters/http/rbac/rbac_filter_test.cc +++ b/test/extensions/filters/http/rbac/rbac_filter_test.cc @@ -86,7 +86,8 @@ class RoleBasedAccessControlFilterTest : public testing::Test { RoleBasedAccessControlFilter filter_; Network::Address::InstanceConstSharedPtr address_; std::string requested_server_name_; - Http::TestHeaderMapImpl headers_; + Http::TestRequestHeaderMapImpl headers_; + Http::TestRequestTrailerMapImpl trailers_; }; TEST_F(RoleBasedAccessControlFilterTest, Allowed) { @@ -100,7 +101,7 @@ TEST_F(RoleBasedAccessControlFilterTest, Allowed) { Buffer::OwnedImpl data(""); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(trailers_)); } TEST_F(RoleBasedAccessControlFilterTest, RequestedServerName) { @@ -115,13 +116,13 @@ TEST_F(RoleBasedAccessControlFilterTest, RequestedServerName) { Buffer::OwnedImpl data(""); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data, false)); - EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(headers_)); + EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(trailers_)); } TEST_F(RoleBasedAccessControlFilterTest, Path) { setDestinationPort(999); - auto headers = Http::TestHeaderMapImpl{ + auto headers = Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/suffix#seg?param=value"}, {":scheme", "http"}, @@ -134,7 +135,7 @@ TEST_F(RoleBasedAccessControlFilterTest, Denied) { setDestinationPort(456); setMetadata(); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "403"}, {"content-length", "19"}, {"content-type", "text/plain"}, diff --git a/test/extensions/filters/http/router/auto_sni_integration_test.cc b/test/extensions/filters/http/router/auto_sni_integration_test.cc index 90114e57d2..95724d818b 100644 --- a/test/extensions/filters/http/router/auto_sni_integration_test.cc +++ b/test/extensions/filters/http/router/auto_sni_integration_test.cc @@ -103,12 +103,12 @@ TEST_P(AutoSniIntegrationTest, PassingNotDNS) { TEST_P(AutoSniIntegrationTest, PassingHostWithoutPort) { setup(); codec_client_ = makeHttpConnection(lookupPort("http")); - const auto response_ = - sendRequestAndWaitForResponse(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/"}, - {":scheme", "http"}, - {":authority", "example.com:8080"}}, - 0, default_response_headers_, 0); + const auto response_ = sendRequestAndWaitForResponse( + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/"}, + {":scheme", "http"}, + {":authority", "example.com:8080"}}, + 0, default_response_headers_, 0); EXPECT_TRUE(upstream_request_->complete()); EXPECT_TRUE(response_->complete()); diff --git a/test/extensions/filters/http/squash/squash_filter_integration_test.cc b/test/extensions/filters/http/squash/squash_filter_integration_test.cc index 1ccfbc454c..a1ead08895 100644 --- a/test/extensions/filters/http/squash/squash_filter_integration_test.cc +++ b/test/extensions/filters/http/squash/squash_filter_integration_test.cc @@ -45,9 +45,9 @@ class SquashFilterIntegrationTest : public testing::TestWithParamwaitForEndStream(*dispatcher_); RELEASE_ASSERT(result, result.message()); if (body.empty()) { - request_stream->encodeHeaders(Http::TestHeaderMapImpl{{":status", status}}, true); + request_stream->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", status}}, true); } else { - request_stream->encodeHeaders(Http::TestHeaderMapImpl{{":status", status}}, false); + request_stream->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", status}}, false); Buffer::OwnedImpl responseBuffer(body); request_stream->encodeData(responseBuffer, true); } @@ -62,10 +62,10 @@ class SquashFilterIntegrationTest : public testing::TestWithParammakeHeaderOnlyRequest(headers); } diff --git a/test/extensions/filters/http/squash/squash_filter_test.cc b/test/extensions/filters/http/squash/squash_filter_test.cc index 5f51676c6f..c4769c97d8 100644 --- a/test/extensions/filters/http/squash/squash_filter_test.cc +++ b/test/extensions/filters/http/squash/squash_filter_test.cc @@ -188,10 +188,10 @@ class SquashFilterTest : public testing::Test { EXPECT_CALL(*attachmentTimeout_timer_, enableTimer(config_->attachmentTimeout(), _)); - Envoy::Http::TestHeaderMapImpl headers{{":method", "GET"}, - {":authority", "www.solo.io"}, - {"x-squash-debug", "true"}, - {":path", "/getsomething"}}; + Envoy::Http::TestRequestHeaderMapImpl headers{{":method", "GET"}, + {":authority", "www.solo.io"}, + {"x-squash-debug", "true"}, + {":path", "/getsomething"}}; EXPECT_EQ(Envoy::Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(headers, false)); } @@ -201,7 +201,7 @@ class SquashFilterTest : public testing::Test { Http::MetadataMap metadata_map{{"metadata", "metadata"}}; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->decodeMetadata(metadata_map)); - Envoy::Http::TestHeaderMapImpl trailers{}; + Http::TestRequestTrailerMapImpl trailers; // Complete a full request cycle Envoy::Buffer::OwnedImpl buffer("nothing here"); EXPECT_EQ(Envoy::Http::FilterDataStatus::StopIterationAndBuffer, @@ -212,7 +212,7 @@ class SquashFilterTest : public testing::Test { void expectAsyncClientSend() { EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce(Invoke( - [&](Envoy::Http::MessagePtr&, Envoy::Http::AsyncClient::Callbacks& cb, + [&](Envoy::Http::RequestMessagePtr&, Envoy::Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Envoy::Http::AsyncClient::Request* { callbacks_.push_back(&cb); return &request_; @@ -220,8 +220,8 @@ class SquashFilterTest : public testing::Test { } void completeRequest(const std::string& status, const std::string& body) { - Http::MessagePtr msg(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", status}}})); + Http::ResponseMessagePtr msg(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", status}}})); msg->body() = std::make_unique(body); popPendingCallback()->onSuccess(std::move(msg)); } @@ -263,13 +263,13 @@ TEST_F(SquashFilterTest, DecodeHeaderContinuesOnClientFail) { EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce(Invoke( - [&](Envoy::Http::MessagePtr&, Envoy::Http::AsyncClient::Callbacks& callbacks, + [&](Envoy::Http::RequestMessagePtr&, Envoy::Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Envoy::Http::AsyncClient::Request* { callbacks.onFailure(Envoy::Http::AsyncClient::FailureReason::Reset); return nullptr; })); - Envoy::Http::TestHeaderMapImpl headers{{":method", "GET"}, + Http::TestRequestHeaderMapImpl headers{{":method", "GET"}, {":authority", "www.solo.io"}, {"x-squash-debug", "true"}, {":path", "/getsomething"}}; @@ -277,7 +277,8 @@ TEST_F(SquashFilterTest, DecodeHeaderContinuesOnClientFail) { Envoy::Buffer::OwnedImpl data("nothing here"); EXPECT_EQ(Envoy::Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_EQ(Envoy::Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - EXPECT_EQ(Envoy::Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(headers)); + Http::TestRequestTrailerMapImpl trailers; + EXPECT_EQ(Envoy::Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); } TEST_F(SquashFilterTest, DecodeContinuesOnCreateAttachmentFail) { @@ -289,7 +290,7 @@ TEST_F(SquashFilterTest, DecodeContinuesOnCreateAttachmentFail) { Envoy::Buffer::OwnedImpl data("nothing here"); EXPECT_EQ(Envoy::Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - Envoy::Http::TestHeaderMapImpl trailers{}; + Http::TestRequestTrailerMapImpl trailers; EXPECT_EQ(Envoy::Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); } @@ -297,7 +298,7 @@ TEST_F(SquashFilterTest, DoesNothingWithNoHeader) { initFilter(); EXPECT_CALL(cm_, httpAsyncClientForCluster(_)).Times(0); - Envoy::Http::TestHeaderMapImpl headers{{":method", "GET"}, + Http::TestRequestHeaderMapImpl headers{{":method", "GET"}, {":authority", "www.solo.io"}, {"x-not-squash-debug", "true"}, {":path", "/getsomething"}}; @@ -305,7 +306,8 @@ TEST_F(SquashFilterTest, DoesNothingWithNoHeader) { Envoy::Buffer::OwnedImpl data("nothing here"); EXPECT_EQ(Envoy::Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(headers, false)); EXPECT_EQ(Envoy::Http::FilterDataStatus::Continue, filter_->decodeData(data, false)); - EXPECT_EQ(Envoy::Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(headers)); + Http::TestRequestTrailerMapImpl trailers; + EXPECT_EQ(Envoy::Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(trailers)); } TEST_F(SquashFilterTest, Timeout) { @@ -431,12 +433,12 @@ TEST_F(SquashFilterTest, TimerExpiresInline) { })); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) - .WillOnce(Invoke([&](Envoy::Http::MessagePtr&, Envoy::Http::AsyncClient::Callbacks&, + .WillOnce(Invoke([&](Envoy::Http::RequestMessagePtr&, Envoy::Http::AsyncClient::Callbacks&, const Http::AsyncClient::RequestOptions&) -> Envoy::Http::AsyncClient::Request* { return &request_; })); EXPECT_CALL(request_, cancel()); - Envoy::Http::TestHeaderMapImpl headers{{":method", "GET"}, + Http::TestRequestHeaderMapImpl headers{{":method", "GET"}, {":authority", "www.solo.io"}, {"x-squash-debug", "true"}, {":path", "/getsomething"}}; diff --git a/test/extensions/filters/http/tap/tap_config_impl_test.cc b/test/extensions/filters/http/tap/tap_config_impl_test.cc index dea514a234..2033c1cd24 100644 --- a/test/extensions/filters/http/tap/tap_config_impl_test.cc +++ b/test/extensions/filters/http/tap/tap_config_impl_test.cc @@ -38,10 +38,10 @@ class HttpPerRequestTapperImplTest : public testing::Test { std::vector matchers_{1}; TapCommon::MockMatcher matcher_{matchers_}; TapCommon::Matcher::MatchStatusVector* statuses_; - const Http::TestHeaderMapImpl request_headers_{{"a", "b"}}; - const Http::TestHeaderMapImpl request_trailers_{{"c", "d"}}; - const Http::TestHeaderMapImpl response_headers_{{"e", "f"}}; - const Http::TestHeaderMapImpl response_trailers_{{"g", "h"}}; + const Http::TestRequestHeaderMapImpl request_headers_{{"a", "b"}}; + const Http::TestRequestTrailerMapImpl request_trailers_{{"c", "d"}}; + const Http::TestResponseHeaderMapImpl response_headers_{{"e", "f"}}; + const Http::TestResponseTrailerMapImpl response_trailers_{{"g", "h"}}; }; // Buffered tap with no match. diff --git a/test/extensions/filters/http/tap/tap_filter_integration_test.cc b/test/extensions/filters/http/tap/tap_filter_integration_test.cc index 9b188b57b8..e93baf3f9e 100644 --- a/test/extensions/filters/http/tap/tap_filter_integration_test.cc +++ b/test/extensions/filters/http/tap/tap_filter_integration_test.cc @@ -42,12 +42,12 @@ class TapIntegrationTest : public testing::TestWithParam& request_body_chunks, - const Http::TestHeaderMapImpl* request_trailers, - const Http::TestHeaderMapImpl& response_headers, + const Http::TestRequestTrailerMapImpl* request_trailers, + const Http::TestResponseHeaderMapImpl& response_headers, const std::vector& response_body_chunks, - const Http::TestHeaderMapImpl* response_trailers) { + const Http::TestResponseTrailerMapImpl* response_trailers) { IntegrationStreamDecoderPtr decoder; if (request_trailers == nullptr && request_body_chunks.empty()) { decoder = codec_client_->makeHeaderOnlyRequest(request_headers); @@ -83,7 +83,7 @@ class TapIntegrationTest : public testing::TestWithParammakeRequestWithBody(admin_request_headers, admin_request_yaml); admin_response_->waitForHeaders(); @@ -127,22 +127,22 @@ class TapIntegrationTest : public testing::TestWithParamdecodeHeaders(request_headers, false)); Buffer::OwnedImpl request_body; EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(request_body, false)); - Http::TestHeaderMapImpl request_trailers; + Http::TestRequestTrailerMapImpl request_trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encodeHeaders(response_headers, false)); Buffer::OwnedImpl response_body; EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_body, false)); - Http::TestHeaderMapImpl response_trailers; + Http::TestResponseTrailerMapImpl response_trailers; EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers)); Http::MetadataMap metadata; EXPECT_EQ(Http::FilterMetadataStatus::Continue, filter_->encodeMetadata(metadata)); @@ -96,17 +96,17 @@ TEST_F(TapFilterTest, Config) { InSequence s; setup(true); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_CALL(*http_per_request_tapper_, onRequestHeaders(_)); EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false)); Buffer::OwnedImpl request_body; EXPECT_CALL(*http_per_request_tapper_, onRequestBody(_)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(request_body, false)); - Http::TestHeaderMapImpl request_trailers; + Http::TestRequestTrailerMapImpl request_trailers; EXPECT_CALL(*http_per_request_tapper_, onRequestTrailers(_)); EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->decodeTrailers(request_trailers)); - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->encode100ContinueHeaders(response_headers)); EXPECT_CALL(*http_per_request_tapper_, onResponseHeaders(_)); @@ -114,7 +114,7 @@ TEST_F(TapFilterTest, Config) { Buffer::OwnedImpl response_body; EXPECT_CALL(*http_per_request_tapper_, onResponseBody(_)); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->encodeData(response_body, false)); - Http::TestHeaderMapImpl response_trailers; + Http::TestResponseTrailerMapImpl response_trailers; EXPECT_CALL(*http_per_request_tapper_, onResponseTrailers(_)); EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_->encodeTrailers(response_trailers)); diff --git a/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc b/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc index 6b8ad6c4c0..b4b522f7c2 100644 --- a/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc +++ b/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc @@ -96,7 +96,7 @@ stat_prefix: vpn EXPECT_CALL(cm_, httpAsyncClientForCluster("vpn")).WillOnce(ReturnRef(cm_.async_client_)); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([this](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([this](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callbacks_ = &callbacks; return &request_; @@ -168,8 +168,8 @@ TEST_F(ClientSslAuthFilterTest, Ssl) { // Respond. EXPECT_CALL(*interval_timer_, enableTimer(_, _)); - Http::MessagePtr message(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); message->body() = std::make_unique( api_->fileSystem().fileReadToEnd(TestEnvironment::runfilesPath( "test/extensions/filters/network/client_ssl_auth/test_data/vpn_response_1.json"))); @@ -226,7 +226,7 @@ TEST_F(ClientSslAuthFilterTest, Ssl) { // Error response. EXPECT_CALL(*interval_timer_, enableTimer(_, _)); message = std::make_unique( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "503"}}}); + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "503"}}}); callbacks_->onSuccess(std::move(message)); // Interval timer fires. @@ -236,7 +236,7 @@ TEST_F(ClientSslAuthFilterTest, Ssl) { // Parsing error EXPECT_CALL(*interval_timer_, enableTimer(_, _)); message = std::make_unique( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}}); + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}}); message->body() = std::make_unique("bad_json"); callbacks_->onSuccess(std::move(message)); @@ -252,10 +252,11 @@ TEST_F(ClientSslAuthFilterTest, Ssl) { EXPECT_CALL(cm_, httpAsyncClientForCluster("vpn")).WillOnce(ReturnRef(cm_.async_client_)); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - callbacks.onSuccess(Http::MessagePtr{new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "503"}}})}); + callbacks.onSuccess( + Http::ResponseMessagePtr{new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "503"}}})}); return nullptr; })); EXPECT_CALL(*interval_timer_, enableTimer(_, _)); diff --git a/test/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit_test.cc b/test/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit_test.cc index f44c8da060..5c2d384563 100644 --- a/test/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit_test.cc +++ b/test/extensions/filters/network/thrift_proxy/filters/ratelimit/ratelimit_test.cc @@ -83,7 +83,7 @@ class ThriftRateLimitFilterTest : public testing::Test { NiceMock filter_callbacks_; Filters::Common::RateLimit::RequestCallbacks* request_callbacks_{}; ThriftProxy::MessageMetadataSharedPtr request_metadata_; - Http::TestHeaderMapImpl response_headers_; + Http::TestResponseHeaderMapImpl response_headers_; Buffer::OwnedImpl data_; Buffer::OwnedImpl response_data_; NiceMock runtime_; diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc index 714321df06..0c5c2073d4 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_client_session_test.cc @@ -145,7 +145,7 @@ class EnvoyQuicClientSessionTest : public testing::TestWithParam { stream.getStream().addCallbacks(stream_callbacks); std::string host("www.abc.com"); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":authority", host}, {":method", "GET"}, {":path", "/"}}; stream.encodeHeaders(request_headers, true); return stream; diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc index 260138a4cf..7d5d8f4537 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_client_stream_test.cc @@ -99,7 +99,7 @@ class EnvoyQuicClientStreamTest : public testing::TestWithParam { Http::MockResponseDecoder stream_decoder_; Http::MockStreamCallbacks stream_callbacks_; std::string host_{"www.abc.com"}; - Http::TestHeaderMapImpl request_headers_; + Http::TestRequestHeaderMapImpl request_headers_; quic::QuicHeaderList response_headers_; quic::QuicHeaderList trailers_; Buffer::OwnedImpl request_body_{"Hello world"}; diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc index 323b1a2d88..e8f7e6eacd 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_server_session_test.cc @@ -434,8 +434,8 @@ TEST_P(EnvoyQuicServerSessionTest, WriteUpdatesDelayCloseTimer) { stream->OnStreamHeaderList(/*fin=*/true, request_headers.uncompressed_header_bytes(), request_headers); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, - {":content-length", "32770"}}; // 32KB + 2 bytes + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {":content-length", "32770"}}; // 32KB + 2 bytes stream->encodeHeaders(response_headers, false); std::string response(32 * 1024 + 1, 'a'); @@ -529,8 +529,8 @@ TEST_P(EnvoyQuicServerSessionTest, FlushCloseNoTimeout) { stream->OnStreamHeaderList(/*fin=*/true, request_headers.uncompressed_header_bytes(), request_headers); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, - {":content-length", "32770"}}; // 32KB + 2 bytes + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {":content-length", "32770"}}; // 32KB + 2 bytes stream->encodeHeaders(response_headers, false); std::string response(32 * 1024 + 1, 'a'); @@ -826,8 +826,8 @@ TEST_P(EnvoyQuicServerSessionTest, SendBufferWatermark) { stream1->OnStreamHeaderList(/*fin=*/true, request_headers.uncompressed_header_bytes(), request_headers); - Http::TestHeaderMapImpl response_headers{{":status", "200"}, - {":content-length", "32770"}}; // 32KB + 2 bytes + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}, + {":content-length", "32770"}}; // 32KB + 2 bytes stream1->encodeHeaders(response_headers, false); std::string response(32 * 1024 + 1, 'a'); diff --git a/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc b/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc index 22ab4fdf80..78a38bd23b 100644 --- a/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc +++ b/test/extensions/quic_listeners/quiche/envoy_quic_server_stream_test.cc @@ -141,7 +141,7 @@ class EnvoyQuicServerStreamTest : public testing::TestWithParam { Http::MockRequestDecoder stream_decoder_; Http::MockStreamCallbacks stream_callbacks_; quic::QuicHeaderList request_headers_; - Http::TestHeaderMapImpl response_headers_; + Http::TestResponseHeaderMapImpl response_headers_; quic::QuicHeaderList trailers_; std::string host_{"www.abc.com"}; std::string request_body_{"Hello world"}; diff --git a/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc b/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc index e5adae7e5d..44fa6163c2 100644 --- a/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc +++ b/test/extensions/quic_listeners/quiche/integration/quic_http_integration_test.cc @@ -212,10 +212,10 @@ TEST_P(QuicHttpIntegrationTest, TestDelayedConnectionTeardownTimeoutTrigger) { codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); @@ -332,10 +332,10 @@ TEST_P(QuicHttpIntegrationTest, ConnectionMigration) { uint32_t old_port = lookupPort("http"); codec_client_ = makeHttpConnection(old_port); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); @@ -351,7 +351,7 @@ TEST_P(QuicHttpIntegrationTest, ConnectionMigration) { codec_client_->sendData(*request_encoder_, 1024u, true); waitForNextUpstreamRequest(0, TestUtility::DefaultTimeout); // Send response headers, and end_stream if there is no response body. - const Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + const Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; size_t response_size{5u}; upstream_request_->encodeHeaders(response_headers, false); upstream_request_->encodeData(response_size, true); diff --git a/test/extensions/stats_sinks/metrics_service/metrics_service_integration_test.cc b/test/extensions/stats_sinks/metrics_service/metrics_service_integration_test.cc index b7598cdc12..5539ece5fd 100644 --- a/test/extensions/stats_sinks/metrics_service/metrics_service_integration_test.cc +++ b/test/extensions/stats_sinks/metrics_service/metrics_service_integration_test.cc @@ -148,11 +148,11 @@ TEST_P(MetricsServiceIntegrationTest, BasicFlow) { initialize(); // Send an empty request so that histogram values merged for cluster_0. codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-lyft-user-id", "123"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-lyft-user-id", "123"}}; sendRequestAndWaitForResponse(request_headers, 0, default_response_headers_, 0); ASSERT_TRUE(waitForMetricsServiceConnection()); diff --git a/test/extensions/tracers/common/ot/opentracing_driver_impl_test.cc b/test/extensions/tracers/common/ot/opentracing_driver_impl_test.cc index 23e3c76f17..5224668a4b 100644 --- a/test/extensions/tracers/common/ot/opentracing_driver_impl_test.cc +++ b/test/extensions/tracers/common/ot/opentracing_driver_impl_test.cc @@ -55,9 +55,9 @@ class OpenTracingDriverTest : public testing::Test { } const std::string operation_name_{"test"}; - Http::TestHeaderMapImpl request_headers_{ + Http::TestRequestHeaderMapImpl request_headers_{ {":path", "/"}, {":method", "GET"}, {"x-request-id", "foo"}}; - const Http::TestHeaderMapImpl response_headers_{{":status", "500"}}; + const Http::TestResponseHeaderMapImpl response_headers_{{":status", "500"}}; SystemTime start_time_; std::unique_ptr driver_; diff --git a/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc b/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc index 07789b6ecf..659d9f4243 100644 --- a/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc +++ b/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc @@ -70,9 +70,9 @@ class DatadogDriverTest : public testing::Test { } const std::string operation_name_{"test"}; - Http::TestHeaderMapImpl request_headers_{ + Http::TestRequestHeaderMapImpl request_headers_{ {":path", "/"}, {":method", "GET"}, {"x-request-id", "foo"}}; - const Http::TestHeaderMapImpl response_headers_{{":status", "500"}}; + const Http::TestResponseHeaderMapImpl response_headers_{{":status", "500"}}; SystemTime start_time_; NiceMock tls_; @@ -131,7 +131,7 @@ TEST_F(DatadogDriverTest, FlushSpansTimer) { EXPECT_CALL(cm_.async_client_, send_(_, _, Http::AsyncClient::RequestOptions().setTimeout(timeout))) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callback = &callbacks; @@ -154,8 +154,8 @@ TEST_F(DatadogDriverTest, FlushSpansTimer) { EXPECT_EQ(1U, stats_.counter("tracing.datadog.timer_flushed").value()); EXPECT_EQ(1U, stats_.counter("tracing.datadog.traces_sent").value()); - Http::MessagePtr msg(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr msg(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); msg->body() = std::make_unique(""); callback->onSuccess(std::move(msg)); diff --git a/test/extensions/tracers/dynamic_ot/dynamic_opentracing_driver_impl_test.cc b/test/extensions/tracers/dynamic_ot/dynamic_opentracing_driver_impl_test.cc index 8600689167..46e2e32e3a 100644 --- a/test/extensions/tracers/dynamic_ot/dynamic_opentracing_driver_impl_test.cc +++ b/test/extensions/tracers/dynamic_ot/dynamic_opentracing_driver_impl_test.cc @@ -40,7 +40,7 @@ class DynamicOpenTracingDriverTest : public testing::Test { Stats::IsolatedStoreImpl stats_; const std::string operation_name_{"test"}; - Http::TestHeaderMapImpl request_headers_{ + Http::TestRequestHeaderMapImpl request_headers_{ {":path", "/"}, {":method", "GET"}, {"x-request-id", "foo"}}; SystemTime start_time_; NiceMock config_; diff --git a/test/extensions/tracers/lightstep/lightstep_tracer_impl_test.cc b/test/extensions/tracers/lightstep/lightstep_tracer_impl_test.cc index ffaf2807be..b143193c2a 100644 --- a/test/extensions/tracers/lightstep/lightstep_tracer_impl_test.cc +++ b/test/extensions/tracers/lightstep/lightstep_tracer_impl_test.cc @@ -85,9 +85,9 @@ class LightStepDriverTest : public testing::Test { } const std::string operation_name_{"test"}; - Http::TestHeaderMapImpl request_headers_{ + Http::TestRequestHeaderMapImpl request_headers_{ {":path", "/"}, {":method", "GET"}, {"x-request-id", "foo"}}; - const Http::TestHeaderMapImpl response_headers_{{":status", "500"}}; + const Http::TestResponseHeaderMapImpl response_headers_{{":status", "500"}}; SystemTime start_time_; StreamInfo::MockStreamInfo stream_info_; @@ -173,7 +173,7 @@ TEST_F(LightStepDriverTest, FlushSeveralSpans) { EXPECT_CALL(cm_.async_client_, send_(_, _, Http::AsyncClient::RequestOptions().setTimeout(timeout))) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callback = &callbacks; @@ -205,10 +205,11 @@ TEST_F(LightStepDriverTest, FlushSeveralSpans) { start_time_, {Tracing::Reason::Sampling, true}); second_span->finishSpan(); - Http::MessagePtr msg(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr msg(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); - msg->trailers(Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{"grpc-status", "0"}}}); + msg->trailers( + Http::ResponseTrailerMapPtr{new Http::TestResponseTrailerMapImpl{{"grpc-status", "0"}}}); std::unique_ptr collector_response = lightstep::Transporter::MakeCollectorResponse(); EXPECT_NE(collector_response, nullptr); @@ -236,7 +237,7 @@ TEST_F(LightStepDriverTest, FlushOneFailure) { EXPECT_CALL(cm_.async_client_, send_(_, _, Http::AsyncClient::RequestOptions().setTimeout(timeout))) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callback = &callbacks; @@ -281,7 +282,7 @@ TEST_F(LightStepDriverTest, FlushOneInvalidResponse) { EXPECT_CALL(cm_.async_client_, send_(_, _, Http::AsyncClient::RequestOptions().setTimeout(timeout))) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callback = &callbacks; @@ -305,10 +306,11 @@ TEST_F(LightStepDriverTest, FlushOneInvalidResponse) { first_span->finishSpan(); - Http::MessagePtr msg(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr msg(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); - msg->trailers(Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{"grpc-status", "0"}}}); + msg->trailers( + Http::ResponseTrailerMapPtr{new Http::TestResponseTrailerMapImpl{{"grpc-status", "0"}}}); msg->body() = std::make_unique("invalidresponse"); callback->onSuccess(std::move(msg)); @@ -360,7 +362,7 @@ TEST_F(LightStepDriverTest, FlushOneSpanGrpcFailure) { EXPECT_CALL(cm_.async_client_, send_(_, _, Http::AsyncClient::RequestOptions().setTimeout(timeout))) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callback = &callbacks; @@ -382,8 +384,8 @@ TEST_F(LightStepDriverTest, FlushOneSpanGrpcFailure) { start_time_, {Tracing::Reason::Sampling, true}); span->finishSpan(); - Http::MessagePtr msg(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr msg(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); // No trailers, gRPC is considered failed. callback->onSuccess(std::move(msg)); @@ -407,7 +409,7 @@ TEST_F(LightStepDriverTest, CancelRequestOnDestruction) { EXPECT_CALL(cm_.async_client_, send_(_, _, Http::AsyncClient::RequestOptions().setTimeout(timeout))) .WillOnce( - Invoke([&](Http::MessagePtr& /*message*/, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr& /*message*/, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callback = &callbacks; diff --git a/test/extensions/tracers/opencensus/tracer_test.cc b/test/extensions/tracers/opencensus/tracer_test.cc index 4ac8102db2..5925566b32 100644 --- a/test/extensions/tracers/opencensus/tracer_test.cc +++ b/test/extensions/tracers/opencensus/tracer_test.cc @@ -107,7 +107,7 @@ TEST(OpenCensusTracerTest, Span) { new OpenCensus::Driver(oc_config, local_info, *Api::createApiForTest())); NiceMock config; - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":path", "/"}, {":method", "GET"}, {"x-request-id", "foo"}}; const std::string operation_name{"my_operation_1"}; SystemTime start_time; @@ -196,7 +196,7 @@ void testIncomingHeaders( std::unique_ptr driver( new OpenCensus::Driver(oc_config, local_info, *Api::createApiForTest())); NiceMock config; - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":path", "/"}, {":method", "GET"}, {"x-request-id", "foo"}, diff --git a/test/extensions/tracers/xray/xray_tracer_impl_test.cc b/test/extensions/tracers/xray/xray_tracer_impl_test.cc index a6add362dd..d28e58b31c 100644 --- a/test/extensions/tracers/xray/xray_tracer_impl_test.cc +++ b/test/extensions/tracers/xray/xray_tracer_impl_test.cc @@ -26,7 +26,7 @@ class XRayDriverTest : public ::testing::Test { NiceMock server_; NiceMock tls_; NiceMock tracing_config_; - Http::TestHeaderMapImpl request_headers_{ + Http::TestRequestHeaderMapImpl request_headers_{ {":authority", "api.amazon.com"}, {":path", "/"}, {":method", "GET"}}; }; diff --git a/test/extensions/tracers/zipkin/span_context_extractor_test.cc b/test/extensions/tracers/zipkin/span_context_extractor_test.cc index 52ff18de7b..0dfa4b8ade 100644 --- a/test/extensions/tracers/zipkin/span_context_extractor_test.cc +++ b/test/extensions/tracers/zipkin/span_context_extractor_test.cc @@ -21,7 +21,7 @@ const std::string parent_id{"0000000000000002"}; } // namespace TEST(ZipkinSpanContextExtractorTest, Largest) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}{}-{}-1-{}", trace_id_high, trace_id, span_id, parent_id)}}; SpanContextExtractor extractor(request_headers); auto context = extractor.extractSpanContext(true); @@ -36,7 +36,7 @@ TEST(ZipkinSpanContextExtractorTest, Largest) { } TEST(ZipkinSpanContextExtractorTest, WithoutParentDebug) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}{}-{}-d", trace_id_high, trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); auto context = extractor.extractSpanContext(true); @@ -51,7 +51,7 @@ TEST(ZipkinSpanContextExtractorTest, WithoutParentDebug) { } TEST(ZipkinSpanContextExtractorTest, MalformedUuid) { - Http::TestHeaderMapImpl request_headers{{"b3", "b970dafd-0d95-40aa-95d8-1d8725aebe40"}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", "b970dafd-0d95-40aa-95d8-1d8725aebe40"}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: invalid trace id b970dafd-0d95-40"); @@ -59,7 +59,7 @@ TEST(ZipkinSpanContextExtractorTest, MalformedUuid) { } TEST(ZipkinSpanContextExtractorTest, MiddleOfString) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}{}-{},", trace_id, trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, @@ -68,7 +68,7 @@ TEST(ZipkinSpanContextExtractorTest, MiddleOfString) { } TEST(ZipkinSpanContextExtractorTest, DebugOnly) { - Http::TestHeaderMapImpl request_headers{{"b3", "d"}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", "d"}}; SpanContextExtractor extractor(request_headers); auto context = extractor.extractSpanContext(true); EXPECT_FALSE(context.second); @@ -82,7 +82,7 @@ TEST(ZipkinSpanContextExtractorTest, DebugOnly) { } TEST(ZipkinSpanContextExtractorTest, Sampled) { - Http::TestHeaderMapImpl request_headers{{"b3", "1"}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", "1"}}; SpanContextExtractor extractor(request_headers); auto context = extractor.extractSpanContext(true); EXPECT_FALSE(context.second); @@ -96,7 +96,7 @@ TEST(ZipkinSpanContextExtractorTest, Sampled) { } TEST(ZipkinSpanContextExtractorTest, SampledFalse) { - Http::TestHeaderMapImpl request_headers{{"b3", "0"}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", "0"}}; SpanContextExtractor extractor(request_headers); auto context = extractor.extractSpanContext(true); EXPECT_FALSE(context.second); @@ -110,7 +110,7 @@ TEST(ZipkinSpanContextExtractorTest, SampledFalse) { } TEST(ZipkinSpanContextExtractorTest, IdNotYetSampled128) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}{}-{}", trace_id_high, trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); auto context = extractor.extractSpanContext(true); @@ -125,7 +125,7 @@ TEST(ZipkinSpanContextExtractorTest, IdNotYetSampled128) { } TEST(ZipkinSpanContextExtractorTest, IdsUnsampled) { - Http::TestHeaderMapImpl request_headers{{"b3", fmt::format("{}-{}-0", trace_id, span_id)}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", fmt::format("{}-{}-0", trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); auto context = extractor.extractSpanContext(true); EXPECT_TRUE(context.second); @@ -139,7 +139,7 @@ TEST(ZipkinSpanContextExtractorTest, IdsUnsampled) { } TEST(ZipkinSpanContextExtractorTest, ParentUnsampled) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}-{}-0-{}", trace_id, span_id, parent_id)}}; SpanContextExtractor extractor(request_headers); auto context = extractor.extractSpanContext(true); @@ -154,7 +154,7 @@ TEST(ZipkinSpanContextExtractorTest, ParentUnsampled) { } TEST(ZipkinSpanContextExtractorTest, ParentDebug) { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}-{}-d-{}", trace_id, span_id, parent_id)}}; SpanContextExtractor extractor(request_headers); auto context = extractor.extractSpanContext(true); @@ -169,7 +169,7 @@ TEST(ZipkinSpanContextExtractorTest, ParentDebug) { } TEST(ZipkinSpanContextExtractorTest, IdsWithDebug) { - Http::TestHeaderMapImpl request_headers{{"b3", fmt::format("{}-{}-d", trace_id, span_id)}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", fmt::format("{}-{}-d", trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); auto context = extractor.extractSpanContext(true); EXPECT_TRUE(context.second); @@ -183,7 +183,7 @@ TEST(ZipkinSpanContextExtractorTest, IdsWithDebug) { } TEST(ZipkinSpanContextExtractorTest, WithoutSampled) { - Http::TestHeaderMapImpl request_headers{{"b3", fmt::format("{}-{}", trace_id, span_id)}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", fmt::format("{}-{}", trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); auto context = extractor.extractSpanContext(false); EXPECT_TRUE(context.second); @@ -198,7 +198,7 @@ TEST(ZipkinSpanContextExtractorTest, WithoutSampled) { TEST(ZipkinSpanContextExtractorTest, TooBig) { { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}{}{}-{}-{}", trace_id, trace_id, trace_id, span_id, trace_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, @@ -207,7 +207,7 @@ TEST(ZipkinSpanContextExtractorTest, TooBig) { } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}{}-{}-1-{}a", trace_id_high, trace_id, span_id, parent_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, @@ -216,7 +216,7 @@ TEST(ZipkinSpanContextExtractorTest, TooBig) { } TEST(ZipkinSpanContextExtractorTest, Empty) { - Http::TestHeaderMapImpl request_headers{{"b3", ""}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", ""}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: empty"); @@ -224,7 +224,7 @@ TEST(ZipkinSpanContextExtractorTest, Empty) { TEST(ZipkinSpanContextExtractorTest, InvalidInput) { { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"X-B3-TraceId", trace_id_high + trace_id.substr(0, 15) + "!"}, {"X-B3-SpanId", span_id}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, @@ -233,7 +233,7 @@ TEST(ZipkinSpanContextExtractorTest, InvalidInput) { } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}!{}-{}", trace_id.substr(0, 15), trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE( @@ -242,7 +242,7 @@ TEST(ZipkinSpanContextExtractorTest, InvalidInput) { } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}{}!-{}", trace_id, trace_id.substr(0, 15), span_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE( @@ -251,7 +251,7 @@ TEST(ZipkinSpanContextExtractorTest, InvalidInput) { } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}!-{}", trace_id.substr(0, 15), span_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE( @@ -260,14 +260,14 @@ TEST(ZipkinSpanContextExtractorTest, InvalidInput) { } { - Http::TestHeaderMapImpl request_headers{{"b3", fmt::format("{}!{}", trace_id, span_id)}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", fmt::format("{}!{}", trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: not exists span id"); } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}-{}!", trace_id, span_id.substr(0, 15))}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE( @@ -276,21 +276,23 @@ TEST(ZipkinSpanContextExtractorTest, InvalidInput) { } { - Http::TestHeaderMapImpl request_headers{{"b3", fmt::format("{}-{}!0", trace_id, span_id)}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"b3", fmt::format("{}-{}!0", trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: not exists sampling field"); } { - Http::TestHeaderMapImpl request_headers{{"b3", fmt::format("{}-{}-c", trace_id, span_id)}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"b3", fmt::format("{}-{}-c", trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: invalid sampling flag c"); } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}-{}-d!{}", trace_id, span_id, parent_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, @@ -298,7 +300,7 @@ TEST(ZipkinSpanContextExtractorTest, InvalidInput) { } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}-{}-d-{}!", trace_id, span_id, parent_id.substr(0, 15))}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE( @@ -307,7 +309,7 @@ TEST(ZipkinSpanContextExtractorTest, InvalidInput) { } { - Http::TestHeaderMapImpl request_headers{{"b3", "-"}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", "-"}}; SpanContextExtractor extractor(request_headers); EXPECT_TRUE(extractor.extractSampled({Tracing::Reason::Sampling, true})); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, @@ -317,49 +319,49 @@ TEST(ZipkinSpanContextExtractorTest, InvalidInput) { TEST(ZipkinSpanContextExtractorTest, Truncated) { { - Http::TestHeaderMapImpl request_headers{{"b3", "-1"}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", "-1"}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: truncated"); } { - Http::TestHeaderMapImpl request_headers{{"b3", "1-"}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", "1-"}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: truncated"); } { - Http::TestHeaderMapImpl request_headers{{"b3", "1-"}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", "1-"}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: truncated"); } { - Http::TestHeaderMapImpl request_headers{{"b3", trace_id.substr(0, 15)}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", trace_id.substr(0, 15)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: truncated"); } { - Http::TestHeaderMapImpl request_headers{{"b3", trace_id}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", trace_id}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: truncated"); } { - Http::TestHeaderMapImpl request_headers{{"b3", trace_id + "-"}}; + Http::TestRequestHeaderMapImpl request_headers{{"b3", trace_id + "-"}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: truncated"); } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}-{}", trace_id.substr(0, 15), span_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, @@ -367,7 +369,7 @@ TEST(ZipkinSpanContextExtractorTest, Truncated) { } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}-{}", trace_id, span_id.substr(0, 15))}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, @@ -375,21 +377,23 @@ TEST(ZipkinSpanContextExtractorTest, Truncated) { } { - Http::TestHeaderMapImpl request_headers{{"b3", fmt::format("{}-{}-", trace_id, span_id)}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"b3", fmt::format("{}-{}-", trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: truncated"); } { - Http::TestHeaderMapImpl request_headers{{"b3", fmt::format("{}-{}-1-", trace_id, span_id)}}; + Http::TestRequestHeaderMapImpl request_headers{ + {"b3", fmt::format("{}-{}-1-", trace_id, span_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, "Invalid input: truncated"); } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}-{}-1-{}", trace_id, span_id, parent_id.substr(0, 15))}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, @@ -397,7 +401,7 @@ TEST(ZipkinSpanContextExtractorTest, Truncated) { } { - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {"b3", fmt::format("{}-{}-{}{}", trace_id, span_id, trace_id, trace_id)}}; SpanContextExtractor extractor(request_headers); EXPECT_THROW_WITH_MESSAGE(extractor.extractSpanContext(true), ExtractorException, diff --git a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc index c7965b8142..a898fbb2e7 100644 --- a/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc +++ b/test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc @@ -83,7 +83,7 @@ class ZipkinDriverTest : public testing::Test { EXPECT_CALL(cm_.async_client_, send_(_, _, Http::AsyncClient::RequestOptions().setTimeout(timeout))) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callback = &callbacks; @@ -108,8 +108,8 @@ class ZipkinDriverTest : public testing::Test { config_, request_headers_, operation_name_, start_time_, {Tracing::Reason::Sampling, true}); second_span->finishSpan(); - Http::MessagePtr msg(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "202"}}})); + Http::ResponseMessagePtr msg(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "202"}}})); callback->onSuccess(std::move(msg)); @@ -130,7 +130,7 @@ class ZipkinDriverTest : public testing::Test { uint64_t generateRandom64() { return Util::generateRandom64(time_source_); } const std::string operation_name_{"test"}; - Http::TestHeaderMapImpl request_headers_{ + Http::TestRequestHeaderMapImpl request_headers_{ {":authority", "api.lyft.com"}, {":path", "/"}, {":method", "GET"}, {"x-request-id", "foo"}}; SystemTime start_time_; StreamInfo::MockStreamInfo stream_info_; @@ -212,7 +212,7 @@ TEST_F(ZipkinDriverTest, FlushOneSpanReportFailure) { EXPECT_CALL(cm_.async_client_, send_(_, _, Http::AsyncClient::RequestOptions().setTimeout(timeout))) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callback = &callbacks; @@ -232,8 +232,8 @@ TEST_F(ZipkinDriverTest, FlushOneSpanReportFailure) { start_time_, {Tracing::Reason::Sampling, true}); span->finishSpan(); - Http::MessagePtr msg(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "404"}}})); + Http::ResponseMessagePtr msg(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "404"}}})); // AsyncClient can fail with valid HTTP headers callback->onSuccess(std::move(msg)); diff --git a/test/extensions/transport_sockets/tls/integration/ssl_integration_test.cc b/test/extensions/transport_sockets/tls/integration/ssl_integration_test.cc index f903ec98ca..475a25ef41 100644 --- a/test/extensions/transport_sockets/tls/integration/ssl_integration_test.cc +++ b/test/extensions/transport_sockets/tls/integration/ssl_integration_test.cc @@ -511,7 +511,7 @@ TEST_P(SslTapIntegrationTest, TruncationWithMultipleDataFrames) { const uint64_t id = Network::ConnectionImpl::nextGlobalIdForTest() + 1; codec_client_ = makeHttpConnection(creator()); - const Http::TestHeaderMapImpl request_headers{ + const Http::TestRequestHeaderMapImpl request_headers{ {":method", "GET"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}}; auto result = codec_client_->startRequest(request_headers); auto decoder = std::move(result.second); @@ -520,7 +520,7 @@ TEST_P(SslTapIntegrationTest, TruncationWithMultipleDataFrames) { Buffer::OwnedImpl data2("two"); result.first.encodeData(data2, true); waitForNextUpstreamRequest(); - const Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + const Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; upstream_request_->encodeHeaders(response_headers, false); Buffer::OwnedImpl data3("three"); upstream_request_->encodeData(data3, false); diff --git a/test/fuzz/utility.h b/test/fuzz/utility.h index b03fc4bf08..c1323ce49d 100644 --- a/test/fuzz/utility.h +++ b/test/fuzz/utility.h @@ -76,11 +76,12 @@ replaceInvalidStringValues(const envoy::config::core::v3::Metadata& upstream_met return processed; } -// Convert from test proto Headers to TestHeaderMapImpl. -inline Http::TestHeaderMapImpl fromHeaders( +// Convert from test proto Headers to a variant of TestHeaderMapImpl. +template +inline T fromHeaders( const test::fuzz::Headers& headers, const std::unordered_set& ignore_headers = std::unordered_set()) { - Http::TestHeaderMapImpl header_map; + T header_map; for (const auto& header : headers.headers()) { // HeaderMapImpl and places such as the route lookup should never see strings with embedded // {NULL, CR, LF} values, the HTTP codecs should reject them. So, don't inject any such strings diff --git a/test/integration/eds_integration_test.cc b/test/integration/eds_integration_test.cc index c8a46a3fce..b9f51205fc 100644 --- a/test/integration/eds_integration_test.cc +++ b/test/integration/eds_integration_test.cc @@ -171,7 +171,7 @@ TEST_P(EdsIntegrationTest, Http2HcClusterRewarming) { // Wait for the first HC and verify the host is healthy. This should warm the initial cluster. waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); test_server_->waitForGaugeEq("cluster.cluster_0.membership_healthy", 1); EXPECT_EQ(1, test_server_->gauge("cluster.cluster_0.membership_total")->value()); @@ -197,7 +197,7 @@ TEST_P(EdsIntegrationTest, Http2HcClusterRewarming) { // Respond with a health check. This will cause the previous cluster to be destroyed inline as // part of processing the response. - upstream_request->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, true); + upstream_request->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, true); test_server_->waitForGaugeEq("cluster_manager.warming_clusters", 0); EXPECT_EQ(0, test_server_->gauge("cluster_manager.warming_clusters")->value()); @@ -221,7 +221,7 @@ TEST_P(EdsIntegrationTest, RemoveAfterHcFail) { // Wait for the first HC and verify the host is healthy. waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); test_server_->waitForGaugeEq("cluster.cluster_0.membership_healthy", 1); EXPECT_EQ(1, test_server_->gauge("cluster.cluster_0.membership_total")->value()); @@ -233,7 +233,7 @@ TEST_P(EdsIntegrationTest, RemoveAfterHcFail) { // Fail HC and verify the host is gone. waitForNextUpstreamRequest(); upstream_request_->encodeHeaders( - Http::TestHeaderMapImpl{{":status", "503"}, {"connection", "close"}}, true); + Http::TestResponseHeaderMapImpl{{":status", "503"}, {"connection", "close"}}, true); test_server_->waitForGaugeEq("cluster.cluster_0.membership_healthy", 0); EXPECT_EQ(0, test_server_->gauge("cluster.cluster_0.membership_total")->value()); } @@ -254,7 +254,7 @@ TEST_P(EdsIntegrationTest, EndpointWarmingSuccessfulHc) { // Wait for the first HC and verify the host is healthy and that it is no longer being excluded. // The other endpoint should still be excluded. waitForNextUpstreamRequest(0); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); test_server_->waitForGaugeEq("cluster.cluster_0.membership_excluded", 0); EXPECT_EQ(1, test_server_->gauge("cluster.cluster_0.membership_total")->value()); EXPECT_EQ(1, test_server_->gauge("cluster.cluster_0.membership_healthy")->value()); @@ -277,7 +277,7 @@ TEST_P(EdsIntegrationTest, EndpointWarmingFailedHc) { // Wait for the first HC and verify the host is healthy and that it is no longer being excluded. // The other endpoint should still be excluded. waitForNextUpstreamRequest(0); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, true); test_server_->waitForGaugeEq("cluster.cluster_0.membership_excluded", 0); EXPECT_EQ(1, test_server_->gauge("cluster.cluster_0.membership_total")->value()); EXPECT_EQ(0, test_server_->gauge("cluster.cluster_0.membership_healthy")->value()); diff --git a/test/integration/fake_upstream.cc b/test/integration/fake_upstream.cc index 04eef68741..0ff45af079 100644 --- a/test/integration/fake_upstream.cc +++ b/test/integration/fake_upstream.cc @@ -73,14 +73,16 @@ void FakeStream::decodeMetadata(Http::MetadataMapPtr&& metadata_map_ptr) { } } -void FakeStream::encode100ContinueHeaders(const Http::HeaderMap& headers) { - std::shared_ptr headers_copy(Http::HeaderMapImpl::create(headers)); +void FakeStream::encode100ContinueHeaders(const Http::ResponseHeaderMap& headers) { + std::shared_ptr headers_copy( + Http::createHeaderMap(headers)); parent_.connection().dispatcher().post( [this, headers_copy]() -> void { encoder_.encode100ContinueHeaders(*headers_copy); }); } void FakeStream::encodeHeaders(const Http::HeaderMap& headers, bool end_stream) { - std::shared_ptr headers_copy(Http::HeaderMapImpl::create(headers)); + std::shared_ptr headers_copy( + Http::createHeaderMap(headers)); if (add_served_by_header_) { headers_copy->addCopy(Http::LowerCaseString("x-served-by"), parent_.connection().localAddress()->asString()); @@ -111,7 +113,8 @@ void FakeStream::encodeData(Buffer::Instance& data, bool end_stream) { } void FakeStream::encodeTrailers(const Http::HeaderMap& trailers) { - std::shared_ptr trailers_copy(Http::HeaderMapImpl::create(trailers)); + std::shared_ptr trailers_copy( + Http::createHeaderMap(trailers)); parent_.connection().dispatcher().post( [this, trailers_copy]() -> void { encoder_.encodeTrailers(*trailers_copy); }); } @@ -204,7 +207,7 @@ AssertionResult FakeStream::waitForReset(milliseconds timeout) { } void FakeStream::startGrpcStream() { - encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); } void FakeStream::finishGrpcStream(Grpc::Status::GrpcStatus status) { diff --git a/test/integration/fake_upstream.h b/test/integration/fake_upstream.h index a28c3945bf..5ede168276 100644 --- a/test/integration/fake_upstream.h +++ b/test/integration/fake_upstream.h @@ -56,7 +56,7 @@ class FakeStream : public Http::RequestDecoder, Thread::LockGuard lock(lock_); return end_stream_; } - void encode100ContinueHeaders(const Http::HeaderMap& headers); + void encode100ContinueHeaders(const Http::ResponseHeaderMap& headers); void encodeHeaders(const Http::HeaderMap& headers, bool end_stream); void encodeData(uint64_t size, bool end_stream); void encodeData(Buffer::Instance& data, bool end_stream); diff --git a/test/integration/filter_manager_integration_test.cc b/test/integration/filter_manager_integration_test.cc index 63b736255a..d8830aad80 100644 --- a/test/integration/filter_manager_integration_test.cc +++ b/test/integration/filter_manager_integration_test.cc @@ -312,7 +312,7 @@ TEST_P(InjectDataWithHttpConnectionManagerIntegrationTest, codec_client_ = makeHttpConnection(lookupPort("http")); - Http::TestHeaderMapImpl headers{ + Http::TestRequestHeaderMapImpl headers{ {":method", "POST"}, {":path", "/api"}, {":authority", "host"}, {":scheme", "http"}}; auto response = codec_client_->makeRequestWithBody(headers, "hello!"); @@ -320,7 +320,7 @@ TEST_P(InjectDataWithHttpConnectionManagerIntegrationTest, EXPECT_TRUE(upstream_request_->complete()); EXPECT_EQ("hello!", upstream_request_->body().toString()); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); Buffer::OwnedImpl response_data{"greetings"}; upstream_request_->encodeData(response_data, true); diff --git a/test/integration/filters/call_decodedata_once_filter.cc b/test/integration/filters/call_decodedata_once_filter.cc index 0451fd901b..5e742dc825 100644 --- a/test/integration/filters/call_decodedata_once_filter.cc +++ b/test/integration/filters/call_decodedata_once_filter.cc @@ -15,7 +15,7 @@ class CallDecodeDataOnceFilter : public Http::PassThroughFilter { public: constexpr static char name[] = "call-decodedata-once-filter"; - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& header_map, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& header_map, bool) override { const Http::HeaderEntry* entry_content = header_map.get(Envoy::Http::LowerCaseString("content_size")); const Http::HeaderEntry* entry_added = @@ -33,7 +33,7 @@ class CallDecodeDataOnceFilter : public Http::PassThroughFilter { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { return Http::FilterTrailersStatus::Continue; } diff --git a/test/integration/filters/decode_headers_return_stop_all_filter.cc b/test/integration/filters/decode_headers_return_stop_all_filter.cc index 8ac96e63ff..133604822c 100644 --- a/test/integration/filters/decode_headers_return_stop_all_filter.cc +++ b/test/integration/filters/decode_headers_return_stop_all_filter.cc @@ -26,7 +26,7 @@ class DecodeHeadersReturnStopAllFilter : public Http::PassThroughFilter { // Returns Http::FilterHeadersStatus::StopAllIterationAndBuffer or // Http::FilterHeadersStatus::StopAllIterationAndWatermark for headers. Triggers a timer to // continue iteration after 5s. - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& header_map, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& header_map, bool) override { const Http::HeaderEntry* entry_content = header_map.get(Envoy::Http::LowerCaseString("content_size")); const Http::HeaderEntry* entry_added = @@ -76,7 +76,7 @@ class DecodeHeadersReturnStopAllFilter : public Http::PassThroughFilter { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { ASSERT(timer_triggered_); if (is_first_trigger_) { Buffer::OwnedImpl data(std::string(added_size_, 'a')); diff --git a/test/integration/filters/eds_ready_filter.cc b/test/integration/filters/eds_ready_filter.cc index 3a8339d0ec..2eaaf0b8e4 100644 --- a/test/integration/filters/eds_ready_filter.cc +++ b/test/integration/filters/eds_ready_filter.cc @@ -20,7 +20,7 @@ class EdsReadyFilter : public Http::PassThroughFilter { public: EdsReadyFilter(const Stats::Scope& root_scope, Stats::SymbolTable& symbol_table) : root_scope_(root_scope), stat_name_("cluster.cluster_0.membership_healthy", symbol_table) {} - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap&, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool) override { Stats::GaugeOptConstRef gauge = root_scope_.findGauge(stat_name_.statName()); if (!gauge.has_value()) { decoder_callbacks_->sendLocalReply(Envoy::Http::Code::InternalServerError, diff --git a/test/integration/filters/encode_headers_return_stop_all_filter.cc b/test/integration/filters/encode_headers_return_stop_all_filter.cc index 8668fa6ff1..88a409501c 100644 --- a/test/integration/filters/encode_headers_return_stop_all_filter.cc +++ b/test/integration/filters/encode_headers_return_stop_all_filter.cc @@ -26,7 +26,7 @@ class EncodeHeadersReturnStopAllFilter : public Http::PassThroughFilter { // Returns Http::FilterHeadersStatus::StopAllIterationAndBuffer or // Http::FilterHeadersStatus::StopAllIterationAndWatermark for headers. Triggers a timer to // continue iteration after 5s. - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap& header_map, bool) override { + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& header_map, bool) override { const Http::HeaderEntry* entry_content = header_map.get(Envoy::Http::LowerCaseString("content_size")); const Http::HeaderEntry* entry_added = @@ -72,7 +72,7 @@ class EncodeHeadersReturnStopAllFilter : public Http::PassThroughFilter { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap&) override { ASSERT(timer_triggered_); Http::MetadataMap metadata_map = {{"trailers", "trailers"}}; Http::MetadataMapPtr metadata_map_ptr = std::make_unique(metadata_map); diff --git a/test/integration/filters/headers_only_filter.cc b/test/integration/filters/headers_only_filter.cc index 4c661f22e6..c414285882 100644 --- a/test/integration/filters/headers_only_filter.cc +++ b/test/integration/filters/headers_only_filter.cc @@ -15,7 +15,7 @@ class HeaderOnlyDecoderFilter : public Http::PassThroughFilter { public: constexpr static char name[] = "decode-headers-only"; - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap&, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool) override { return Http::FilterHeadersStatus::ContinueAndEndStream; } }; @@ -29,7 +29,7 @@ class HeaderOnlyEncoderFilter : public Http::PassThroughFilter { public: constexpr static char name[] = "encode-headers-only"; - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap&, bool) override { + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap&, bool) override { return Http::FilterHeadersStatus::ContinueAndEndStream; } }; diff --git a/test/integration/filters/metadata_stop_all_filter.cc b/test/integration/filters/metadata_stop_all_filter.cc index b8e1093be8..f119c38cc9 100644 --- a/test/integration/filters/metadata_stop_all_filter.cc +++ b/test/integration/filters/metadata_stop_all_filter.cc @@ -21,7 +21,7 @@ class MetadataStopAllFilter : public Http::PassThroughFilter { public: constexpr static char name[] = "metadata-stop-all-filter"; - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& header_map, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& header_map, bool) override { const Http::HeaderEntry* entry_content = header_map.get(Envoy::Http::LowerCaseString("content_size")); ASSERT(entry_content != nullptr); @@ -37,7 +37,7 @@ class MetadataStopAllFilter : public Http::PassThroughFilter { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { ASSERT(timer_triggered_); return Http::FilterTrailersStatus::Continue; } diff --git a/test/integration/filters/process_context_filter.cc b/test/integration/filters/process_context_filter.cc index 0e335f7835..25772dac57 100644 --- a/test/integration/filters/process_context_filter.cc +++ b/test/integration/filters/process_context_filter.cc @@ -20,7 +20,7 @@ class ProcessContextFilter : public Http::PassThroughFilter { public: ProcessContextFilter(ProcessContext& process_context) : process_object_(dynamic_cast(process_context.get())) {} - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap&, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool) override { if (!process_object_.isHealthy()) { decoder_callbacks_->sendLocalReply(Envoy::Http::Code::InternalServerError, "ProcessObjectForFilter is unhealthy", nullptr, diff --git a/test/integration/filters/request_metadata_filter.cc b/test/integration/filters/request_metadata_filter.cc index 6188608b31..ff4e7ba203 100644 --- a/test/integration/filters/request_metadata_filter.cc +++ b/test/integration/filters/request_metadata_filter.cc @@ -14,7 +14,7 @@ namespace Envoy { // "consume", the metadata will be consumed and not forwarded to the next hop. class RequestMetadataStreamFilter : public Http::PassThroughFilter { public: - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap&, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool) override { Http::MetadataMap metadata_map = {{"headers", "headers"}}; Http::MetadataMapPtr metadata_map_ptr = std::make_unique(metadata_map); decoder_callbacks_->addDecodedMetadata().emplace_back(std::move(metadata_map_ptr)); @@ -28,7 +28,7 @@ class RequestMetadataStreamFilter : public Http::PassThroughFilter { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { Http::MetadataMap metadata_map = {{"trailers", "trailers"}}; Http::MetadataMapPtr metadata_map_ptr = std::make_unique(metadata_map); decoder_callbacks_->addDecodedMetadata().emplace_back(std::move(metadata_map_ptr)); diff --git a/test/integration/filters/response_metadata_filter.cc b/test/integration/filters/response_metadata_filter.cc index f4e62df60b..a45aa8c758 100644 --- a/test/integration/filters/response_metadata_filter.cc +++ b/test/integration/filters/response_metadata_filter.cc @@ -16,7 +16,7 @@ namespace Envoy { class ResponseMetadataStreamFilter : public Http::PassThroughFilter { public: // Inserts one new metadata_map. - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap&, bool) override { + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap&, bool) override { Http::MetadataMap metadata_map = {{"headers", "headers"}, {"duplicate", "duplicate"}}; Http::MetadataMapPtr metadata_map_ptr = std::make_unique(metadata_map); encoder_callbacks_->addEncodedMetadata(std::move(metadata_map_ptr)); @@ -32,7 +32,7 @@ class ResponseMetadataStreamFilter : public Http::PassThroughFilter { } // Inserts two metadata_maps by calling decoder_callbacks_->encodeMetadata() twice. - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap&) override { Http::MetadataMap metadata_map = {{"trailers", "trailers"}}; Http::MetadataMapPtr metadata_map_ptr = std::make_unique(metadata_map); encoder_callbacks_->addEncodedMetadata(std::move(metadata_map_ptr)); @@ -43,7 +43,7 @@ class ResponseMetadataStreamFilter : public Http::PassThroughFilter { } // Inserts two metadata_maps by calling decoder_callbacks_->encodeMetadata() twice. - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override { + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override { Http::MetadataMap metadata_map = {{"100-continue", "100-continue"}, {"duplicate", "duplicate"}}; Http::MetadataMapPtr metadata_map_ptr = std::make_unique(metadata_map); encoder_callbacks_->addEncodedMetadata(std::move(metadata_map_ptr)); diff --git a/test/integration/filters/stop_iteration_and_continue_filter.cc b/test/integration/filters/stop_iteration_and_continue_filter.cc index f8189b3eef..c631d8b9e7 100644 --- a/test/integration/filters/stop_iteration_and_continue_filter.cc +++ b/test/integration/filters/stop_iteration_and_continue_filter.cc @@ -27,7 +27,7 @@ class StopIterationAndContinueFilter : public Http::PassThroughFilter { encode_delay_timer_->enableTimer(std::chrono::seconds(0)); } - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap&, bool end_stream) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool end_stream) override { if (end_stream) { setEndStreamAndDecodeTimer(); return Http::FilterHeadersStatus::StopIteration; @@ -43,7 +43,7 @@ class StopIterationAndContinueFilter : public Http::PassThroughFilter { return Http::FilterDataStatus::StopIterationNoBuffer; } - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap&, bool end_stream) override { + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap&, bool end_stream) override { if (end_stream) { setEndStreamAndEncodeTimer(); return Http::FilterHeadersStatus::StopIteration; diff --git a/test/integration/hds_integration_test.cc b/test/integration/hds_integration_test.cc index 429abb4442..00b405b411 100644 --- a/test/integration/hds_integration_test.cc +++ b/test/integration/hds_integration_test.cc @@ -257,7 +257,7 @@ TEST_P(HdsIntegrationTest, SingleEndpointHealthyHttp) { healthcheckEndpoints(); // Endpoint responds to the health check - host_stream_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + host_stream_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); host_stream_->encodeData(1024, true); // Receive updates until the one we expect arrives @@ -328,7 +328,7 @@ TEST_P(HdsIntegrationTest, SingleEndpointUnhealthyHttp) { healthcheckEndpoints(); // Endpoint responds to the health check - host_stream_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "404"}}, false); + host_stream_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "404"}}, false); host_stream_->encodeData(1024, true); // Receive updates until the one we expect arrives @@ -473,9 +473,9 @@ TEST_P(HdsIntegrationTest, TwoEndpointsSameLocality) { healthcheckEndpoints("anna"); // Endpoints respond to the health check - host_stream_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "404"}}, false); + host_stream_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "404"}}, false); host_stream_->encodeData(1024, true); - host2_stream_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + host2_stream_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); host2_stream_->encodeData(1024, true); // Receive updates until the one we expect arrives @@ -525,9 +525,9 @@ TEST_P(HdsIntegrationTest, TwoEndpointsDifferentLocality) { healthcheckEndpoints("anna"); // Endpoint responds to the health check - host_stream_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "404"}}, false); + host_stream_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "404"}}, false); host_stream_->encodeData(1024, true); - host2_stream_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + host2_stream_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); host2_stream_->encodeData(1024, true); // Receive updates until the one we expect arrives @@ -588,9 +588,9 @@ TEST_P(HdsIntegrationTest, TwoEndpointsDifferentClusters) { healthcheckEndpoints("cat"); // Endpoint responds to the health check - host_stream_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "404"}}, false); + host_stream_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "404"}}, false); host_stream_->encodeData(1024, true); - host2_stream_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + host2_stream_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); host2_stream_->encodeData(1024, true); // Receive updates until the one we expect arrives @@ -632,7 +632,7 @@ TEST_P(HdsIntegrationTest, TestUpdateMessage) { healthcheckEndpoints(); // Endpoint responds to the health check - host_stream_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + host_stream_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); host_stream_->encodeData(1024, true); // Receive updates until the one we expect arrives @@ -678,7 +678,7 @@ TEST_P(HdsIntegrationTest, TestUpdateMessage) { ASSERT_TRUE(host2_stream_->waitForEndStream(*dispatcher_)); // Endpoint responds to the health check - host2_stream_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "404"}}, false); + host2_stream_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "404"}}, false); host2_stream_->encodeData(1024, true); // Receive updates until the one we expect arrives diff --git a/test/integration/http2_integration_test.cc b/test/integration/http2_integration_test.cc index 4106538809..1180b2b957 100644 --- a/test/integration/http2_integration_test.cc +++ b/test/integration/http2_integration_test.cc @@ -308,7 +308,7 @@ TEST_P(Http2MetadataIntegrationTest, TestResponseMetadata) { waitForNextUpstreamRequest(); upstream_request_->encodeHeaders(default_response_headers_, false); upstream_request_->encodeData(10, false); - Http::TestHeaderMapImpl response_trailers{{"response", "trailer"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"response", "trailer"}}; upstream_request_->encodeTrailers(response_trailers); response->waitForEndStream(); @@ -318,15 +318,16 @@ TEST_P(Http2MetadataIntegrationTest, TestResponseMetadata) { EXPECT_EQ(response->keyCount("duplicate"), 3); // Upstream responds with headers, 100-continue and data. - response = codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "GET"}, + response = + codec_client_->makeRequestWithBody(Http::TestRequestHeaderMapImpl{{":method", "GET"}, {":path", "/dynamo/url"}, {":scheme", "http"}, {":authority", "host"}, {"expect", "100-continue"}}, - 10); + 10); waitForNextUpstreamRequest(); - upstream_request_->encode100ContinueHeaders(Http::TestHeaderMapImpl{{":status", "100"}}); + upstream_request_->encode100ContinueHeaders(Http::TestResponseHeaderMapImpl{{":status", "100"}}); response->waitForContinueHeaders(); upstream_request_->encodeHeaders(default_response_headers_, false); upstream_request_->encodeData(100, true); @@ -415,7 +416,7 @@ TEST_P(Http2MetadataIntegrationTest, ProxySmallMetadataInRequest) { codec_client_->sendMetadata(*request_encoder_, metadata_map); codec_client_->sendData(*request_encoder_, 1, false); codec_client_->sendMetadata(*request_encoder_, metadata_map); - Http::TestHeaderMapImpl request_trailers{{"request", "trailer"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"request", "trailer"}}; codec_client_->sendTrailers(*request_encoder_, request_trailers); waitForNextUpstreamRequest(); @@ -445,7 +446,7 @@ TEST_P(Http2MetadataIntegrationTest, ProxyLargeMetadataInRequest) { codec_client_->sendMetadata(*request_encoder_, metadata_map); codec_client_->sendData(*request_encoder_, 1, false); codec_client_->sendMetadata(*request_encoder_, metadata_map); - Http::TestHeaderMapImpl request_trailers{{"request", "trailer"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"request", "trailer"}}; codec_client_->sendTrailers(*request_encoder_, request_trailers); waitForNextUpstreamRequest(); @@ -542,7 +543,7 @@ TEST_P(Http2MetadataIntegrationTest, ConsumeAndInsertRequestMetadata) { codec_client_->sendData(*request_encoder_, 10, false); metadata_map = {{"consume", "consume"}}; codec_client_->sendMetadata(*request_encoder_, metadata_map); - Http::TestHeaderMapImpl request_trailers{{"trailer", "trailer"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"trailer", "trailer"}}; codec_client_->sendTrailers(*request_encoder_, request_trailers); waitForNextUpstreamRequest(); @@ -613,18 +614,18 @@ void Http2MetadataIntegrationTest::runHeaderOnlyTest(bool send_request_body, siz // Sends a request with body. Only headers will pass through filters. IntegrationStreamDecoderPtr response; if (send_request_body) { - response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, - body_size); + response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, + body_size); } else { - response = - codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + response = codec_client_->makeHeaderOnlyRequest( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); } waitForNextUpstreamRequest(); @@ -691,7 +692,7 @@ void Http2MetadataIntegrationTest::testRequestMetadataWithStopAllFilter() { codec_client_->sendMetadata(*request_encoder_, metadata_map); metadata_map = {{"consume", "consume"}}; codec_client_->sendMetadata(*request_encoder_, metadata_map); - Http::TestHeaderMapImpl request_trailers{{"trailer", "trailer"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"trailer", "trailer"}}; codec_client_->sendTrailers(*request_encoder_, request_trailers); waitForNextUpstreamRequest(); @@ -746,7 +747,7 @@ name: encode-headers-return-stop-all-filter } upstream_request_->encodeData(size, false); - Http::TestHeaderMapImpl response_trailers{{"response", "trailer"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"response", "trailer"}}; upstream_request_->encodeTrailers(response_trailers); response->waitForEndStream(); @@ -828,7 +829,7 @@ TEST_P(Http2IntegrationTest, GoAway) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto encoder_decoder = codec_client_->startRequest(Http::TestHeaderMapImpl{ + auto encoder_decoder = codec_client_->startRequest(Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/healthcheck"}, {":scheme", "http"}, {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); @@ -865,13 +866,13 @@ TEST_P(Http2IntegrationTest, GrpcRequestTimeout) { // With upstream request timeout Envoy should send a gRPC-Status "DEADLINE EXCEEDED". // TODO: Properly map request timeout to "DEADLINE EXCEEDED" instead of "SERVICE UNAVAILABLE". auto response = codec_client_->makeHeaderOnlyRequest( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"te", "trailers"}, - {"grpc-timeout", "1S"}, // 1 Second - {"content-type", "application/grpc"}}); + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"te", "trailers"}, + {"grpc-timeout", "1S"}, // 1 Second + {"content-type", "application/grpc"}}); response->waitForEndStream(); EXPECT_TRUE(response->complete()); EXPECT_EQ("200", response->headers().Status()->value().getStringView()); @@ -907,10 +908,10 @@ TEST_P(Http2IntegrationTest, IdleTimeoutWithSimultaneousRequests) { // Start request 1 auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); encoder1 = &encoder_decoder.first; auto response1 = std::move(encoder_decoder.second); @@ -919,10 +920,10 @@ TEST_P(Http2IntegrationTest, IdleTimeoutWithSimultaneousRequests) { // Start request 2 auto encoder_decoder2 = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); encoder2 = &encoder_decoder2.first; auto response2 = std::move(encoder_decoder2.second); ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection2)); @@ -937,7 +938,7 @@ TEST_P(Http2IntegrationTest, IdleTimeoutWithSimultaneousRequests) { ASSERT_TRUE(upstream_request2->waitForEndStream(*dispatcher_)); // Respond to request 2 - upstream_request2->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request2->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_request2->encodeData(request2_bytes, true); response2->waitForEndStream(); EXPECT_TRUE(upstream_request2->complete()); @@ -951,7 +952,7 @@ TEST_P(Http2IntegrationTest, IdleTimeoutWithSimultaneousRequests) { EXPECT_NE(0, test_server_->counter("cluster.cluster_0.upstream_cx_total")->value()); // Respond to request 1 - upstream_request1->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request1->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_request1->encodeData(request1_bytes, true); response1->waitForEndStream(); EXPECT_TRUE(upstream_request1->complete()); @@ -984,10 +985,10 @@ TEST_P(Http2IntegrationTest, RequestMirrorWithBody) { // Send request with body. IntegrationStreamDecoderPtr request = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, + codec_client_->makeRequestWithBody(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, "hello"); // Wait for the first request as well as the shadow. @@ -1004,8 +1005,8 @@ TEST_P(Http2IntegrationTest, RequestMirrorWithBody) { EXPECT_EQ("hello", upstream_request2->body().toString()); EXPECT_EQ("host-shadow", upstream_request2->headers().Host()->value().getStringView()); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); - upstream_request2->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); + upstream_request2->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); request->waitForEndStream(); EXPECT_EQ("200", request->headers().Status()->value().getStringView()); @@ -1027,10 +1028,10 @@ void Http2IntegrationTest::simultaneousRequest(int32_t request1_bytes, int32_t r // Start request 1 auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); encoder1 = &encoder_decoder.first; auto response1 = std::move(encoder_decoder.second); @@ -1039,10 +1040,10 @@ void Http2IntegrationTest::simultaneousRequest(int32_t request1_bytes, int32_t r // Start request 2 auto encoder_decoder2 = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); encoder2 = &encoder_decoder2.first; auto response2 = std::move(encoder_decoder2.second); ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection2)); @@ -1057,7 +1058,7 @@ void Http2IntegrationTest::simultaneousRequest(int32_t request1_bytes, int32_t r ASSERT_TRUE(upstream_request2->waitForEndStream(*dispatcher_)); // Respond to request 2 - upstream_request2->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request2->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_request2->encodeData(request2_bytes, true); response2->waitForEndStream(); EXPECT_TRUE(upstream_request2->complete()); @@ -1067,7 +1068,7 @@ void Http2IntegrationTest::simultaneousRequest(int32_t request1_bytes, int32_t r EXPECT_EQ(request2_bytes, response2->body().size()); // Respond to request 1 - upstream_request1->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request1->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_request1->encodeData(request2_bytes, true); response1->waitForEndStream(); EXPECT_TRUE(upstream_request1->complete()); @@ -1245,7 +1246,7 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, Http2MetadataIntegrationTest, TestUtility::ipTestParamsToString); void Http2RingHashIntegrationTest::sendMultipleRequests( - int request_bytes, Http::TestHeaderMapImpl headers, + int request_bytes, Http::TestRequestHeaderMapImpl headers, std::function cb) { TestRandomGenerator rand; const uint32_t num_requests = 50; @@ -1278,7 +1279,7 @@ void Http2RingHashIntegrationTest::sendMultipleRequests( for (uint32_t i = 0; i < num_requests; ++i) { ASSERT_TRUE(upstream_requests[i]->waitForEndStream(*dispatcher_)); - upstream_requests[i]->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_requests[i]->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_requests[i]->encodeData(rand.random() % (1024 * 2), true); } @@ -1311,10 +1312,10 @@ TEST_P(Http2RingHashIntegrationTest, CookieRoutingNoCookieNoTtl) { std::set served_by; sendMultipleRequests( 1024, - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, [&](IntegrationStreamDecoder& response) { EXPECT_EQ("200", response.headers().Status()->value().getStringView()); EXPECT_TRUE(response.headers().get(Http::Headers::get().SetCookie) == nullptr); @@ -1341,10 +1342,10 @@ TEST_P(Http2RingHashIntegrationTest, CookieRoutingNoCookieWithNonzeroTtlSet) { std::set set_cookies; sendMultipleRequests( 1024, - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, [&](IntegrationStreamDecoder& response) { EXPECT_EQ("200", response.headers().Status()->value().getStringView()); std::string value( @@ -1372,10 +1373,10 @@ TEST_P(Http2RingHashIntegrationTest, CookieRoutingNoCookieWithZeroTtlSet) { std::set set_cookies; sendMultipleRequests( 1024, - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, [&](IntegrationStreamDecoder& response) { EXPECT_EQ("200", response.headers().Status()->value().getStringView()); std::string value( @@ -1402,11 +1403,11 @@ TEST_P(Http2RingHashIntegrationTest, CookieRoutingWithCookieNoTtl) { std::set served_by; sendMultipleRequests( 1024, - Http::TestHeaderMapImpl{{":method", "POST"}, - {"cookie", "foo=bar"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {"cookie", "foo=bar"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, [&](IntegrationStreamDecoder& response) { EXPECT_EQ("200", response.headers().Status()->value().getStringView()); EXPECT_TRUE(response.headers().get(Http::Headers::get().SetCookie) == nullptr); @@ -1433,11 +1434,11 @@ TEST_P(Http2RingHashIntegrationTest, CookieRoutingWithCookieWithTtlSet) { std::set served_by; sendMultipleRequests( 1024, - Http::TestHeaderMapImpl{{":method", "POST"}, - {"cookie", "foo=bar"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {"cookie", "foo=bar"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, [&](IntegrationStreamDecoder& response) { EXPECT_EQ("200", response.headers().Status()->value().getStringView()); EXPECT_TRUE(response.headers().get(Http::Headers::get().SetCookie) == nullptr); diff --git a/test/integration/http2_integration_test.h b/test/integration/http2_integration_test.h index 4a251bc92b..d19d2d6436 100644 --- a/test/integration/http2_integration_test.h +++ b/test/integration/http2_integration_test.h @@ -37,7 +37,7 @@ class Http2RingHashIntegrationTest : public Http2IntegrationTest { void createUpstreams() override; - void sendMultipleRequests(int request_bytes, Http::TestHeaderMapImpl headers, + void sendMultipleRequests(int request_bytes, Http::TestRequestHeaderMapImpl headers, std::function cb); std::vector fake_upstream_connections_; diff --git a/test/integration/http2_upstream_integration_test.cc b/test/integration/http2_upstream_integration_test.cc index 825388c048..efd248cf52 100644 --- a/test/integration/http2_upstream_integration_test.cc +++ b/test/integration/http2_upstream_integration_test.cc @@ -64,10 +64,10 @@ void Http2UpstreamIntegrationTest::bidirectionalStreaming(uint32_t bytes) { // Start the request. auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); auto response = std::move(encoder_decoder.second); request_encoder_ = &encoder_decoder.first; ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_)); @@ -78,12 +78,13 @@ void Http2UpstreamIntegrationTest::bidirectionalStreaming(uint32_t bytes) { ASSERT_TRUE(upstream_request_->waitForData(*dispatcher_, bytes)); // Start sending the response and ensure it is received downstream. - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_request_->encodeData(bytes, false); response->waitForBodyData(bytes); // Finish the request. - codec_client_->sendTrailers(*request_encoder_, Http::TestHeaderMapImpl{{"trailer", "foo"}}); + codec_client_->sendTrailers(*request_encoder_, + Http::TestRequestTrailerMapImpl{{"trailer", "foo"}}); ASSERT_TRUE(upstream_request_->waitForEndStream(*dispatcher_)); // Finish the response. @@ -105,10 +106,10 @@ TEST_P(Http2UpstreamIntegrationTest, BidirectionalStreamingReset) { // Start sending the request. auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); auto response = std::move(encoder_decoder.second); request_encoder_ = &encoder_decoder.first; ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_)); @@ -119,12 +120,13 @@ TEST_P(Http2UpstreamIntegrationTest, BidirectionalStreamingReset) { ASSERT_TRUE(upstream_request_->waitForData(*dispatcher_, 1024)); // Start sending the response. - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_request_->encodeData(1024, false); response->waitForBodyData(1024); // Finish sending the request. - codec_client_->sendTrailers(*request_encoder_, Http::TestHeaderMapImpl{{"trailer", "foo"}}); + codec_client_->sendTrailers(*request_encoder_, + Http::TestRequestTrailerMapImpl{{"trailer", "foo"}}); ASSERT_TRUE(upstream_request_->waitForEndStream(*dispatcher_)); // Reset the stream. @@ -144,10 +146,10 @@ void Http2UpstreamIntegrationTest::simultaneousRequest(uint32_t request1_bytes, // Start request 1 auto encoder_decoder1 = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); Http::RequestEncoder* encoder1 = &encoder_decoder1.first; auto response1 = std::move(encoder_decoder1.second); ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_)); @@ -155,10 +157,10 @@ void Http2UpstreamIntegrationTest::simultaneousRequest(uint32_t request1_bytes, // Start request 2 auto encoder_decoder2 = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); Http::RequestEncoder* encoder2 = &encoder_decoder2.first; auto response2 = std::move(encoder_decoder2.second); ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request2)); @@ -172,7 +174,7 @@ void Http2UpstreamIntegrationTest::simultaneousRequest(uint32_t request1_bytes, ASSERT_TRUE(upstream_request2->waitForEndStream(*dispatcher_)); // Respond to request 2 - upstream_request2->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request2->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_request2->encodeData(response2_bytes, true); response2->waitForEndStream(); EXPECT_TRUE(upstream_request2->complete()); @@ -182,7 +184,7 @@ void Http2UpstreamIntegrationTest::simultaneousRequest(uint32_t request1_bytes, EXPECT_EQ(response2_bytes, response2->body().size()); // Respond to request 1 - upstream_request1->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request1->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_request1->encodeData(response1_bytes, true); response1->waitForEndStream(); EXPECT_TRUE(upstream_request1->complete()); @@ -213,7 +215,7 @@ void Http2UpstreamIntegrationTest::manySimultaneousRequests(uint32_t request_byt codec_client_ = makeHttpConnection(lookupPort("http")); for (uint32_t i = 0; i < num_requests; ++i) { response_bytes.push_back(rand.random() % (1024 * 2)); - auto headers = Http::TestHeaderMapImpl{ + auto headers = Http::TestRequestHeaderMapImpl{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, @@ -271,10 +273,10 @@ TEST_P(Http2UpstreamIntegrationTest, UpstreamConnectionCloseWithManyStreams) { codec_client_ = makeHttpConnection(lookupPort("http")); for (uint32_t i = 0; i < num_requests; ++i) { auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); encoders.push_back(&encoder_decoder.first); responses.push_back(std::move(encoder_decoder.second)); @@ -305,7 +307,7 @@ TEST_P(Http2UpstreamIntegrationTest, UpstreamConnectionCloseWithManyStreams) { } for (uint32_t i = 1; i < num_requests; ++i) { ASSERT_TRUE(upstream_requests[i]->waitForEndStream(*dispatcher_)); - upstream_requests[i]->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_requests[i]->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_requests[i]->encodeData(100, false); } // Close the connection. @@ -351,11 +353,11 @@ name: envoy.router // Send the request. codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"te", "trailers"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"te", "trailers"}}); auto downstream_request = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); Buffer::OwnedImpl data(R"({"TableName":"locations"})"); @@ -406,7 +408,7 @@ TEST_P(Http2UpstreamIntegrationTest, ManyResponseHeadersAccepted) { auto* http_protocol_options = cluster->mutable_common_http_protocol_options(); http_protocol_options->mutable_max_headers_count()->set_value(200); }); - Http::TestHeaderMapImpl response_headers(default_response_headers_); + Http::TestResponseHeaderMapImpl response_headers(default_response_headers_); for (int i = 0; i < 150; i++) { response_headers.addCopy(std::to_string(i), std::string(1, 'a')); } diff --git a/test/integration/http_integration.cc b/test/integration/http_integration.cc index 928f6cd1c4..79e811cefc 100644 --- a/test/integration/http_integration.cc +++ b/test/integration/http_integration.cc @@ -75,7 +75,7 @@ void IntegrationCodecClient::flushWrite() { } IntegrationStreamDecoderPtr -IntegrationCodecClient::makeHeaderOnlyRequest(const Http::HeaderMap& headers) { +IntegrationCodecClient::makeHeaderOnlyRequest(const Http::RequestHeaderMap& headers) { auto response = std::make_unique(dispatcher_); Http::RequestEncoder& encoder = newStream(*response); encoder.getStream().addCallbacks(*response); @@ -85,12 +85,13 @@ IntegrationCodecClient::makeHeaderOnlyRequest(const Http::HeaderMap& headers) { } IntegrationStreamDecoderPtr -IntegrationCodecClient::makeRequestWithBody(const Http::HeaderMap& headers, uint64_t body_size) { +IntegrationCodecClient::makeRequestWithBody(const Http::RequestHeaderMap& headers, + uint64_t body_size) { return makeRequestWithBody(headers, std::string(body_size, 'a')); } IntegrationStreamDecoderPtr -IntegrationCodecClient::makeRequestWithBody(const Http::HeaderMap& headers, +IntegrationCodecClient::makeRequestWithBody(const Http::RequestHeaderMap& headers, const std::string& body) { auto response = std::make_unique(dispatcher_); Http::RequestEncoder& encoder = newStream(*response); @@ -122,7 +123,7 @@ void IntegrationCodecClient::sendData(Http::RequestEncoder& encoder, uint64_t si } void IntegrationCodecClient::sendTrailers(Http::RequestEncoder& encoder, - const Http::HeaderMap& trailers) { + const Http::RequestTrailerMap& trailers) { encoder.encodeTrailers(trailers); flushWrite(); } @@ -142,7 +143,7 @@ void IntegrationCodecClient::sendMetadata(Http::RequestEncoder& encoder, } std::pair -IntegrationCodecClient::startRequest(const Http::HeaderMap& headers) { +IntegrationCodecClient::startRequest(const Http::RequestHeaderMap& headers) { auto response = std::make_unique(dispatcher_); Http::RequestEncoder& encoder = newStream(*response); encoder.getStream().addCallbacks(*response); @@ -289,9 +290,9 @@ ConfigHelper::ConfigModifierFunction HttpIntegrationTest::setEnableUpstreamTrail } IntegrationStreamDecoderPtr HttpIntegrationTest::sendRequestAndWaitForResponse( - const Http::TestHeaderMapImpl& request_headers, uint32_t request_body_size, - const Http::TestHeaderMapImpl& response_headers, uint32_t response_size, int upstream_index, - std::chrono::milliseconds time) { + const Http::TestRequestHeaderMapImpl& request_headers, uint32_t request_body_size, + const Http::TestResponseHeaderMapImpl& response_headers, uint32_t response_size, + int upstream_index, std::chrono::milliseconds time) { ASSERT(codec_client_ != nullptr); // Send the request to Envoy. IntegrationStreamDecoderPtr response; @@ -415,7 +416,7 @@ void HttpIntegrationTest::testRouterRequestAndResponseWithBody( initialize(); codec_client_ = makeHttpConnection( create_connection ? ((*create_connection)()) : makeClientConnection((lookupPort("http")))); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}, {"x-lyft-user-id", "123"}, {"x-forwarded-for", "10.0.0.1"}}; if (big_header) { @@ -437,11 +438,11 @@ HttpIntegrationTest::makeHeaderOnlyRequest(ConnectionCreationFunction* create_co } codec_client_ = makeHttpConnection( create_connection ? ((*create_connection)()) : makeClientConnection((lookupPort("http")))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", path}, - {":scheme", "http"}, - {":authority", authority}, - {"x-lyft-user-id", "123"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", path}, + {":scheme", "http"}, + {":authority", authority}, + {"x-lyft-user-id", "123"}}; return sendRequestAndWaitForResponse(request_headers, 0, default_response_headers_, 0, upstream_index); } @@ -631,16 +632,16 @@ void HttpIntegrationTest::testRouterUpstreamResponseBeforeRequestComplete() { void HttpIntegrationTest::testRetry() { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}}, - 1024); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}}, + 1024); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); if (fake_upstreams_[0]->httpType() == FakeHttpConnection::Type::HTTP1) { ASSERT_TRUE(fake_upstream_connection_->waitForDisconnect()); @@ -670,16 +671,16 @@ void HttpIntegrationTest::testRetryAttemptCountHeader() { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test_retry"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}}, - 1024); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test_retry"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}}, + 1024); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); EXPECT_EQ( atoi(std::string(upstream_request_->headers().EnvoyAttemptCount()->value().getStringView()) @@ -710,22 +711,23 @@ void HttpIntegrationTest::testRetryAttemptCountHeader() { } void HttpIntegrationTest::testGrpcRetry() { - Http::TestHeaderMapImpl response_trailers{{"response1", "trailer1"}, {"grpc-status", "0"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"response1", "trailer1"}, + {"grpc-status", "0"}}; initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-grpc-on", "cancelled"}}); + auto encoder_decoder = codec_client_->startRequest( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-grpc-on", "cancelled"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); codec_client_->sendData(*request_encoder_, 1024, true); waitForNextUpstreamRequest(); upstream_request_->encodeHeaders( - Http::TestHeaderMapImpl{{":status", "200"}, {"grpc-status", "1"}}, false); + Http::TestResponseHeaderMapImpl{{":status", "200"}, {"grpc-status", "1"}}, false); if (fake_upstreams_[0]->httpType() == FakeHttpConnection::Type::HTTP1) { ASSERT_TRUE(fake_upstream_connection_->waitForDisconnect()); ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_)); @@ -759,11 +761,11 @@ void HttpIntegrationTest::testEnvoyHandling100Continue(bool additional_continue_ codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/dynamo/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"expect", "100-continue"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/dynamo/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"expect", "100-continue"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_)); @@ -786,7 +788,8 @@ void HttpIntegrationTest::testEnvoyHandling100Continue(bool additional_continue_ if (additional_continue_from_upstream) { // Make sure if upstream sends an 100-Continue Envoy doesn't send its own and proxy the one // from upstream! - upstream_request_->encode100ContinueHeaders(Http::TestHeaderMapImpl{{":status", "100"}}); + upstream_request_->encode100ContinueHeaders( + Http::TestResponseHeaderMapImpl{{":status", "100"}}); } upstream_request_->encodeHeaders(default_response_headers_, false); upstream_request_->encodeData(12, true); @@ -829,11 +832,11 @@ void HttpIntegrationTest::testEnvoyProxying100Continue(bool continue_before_upst codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/dynamo/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"expect", "100-continue"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/dynamo/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"expect", "100-continue"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); @@ -844,7 +847,8 @@ void HttpIntegrationTest::testEnvoyProxying100Continue(bool continue_before_upst if (continue_before_upstream_complete) { // This case tests sending on 100-Continue headers before the client has sent all the // request data. - upstream_request_->encode100ContinueHeaders(Http::TestHeaderMapImpl{{":status", "100"}}); + upstream_request_->encode100ContinueHeaders( + Http::TestResponseHeaderMapImpl{{":status", "100"}}); response->waitForContinueHeaders(); } // Send all of the request data and wait for it to be received upstream. @@ -853,7 +857,8 @@ void HttpIntegrationTest::testEnvoyProxying100Continue(bool continue_before_upst if (!continue_before_upstream_complete) { // This case tests forwarding 100-Continue after the client has sent all data. - upstream_request_->encode100ContinueHeaders(Http::TestHeaderMapImpl{{":status", "100"}}); + upstream_request_->encode100ContinueHeaders( + Http::TestResponseHeaderMapImpl{{":status", "100"}}); response->waitForContinueHeaders(); } // Now send the rest of the response. @@ -930,7 +935,7 @@ void HttpIntegrationTest::testLargeRequestHeaders(uint32_t size, uint32_t count, max_request_headers_kb_ = max_size; max_request_headers_count_ = max_count; - Http::TestHeaderMapImpl big_headers{ + Http::TestRequestHeaderMapImpl big_headers{ {":method", "GET"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}}; // Already added four headers. @@ -969,7 +974,7 @@ void HttpIntegrationTest::testLargeRequestTrailers(uint32_t size, uint32_t max_s [&](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm) -> void { hcm.mutable_max_request_headers_kb()->set_value(max_size); }); max_request_headers_kb_ = max_size; - Http::TestHeaderMapImpl request_trailers{{"trailer", "trailer"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"trailer", "trailer"}}; request_trailers.addCopy("big", std::string(size * 1024, 'a')); initialize(); @@ -1017,7 +1022,7 @@ void HttpIntegrationTest::testManyRequestHeaders(std::chrono::milliseconds time) max_request_headers_count_); }); - Http::TestHeaderMapImpl big_headers{ + Http::TestRequestHeaderMapImpl big_headers{ {":method", "GET"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}}; for (int i = 0; i < 20000; i++) { @@ -1039,12 +1044,12 @@ void HttpIntegrationTest::testDownstreamResetBeforeResponseComplete() { codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"cookie", "a=b"}, - {"cookie", "c=d"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"cookie", "a=b"}, + {"cookie", "c=d"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); codec_client_->sendData(*request_encoder_, 0, true); @@ -1078,16 +1083,18 @@ void HttpIntegrationTest::testDownstreamResetBeforeResponseComplete() { void HttpIntegrationTest::testTrailers(uint64_t request_size, uint64_t response_size, bool check_request, bool check_response) { - Http::TestHeaderMapImpl request_trailers{{"request1", "trailer1"}, {"request2", "trailer2"}}; - Http::TestHeaderMapImpl response_trailers{{"response1", "trailer1"}, {"response2", "trailer2"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"request1", "trailer1"}, + {"request2", "trailer2"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"response1", "trailer1"}, + {"response2", "trailer2"}}; initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); codec_client_->sendData(*request_encoder_, request_size, false); diff --git a/test/integration/http_integration.h b/test/integration/http_integration.h index 26f56b12a8..9edd6b1468 100644 --- a/test/integration/http_integration.h +++ b/test/integration/http_integration.h @@ -22,22 +22,22 @@ class IntegrationCodecClient : public Http::CodecClientProd { Upstream::HostDescriptionConstSharedPtr host_description, Http::CodecClient::Type type); - IntegrationStreamDecoderPtr makeHeaderOnlyRequest(const Http::HeaderMap& headers); - IntegrationStreamDecoderPtr makeRequestWithBody(const Http::HeaderMap& headers, + IntegrationStreamDecoderPtr makeHeaderOnlyRequest(const Http::RequestHeaderMap& headers); + IntegrationStreamDecoderPtr makeRequestWithBody(const Http::RequestHeaderMap& headers, uint64_t body_size); - IntegrationStreamDecoderPtr makeRequestWithBody(const Http::HeaderMap& headers, + IntegrationStreamDecoderPtr makeRequestWithBody(const Http::RequestHeaderMap& headers, const std::string& body); bool sawGoAway() const { return saw_goaway_; } bool connected() const { return connected_; } void sendData(Http::RequestEncoder& encoder, absl::string_view data, bool end_stream); void sendData(Http::RequestEncoder& encoder, Buffer::Instance& data, bool end_stream); void sendData(Http::RequestEncoder& encoder, uint64_t size, bool end_stream); - void sendTrailers(Http::RequestEncoder& encoder, const Http::HeaderMap& trailers); + void sendTrailers(Http::RequestEncoder& encoder, const Http::RequestTrailerMap& trailers); void sendReset(Http::RequestEncoder& encoder); // Intentionally makes a copy of metadata_map. void sendMetadata(Http::RequestEncoder& encoder, Http::MetadataMap metadata_map); std::pair - startRequest(const Http::HeaderMap& headers); + startRequest(const Http::RequestHeaderMap& headers); bool waitForDisconnect(std::chrono::milliseconds time_to_wait = std::chrono::milliseconds(0)); Network::ClientConnection* connection() const { return connection_.get(); } Network::ConnectionEvent last_connection_event() const { return last_connection_event_; } @@ -129,8 +129,8 @@ class HttpIntegrationTest : public BaseIntegrationTest { // Waits for the complete downstream response before returning. // Requires |codec_client_| to be initialized. IntegrationStreamDecoderPtr sendRequestAndWaitForResponse( - const Http::TestHeaderMapImpl& request_headers, uint32_t request_body_size, - const Http::TestHeaderMapImpl& response_headers, uint32_t response_body_size, + const Http::TestRequestHeaderMapImpl& request_headers, uint32_t request_body_size, + const Http::TestResponseHeaderMapImpl& response_headers, uint32_t response_body_size, int upstream_index = 0, std::chrono::milliseconds time = TestUtility::DefaultTimeout); // Wait for the end of stream on the next upstream stream on any of the provided fake upstreams. @@ -194,8 +194,9 @@ class HttpIntegrationTest : public BaseIntegrationTest { void testRouterUpstreamResponseBeforeRequestComplete(); void testTwoRequests(bool force_network_backup = false); - void testLargeHeaders(Http::TestHeaderMapImpl request_headers, - Http::TestHeaderMapImpl request_trailers, uint32_t size, uint32_t max_size); + void testLargeHeaders(Http::TestRequestHeaderMapImpl request_headers, + Http::TestRequestTrailerMapImpl request_trailers, uint32_t size, + uint32_t max_size); void testLargeRequestHeaders(uint32_t size, uint32_t count, uint32_t max_size = 60, uint32_t max_count = 100); void testLargeRequestTrailers(uint32_t size, uint32_t max_size = 60); @@ -233,8 +234,8 @@ class HttpIntegrationTest : public BaseIntegrationTest { // A pointer to the request encoder, if used. Http::RequestEncoder* request_encoder_{nullptr}; // The response headers sent by sendRequestAndWaitForResponse() by default. - Http::TestHeaderMapImpl default_response_headers_{{":status", "200"}}; - Http::TestHeaderMapImpl default_request_headers_{ + Http::TestResponseHeaderMapImpl default_response_headers_{{":status", "200"}}; + Http::TestRequestHeaderMapImpl default_request_headers_{ {":method", "GET"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}}; // The codec type for the client-to-Envoy connection Http::CodecClient::Type downstream_protocol_{Http::CodecClient::Type::HTTP1}; diff --git a/test/integration/http_subset_lb_integration_test.cc b/test/integration/http_subset_lb_integration_test.cc index 0245413177..58be89b76d 100644 --- a/test/integration/http_subset_lb_integration_test.cc +++ b/test/integration/http_subset_lb_integration_test.cc @@ -145,13 +145,13 @@ class HttpSubsetLbIntegrationTest // the given type ("a" or "b"). If is_hash_lb_, verifies that a single host is selected over n // iterations (e.g. for maglev/hash-ring policies). Otherwise, expected more than one host to be // selected over at least n iterations and at most m. - void runTest(Http::TestHeaderMapImpl& request_headers, const std::string expected_host_type, - const int n = 100, const int m = 1000) { + void runTest(Http::TestRequestHeaderMapImpl& request_headers, + const std::string expected_host_type, const int n = 100, const int m = 1000) { ASSERT_LT(n, m); std::set hosts; for (int i = 0; i < m; i++) { - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; // Send header only request. IntegrationStreamDecoderPtr response = codec_client_->makeHeaderOnlyRequest(request_headers); @@ -195,12 +195,12 @@ class HttpSubsetLbIntegrationTest const std::string type_header_{"x-type"}; const std::string type_key_{"type"}; - Http::TestHeaderMapImpl type_a_request_headers_{{":method", "GET"}, {":path", "/test"}, - {":scheme", "http"}, {":authority", "host"}, - {"x-type", "a"}, {"x-hash", "hash-a"}}; - Http::TestHeaderMapImpl type_b_request_headers_{{":method", "GET"}, {":path", "/test"}, - {":scheme", "http"}, {":authority", "host"}, - {"x-type", "b"}, {"x-hash", "hash-b"}}; + Http::TestRequestHeaderMapImpl type_a_request_headers_{ + {":method", "GET"}, {":path", "/test"}, {":scheme", "http"}, + {":authority", "host"}, {"x-type", "a"}, {"x-hash", "hash-a"}}; + Http::TestRequestHeaderMapImpl type_b_request_headers_{ + {":method", "GET"}, {":path", "/test"}, {":scheme", "http"}, + {":authority", "host"}, {"x-type", "b"}, {"x-hash", "hash-b"}}; }; INSTANTIATE_TEST_SUITE_P(SubsetCompatibleLoadBalancers, HttpSubsetLbIntegrationTest, diff --git a/test/integration/http_timeout_integration_test.cc b/test/integration/http_timeout_integration_test.cc index 6a9ae16ee2..c1217c05f0 100644 --- a/test/integration/http_timeout_integration_test.cc +++ b/test/integration/http_timeout_integration_test.cc @@ -15,12 +15,12 @@ TEST_P(HttpTimeoutIntegrationTest, GlobalTimeout) { codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); auto encoder_decoder = codec_client_->startRequest( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-upstream-rq-timeout-ms", "500"}}); + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-upstream-rq-timeout-ms", "500"}}); auto response = std::move(encoder_decoder.second); request_encoder_ = &encoder_decoder.first; @@ -55,13 +55,13 @@ TEST_P(HttpTimeoutIntegrationTest, UseTimeoutSetByEgressEnvoy) { initialize(); codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); auto encoder_decoder = codec_client_->startRequest( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-upstream-rq-timeout-ms", "500"}, - {"x-envoy-expected-rq-timeout-ms", "300"}}); + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-upstream-rq-timeout-ms", "500"}, + {"x-envoy-expected-rq-timeout-ms", "300"}}); auto response = std::move(encoder_decoder.second); request_encoder_ = &encoder_decoder.first; @@ -97,12 +97,12 @@ TEST_P(HttpTimeoutIntegrationTest, DeriveTimeoutInIngressEnvoy) { initialize(); codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); auto encoder_decoder = codec_client_->startRequest( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-upstream-rq-timeout-ms", "500"}}); + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-upstream-rq-timeout-ms", "500"}}); auto response = std::move(encoder_decoder.second); request_encoder_ = &encoder_decoder.first; @@ -138,13 +138,13 @@ TEST_P(HttpTimeoutIntegrationTest, IgnoreTimeoutSetByEgressEnvoy) { codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); auto encoder_decoder = codec_client_->startRequest( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-upstream-rq-timeout-ms", "500"}, - {"x-envoy-expected-rq-timeout-ms", "600"}}); + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-upstream-rq-timeout-ms", "500"}, + {"x-envoy-expected-rq-timeout-ms", "600"}}); auto response = std::move(encoder_decoder.second); request_encoder_ = &encoder_decoder.first; @@ -179,12 +179,12 @@ TEST_P(HttpTimeoutIntegrationTest, GlobalTimeoutAfterHeadersBeforeBodyResetsUpst initialize(); codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-upstream-rq-timeout-ms", "100"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-upstream-rq-timeout-ms", "100"}}; auto encoder_decoder = codec_client_->startRequest(request_headers); auto response = std::move(encoder_decoder.second); request_encoder_ = &encoder_decoder.first; @@ -198,7 +198,7 @@ TEST_P(HttpTimeoutIntegrationTest, GlobalTimeoutAfterHeadersBeforeBodyResetsUpst ASSERT_TRUE(upstream_request_->waitForEndStream(*dispatcher_)); // Respond with headers, not end of stream. - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; upstream_request_->encodeHeaders(response_headers, false); response->waitForHeaders(); @@ -225,14 +225,14 @@ TEST_P(HttpTimeoutIntegrationTest, PerTryTimeout) { codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); auto encoder_decoder = codec_client_->startRequest( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}, - {"x-envoy-upstream-rq-timeout-ms", "500"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "400"}}); + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}, + {"x-envoy-upstream-rq-timeout-ms", "500"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "400"}}); auto response = std::move(encoder_decoder.second); request_encoder_ = &encoder_decoder.first; @@ -274,15 +274,15 @@ TEST_P(HttpTimeoutIntegrationTest, HedgedPerTryTimeout) { codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); auto encoder_decoder = codec_client_->startRequest( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}, - {"x-envoy-hedge-on-per-try-timeout", "true"}, - {"x-envoy-upstream-rq-timeout-ms", "500"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "400"}}); + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}, + {"x-envoy-hedge-on-per-try-timeout", "true"}, + {"x-envoy-upstream-rq-timeout-ms", "500"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "400"}}); auto response = std::move(encoder_decoder.second); request_encoder_ = &encoder_decoder.first; @@ -306,7 +306,7 @@ TEST_P(HttpTimeoutIntegrationTest, HedgedPerTryTimeout) { ASSERT_TRUE(upstream_request2->waitForEndStream(*dispatcher_)); // Encode 200 response headers for the first (timed out) request. - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; upstream_request_->encodeHeaders(response_headers, true); response->waitForHeaders(); @@ -368,15 +368,15 @@ void HttpTimeoutIntegrationTest::testRouterRequestAndResponseWithHedgedPerTryTim initialize(); codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http"))); - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}, - {"x-envoy-hedge-on-per-try-timeout", "true"}, - {"x-envoy-upstream-rq-timeout-ms", "5000"}, - {"x-envoy-upstream-rq-per-try-timeout-ms", "400"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}, + {"x-envoy-hedge-on-per-try-timeout", "true"}, + {"x-envoy-upstream-rq-timeout-ms", "5000"}, + {"x-envoy-upstream-rq-per-try-timeout-ms", "400"}}; auto encoder_decoder = codec_client_->startRequest(request_headers); auto response = std::move(encoder_decoder.second); @@ -402,7 +402,7 @@ void HttpTimeoutIntegrationTest::testRouterRequestAndResponseWithHedgedPerTryTim ASSERT_TRUE(upstream_request2->waitForHeadersComplete()); ASSERT_TRUE(upstream_request2->waitForEndStream(*dispatcher_)); - Http::TestHeaderMapImpl response_headers{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response_headers{{":status", "200"}}; if (first_request_wins) { // Encode 200 response headers for the first (timed out) request. upstream_request_->encodeHeaders(response_headers, response_size == 0); diff --git a/test/integration/idle_timeout_integration_test.cc b/test/integration/idle_timeout_integration_test.cc index 7607048d5e..d4827b0d71 100644 --- a/test/integration/idle_timeout_integration_test.cc +++ b/test/integration/idle_timeout_integration_test.cc @@ -43,10 +43,10 @@ class IdleTimeoutIntegrationTest : public HttpProtocolIntegrationTest { fake_upstreams_[0]->set_allow_unexpected_disconnects(true); codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http")))); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", method}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", method}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); AssertionResult result = @@ -234,7 +234,7 @@ TEST_P(IdleTimeoutIntegrationTest, PerStreamIdleTimeoutAfterUpstreamHeaders) { enable_per_stream_idle_timeout_ = true; auto response = setupPerStreamIdleTimeoutTest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); waitForTimeout(*response, "downstream_rq_idle_timeout"); @@ -251,10 +251,10 @@ TEST_P(IdleTimeoutIntegrationTest, PerStreamIdleTimeoutAfterBidiData) { auto response = setupPerStreamIdleTimeoutTest(); sleep(); - upstream_request_->encode100ContinueHeaders(Http::TestHeaderMapImpl{{":status", "100"}}); + upstream_request_->encode100ContinueHeaders(Http::TestResponseHeaderMapImpl{{":status", "100"}}); sleep(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); sleep(); upstream_request_->encodeData(1, false); @@ -263,7 +263,8 @@ TEST_P(IdleTimeoutIntegrationTest, PerStreamIdleTimeoutAfterBidiData) { codec_client_->sendData(*request_encoder_, 1, false); sleep(); - Http::TestHeaderMapImpl request_trailers{{"request1", "trailer1"}, {"request2", "trailer2"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"request1", "trailer1"}, + {"request2", "trailer2"}}; codec_client_->sendTrailers(*request_encoder_, request_trailers); sleep(); @@ -358,7 +359,7 @@ TEST_P(IdleTimeoutIntegrationTest, RequestTimeoutIsDisarmedByPrematureEncodeHead enable_per_stream_idle_timeout_ = true; auto response = setupPerStreamIdleTimeoutTest("POST"); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); waitForTimeout(*response); @@ -371,7 +372,7 @@ TEST_P(IdleTimeoutIntegrationTest, RequestTimeoutIsNotDisarmedByEncode100Continu enable_request_timeout_ = true; auto response = setupPerStreamIdleTimeoutTest("POST"); - upstream_request_->encode100ContinueHeaders(Http::TestHeaderMapImpl{{":status", "100"}}); + upstream_request_->encode100ContinueHeaders(Http::TestResponseHeaderMapImpl{{":status", "100"}}); waitForTimeout(*response, "downstream_rq_timeout"); diff --git a/test/integration/integration_test.cc b/test/integration/integration_test.cc index a1085f92af..96605ed37e 100644 --- a/test/integration/integration_test.cc +++ b/test/integration/integration_test.cc @@ -101,10 +101,10 @@ TEST_P(IntegrationTest, AdminDrainDrainsListeners) { uint32_t http_port = lookupPort("http"); codec_client_ = makeHttpConnection(http_port); - Http::TestHeaderMapImpl request_headers{{":method", "HEAD"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "HEAD"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}; IntegrationStreamDecoderPtr response = codec_client_->makeHeaderOnlyRequest(request_headers); waitForNextUpstreamRequest(0); fake_upstreams_[0]->set_allow_unexpected_disconnects(true); @@ -185,10 +185,10 @@ TEST_P(IntegrationTest, ConnectionClose) { codec_client_ = makeHttpConnection(lookupPort("http")); auto response = - codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/healthcheck"}, - {":authority", "host"}, - {"connection", "close"}}); + codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/healthcheck"}, + {":authority", "host"}, + {"connection", "close"}}); response->waitForEndStream(); codec_client_->waitForDisconnect(); @@ -238,8 +238,8 @@ TEST_P(IntegrationTest, ResponseFramedByConnectionCloseWithReadLimits) { // Disable chunk encoding to trigger framing by connection close. // TODO: This request should be propagated to codecs via API, instead of using a pseudo-header. // See: https://github.com/envoyproxy/envoy/issues/9749 - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}, {":no-chunks", "1"}}, - false); + upstream_request_->encodeHeaders( + Http::TestResponseHeaderMapImpl{{":status", "200"}, {":no-chunks", "1"}}, false); upstream_request_->encodeData(512, true); ASSERT_TRUE(fake_upstream_connection_->close()); @@ -337,17 +337,17 @@ TEST_P(IntegrationTest, HittingGrpcFilterLimitBufferingHeaders) { codec_client_ = makeHttpConnection(lookupPort("http")); auto response = codec_client_->makeHeaderOnlyRequest( - Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"content-type", "application/grpc"}, - {"x-envoy-retry-grpc-on", "cancelled"}}); + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"content-type", "application/grpc"}, + {"x-envoy-retry-grpc-on", "cancelled"}}); waitForNextUpstreamRequest(); // Send the overly large response. Because the grpc_http1_bridge filter buffers and buffer // limits are exceeded, this will be translated into an unknown gRPC error. - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); fake_upstreams_[0]->set_allow_unexpected_disconnects(true); upstream_request_->encodeData(1024 * 65, false); ASSERT_TRUE(fake_upstream_connection_->waitForDisconnect()); @@ -701,7 +701,7 @@ TEST_P(IntegrationTest, NoHost) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "GET"}, {":path", "/test/long/url"}, {":scheme", "http"}}; auto response = codec_client_->makeHeaderOnlyRequest(request_headers); response->waitForEndStream(); @@ -793,7 +793,7 @@ TEST_P(IntegrationTest, UpstreamProtocolError) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto encoder_decoder = codec_client_->startRequest(Http::TestHeaderMapImpl{ + auto encoder_decoder = codec_client_->startRequest(Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/test/long/url"}, {":authority", "host"}}); auto response = std::move(encoder_decoder.second); @@ -886,10 +886,10 @@ TEST_P(IntegrationTest, TestBind) { codec_client_ = makeHttpConnection(lookupPort("http")); auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, + codec_client_->makeRequestWithBody(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, 1024); ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_)); ASSERT_NE(fake_upstream_connection_, nullptr); @@ -915,12 +915,12 @@ TEST_P(IntegrationTest, TestFailedBind) { // With no ability to successfully bind on an upstream connection Envoy should // send a 500. auto response = codec_client_->makeHeaderOnlyRequest( - Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-upstream-rq-timeout-ms", "1000"}}); + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-upstream-rq-timeout-ms", "1000"}}); response->waitForEndStream(); EXPECT_TRUE(response->complete()); EXPECT_THAT(response->headers(), HttpStatusIs("503")); @@ -939,15 +939,15 @@ TEST_P(IntegrationTest, ViaAppendHeaderOnly) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":authority", "host"}, - {"via", "foo"}, - {"connection", "close"}}); + auto response = codec_client_->makeHeaderOnlyRequest( + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":authority", "host"}, + {"via", "foo"}, + {"connection", "close"}}); waitForNextUpstreamRequest(); EXPECT_THAT(upstream_request_->headers(), HeaderValueOf(Headers::get().Via, "foo, bar")); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); codec_client_->waitForDisconnect(); EXPECT_TRUE(response->complete()); @@ -978,10 +978,10 @@ TEST_P(IntegrationTest, TestDelayedConnectionTeardownOnGracefulClose) { codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); @@ -1016,10 +1016,10 @@ TEST_P(IntegrationTest, TestDelayedConnectionTeardownConfig) { codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); @@ -1056,10 +1056,10 @@ TEST_P(IntegrationTest, TestDelayedConnectionTeardownTimeoutTrigger) { codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); @@ -1122,10 +1122,10 @@ TEST_P(IntegrationTest, ProcessObjectHealthy) { codec_client_ = makeHttpConnection(lookupPort("http")); auto response = - codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/healthcheck"}, - {":authority", "host"}, - {"connection", "close"}}); + codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/healthcheck"}, + {":authority", "host"}, + {"connection", "close"}}); response->waitForEndStream(); codec_client_->waitForDisconnect(); @@ -1143,10 +1143,10 @@ TEST_P(IntegrationTest, ProcessObjectUnealthy) { codec_client_ = makeHttpConnection(lookupPort("http")); auto response = - codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/healthcheck"}, - {":authority", "host"}, - {"connection", "close"}}); + codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/healthcheck"}, + {":authority", "host"}, + {"connection", "close"}}); response->waitForEndStream(); codec_client_->waitForDisconnect(); diff --git a/test/integration/load_stats_integration_test.cc b/test/integration/load_stats_integration_test.cc index 9369d9e6c3..a9cf875308 100644 --- a/test/integration/load_stats_integration_test.cc +++ b/test/integration/load_stats_integration_test.cc @@ -145,9 +145,9 @@ class LoadStatsIntegrationTest : public testing::TestWithParammakeRequestWithBody(headers, request_size_); } @@ -287,7 +287,7 @@ class LoadStatsIntegrationTest : public testing::TestWithParamencodeHeaders( - Http::TestHeaderMapImpl{{":status", std::to_string(response_code)}}, false); + Http::TestResponseHeaderMapImpl{{":status", std::to_string(response_code)}}, false); upstream_request_->encodeData(response_size_, true); response_->waitForEndStream(); diff --git a/test/integration/overload_integration_test.cc b/test/integration/overload_integration_test.cc index e046712d26..b8406f587c 100644 --- a/test/integration/overload_integration_test.cc +++ b/test/integration/overload_integration_test.cc @@ -68,7 +68,7 @@ TEST_P(OverloadIntegrationTest, CloseStreamsWhenOverloaded) { updateResource(0.9); test_server_->waitForGaugeEq("overload.envoy.overload_actions.stop_accepting_requests.active", 1); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "GET"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}}; codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http")))); auto response = codec_client_->makeRequestWithBody(request_headers, 10); @@ -115,7 +115,7 @@ TEST_P(OverloadIntegrationTest, DisableKeepaliveWhenOverloaded) { test_server_->waitForGaugeEq("overload.envoy.overload_actions.disable_http_keepalive.active", 1); codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http")))); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "GET"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}}; auto response = sendRequestAndWaitForResponse(request_headers, 1, default_response_headers_, 1); codec_client_->waitForDisconnect(); @@ -145,7 +145,7 @@ TEST_P(OverloadIntegrationTest, StopAcceptingConnectionsWhenOverloaded) { test_server_->waitForGaugeEq("overload.envoy.overload_actions.stop_accepting_connections.active", 1); codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http")))); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "GET"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}}; auto response = codec_client_->makeRequestWithBody(request_headers, 10); EXPECT_FALSE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_, diff --git a/test/integration/protocol_integration_test.cc b/test/integration/protocol_integration_test.cc index 6ac15e24d4..76d8363e83 100644 --- a/test/integration/protocol_integration_test.cc +++ b/test/integration/protocol_integration_test.cc @@ -55,7 +55,7 @@ void setDoNotValidateRouteConfig( // downstream"? class DownstreamProtocolIntegrationTest : public HttpProtocolIntegrationTest { protected: - void changeHeadersForStopAllTests(Http::TestHeaderMapImpl& headers, bool set_buffer_limit) { + template void changeHeadersForStopAllTests(T& headers, bool set_buffer_limit) { headers.addCopy("content_size", std::to_string(count_ * size_)); headers.addCopy("added_size", std::to_string(added_decoded_data_size_)); headers.addCopy("is_first_trigger", "value"); @@ -166,7 +166,7 @@ name: envoy.health_check initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{ + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/healthcheck"}, {":scheme", "http"}, {":authority", "host"}}); response->waitForEndStream(); @@ -187,7 +187,7 @@ name: envoy.health_check initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{ + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/healthcheck"}, {":scheme", "http"}, {":authority", "host"}}); response->waitForEndStream(); @@ -206,7 +206,7 @@ name: add-trailers-filter codec_client_ = makeHttpConnection(lookupPort("http")); auto response = codec_client_->makeRequestWithBody(default_request_headers_, 128); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); upstream_request_->encodeData(128, true); response->waitForEndStream(); @@ -244,11 +244,11 @@ TEST_P(ProtocolIntegrationTest, DrainClose) { TEST_P(ProtocolIntegrationTest, ResponseWithHostHeader) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + auto response = codec_client_->makeHeaderOnlyRequest( + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); waitForNextUpstreamRequest(); upstream_request_->encodeHeaders( Http::TestResponseHeaderMapImpl{{":status", "200"}, {"host", "host"}}, true); @@ -262,16 +262,16 @@ TEST_P(ProtocolIntegrationTest, ResponseWithHostHeader) { TEST_P(ProtocolIntegrationTest, Retry) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}}, - 1024); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}}, + 1024); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); if (fake_upstreams_[0]->httpType() == FakeHttpConnection::Type::HTTP1) { ASSERT_TRUE(fake_upstream_connection_->waitForDisconnect()); @@ -300,16 +300,16 @@ TEST_P(DownstreamProtocolIntegrationTest, RetryAttemptCountHeader) { config_helper_.addVirtualHost(host); initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test_retry"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}}, - 1024); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test_retry"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}}, + 1024); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); EXPECT_EQ( atoi(std::string(upstream_request_->headers().EnvoyAttemptCount()->value().getStringView()) @@ -376,18 +376,18 @@ TEST_P(DownstreamProtocolIntegrationTest, RetryPriority) { fake_upstreams_count_ = 2; initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test_retry"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}}, - 1024); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test_retry"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}}, + 1024); // Note how we're expecting each upstream request to hit the same upstream. waitForNextUpstreamRequest(0); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); if (fake_upstreams_[0]->httpType() == FakeHttpConnection::Type::HTTP1) { ASSERT_TRUE(fake_upstream_connection_->waitForDisconnect()); @@ -438,19 +438,19 @@ TEST_P(DownstreamProtocolIntegrationTest, RetryHostPredicateFilter) { fake_upstreams_count_ = 2; initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test_retry"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}}, - 1024); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test_retry"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}}, + 1024); // Note how we're expecting each upstream request to hit the same upstream. auto upstream_idx = waitForNextUpstreamRequest({0, 1}); ASSERT_TRUE(upstream_idx.has_value()); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); if (fake_upstreams_[*upstream_idx]->httpType() == FakeHttpConnection::Type::HTTP1) { ASSERT_TRUE(fake_upstream_connection_->waitForDisconnect()); @@ -480,17 +480,17 @@ TEST_P(ProtocolIntegrationTest, RetryHittingBufferLimit) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}}, - 1024 * 65); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}}, + 1024 * 65); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, true); response->waitForEndStream(); EXPECT_TRUE(upstream_request_->complete()); @@ -508,17 +508,17 @@ TEST_P(ProtocolIntegrationTest, RetryHittingRouteLimits) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/"}, - {":scheme", "http"}, - {":authority", "nobody.com"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}}, - 1); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/"}, + {":scheme", "http"}, + {":authority", "nobody.com"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}}, + 1); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, true); response->waitForEndStream(); EXPECT_TRUE(upstream_request_->complete()); @@ -541,14 +541,14 @@ TEST_P(DownstreamProtocolIntegrationTest, HittingDecoderFilterLimit) { // Envoy will likely connect and proxy some unspecified amount of data before // hitting the buffer limit and disconnecting. Ignore this if it happens. fake_upstreams_[0]->set_allow_unexpected_disconnects(true); - auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/dynamo/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-for", "10.0.0.1"}, - {"x-envoy-retry-on", "5xx"}}, - 1024 * 65); + auto response = codec_client_->makeRequestWithBody( + Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/dynamo/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-for", "10.0.0.1"}, + {"x-envoy-retry-on", "5xx"}}, + 1024 * 65); response->waitForEndStream(); // With HTTP/1 there's a possible race where if the connection backs up early, @@ -629,11 +629,11 @@ TEST_P(DownstreamProtocolIntegrationTest, ValidZeroLengthContent) { codec_client_ = makeHttpConnection(lookupPort("http")); - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"content-length", "0"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"content-length", "0"}}; auto response = sendRequestAndWaitForResponse(request_headers, 0, default_response_headers_, 0); ASSERT_TRUE(response->complete()); @@ -645,11 +645,11 @@ TEST_P(DownstreamProtocolIntegrationTest, LargeCookieParsingConcatenated) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"content-length", "0"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"content-length", "0"}}; std::vector cookie_pieces; cookie_pieces.reserve(7000); for (int i = 0; i < 7000; i++) { @@ -677,11 +677,11 @@ TEST_P(DownstreamProtocolIntegrationTest, LargeCookieParsingMany) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"content-length", "0"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"content-length", "0"}}; for (int i = 0; i < 2000; i++) { request_headers.addCopy("cookie", fmt::sprintf("a%x=b", i)); } @@ -697,10 +697,10 @@ TEST_P(DownstreamProtocolIntegrationTest, InvalidContentLength) { codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":authority", "host"}, - {"content-length", "-1"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":authority", "host"}, + {"content-length", "-1"}}); auto response = std::move(encoder_decoder.second); codec_client_->waitForDisconnect(); @@ -727,10 +727,10 @@ TEST_P(DownstreamProtocolIntegrationTest, InvalidContentLengthAllowed) { codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":authority", "host"}, - {"content-length", "-1"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":authority", "host"}, + {"content-length", "-1"}}); auto response = std::move(encoder_decoder.second); if (downstream_protocol_ == Http::CodecClient::Type::HTTP1) { @@ -753,10 +753,10 @@ TEST_P(DownstreamProtocolIntegrationTest, MultipleContentLengths) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":authority", "host"}, - {"content-length", "3,2"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":authority", "host"}, + {"content-length", "3,2"}}); auto response = std::move(encoder_decoder.second); codec_client_->waitForDisconnect(); @@ -781,10 +781,10 @@ TEST_P(DownstreamProtocolIntegrationTest, MultipleContentLengthsAllowed) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":authority", "host"}, - {"content-length", "3,2"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":authority", "host"}, + {"content-length", "3,2"}}); auto response = std::move(encoder_decoder.second); if (downstream_protocol_ == Http::CodecClient::Type::HTTP1) { @@ -811,13 +811,13 @@ name: encode-headers-only codec_client_ = makeHttpConnection(lookupPort("http")); auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, + codec_client_->makeRequestWithBody(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, 128); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); response->waitForEndStream(); EXPECT_TRUE(upstream_request_->waitForEndStream(*dispatcher_)); if (upstreamProtocol() == FakeHttpConnection::Type::HTTP1) { @@ -841,13 +841,13 @@ name: decode-headers-only codec_client_ = makeHttpConnection(lookupPort("http")); auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, + codec_client_->makeRequestWithBody(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, 128); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); upstream_request_->encodeData(128, true); response->waitForEndStream(); @@ -870,13 +870,13 @@ name: passthrough-filter codec_client_ = makeHttpConnection(lookupPort("http")); auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, + codec_client_->makeRequestWithBody(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, 128); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); response->waitForEndStream(); if (upstreamProtocol() == FakeHttpConnection::Type::HTTP1) { ASSERT_TRUE(fake_upstream_connection_->waitForDisconnect()); @@ -905,13 +905,13 @@ name: passthrough-filter codec_client_ = makeHttpConnection(lookupPort("http")); auto response = - codec_client_->makeRequestWithBody(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}, + codec_client_->makeRequestWithBody(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}, 128); waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); upstream_request_->encodeData(128, true); response->waitForEndStream(); @@ -933,16 +933,16 @@ name: decode-headers-only // First send the request headers. The filter should turn this into a header-only // request. auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); // Wait for the upstream request and begin sending a response with end_stream = false. waitForNextUpstreamRequest(); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, false); // Simulate additional data after the request has been turned into a headers only request. Buffer::OwnedImpl data(std::string(128, 'a')); @@ -981,7 +981,7 @@ TEST_P(DownstreamProtocolIntegrationTest, ManyRequestTrailersRejected) { // Default header (and trailer) count limit is 100. config_helper_.addConfigModifier(setEnableDownstreamTrailersHttp1()); config_helper_.addConfigModifier(setEnableUpstreamTrailersHttp1()); - Http::TestHeaderMapImpl request_trailers; + Http::TestRequestTrailerMapImpl request_trailers; for (int i = 0; i < 150; i++) { request_trailers.addCopy("trailer", std::string(1, 'a')); } @@ -1016,7 +1016,7 @@ TEST_P(DownstreamProtocolIntegrationTest, ManyRequestTrailersAccepted) { }); config_helper_.addConfigModifier(setEnableUpstreamTrailersHttp1()); max_request_headers_count_ = max_count; - Http::TestHeaderMapImpl request_trailers; + Http::TestRequestTrailerMapImpl request_trailers; for (int i = 0; i < 150; i++) { request_trailers.addCopy("trailer", std::string(1, 'a')); } @@ -1067,7 +1067,7 @@ TEST_P(DownstreamProtocolIntegrationTest, ManyTrailerHeaders) { max_request_headers_count_); }); - Http::HeaderMapImpl request_trailers{}; + Http::RequestTrailerMapImpl request_trailers; for (int i = 0; i < 20000; i++) { request_trailers.addCopy(Http::LowerCaseString(std::to_string(i)), ""); } @@ -1075,10 +1075,10 @@ TEST_P(DownstreamProtocolIntegrationTest, ManyTrailerHeaders) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = - codec_client_->startRequest(Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}); + codec_client_->startRequest(Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}); request_encoder_ = &encoder_decoder.first; auto response = std::move(encoder_decoder.second); codec_client_->sendTrailers(*request_encoder_, request_trailers); @@ -1107,10 +1107,10 @@ TEST_P(DownstreamProtocolIntegrationTest, ManyTrailerHeaders) { // H2 H2 Success TEST_P(ProtocolIntegrationTest, LargeRequestMethod) { const std::string long_method = std::string(48 * 1024, 'a'); - const Http::TestHeaderMapImpl request_headers{{":method", long_method}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}; + const Http::TestRequestHeaderMapImpl request_headers{{":method", long_method}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}; initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); @@ -1182,7 +1182,7 @@ name: passthrough-filter for (int i = 0; i < count_; i++) { codec_client_->sendData(*request_encoder_, size_, false); } - Http::TestHeaderMapImpl request_trailers{{"trailer", "trailer"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"trailer", "trailer"}}; codec_client_->sendTrailers(*request_encoder_, request_trailers); waitForNextUpstreamRequest(); @@ -1241,7 +1241,7 @@ name: passthrough-filter // Gives buffer 1s to react to buffer limit. absl::SleepFor(absl::Seconds(1)); codec_client_->sendData(*request_encoder_, size_, false); - Http::TestHeaderMapImpl request_trailers{{"trailer", "trailer"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"trailer", "trailer"}}; codec_client_->sendTrailers(*request_encoder_, request_trailers); waitForNextUpstreamRequest(); @@ -1289,7 +1289,7 @@ name: passthrough-filter for (int i = 0; i < count_; i++) { codec_client_->sendData(*request_encoder_, size_, false); } - Http::TestHeaderMapImpl request_trailers{{"trailer", "trailer"}}; + Http::TestRequestTrailerMapImpl request_trailers{{"trailer", "trailer"}}; codec_client_->sendTrailers(*request_encoder_, request_trailers); waitForNextUpstreamRequest(); @@ -1322,7 +1322,7 @@ name: encode-headers-return-stop-all-filter // Sleeps for 1s in order to be consistent with testEncodeHeadersReturnsStopAllWatermark. absl::SleepFor(absl::Seconds(1)); upstream_request_->encodeData(size_, false); - Http::TestHeaderMapImpl response_trailers{{"response", "trailer"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"response", "trailer"}}; upstream_request_->encodeTrailers(response_trailers); response->waitForEndStream(); @@ -1362,7 +1362,7 @@ name: encode-headers-return-stop-all-filter // Gives buffer 1s to react to buffer limit. absl::SleepFor(absl::Seconds(1)); upstream_request_->encodeData(size_, false); - Http::TestHeaderMapImpl response_trailers{{"response", "trailer"}}; + Http::TestResponseTrailerMapImpl response_trailers{{"response", "trailer"}}; upstream_request_->encodeTrailers(response_trailers); response->waitForEndStream(); @@ -1377,7 +1377,7 @@ TEST_P(ProtocolIntegrationTest, MultipleSetCookies) { codec_client_ = makeHttpConnection(lookupPort("http")); - Http::TestHeaderMapImpl response_headers{ + Http::TestResponseHeaderMapImpl response_headers{ {":status", "200"}, {"set-cookie", "foo"}, {"set-cookie", "bar"}}; auto response = sendRequestAndWaitForResponse(default_request_headers_, 0, response_headers, 0); @@ -1497,10 +1497,10 @@ TEST_P(DownstreamProtocolIntegrationTest, InvalidAuthority) { codec_client_ = makeHttpConnection(lookupPort("http")); - Http::TestHeaderMapImpl request_headers{{":method", "POST"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "ho|st|"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "ho|st|"}}; auto response = codec_client_->makeHeaderOnlyRequest(request_headers); if (downstreamProtocol() == Http::CodecClient::Type::HTTP1) { @@ -1519,8 +1519,8 @@ TEST_P(DownstreamProtocolIntegrationTest, InvalidAuthority) { TEST_P(DownstreamProtocolIntegrationTest, ConnectIsBlocked) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest( - Http::TestHeaderMapImpl{{":method", "CONNECT"}, {":path", "/"}, {":authority", "host"}}); + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ + {":method", "CONNECT"}, {":path", "/"}, {":authority", "host"}}); if (downstreamProtocol() == Http::CodecClient::Type::HTTP1) { response->waitForEndStream(); @@ -1546,8 +1546,8 @@ TEST_P(DownstreamProtocolIntegrationTest, ConnectStreamRejection) { initialize(); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = codec_client_->makeHeaderOnlyRequest( - Http::TestHeaderMapImpl{{":method", "CONNECT"}, {":path", "/"}, {":authority", "host"}}); + auto response = codec_client_->makeHeaderOnlyRequest(Http::TestRequestHeaderMapImpl{ + {":method", "CONNECT"}, {":path", "/"}, {":authority", "host"}}); response->waitForReset(); EXPECT_FALSE(codec_client_->disconnected()); diff --git a/test/integration/ratelimit_integration_test.cc b/test/integration/ratelimit_integration_test.cc index 8d6fa322cd..81346613d4 100644 --- a/test/integration/ratelimit_integration_test.cc +++ b/test/integration/ratelimit_integration_test.cc @@ -68,9 +68,9 @@ class RatelimitIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, void initiateClientConnection() { auto conn = makeClientConnection(lookupPort("http")); codec_client_ = makeHttpConnection(std::move(conn)); - Http::TestHeaderMapImpl headers{{":method", "POST"}, {":path", "/test/long/url"}, - {":scheme", "http"}, {":authority", "host"}, - {"x-lyft-user-id", "123"}, {"x-forwarded-for", "10.0.0.1"}}; + Http::TestRequestHeaderMapImpl headers{ + {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, + {":authority", "host"}, {"x-lyft-user-id", "123"}, {"x-forwarded-for", "10.0.0.1"}}; response_ = codec_client_->makeRequestWithBody(headers, request_size_); } @@ -108,7 +108,7 @@ class RatelimitIntegrationTest : public Grpc::GrpcClientIntegrationParamTest, result = upstream_request_->waitForEndStream(*dispatcher_); RELEASE_ASSERT(result, result.message()); - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); upstream_request_->encodeData(response_size_, true); response_->waitForEndStream(); @@ -216,7 +216,7 @@ TEST_P(RatelimitIntegrationTest, OkWithHeaders) { waitForRatelimitRequest(); Http::TestHeaderMapImpl ratelimit_response_headers{{"x-ratelimit-limit", "1000"}, {"x-ratelimit-remaining", "500"}}; - Http::TestHeaderMapImpl request_headers_to_add{{"x-ratelimit-done", "true"}}; + Http::TestRequestHeaderMapImpl request_headers_to_add{{"x-ratelimit-done", "true"}}; sendRateLimitResponse(envoy::service::ratelimit::v3::RateLimitResponse::OK, ratelimit_response_headers, request_headers_to_add); @@ -288,7 +288,7 @@ TEST_P(RatelimitIntegrationTest, OverLimitWithHeaders) { TEST_P(RatelimitIntegrationTest, Error) { initiateClientConnection(); waitForRatelimitRequest(); - ratelimit_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "404"}}, true); + ratelimit_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "404"}}, true); // Rate limiter fails open waitForSuccessfulUpstreamResponse(); cleanup(); @@ -348,7 +348,7 @@ TEST_P(RatelimitIntegrationTest, FailedConnect) { TEST_P(RatelimitFailureModeIntegrationTest, ErrorWithFailureModeOff) { initiateClientConnection(); waitForRatelimitRequest(); - ratelimit_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "503"}}, true); + ratelimit_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "503"}}, true); // Rate limiter fail closed waitForFailedUpstreamResponse(500); cleanup(); diff --git a/test/integration/scoped_rds_integration_test.cc b/test/integration/scoped_rds_integration_test.cc index 1d8adc6d95..8955cc0fb6 100644 --- a/test/integration/scoped_rds_integration_test.cc +++ b/test/integration/scoped_rds_integration_test.cc @@ -272,11 +272,11 @@ route_configuration_name: {} // No scope key matches "xyz-route". codec_client_ = makeHttpConnection(lookupPort("http")); auto response = codec_client_->makeHeaderOnlyRequest( - Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/meh"}, - {":authority", "host"}, - {":scheme", "http"}, - {"Addr", "x-foo-key=xyz-route"}}); + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/meh"}, + {":authority", "host"}, + {":scheme", "http"}, + {"Addr", "x-foo-key=xyz-route"}}); response->waitForEndStream(); verifyResponse(std::move(response), "404", Http::TestHeaderMapImpl{}, ""); cleanupUpstreamAndDownstream(); @@ -285,12 +285,12 @@ route_configuration_name: {} test_server_->waitForCounterGe("http.config_test.rds.foo_route1.update_success", 1); for (const std::string& scope_key : std::vector{"foo-route", "bar-route"}) { sendRequestAndVerifyResponse( - Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/meh"}, - {":authority", "host"}, - {":scheme", "http"}, - {"Addr", fmt::format("x-foo-key={}", scope_key)}}, - 456, Http::TestHeaderMapImpl{{":status", "200"}, {"service", scope_key}}, 123, + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/meh"}, + {":authority", "host"}, + {":scheme", "http"}, + {"Addr", fmt::format("x-foo-key={}", scope_key)}}, + 456, Http::TestResponseHeaderMapImpl{{":status", "200"}, {"service", scope_key}}, 123, /*cluster_0*/ 0); } test_server_->waitForCounterGe("http.config_test.scoped_rds.foo-scoped-routes.update_attempt", @@ -320,22 +320,22 @@ route_configuration_name: {} // 'cluster_1'. for (const std::string& scope_key : std::vector{"foo-route", "bar-route"}) { sendRequestAndVerifyResponse( - Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/meh"}, - {":authority", "host"}, - {":scheme", "http"}, - {"Addr", fmt::format("x-foo-key={}", scope_key)}}, - 456, Http::TestHeaderMapImpl{{":status", "200"}, {"service", scope_key}}, 123, + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/meh"}, + {":authority", "host"}, + {":scheme", "http"}, + {"Addr", fmt::format("x-foo-key={}", scope_key)}}, + 456, Http::TestResponseHeaderMapImpl{{":status", "200"}, {"service", scope_key}}, 123, /*cluster_1*/ 1); } // Now requests within scope 'foo_scope3' get routed to 'cluster_0'. sendRequestAndVerifyResponse( - Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/meh"}, - {":authority", "host"}, - {":scheme", "http"}, - {"Addr", fmt::format("x-foo-key={}", "baz-route")}}, - 456, Http::TestHeaderMapImpl{{":status", "200"}, {"service", "bluh"}}, 123, + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/meh"}, + {":authority", "host"}, + {":scheme", "http"}, + {"Addr", fmt::format("x-foo-key={}", "baz-route")}}, + 456, Http::TestResponseHeaderMapImpl{{":status", "200"}, {"service", "bluh"}}, 123, /*cluster_0*/ 0); // Delete foo_scope1 and requests within the scope gets 400s. @@ -343,11 +343,11 @@ route_configuration_name: {} test_server_->waitForCounterGe("http.config_test.scoped_rds.foo-scoped-routes.update_success", 3); codec_client_ = makeHttpConnection(lookupPort("http")); response = codec_client_->makeHeaderOnlyRequest( - Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/meh"}, - {":authority", "host"}, - {":scheme", "http"}, - {"Addr", "x-foo-key=foo-route"}}); + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/meh"}, + {":authority", "host"}, + {":scheme", "http"}, + {"Addr", "x-foo-key=foo-route"}}); response->waitForEndStream(); verifyResponse(std::move(response), "404", Http::TestHeaderMapImpl{}, ""); cleanupUpstreamAndDownstream(); @@ -358,11 +358,11 @@ route_configuration_name: {} test_server_->waitForCounterGe("http.config_test.scoped_rds.foo-scoped-routes.update_success", 4); codec_client_ = makeHttpConnection(lookupPort("http")); response = codec_client_->makeHeaderOnlyRequest( - Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/meh"}, - {":authority", "host"}, - {":scheme", "http"}, - {"Addr", "x-foo-key=xyz-route"}}); + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/meh"}, + {":authority", "host"}, + {":scheme", "http"}, + {"Addr", "x-foo-key=xyz-route"}}); response->waitForEndStream(); // Get 404 because RDS hasn't pushed route configuration "foo_route4" yet. // But scope is found and the Router::NullConfigImpl is returned. @@ -375,12 +375,12 @@ route_configuration_name: {} sendRdsResponse(fmt::format(route_config_tmpl, "foo_route4", "cluster_1"), "3"); test_server_->waitForCounterGe("http.config_test.rds.foo_route4.update_success", 1); sendRequestAndVerifyResponse( - Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/meh"}, - {":authority", "host"}, - {":scheme", "http"}, - {"Addr", "x-foo-key=xyz-route"}}, - 456, Http::TestHeaderMapImpl{{":status", "200"}, {"service", "xyz-route"}}, 123, + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/meh"}, + {":authority", "host"}, + {":scheme", "http"}, + {"Addr", "x-foo-key=xyz-route"}}, + 456, Http::TestResponseHeaderMapImpl{{":status", "200"}, {"service", "xyz-route"}}, 123, /*cluster_1 */ 1); } @@ -403,12 +403,12 @@ route_configuration_name: foo_route1 test_server_->waitForCounterGe("http.config_test.scoped_rds.foo-scoped-routes.update_rejected", 1); codec_client_ = makeHttpConnection(lookupPort("http")); - auto response = - codec_client_->makeHeaderOnlyRequest(Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/meh"}, - {":authority", "host"}, - {":scheme", "http"}, - {"Addr", "x-foo-key=foo"}}); + auto response = codec_client_->makeHeaderOnlyRequest( + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/meh"}, + {":authority", "host"}, + {":scheme", "http"}, + {"Addr", "x-foo-key=foo"}}); response->waitForEndStream(); verifyResponse(std::move(response), "404", Http::TestHeaderMapImpl{}, ""); cleanupUpstreamAndDownstream(); @@ -436,12 +436,13 @@ route_configuration_name: foo_route1 sendRdsResponse(fmt::format(route_config_tmpl, "foo_route1", "cluster_0"), "1"); test_server_->waitForCounterGe("http.config_test.rds.foo_route1.update_success", 1); sendRequestAndVerifyResponse( - Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/meh"}, - {":authority", "host"}, - {":scheme", "http"}, - {"Addr", "x-foo-key=foo"}}, - 456, Http::TestHeaderMapImpl{{":status", "200"}, {"service", "bluh"}}, 123, /*cluster_0*/ 0); + Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/meh"}, + {":authority", "host"}, + {":scheme", "http"}, + {"Addr", "x-foo-key=foo"}}, + 456, Http::TestResponseHeaderMapImpl{{":status", "200"}, {"service", "bluh"}}, 123, + /*cluster_0*/ 0); } } // namespace diff --git a/test/integration/sds_generic_secret_integration_test.cc b/test/integration/sds_generic_secret_integration_test.cc index 4342e3b288..8558325a7b 100644 --- a/test/integration/sds_generic_secret_integration_test.cc +++ b/test/integration/sds_generic_secret_integration_test.cc @@ -29,7 +29,7 @@ class SdsGenericSecretTestFilter : public Http::StreamDecoderFilter { void onDestroy() override{}; // Http::StreamDecoderFilter - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool) override { + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, bool) override { headers.addCopy(Http::LowerCaseString("secret"), Config::DataSource::read(config_provider_->secret()->secret(), true, api_)); return Http::FilterHeadersStatus::Continue; @@ -39,7 +39,7 @@ class SdsGenericSecretTestFilter : public Http::StreamDecoderFilter { return Http::FilterDataStatus::Continue; } - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap&) override { + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override { return Http::FilterTrailersStatus::Continue; } @@ -146,7 +146,7 @@ TEST_P(SdsGenericSecretIntegrationTest, FilterFetchSuccess) { initialize(); codec_client_ = makeHttpConnection((lookupPort("http"))); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}; sendRequestAndWaitForResponse(request_headers, 0, default_response_headers_, 0); diff --git a/test/integration/transport_socket_match_integration_test.cc b/test/integration/transport_socket_match_integration_test.cc index 4b612d5184..96358e6ff4 100644 --- a/test/integration/transport_socket_match_integration_test.cc +++ b/test/integration/transport_socket_match_integration_test.cc @@ -164,16 +164,16 @@ require_client_certificate: true } const uint32_t num_hosts_; - Http::TestHeaderMapImpl type_a_request_headers_{{":method", "GET"}, - {":path", "/test"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-type", "a"}}; - Http::TestHeaderMapImpl type_b_request_headers_{{":method", "GET"}, - {":path", "/test"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-type", "b"}}; + Http::TestRequestHeaderMapImpl type_a_request_headers_{{":method", "GET"}, + {":path", "/test"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-type", "a"}}; + Http::TestRequestHeaderMapImpl type_b_request_headers_{{":method", "GET"}, + {":path", "/test"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-type", "b"}}; const std::string host_type_header_{"x-host-type"}; const std::string host_header_{"x-host"}; const std::string type_header_{"x-type"}; diff --git a/test/integration/uds_integration_test.cc b/test/integration/uds_integration_test.cc index 3a191607ec..ddb9abc68a 100644 --- a/test/integration/uds_integration_test.cc +++ b/test/integration/uds_integration_test.cc @@ -89,7 +89,7 @@ TEST_P(UdsListenerIntegrationTest, TestPeerCredentials) { initialize(); auto client_connection = createConnectionFn()(); codec_client_ = makeHttpConnection(std::move(client_connection)); - Http::TestHeaderMapImpl request_headers{ + Http::TestRequestHeaderMapImpl request_headers{ {":method", "POST"}, {":path", "/test/long/url"}, {":scheme", "http"}, {":authority", "host"}, {"x-lyft-user-id", "123"}, {"x-forwarded-for", "10.0.0.1"}}; auto response = codec_client_->makeHeaderOnlyRequest(request_headers); @@ -104,7 +104,7 @@ TEST_P(UdsListenerIntegrationTest, TestPeerCredentials) { EXPECT_EQ(credentials->gid, getgid()); #endif - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); } diff --git a/test/integration/utility.cc b/test/integration/utility.cc index 19f830aca3..48c70d0886 100644 --- a/test/integration/utility.cc +++ b/test/integration/utility.cc @@ -84,7 +84,7 @@ IntegrationUtil::makeSingleRequest(const Network::Address::InstanceConstSharedPt Http::RequestEncoder& encoder = client.newStream(*response); encoder.getStream().addCallbacks(*response); - Http::HeaderMapImpl headers; + Http::RequestHeaderMapImpl headers; headers.setMethod(method); headers.setPath(url); headers.setHost(host); diff --git a/test/integration/vhds_integration_test.cc b/test/integration/vhds_integration_test.cc index b6d529fd1a..a5ce255263 100644 --- a/test/integration/vhds_integration_test.cc +++ b/test/integration/vhds_integration_test.cc @@ -439,11 +439,11 @@ TEST_P(VhdsIntegrationTest, VhdsVirtualHostAddUpdateRemove) { // an upstream request to an (now) unknown domain codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http")))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/"}, - {":scheme", "http"}, - {":authority", "vhost.first"}, - {"x-lyft-user-id", "123"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/"}, + {":scheme", "http"}, + {":authority", "vhost.first"}, + {"x-lyft-user-id", "123"}}; IntegrationStreamDecoderPtr response = codec_client_->makeHeaderOnlyRequest(request_headers); EXPECT_TRUE(compareDeltaDiscoveryRequest(Config::TypeUrl::get().VirtualHost, {vhdsRequestResourceName("vhost.first")}, {}, @@ -506,11 +506,11 @@ TEST_P(VhdsIntegrationTest, RdsWithVirtualHostsVhdsVirtualHostAddUpdateRemove) { codec_client_->waitForDisconnect(); codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http")))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/"}, - {":scheme", "http"}, - {":authority", "vhost.first"}, - {"x-lyft-user-id", "123"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/"}, + {":scheme", "http"}, + {":authority", "vhost.first"}, + {"x-lyft-user-id", "123"}}; IntegrationStreamDecoderPtr response = codec_client_->makeHeaderOnlyRequest(request_headers); EXPECT_TRUE(compareDeltaDiscoveryRequest(Config::TypeUrl::get().VirtualHost, {vhdsRequestResourceName("vhost.first")}, {}, @@ -547,11 +547,11 @@ TEST_P(VhdsIntegrationTest, VhdsOnDemandUpdateWithResourceNameAsAlias) { // Attempt to make a request to an unknown host codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http")))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/"}, - {":scheme", "http"}, - {":authority", "vhost_1"}, - {"x-lyft-user-id", "123"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/"}, + {":scheme", "http"}, + {":authority", "vhost_1"}, + {"x-lyft-user-id", "123"}}; IntegrationStreamDecoderPtr response = codec_client_->makeHeaderOnlyRequest(request_headers); EXPECT_TRUE(compareDeltaDiscoveryRequest(Config::TypeUrl::get().VirtualHost, {vhdsRequestResourceName("vhost_1")}, {}, vhds_stream_)); @@ -593,11 +593,11 @@ TEST_P(VhdsIntegrationTest, VhdsOnDemandUpdateFailToResolveTheAlias) { // Attempt to make a request to an unknown host codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http")))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/"}, - {":scheme", "http"}, - {":authority", "vhost.third"}, - {"x-lyft-user-id", "123"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/"}, + {":scheme", "http"}, + {":authority", "vhost.third"}, + {"x-lyft-user-id", "123"}}; IntegrationStreamDecoderPtr response = codec_client_->makeHeaderOnlyRequest(request_headers); EXPECT_TRUE(compareDeltaDiscoveryRequest(Config::TypeUrl::get().VirtualHost, {vhdsRequestResourceName("vhost.third")}, {}, @@ -634,11 +634,11 @@ TEST_P(VhdsIntegrationTest, VhdsOnDemandUpdateFailToResolveOneAliasOutOfSeveral) // Attempt to make a request to an unknown host codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http")))); - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/"}, - {":scheme", "http"}, - {":authority", "vhost.third"}, - {"x-lyft-user-id", "123"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/"}, + {":scheme", "http"}, + {":authority", "vhost.third"}, + {"x-lyft-user-id", "123"}}; IntegrationStreamDecoderPtr response = codec_client_->makeHeaderOnlyRequest(request_headers); EXPECT_TRUE(compareDeltaDiscoveryRequest(Config::TypeUrl::get().VirtualHost, {vhdsRequestResourceName("vhost.third")}, {}, diff --git a/test/integration/websocket_integration_test.cc b/test/integration/websocket_integration_test.cc index 6bc6ac28d6..0fba666750 100644 --- a/test/integration/websocket_integration_test.cc +++ b/test/integration/websocket_integration_test.cc @@ -19,8 +19,8 @@ namespace Envoy { namespace { -Http::TestHeaderMapImpl upgradeRequestHeaders(const char* upgrade_type = "websocket", - uint32_t content_length = 0) { +Http::TestRequestHeaderMapImpl upgradeRequestHeaders(const char* upgrade_type = "websocket", + uint32_t content_length = 0) { return Http::TestHeaderMapImpl{{":authority", "host"}, {"content-length", fmt::format("{}", content_length)}, {":path", "/websocket/test"}, @@ -30,11 +30,11 @@ Http::TestHeaderMapImpl upgradeRequestHeaders(const char* upgrade_type = "websoc {"connection", "keep-alive, upgrade"}}; } -Http::TestHeaderMapImpl upgradeResponseHeaders(const char* upgrade_type = "websocket") { - return Http::TestHeaderMapImpl{{":status", "101"}, - {"connection", "upgrade"}, - {"upgrade", upgrade_type}, - {"content-length", "0"}}; +Http::TestResponseHeaderMapImpl upgradeResponseHeaders(const char* upgrade_type = "websocket") { + return Http::TestResponseHeaderMapImpl{{":status", "101"}, + {"connection", "upgrade"}, + {"upgrade", upgrade_type}, + {"content-length", "0"}}; } } // namespace @@ -131,8 +131,8 @@ void WebsocketIntegrationTest::initialize() { } void WebsocketIntegrationTest::performUpgrade( - const Http::TestHeaderMapImpl& upgrade_request_headers, - const Http::TestHeaderMapImpl& upgrade_response_headers) { + const Http::TestRequestHeaderMapImpl& upgrade_request_headers, + const Http::TestResponseHeaderMapImpl& upgrade_response_headers) { // Establish the initial connection. codec_client_ = makeHttpConnection(lookupPort("http")); @@ -371,11 +371,11 @@ TEST_P(WebsocketIntegrationTest, WebsocketCustomFilterChain) { // HTTP requests are configured to disallow large bodies. { - Http::TestHeaderMapImpl request_headers{{":method", "GET"}, - {":path", "/"}, - {"content-length", "2048"}, - {":authority", "host"}, - {":scheme", "https"}}; + Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, + {":path", "/"}, + {"content-length", "2048"}, + {":authority", "host"}, + {":scheme", "https"}}; codec_client_ = makeHttpConnection(lookupPort("http")); auto encoder_decoder = codec_client_->startRequest(request_headers); response_ = std::move(encoder_decoder.second); diff --git a/test/integration/websocket_integration_test.h b/test/integration/websocket_integration_test.h index 69f88ccb1f..ba7b227aa0 100644 --- a/test/integration/websocket_integration_test.h +++ b/test/integration/websocket_integration_test.h @@ -17,8 +17,8 @@ class WebsocketIntegrationTest : public HttpProtocolIntegrationTest { void initialize() override; protected: - void performUpgrade(const Http::TestHeaderMapImpl& upgrade_request_headers, - const Http::TestHeaderMapImpl& upgrade_response_headers); + void performUpgrade(const Http::TestRequestHeaderMapImpl& upgrade_request_headers, + const Http::TestResponseHeaderMapImpl& upgrade_response_headers); void sendBidirectionalData(); void validateUpgradeRequestHeaders(const Http::HeaderMap& proxied_request_headers, diff --git a/test/integration/xfcc_integration_test.cc b/test/integration/xfcc_integration_test.cc index 1585e3bb97..e1cf0a4e08 100644 --- a/test/integration/xfcc_integration_test.cc +++ b/test/integration/xfcc_integration_test.cc @@ -156,18 +156,18 @@ void XfccIntegrationTest::initialize() { void XfccIntegrationTest::testRequestAndResponseWithXfccHeader(std::string previous_xfcc, std::string expected_xfcc) { Network::ClientConnectionPtr conn = tls_ ? makeMtlsClientConnection() : makeTcpClientConnection(); - Http::TestHeaderMapImpl header_map; + Http::TestRequestHeaderMapImpl header_map; if (previous_xfcc.empty()) { - header_map = Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}}; + header_map = Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}}; } else { - header_map = Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/test/long/url"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-forwarded-client-cert", previous_xfcc.c_str()}}; + header_map = Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/test/long/url"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-forwarded-client-cert", previous_xfcc.c_str()}}; } codec_client_ = makeHttpConnection(std::move(conn)); @@ -181,7 +181,7 @@ void XfccIntegrationTest::testRequestAndResponseWithXfccHeader(std::string previ EXPECT_EQ(expected_xfcc, upstream_request_->headers().ForwardedClientCert()->value().getStringView()); } - upstream_request_->encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, true); + upstream_request_->encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, true); response->waitForEndStream(); EXPECT_TRUE(upstream_request_->complete()); EXPECT_TRUE(response->complete()); diff --git a/test/mocks/grpc/mocks.h b/test/mocks/grpc/mocks.h index 795c0971ad..a2ec37ea59 100644 --- a/test/mocks/grpc/mocks.h +++ b/test/mocks/grpc/mocks.h @@ -45,7 +45,7 @@ class MockAsyncRequestCallbacks : public AsyncRequestCallbacks { onSuccess_(*response, span); } - MOCK_METHOD(void, onCreateInitialMetadata, (Http::HeaderMap & metadata)); + MOCK_METHOD(void, onCreateInitialMetadata, (Http::RequestHeaderMap & metadata)); MOCK_METHOD(void, onSuccess_, (const ResponseType& response, Tracing::Span& span)); MOCK_METHOD(void, onFailure, (Status::GrpcStatus status, const std::string& message, Tracing::Span& span)); @@ -54,20 +54,20 @@ class MockAsyncRequestCallbacks : public AsyncRequestCallbacks { template class MockAsyncStreamCallbacks : public AsyncStreamCallbacks { public: - void onReceiveInitialMetadata(Http::HeaderMapPtr&& metadata) { + void onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&& metadata) { onReceiveInitialMetadata_(*metadata); } void onReceiveMessage(std::unique_ptr&& message) { onReceiveMessage_(*message); } - void onReceiveTrailingMetadata(Http::HeaderMapPtr&& metadata) { + void onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&& metadata) { onReceiveTrailingMetadata_(*metadata); } - MOCK_METHOD(void, onCreateInitialMetadata, (Http::HeaderMap & metadata)); - MOCK_METHOD(void, onReceiveInitialMetadata_, (const Http::HeaderMap& metadata)); + MOCK_METHOD(void, onCreateInitialMetadata, (Http::RequestHeaderMap & metadata)); + MOCK_METHOD(void, onReceiveInitialMetadata_, (const Http::ResponseHeaderMap& metadata)); MOCK_METHOD(void, onReceiveMessage_, (const ResponseType& message)); - MOCK_METHOD(void, onReceiveTrailingMetadata_, (const Http::HeaderMap& metadata)); + MOCK_METHOD(void, onReceiveTrailingMetadata_, (const Http::ResponseTrailerMap& metadata)); MOCK_METHOD(void, onRemoteClose, (Status::GrpcStatus status, const std::string& message)); }; diff --git a/test/mocks/http/mocks.cc b/test/mocks/http/mocks.cc index 281b8e0c8c..6b041b740e 100644 --- a/test/mocks/http/mocks.cc +++ b/test/mocks/http/mocks.cc @@ -63,7 +63,7 @@ MockStreamDecoderFilterCallbacks::MockStreamDecoderFilterCallbacks() { ON_CALL(*this, scope()).WillByDefault(ReturnRef(scope_)); ON_CALL(*this, sendLocalReply(_, _, _, _, _)) .WillByDefault(Invoke([this](Code code, absl::string_view body, - std::function modify_headers, + std::function modify_headers, const absl::optional grpc_status, absl::string_view details) { sendLocalReply_(code, body, modify_headers, grpc_status, details); @@ -75,12 +75,13 @@ MockStreamDecoderFilterCallbacks::MockStreamDecoderFilterCallbacks() { MockStreamDecoderFilterCallbacks::~MockStreamDecoderFilterCallbacks() = default; void MockStreamDecoderFilterCallbacks::sendLocalReply_( - Code code, absl::string_view body, std::function modify_headers, + Code code, absl::string_view body, + std::function modify_headers, const absl::optional grpc_status, absl::string_view details) { details_ = std::string(details); Utility::sendLocalReply( is_grpc_request_, - [this, modify_headers](HeaderMapPtr&& headers, bool end_stream) -> void { + [this, modify_headers](ResponseHeaderMapPtr&& headers, bool end_stream) -> void { if (modify_headers != nullptr) { modify_headers(*headers); } diff --git a/test/mocks/http/mocks.h b/test/mocks/http/mocks.h index 4b7c72b18d..fb31f0270e 100644 --- a/test/mocks/http/mocks.h +++ b/test/mocks/http/mocks.h @@ -156,17 +156,17 @@ class MockStreamDecoderFilterCallbacks : public StreamDecoderFilterCallbacks, // Http::StreamDecoderFilterCallbacks void sendLocalReply_(Code code, absl::string_view body, - std::function modify_headers, + std::function modify_headers, const absl::optional grpc_status, absl::string_view details); - void encode100ContinueHeaders(HeaderMapPtr&& headers) override { + void encode100ContinueHeaders(ResponseHeaderMapPtr&& headers) override { encode100ContinueHeaders_(*headers); } - void encodeHeaders(HeaderMapPtr&& headers, bool end_stream) override { + void encodeHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) override { encodeHeaders_(*headers, end_stream); } - void encodeTrailers(HeaderMapPtr&& trailers) override { encodeTrailers_(*trailers); } + void encodeTrailers(ResponseTrailerMapPtr&& trailers) override { encodeTrailers_(*trailers); } void encodeMetadata(MetadataMapPtr&& metadata_map) override { encodeMetadata_(std::move(metadata_map)); } @@ -179,13 +179,13 @@ class MockStreamDecoderFilterCallbacks : public StreamDecoderFilterCallbacks, MOCK_METHOD(const Buffer::Instance*, decodingBuffer, ()); MOCK_METHOD(void, modifyDecodingBuffer, (std::function)); MOCK_METHOD(void, encode100ContinueHeaders_, (HeaderMap & headers)); - MOCK_METHOD(void, encodeHeaders_, (HeaderMap & headers, bool end_stream)); + MOCK_METHOD(void, encodeHeaders_, (ResponseHeaderMap & headers, bool end_stream)); MOCK_METHOD(void, encodeData, (Buffer::Instance & data, bool end_stream)); - MOCK_METHOD(void, encodeTrailers_, (HeaderMap & trailers)); + MOCK_METHOD(void, encodeTrailers_, (ResponseTrailerMap & trailers)); MOCK_METHOD(void, encodeMetadata_, (MetadataMapPtr metadata_map)); MOCK_METHOD(void, sendLocalReply, (Code code, absl::string_view body, - std::function modify_headers, + std::function modify_headers, const absl::optional grpc_status, absl::string_view details)); @@ -249,9 +249,9 @@ class MockStreamDecoderFilter : public StreamDecoderFilter { MOCK_METHOD(void, onDestroy, ()); // Http::StreamDecoderFilter - MOCK_METHOD(FilterHeadersStatus, decodeHeaders, (HeaderMap & headers, bool end_stream)); + MOCK_METHOD(FilterHeadersStatus, decodeHeaders, (RequestHeaderMap & headers, bool end_stream)); MOCK_METHOD(FilterDataStatus, decodeData, (Buffer::Instance & data, bool end_stream)); - MOCK_METHOD(FilterTrailersStatus, decodeTrailers, (HeaderMap & trailers)); + MOCK_METHOD(FilterTrailersStatus, decodeTrailers, (RequestTrailerMap & trailers)); MOCK_METHOD(FilterMetadataStatus, decodeMetadata, (Http::MetadataMap & metadata_map)); MOCK_METHOD(void, setDecoderFilterCallbacks, (StreamDecoderFilterCallbacks & callbacks)); MOCK_METHOD(void, decodeComplete, ()); @@ -268,10 +268,10 @@ class MockStreamEncoderFilter : public StreamEncoderFilter { MOCK_METHOD(void, onDestroy, ()); // Http::MockStreamEncoderFilter - MOCK_METHOD(FilterHeadersStatus, encode100ContinueHeaders, (HeaderMap & headers)); - MOCK_METHOD(FilterHeadersStatus, encodeHeaders, (HeaderMap & headers, bool end_stream)); + MOCK_METHOD(FilterHeadersStatus, encode100ContinueHeaders, (ResponseHeaderMap & headers)); + MOCK_METHOD(FilterHeadersStatus, encodeHeaders, (ResponseHeaderMap & headers, bool end_stream)); MOCK_METHOD(FilterDataStatus, encodeData, (Buffer::Instance & data, bool end_stream)); - MOCK_METHOD(FilterTrailersStatus, encodeTrailers, (HeaderMap & trailers)); + MOCK_METHOD(FilterTrailersStatus, encodeTrailers, (ResponseTrailerMap & trailers)); MOCK_METHOD(FilterMetadataStatus, encodeMetadata, (MetadataMap & metadata_map)); MOCK_METHOD(void, setEncoderFilterCallbacks, (StreamEncoderFilterCallbacks & callbacks)); MOCK_METHOD(void, encodeComplete, ()); @@ -288,17 +288,17 @@ class MockStreamFilter : public StreamFilter { MOCK_METHOD(void, onDestroy, ()); // Http::StreamDecoderFilter - MOCK_METHOD(FilterHeadersStatus, decodeHeaders, (HeaderMap & headers, bool end_stream)); + MOCK_METHOD(FilterHeadersStatus, decodeHeaders, (RequestHeaderMap & headers, bool end_stream)); MOCK_METHOD(FilterDataStatus, decodeData, (Buffer::Instance & data, bool end_stream)); - MOCK_METHOD(FilterTrailersStatus, decodeTrailers, (HeaderMap & trailers)); + MOCK_METHOD(FilterTrailersStatus, decodeTrailers, (RequestTrailerMap & trailers)); MOCK_METHOD(FilterMetadataStatus, decodeMetadata, (Http::MetadataMap & metadata_map)); MOCK_METHOD(void, setDecoderFilterCallbacks, (StreamDecoderFilterCallbacks & callbacks)); // Http::MockStreamEncoderFilter - MOCK_METHOD(FilterHeadersStatus, encode100ContinueHeaders, (HeaderMap & headers)); - MOCK_METHOD(FilterHeadersStatus, encodeHeaders, (HeaderMap & headers, bool end_stream)); + MOCK_METHOD(FilterHeadersStatus, encode100ContinueHeaders, (ResponseHeaderMap & headers)); + MOCK_METHOD(FilterHeadersStatus, encodeHeaders, (ResponseHeaderMap & headers, bool end_stream)); MOCK_METHOD(FilterDataStatus, encodeData, (Buffer::Instance & data, bool end_stream)); - MOCK_METHOD(FilterTrailersStatus, encodeTrailers, (HeaderMap & trailers)); + MOCK_METHOD(FilterTrailersStatus, encodeTrailers, (ResponseTrailerMap & trailers)); MOCK_METHOD(FilterMetadataStatus, encodeMetadata, (MetadataMap & metadata_map)); MOCK_METHOD(void, setEncoderFilterCallbacks, (StreamEncoderFilterCallbacks & callbacks)); @@ -314,12 +314,13 @@ class MockAsyncClient : public AsyncClient { MOCK_METHOD(void, onRequestDestroy, ()); // Http::AsyncClient - Request* send(MessagePtr&& request, Callbacks& callbacks, const RequestOptions& args) override { + Request* send(RequestMessagePtr&& request, Callbacks& callbacks, + const RequestOptions& args) override { return send_(request, callbacks, args); } MOCK_METHOD(Request*, send_, - (MessagePtr & request, Callbacks& callbacks, const RequestOptions& args)); + (RequestMessagePtr & request, Callbacks& callbacks, const RequestOptions& args)); MOCK_METHOD(Stream*, start, (StreamCallbacks & callbacks, const StreamOptions& args)); @@ -333,10 +334,10 @@ class MockAsyncClientCallbacks : public AsyncClient::Callbacks { MockAsyncClientCallbacks(); ~MockAsyncClientCallbacks() override; - void onSuccess(MessagePtr&& response) override { onSuccess_(response.get()); } + void onSuccess(ResponseMessagePtr&& response) override { onSuccess_(response.get()); } // Http::AsyncClient::Callbacks - MOCK_METHOD(void, onSuccess_, (Message * response)); + MOCK_METHOD(void, onSuccess_, (ResponseMessage * response)); MOCK_METHOD(void, onFailure, (Http::AsyncClient::FailureReason reason)); }; @@ -345,14 +346,14 @@ class MockAsyncClientStreamCallbacks : public AsyncClient::StreamCallbacks { MockAsyncClientStreamCallbacks(); ~MockAsyncClientStreamCallbacks() override; - void onHeaders(HeaderMapPtr&& headers, bool end_stream) override { + void onHeaders(ResponseHeaderMapPtr&& headers, bool end_stream) override { onHeaders_(*headers, end_stream); } - void onTrailers(HeaderMapPtr&& trailers) override { onTrailers_(*trailers); } + void onTrailers(ResponseTrailerMapPtr&& trailers) override { onTrailers_(*trailers); } - MOCK_METHOD(void, onHeaders_, (HeaderMap & headers, bool end_stream)); + MOCK_METHOD(void, onHeaders_, (ResponseHeaderMap & headers, bool end_stream)); MOCK_METHOD(void, onData, (Buffer::Instance & data, bool end_stream)); - MOCK_METHOD(void, onTrailers_, (HeaderMap & headers)); + MOCK_METHOD(void, onTrailers_, (ResponseTrailerMap & headers)); MOCK_METHOD(void, onComplete, ()); MOCK_METHOD(void, onReset, ()); }; @@ -372,9 +373,9 @@ class MockAsyncClientStream : public AsyncClient::Stream { MockAsyncClientStream(); ~MockAsyncClientStream() override; - MOCK_METHOD(void, sendHeaders, (HeaderMap & headers, bool end_stream)); + MOCK_METHOD(void, sendHeaders, (RequestHeaderMap & headers, bool end_stream)); MOCK_METHOD(void, sendData, (Buffer::Instance & data, bool end_stream)); - MOCK_METHOD(void, sendTrailers, (HeaderMap & trailers)); + MOCK_METHOD(void, sendTrailers, (RequestTrailerMap & trailers)); MOCK_METHOD(void, reset, ()); }; diff --git a/test/mocks/http/stream_decoder.cc b/test/mocks/http/stream_decoder.cc index 77b922c845..550d7e4715 100644 --- a/test/mocks/http/stream_decoder.cc +++ b/test/mocks/http/stream_decoder.cc @@ -23,10 +23,6 @@ MockRequestDecoder::MockRequestDecoder() { MockRequestDecoder::~MockRequestDecoder() = default; MockResponseDecoder::MockResponseDecoder() { - ON_CALL(*this, decode100ContinueHeaders_(_)) - .WillByDefault( - Invoke([](ResponseHeaderMapPtr& headers) { auto moved_headers = std::move(headers); })); - ON_CALL(*this, decodeHeaders_(_, _)) .WillByDefault(Invoke([](ResponseHeaderMapPtr& headers, bool) { // Check for passing request headers as response headers in a test. diff --git a/test/mocks/http/stream_encoder.h b/test/mocks/http/stream_encoder.h index 2adb8d484b..f97546c677 100644 --- a/test/mocks/http/stream_encoder.h +++ b/test/mocks/http/stream_encoder.h @@ -28,8 +28,8 @@ class MockRequestEncoder : public MockStreamEncoder, public RequestEncoder { ~MockRequestEncoder(); // Http::RequestEncoder - MOCK_METHOD(void, encodeHeaders, (const HeaderMap& headers, bool end_stream)); - MOCK_METHOD(void, encodeTrailers, (const HeaderMap& trailers)); + MOCK_METHOD(void, encodeHeaders, (const RequestHeaderMap& headers, bool end_stream)); + MOCK_METHOD(void, encodeTrailers, (const RequestTrailerMap& trailers)); }; class MockResponseEncoder : public MockStreamEncoder, public ResponseEncoder { @@ -38,9 +38,9 @@ class MockResponseEncoder : public MockStreamEncoder, public ResponseEncoder { ~MockResponseEncoder(); // Http::ResponseEncoder - MOCK_METHOD(void, encode100ContinueHeaders, (const HeaderMap& headers)); - MOCK_METHOD(void, encodeHeaders, (const HeaderMap& headers, bool end_stream)); - MOCK_METHOD(void, encodeTrailers, (const HeaderMap& trailers)); + MOCK_METHOD(void, encode100ContinueHeaders, (const ResponseHeaderMap& headers)); + MOCK_METHOD(void, encodeHeaders, (const ResponseHeaderMap& headers, bool end_stream)); + MOCK_METHOD(void, encodeTrailers, (const ResponseTrailerMap& trailers)); }; } // namespace Http diff --git a/test/mocks/router/mocks.h b/test/mocks/router/mocks.h index a75e91a9fc..68156caf94 100644 --- a/test/mocks/router/mocks.h +++ b/test/mocks/router/mocks.h @@ -206,13 +206,13 @@ class MockShadowWriter : public ShadowWriter { ~MockShadowWriter() override; // Router::ShadowWriter - void shadow(const std::string& cluster, Http::MessagePtr&& request, + void shadow(const std::string& cluster, Http::RequestMessagePtr&& request, std::chrono::milliseconds timeout) override { shadow_(cluster, request, timeout); } MOCK_METHOD(void, shadow_, - (const std::string& cluster, Http::MessagePtr& request, + (const std::string& cluster, Http::RequestMessagePtr& request, std::chrono::milliseconds timeout)); }; diff --git a/test/server/config_validation/async_client_test.cc b/test/server/config_validation/async_client_test.cc index ca25ac04ee..902e8cb10e 100644 --- a/test/server/config_validation/async_client_test.cc +++ b/test/server/config_validation/async_client_test.cc @@ -13,7 +13,7 @@ namespace Http { namespace { TEST(ValidationAsyncClientTest, MockedMethods) { - MessagePtr message{new RequestMessageImpl()}; + RequestMessagePtr message{new RequestMessageImpl()}; MockAsyncClientCallbacks callbacks; MockAsyncClientStreamCallbacks stream_callbacks; diff --git a/test/server/http/admin_test.cc b/test/server/http/admin_test.cc index d5cfbafea8..0439a7774e 100644 --- a/test/server/http/admin_test.cc +++ b/test/server/http/admin_test.cc @@ -94,7 +94,7 @@ class AdminFilterTest : public testing::TestWithParam callbacks_; - Http::TestHeaderMapImpl request_headers_; + Http::TestRequestHeaderMapImpl request_headers_; }; // Check default implementations the admin class picks up. @@ -599,7 +599,8 @@ TEST_P(AdminFilterTest, Trailers) { EXPECT_CALL(callbacks_, decodingBuffer()); filter_.getRequestBody(); EXPECT_CALL(callbacks_, encodeHeaders_(_, false)); - EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_.decodeTrailers(request_headers_)); + Http::TestRequestTrailerMapImpl request_trailers; + EXPECT_EQ(Http::FilterTrailersStatus::StopIteration, filter_.decodeTrailers(request_trailers)); } class AdminInstanceTest : public testing::TestWithParam { @@ -650,7 +651,7 @@ class AdminInstanceTest : public testing::TestWithParam server_; Stats::IsolatedStoreImpl listener_scope_; AdminImpl admin_; - Http::TestHeaderMapImpl request_headers_; + Http::TestRequestHeaderMapImpl request_headers_; Server::AdminFilter admin_filter_; NiceMock callbacks_; }; diff --git a/test/server/server_test.cc b/test/server/server_test.cc index 97bb076da8..9e2416eb01 100644 --- a/test/server/server_test.cc +++ b/test/server/server_test.cc @@ -655,7 +655,7 @@ TEST_P(ServerInstanceImplTest, BootstrapRuntime) { TEST_P(ServerInstanceImplTest, RuntimeNoAdminLayer) { options_.service_cluster_name_ = "some_service"; initialize("test/server/test_data/server/runtime_bootstrap.yaml"); - Http::TestHeaderMapImpl response_headers; + Http::TestResponseHeaderMapImpl response_headers; std::string response_body; EXPECT_EQ(Http::Code::OK, server_->admin().request("/runtime", "GET", response_headers, response_body)); From 967931a198436bd5033aaa42fe83db7529a6fa51 Mon Sep 17 00:00:00 2001 From: gargnupur Date: Tue, 18 Feb 2020 16:42:36 -0800 Subject: [PATCH 75/87] Fix path of requirements.txt --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cbf52f2847..7e91432672 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -62,7 +62,7 @@ jobs: steps: - run: rm -rf /home/circleci/project/.git # CircleCI git caching is likely broken - checkout - - run: pip install -r tools/requirements.txt + - run: pip install -r tools/code_format/requirements.txt - run: ci/do_circle_ci.sh check_format - run: ci/do_circle_ci.sh check_repositories - run: ci/do_circle_ci.sh check_spelling From c9d9d9ab3ded6cc9dfc210ea5f62e55f57d4a508 Mon Sep 17 00:00:00 2001 From: Jimmy Chen <28548492+JimmyCYJ@users.noreply.github.com> Date: Tue, 18 Feb 2020 16:45:42 -0800 Subject: [PATCH 76/87] Update gRPC SHA (#10056) Signed-off-by: Jimmy Chen --- bazel/repository_locations.bzl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index b5b2d4b595..23158dbc78 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -109,9 +109,11 @@ REPOSITORY_LOCATIONS = dict( urls = ["https://github.com/gperftools/gperftools/archive/fc00474ddc21fff618fc3f009b46590e241e425e.tar.gz"], ), com_github_grpc_grpc = dict( - sha256 = "ffbe61269160ea745e487f79b0fd06b6edd3d50c6d9123f053b5634737cf2f69", - strip_prefix = "grpc-1.25.0", - urls = ["https://github.com/grpc/grpc/archive/v1.25.0.tar.gz"], + # TODO(JimmyCYJ): Bump to release 1.27 + # This sha on grpc:v1.25.x branch is specifically chosen to fix gRPC STS call credential options. + sha256 = "bbc8f020f4e85ec029b047fab939b8c81f3d67254b5c724e1003a2bc49ddd123", + strip_prefix = "grpc-d8f4928fa779f6005a7fe55a176bdb373b0f910f", + urls = ["https://github.com/grpc/grpc/archive/d8f4928fa779f6005a7fe55a176bdb373b0f910f.tar.gz"], ), com_github_luajit_luajit = dict( sha256 = "409f7fe570d3c16558e594421c47bdd130238323c9d6fd6c83dedd2aaeb082a8", From 43ef41d438b2d211a1d80f73f6d2d106eef866b7 Mon Sep 17 00:00:00 2001 From: Lisa Lu Date: Tue, 18 Feb 2020 16:47:14 -0800 Subject: [PATCH 77/87] router check tool: response headers (#10090) Signed-off-by: Lisa Lu --- test/tools/router_check/router.cc | 21 +++++++++++++++--- .../test/config/TestRoutes.golden.proto.json | 22 +++++++++++++++++++ .../router_check/test/config/TestRoutes.yaml | 11 +++++++++- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/test/tools/router_check/router.cc b/test/tools/router_check/router.cc index 9013761cc0..97280703c0 100644 --- a/test/tools/router_check/router.cc +++ b/test/tools/router_check/router.cc @@ -331,6 +331,7 @@ bool RouterCheckTool::compareRewritePath(ToolConfig& tool_config, const std::str if (!headers_finalized_) { tool_config.route_->routeEntry()->finalizeRequestHeaders(*tool_config.headers_, stream_info, true); + tool_config.route_->routeEntry()->finalizeResponseHeaders(*tool_config.headers_, stream_info); headers_finalized_ = true; } @@ -362,6 +363,7 @@ bool RouterCheckTool::compareRewriteHost(ToolConfig& tool_config, const std::str if (!headers_finalized_) { tool_config.route_->routeEntry()->finalizeRequestHeaders(*tool_config.headers_, stream_info, true); + tool_config.route_->routeEntry()->finalizeResponseHeaders(*tool_config.headers_, stream_info); headers_finalized_ = true; } @@ -387,8 +389,16 @@ bool RouterCheckTool::compareRewriteHost( bool RouterCheckTool::compareRedirectPath(ToolConfig& tool_config, const std::string& expected) { std::string actual = ""; + Envoy::StreamInfo::StreamInfoImpl stream_info(Envoy::Http::Protocol::Http11, + factory_context_->dispatcher().timeSource()); if (tool_config.route_->directResponseEntry() != nullptr) { - tool_config.route_->directResponseEntry()->rewritePathHeader(*tool_config.headers_, true); + if (!headers_finalized_) { + tool_config.route_->directResponseEntry()->rewritePathHeader(*tool_config.headers_, true); + tool_config.route_->directResponseEntry()->finalizeResponseHeaders(*tool_config.headers_, + stream_info); + headers_finalized_ = true; + } + actual = tool_config.route_->directResponseEntry()->newPath(*tool_config.headers_); } @@ -436,8 +446,13 @@ bool RouterCheckTool::compareCustomHeaderField(ToolConfig& tool_config, const st factory_context_->dispatcher().timeSource()); stream_info.setDownstreamRemoteAddress(Network::Utility::getCanonicalIpv4LoopbackAddress()); if (tool_config.route_->routeEntry() != nullptr) { - tool_config.route_->routeEntry()->finalizeRequestHeaders(*tool_config.headers_, stream_info, - true); + if (!headers_finalized_) { + tool_config.route_->routeEntry()->finalizeRequestHeaders(*tool_config.headers_, stream_info, + true); + tool_config.route_->routeEntry()->finalizeResponseHeaders(*tool_config.headers_, stream_info); + headers_finalized_ = true; + } + actual = tool_config.headers_->get_(field); } return compareResults(actual, expected, "custom_header"); diff --git a/test/tools/router_check/test/config/TestRoutes.golden.proto.json b/test/tools/router_check/test/config/TestRoutes.golden.proto.json index 788e8af713..8820b72aa2 100644 --- a/test/tools/router_check/test/config/TestRoutes.golden.proto.json +++ b/test/tools/router_check/test/config/TestRoutes.golden.proto.json @@ -324,6 +324,28 @@ } ] } + }, + { + "test_name": "Header_Fields Response", + "input": { + "authority": "www.lyft.com", + "path": "/ping", + "method": "GET" + }, + "validate": { + "cluster_name": "", + "host_rewrite": "", + "path_redirect": "http://www.lyft.com/ping", + "path_rewrite": "", + "virtual_cluster_name": "", + "virtual_host_name": "", + "header_fields": [ + { + "key": "content-type", + "value": "text/plain" + } + ] + } } ] } diff --git a/test/tools/router_check/test/config/TestRoutes.yaml b/test/tools/router_check/test/config/TestRoutes.yaml index 862b6a4da8..43470daf09 100644 --- a/test/tools/router_check/test/config/TestRoutes.yaml +++ b/test/tools/router_check/test/config/TestRoutes.yaml @@ -12,6 +12,16 @@ virtual_hosts: route: cluster: www2 prefix_rewrite: /api/new_endpoint + - match: + prefix: /ping + direct_response: + status: 200 + body: + inline_string: "Success!" + response_headers_to_add: + - header: + key: "content-type" + value: "text/plain" - match: path: / route: @@ -20,7 +30,6 @@ virtual_hosts: prefix: / route: cluster: www2 - - name: www2_staging domains: - www-staging.lyft.net From 0e1d589a478e4929f114c8d3ce29eccb6ad32693 Mon Sep 17 00:00:00 2001 From: gargnupur Date: Tue, 18 Feb 2020 16:48:37 -0800 Subject: [PATCH 78/87] Fix fmt --- test/tools/wee8_compile/wee8_compile.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/test/tools/wee8_compile/wee8_compile.cc b/test/tools/wee8_compile/wee8_compile.cc index f9561d55df..42cbfea08a 100644 --- a/test/tools/wee8_compile/wee8_compile.cc +++ b/test/tools/wee8_compile/wee8_compile.cc @@ -230,4 +230,3 @@ int main(int argc, char* argv[]) { return EXIT_SUCCESS; } - From 1223a2b4aef6eb90f3e34eebf496aead4930c4ab Mon Sep 17 00:00:00 2001 From: yanavlasov Date: Tue, 18 Feb 2020 20:46:12 -0500 Subject: [PATCH 79/87] Plumb the flaky flag from envoy_cc_test to the native.cc_test (#10009) Signed-off-by: Yan Avlasov --- bazel/envoy_test.bzl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bazel/envoy_test.bzl b/bazel/envoy_test.bzl index 1ea82dbe4b..dd49268d66 100644 --- a/bazel/envoy_test.bzl +++ b/bazel/envoy_test.bzl @@ -163,7 +163,8 @@ def envoy_cc_test( shard_count = None, coverage = True, local = False, - size = "medium"): + size = "medium", + flaky = False): if coverage: coverage_tags = tags + ["coverage_test_lib"] else: @@ -199,6 +200,7 @@ def envoy_cc_test( local = local, shard_count = shard_count, size = size, + flaky = flaky, ) # Envoy C++ test related libraries (that want gtest, gmock) should be specified From a5c6d907e398987b7c6c08df043ce04293c2cca7 Mon Sep 17 00:00:00 2001 From: rulex123 <29862113+rulex123@users.noreply.github.com> Date: Wed, 19 Feb 2020 06:11:41 +0100 Subject: [PATCH 80/87] tools: reorg tools dir (#10092) Description: last iteration in reorg of tools dir (see #9568). In this PR: - debugging files are grouped under `tools/debugging`; - protoxform test files are moved to `tools/protoxform`; - proto format files are grouped under `tools/proto_format`. Risk Level: low Testing: manual Docs Changes: N/A Release Notes: N/A Signed-off-by: Erica Manno --- ci/do_ci.sh | 6 +++--- support/hooks/pre-push | 2 +- tools/{ => debugging}/run-valgrind.sh | 2 +- tools/{ => debugging}/valgrind-suppressions.txt | 0 tools/{ => proto_format}/proto_format.sh | 6 +++++- tools/{ => proto_format}/proto_sync.py | 4 ++-- tools/{ => protoxform}/protoxform_test.sh | 6 +++++- tools/{ => protoxform}/protoxform_test_helper.py | 0 8 files changed, 17 insertions(+), 9 deletions(-) rename tools/{ => debugging}/run-valgrind.sh (88%) rename tools/{ => debugging}/valgrind-suppressions.txt (100%) rename tools/{ => proto_format}/proto_format.sh (88%) rename tools/{ => proto_format}/proto_sync.py (99%) rename tools/{ => protoxform}/protoxform_test.sh (74%) rename tools/{ => protoxform}/protoxform_test_helper.py (100%) diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 6f407d7df2..3194460a27 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -304,11 +304,11 @@ elif [[ "$CI_TARGET" == "fix_format" ]]; then # proto_format.sh needs to build protobuf. setup_clang_toolchain echo "protoxform_test..." - ./tools/protoxform_test.sh + ./tools/protoxform/protoxform_test.sh echo "fix_format..." ./tools/code_format/check_format.py fix ./tools/code_format/format_python_tools.sh fix - ./tools/proto_format.sh fix + ./tools/proto_format/proto_format.sh fix exit 0 elif [[ "$CI_TARGET" == "check_format" ]]; then # proto_format.sh needs to build protobuf. @@ -318,7 +318,7 @@ elif [[ "$CI_TARGET" == "check_format" ]]; then echo "check_format..." ./tools/code_format/check_format.py check ./tools/code_format/format_python_tools.sh check - ./tools/proto_format.sh check + ./tools/proto_format/proto_format.sh check exit 0 elif [[ "$CI_TARGET" == "check_repositories" ]]; then echo "check_repositories..." diff --git a/support/hooks/pre-push b/support/hooks/pre-push index 7b08dd4e0e..1a1378b0cd 100755 --- a/support/hooks/pre-push +++ b/support/hooks/pre-push @@ -72,7 +72,7 @@ do done # TODO(mattklein123): Optimally we would be able to do this on a per-file basis. - "$SCRIPT_DIR"/proto_format.sh check + "$SCRIPT_DIR"/proto_format/proto_format.sh check if [[ $? -ne 0 ]]; then exit 1 fi diff --git a/tools/run-valgrind.sh b/tools/debugging/run-valgrind.sh similarity index 88% rename from tools/run-valgrind.sh rename to tools/debugging/run-valgrind.sh index 7084d6f8ea..6211a77ce8 100755 --- a/tools/run-valgrind.sh +++ b/tools/debugging/run-valgrind.sh @@ -1,7 +1,7 @@ #!/bin/sh # # Helper script to run tests under valgrind. Usage: -# bazel test --run_under=`pwd`/tools/run-valgrind.sh ... +# bazel test --run_under=`pwd`/tools/debugging/run-valgrind.sh ... # dir=$(dirname "$0") diff --git a/tools/valgrind-suppressions.txt b/tools/debugging/valgrind-suppressions.txt similarity index 100% rename from tools/valgrind-suppressions.txt rename to tools/debugging/valgrind-suppressions.txt diff --git a/tools/proto_format.sh b/tools/proto_format/proto_format.sh similarity index 88% rename from tools/proto_format.sh rename to tools/proto_format/proto_format.sh index 3308909c0c..2f29c8ba65 100755 --- a/tools/proto_format.sh +++ b/tools/proto_format/proto_format.sh @@ -25,7 +25,11 @@ bazel build ${BAZEL_BUILD_OPTIONS} --//tools/api_proto_plugin:default_type_db_ta @envoy_api_canonical//docs:protos --aspects //tools/protoxform:protoxform.bzl%protoxform_aspect --output_groups=proto \ --action_env=CPROFILE_ENABLED=1 --host_force_python=PY3 -./tools/proto_sync.py "--mode=$1" ${PROTO_TARGETS} +TOOLS=$(dirname $(dirname $(realpath $0))) +# to satisfy dependency on api_proto_plugin +export PYTHONPATH="$TOOLS" +./tools/proto_format/proto_sync.py "--mode=$1" ${PROTO_TARGETS} + bazel build ${BAZEL_BUILD_OPTIONS} //tools/type_whisperer:api_build_file cp -f bazel-bin/tools/type_whisperer/BUILD.api_build_file api/BUILD diff --git a/tools/proto_sync.py b/tools/proto_format/proto_sync.py similarity index 99% rename from tools/proto_sync.py rename to tools/proto_format/proto_sync.py index 36c40fd125..cc9112a37f 100755 --- a/tools/proto_sync.py +++ b/tools/proto_format/proto_sync.py @@ -58,8 +58,8 @@ class RequiresReformatError(ProtoSyncError): def __init__(self, message): super(RequiresReformatError, self).__init__( - '%s; either run ./ci/do_ci.sh fix_format or ./tools/proto_format.sh fix to reformat.\n' % - message) + '%s; either run ./ci/do_ci.sh fix_format or ./tools/proto_format/proto_format.sh fix to reformat.\n' + % message) def GetDirectoryFromPackage(package): diff --git a/tools/protoxform_test.sh b/tools/protoxform/protoxform_test.sh similarity index 74% rename from tools/protoxform_test.sh rename to tools/protoxform/protoxform_test.sh index 705a8235e1..b4661db9c3 100755 --- a/tools/protoxform_test.sh +++ b/tools/protoxform/protoxform_test.sh @@ -10,4 +10,8 @@ bazel build ${BAZEL_BUILD_OPTIONS} --//tools/api_proto_plugin:default_type_db_ta //tools/testdata/protoxform:protos --aspects //tools/protoxform:protoxform.bzl%protoxform_aspect --output_groups=proto \ --action_env=CPROFILE_ENABLED=1 --host_force_python=PY3 -./tools/protoxform_test_helper.py ${PROTO_TARGETS} \ No newline at end of file +TOOLS=$(dirname $(dirname $(realpath $0))) +# to satisfy dependency on run_command +export PYTHONPATH="$TOOLS" + +./tools/protoxform/protoxform_test_helper.py ${PROTO_TARGETS} diff --git a/tools/protoxform_test_helper.py b/tools/protoxform/protoxform_test_helper.py similarity index 100% rename from tools/protoxform_test_helper.py rename to tools/protoxform/protoxform_test_helper.py From 8c283373f03f32e79e41c6e86692c2d117f59aea Mon Sep 17 00:00:00 2001 From: gargnupur Date: Wed, 19 Feb 2020 01:29:26 -0800 Subject: [PATCH 81/87] Fix test --- test/stress/stress_test_downstream.cc | 14 +++++------ test/stress/stress_test_upstream.cc | 34 ++++++++++++--------------- test/stress/stress_test_upstream.h | 6 ++--- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/test/stress/stress_test_downstream.cc b/test/stress/stress_test_downstream.cc index 33154cd04b..06931b6117 100644 --- a/test/stress/stress_test_downstream.cc +++ b/test/stress/stress_test_downstream.cc @@ -12,7 +12,7 @@ namespace Envoy { namespace Stress { -class ClientStream : public Http::StreamDecoder, +class ClientStream : public Http::ResponseDecoder, public Http::StreamCallbacks, Logger::Loggable { public: @@ -27,15 +27,15 @@ class ClientStream : public Http::StreamDecoder, } // - // Http::StreamDecoder + // Http::ResponseDecoder // - void decode100ContinueHeaders(Http::HeaderMapPtr&&) override { + void decode100ContinueHeaders(Http::ResponseHeaderMapPtr&&) override { ENVOY_LOG(trace, "ClientStream({}:{}:{}) got continue headers", connection_.name(), connection_.id(), id_); } - void decodeHeaders(Http::HeaderMapPtr&& response_headers, bool end_stream) override { + void decodeHeaders(Http::ResponseHeaderMapPtr&& response_headers, bool end_stream) override { ENVOY_LOG(debug, "ClientStream({}:{}:{}) got response headers", connection_.name(), connection_.id(), id_); @@ -57,7 +57,7 @@ class ClientStream : public Http::StreamDecoder, } } - void decodeTrailers(Http::HeaderMapPtr&&) override { + void decodeTrailers(Http::ResponseTrailerMapPtr&&) override { ENVOY_LOG(trace, "ClientStream({}:{}:{}) got response trailers", connection_.name(), connection_.id(), id_); onEndStream(); @@ -130,7 +130,7 @@ class ClientStream : public Http::StreamDecoder, return; } - Http::StreamEncoder& encoder = connection_.httpConnection().newStream(*this); + Http::RequestEncoder& encoder = connection_.httpConnection().newStream(*this); encoder.getStream().addCallbacks(*this); ENVOY_LOG(debug, "ClientStream({}:{}:{}) sending request headers", connection_.name(), @@ -157,7 +157,7 @@ class ClientStream : public Http::StreamDecoder, uint32_t id_; ClientConnection& connection_; - Http::HeaderMapPtr response_headers_{nullptr}; + Http::ResponseHeaderMapPtr response_headers_{nullptr}; ClientResponseCallback& callback_; Event::TimerPtr timeout_timer_{nullptr}; }; diff --git a/test/stress/stress_test_upstream.cc b/test/stress/stress_test_upstream.cc index 55d9ba736a..9bd9f3d8dc 100644 --- a/test/stress/stress_test_upstream.cc +++ b/test/stress/stress_test_upstream.cc @@ -11,6 +11,7 @@ #include "common/http/conn_manager_config.h" #include "common/http/conn_manager_impl.h" #include "common/http/exception.h" +#include "common/http/header_map_impl.h" #include "common/http/http1/codec_impl.h" #include "common/http/http2/codec_impl.h" #include "common/network/listen_socket_impl.h" @@ -29,12 +30,12 @@ namespace Stress { static Http::LowerCaseString RequestId(std::string("x-request-id")); class ServerStreamImpl : public ServerStream, - public Http::StreamDecoder, + public Http::RequestDecoder, public Http::StreamCallbacks, Logger::Loggable { public: ServerStreamImpl(uint32_t id, ServerConnection& connection, - ServerRequestCallback& request_callback, Http::StreamEncoder& stream_encoder) + ServerRequestCallback& request_callback, Http::ResponseEncoder& stream_encoder) : id_(id), connection_(connection), request_callback_(request_callback), stream_encoder_(stream_encoder) {} @@ -50,7 +51,7 @@ class ServerStreamImpl : public ServerStream, // ServerStream // - void sendResponseHeaders(const Http::HeaderMap& response_headers, + void sendResponseHeaders(const Http::ResponseHeaderMap& response_headers, const std::chrono::milliseconds delay) override { if (connection_.networkConnection().state() != Network::Connection::State::Open) { ENVOY_LOG(warn, "ServerStream({}:{}:{})'s underlying connection is not open!", @@ -71,7 +72,7 @@ class ServerStreamImpl : public ServerStream, return; } - response_headers_ = std::make_unique(response_headers); + response_headers_ = Http::createHeaderMap(response_headers); delay_timer_ = connection_.dispatcher().createTimer([this, delay]() { ENVOY_LOG(debug, "ServerStream({}:{}:{}) sending response headers after {} msec delay", connection_.name(), connection_.id(), id_, static_cast(delay.count())); @@ -96,9 +97,9 @@ class ServerStreamImpl : public ServerStream, Event::TimerCb send_grpc_response = [this, delay]() { ENVOY_LOG(debug, "ServerStream({}:{}:{}) sending gRPC response after {} msec delay", connection_.name(), connection_.id(), id_, static_cast(delay.count())); - stream_encoder_.encodeHeaders(Http::TestHeaderMapImpl{{":status", "200"}}, false); + stream_encoder_.encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); stream_encoder_.encodeData(*response_body_, false); - stream_encoder_.encodeTrailers(Http::TestHeaderMapImpl{ + stream_encoder_.encodeTrailers(Http::TestResponseTrailerMapImpl{ {"grpc-status", std::to_string(static_cast(response_status_))}}); }; @@ -116,21 +117,16 @@ class ServerStreamImpl : public ServerStream, } // - // Http::StreamDecoder + // Http::RequestDecoder // - void decode100ContinueHeaders(Http::HeaderMapPtr&&) override { - ENVOY_LOG(error, "ServerStream({}:{}:{}) got continue headers?!?!", connection_.name(), - connection_.id(), id_); - } - /** * Called with decoded headers, optionally indicating end of stream. * @param headers supplies the decoded headers map that is moved into the * callee. * @param end_stream supplies whether this is a header only request/response. */ - void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override { + void decodeHeaders(Http::RequestHeaderMapPtr&& headers, bool end_stream) override { ENVOY_LOG(debug, "ServerStream({}:{}:{}) got request headers", connection_.name(), connection_.id(), id_); @@ -152,7 +148,7 @@ class ServerStreamImpl : public ServerStream, } } - void decodeTrailers(Http::HeaderMapPtr&&) override { + void decodeTrailers(Http::RequestTrailerMapPtr&&) override { ENVOY_LOG(trace, "ServerStream({}:{}:{}) got request trailers", connection_.name(), connection_.id(), id_); onEndStream(); @@ -226,12 +222,12 @@ class ServerStreamImpl : public ServerStream, uint32_t id_; ServerConnection& connection_; - Http::HeaderMapPtr request_headers_{nullptr}; - Http::HeaderMapPtr response_headers_{nullptr}; + Http::RequestHeaderMapPtr request_headers_{nullptr}; + Http::ResponseHeaderMapPtr response_headers_{nullptr}; Buffer::InstancePtr response_body_{nullptr}; Grpc::Status::GrpcStatus response_status_{Grpc::Status::Ok}; ServerRequestCallback& request_callback_; - Http::StreamEncoder& stream_encoder_; + Http::ResponseEncoder& stream_encoder_; Event::TimerPtr delay_timer_{nullptr}; }; @@ -318,7 +314,7 @@ Network::FilterStatus ServerConnection::onNewConnection() { void ServerConnection::initializeReadFilterCallbacks(Network::ReadFilterCallbacks&) {} -Http::StreamDecoder& ServerConnection::newStream(Http::StreamEncoder& stream_encoder, bool) { +Http::RequestDecoder& ServerConnection::newStream(Http::ResponseEncoder& stream_encoder, bool) { ServerStreamImpl* raw = nullptr; uint32_t id = 0U; @@ -594,7 +590,7 @@ uint64_t Server::listenerTag() const { return 0; } const std::string& Server::name() const { return name_; } -const Network::ActiveUdpListenerFactory* Server::udpListenerFactory() { return nullptr; } +Network::ActiveUdpListenerFactory* Server::udpListenerFactory() { return nullptr; } const Network::FilterChain* Server::findFilterChain(const Network::ConnectionSocket&) const { return &server_filter_chain_; diff --git a/test/stress/stress_test_upstream.h b/test/stress/stress_test_upstream.h index 7c85452f6c..2b2f61bfb9 100644 --- a/test/stress/stress_test_upstream.h +++ b/test/stress/stress_test_upstream.h @@ -47,7 +47,7 @@ class ServerStream { * immediately */ virtual void - sendResponseHeaders(const Http::HeaderMap& response_headers, + sendResponseHeaders(const Http::ResponseHeaderMap& response_headers, const std::chrono::milliseconds delay = std::chrono::milliseconds(0)) PURE; /** @@ -130,7 +130,7 @@ class ServerConnection : public Network::ReadFilter, // Http::ServerConnectionCallbacks // - Http::StreamDecoder& newStream(Http::StreamEncoder& stream_encoder, + Http::RequestDecoder& newStream(Http::ResponseEncoder& stream_encoder, bool is_internally_created = false) override; // @@ -326,7 +326,7 @@ class Server : public Network::FilterChainManager, const std::string& name() const override; - const Network::ActiveUdpListenerFactory* udpListenerFactory() override; + Network::ActiveUdpListenerFactory* udpListenerFactory() override; Network::ConnectionBalancer& connectionBalancer() override { return connection_balancer_; } From 6a8680dcfe893034872ce922126cbb9bbc326875 Mon Sep 17 00:00:00 2001 From: gargnupur Date: Wed, 19 Feb 2020 12:29:11 -0800 Subject: [PATCH 82/87] Fix build --- source/extensions/common/wasm/context.cc | 34 +++++++++++++++++------- source/extensions/common/wasm/context.h | 34 +++++++++++++----------- test/stress/stress_test_upstream.h | 2 +- 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/source/extensions/common/wasm/context.cc b/source/extensions/common/wasm/context.cc index fb4933d39f..41a8d2605a 100644 --- a/source/extensions/common/wasm/context.cc +++ b/source/extensions/common/wasm/context.cc @@ -198,8 +198,20 @@ class SharedData { SharedData global_shared_data; -Http::HeaderMapPtr buildHeaderMapFromPairs(const Pairs& pairs) { - auto map = std::make_unique(); +Http::RequestTrailerMapPtr buildRequestTrailerMapFromPairs(const Pairs& pairs) { + auto map = std::make_unique(); + for (auto& p : pairs) { + // Note: because of the lack of a string_view interface for addCopy and + // the lack of an interface to add an entry with an empty value and return + // the entry, there is no efficient way to prevent either a double copy + // of the valueor a double lookup of the entry. + map->addCopy(Http::LowerCaseString(std::string(p.first)), std::string(p.second)); + } + return map; +} + +Http::RequestHeaderMapPtr buildRequestHeaderMapFromPairs(const Pairs& pairs) { + auto map = std::make_unique(); for (auto& p : pairs) { // Note: because of the lack of a string_view interface for addCopy and // the lack of an interface to add an entry with an empty value and return @@ -805,7 +817,8 @@ WasmResult Context::httpCall(absl::string_view cluster, const Pairs& request_hea return WasmResult::BadArgument; } - Http::MessagePtr message(new Http::RequestMessageImpl(buildHeaderMapFromPairs(request_headers))); + Http::RequestMessagePtr message( + new Http::RequestMessageImpl(buildRequestHeaderMapFromPairs(request_headers))); // Check that we were provided certain headers. if (message->headers().Path() == nullptr || message->headers().Method() == nullptr || @@ -819,7 +832,7 @@ WasmResult Context::httpCall(absl::string_view cluster, const Pairs& request_hea } if (request_trailers.size() > 0) { - message->trailers(buildHeaderMapFromPairs(request_trailers)); + message->trailers(buildRequestTrailerMapFromPairs(request_trailers)); } absl::optional timeout; @@ -1533,7 +1546,7 @@ void Context::onDelete() { } } -Http::FilterHeadersStatus Context::decodeHeaders(Http::HeaderMap& headers, bool end_stream) { +Http::FilterHeadersStatus Context::decodeHeaders(Http::RequestHeaderMap& headers, bool end_stream) { request_headers_ = &headers; end_of_stream_ = end_stream; auto result = onRequestHeaders(); @@ -1549,7 +1562,7 @@ Http::FilterDataStatus Context::decodeData(Buffer::Instance& data, bool end_stre return result; } -Http::FilterTrailersStatus Context::decodeTrailers(Http::HeaderMap& trailers) { +Http::FilterTrailersStatus Context::decodeTrailers(Http::RequestTrailerMap& trailers) { request_trailers_ = &trailers; auto result = onRequestTrailers(); request_trailers_ = nullptr; @@ -1567,11 +1580,12 @@ void Context::setDecoderFilterCallbacks(Envoy::Http::StreamDecoderFilterCallback decoder_callbacks_ = &callbacks; } -Http::FilterHeadersStatus Context::encode100ContinueHeaders(Http::HeaderMap&) { +Http::FilterHeadersStatus Context::encode100ContinueHeaders(Http::ResponseHeaderMap&) { return Http::FilterHeadersStatus::Continue; } -Http::FilterHeadersStatus Context::encodeHeaders(Http::HeaderMap& headers, bool end_stream) { +Http::FilterHeadersStatus Context::encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) { response_headers_ = &headers; end_of_stream_ = end_stream; auto result = onResponseHeaders(); @@ -1587,7 +1601,7 @@ Http::FilterDataStatus Context::encodeData(Buffer::Instance& data, bool end_stre return result; } -Http::FilterTrailersStatus Context::encodeTrailers(Http::HeaderMap& trailers) { +Http::FilterTrailersStatus Context::encodeTrailers(Http::ResponseTrailerMap& trailers) { response_trailers_ = &trailers; auto result = onResponseTrailers(); response_trailers_ = nullptr; @@ -1607,7 +1621,7 @@ void Context::setEncoderFilterCallbacks(Envoy::Http::StreamEncoderFilterCallback encoder_callbacks_ = &callbacks; } -void Context::onHttpCallSuccess(uint32_t token, Envoy::Http::MessagePtr& response) { +void Context::onHttpCallSuccess(uint32_t token, Envoy::Http::ResponseMessagePtr& response) { http_call_response_ = &response; onHttpCallResponse(token, response->headers().size(), response->body()->length(), headerSize(response->trailers())); diff --git a/source/extensions/common/wasm/context.h b/source/extensions/common/wasm/context.h index 07082b9fba..64da6a35a1 100644 --- a/source/extensions/common/wasm/context.h +++ b/source/extensions/common/wasm/context.h @@ -193,19 +193,21 @@ class Context : public Logger::Loggable, // // Http::StreamDecoderFilter // - Http::FilterHeadersStatus decodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus decodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap& trailers) override; Http::FilterMetadataStatus decodeMetadata(Http::MetadataMap& metadata_map) override; void setDecoderFilterCallbacks(Envoy::Http::StreamDecoderFilterCallbacks& callbacks) override; // // Http::StreamEncoderFilter // - Http::FilterHeadersStatus encode100ContinueHeaders(Http::HeaderMap&) override; - Http::FilterHeadersStatus encodeHeaders(Http::HeaderMap& headers, bool end_stream) override; + Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override; + Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& headers, + bool end_stream) override; Http::FilterDataStatus encodeData(Buffer::Instance& data, bool end_stream) override; - Http::FilterTrailersStatus encodeTrailers(Http::HeaderMap& trailers) override; + Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap& trailers) override; Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap& metadata_map) override; void setEncoderFilterCallbacks(Envoy::Http::StreamEncoderFilterCallbacks& callbacks) override; @@ -333,7 +335,7 @@ class Context : public Logger::Loggable, struct AsyncClientHandler : public Http::AsyncClient::Callbacks { // Http::AsyncClient::Callbacks - void onSuccess(Envoy::Http::MessagePtr&& response) override { + void onSuccess(Envoy::Http::ResponseMessagePtr&& response) override { context_->onHttpCallSuccess(token_, response); } void onFailure(Http::AsyncClient::FailureReason reason) override { @@ -347,7 +349,7 @@ class Context : public Logger::Loggable, struct GrpcCallClientHandler : public Grpc::RawAsyncRequestCallbacks { // Grpc::AsyncRequestCallbacks - void onCreateInitialMetadata(Http::HeaderMap& metadata) override { + void onCreateInitialMetadata(Http::RequestHeaderMap& metadata) override { context_->onGrpcCreateInitialMetadata(token_, metadata); } void onSuccessRaw(Buffer::InstancePtr&& response, Tracing::Span& /* span */) override { @@ -366,17 +368,17 @@ class Context : public Logger::Loggable, struct GrpcStreamClientHandler : public Grpc::RawAsyncStreamCallbacks { // Grpc::AsyncStreamCallbacks - void onCreateInitialMetadata(Http::HeaderMap& metadata) override { + void onCreateInitialMetadata(Http::RequestHeaderMap& metadata) override { context_->onGrpcCreateInitialMetadata(token_, metadata); } - void onReceiveInitialMetadata(Http::HeaderMapPtr&& metadata) override { + void onReceiveInitialMetadata(Http::ResponseHeaderMapPtr&& metadata) override { context_->onGrpcReceiveInitialMetadata(token_, std::move(metadata)); } bool onReceiveMessageRaw(Buffer::InstancePtr&& response) override { context_->onGrpcReceive(token_, std::move(response)); return true; } - void onReceiveTrailingMetadata(Http::HeaderMapPtr&& metadata) override { + void onReceiveTrailingMetadata(Http::ResponseTrailerMapPtr&& metadata) override { context_->onGrpcReceiveTrailingMetadata(token_, std::move(metadata)); } void onRemoteClose(Grpc::Status::GrpcStatus status, const std::string& message) override { @@ -392,7 +394,7 @@ class Context : public Logger::Loggable, void initializeRoot(Wasm* wasm, PluginSharedPtr plugin); std::string makeRootLogPrefix(absl::string_view vm_id) const; - void onHttpCallSuccess(uint32_t token, Envoy::Http::MessagePtr& response); + void onHttpCallSuccess(uint32_t token, Envoy::Http::ResponseMessagePtr& response); void onHttpCallFailure(uint32_t token, Http::AsyncClient::FailureReason reason); virtual void onGrpcCreateInitialMetadata(uint32_t token, @@ -448,17 +450,17 @@ class Context : public Logger::Loggable, // HTTP filter state. // NB: this are only available (non-nullptr) during the calls corresponding to when the data is // live. For example, request_headers_ is available during the onRequestHeaders() call. - Http::HeaderMap* request_headers_{}; - Http::HeaderMap* response_headers_{}; + Http::RequestHeaderMap* request_headers_{}; + Http::ResponseHeaderMap* response_headers_{}; Buffer::Instance* request_body_buffer_{}; Buffer::Instance* response_body_buffer_{}; - Http::HeaderMap* request_trailers_{}; - Http::HeaderMap* response_trailers_{}; + Http::RequestTrailerMap* request_trailers_{}; + Http::ResponseTrailerMap* response_trailers_{}; Http::MetadataMap* request_metadata_{}; Http::MetadataMap* response_metadata_{}; // Only available during onHttpCallResponse. - Envoy::Http::MessagePtr* http_call_response_{}; + Envoy::Http::ResponseMessagePtr* http_call_response_{}; Http::HeaderMap* grpc_create_initial_metadata_{}; Http::HeaderMapPtr grpc_receive_initial_metadata_{}; diff --git a/test/stress/stress_test_upstream.h b/test/stress/stress_test_upstream.h index 2b2f61bfb9..3719356b59 100644 --- a/test/stress/stress_test_upstream.h +++ b/test/stress/stress_test_upstream.h @@ -131,7 +131,7 @@ class ServerConnection : public Network::ReadFilter, // Http::RequestDecoder& newStream(Http::ResponseEncoder& stream_encoder, - bool is_internally_created = false) override; + bool is_internally_created = false) override; // // Network::ConnectionCallbacks From cbd2535e537bca8f0c30bd550223bc10fb00ca25 Mon Sep 17 00:00:00 2001 From: gargnupur Date: Wed, 19 Feb 2020 13:06:38 -0800 Subject: [PATCH 83/87] Fix test --- .../filters/http/wasm/config_test.cc | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/test/extensions/filters/http/wasm/config_test.cc b/test/extensions/filters/http/wasm/config_test.cc index bdc3652e56..3a95f92920 100644 --- a/test/extensions/filters/http/wasm/config_test.cc +++ b/test/extensions/filters/http/wasm/config_test.cc @@ -171,10 +171,11 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteWASM) { .WillOnce(ReturnRef(cluster_manager_.async_client_)); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - Http::MessagePtr response(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response( + new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response->body() = std::make_unique(code); callbacks.onSuccess(std::move(response)); return nullptr; @@ -216,7 +217,7 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteConnectionReset) { .WillOnce(ReturnRef(cluster_manager_.async_client_)); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { callbacks.onFailure(Envoy::Http::AsyncClient::FailureReason::Reset); return nullptr; @@ -255,10 +256,11 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteSuccessWith503) { .WillOnce(ReturnRef(cluster_manager_.async_client_)); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - callbacks.onSuccess(Http::MessagePtr{new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "503"}}})}); + callbacks.onSuccess( + Http::ResponseMessagePtr{new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "503"}}})}); return nullptr; })); @@ -294,10 +296,11 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteSuccessIncorrectSha256) { .WillOnce(ReturnRef(cluster_manager_.async_client_)); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - Http::MessagePtr response(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response( + new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response->body() = std::make_unique(code); callbacks.onSuccess(std::move(response)); return nullptr; @@ -335,10 +338,11 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteSuccessBadcode) { .WillOnce(ReturnRef(cluster_manager_.async_client_)); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr&, Http::AsyncClient::Callbacks& callbacks, + Invoke([&](Http::RequestMessagePtr&, Http::AsyncClient::Callbacks& callbacks, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - Http::MessagePtr response(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response( + new Http::ResponseMessageImpl(Http::ResponseHeaderMapPtr{ + new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response->body() = std::make_unique(code); callbacks.onSuccess(std::move(response)); return nullptr; From cf29477ef916cb3d367c97a274c62511f777a995 Mon Sep 17 00:00:00 2001 From: gargnupur Date: Wed, 19 Feb 2020 14:09:11 -0800 Subject: [PATCH 84/87] Fix test Signed-off-by: gargnupur --- .../filters/http/wasm/wasm_filter_test.cc | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/test/extensions/filters/http/wasm/wasm_filter_test.cc b/test/extensions/filters/http/wasm/wasm_filter_test.cc index d3c37aaca2..eb44600f22 100644 --- a/test/extensions/filters/http/wasm/wasm_filter_test.cc +++ b/test/extensions/filters/http/wasm/wasm_filter_test.cc @@ -178,7 +178,7 @@ TEST_P(WasmHttpFilterTest, HeadersOnlyRequestHeadersOnly) { scriptLog_(spdlog::level::debug, Eq(absl::string_view("onRequestHeaders 2")))); EXPECT_CALL(*filter_, scriptLog_(spdlog::level::info, Eq(absl::string_view("header path /")))); EXPECT_CALL(*filter_, scriptLog_(spdlog::level::warn, Eq(absl::string_view("onDone 2")))); - Http::TestHeaderMapImpl request_headers{{":path", "/"}, {"server", "envoy"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}, {"server", "envoy"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); EXPECT_THAT(request_headers.get_("newheader"), Eq("newheadervalue")); EXPECT_THAT(request_headers.get_("server"), Eq("envoy-wasm")); @@ -196,7 +196,7 @@ TEST_P(WasmHttpFilterTest, HeadersOnlyRequestHeadersAndBody) { EXPECT_CALL(*filter_, scriptLog_(spdlog::level::err, Eq(absl::string_view("onRequestBody hello")))); EXPECT_CALL(*filter_, scriptLog_(spdlog::level::warn, Eq(absl::string_view("onDone 2")))); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, true)); @@ -216,7 +216,7 @@ TEST_P(WasmHttpFilterTest, AccessLog) { EXPECT_CALL(*filter_, scriptLog_(spdlog::level::warn, Eq(absl::string_view("onLog 2 /")))); EXPECT_CALL(*filter_, scriptLog_(spdlog::level::warn, Eq(absl::string_view("onDone 2")))); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, true)); @@ -230,21 +230,21 @@ TEST_P(WasmHttpFilterTest, AsyncCall) { "{{ test_rundir }}/test/extensions/filters/http/wasm/test_data/async_call_cpp.wasm"))); setupFilter(); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Http::MockAsyncClientRequest request(&cluster_manager_.async_client_); Http::AsyncClient::Callbacks* callbacks = nullptr; EXPECT_CALL(cluster_manager_, get(Eq("cluster"))); EXPECT_CALL(cluster_manager_, httpAsyncClientForCluster("cluster")); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& cb, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - EXPECT_EQ((Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/"}, - {":authority", "foo"}, - {"content-length", "11"}}), + EXPECT_EQ((Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/"}, + {":authority", "foo"}, + {"content-length", "11"}}), message->headers()); - EXPECT_EQ((Http::TestHeaderMapImpl{{"trail", "cow"}}), *message->trailers()); + EXPECT_EQ((Http::TestRequestTrailerMapImpl{{"trail", "cow"}}), *message->trailers()); callbacks = &cb; return &request; })); @@ -254,8 +254,8 @@ TEST_P(WasmHttpFilterTest, AsyncCall) { EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); - Http::MessagePtr response_message(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response_message->body().reset(new Buffer::OwnedImpl("response")); EXPECT_NE(callbacks, nullptr); @@ -269,21 +269,21 @@ TEST_P(WasmHttpFilterTest, AsyncCallAfterDestroyed) { "{{ test_rundir }}/test/extensions/filters/http/wasm/test_data/async_call_cpp.wasm"))); setupFilter(); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; Http::MockAsyncClientRequest request(&cluster_manager_.async_client_); Http::AsyncClient::Callbacks* callbacks = nullptr; EXPECT_CALL(cluster_manager_, get(Eq("cluster"))); EXPECT_CALL(cluster_manager_, httpAsyncClientForCluster("cluster")); EXPECT_CALL(cluster_manager_.async_client_, send_(_, _, _)) .WillOnce( - Invoke([&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& cb, + Invoke([&](Http::RequestMessagePtr& message, Http::AsyncClient::Callbacks& cb, const Http::AsyncClient::RequestOptions&) -> Http::AsyncClient::Request* { - EXPECT_EQ((Http::TestHeaderMapImpl{{":method", "POST"}, - {":path", "/"}, - {":authority", "foo"}, - {"content-length", "11"}}), + EXPECT_EQ((Http::TestRequestHeaderMapImpl{{":method", "POST"}, + {":path", "/"}, + {":authority", "foo"}, + {"content-length", "11"}}), message->headers()); - EXPECT_EQ((Http::TestHeaderMapImpl{{"trail", "cow"}}), *message->trailers()); + EXPECT_EQ((Http::TestRequestTrailerMapImpl{{"trail", "cow"}}), *message->trailers()); callbacks = &cb; return &request; })); @@ -298,8 +298,8 @@ TEST_P(WasmHttpFilterTest, AsyncCallAfterDestroyed) { plugin_.reset(); wasm_.reset(); - Http::MessagePtr response_message(new Http::ResponseMessageImpl( - Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + Http::ResponseMessagePtr response_message(new Http::ResponseMessageImpl( + Http::ResponseHeaderMapPtr{new Http::TestResponseHeaderMapImpl{{":status", "200"}}})); response_message->body().reset(new Buffer::OwnedImpl("response")); // (Don't) Make the callback on the destroyed VM. @@ -344,7 +344,7 @@ TEST_P(WasmHttpFilterTest, GrpcCall) { return std::move(client_factory); })); EXPECT_CALL(*root_context_, scriptLog_(spdlog::level::debug, Eq("response"))); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -394,7 +394,7 @@ TEST_P(WasmHttpFilterTest, GrpcCallAfterDestroyed) { .WillOnce(Invoke([&](const GrpcService&, Stats::Scope&, bool) -> Grpc::AsyncClientFactoryPtr { return std::move(client_factory); })); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_->decodeHeaders(request_headers, false)); @@ -456,7 +456,7 @@ TEST_P(WasmHttpFilterTest, Metadata) { scriptLog_(spdlog::level::info, Eq(absl::string_view("duration is 15000000")))); EXPECT_CALL(*filter_, scriptLog_(spdlog::level::info, Eq(absl::string_view("grpc service: test")))); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); Buffer::OwnedImpl data("hello"); EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, true)); @@ -478,7 +478,7 @@ TEST_F(WasmHttpFilterTest, NullPluginRequestHeadersOnly) { scriptLog_(spdlog::level::debug, Eq(absl::string_view("onRequestHeaders 2")))); EXPECT_CALL(*filter_, scriptLog_(spdlog::level::info, Eq(absl::string_view("header path /")))); EXPECT_CALL(*filter_, scriptLog_(spdlog::level::warn, Eq(absl::string_view("onDone 2")))); - Http::TestHeaderMapImpl request_headers{{":path", "/"}, {"server", "envoy"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}, {"server", "envoy"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); EXPECT_THAT(request_headers.get_("newheader"), Eq("newheadervalue")); EXPECT_THAT(request_headers.get_("server"), Eq("envoy-wasm")); @@ -517,7 +517,7 @@ TEST_F(WasmHttpFilterTest, NullVmResolver) { EXPECT_CALL(*filter_, scriptLog_(spdlog::level::warn, Eq(absl::string_view("state: wasm_value")))); - Http::TestHeaderMapImpl request_headers{{":path", "/test_context"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/test_context"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); StreamInfo::MockStreamInfo log_stream_info; filter_->log(&request_headers, nullptr, nullptr, log_stream_info); @@ -533,7 +533,7 @@ TEST_P(WasmHttpFilterTest, SharedData) { EXPECT_CALL(*filter_, scriptLog_(spdlog::level::warn, Eq(absl::string_view("get 2 shared_data_value2")))); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); StreamInfo::MockStreamInfo log_stream_info; filter_->log(&request_headers, nullptr, nullptr, log_stream_info); @@ -549,7 +549,7 @@ TEST_P(WasmHttpFilterTest, SharedQueue) { scriptLog_(spdlog::level::info, Eq(absl::string_view("onQueueReady")))); EXPECT_CALL(*root_context_, scriptLog_(spdlog::level::debug, Eq(absl::string_view("data data1 Ok")))); - Http::TestHeaderMapImpl request_headers{{":path", "/"}}; + Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}}; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); auto token = Common::Wasm::resolveQueueForTest("vm_id", "my_shared_queue"); wasm_->wasm()->queueReady(root_context_->id(), token); @@ -560,7 +560,7 @@ TEST_P(WasmHttpFilterTest, RootIdNotRegistered) { setupConfig(TestEnvironment::readFileToStringForTest(TestEnvironment::substitute( "{{ test_rundir }}/test/extensions/filters/http/wasm/test_data/root_id_cpp.wasm"))); setupFilter(); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); } @@ -573,7 +573,7 @@ TEST_P(WasmHttpFilterTest, RootId1) { setupFilter("context1"); EXPECT_CALL(*filter_, scriptLog_(spdlog::level::debug, Eq(absl::string_view("onRequestHeaders1 2")))); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); } @@ -586,7 +586,7 @@ TEST_P(WasmHttpFilterTest, RootId2) { setupFilter("context2"); EXPECT_CALL(*filter_, scriptLog_(spdlog::level::debug, Eq(absl::string_view("onRequestHeaders2 2")))); - Http::TestHeaderMapImpl request_headers; + Http::TestRequestHeaderMapImpl request_headers; EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true)); } From d909dc92fe2320951b0a3be458ef980ec7f71a23 Mon Sep 17 00:00:00 2001 From: gargnupur Date: Wed, 19 Feb 2020 14:46:26 -0800 Subject: [PATCH 85/87] Fix tests Signed-off-by: gargnupur --- .../http/wasm/wasm_filter_stress_test.cc | 35 ++++++++-------- test/stress/stress_test_downstream.cc | 11 ++--- test/stress/stress_test_downstream.h | 10 +++-- test/stress/stress_test_self_test.cc | 41 ++++++++++--------- test/stress/stress_test_upstream.cc | 7 ++-- test/stress/stress_test_upstream.h | 2 +- 6 files changed, 56 insertions(+), 50 deletions(-) diff --git a/test/extensions/filters/http/wasm/wasm_filter_stress_test.cc b/test/extensions/filters/http/wasm/wasm_filter_stress_test.cc index ab94042050..6a0da52838 100644 --- a/test/extensions/filters/http/wasm/wasm_filter_stress_test.cc +++ b/test/extensions/filters/http/wasm/wasm_filter_stress_test.cc @@ -88,14 +88,14 @@ TEST_P(GrpcWasmStressTest, CalloutHappyPath) { addCluster(std::make_unique(StressTest::ORIGIN_CLUSTER_NAME)) .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::HeaderMapPtr&&) { + [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { ENVOY_LOG(debug, "Origin server received request"); - Http::TestHeaderMapImpl response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response{{":status", "200"}}; stream.sendResponseHeaders(response); })); addCluster(std::make_unique(callout_cluster_name)) .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::HeaderMapPtr&&) { + [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { ENVOY_LOG(debug, "Callout server received request"); ProtobufWkt::Value response; response.set_string_value("response"); @@ -118,7 +118,7 @@ TEST_P(GrpcWasmStressTest, CalloutHappyPath) { // Exec test and wait for it to finish // - Http::HeaderMapPtr request{new Http::TestHeaderMapImpl{ + Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; client->run(connections_to_initiate, requests_to_send, std::move(request)); @@ -195,14 +195,14 @@ TEST_P(GrpcWasmStressTest, CalloutErrorResponse) { addCluster(std::make_unique(StressTest::ORIGIN_CLUSTER_NAME)) .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::HeaderMapPtr&&) { + [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { ENVOY_LOG(debug, "Origin server received request"); - Http::TestHeaderMapImpl response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response{{":status", "200"}}; stream.sendResponseHeaders(response); })); addCluster(std::make_unique(callout_cluster_name)) .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::HeaderMapPtr&&) { + [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { ENVOY_LOG(debug, "Callout server received request"); ProtobufWkt::Value response; response.set_string_value("response"); @@ -225,7 +225,7 @@ TEST_P(GrpcWasmStressTest, CalloutErrorResponse) { // Exec test and wait for it to finish // - Http::HeaderMapPtr request{new Http::TestHeaderMapImpl{ + Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; client->run(connections_to_initiate, requests_to_send, std::move(request)); @@ -306,16 +306,16 @@ TEST_P(HttpWasmStressTest, DISABLED_CalloutHappyPath) { // addCluster(std::make_unique(StressTest::ORIGIN_CLUSTER_NAME)) .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::HeaderMapPtr&&) { + [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { ENVOY_LOG(debug, "Origin server received request"); - Http::TestHeaderMapImpl response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response{{":status", "200"}}; stream.sendResponseHeaders(response); })); addCluster(std::make_unique(callout_cluster_name)) .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::HeaderMapPtr&&) { + [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { ENVOY_LOG(debug, "Callout server received request"); - Http::TestHeaderMapImpl response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response{{":status", "200"}}; stream.sendResponseHeaders(response); })); @@ -339,11 +339,12 @@ TEST_P(HttpWasmStressTest, DISABLED_CalloutHappyPath) { fmt::format("http://{}:{}/", Network::Test::getLoopbackAddressString(ipVersion()), firstPortInCluster(callout_cluster_name)); - Http::HeaderMapPtr request{new Http::TestHeaderMapImpl{{":method", "GET"}, - {":path", "/"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-callout-url", callout_url}}}; + Http::RequestHeaderMapPtr request{ + new Http::TestRequestHeaderMapImpl{{":method", "GET"}, + {":path", "/"}, + {":scheme", "http"}, + {":authority", "host"}, + {"x-callout-url", callout_url}}}; client->run(connections_to_initiate, requests_to_send, std::move(request)); // diff --git a/test/stress/stress_test_downstream.cc b/test/stress/stress_test_downstream.cc index 06931b6117..4f559f0bf8 100644 --- a/test/stress/stress_test_downstream.cc +++ b/test/stress/stress_test_downstream.cc @@ -120,7 +120,7 @@ class ClientStream : public Http::ResponseDecoder, connection_.id(), id_); } - virtual void sendRequest(const Http::HeaderMap& request_headers, + virtual void sendRequest(const Http::RequestHeaderMap& request_headers, const std::chrono::milliseconds timeout) { if (connection_.networkConnection().state() != Network::Connection::State::Open) { ENVOY_LOG(warn, "ClientStream({}:{}:{})'s underlying connection is not open!", @@ -356,7 +356,8 @@ void ClientConnection::onGoAway() { ENVOY_LOG(warn, "ClientConnection({}:{}) remote closed", client_.name(), id_); } -void ClientConnection::sendRequest(const Http::HeaderMap& headers, ClientResponseCallback& callback, +void ClientConnection::sendRequest(const Http::RequestHeaderMap& headers, + ClientResponseCallback& callback, std::chrono::milliseconds timeout) { newStream(callback).sendRequest(headers, timeout); } @@ -458,7 +459,7 @@ LoadGenerator::LoadGenerator(Client& client, Network::TransportSocketFactory& so const Network::ConnectionSocket::OptionsSharedPtr& sockopts) : client_(client), socket_factory_(socket_factory), http_version_(http_version), address_(address), sockopts_(sockopts) { - response_callback_ = [this](ClientConnection& connection, Http::HeaderMapPtr&& response) { + response_callback_ = [this](ClientConnection& connection, Http::ResponseHeaderMapPtr&& response) { if (!response) { ENVOY_LOG(debug, "Connection({}:{}) timedout waiting for response", connection.name(), connection.id()); @@ -533,8 +534,8 @@ LoadGenerator::LoadGenerator(Client& client, Network::TransportSocketFactory& so }; } -void LoadGenerator::run(uint32_t connections, uint32_t requests, Http::HeaderMapPtr&& request, - std::chrono::milliseconds timeout) { +void LoadGenerator::run(uint32_t connections, uint32_t requests, + Http::RequestHeaderMapPtr&& request, std::chrono::milliseconds timeout) { connections_to_initiate_ = connections; requests_to_send_ = requests; request_ = std::move(request); diff --git a/test/stress/stress_test_downstream.h b/test/stress/stress_test_downstream.h index 1a576e5820..11960c3c5c 100644 --- a/test/stress/stress_test_downstream.h +++ b/test/stress/stress_test_downstream.h @@ -77,7 +77,8 @@ typedef std::function +typedef std::function ClientResponseCallback; class ClientConnection : public Network::ConnectionCallbacks, @@ -111,7 +112,8 @@ class ClientConnection : public Network::ConnectionCallbacks, * @param request_headers * @param callback */ - virtual void sendRequest(const Http::HeaderMap& request_headers, ClientResponseCallback& callback, + virtual void sendRequest(const Http::RequestHeaderMap& request_headers, + ClientResponseCallback& callback, std::chrono::milliseconds timeout = std::chrono::milliseconds(5'000)); /** @@ -242,7 +244,7 @@ class LoadGenerator : Logger::Loggable { * @param timeout The time in msec to wait to receive a response after sending * each request. */ - void run(uint32_t connections, uint32_t requests, Http::HeaderMapPtr&& request, + void run(uint32_t connections, uint32_t requests, Http::RequestHeaderMapPtr&& request, std::chrono::milliseconds timeout = std::chrono::milliseconds(5'000)); uint32_t connectFailures() const; @@ -258,7 +260,7 @@ class LoadGenerator : Logger::Loggable { private: uint32_t connections_to_initiate_{0}; uint32_t requests_to_send_{0}; - Http::HeaderMapPtr request_{}; + Http::RequestHeaderMapPtr request_{}; Client& client_; Network::TransportSocketFactory& socket_factory_; Http::CodecClient::Type http_version_; diff --git a/test/stress/stress_test_self_test.cc b/test/stress/stress_test_self_test.cc index 54a40107ff..7807047981 100644 --- a/test/stress/stress_test_self_test.cc +++ b/test/stress/stress_test_self_test.cc @@ -53,18 +53,19 @@ TEST_P(StressTestSelfTest, HappyPath) { try { // Take a really long time (500 msec) to send a 200 OK response. - ServerCallbackHelper server_callbacks( - [use_grpc = use_grpc_](ServerConnection&, ServerStream& stream, Http::HeaderMapPtr&&) { - if (use_grpc) { - ProtobufWkt::Value response; - response.set_string_value("response"); - stream.sendGrpcResponse(Grpc::Status::Ok, response); - return; - } - - Http::TestHeaderMapImpl response{{":status", "200"}}; - stream.sendResponseHeaders(response); - }); + ServerCallbackHelper server_callbacks([use_grpc = use_grpc_](ServerConnection&, + ServerStream& stream, + Http::RequestHeaderMapPtr&&) { + if (use_grpc) { + ProtobufWkt::Value response; + response.set_string_value("response"); + stream.sendGrpcResponse(Grpc::Status::Ok, response); + return; + } + + Http::TestResponseHeaderMapImpl response{{":status", "200"}}; + stream.sendResponseHeaders(response); + }); server_.start(server_callbacks); // @@ -78,7 +79,7 @@ TEST_P(StressTestSelfTest, HappyPath) { // Exec test and wait for it to finish // - Http::HeaderMapPtr request{new Http::TestHeaderMapImpl{ + Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; load_generator.run(connections_to_initiate, requests_to_send, std::move(request)); @@ -134,7 +135,7 @@ TEST_P(StressTestSelfTest, AcceptAndClose) { try { // Immediately close any connection accepted. ServerCallbackHelper server_callbacks( - [](ServerConnection&, ServerStream&, Http::HeaderMapPtr&&) { + [](ServerConnection&, ServerStream&, Http::RequestHeaderMapPtr&&) { GTEST_FATAL_FAILURE_("Connections immediately closed so no response should be received"); }, [](ServerConnection&) -> ServerCallbackResult { return ServerCallbackResult::CLOSE; }); @@ -152,7 +153,7 @@ TEST_P(StressTestSelfTest, AcceptAndClose) { // Exec test and wait for it to finish // - Http::HeaderMapPtr request{new Http::TestHeaderMapImpl{ + Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; load_generator.run(connections_to_initiate, requests_to_send, std::move(request)); @@ -202,8 +203,8 @@ TEST_P(StressTestSelfTest, SlowResponse) { try { // Take a really long time (500 msec) to send a 200 OK response. ServerCallbackHelper server_callbacks( - [](ServerConnection&, ServerStream& stream, Http::HeaderMapPtr&&) { - Http::TestHeaderMapImpl response{{":status", "200"}}; + [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { + Http::TestResponseHeaderMapImpl response{{":status", "200"}}; stream.sendResponseHeaders(response, std::chrono::milliseconds(500)); }); @@ -220,7 +221,7 @@ TEST_P(StressTestSelfTest, SlowResponse) { // Exec test and wait for it to finish // - Http::HeaderMapPtr request{new Http::TestHeaderMapImpl{ + Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; load_generator.run(connections_to_initiate, requests_to_send, std::move(request), std::chrono::milliseconds(250)); @@ -283,7 +284,7 @@ TEST_P(StressTestSelfTest, NoServer) { // Exec test and wait for it to finish // - Http::HeaderMapPtr request{new Http::TestHeaderMapImpl{ + Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; load_generator.run(connections_to_initiate, requests_to_send, std::move(request)); @@ -338,7 +339,7 @@ TEST_P(StressTestSelfTest, NoAccept) { // Exec test and wait for it to finish // - Http::HeaderMapPtr request{new Http::TestHeaderMapImpl{ + Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; load_generator.run(connections_to_initiate, requests_to_send, std::move(request), std::chrono::milliseconds(250)); diff --git a/test/stress/stress_test_upstream.cc b/test/stress/stress_test_upstream.cc index 9bd9f3d8dc..f87896227f 100644 --- a/test/stress/stress_test_upstream.cc +++ b/test/stress/stress_test_upstream.cc @@ -403,14 +403,15 @@ ServerCallbackHelper::ServerCallbackHelper(ServerRequestCallback&& request_callb if (request_callback) { request_callback_ = [this, request_callback = std::move(request_callback)]( ServerConnection& connection, ServerStream& stream, - Http::HeaderMapPtr&& request_headers) { + Http::RequestHeaderMapPtr&& request_headers) { ++requests_received_; request_callback(connection, stream, std::move(request_headers)); }; } else { - request_callback_ = [this](ServerConnection&, ServerStream& stream, Http::HeaderMapPtr&&) { + request_callback_ = [this](ServerConnection&, ServerStream& stream, + Http::RequestHeaderMapPtr&&) { ++requests_received_; - Http::TestHeaderMapImpl response{{":status", "200"}}; + Http::TestResponseHeaderMapImpl response{{":status", "200"}}; stream.sendResponseHeaders(response); }; } diff --git a/test/stress/stress_test_upstream.h b/test/stress/stress_test_upstream.h index 3719356b59..61508c3de0 100644 --- a/test/stress/stress_test_upstream.h +++ b/test/stress/stress_test_upstream.h @@ -76,7 +76,7 @@ typedef std::function typedef std::function ServerCloseCallback; typedef std::function + Http::RequestHeaderMapPtr&& request_headers)> ServerRequestCallback; class ServerConnection : public Network::ReadFilter, From ce15882a5d35ccf923eb92462d5ebfdb5d9f204c Mon Sep 17 00:00:00 2001 From: gargnupur Date: Wed, 19 Feb 2020 20:05:48 -0800 Subject: [PATCH 86/87] Remove wasm filter stress test Signed-off-by: gargnupur --- test/extensions/filters/http/wasm/BUILD | 19 - .../http/wasm/wasm_filter_stress_test.cc | 383 ------------------ 2 files changed, 402 deletions(-) delete mode 100644 test/extensions/filters/http/wasm/wasm_filter_stress_test.cc diff --git a/test/extensions/filters/http/wasm/BUILD b/test/extensions/filters/http/wasm/BUILD index c093b07acc..45e51a45ed 100644 --- a/test/extensions/filters/http/wasm/BUILD +++ b/test/extensions/filters/http/wasm/BUILD @@ -56,22 +56,3 @@ envoy_extension_cc_test( "@envoy_api//envoy/extensions/filters/http/wasm/v3:pkg_cc_proto", ], ) - -envoy_extension_cc_test( - name = "wasm_filter_stress_test", - size = "large", - srcs = ["wasm_filter_stress_test.cc"], - data = [ - "//test/extensions/filters/http/wasm/test_data:modules", - ], - extension_name = "envoy.filters.http.wasm", - external_deps = ["abseil_optional"], - deps = [ - "//source/extensions/common/wasm:wasm_lib", - "//source/extensions/filters/http/wasm:config", - "//source/extensions/wasm:config", - "//test/proto:helloworld_proto_cc_proto", - "//test/stress:stress_test_lib", - "//test/test_common:environment_lib", - ], -) diff --git a/test/extensions/filters/http/wasm/wasm_filter_stress_test.cc b/test/extensions/filters/http/wasm/wasm_filter_stress_test.cc deleted file mode 100644 index 6a0da52838..0000000000 --- a/test/extensions/filters/http/wasm/wasm_filter_stress_test.cc +++ /dev/null @@ -1,383 +0,0 @@ -#include "envoy/server/wasm_config.h" - -#include "test/stress/stress_test.h" - -using namespace Envoy::Stress; - -namespace Envoy { -namespace Extensions { -namespace Wasm { - -static const std::string STAT_PREFIX{"wasm_filter_stress_test"}; - -class WasmStressTest : public Stress::StressTest, - public testing::TestWithParam< - std::tuple> { -public: - WasmStressTest() - : StressTest(::ipVersion(std::get<3>(GetParam())), ::httpType(std::get<2>(GetParam()))), - wasm_vm_{std::get<0>(GetParam())}, wasm_lang_{std::get<1>(GetParam())} {} - - const std::string& wasmVM() const { return wasm_vm_; } - - const std::string& wasmLang() const { return wasm_lang_; } - -private: - std::string wasm_vm_; - std::string wasm_lang_; -}; - -class GrpcWasmStressTest : public WasmStressTest {}; - -class HttpWasmStressTest : public WasmStressTest {}; - -INSTANTIATE_TEST_SUITE_P(RuntimesAndLanguages, GrpcWasmStressTest, - testing::Combine(testing::Values("envoy.wasm.runtime.v8" -#if defined(ENVOY_WASM_WAVM) - , - "envoy.wasm.runtime.wavm" -#endif - ), - testing::Values("cpp"), testing::Values("http2"), - testing::Values("IPv4", "IPv6"))); - -INSTANTIATE_TEST_SUITE_P(RuntimesAndLanguages, HttpWasmStressTest, - testing::Combine(testing::Values("envoy.wasm.runtime.v8" -#if defined(ENVOY_WASM_WAVM) - , - "envoy.wasm.runtime.wavm" -#endif - ), - testing::Values("cpp"), testing::Values("http1", "http2"), - testing::Values("IPv4", "IPv6"))); - -TEST_P(GrpcWasmStressTest, CalloutHappyPath) { - constexpr uint32_t connections_to_initiate = 30; - constexpr uint32_t requests_to_send = 30 * connections_to_initiate; - const std::string wasm_file = TestEnvironment::runfilesPath(absl::StrCat( - "test/extensions/filters/http/wasm/test_data/grpc_callout_", wasmLang(), ".wasm")); - // Must match cluster name in the wasm bundle: - const std::string callout_cluster_name{"callout_cluster"}; - - // - // Configure the wasm filter - // - - config_helper_.addFilter(fmt::format(R"EOF( - name: envoy.filters.http.wasm - typed_config: - "@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm - config: - vm_config: - runtime: "{}" - code: - local: - filename: "{}" -)EOF", - wasmVM(), wasm_file)); - - // - // This test first sends a request from wasm to a callout cluster: - // Client -> Envoy -> Wasm -> Callout Cluster - // Envoy then unconditionally forwards the request to the origin cluster - // Envoy -> Origin Cluster - // - // Both Callout and Origin clusters have a single server that immediately - // returns a 200 OK response. - // - - addCluster(std::make_unique(StressTest::ORIGIN_CLUSTER_NAME)) - .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { - ENVOY_LOG(debug, "Origin server received request"); - Http::TestResponseHeaderMapImpl response{{":status", "200"}}; - stream.sendResponseHeaders(response); - })); - addCluster(std::make_unique(callout_cluster_name)) - .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { - ENVOY_LOG(debug, "Callout server received request"); - ProtobufWkt::Value response; - response.set_string_value("response"); - stream.sendGrpcResponse(Grpc::Status::Ok, response); - })); - - try { - bind(); - } catch (Network::SocketBindException& ex) { - if (Network::Address::IpVersion::v6 == ipVersion()) { - ENVOY_LOG(info, "Environment does not support IPv6, skipping test"); - GTEST_SKIP(); - } - throw ex; - } - - LoadGeneratorPtr client = start(); - - // - // Exec test and wait for it to finish - // - - Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ - {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; - client->run(connections_to_initiate, requests_to_send, std::move(request)); - - CounterMap counters; - extractCounters(counters); - - // - // Block until all servers exit - // - - stopServers(); - - // - // Evaluate test - // - - // All client connections are successfully established. - EXPECT_EQ(client->connectSuccesses(), connections_to_initiate); - EXPECT_EQ(client->connectFailures(), 0); - // Client close callback called for every client connection. - EXPECT_EQ(client->localCloses(), connections_to_initiate); - // Client response callback is called for every request sent - EXPECT_EQ(client->responsesReceived(), requests_to_send); - // Every response was a 2xx class - EXPECT_EQ(client->class2xxResponses(), requests_to_send); - EXPECT_EQ(client->class4xxResponses(), 0); - EXPECT_EQ(client->class5xxResponses(), 0); - EXPECT_EQ(client->responseTimeouts(), 0); - // No client sockets are rudely closed by server / no client sockets are - // reset. - EXPECT_EQ(client->remoteCloses(), 0); - - // assert that the callout server and origin server see every request - EXPECT_EQ(findCluster(StressTest::ORIGIN_CLUSTER_NAME).requestsReceived(), requests_to_send); - EXPECT_EQ(findCluster(callout_cluster_name).requestsReceived(), requests_to_send); - - // dumpCounters(counters); - - // And the wasm filter should have successfully created the callout_successes - // counter and received a successful gRPC response for every inbound request. - EXPECT_EQ(counters["test_callout_successes"], requests_to_send); -} - -TEST_P(GrpcWasmStressTest, CalloutErrorResponse) { - constexpr uint32_t connections_to_initiate = 30; - constexpr uint32_t requests_to_send = 30 * connections_to_initiate; - const std::string wasm_file = TestEnvironment::runfilesPath(absl::StrCat( - "test/extensions/filters/http/wasm/test_data/grpc_callout_", wasmLang(), ".wasm")); - // Must match cluster name in the wasm bundle: - const std::string callout_cluster_name{"callout_cluster"}; - - // - // Configure the wasm filter - // - - config_helper_.addFilter(fmt::format(R"EOF( - name: envoy.filters.http.wasm - config: - config: - vm_config: - runtime: "{}" - code: - local: - filename: "{}" -)EOF", - wasmVM(), wasm_file)); - - // - // This test first sends a request from wasm to a callout cluster: - // Client -> Envoy -> Wasm -> Callout Cluster - // The callout cluster sends an error response which prevents Envoy from - // forwarding the data plane request to the origin cluster. - // - - addCluster(std::make_unique(StressTest::ORIGIN_CLUSTER_NAME)) - .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { - ENVOY_LOG(debug, "Origin server received request"); - Http::TestResponseHeaderMapImpl response{{":status", "200"}}; - stream.sendResponseHeaders(response); - })); - addCluster(std::make_unique(callout_cluster_name)) - .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { - ENVOY_LOG(debug, "Callout server received request"); - ProtobufWkt::Value response; - response.set_string_value("response"); - stream.sendGrpcResponse(Grpc::Status::PermissionDenied, response); - })); - - try { - bind(); - } catch (Network::SocketBindException& ex) { - if (Network::Address::IpVersion::v6 == ipVersion()) { - ENVOY_LOG(info, "Environment does not support IPv6, skipping test"); - GTEST_SKIP(); - } - throw ex; - } - - LoadGeneratorPtr client = start(); - - // - // Exec test and wait for it to finish - // - - Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ - {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; - client->run(connections_to_initiate, requests_to_send, std::move(request)); - - CounterMap counters; - extractCounters(counters); - - // - // Block until all servers exit - // - - stopServers(); - - // - // Evaluate test - // - - // All client connections are successfully established. - EXPECT_EQ(client->connectSuccesses(), connections_to_initiate); - EXPECT_EQ(client->connectFailures(), 0); - // Client close callback called for every client connection. - EXPECT_EQ(client->localCloses(), connections_to_initiate); - // Client response callback is called for every request sent - EXPECT_EQ(client->responsesReceived(), requests_to_send); - // Every response was a 5xx class - EXPECT_EQ(client->class2xxResponses(), 0); - EXPECT_EQ(client->class4xxResponses(), 0); - EXPECT_EQ(client->class5xxResponses(), requests_to_send); - EXPECT_EQ(client->responseTimeouts(), 0); - // No client sockets are rudely closed by server / no client sockets are - // reset. - EXPECT_EQ(client->remoteCloses(), 0); - - // assert that the callout server saw every request and prevented the - // origin server from seeing it. - EXPECT_EQ(findCluster(StressTest::ORIGIN_CLUSTER_NAME).requestsReceived(), 0); - EXPECT_EQ(findCluster(callout_cluster_name).requestsReceived(), requests_to_send); - - // And the wasm filter should have successfully created the failure - // counter and received a gRPC error response for every inbound request. - EXPECT_EQ(counters["test_callout_failures"], requests_to_send); -} - -// TODO fix test. Currently fails with a: -// terminate called after throwing an instance of 'Extensions::Common::Wasm::WasmException' -// what(): emscripten cxa_allocate_exception -TEST_P(HttpWasmStressTest, DISABLED_CalloutHappyPath) { - constexpr uint32_t connections_to_initiate = 30; - constexpr uint32_t requests_to_send = 30 * connections_to_initiate; - const std::string wasm_vm{std::get<0>(GetParam())}; - const std::string wasm_file = TestEnvironment::runfilesPath( - absl::StrCat("test/extensions/filters/http/wasm/test_data/http_callout_", - std::get<1>(GetParam()), ".wasm")); - const std::string callout_cluster_name{"callout_cluster"}; - - // - // Configure the wasm filter - // - - config_helper_.addFilter(fmt::format(R"EOF( - name: envoy.filters.http.wasm - config: - config: - vm_config: - runtime: "{}" - code: - filename: "{}" -)EOF", - wasm_vm, wasm_file)); - - // - // This test first sends a request from wasm to a callout cluster: - // Client -> Envoy -> Wasm -> Callout Cluster - // Envoy then unconditionally forwards the request to the origin cluster - // Envoy -> Origin Cluster - // - // Both Callout and Origin clusters have a single server that immediately - // returns a 200 OK response. - // - addCluster(std::make_unique(StressTest::ORIGIN_CLUSTER_NAME)) - .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { - ENVOY_LOG(debug, "Origin server received request"); - Http::TestResponseHeaderMapImpl response{{":status", "200"}}; - stream.sendResponseHeaders(response); - })); - addCluster(std::make_unique(callout_cluster_name)) - .addServer(std::make_unique( - [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { - ENVOY_LOG(debug, "Callout server received request"); - Http::TestResponseHeaderMapImpl response{{":status", "200"}}; - stream.sendResponseHeaders(response); - })); - - try { - bind(); - } catch (Network::SocketBindException& ex) { - if (Network::Address::IpVersion::v6 == ipVersion()) { - ENVOY_LOG(info, "Environment does not support IPv6, skipping test"); - GTEST_SKIP(); - } - throw ex; - } - - LoadGeneratorPtr client = start(); - - // - // Exec test and wait for it to finish (pass callout URL to wasm via http header) - // - - std::string callout_url = - fmt::format("http://{}:{}/", Network::Test::getLoopbackAddressString(ipVersion()), - firstPortInCluster(callout_cluster_name)); - - Http::RequestHeaderMapPtr request{ - new Http::TestRequestHeaderMapImpl{{":method", "GET"}, - {":path", "/"}, - {":scheme", "http"}, - {":authority", "host"}, - {"x-callout-url", callout_url}}}; - client->run(connections_to_initiate, requests_to_send, std::move(request)); - - // - // Block until all servers exit - // - - stopServers(); - - // - // Evaluate test - // - - // All client connections are successfully established. - EXPECT_EQ(client->connectSuccesses(), connections_to_initiate); - EXPECT_EQ(client->connectFailures(), 0); - // Client close callback called for every client connection. - EXPECT_EQ(client->localCloses(), connections_to_initiate); - // Client response callback is called for every request sent - EXPECT_EQ(client->responsesReceived(), requests_to_send); - // Every response was a 2xx class - EXPECT_EQ(client->class2xxResponses(), requests_to_send); - EXPECT_EQ(client->class4xxResponses(), 0); - EXPECT_EQ(client->class5xxResponses(), 0); - EXPECT_EQ(client->responseTimeouts(), 0); - // No client sockets are rudely closed by server / no client sockets are - // reset. - EXPECT_EQ(client->remoteCloses(), 0); - - // assert that the callout server and origin server see every request - EXPECT_EQ(findCluster(StressTest::ORIGIN_CLUSTER_NAME).requestsReceived(), requests_to_send); - EXPECT_EQ(findCluster(callout_cluster_name).requestsReceived(), requests_to_send); -} - -} // namespace Wasm -} // namespace Extensions -} // namespace Envoy From ff36099a5def965a8d398062b0c2715a6a3b984c Mon Sep 17 00:00:00 2001 From: gargnupur Date: Wed, 19 Feb 2020 20:12:28 -0800 Subject: [PATCH 87/87] Remove wasm stress test framework Signed-off-by: gargnupur --- test/stress/BUILD | 40 -- test/stress/stress_test.cc | 206 -------- test/stress/stress_test.h | 96 ---- test/stress/stress_test_common.cc | 35 -- test/stress/stress_test_common.h | 18 - test/stress/stress_test_downstream.cc | 576 ---------------------- test/stress/stress_test_downstream.h | 290 ----------- test/stress/stress_test_self_test.cc | 379 --------------- test/stress/stress_test_upstream.cc | 676 -------------------------- test/stress/stress_test_upstream.h | 424 ---------------- 10 files changed, 2740 deletions(-) delete mode 100644 test/stress/BUILD delete mode 100644 test/stress/stress_test.cc delete mode 100644 test/stress/stress_test.h delete mode 100644 test/stress/stress_test_common.cc delete mode 100644 test/stress/stress_test_common.h delete mode 100644 test/stress/stress_test_downstream.cc delete mode 100644 test/stress/stress_test_downstream.h delete mode 100644 test/stress/stress_test_self_test.cc delete mode 100644 test/stress/stress_test_upstream.cc delete mode 100644 test/stress/stress_test_upstream.h diff --git a/test/stress/BUILD b/test/stress/BUILD deleted file mode 100644 index 7b1098f1cc..0000000000 --- a/test/stress/BUILD +++ /dev/null @@ -1,40 +0,0 @@ -licenses(["notice"]) # Apache 2 - -load( - "//bazel:envoy_build_system.bzl", - "envoy_cc_test", - "envoy_cc_test_library", - "envoy_package", -) - -envoy_package() - -envoy_cc_test_library( - name = "stress_test_lib", - srcs = [ - "stress_test.cc", - "stress_test_common.cc", - "stress_test_downstream.cc", - "stress_test_upstream.cc", - ], - hdrs = [ - "stress_test.h", - "stress_test_common.h", - "stress_test_downstream.h", - "stress_test_upstream.h", - ], - deps = [ - "//source/server:server_lib", - "//test/integration:http_protocol_integration_lib", - ], -) - -envoy_cc_test( - name = "stress_test_self_test", - srcs = [ - "stress_test_self_test.cc", - ], - deps = [ - ":stress_test_lib", - ], -) diff --git a/test/stress/stress_test.cc b/test/stress/stress_test.cc deleted file mode 100644 index e440c5af75..0000000000 --- a/test/stress/stress_test.cc +++ /dev/null @@ -1,206 +0,0 @@ -#include "stress_test.h" - -#include "stress_test_upstream.h" - -namespace Envoy { -namespace Stress { - -const std::string StressTest::ORIGIN_CLUSTER_NAME{"origin_cluster"}; - -static const std::string BOOTSTRAP_CONFIG = R"EOF( -admin: - access_log_path: /dev/null - address: - socket_address: - address: {} - port_value: 0 -dynamic_resources: - lds_config: - path: /dev/null -static_resources: - listeners: - name: listener_0 - address: - socket_address: - address: {} - port_value: 0 - filter_chains: - filters: - name: envoy.http_connection_manager - typed_config: - "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager - stat_prefix: config_test - http_filters: - name: envoy.router - codec_type: auto - access_log: - name: envoy.file_access_log - filter: - not_health_check_filter: {{}} - config: - path: /dev/null - route_config: - virtual_hosts: - name: integration - routes: - route: - cluster: {} - match: - prefix: "/" - domains: "*" - name: route_config_0 -)EOF"; - -std::string StressTest::baseBootstrap(Network::Address::IpVersion ip_version) { - return fmt::format(BOOTSTRAP_CONFIG, Network::Test::getLoopbackAddressString(ip_version), - Network::Test::getLoopbackAddressString(ip_version), ORIGIN_CLUSTER_NAME); -} - -ClusterHelper& StressTest::addCluster(ClusterHelperPtr&& cluster_helper) { - const std::string& name = cluster_helper->name(); - auto it = clusters_.emplace(std::make_pair( - name, std::make_unique(std::move(cluster_helper), transport_socket_factory_, - ip_version_, http_type_))); - - if (!it.second) { - throw EnvoyException(fmt::format("Duplicate cluster named '{}'", name)); - } - - return it.first->second->clusterHelper(); -} - -void StressTest::bind() { - for (auto& it : clusters_) { - it.second->bind(); - } -} - -LoadGeneratorPtr StressTest::start() { - { - const auto& it = clusters_.find(ORIGIN_CLUSTER_NAME); - if (it == clusters_.end()) { - throw EnvoyException(fmt::format("One cluster must be named '{}'", ORIGIN_CLUSTER_NAME)); - } - } - - for (auto& it : clusters_) { - it.second->start(); - it.second->addClusterToBootstrap(config_helper_, ports_); - } - - setUpstreamProtocol(Http::CodecClient::Type::HTTP2 == http_type_ - ? FakeHttpConnection::Type::HTTP2 - : FakeHttpConnection::Type::HTTP1); - // Start envoy - HttpIntegrationTest::initialize(); - - ENVOY_LOG(debug, "Bootstrap Config:\n{}", - MessageUtil::getYamlStringFromMessage(config_helper_.bootstrap(), true)); - - Network::Address::InstanceConstSharedPtr address{ - loopbackAddress(ip_version_, lookupPort("http"))}; - return std::make_unique(client_, transport_socket_factory_, http_type_, address); -} - -uint16_t StressTest::firstPortInCluster(const std::string& cluster_name) const { - const auto& it = clusters_.find(cluster_name); - return it == clusters_.end() ? 0 : it->second->firstPort(); -} - -const ClusterHelper& StressTest::findCluster(const std::string& cluster_name) const { - const auto& it = clusters_.find(cluster_name); - if (it == clusters_.end()) { - throw EnvoyException(fmt::format("Cannot find cluster '{}'", cluster_name)); - } - return it->second->clusterHelper(); -} - -void StressTest::stopServers() { - // Stop envoy by destroying it. - test_server_ = nullptr; - - // Wait until all clusters have no more active connections - for (auto& it : clusters_) { - it.second->wait(); - } -} - -// Must be called before Envoy is stopped -void StressTest::extractCounters(StressTest::CounterMap& counters, const std::string& prefix) { - for (const auto& it : test_server_->stat_store().counters()) { - if (!absl::StartsWith(it->name(), prefix)) { - continue; - } - counters[it->name()] = it->value(); - } -} - -void StressTest::dumpCounters(StressTest::CounterMap& counters) { - for (const auto& it : counters) { - ENVOY_LOG(info, "{} = {}", it.first, it.second); - } -} - -void StressTest::Cluster::bind() { - if (bound_) { - return; - } - for (size_t i = 0; i < cluster_helper_->servers().size(); ++i) { - listen_socket_factories_.push_back(std::make_shared(ip_version_)); - ENVOY_LOG(debug, "{} bound port {}", cluster_helper_->name(), - listen_socket_factories_.back()->localAddress()->ip()->port()); - } - bound_ = true; -} - -void StressTest::Cluster::addClusterToBootstrap(ConfigHelper& config_helper, - std::vector& ports) const { - config_helper.addConfigModifier([this](envoy::config::bootstrap::v3::Bootstrap& bootstrap) { - auto cluster = bootstrap.mutable_static_resources()->add_clusters(); - - cluster->set_name(cluster_helper_->name()); - cluster->set_type( - envoy::config::cluster::v3::Cluster_DiscoveryType::Cluster_DiscoveryType_STATIC); - cluster->set_lb_policy( - envoy::config::cluster::v3::Cluster_LbPolicy::Cluster_LbPolicy_ROUND_ROBIN); - - if (http_type_ == Http::CodecClient::Type::HTTP1) { - auto opts = cluster->mutable_http_protocol_options(); - opts->set_accept_http_10(false); - } else { - auto opts = cluster->mutable_http2_protocol_options(); - auto value = opts->mutable_max_concurrent_streams(); - value->set_value(2147483647U); - } - - for (const auto& listen_socket_factory : listen_socket_factories_) { - cluster->mutable_load_assignment()->set_cluster_name(cluster->name()); - auto* endpoints = cluster->mutable_load_assignment()->add_endpoints(); - auto* address = endpoints->add_lb_endpoints() - ->mutable_endpoint() - ->mutable_address() - ->mutable_socket_address(); - address->set_address(Network::Test::getLoopbackAddressString(ip_version_)); - address->set_port_value(listen_socket_factory->localAddress()->ip()->port()); - } - }); - - // This avoids "assert failure: ports.size() > port_idx" complaints from - // ConfigHelper::finalize() - for (const auto& listen_socket_factory : listen_socket_factories_) { - ports.push_back(listen_socket_factory->localAddress()->ip()->port()); - } -} - -void StressTest::Cluster::start() { - bind(); - for (size_t i = 0; i < cluster_helper_->servers().size(); ++i) { - servers_.emplace_back(new Server(fmt::format("{}-{}", cluster_helper_->name(), i), - listen_socket_factories_[i], transport_socket_factory_, - http_type_)); - servers_.back()->start(*cluster_helper_->servers()[i]); - } -} - -} // namespace Stress -} // namespace Envoy diff --git a/test/stress/stress_test.h b/test/stress/stress_test.h deleted file mode 100644 index 73ec86f266..0000000000 --- a/test/stress/stress_test.h +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once - -#include "envoy/network/listener.h" - -#include "test/integration/http_integration.h" -#include "test/stress/stress_test_downstream.h" -#include "test/stress/stress_test_upstream.h" - -namespace Envoy { -namespace Stress { - -class StressTest : public HttpIntegrationTest { -public: - static const std::string ORIGIN_CLUSTER_NAME; - - StressTest(Network::Address::IpVersion ip_protocol, Http::CodecClient::Type http_type) - : HttpIntegrationTest(http_type, ip_protocol, baseBootstrap(ip_protocol)), - ip_version_(ip_protocol), http_type_{http_type}, - transport_socket_factory_{}, client_{"client"} { - // Tell the base class that we will create our own upstream origin server - fake_upstreams_count_ = 0; - } - -protected: - Network::Address::IpVersion ipVersion() const { return ip_version_; } - - Http::CodecClient::Type httpType() const { return http_type_; } - - ClusterHelper& addCluster(ClusterHelperPtr&& cluster_helper); - - void bind(); - - LoadGeneratorPtr start(); - - uint16_t envoyPort() { return static_cast(lookupPort("http")); } - - uint16_t firstPortInCluster(const std::string& cluster_name) const; - - const ClusterHelper& findCluster(const std::string& cluster_name) const; - - void stopServers(); - - using CounterMap = std::unordered_map; - - // Must be called before Envoy is stopped - void extractCounters(CounterMap& counters, const std::string& prefix = ""); - - void dumpCounters(CounterMap& counters); - -private: - static std::string baseBootstrap(Network::Address::IpVersion ip_protocol); - - class Cluster { - public: - Cluster(ClusterHelperPtr&& cluster_helper, - Network::TransportSocketFactory& transport_socket_factory, - Network::Address::IpVersion ip_version, Http::CodecClient::Type http_type) - : transport_socket_factory_{transport_socket_factory}, ip_version_{ip_version}, - http_type_{http_type}, cluster_helper_{std::move(cluster_helper)} {} - - void wait() { cluster_helper_->wait(); } - - void bind(); - - uint16_t firstPort() const { - return static_cast(listen_socket_factories_[0]->localAddress()->ip()->port()); - } - - const ClusterHelper& clusterHelper() const { return *cluster_helper_; } - ClusterHelper& clusterHelper() { return *cluster_helper_; } - - void addClusterToBootstrap(ConfigHelper& config_helper, std::vector& ports) const; - - void start(); - - private: - bool bound_{false}; - Network::TransportSocketFactory& transport_socket_factory_; - Network::Address::IpVersion ip_version_; - Http::CodecClient::Type http_type_; - ClusterHelperPtr cluster_helper_; - std::vector listen_socket_factories_; - std::vector servers_; - }; - - typedef std::unique_ptr ClusterPtr; - - Network::Address::IpVersion ip_version_; - Http::CodecClient::Type http_type_; - Network::RawBufferSocketFactory transport_socket_factory_; - Client client_; - std::unordered_map clusters_; -}; - -} // namespace Stress -} // namespace Envoy diff --git a/test/stress/stress_test_common.cc b/test/stress/stress_test_common.cc deleted file mode 100644 index 553e249233..0000000000 --- a/test/stress/stress_test_common.cc +++ /dev/null @@ -1,35 +0,0 @@ -#include "stress_test_common.h" - -#include "common/network/address_impl.h" - -namespace Envoy { -namespace Stress { - -Http::CodecClient::Type httpType(const std::string& str) { - return 0 == str.compare("http1") ? Http::CodecClient::Type::HTTP1 - : Http::CodecClient::Type::HTTP2; -} - -Network::Address::IpVersion ipVersion(const std::string& str) { - return 0 == str.compare("IPv4") ? Network::Address::IpVersion::v4 - : Network::Address::IpVersion::v6; -} - -Network::Address::InstanceConstSharedPtr loopbackAddress(Network::Address::IpVersion ip_version, - uint32_t port) { - switch (ip_version) { - case Network::Address::IpVersion::v6: { - Network::Address::InstanceConstSharedPtr addr{new Network::Address::Ipv6Instance("::1", port)}; - return addr; - } - case Network::Address::IpVersion::v4: - default: { - Network::Address::InstanceConstSharedPtr addr{ - new Network::Address::Ipv4Instance("127.0.0.1", port)}; - return addr; - } - } -} - -} // namespace Stress -} // namespace Envoy diff --git a/test/stress/stress_test_common.h b/test/stress/stress_test_common.h deleted file mode 100644 index fec235bd42..0000000000 --- a/test/stress/stress_test_common.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "envoy/network/address.h" - -#include "common/http/codec_client.h" - -namespace Envoy { -namespace Stress { - -extern Network::Address::InstanceConstSharedPtr -loopbackAddress(Network::Address::IpVersion ip_version, uint32_t port); - -extern Http::CodecClient::Type httpType(const std::string& str); - -extern Network::Address::IpVersion ipVersion(const std::string& str); - -} // namespace Stress -} // namespace Envoy diff --git a/test/stress/stress_test_downstream.cc b/test/stress/stress_test_downstream.cc deleted file mode 100644 index 4f559f0bf8..0000000000 --- a/test/stress/stress_test_downstream.cc +++ /dev/null @@ -1,576 +0,0 @@ -#include "stress_test_downstream.h" - -#include -#include - -#include "envoy/thread/thread.h" - -#include "common/http/http1/codec_impl.h" -#include "common/http/http2/codec_impl.h" -#include "common/stats/isolated_store_impl.h" - -namespace Envoy { -namespace Stress { - -class ClientStream : public Http::ResponseDecoder, - public Http::StreamCallbacks, - Logger::Loggable { -public: - ClientStream(uint32_t id, ClientConnection& connection, ClientResponseCallback& callback) - : id_(id), connection_(connection), callback_(callback) {} - ClientStream(const ClientStream&) = delete; - - void operator=(const ClientStream&) = delete; - - ~ClientStream() override { - ENVOY_LOG(trace, "ClientStream({}:{}:{}) destroyed", connection_.name(), connection_.id(), id_); - } - - // - // Http::ResponseDecoder - // - - void decode100ContinueHeaders(Http::ResponseHeaderMapPtr&&) override { - ENVOY_LOG(trace, "ClientStream({}:{}:{}) got continue headers", connection_.name(), - connection_.id(), id_); - } - - void decodeHeaders(Http::ResponseHeaderMapPtr&& response_headers, bool end_stream) override { - ENVOY_LOG(debug, "ClientStream({}:{}:{}) got response headers", connection_.name(), - connection_.id(), id_); - - response_headers_ = std::move(response_headers); - - if (end_stream) { - onEndStream(); - // stream is now destroyed - } - } - - void decodeData(Buffer::Instance&, bool end_stream) override { - ENVOY_LOG(debug, "ClientStream({}:{}:{}) got response body data", connection_.name(), - connection_.id(), id_); - - if (end_stream) { - onEndStream(); - // stream is now destroyed - } - } - - void decodeTrailers(Http::ResponseTrailerMapPtr&&) override { - ENVOY_LOG(trace, "ClientStream({}:{}:{}) got response trailers", connection_.name(), - connection_.id(), id_); - onEndStream(); - // stream is now destroyed - } - - void decodeMetadata(Http::MetadataMapPtr&&) override { - ENVOY_LOG(trace, "ClientStream({}:{}):{} got metadata", connection_.name(), connection_.id(), - id_); - } - - // - // Http::StreamCallbacks - // - - void onResetStream(Http::StreamResetReason reason, absl::string_view) override { - switch (reason) { - case Http::StreamResetReason::LocalReset: - ENVOY_LOG(trace, "ClientStream({}:{}:{}) was locally reset", connection_.name(), - connection_.id(), id_); - break; - case Http::StreamResetReason::LocalRefusedStreamReset: - ENVOY_LOG(trace, "ClientStream({}:{}:{}) refused local stream reset", connection_.name(), - connection_.id(), id_); - break; - case Http::StreamResetReason::RemoteReset: - ENVOY_LOG(trace, "ClientStream({}:{}:{}) was remotely reset", connection_.name(), - connection_.id(), id_); - break; - case Http::StreamResetReason::RemoteRefusedStreamReset: - ENVOY_LOG(trace, "ClientStream({}:{}:{}) refused remote stream reset", connection_.name(), - connection_.id(), id_); - break; - case Http::StreamResetReason::ConnectionFailure: - ENVOY_LOG(trace, "ClientStream({}:{}:{}) reseet due to initial connection failure", - connection_.name(), connection_.id(), id_); - break; - case Http::StreamResetReason::ConnectionTermination: - ENVOY_LOG(trace, "ClientStream({}:{}:{}) reset due to underlying connection reset", - connection_.name(), connection_.id(), id_); - break; - case Http::StreamResetReason::Overflow: - ENVOY_LOG(trace, "ClientStream({}:{}:{}) reset due to resource overflow", connection_.name(), - connection_.id(), id_); - break; - default: - ENVOY_LOG(trace, "ClientStream({}:{}:{}) reset due to unknown reason", connection_.name(), - connection_.id(), id_); - break; - } - } - - void onAboveWriteBufferHighWatermark() override { - ENVOY_LOG(trace, "ClientStream({}:{}:{}) above write buffer high watermark", connection_.name(), - connection_.id(), id_); - } - - void onBelowWriteBufferLowWatermark() override { - ENVOY_LOG(trace, "ClientStream({}:{}:{}) below write buffer low watermark", connection_.name(), - connection_.id(), id_); - } - - virtual void sendRequest(const Http::RequestHeaderMap& request_headers, - const std::chrono::milliseconds timeout) { - if (connection_.networkConnection().state() != Network::Connection::State::Open) { - ENVOY_LOG(warn, "ClientStream({}:{}:{})'s underlying connection is not open!", - connection_.name(), connection_.id(), id_); - connection_.removeStream(id_); - // This stream is now destroyed - return; - } - - Http::RequestEncoder& encoder = connection_.httpConnection().newStream(*this); - encoder.getStream().addCallbacks(*this); - - ENVOY_LOG(debug, "ClientStream({}:{}:{}) sending request headers", connection_.name(), - connection_.id(), id_); - encoder.encodeHeaders(request_headers, true); - - timeout_timer_ = connection_.dispatcher().createTimer([this, timeout]() { - ENVOY_LOG(debug, "ClientStream({}:{}:{}) timed out after {} msec waiting for response", - connection_.name(), connection_.id(), id_, static_cast(timeout.count())); - callback_(connection_, nullptr); - connection_.removeStream(id_); - // This stream is now destroyed - }); - timeout_timer_->enableTimer(timeout); - } - -private: - void onEndStream() { - ENVOY_LOG(debug, "ClientStream({}:{}:{}) complete", connection_.name(), connection_.id(), id_); - callback_(connection_, std::move(response_headers_)); - connection_.removeStream(id_); - // This stream is now destroyed - } - - uint32_t id_; - ClientConnection& connection_; - Http::ResponseHeaderMapPtr response_headers_{nullptr}; - ClientResponseCallback& callback_; - Event::TimerPtr timeout_timer_{nullptr}; -}; - -class HttpClientReadFilter : public Network::ReadFilter, Logger::Loggable { -public: - HttpClientReadFilter(const std::string& name, uint32_t id, Http::ClientConnection& connection) - : name_(name), id_(id), connection_(connection) {} - HttpClientReadFilter(const HttpClientReadFilter&) = delete; - - void operator=(const HttpClientReadFilter&) = delete; - - // - // Network::ReadFilter - // - - Network::FilterStatus onData(Buffer::Instance& data, bool end_stream) override { - ENVOY_LOG(trace, "ClientConnection({}:{}) got data", name_, id_); - - connection_.dispatch(data); - - if (end_stream) { - ENVOY_LOG(error, "ClientConnection({}:{}) got end stream", name_, id_); - } - - return Network::FilterStatus::StopIteration; - } - - Network::FilterStatus onNewConnection() override { return Network::FilterStatus::Continue; } - - void initializeReadFilterCallbacks(Network::ReadFilterCallbacks&) override {} - -private: - std::string name_; - uint32_t id_; - Http::ClientConnection& connection_; -}; - -typedef std::unique_ptr HttpClientReadFilterPtr; -typedef std::shared_ptr HttpClientReadFilterSharedPtr; - -static constexpr uint32_t max_request_headers_kb = 2U; -static constexpr uint32_t max_request_headers_count = 100U; - -class Http1ClientConnection : public ClientConnection { -public: - Http1ClientConnection(Client& client, uint32_t id, ClientConnectCallback& connect_callback, - ClientCloseCallback& close_callback, - std::shared_ptr& dispatcher, - Network::ClientConnectionPtr&& network_connection) - : ClientConnection(client, id, connect_callback, close_callback, dispatcher), stats_(), - network_connection_(std::move(network_connection)), - http_connection_(*network_connection_, stats_, *this, Http::Http1Settings(), - max_request_headers_count), - read_filter_{std::make_shared(client.name(), id, http_connection_)} { - network_connection_->addReadFilter(read_filter_); - network_connection_->addConnectionCallbacks(*this); - } - Http1ClientConnection(const Http1ClientConnection&) = delete; - - Http1ClientConnection& operator=(const Http1ClientConnection&) = delete; - - Network::ClientConnection& networkConnection() override { return *network_connection_; } - - Http::ClientConnection& httpConnection() override { return http_connection_; } - -private: - Stats::IsolatedStoreImpl stats_; - Network::ClientConnectionPtr network_connection_; - Http::Http1::ClientConnectionImpl http_connection_; - HttpClientReadFilterSharedPtr read_filter_; -}; - -class Http2ClientConnection : public ClientConnection { -public: - Http2ClientConnection(Client& client, uint32_t id, ClientConnectCallback& connect_callback, - ClientCloseCallback& close_callback, - std::shared_ptr& dispatcher, - Network::ClientConnectionPtr&& network_connection) - : ClientConnection(client, id, connect_callback, close_callback, dispatcher), stats_(), - settings_(), network_connection_(std::move(network_connection)), - http_connection_(*network_connection_, *this, stats_, settings_, max_request_headers_kb, - max_request_headers_count), - read_filter_{std::make_shared(client.name(), id, http_connection_)} { - network_connection_->addReadFilter(read_filter_); - network_connection_->addConnectionCallbacks(*this); - } - Http2ClientConnection(const Http2ClientConnection&) = delete; - - Http2ClientConnection& operator=(const Http2ClientConnection&) = delete; - - Network::ClientConnection& networkConnection() override { return *network_connection_; } - - Http::ClientConnection& httpConnection() override { return http_connection_; } - -private: - Stats::IsolatedStoreImpl stats_; - Http::Http2Settings settings_; - Network::ClientConnectionPtr network_connection_; - Http::Http2::ClientConnectionImpl http_connection_; - HttpClientReadFilterSharedPtr read_filter_; -}; - -ClientStream& ClientConnection::newStream(ClientResponseCallback& callback) { - std::lock_guard guard(streams_lock_); - - uint32_t id = stream_counter_++; - ClientStreamPtr stream = std::make_unique(id, *this, callback); - ClientStream* raw = stream.get(); - streams_[id] = std::move(stream); - - return *raw; -} - -ClientConnection::ClientConnection(Client& client, uint32_t id, - ClientConnectCallback& connect_callback, - ClientCloseCallback& close_callback, - std::shared_ptr& dispatcher) - : client_(client), id_(id), connect_callback_(connect_callback), - close_callback_(close_callback), dispatcher_(dispatcher) {} - -ClientConnection::~ClientConnection() { - ENVOY_LOG(trace, "ClientConnection({}:{}) destroyed", client_.name(), id_); -} - -const std::string& ClientConnection::name() const { return client_.name(); } - -uint32_t ClientConnection::id() const { return id_; } - -Event::Dispatcher& ClientConnection::dispatcher() { return *dispatcher_; }; - -void ClientConnection::removeStream(uint32_t stream_id) { - unsigned long size = 0UL; - - { - std::lock_guard guard(streams_lock_); - streams_.erase(stream_id); - size = streams_.size(); - } - - if (0 == size) { - ENVOY_LOG(debug, "ClientConnection({}:{}) is idle", client_.name(), id_); - if (ClientCallbackResult::CLOSE == connect_callback_(*this, ClientConnectionState::IDLE)) { - // This will trigger a - // networkConnection().onEvent(Network::ConnectionEvent::LocalClose) - networkConnection().close(Network::ConnectionCloseType::NoFlush); - } - } -} - -void ClientConnection::onEvent(Network::ConnectionEvent event) { - switch (event) { - // properly on connection destruction. - case Network::ConnectionEvent::RemoteClose: - if (established_) { - ENVOY_LOG(debug, "ClientConnection({}:{}) closed by peer or reset", client_.name(), id_); - close_callback_(*this, ClientCloseReason::REMOTE_CLOSE); - } else { - ENVOY_LOG(debug, "ClientConnection({}:{}) cannot connect to peer", client_.name(), id_); - close_callback_(*this, ClientCloseReason::CONNECT_FAILED); - } - client_.releaseConnection(*this); - // ClientConnection has been destroyed - return; - case Network::ConnectionEvent::LocalClose: - ENVOY_LOG(debug, "ClientConnection({}:{}) closed locally", client_.name(), id_); - close_callback_(*this, ClientCloseReason::LOCAL_CLOSE); - client_.releaseConnection(*this); - // ClientConnection has been destroyed - return; - case Network::ConnectionEvent::Connected: - established_ = true; - ENVOY_LOG(debug, "ClientConnection({}:{}) established", client_.name(), id_); - if (ClientCallbackResult::CLOSE == connect_callback_(*this, ClientConnectionState::CONNECTED)) { - // This will trigger a - // networkConnection().onEvent(Network::ConnectionEvent::LocalClose) - networkConnection().close(Network::ConnectionCloseType::NoFlush); - } - break; - default: - ENVOY_LOG(error, "ClientConnection({}:{}) got unknown event", client_.name(), id_); - }; -} - -void ClientConnection::onAboveWriteBufferHighWatermark() { - ENVOY_LOG(warn, "ClientConnection({}:{}) above write buffer high watermark", client_.name(), id_); - httpConnection().onUnderlyingConnectionAboveWriteBufferHighWatermark(); -} - -void ClientConnection::onBelowWriteBufferLowWatermark() { - ENVOY_LOG(warn, "ClientConnection({}:{}) below write buffer low watermark", client_.name(), id_); - httpConnection().onUnderlyingConnectionBelowWriteBufferLowWatermark(); -} - -void ClientConnection::onGoAway() { - ENVOY_LOG(warn, "ClientConnection({}:{}) remote closed", client_.name(), id_); -} - -void ClientConnection::sendRequest(const Http::RequestHeaderMap& headers, - ClientResponseCallback& callback, - std::chrono::milliseconds timeout) { - newStream(callback).sendRequest(headers, timeout); -} - -Client::Client(const std::string& name) - : name_(name), stats_(), thread_(nullptr), time_system_(), - api_(Thread::threadFactoryForTest(), stats_, time_system_, Filesystem::fileSystemForTest()), - dispatcher_{api_.allocateDispatcher()} {} - -Client::~Client() { - stop(); - ENVOY_LOG(trace, "Client({}) destroyed", name_); -} - -const std::string& Client::name() const { return name_; } - -void Client::connect(Network::TransportSocketFactory& socket_factory, - Http::CodecClient::Type http_version, - Network::Address::InstanceConstSharedPtr& address, - const Network::ConnectionSocket::OptionsSharedPtr& sockopts, - ClientConnectCallback& connect_cb, ClientCloseCallback& close_cb) { - dispatcher_->post([this, &socket_factory, http_version, address, sockopts, &connect_cb, - &close_cb]() { - Network::ClientConnectionPtr connection = dispatcher_->createClientConnection( - address, nullptr, socket_factory.createTransportSocket(nullptr), sockopts); - uint32_t id = connection_counter_++; - - ClientConnectionPtr ptr; - if (Http::CodecClient::Type::HTTP1 == http_version) { - ptr = std::make_unique(*this, id, connect_cb, close_cb, dispatcher_, - std::move(connection)); - } else { - ptr = std::make_unique(*this, id, connect_cb, close_cb, dispatcher_, - std::move(connection)); - } - ClientConnection& raw = *ptr.get(); - - { - std::lock_guard guard(connections_lock_); - connections_[id] = std::move(ptr); - } - - ENVOY_LOG(debug, "ClientConnection({}:{}) connecting to {}", name_, id, address->asString()); - raw.networkConnection().connect(); - }); -} - -void Client::start() { - std::promise promise; - - if (is_running_) { - return; - } - - thread_ = api_.threadFactory().createThread([this, &promise]() { - ENVOY_LOG(debug, "Client({}) dispatcher started", name_); - - is_running_ = true; - promise.set_value(true); // do not use promise again after this - while (is_running_) { - dispatcher_->run(Event::Dispatcher::RunType::NonBlock); - } - - ENVOY_LOG(debug, "Client({}) dispatcher stopped", name_); - }); - - promise.get_future().get(); -} - -void Client::stop() { - ENVOY_LOG(debug, "Client({}) stop requested", name_); - - is_running_ = false; - if (thread_) { - thread_->join(); - thread_ = nullptr; - } - - ENVOY_LOG(debug, "Client({}) stopped", name_); -} - -void Client::releaseConnection(uint32_t id) { - size_t erased = 0; - { - std::lock_guard guard(connections_lock_); - dispatcher_->deferredDelete(std::move(connections_[id])); - erased = connections_.erase(id); - } - if (1 > erased) { - ENVOY_LOG(error, "Client({}) cannot remove ClientConnection({}:{})", name_, name_, id); - } -} - -void Client::releaseConnection(ClientConnection& connection) { releaseConnection(connection.id()); } - -LoadGenerator::LoadGenerator(Client& client, Network::TransportSocketFactory& socket_factory, - Http::CodecClient::Type http_version, - Network::Address::InstanceConstSharedPtr& address, - const Network::ConnectionSocket::OptionsSharedPtr& sockopts) - : client_(client), socket_factory_(socket_factory), http_version_(http_version), - address_(address), sockopts_(sockopts) { - response_callback_ = [this](ClientConnection& connection, Http::ResponseHeaderMapPtr&& response) { - if (!response) { - ENVOY_LOG(debug, "Connection({}:{}) timedout waiting for response", connection.name(), - connection.id()); - ++response_timeouts_; - return; - } - - ++responses_received_; - - uint64_t status = 0; - auto str = std::string(response->Status()->value().getStringView()); - if (!StringUtil::atoull(str.c_str(), status)) { - ENVOY_LOG(error, "Connection({}:{}) received response with bad status", connection.name(), - connection.id()); - } else if (200 <= status && status < 300) { - ++class_2xx_; - } else if (400 <= status && status < 500) { - ++class_4xx_; - } else if (500 <= status && status < 600) { - ++class_5xx_; - } - - if (0 >= requests_remaining_--) { - // Break if we've already sent or scheduled every request we wanted to - return; - } - - connection.sendRequest(*request_, response_callback_, timeout_); - }; - - connect_callback_ = [this](ClientConnection& connection, - ClientConnectionState state) -> ClientCallbackResult { - if (state == ClientConnectionState::IDLE) { - // This will result in a CloseReason::LOCAL_CLOSE passed to the - // close_callback - return ClientCallbackResult::CLOSE; - } - // If ConnectionResult::SUCCESS: - - ++connect_successes_; - - if (0 >= requests_remaining_--) { - // This will result in a ConnectionState::IDLE passed to this callback - // once all active streams have finished. - return ClientCallbackResult::CONTINUE; - } - - connection.sendRequest(*request_, response_callback_, timeout_); - - return ClientCallbackResult::CONTINUE; - }; - - close_callback_ = [this](ClientConnection&, ClientCloseReason reason) { - switch (reason) { - case ClientCloseReason::CONNECT_FAILED: - ++connect_failures_; - break; - case ClientCloseReason::REMOTE_CLOSE: - ++remote_closes_; - break; - case ClientCloseReason::LOCAL_CLOSE: - // We initiated this by responding to ConnectionState::IDLE with a - // CallbackResult::Close - ++local_closes_; - break; - } - - // Unblock run() once we've seen a close for every connection initiated. - if (remote_closes_ + local_closes_ + connect_failures_ >= connections_to_initiate_) { - promise_all_connections_closed_.set_value(true); - } - }; -} - -void LoadGenerator::run(uint32_t connections, uint32_t requests, - Http::RequestHeaderMapPtr&& request, std::chrono::milliseconds timeout) { - connections_to_initiate_ = connections; - requests_to_send_ = requests; - request_ = std::move(request); - promise_all_connections_closed_ = std::promise(); - timeout_ = timeout; - requests_remaining_ = requests_to_send_; - connect_failures_ = 0; - connect_successes_ = 0; - responses_received_ = 0; - response_timeouts_ = 0; - local_closes_ = 0; - remote_closes_ = 0; - class_2xx_ = 0; - class_4xx_ = 0; - class_5xx_ = 0; - - client_.start(); // idempotent - - for (uint32_t i = 0; i < connections_to_initiate_; ++i) { - client_.connect(socket_factory_, http_version_, address_, sockopts_, connect_callback_, - close_callback_); - } - - promise_all_connections_closed_.get_future().get(); -} - -uint32_t LoadGenerator::connectFailures() const { return connect_failures_; } -uint32_t LoadGenerator::connectSuccesses() const { return connect_successes_; } -uint32_t LoadGenerator::responsesReceived() const { return responses_received_; } -uint32_t LoadGenerator::responseTimeouts() const { return response_timeouts_; } -uint32_t LoadGenerator::localCloses() const { return local_closes_; } -uint32_t LoadGenerator::remoteCloses() const { return remote_closes_; } -uint32_t LoadGenerator::class2xxResponses() const { return class_2xx_; } -uint32_t LoadGenerator::class4xxResponses() const { return class_4xx_; } -uint32_t LoadGenerator::class5xxResponses() const { return class_5xx_; } - -} // namespace Stress -} // namespace Envoy diff --git a/test/stress/stress_test_downstream.h b/test/stress/stress_test_downstream.h deleted file mode 100644 index 11960c3c5c..0000000000 --- a/test/stress/stress_test_downstream.h +++ /dev/null @@ -1,290 +0,0 @@ -#pragma once - -#include - -#include "envoy/api/api.h" -#include "envoy/event/dispatcher.h" -#include "envoy/http/codec.h" -#include "envoy/network/address.h" -#include "envoy/thread/thread.h" - -#include "common/api/api_impl.h" -#include "common/common/thread.h" -#include "common/http/codec_client.h" -#include "common/network/raw_buffer_socket.h" -#include "common/stats/isolated_store_impl.h" - -#include "test/test_common/test_time.h" -#include "test/test_common/utility.h" - -#include "fmt/printf.h" -#include "stress_test_common.h" - -namespace Envoy { -namespace Stress { - -class ClientStream; -class ClientConnection; -class Client; -typedef std::unique_ptr ClientStreamPtr; -typedef std::shared_ptr ClientStreamSharedPtr; -typedef std::unique_ptr ClientConnectionPtr; -typedef std::shared_ptr ClientConnectionSharedPtr; -typedef std::unique_ptr ClientPtr; -typedef std::shared_ptr ClientSharedPtr; - -enum class ClientConnectionState { - CONNECTED, // Connection established. Non-Terminal. Will be followed by one - // of the codes below. - IDLE, // Connection has no active streams. Non-Terminal. Close it, use it, - // or put it in a pool. -}; - -enum class ClientCloseReason { - CONNECT_FAILED, // Connection could not be established - REMOTE_CLOSE, // Peer closed or connection was reset after it was - // established. - LOCAL_CLOSE // This process decided to close the connection. -}; - -enum class ClientCallbackResult { - CONTINUE, // Leave the connection open - CLOSE // Close the connection. -}; - -/** - * Handle a non-terminal connection event asynchronously. - * - * @param connection The connection with the event - * @param state The state of the connection (connected or idle). - */ -typedef std::function - ClientConnectCallback; - -/** - * Handle a terminal connection close event asynchronously. - * - * @param connection The connection that was closed - * @param reason The reason the connection was closed - */ -typedef std::function - ClientCloseCallback; - -/** - * Handle a response asynchronously. - * - * @param connection The connection that received the response. - * @param response_headers The response headers or null if timed out. - */ -typedef std::function - ClientResponseCallback; - -class ClientConnection : public Network::ConnectionCallbacks, - public Http::ConnectionCallbacks, - public Event::DeferredDeletable, - protected Logger::Loggable { -public: - ClientConnection(Client& client, uint32_t id, ClientConnectCallback& connect_callback, - ClientCloseCallback& close_callback, - std::shared_ptr& dispatcher); - ClientConnection(const ClientConnection&) = delete; - - ClientConnection& operator=(const ClientConnection&) = delete; - ~ClientConnection() override; - - const std::string& name() const; - - uint32_t id() const; - - virtual Network::ClientConnection& networkConnection() PURE; - - virtual Http::ClientConnection& httpConnection() PURE; - - Event::Dispatcher& dispatcher(); - - /** - * Asynchronously send a request. On HTTP1.1 connections at most one request - * can be outstanding on a connection. For HTTP2 multiple requests may - * outstanding. - * - * @param request_headers - * @param callback - */ - virtual void sendRequest(const Http::RequestHeaderMap& request_headers, - ClientResponseCallback& callback, - std::chrono::milliseconds timeout = std::chrono::milliseconds(5'000)); - - /** - * For internal use - * - * @param stream_id - */ - void removeStream(uint32_t stream_id); - - // - // Network::ConnectionCallbacks - // - - void onEvent(Network::ConnectionEvent event) override; - - void onAboveWriteBufferHighWatermark() override; - - void onBelowWriteBufferLowWatermark() override; - - // - // Http::ConnectionCallbacks - // - - void onGoAway() override; - -private: - ClientStream& newStream(ClientResponseCallback& callback); - - Client& client_; - uint32_t id_; - ClientConnectCallback& connect_callback_; - ClientCloseCallback& close_callback_; - std::shared_ptr dispatcher_; - bool established_{false}; - - std::mutex streams_lock_; - std::unordered_map streams_; - std::atomic stream_counter_{0U}; -}; - -class Client : Logger::Loggable { -public: - explicit Client(const std::string& name); - Client(const Client&) = delete; - - Client& operator=(const Client&) = delete; - virtual ~Client(); - - const std::string& name() const; - - /** - * Start the client's dispatcher in a background thread. This is a noop if - * the client has already been started. This will block until the dispatcher - * is running on another thread. - */ - void start(); - - /** - * Stop the client's dispatcher and join the background thread. This will - * block until the background thread exits. - */ - void stop(); - - /** - * For internal use - */ - void releaseConnection(uint32_t id); - - /** - * For internal use - */ - void releaseConnection(ClientConnection& connection); - - /** - * Asynchronously connect to a peer. The connect_callback will be called on - * successful connection establishment and also on idle state, giving the - * caller the opportunity to reuse or close connections. The close_callback - * will be called after the connection is closed, giving the caller the - * opportunity to cleanup additional resources, etc. - */ - void connect(Network::TransportSocketFactory& socket_factory, - Http::CodecClient::Type http_version, - Network::Address::InstanceConstSharedPtr& address, - const Network::ConnectionSocket::OptionsSharedPtr& sockopts, - ClientConnectCallback& connect_callback, ClientCloseCallback& close_callback); - -private: - std::atomic is_running_{false}; - std::string name_; - Stats::IsolatedStoreImpl stats_; - Thread::ThreadPtr thread_; - Event::TestRealTimeSystem time_system_; - Api::Impl api_; - std::shared_ptr dispatcher_; - - std::mutex connections_lock_; - std::unordered_map connections_; - uint32_t connection_counter_{0U}; -}; - -class LoadGenerator : Logger::Loggable { -public: - /** - * A wrapper around Client and its callbacks that implements a simple load - * generator. - * - * @param socket_factory Socket factory (use for plain TCP vs. TLS) - * @param http_version HTTP version (h1 vs h2) - * @param address Address (ip addr, port, ip protocol version) to connect to - * @param sockopts Socket options for the client sockets. Use default if - * null. - */ - LoadGenerator(Client& client, Network::TransportSocketFactory& socket_factory, - Http::CodecClient::Type http_version, - Network::Address::InstanceConstSharedPtr& address, - const Network::ConnectionSocket::OptionsSharedPtr& sockopts = nullptr); - LoadGenerator(const LoadGenerator&) = delete; - void operator=(const LoadGenerator&) = delete; - virtual ~LoadGenerator() = default; - - /** - * Generate load and block until all connections have finished (successfully - * or otherwise). - * - * @param connections Connections to create - * @param requests Total requests across all connections to send - * @param request The request to send - * @param timeout The time in msec to wait to receive a response after sending - * each request. - */ - void run(uint32_t connections, uint32_t requests, Http::RequestHeaderMapPtr&& request, - std::chrono::milliseconds timeout = std::chrono::milliseconds(5'000)); - - uint32_t connectFailures() const; - uint32_t connectSuccesses() const; - uint32_t responsesReceived() const; - uint32_t responseTimeouts() const; - uint32_t localCloses() const; - uint32_t remoteCloses() const; - uint32_t class2xxResponses() const; - uint32_t class4xxResponses() const; - uint32_t class5xxResponses() const; - -private: - uint32_t connections_to_initiate_{0}; - uint32_t requests_to_send_{0}; - Http::RequestHeaderMapPtr request_{}; - Client& client_; - Network::TransportSocketFactory& socket_factory_; - Http::CodecClient::Type http_version_; - Network::Address::InstanceConstSharedPtr address_; - const Network::ConnectionSocket::OptionsSharedPtr sockopts_; - - ClientConnectCallback connect_callback_; - ClientResponseCallback response_callback_; - ClientCloseCallback close_callback_; - std::chrono::milliseconds timeout_{std::chrono::milliseconds(0)}; - std::atomic requests_remaining_{0}; - std::atomic connect_failures_{0}; - std::atomic connect_successes_{0}; - std::atomic responses_received_{0}; - std::atomic response_timeouts_{0}; - std::atomic local_closes_{0}; - std::atomic remote_closes_{0}; - std::atomic class_2xx_{0}; - std::atomic class_4xx_{0}; - std::atomic class_5xx_{0}; - std::promise promise_all_connections_closed_; -}; - -typedef std::unique_ptr LoadGeneratorPtr; - -} // namespace Stress -} // namespace Envoy \ No newline at end of file diff --git a/test/stress/stress_test_self_test.cc b/test/stress/stress_test_self_test.cc deleted file mode 100644 index 7807047981..0000000000 --- a/test/stress/stress_test_self_test.cc +++ /dev/null @@ -1,379 +0,0 @@ -#include "envoy/network/listener.h" - -#include "common/network/utility.h" - -#include "test/test_common/network_utility.h" - -#include "gtest/gtest.h" -#include "stress_test_downstream.h" -#include "stress_test_upstream.h" - -namespace Envoy { -namespace Stress { - -/** - * Test of the StressTest::Client against the StressTest::Server without an - * Envoy intermediary. - */ -class StressTestSelfTest - : public testing::TestWithParam>, - protected Logger::Loggable { -public: - StressTestSelfTest() - : transport_socket_factory_(), ip_version_(ipVersion(std::get<1>(GetParam()))), - http_type_(httpType(std::get<0>(GetParam()))), - use_grpc_(0 == std::get<2>(GetParam()).compare("gRPC")), - listen_socket_factory_(std::make_shared()), client_("client"), - server_("server", listen_socket_factory_, transport_socket_factory_, http_type_) {} - -protected: - Network::RawBufferSocketFactory transport_socket_factory_; - Network::Address::IpVersion ip_version_; - Http::CodecClient::Type http_type_; - bool use_grpc_; - - Network::ListenSocketFactorySharedPtr listen_socket_factory_; - Client client_; - Server server_; -}; - -INSTANTIATE_TEST_SUITE_P(RuntimesAndLanguages, StressTestSelfTest, - testing::Combine(testing::Values("http1", "http2"), - testing::Values("IPv4", "IPv6"), - testing::Values("HTTP"))); - -TEST_P(StressTestSelfTest, HappyPath) { - // Logger::Registry::setLogLevel(spdlog::level::info); - constexpr uint32_t connections_to_initiate = 30; - constexpr uint32_t requests_to_send = 30 * connections_to_initiate; - - // - // Server Setup - // - - try { - // Take a really long time (500 msec) to send a 200 OK response. - ServerCallbackHelper server_callbacks([use_grpc = use_grpc_](ServerConnection&, - ServerStream& stream, - Http::RequestHeaderMapPtr&&) { - if (use_grpc) { - ProtobufWkt::Value response; - response.set_string_value("response"); - stream.sendGrpcResponse(Grpc::Status::Ok, response); - return; - } - - Http::TestResponseHeaderMapImpl response{{":status", "200"}}; - stream.sendResponseHeaders(response); - }); - server_.start(server_callbacks); - - // - // Client setup - // - - Network::Address::InstanceConstSharedPtr address = listen_socket_factory_->localAddress(); - LoadGenerator load_generator(client_, transport_socket_factory_, http_type_, address); - - // - // Exec test and wait for it to finish - // - - Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ - {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; - load_generator.run(connections_to_initiate, requests_to_send, std::move(request)); - - // wait until the server has closed all connections created by the client - server_callbacks.wait(load_generator.connectSuccesses()); - - // - // Evaluate test - // - - // All client connections are successfully established. - EXPECT_EQ(load_generator.connectSuccesses(), connections_to_initiate); - EXPECT_EQ(0, load_generator.connectFailures()); - // Client close callback called for every client connection. - EXPECT_EQ(load_generator.localCloses(), connections_to_initiate); - // Client response callback is called for every request sent - EXPECT_EQ(load_generator.responsesReceived(), requests_to_send); - // Every response was a 2xx class - EXPECT_EQ(load_generator.class2xxResponses(), requests_to_send); - EXPECT_EQ(0, load_generator.class4xxResponses()); - EXPECT_EQ(0, load_generator.class5xxResponses()); - // No client sockets are rudely closed by server / no client sockets are - // reset. - EXPECT_EQ(0, load_generator.remoteCloses()); - EXPECT_EQ(0, load_generator.responseTimeouts()); - - // Server accept callback is called for every client connection initiated. - EXPECT_EQ(server_callbacks.connectionsAccepted(), connections_to_initiate); - // Server request callback is called for every client request sent - EXPECT_EQ(server_callbacks.requestsReceived(), requests_to_send); - // Server does not close its own sockets but instead relies on the client to - // initate the close - EXPECT_EQ(0, server_callbacks.localCloses()); - // Server sees a client-initiated close for every socket it accepts - EXPECT_EQ(server_callbacks.remoteCloses(), server_callbacks.connectionsAccepted()); - } catch (Network::SocketBindException& ex) { - if (Network::Address::IpVersion::v6 == ip_version_) { - ENVOY_LOG(info, "Environment does not support IPv6, skipping test"); - GTEST_SKIP(); - } - throw ex; - } -} - -TEST_P(StressTestSelfTest, AcceptAndClose) { - constexpr uint32_t connections_to_initiate = 30; - constexpr uint32_t requests_to_send = 30 * connections_to_initiate; - - // - // Server Setup - // - - try { - // Immediately close any connection accepted. - ServerCallbackHelper server_callbacks( - [](ServerConnection&, ServerStream&, Http::RequestHeaderMapPtr&&) { - GTEST_FATAL_FAILURE_("Connections immediately closed so no response should be received"); - }, - [](ServerConnection&) -> ServerCallbackResult { return ServerCallbackResult::CLOSE; }); - - server_.start(server_callbacks); - - // - // Client setup - // - - Network::Address::InstanceConstSharedPtr address = listen_socket_factory_->localAddress(); - LoadGenerator load_generator(client_, transport_socket_factory_, http_type_, address); - - // - // Exec test and wait for it to finish - // - - Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ - {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; - load_generator.run(connections_to_initiate, requests_to_send, std::move(request)); - - // wait until the server has closed all connections created by the client - server_callbacks.wait(load_generator.connectSuccesses()); - - // - // Evaluate test - // - - // Assert that all connections succeed but no responses are received and the - // server closes the connections. - EXPECT_EQ(load_generator.connectSuccesses(), connections_to_initiate); - EXPECT_EQ(0, load_generator.connectFailures()); - EXPECT_EQ(load_generator.remoteCloses(), connections_to_initiate); - EXPECT_EQ(0, load_generator.localCloses()); - EXPECT_EQ(0, load_generator.responsesReceived()); - EXPECT_EQ(0, load_generator.class2xxResponses()); - EXPECT_EQ(0, load_generator.class4xxResponses()); - EXPECT_EQ(0, load_generator.class5xxResponses()); - EXPECT_EQ(0, load_generator.responseTimeouts()); - - // Server accept callback is called for every client connection initiated. - EXPECT_EQ(server_callbacks.connectionsAccepted(), connections_to_initiate); - // Server request callback is never called - EXPECT_EQ(0, server_callbacks.requestsReceived()); - // Server closes every connection - EXPECT_EQ(server_callbacks.connectionsAccepted(), server_callbacks.localCloses()); - EXPECT_EQ(0, server_callbacks.remoteCloses()); - } catch (Network::SocketBindException& ex) { - if (Network::Address::IpVersion::v6 == ip_version_) { - ENVOY_LOG(info, "Environment does not support IPv6, skipping test"); - GTEST_SKIP(); - } - throw ex; - } -} - -TEST_P(StressTestSelfTest, SlowResponse) { - constexpr uint32_t connections_to_initiate = 30; - constexpr uint32_t requests_to_send = 30 * connections_to_initiate; - - // - // Server Setup - // - - try { - // Take a really long time (500 msec) to send a 200 OK response. - ServerCallbackHelper server_callbacks( - [](ServerConnection&, ServerStream& stream, Http::RequestHeaderMapPtr&&) { - Http::TestResponseHeaderMapImpl response{{":status", "200"}}; - stream.sendResponseHeaders(response, std::chrono::milliseconds(500)); - }); - - server_.start(server_callbacks); - - // - // Client setup - // - - Network::Address::InstanceConstSharedPtr address = listen_socket_factory_->localAddress(); - LoadGenerator load_generator(client_, transport_socket_factory_, http_type_, address); - - // - // Exec test and wait for it to finish - // - - Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ - {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; - load_generator.run(connections_to_initiate, requests_to_send, std::move(request), - std::chrono::milliseconds(250)); - - // wait until the server has closed all connections created by the client - server_callbacks.wait(load_generator.connectSuccesses()); - - // - // Evaluate test - // - - // Assert that all connections succeed but all responses timeout leading to - // local closing of all connections. - EXPECT_EQ(load_generator.connectSuccesses(), connections_to_initiate); - EXPECT_EQ(0, load_generator.connectFailures()); - EXPECT_EQ(load_generator.responseTimeouts(), connections_to_initiate); - EXPECT_EQ(load_generator.localCloses(), connections_to_initiate); - EXPECT_EQ(0, load_generator.remoteCloses()); - EXPECT_EQ(0, load_generator.responsesReceived()); - EXPECT_EQ(0, load_generator.class2xxResponses()); - EXPECT_EQ(0, load_generator.class4xxResponses()); - EXPECT_EQ(0, load_generator.class5xxResponses()); - - // Server accept callback is called for every client connection initiated. - EXPECT_EQ(server_callbacks.connectionsAccepted(), connections_to_initiate); - // Server receives a request on each connection - EXPECT_EQ(server_callbacks.requestsReceived(), connections_to_initiate); - // Server sees that the client closes each connection after it gives up - EXPECT_EQ(server_callbacks.connectionsAccepted(), server_callbacks.remoteCloses()); - EXPECT_EQ(0, server_callbacks.localCloses()); - } catch (Network::SocketBindException& ex) { - if (Network::Address::IpVersion::v6 == ip_version_) { - ENVOY_LOG(info, "Environment does not support IPv6, skipping test"); - GTEST_SKIP(); - } - throw ex; - } -} - -TEST_P(StressTestSelfTest, NoServer) { - constexpr uint32_t connections_to_initiate = 30; - constexpr uint32_t requests_to_send = 30 * connections_to_initiate; - - // Create a listening socket bound to an ephemeral port picked by the kernel, - // but don't create a server to call listen() on it. Result will be - // ECONNREFUSEDs and we won't accidentally send connects to another process. - - try { - Network::TcpListenSocket listening_socket(loopbackAddress(ip_version_, 0), nullptr, true); - Network::Address::InstanceConstSharedPtr address{ - loopbackAddress(ip_version_, listening_socket.localAddress()->ip()->port())}; - - // - // Client setup - // - - LoadGenerator load_generator(client_, transport_socket_factory_, http_type_, address); - - // - // Exec test and wait for it to finish - // - - Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ - {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; - load_generator.run(connections_to_initiate, requests_to_send, std::move(request)); - - // - // Evaluate test - // - - // All client connections fail - EXPECT_EQ(load_generator.connectFailures(), connections_to_initiate); - // Nothing else happened - EXPECT_EQ(0, load_generator.connectSuccesses()); - EXPECT_EQ(0, load_generator.localCloses()); - EXPECT_EQ(0, load_generator.responseTimeouts()); - EXPECT_EQ(0, load_generator.responsesReceived()); - EXPECT_EQ(0, load_generator.class2xxResponses()); - EXPECT_EQ(0, load_generator.class4xxResponses()); - EXPECT_EQ(0, load_generator.class5xxResponses()); - EXPECT_EQ(0, load_generator.remoteCloses()); - } catch (Network::SocketBindException& ex) { - if (Network::Address::IpVersion::v6 == ip_version_) { - ENVOY_LOG(info, "Environment does not support IPv6, skipping test"); - GTEST_SKIP(); - } - throw ex; - } -} - -TEST_P(StressTestSelfTest, NoAccept) { - constexpr uint32_t connections_to_initiate = 30; - constexpr uint32_t requests_to_send = 30 * connections_to_initiate; - - // - // Server Setup - // - - try { - - ServerCallbackHelper server_callbacks; // sends a 200 OK to everything - server_.start(server_callbacks); - - // but don't call accept() on the listening socket - server_.stopAcceptingConnections(); - - // - // Client setup - // - - Network::Address::InstanceConstSharedPtr address = listen_socket_factory_->localAddress(); - LoadGenerator load_generator(client_, transport_socket_factory_, http_type_, address); - - // - // Exec test and wait for it to finish - // - - Http::RequestHeaderMapPtr request{new Http::TestRequestHeaderMapImpl{ - {":method", "GET"}, {":path", "/"}, {":scheme", "http"}, {":authority", "host"}}}; - load_generator.run(connections_to_initiate, requests_to_send, std::move(request), - std::chrono::milliseconds(250)); - - // - // Evaluate test - // - - // Assert that all connections succeed but all responses timeout leading to - // local closing of all connections. - EXPECT_EQ(load_generator.connectSuccesses(), connections_to_initiate); - EXPECT_EQ(0, load_generator.connectFailures()); - EXPECT_EQ(load_generator.responseTimeouts(), connections_to_initiate); - EXPECT_EQ(load_generator.localCloses(), connections_to_initiate); - EXPECT_EQ(0, load_generator.remoteCloses()); - EXPECT_EQ(0, load_generator.responsesReceived()); - EXPECT_EQ(0, load_generator.class2xxResponses()); - EXPECT_EQ(0, load_generator.class4xxResponses()); - EXPECT_EQ(0, load_generator.class5xxResponses()); - - // From the server point of view, nothing happened - EXPECT_EQ(0, server_callbacks.connectionsAccepted()); - EXPECT_EQ(0, server_callbacks.requestsReceived()); - EXPECT_EQ(0, server_callbacks.connectionsAccepted()); - EXPECT_EQ(0, server_callbacks.remoteCloses()); - EXPECT_EQ(0, server_callbacks.localCloses()); - } catch (Network::SocketBindException& ex) { - if (Network::Address::IpVersion::v6 == ip_version_) { - ENVOY_LOG(info, "Environment does not support IPv6, skipping test"); - GTEST_SKIP(); - } - throw ex; - } -} - -} // namespace Stress -} // namespace Envoy diff --git a/test/stress/stress_test_upstream.cc b/test/stress/stress_test_upstream.cc deleted file mode 100644 index f87896227f..0000000000 --- a/test/stress/stress_test_upstream.cc +++ /dev/null @@ -1,676 +0,0 @@ -#include "stress_test_upstream.h" - -#include - -#include "envoy/http/codec.h" -#include "envoy/network/transport_socket.h" - -#include "common/common/lock_guard.h" -#include "common/common/logger.h" -#include "common/grpc/codec.h" -#include "common/http/conn_manager_config.h" -#include "common/http/conn_manager_impl.h" -#include "common/http/exception.h" -#include "common/http/header_map_impl.h" -#include "common/http/http1/codec_impl.h" -#include "common/http/http2/codec_impl.h" -#include "common/network/listen_socket_impl.h" -#include "common/network/raw_buffer_socket.h" - -#include "server/connection_handler_impl.h" - -#include "test/test_common/network_utility.h" -#include "test/test_common/utility.h" - -#include "fmt/printf.h" - -namespace Envoy { -namespace Stress { - -static Http::LowerCaseString RequestId(std::string("x-request-id")); - -class ServerStreamImpl : public ServerStream, - public Http::RequestDecoder, - public Http::StreamCallbacks, - Logger::Loggable { -public: - ServerStreamImpl(uint32_t id, ServerConnection& connection, - ServerRequestCallback& request_callback, Http::ResponseEncoder& stream_encoder) - : id_(id), connection_(connection), request_callback_(request_callback), - stream_encoder_(stream_encoder) {} - - ~ServerStreamImpl() override { - ENVOY_LOG(trace, "ServerStream({}:{}:{}) destroyed", connection_.name(), connection_.id(), id_); - } - - ServerStreamImpl(const ServerStreamImpl&) = delete; - - ServerStreamImpl& operator=(const ServerStreamImpl&) = delete; - - // - // ServerStream - // - - void sendResponseHeaders(const Http::ResponseHeaderMap& response_headers, - const std::chrono::milliseconds delay) override { - if (connection_.networkConnection().state() != Network::Connection::State::Open) { - ENVOY_LOG(warn, "ServerStream({}:{}:{})'s underlying connection is not open!", - connection_.name(), connection_.id(), id_); - return; - } - - if (delay <= std::chrono::milliseconds(0)) { - ENVOY_LOG(debug, "ServerStream({}:{}:{}) sending response headers", connection_.name(), - connection_.id(), id_); - stream_encoder_.encodeHeaders(response_headers, true); - return; - } - - // Limitation: at most one response can be sent on a stream at a time. - assert(nullptr == delay_timer_.get()); - if (delay_timer_.get()) { - return; - } - - response_headers_ = Http::createHeaderMap(response_headers); - delay_timer_ = connection_.dispatcher().createTimer([this, delay]() { - ENVOY_LOG(debug, "ServerStream({}:{}:{}) sending response headers after {} msec delay", - connection_.name(), connection_.id(), id_, static_cast(delay.count())); - stream_encoder_.encodeHeaders(*response_headers_, true); - delay_timer_->disableTimer(); - delay_timer_ = nullptr; - response_headers_ = nullptr; - }); - delay_timer_->enableTimer(delay); - } - - void sendGrpcResponse(Grpc::Status::GrpcStatus status, const ProtobufWkt::Message& message, - const std::chrono::milliseconds delay) override { - // Limitation: at most one response can be sent on a stream at a time. - assert(nullptr == delay_timer_.get()); - if (delay_timer_.get()) { - return; - } - - response_status_ = status; - response_body_ = Grpc::Common::serializeToGrpcFrame(message); - Event::TimerCb send_grpc_response = [this, delay]() { - ENVOY_LOG(debug, "ServerStream({}:{}:{}) sending gRPC response after {} msec delay", - connection_.name(), connection_.id(), id_, static_cast(delay.count())); - stream_encoder_.encodeHeaders(Http::TestResponseHeaderMapImpl{{":status", "200"}}, false); - stream_encoder_.encodeData(*response_body_, false); - stream_encoder_.encodeTrailers(Http::TestResponseTrailerMapImpl{ - {"grpc-status", std::to_string(static_cast(response_status_))}}); - }; - - if (delay <= std::chrono::milliseconds(0)) { - send_grpc_response(); - return; - } - - delay_timer_ = connection_.dispatcher().createTimer([this, send_grpc_response]() { - send_grpc_response(); - delay_timer_->disableTimer(); - }); - - delay_timer_->enableTimer(delay); - } - - // - // Http::RequestDecoder - // - - /** - * Called with decoded headers, optionally indicating end of stream. - * @param headers supplies the decoded headers map that is moved into the - * callee. - * @param end_stream supplies whether this is a header only request/response. - */ - void decodeHeaders(Http::RequestHeaderMapPtr&& headers, bool end_stream) override { - ENVOY_LOG(debug, "ServerStream({}:{}:{}) got request headers", connection_.name(), - connection_.id(), id_); - - request_headers_ = std::move(headers); - - if (end_stream) { - onEndStream(); - // stream is now destroyed - } - } - - void decodeData(Buffer::Instance&, bool end_stream) override { - ENVOY_LOG(debug, "ServerStream({}:{}:{}) got request body data", connection_.name(), - connection_.id(), id_); - - if (end_stream) { - onEndStream(); - // stream is now destroyed - } - } - - void decodeTrailers(Http::RequestTrailerMapPtr&&) override { - ENVOY_LOG(trace, "ServerStream({}:{}:{}) got request trailers", connection_.name(), - connection_.id(), id_); - onEndStream(); - // stream is now destroyed - } - - void decodeMetadata(Http::MetadataMapPtr&&) override { - ENVOY_LOG(trace, "ServerStream({}:{}):{} got metadata", connection_.name(), connection_.id(), - id_); - } - - // - // Http::StreamCallbacks - // - - void onResetStream(Http::StreamResetReason reason, absl::string_view) override { - switch (reason) { - case Http::StreamResetReason::LocalReset: - ENVOY_LOG(trace, "ServerStream({}:{}:{}) was locally reset", connection_.name(), - connection_.id(), id_); - break; - case Http::StreamResetReason::LocalRefusedStreamReset: - ENVOY_LOG(trace, "ServerStream({}:{}:{}) refused local stream reset", connection_.name(), - connection_.id(), id_); - break; - case Http::StreamResetReason::RemoteReset: - ENVOY_LOG(trace, "ServerStream({}:{}:{}) was remotely reset", connection_.name(), - connection_.id(), id_); - break; - case Http::StreamResetReason::RemoteRefusedStreamReset: - ENVOY_LOG(trace, "ServerStream({}:{}:{}) refused remote stream reset", connection_.name(), - connection_.id(), id_); - break; - case Http::StreamResetReason::ConnectionFailure: - ENVOY_LOG(trace, "ServerStream({}:{}:{}) reseet due to initial connection failure", - connection_.name(), connection_.id(), id_); - break; - case Http::StreamResetReason::ConnectionTermination: - ENVOY_LOG(trace, "ServerStream({}:{}:{}) reset due to underlying connection reset", - connection_.name(), connection_.id(), id_); - break; - case Http::StreamResetReason::Overflow: - ENVOY_LOG(trace, "ServerStream({}:{}:{}) reset due to resource overflow", connection_.name(), - connection_.id(), id_); - break; - default: - ENVOY_LOG(trace, "ServerStream({}:{}:{}) reset due to unknown reason", connection_.name(), - connection_.id(), id_); - break; - } - } - - void onAboveWriteBufferHighWatermark() override { - ENVOY_LOG(trace, "ServerStream({}:{}:{}) above write buffer high watermark", connection_.name(), - connection_.id(), id_); - } - - void onBelowWriteBufferLowWatermark() override { - ENVOY_LOG(trace, "ServerStream({}:{}:{}) below write buffer low watermark", connection_.name(), - connection_.id(), id_); - } - -private: - void onEndStream() { - ENVOY_LOG(debug, "ServerStream({}:{}:{}) complete", connection_.name(), connection_.id(), id_); - request_callback_(connection_, *this, std::move(request_headers_)); - - connection_.removeStream(id_); - // This stream is now destroyed - } - - uint32_t id_; - ServerConnection& connection_; - Http::RequestHeaderMapPtr request_headers_{nullptr}; - Http::ResponseHeaderMapPtr response_headers_{nullptr}; - Buffer::InstancePtr response_body_{nullptr}; - Grpc::Status::GrpcStatus response_status_{Grpc::Status::Ok}; - ServerRequestCallback& request_callback_; - Http::ResponseEncoder& stream_encoder_; - Event::TimerPtr delay_timer_{nullptr}; -}; - -ServerConnection::ServerConnection(const std::string& name, uint32_t id, - ServerRequestCallback& request_callback, - ServerCloseCallback& close_callback, - Network::Connection& network_connection, - Event::Dispatcher& dispatcher, Http::CodecClient::Type http_type, - Stats::Scope& scope) - : name_(name), id_(id), network_connection_(network_connection), dispatcher_(dispatcher), - request_callback_(request_callback), close_callback_(close_callback) { - constexpr uint32_t max_request_headers_kb = 2U; - constexpr uint32_t max_request_headers_count = 100; - - switch (http_type) { - case Http::CodecClient::Type::HTTP1: - http_connection_ = std::make_unique( - network_connection, scope, *this, Http::Http1Settings(), max_request_headers_kb, - max_request_headers_count); - break; - case Http::CodecClient::Type::HTTP2: { - Http::Http2Settings settings; - settings.allow_connect_ = true; - settings.allow_metadata_ = true; - http_connection_ = std::make_unique( - network_connection, *this, scope, settings, max_request_headers_kb, - max_request_headers_count); - } break; - default: - ENVOY_LOG(error, - "ServerConnection({}:{}) doesn't support http type %d, " - "defaulting to HTTP1", - name_, id_, static_cast(http_type) + 1); - http_connection_ = std::make_unique( - network_connection, scope, *this, Http::Http1Settings(), max_request_headers_kb, - max_request_headers_count); - break; - } -} - -ServerConnection::~ServerConnection() { - ENVOY_LOG(trace, "ServerConnection({}:{}) destroyed", name_, id_); -} - -const std::string& ServerConnection::name() const { return name_; } - -uint32_t ServerConnection::id() const { return id_; } - -Network::Connection& ServerConnection::networkConnection() { return network_connection_; } - -const Network::Connection& ServerConnection::networkConnection() const { - return network_connection_; -} - -Http::ServerConnection& ServerConnection::httpConnection() { return *http_connection_; } - -const Http::ServerConnection& ServerConnection::httpConnection() const { return *http_connection_; } - -Event::Dispatcher& ServerConnection::dispatcher() { return dispatcher_; } - -Network::FilterStatus ServerConnection::onData(Buffer::Instance& data, bool end_stream) { - ENVOY_LOG(trace, "ServerConnection({}:{}) got data", name_, id_); - - try { - http_connection_->dispatch(data); - } catch (const Http::CodecProtocolException& e) { - ENVOY_LOG(error, "ServerConnection({}:{}) received the wrong protocol: {}", name_, id_, - e.what()); - network_connection_.close(Network::ConnectionCloseType::NoFlush); - return Network::FilterStatus::StopIteration; - } - - if (end_stream) { - ENVOY_LOG(error, "ServerConnection({}:{}) got end stream", name_, id_); - } - - return Network::FilterStatus::StopIteration; -} - -Network::FilterStatus ServerConnection::onNewConnection() { - ENVOY_LOG(trace, "ServerConnection({}:{}) onNewConnection", name_, id_); - return Network::FilterStatus::Continue; -} - -void ServerConnection::initializeReadFilterCallbacks(Network::ReadFilterCallbacks&) {} - -Http::RequestDecoder& ServerConnection::newStream(Http::ResponseEncoder& stream_encoder, bool) { - ServerStreamImpl* raw = nullptr; - uint32_t id = 0U; - - { - std::lock_guard guard(streams_lock_); - - id = stream_counter_++; - auto stream = std::make_unique(id, *this, request_callback_, stream_encoder); - raw = stream.get(); - streams_[id] = std::move(stream); - } - - ENVOY_LOG(debug, "ServerConnection({}:{}) received new Stream({}:{}:{})", name_, id_, name_, id_, - id); - - return *raw; -} - -void ServerConnection::removeStream(uint32_t stream_id) { - unsigned long size = 0UL; - - { - std::lock_guard guard(streams_lock_); - streams_.erase(stream_id); - size = streams_.size(); - } - - if (0 == size) { - ENVOY_LOG(debug, "ServerConnection({}:{}) is idle", name_, id_); - } -} - -void ServerConnection::onEvent(Network::ConnectionEvent event) { - switch (event) { - case Network::ConnectionEvent::RemoteClose: - ENVOY_LOG(debug, "ServerConnection({}:{}) closed by peer or reset", name_, id_); - close_callback_(*this, ServerCloseReason::REMOTE_CLOSE); - return; - case Network::ConnectionEvent::LocalClose: - ENVOY_LOG(debug, "ServerConnection({}:{}) closed locally", name_, id_); - close_callback_(*this, ServerCloseReason::LOCAL_CLOSE); - return; - default: - ENVOY_LOG(error, "ServerConnection({}:{}) got unknown event", name_, id_); - } -} - -void ServerConnection::onAboveWriteBufferHighWatermark() { - ENVOY_LOG(debug, "ServerConnection({}:{}) above write buffer high watermark", name_, id_); - http_connection_->onUnderlyingConnectionAboveWriteBufferHighWatermark(); -} - -void ServerConnection::onBelowWriteBufferLowWatermark() { - ENVOY_LOG(debug, "ServerConnection({}:{}) below write buffer low watermark", name_, id_); - http_connection_->onUnderlyingConnectionBelowWriteBufferLowWatermark(); -} - -void ServerConnection::onGoAway() { ENVOY_LOG(warn, "ServerConnection({}) got go away", name_); } - -ServerFilterChain::ServerFilterChain(Network::TransportSocketFactory& transport_socket_factory) - : transport_socket_factory_(transport_socket_factory) {} - -const Network::TransportSocketFactory& ServerFilterChain::transportSocketFactory() const { - return transport_socket_factory_; -} - -const std::vector& ServerFilterChain::networkFilterFactories() const { - return network_filter_factories_; -} - -LocalListenSocket::LocalListenSocket(Network::Address::IpVersion ip_version, uint16_t port, - const Network::Socket::OptionsSharedPtr& options, - bool bind_to_port) - : NetworkListenSocket(loopbackAddress(ip_version, port), options, bind_to_port) {} - -LocalListenSocketFactory::LocalListenSocketFactory(Network::Address::IpVersion ip_version, - uint16_t port, - const Network::Socket::OptionsSharedPtr& options, - bool bind_to_port) - : local_listen_socket_( - std::make_shared(ip_version, port, options, bind_to_port)) {} - -ServerCallbackHelper::ServerCallbackHelper(ServerRequestCallback&& request_callback, - ServerAcceptCallback&& accept_callback, - ServerCloseCallback&& close_callback) { - if (request_callback) { - request_callback_ = [this, request_callback = std::move(request_callback)]( - ServerConnection& connection, ServerStream& stream, - Http::RequestHeaderMapPtr&& request_headers) { - ++requests_received_; - request_callback(connection, stream, std::move(request_headers)); - }; - } else { - request_callback_ = [this](ServerConnection&, ServerStream& stream, - Http::RequestHeaderMapPtr&&) { - ++requests_received_; - Http::TestResponseHeaderMapImpl response{{":status", "200"}}; - stream.sendResponseHeaders(response); - }; - } - - if (accept_callback) { - accept_callback_ = [this, accept_callback = std::move(accept_callback)]( - ServerConnection& connection) -> ServerCallbackResult { - ++accepts_; - return accept_callback(connection); - }; - } else { - accept_callback_ = [this](ServerConnection&) -> ServerCallbackResult { - ++accepts_; - return ServerCallbackResult::CONTINUE; - }; - } - - if (close_callback) { - close_callback_ = [this, close_callback = std::move(close_callback)]( - ServerConnection& connection, ServerCloseReason reason) { - absl::MutexLock lock(&mutex_); - - switch (reason) { - case ServerCloseReason::REMOTE_CLOSE: - ++remote_closes_; - break; - case ServerCloseReason::LOCAL_CLOSE: - ++local_closes_; - break; - } - - close_callback(connection, reason); - }; - } else { - close_callback_ = [this](ServerConnection&, ServerCloseReason reason) { - absl::MutexLock lock(&mutex_); - - switch (reason) { - case ServerCloseReason::REMOTE_CLOSE: - ++remote_closes_; - break; - case ServerCloseReason::LOCAL_CLOSE: - ++local_closes_; - break; - } - }; - } -} - -uint32_t ServerCallbackHelper::connectionsAccepted() const { return accepts_; } - -uint32_t ServerCallbackHelper::requestsReceived() const { return requests_received_; } - -uint32_t ServerCallbackHelper::localCloses() const { - absl::MutexLock lock(&mutex_); - return local_closes_; -} - -uint32_t ServerCallbackHelper::remoteCloses() const { - absl::MutexLock lock(&mutex_); - return remote_closes_; -} - -ServerAcceptCallback ServerCallbackHelper::acceptCallback() const { return accept_callback_; } - -ServerRequestCallback ServerCallbackHelper::requestCallback() const { return request_callback_; } - -ServerCloseCallback ServerCallbackHelper::closeCallback() const { return close_callback_; } - -void ServerCallbackHelper::wait(uint32_t connections_closed) { - auto constraints = [connections_closed, this]() { - return connections_closed <= local_closes_ + remote_closes_; - }; - - absl::MutexLock lock(&mutex_); - mutex_.Await(absl::Condition(&constraints)); -} - -void ServerCallbackHelper::wait() { - auto constraints = [this]() { return accepts_ <= local_closes_ + remote_closes_; }; - - absl::MutexLock lock(&mutex_); - mutex_.Await(absl::Condition(&constraints)); -} - -Server::Server(const std::string& name, Network::ListenSocketFactorySharedPtr listen_socket_factory, - Network::TransportSocketFactory& transport_socket_factory, - Http::CodecClient::Type http_type) - : name_(name), stats_(), time_system_(), - api_(Thread::threadFactoryForTest(), stats_, time_system_, Filesystem::fileSystemForTest()), - dispatcher_(api_.allocateDispatcher()), - connection_handler_(new Envoy::Server::ConnectionHandlerImpl(*dispatcher_, "stress_server")), - thread_(nullptr), listen_socket_factory_(std::move(listen_socket_factory)), - server_filter_chain_(transport_socket_factory), http_type_(http_type) {} - -Server::~Server() { stop(); } - -void Server::start(ServerAcceptCallback&& accept_callback, ServerRequestCallback&& request_callback, - ServerCloseCallback&& close_callback) { - accept_callback_ = std::move(accept_callback); - request_callback_ = std::move(request_callback); - close_callback_ = std::move(close_callback); - std::promise promise; - - thread_ = api_.threadFactory().createThread([this, &promise]() { - is_running = true; - ENVOY_LOG(debug, "Server({}) started", name_.c_str()); - connection_handler_->addListener(*this); - - promise.set_value(true); // do not use promise again after this - while (is_running) { - dispatcher_->run(Event::Dispatcher::RunType::NonBlock); - } - - ENVOY_LOG(debug, "Server({}) stopped", name_.c_str()); - - connection_handler_.reset(); - }); - - promise.get_future().get(); -} - -void Server::start(ServerCallbackHelper& helper) { - start(helper.acceptCallback(), helper.requestCallback(), helper.closeCallback()); -} - -void Server::stop() { - is_running = false; - - if (thread_) { - thread_->join(); - thread_ = nullptr; - } -} - -void Server::stopAcceptingConnections() { - ENVOY_LOG(debug, "Server({}) stopped accepting connections", name_); - connection_handler_->disableListeners(); -} - -void Server::startAcceptingConnections() { - ENVOY_LOG(debug, "Server({}) started accepting connections", name_); - connection_handler_->enableListeners(); -} - -const Stats::Store& Server::statsStore() const { return stats_; } - -void Server::setPerConnectionBufferLimitBytes(uint32_t limit) { - connection_buffer_limit_bytes_ = limit; -} - -// -// Network::ListenerConfig -// - -Network::FilterChainManager& Server::filterChainManager() { return *this; } - -Network::FilterChainFactory& Server::filterChainFactory() { return *this; } - -Network::ListenSocketFactory& Server::listenSocketFactory() { return *listen_socket_factory_; } - -bool Server::bindToPort() { return true; } - -bool Server::handOffRestoredDestinationConnections() const { return false; } - -uint32_t Server::perConnectionBufferLimitBytes() const { return connection_buffer_limit_bytes_; } - -std::chrono::milliseconds Server::listenerFiltersTimeout() const { - return std::chrono::milliseconds(0); -} - -bool Server::continueOnListenerFiltersTimeout() const { return false; } - -Stats::Scope& Server::listenerScope() { return stats_; } - -uint64_t Server::listenerTag() const { return 0; } - -const std::string& Server::name() const { return name_; } - -Network::ActiveUdpListenerFactory* Server::udpListenerFactory() { return nullptr; } - -const Network::FilterChain* Server::findFilterChain(const Network::ConnectionSocket&) const { - return &server_filter_chain_; -} - -bool Server::createNetworkFilterChain(Network::Connection& network_connection, - const std::vector&) { - uint32_t id = connection_counter_++; - ENVOY_LOG(debug, "Server({}) accepted new Connection({}:{})", name_, name_, id); - - ServerConnectionSharedPtr connection = - std::make_shared(name_, id, request_callback_, close_callback_, - network_connection, *dispatcher_, http_type_, stats_); - network_connection.addReadFilter(connection); - network_connection.addConnectionCallbacks(*connection); - - return !(ServerCallbackResult::CLOSE == accept_callback_(*connection)); -} - -bool Server::createListenerFilterChain(Network::ListenerFilterManager&) { return true; } - -ClusterHelper::ClusterHelper(const std::string& name) : name_{name} {} - -ClusterHelper& ClusterHelper::addServer(ServerCallbackHelperPtr&& server_callback) { - server_callback_helpers_.push_back(std::move(server_callback)); - return *this; -} - -const std::vector& ClusterHelper::servers() const { - return server_callback_helpers_; -} - -std::vector& ClusterHelper::servers() { return server_callback_helpers_; } - -uint32_t ClusterHelper::connectionsAccepted() const { - uint32_t total = 0U; - - for (const auto& server_callback_helper : server_callback_helpers_) { - total += server_callback_helper->connectionsAccepted(); - } - - return total; -} - -uint32_t ClusterHelper::requestsReceived() const { - uint32_t total = 0U; - - for (const auto& server_callback_helper : server_callback_helpers_) { - total += server_callback_helper->requestsReceived(); - } - - return total; -} - -uint32_t ClusterHelper::localCloses() const { - uint32_t total = 0U; - - for (const auto& server_callback_helper : server_callback_helpers_) { - total += server_callback_helper->localCloses(); - } - - return total; -} - -uint32_t ClusterHelper::remoteCloses() const { - uint32_t total = 0U; - - for (const auto& server_callback_helper : server_callback_helpers_) { - total += server_callback_helper->remoteCloses(); - } - - return total; -} - -void ClusterHelper::wait() { - for (auto& server_callback_helper : server_callback_helpers_) { - server_callback_helper->wait(); - } -} - -} // namespace Stress -} // namespace Envoy diff --git a/test/stress/stress_test_upstream.h b/test/stress/stress_test_upstream.h deleted file mode 100644 index 61508c3de0..0000000000 --- a/test/stress/stress_test_upstream.h +++ /dev/null @@ -1,424 +0,0 @@ -#pragma once - -#include "envoy/network/address.h" -#include "envoy/network/listener.h" - -#include "common/api/api_impl.h" -#include "common/common/thread.h" -#include "common/grpc/common.h" -#include "common/http/codec_client.h" -#include "common/network/connection_balancer_impl.h" -#include "common/network/listen_socket_impl.h" -#include "common/stats/isolated_store_impl.h" - -#include "test/test_common/test_time.h" -#include "test/test_common/utility.h" - -#include "stress_test_common.h" - -namespace Envoy { -namespace Stress { - -enum class ServerCloseReason { - REMOTE_CLOSE, // Peer closed or connection was reset after it was - // established. - LOCAL_CLOSE // This process decided to close the connection. -}; - -enum class ServerCallbackResult { - CONTINUE, // Leave the connection open - CLOSE // Close the connection. -}; - -class ServerStream { -public: - ServerStream() = default; - - virtual ~ServerStream() = default; - - ServerStream(const ServerStream&) = delete; - void operator=(const ServerStream&) = delete; - - /** - * Send a HTTP header-only response and close the stream. - * - * @param response_headers the response headers - * @param delay delay in msec before sending the response. if 0 send - * immediately - */ - virtual void - sendResponseHeaders(const Http::ResponseHeaderMap& response_headers, - const std::chrono::milliseconds delay = std::chrono::milliseconds(0)) PURE; - - /** - * Send a gRPC response and close the stream - * - * @param status The gRPC status (carried in the HTTP response trailer) - * @param response The gRPC response (carried in the HTTP response body) - * @param delay delay in msec before sending the response. if 0 send - * immediately - */ - virtual void - sendGrpcResponse(Grpc::Status::GrpcStatus status, const Protobuf::Message& response, - const std::chrono::milliseconds delay = std::chrono::milliseconds(0)) PURE; -}; - -typedef std::unique_ptr ServerStreamPtr; -typedef std::shared_ptr ServerStreamSharedPtr; - -class ServerConnection; - -// NB: references passed to any of these callbacks are owned by the caller and -// must not be used after the callback returns -- except for the request headers -// which may be moved into the caller. -typedef std::function - ServerAcceptCallback; -typedef std::function - ServerCloseCallback; -typedef std::function - ServerRequestCallback; - -class ServerConnection : public Network::ReadFilter, - public Network::ConnectionCallbacks, - public Http::ServerConnectionCallbacks, - Logger::Loggable { -public: - ServerConnection(const std::string& name, uint32_t id, ServerRequestCallback& request_callback, - ServerCloseCallback& close_callback, Network::Connection& network_connection, - Event::Dispatcher& dispatcher, Http::CodecClient::Type http_type, - Stats::Scope& scope); - - ~ServerConnection() override; - ServerConnection(const ServerConnection&) = delete; - ServerConnection& operator=(const ServerConnection&) = delete; - - const std::string& name() const; - - uint32_t id() const; - - Network::Connection& networkConnection(); - const Network::Connection& networkConnection() const; - - Http::ServerConnection& httpConnection(); - const Http::ServerConnection& httpConnection() const; - - Event::Dispatcher& dispatcher(); - - /** - * For internal use - */ - void removeStream(uint32_t stream_id); - - // - // Network::ReadFilter - // - - Network::FilterStatus onData(Buffer::Instance& data, bool end_stream) override; - - Network::FilterStatus onNewConnection() override; - - void initializeReadFilterCallbacks(Network::ReadFilterCallbacks&) override; - - // - // Http::ConnectionCallbacks - // - - void onGoAway() override; - - // - // Http::ServerConnectionCallbacks - // - - Http::RequestDecoder& newStream(Http::ResponseEncoder& stream_encoder, - bool is_internally_created = false) override; - - // - // Network::ConnectionCallbacks - // - - void onEvent(Network::ConnectionEvent event) override; - - void onAboveWriteBufferHighWatermark() override; - - void onBelowWriteBufferLowWatermark() override; - -private: - std::string name_; - uint32_t id_; - Network::Connection& network_connection_; - Http::ServerConnectionPtr http_connection_; - Event::Dispatcher& dispatcher_; - ServerRequestCallback& request_callback_; - ServerCloseCallback& close_callback_; - - std::mutex streams_lock_; - std::unordered_map streams_; - uint32_t stream_counter_{0U}; -}; - -typedef std::unique_ptr ServerConnectionPtr; -typedef std::shared_ptr ServerConnectionSharedPtr; - -class ServerFilterChain : public Network::FilterChain { -public: - explicit ServerFilterChain(Network::TransportSocketFactory& transport_socket_factory); - ServerFilterChain(const ServerFilterChain&) = delete; - ServerFilterChain& operator=(const ServerFilterChain&) = delete; - - // - // Network::FilterChain - // - - const Network::TransportSocketFactory& transportSocketFactory() const override; - - const std::vector& networkFilterFactories() const override; - -private: - Network::TransportSocketFactory& transport_socket_factory_; - std::vector network_filter_factories_; -}; - -/** - * A convenience class for creating a listening socket bound to localhost - */ -class LocalListenSocket : public Network::TcpListenSocket { -public: - /** - * Create a listening socket bound to localhost. - * - * @param ip_version v4 or v6. v4 by default. - * @param port the port. If 0, let the kernel allocate an available ephemeral - * port. 0 by default. - * @param options socket options. nullptr by default - * @param bind_to_port if true immediately bind to the port, allocating one if - * necessary. true by default. - */ - explicit LocalListenSocket( - Network::Address::IpVersion ip_version = Network::Address::IpVersion::v4, uint16_t port = 0, - const Network::Socket::OptionsSharedPtr& options = nullptr, bool bind_to_port = true); - - LocalListenSocket(const LocalListenSocket&) = delete; - void operator=(const LocalListenSocket&) = delete; -}; - -class LocalListenSocketFactory : public Network::ListenSocketFactory { -public: - explicit LocalListenSocketFactory( - Network::Address::IpVersion ip_version = Network::Address::IpVersion::v4, uint16_t port = 0, - const Network::Socket::OptionsSharedPtr& options = nullptr, bool bind_to_port = true); - // Network::ListenSocketFactory - Network::SocketSharedPtr getListenSocket() override { return local_listen_socket_; }; - Network::Address::SocketType socketType() const override { - return Network::Address::SocketType::Stream; - }; - const Network::Address::InstanceConstSharedPtr& localAddress() const override { - return local_listen_socket_->localAddress(); - }; - absl::optional> sharedSocket() const override { - return *local_listen_socket_; - }; - -private: - std::shared_ptr local_listen_socket_; -}; - -/** - * A convenience class for passing callbacks to a Server. If no callbacks are - * provided, default callbacks that track some simple metrics will be used. If - * callbacks are provided, they will be wrapped with callbacks that maintain the - * same simple set of metrics. - */ -class ServerCallbackHelper { -public: - explicit ServerCallbackHelper(ServerRequestCallback&& request_callback = nullptr, - ServerAcceptCallback&& accept_callback = nullptr, - ServerCloseCallback&& close_callback = nullptr); - ServerCallbackHelper(const ServerCallbackHelper&) = delete; - ServerCallbackHelper& operator=(const ServerCallbackHelper&) = delete; - virtual ~ServerCallbackHelper() = default; - - uint32_t connectionsAccepted() const; - uint32_t requestsReceived() const; - uint32_t localCloses() const; - uint32_t remoteCloses() const; - ServerAcceptCallback acceptCallback() const; - ServerRequestCallback requestCallback() const; - ServerCloseCallback closeCallback() const; - - /* - * Wait until the server has accepted n connections and seen them closed (due - * to error or client close) - */ - void wait(uint32_t connections); - - /* - * Wait until the server has seen a close for every connection it has - * accepted. - */ - void wait(); - -private: - ServerAcceptCallback accept_callback_; - ServerRequestCallback request_callback_; - ServerCloseCallback close_callback_; - - std::atomic accepts_{0}; - std::atomic requests_received_{0}; - uint32_t local_closes_{0}; - uint32_t remote_closes_{0}; - mutable absl::Mutex mutex_; -}; - -typedef std::unique_ptr ServerCallbackHelperPtr; -typedef std::shared_ptr ServerCallbackHelperSharedPtr; - -class Server : public Network::FilterChainManager, - public Network::FilterChainFactory, - public Network::ListenerConfig, - Logger::Loggable { -public: - Server(const std::string& name, Network::ListenSocketFactorySharedPtr listen_socket_factory, - Network::TransportSocketFactory& transport_socket_factory, - Http::CodecClient::Type http_type); - Server(const Server&) = delete; - Server& operator=(const Server&) = delete; - ~Server() override; - - void start(ServerAcceptCallback&& accept_callback, ServerRequestCallback&& request_callback, - ServerCloseCallback&& close_callback); - - void start(ServerCallbackHelper& helper); - - void stop(); - - void stopAcceptingConnections(); - - void startAcceptingConnections(); - - const Stats::Store& statsStore() const; - - void setPerConnectionBufferLimitBytes(uint32_t limit); - - // - // Network::ListenerConfig - // - - Network::FilterChainManager& filterChainManager() override; - - Network::FilterChainFactory& filterChainFactory() override; - - Network::ListenSocketFactory& listenSocketFactory() override; - - bool bindToPort() override; - - bool handOffRestoredDestinationConnections() const override; - - uint32_t perConnectionBufferLimitBytes() const override; - - std::chrono::milliseconds listenerFiltersTimeout() const override; - - bool continueOnListenerFiltersTimeout() const override; - - Stats::Scope& listenerScope() override; - - uint64_t listenerTag() const override; - - const std::string& name() const override; - - Network::ActiveUdpListenerFactory* udpListenerFactory() override; - - Network::ConnectionBalancer& connectionBalancer() override { return connection_balancer_; } - - envoy::config::core::v3::TrafficDirection direction() const override { - return envoy::config::core::v3::TrafficDirection::UNSPECIFIED; - } - - // - // Network::FilterChainManager - // - - const Network::FilterChain* findFilterChain(const Network::ConnectionSocket&) const override; - - // - // Network::FilterChainFactory - // - - bool createNetworkFilterChain(Network::Connection& network_connection, - const std::vector&) override; - - bool createListenerFilterChain(Network::ListenerFilterManager&) override; - - void createUdpListenerFilterChain(Network::UdpListenerFilterManager&, - Network::UdpReadFilterCallbacks&) override{}; - -private: - std::string name_; - Stats::IsolatedStoreImpl stats_; - Event::TestRealTimeSystem time_system_; - Api::Impl api_; - Event::DispatcherPtr dispatcher_; - Network::ConnectionHandlerPtr connection_handler_; - Network::NopConnectionBalancerImpl connection_balancer_; - Thread::ThreadPtr thread_; - std::atomic is_running{false}; - - ServerAcceptCallback accept_callback_{nullptr}; - ServerRequestCallback request_callback_{nullptr}; - ServerCloseCallback close_callback_{nullptr}; - - // - // Network::ListenerConfig - // - - Network::ListenSocketFactorySharedPtr listen_socket_factory_; - std::atomic connection_buffer_limit_bytes_{0U}; - - // - // Network::FilterChainManager - // - - ServerFilterChain server_filter_chain_; - - // - // Network::FilterChainFactory - // - - Http::CodecClient::Type http_type_; - std::atomic connection_counter_{0U}; -}; - -typedef std::unique_ptr ServerPtr; -typedef std::shared_ptr ServerSharedPtr; - -class ClusterHelper { -public: - explicit ClusterHelper(const std::string& name); - virtual ~ClusterHelper() = default; - ClusterHelper(const ClusterHelper&) = delete; - ClusterHelper& operator=(const ClusterHelper&) = delete; - - ClusterHelper& addServer(ServerCallbackHelperPtr&& server_callback); - - const std::vector& servers() const; - std::vector& servers(); - - inline const std::string& name() const { return name_; } - - uint32_t connectionsAccepted() const; - uint32_t requestsReceived() const; - uint32_t localCloses() const; - uint32_t remoteCloses() const; - - void wait(); - -private: - std::string name_; - std::vector server_callback_helpers_; -}; - -typedef std::unique_ptr ClusterHelperPtr; -typedef std::shared_ptr ClusterHelperSharedPtr; - -} // namespace Stress -} // namespace Envoy