Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions source/extensions/filters/http/local_ratelimit/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ namespace Extensions {
namespace HttpFilters {
namespace LocalRateLimitFilter {

Http::FilterFactoryCb LocalRateLimitFilterConfig::createFilterFactoryFromProtoTyped(
absl::StatusOr<Http::FilterFactoryCb> LocalRateLimitFilterConfig::createFilterFactoryFromProtoTyped(
const envoy::extensions::filters::http::local_ratelimit::v3::LocalRateLimit& proto_config,
const std::string&, Server::Configuration::FactoryContext& context) {

FilterConfigSharedPtr filter_config =
std::make_shared<FilterConfig>(proto_config, context.serverFactoryContext(), context.scope());
absl::Status creation_status = absl::OkStatus();
FilterConfigSharedPtr filter_config = std::make_shared<FilterConfig>(
proto_config, context.serverFactoryContext(), context.scope(), creation_status);
RETURN_IF_NOT_OK_REF(creation_status);
return [filter_config](Http::FilterChainFactoryCallbacks& callbacks) -> void {
callbacks.addStreamFilter(std::make_shared<Filter>(filter_config));
};
Expand All @@ -28,8 +30,10 @@ LocalRateLimitFilterConfig::createHttpFilterFactoryFromProtoTyped(
const envoy::extensions::filters::http::local_ratelimit::v3::LocalRateLimit& proto_config,
const std::string&, Server::Configuration::ServerFactoryContext& context) {

absl::Status creation_status = absl::OkStatus();
FilterConfigSharedPtr filter_config =
std::make_shared<FilterConfig>(proto_config, context, context.scope());
std::make_shared<FilterConfig>(proto_config, context, context.scope(), creation_status);
RETURN_IF_NOT_OK_REF(creation_status);
return [filter_config](Http::FilterChainFactoryCallbacks& callbacks) -> void {
callbacks.addStreamFilter(std::make_shared<Filter>(filter_config));
};
Expand All @@ -39,7 +43,12 @@ absl::StatusOr<Router::RouteSpecificFilterConfigConstSharedPtr>
LocalRateLimitFilterConfig::createRouteSpecificFilterConfigTyped(
const envoy::extensions::filters::http::local_ratelimit::v3::LocalRateLimit& proto_config,
Server::Configuration::ServerFactoryContext& context, ProtobufMessage::ValidationVisitor&) {
return std::make_shared<const FilterConfig>(proto_config, context, context.scope(), true);
absl::Status creation_status = absl::OkStatus();
auto filter_config =
std::make_shared<const FilterConfig>(proto_config, context, context.scope(), creation_status,
/*per_route=*/true);
RETURN_IF_NOT_OK_REF(creation_status);
return filter_config;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions source/extensions/filters/http/local_ratelimit/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ namespace LocalRateLimitFilter {
* Config registration for the local rate limit filter. @see NamedHttpFilterConfigFactory.
*/
class LocalRateLimitFilterConfig
: public Common::FactoryBase<
: public Common::ExceptionFreeFactoryBase<
envoy::extensions::filters::http::local_ratelimit::v3::LocalRateLimit> {
public:
LocalRateLimitFilterConfig() : FactoryBase("envoy.filters.http.local_ratelimit") {}
LocalRateLimitFilterConfig() : ExceptionFreeFactoryBase("envoy.filters.http.local_ratelimit") {}

private:
Http::FilterFactoryCb createFilterFactoryFromProtoTyped(
absl::StatusOr<Http::FilterFactoryCb> createFilterFactoryFromProtoTyped(
const envoy::extensions::filters::http::local_ratelimit::v3::LocalRateLimit& proto_config,
const std::string& stats_prefix, Server::Configuration::FactoryContext& context) override;
absl::StatusOr<Http::FilterFactoryCb> createHttpFilterFactoryFromProtoTyped(
Expand Down
44 changes: 29 additions & 15 deletions source/extensions/filters/http/local_ratelimit/local_ratelimit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ const std::string& PerConnectionRateLimiter::key() {

FilterConfig::FilterConfig(
const envoy::extensions::filters::http::local_ratelimit::v3::LocalRateLimit& config,
Server::Configuration::CommonFactoryContext& context, Stats::Scope& scope, const bool per_route)
Server::Configuration::CommonFactoryContext& context, Stats::Scope& scope,
absl::Status& creation_status, const bool per_route)
: dispatcher_(context.mainThreadDispatcher()), status_(toErrorCode(config.status().code())),
stats_(generateStats(config.stat_prefix(), scope)),
fill_interval_(std::chrono::milliseconds(
Expand All @@ -52,12 +53,6 @@ FilterConfig::FilterConfig(
? std::optional<Envoy::Runtime::FractionalPercent>(
Envoy::Runtime::FractionalPercent(config.filter_enforced(), runtime_))
: std::nullopt),
response_headers_parser_(THROW_OR_RETURN_VALUE(
Envoy::Router::HeaderParser::configure(config.response_headers_to_add()),
Router::HeaderParserPtr)),
request_headers_parser_(THROW_OR_RETURN_VALUE(
Envoy::Router::HeaderParser::configure(config.request_headers_to_add_when_not_enforced()),
Router::HeaderParserPtr)),
stage_(static_cast<uint64_t>(config.stage())),
has_descriptors_(!config.descriptors().empty()),
enable_x_rate_limit_headers_(config.enable_x_ratelimit_headers() ==
Expand All @@ -67,19 +62,32 @@ FilterConfig::FilterConfig(
config.rate_limited_as_resource_exhausted()
? std::make_optional(Grpc::Status::WellKnownGrpcStatus::ResourceExhausted)
: std::nullopt) {
auto response_headers_parser_or =
Envoy::Router::HeaderParser::configure(config.response_headers_to_add());
SET_AND_RETURN_IF_NOT_OK(response_headers_parser_or.status(), creation_status);
response_headers_parser_ = std::move(response_headers_parser_or.value());

auto request_headers_parser_or =
Envoy::Router::HeaderParser::configure(config.request_headers_to_add_when_not_enforced());
SET_AND_RETURN_IF_NOT_OK(request_headers_parser_or.status(), creation_status);
request_headers_parser_ = std::move(request_headers_parser_or.value());

// Note: no token bucket is fine for the global config, which would be the case for enabling
// the filter globally but disabled and then applying limits at the virtual host or
// route level. At the virtual or route level, it makes no sense to have an no token
// bucket so we throw an error. If there's no token bucket configured globally or
// bucket so we return an error. If there's no token bucket configured globally or
// at the vhost/route level, no rate limiting is applied.
if (per_route && !config.has_token_bucket()) {
throw EnvoyException("local rate limit token bucket must be set for per filter configs");
creation_status = absl::InvalidArgumentError(
"local rate limit token bucket must be set for per filter configs");
return;
}

absl::Status creation_status;
rate_limit_config_ = std::make_unique<Filters::Common::RateLimit::RateLimitConfig>(
config.rate_limits(), context, creation_status);
THROW_IF_NOT_OK_REF(creation_status);
if (!creation_status.ok()) {
return;
}

if (rate_limit_config_->empty()) {
if (!config.descriptors().empty()) {
Expand All @@ -94,19 +102,25 @@ FilterConfig::FilterConfig(
Filters::Common::LocalRateLimit::ShareProviderSharedPtr share_provider;
if (config.has_local_cluster_rate_limit()) {
if (rate_limit_per_connection_) {
throw EnvoyException("local_cluster_rate_limit is set and "
"local_rate_limit_per_downstream_connection is set to true");
creation_status =
absl::InvalidArgumentError("local_cluster_rate_limit is set and "
"local_rate_limit_per_downstream_connection is set to true");
return;
}
if (!context.clusterManager().localClusterName().has_value()) {
throw EnvoyException("local_cluster_rate_limit is set but no local cluster name is present");
creation_status = absl::InvalidArgumentError(
"local_cluster_rate_limit is set but no local cluster name is present");
return;
}

// If the local cluster name is set then the relevant cluster must exist or the cluster
// manager will fail to initialize.
share_provider_manager_ = Filters::Common::LocalRateLimit::ShareProviderManager::singleton(
dispatcher_, context.clusterManager(), context.singletonManager());
if (!share_provider_manager_) {
throw EnvoyException("local_cluster_rate_limit is set but no local cluster is present");
creation_status = absl::InvalidArgumentError(
"local_cluster_rate_limit is set but no local cluster is present");
return;
}

share_provider = share_provider_manager_->getShareProvider(config.local_cluster_rate_limit());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class FilterConfig : public Router::RouteSpecificFilterConfig,
public:
FilterConfig(const envoy::extensions::filters::http::local_ratelimit::v3::LocalRateLimit& config,
Server::Configuration::CommonFactoryContext& context, Stats::Scope& scope,
const bool per_route = false);
absl::Status& creation_status, const bool per_route = false);
~FilterConfig() override {
// Ensure that the LocalRateLimiterImpl instance will be destroyed on the thread where its inner
// timer is created and running.
Expand Down
2 changes: 1 addition & 1 deletion source/extensions/filters/http/mcp/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Extensions {
namespace HttpFilters {
namespace Mcp {

Http::FilterFactoryCb McpFilterConfigFactory::createFilterFactoryFromProtoTyped(
absl::StatusOr<Http::FilterFactoryCb> McpFilterConfigFactory::createFilterFactoryFromProtoTyped(
const envoy::extensions::filters::http::mcp::v3::Mcp& proto_config,
const std::string& stats_prefix, Server::Configuration::FactoryContext& context) {

Expand Down
10 changes: 5 additions & 5 deletions source/extensions/filters/http/mcp/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ namespace Mcp {
/**
* Config factory for MCP filter.
*/
class McpFilterConfigFactory
: public Common::FactoryBase<envoy::extensions::filters::http::mcp::v3::Mcp,
envoy::extensions::filters::http::mcp::v3::McpOverride> {
class McpFilterConfigFactory : public Common::ExceptionFreeFactoryBase<
envoy::extensions::filters::http::mcp::v3::Mcp,
envoy::extensions::filters::http::mcp::v3::McpOverride> {
public:
McpFilterConfigFactory() : FactoryBase("envoy.filters.http.mcp") {}
McpFilterConfigFactory() : ExceptionFreeFactoryBase("envoy.filters.http.mcp") {}

private:
Http::FilterFactoryCb createFilterFactoryFromProtoTyped(
absl::StatusOr<Http::FilterFactoryCb> createFilterFactoryFromProtoTyped(
const envoy::extensions::filters::http::mcp::v3::Mcp& proto_config,
const std::string& stats_prefix, Server::Configuration::FactoryContext& context) override;

Expand Down
3 changes: 2 additions & 1 deletion source/extensions/filters/http/mcp_router/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ namespace Extensions {
namespace HttpFilters {
namespace McpRouter {

Http::FilterFactoryCb McpRouterFilterConfigFactory::createFilterFactoryFromProtoTyped(
absl::StatusOr<Http::FilterFactoryCb>
McpRouterFilterConfigFactory::createFilterFactoryFromProtoTyped(
const envoy::extensions::filters::http::mcp_router::v3::McpRouter& proto_config,
const std::string& stats_prefix, Server::Configuration::FactoryContext& context) {

Expand Down
7 changes: 4 additions & 3 deletions source/extensions/filters/http/mcp_router/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,18 @@ namespace McpRouter {
* Config factory for MCP router filter.
*/
class McpRouterFilterConfigFactory
: public Common::FactoryBase<envoy::extensions::filters::http::mcp_router::v3::McpRouter> {
: public Common::ExceptionFreeFactoryBase<
envoy::extensions::filters::http::mcp_router::v3::McpRouter> {
public:
McpRouterFilterConfigFactory() : FactoryBase("envoy.filters.http.mcp_router") {}
McpRouterFilterConfigFactory() : ExceptionFreeFactoryBase("envoy.filters.http.mcp_router") {}

private:
bool
isTerminalFilterByProtoTyped(const envoy::extensions::filters::http::mcp_router::v3::McpRouter&,
Server::Configuration::ServerFactoryContext&) override {
return true;
}
Http::FilterFactoryCb createFilterFactoryFromProtoTyped(
absl::StatusOr<Http::FilterFactoryCb> createFilterFactoryFromProtoTyped(
const envoy::extensions::filters::http::mcp_router::v3::McpRouter& proto_config,
const std::string& stats_prefix, Server::Configuration::FactoryContext& context) override;
};
Expand Down
17 changes: 12 additions & 5 deletions source/extensions/filters/http/on_demand/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ namespace Extensions {
namespace HttpFilters {
namespace OnDemand {

Http::FilterFactoryCb OnDemandFilterFactory::createFilterFactoryFromProtoTyped(
absl::StatusOr<Http::FilterFactoryCb> OnDemandFilterFactory::createFilterFactoryFromProtoTyped(
const envoy::extensions::filters::http::on_demand::v3::OnDemand& proto_config,
const std::string&, Server::Configuration::FactoryContext& context) {
absl::Status creation_status = absl::OkStatus();
OnDemandFilterConfigSharedPtr config = std::make_shared<OnDemandFilterConfig>(
proto_config, context.serverFactoryContext().clusterManager(),
context.messageValidationVisitor());
context.messageValidationVisitor(), creation_status);
RETURN_IF_NOT_OK_REF(creation_status);
return [config](Http::FilterChainFactoryCallbacks& callbacks) -> void {
callbacks.addStreamDecoderFilter(std::make_shared<OnDemandRouteUpdate>(config));
};
Expand All @@ -23,8 +25,10 @@ Http::FilterFactoryCb OnDemandFilterFactory::createFilterFactoryFromProtoTyped(
absl::StatusOr<Http::FilterFactoryCb> OnDemandFilterFactory::createHttpFilterFactoryFromProtoTyped(
const envoy::extensions::filters::http::on_demand::v3::OnDemand& proto_config,
const std::string&, Server::Configuration::ServerFactoryContext& context) {
absl::Status creation_status = absl::OkStatus();
OnDemandFilterConfigSharedPtr config = std::make_shared<OnDemandFilterConfig>(
proto_config, context.clusterManager(), context.messageValidationVisitor());
proto_config, context.clusterManager(), context.messageValidationVisitor(), creation_status);
RETURN_IF_NOT_OK_REF(creation_status);
return [config](Http::FilterChainFactoryCallbacks& callbacks) -> void {
callbacks.addStreamDecoderFilter(std::make_shared<OnDemandRouteUpdate>(config));
};
Expand All @@ -35,8 +39,11 @@ OnDemandFilterFactory::createRouteSpecificFilterConfigTyped(
const envoy::extensions::filters::http::on_demand::v3::PerRouteConfig& proto_config,
Server::Configuration::ServerFactoryContext& context,
ProtobufMessage::ValidationVisitor& validation_visitor) {
return std::make_shared<const OnDemandFilterConfig>(proto_config, context.clusterManager(),
validation_visitor);
absl::Status creation_status = absl::OkStatus();
auto config = std::make_shared<const OnDemandFilterConfig>(proto_config, context.clusterManager(),
validation_visitor, creation_status);
RETURN_IF_NOT_OK_REF(creation_status);
return config;
}

/**
Expand Down
10 changes: 5 additions & 5 deletions source/extensions/filters/http/on_demand/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ namespace OnDemand {
/**
* Config registration for the OnDemand filter. @see NamedHttpFilterConfigFactory.
*/
class OnDemandFilterFactory
: public Common::FactoryBase<envoy::extensions::filters::http::on_demand::v3::OnDemand,
envoy::extensions::filters::http::on_demand::v3::PerRouteConfig> {
class OnDemandFilterFactory : public Common::ExceptionFreeFactoryBase<
envoy::extensions::filters::http::on_demand::v3::OnDemand,
envoy::extensions::filters::http::on_demand::v3::PerRouteConfig> {
public:
OnDemandFilterFactory() : FactoryBase(HttpFilterNames::get().OnDemand) {}
OnDemandFilterFactory() : ExceptionFreeFactoryBase(HttpFilterNames::get().OnDemand) {}

private:
Http::FilterFactoryCb createFilterFactoryFromProtoTyped(
absl::StatusOr<Http::FilterFactoryCb> createFilterFactoryFromProtoTyped(
const envoy::extensions::filters::http::on_demand::v3::OnDemand& proto_config,
const std::string&, Server::Configuration::FactoryContext& context) override;

Expand Down
Loading
Loading