Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions source/common/router/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ envoy_cc_library(
"//source/common/config:utility_lib",
"//source/common/config:well_known_names",
"//source/common/formatter:substitution_format_string_lib",
"//source/common/grpc:common_lib",
"//source/common/http:hash_policy_lib",
"//source/common/http:header_mutation_lib",
"//source/common/http:header_utility_lib",
Expand Down
82 changes: 42 additions & 40 deletions source/common/router/config_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@ bool RouteEntryImplBase::isRedirect() const {
redirect_config_->regex_rewrite_redirect_ != nullptr;
}

bool RouteEntryImplBase::matchRoute(const Http::RequestHeaderMap& headers,
bool RouteEntryImplBase::matchRoute(const RouteMatchContext& route_match_context,
const StreamInfo::StreamInfo& stream_info,
uint64_t random_value) const {
bool matches = true;
Expand All @@ -864,31 +864,26 @@ bool RouteEntryImplBase::matchRoute(const Http::RequestHeaderMap& headers,
}

if (match_grpc_) {
matches &= Grpc::Common::isGrpcRequestHeaders(headers);
if (!matches) {
if (!route_match_context.isGrpc()) {
return false;
}
}

const Http::RequestHeaderMap& headers = route_match_context.headers();
matches &= Http::HeaderUtility::matchHeaders(headers, config_headers_);
if (!matches) {
return false;
}
if (!config_query_parameters_.empty()) {
auto query_parameters =
Http::Utility::QueryParamsMulti::parseQueryString(headers.getPathValue());
matches &= ConfigUtility::matchQueryParams(query_parameters, config_query_parameters_);
matches &= ConfigUtility::matchQueryParams(route_match_context.queryParams(),
config_query_parameters_);
if (!matches) {
return false;
}
}

if (!config_cookies_.empty()) {
const auto cookies =
Http::Utility::parseCookies(headers, [this](absl::string_view key) -> bool {
return config_cookie_names_.find(key) != config_cookie_names_.end();
});
if (!ConfigUtility::matchCookies(cookies, config_cookies_)) {
if (!ConfigUtility::matchCookies(route_match_context.cookies(), config_cookies_)) {
return false;
}
}
Expand Down Expand Up @@ -1397,12 +1392,12 @@ std::string UriTemplateMatcherRouteEntryImpl::currentUrlPathAfterRewrite(
}

RouteConstSharedPtr
UriTemplateMatcherRouteEntryImpl::matches(const Http::RequestHeaderMap& headers,
UriTemplateMatcherRouteEntryImpl::matches(const RouteMatchContext& route_match_context,
const StreamInfo::StreamInfo& stream_info,
uint64_t random_value) const {
if (RouteEntryImplBase::matchRoute(headers, stream_info, random_value) &&
path_matcher_->match(headers.getPathValue())) {
return clusterEntry(headers, stream_info, random_value);
if (RouteEntryImplBase::matchRoute(route_match_context, stream_info, random_value) &&
path_matcher_->match(route_match_context.path())) {
return clusterEntry(route_match_context.headers(), stream_info, random_value);
}
return nullptr;
}
Expand Down Expand Up @@ -1430,12 +1425,12 @@ PrefixRouteEntryImpl::currentUrlPathAfterRewrite(const Http::RequestHeaderMap& h
return currentUrlPathAfterRewriteWithMatchedPath(headers, context, stream_info, matcher());
}

RouteConstSharedPtr PrefixRouteEntryImpl::matches(const Http::RequestHeaderMap& headers,
RouteConstSharedPtr PrefixRouteEntryImpl::matches(const RouteMatchContext& route_match_context,
const StreamInfo::StreamInfo& stream_info,
uint64_t random_value) const {
if (RouteEntryImplBase::matchRoute(headers, stream_info, random_value) &&
path_matcher_->match(sanitizePathBeforePathMatching(headers.getPathValue()))) {
return clusterEntry(headers, stream_info, random_value);
if (RouteEntryImplBase::matchRoute(route_match_context, stream_info, random_value) &&
path_matcher_->match(route_match_context.sanitizedPath())) {
return clusterEntry(route_match_context.headers(), stream_info, random_value);
}
return nullptr;
}
Expand Down Expand Up @@ -1464,12 +1459,12 @@ PathRouteEntryImpl::currentUrlPathAfterRewrite(const Http::RequestHeaderMap& hea
return currentUrlPathAfterRewriteWithMatchedPath(headers, context, stream_info, matcher());
}

RouteConstSharedPtr PathRouteEntryImpl::matches(const Http::RequestHeaderMap& headers,
RouteConstSharedPtr PathRouteEntryImpl::matches(const RouteMatchContext& route_match_context,
const StreamInfo::StreamInfo& stream_info,
uint64_t random_value) const {
if (RouteEntryImplBase::matchRoute(headers, stream_info, random_value) &&
path_matcher_->match(sanitizePathBeforePathMatching(headers.getPathValue()))) {
return clusterEntry(headers, stream_info, random_value);
if (RouteEntryImplBase::matchRoute(route_match_context, stream_info, random_value) &&
path_matcher_->match(route_match_context.sanitizedPath())) {
return clusterEntry(route_match_context.headers(), stream_info, random_value);
}

return nullptr;
Expand Down Expand Up @@ -1505,12 +1500,12 @@ RegexRouteEntryImpl::currentUrlPathAfterRewrite(const Http::RequestHeaderMap& he
return currentUrlPathAfterRewriteWithMatchedPath(headers, context, stream_info, path);
}

RouteConstSharedPtr RegexRouteEntryImpl::matches(const Http::RequestHeaderMap& headers,
RouteConstSharedPtr RegexRouteEntryImpl::matches(const RouteMatchContext& route_match_context,
const StreamInfo::StreamInfo& stream_info,
uint64_t random_value) const {
if (RouteEntryImplBase::matchRoute(headers, stream_info, random_value)) {
if (path_matcher_->match(sanitizePathBeforePathMatching(headers.getPathValue()))) {
return clusterEntry(headers, stream_info, random_value);
if (RouteEntryImplBase::matchRoute(route_match_context, stream_info, random_value)) {
if (path_matcher_->match(route_match_context.sanitizedPathWithoutQuery())) {
return clusterEntry(route_match_context.headers(), stream_info, random_value);
}
}
return nullptr;
Expand All @@ -1536,12 +1531,13 @@ ConnectRouteEntryImpl::currentUrlPathAfterRewrite(const Http::RequestHeaderMap&
return currentUrlPathAfterRewriteWithMatchedPath(headers, context, stream_info, path);
}

RouteConstSharedPtr ConnectRouteEntryImpl::matches(const Http::RequestHeaderMap& headers,
RouteConstSharedPtr ConnectRouteEntryImpl::matches(const RouteMatchContext& route_match_context,
const StreamInfo::StreamInfo& stream_info,
uint64_t random_value) const {
const Http::RequestHeaderMap& headers = route_match_context.headers();
if ((Http::HeaderUtility::isConnect(headers) ||
Http::HeaderUtility::isConnectUdpRequest(headers)) &&
RouteEntryImplBase::matchRoute(headers, stream_info, random_value)) {
RouteEntryImplBase::matchRoute(route_match_context, stream_info, random_value)) {
return clusterEntry(headers, stream_info, random_value);
}
return nullptr;
Expand Down Expand Up @@ -1570,19 +1566,18 @@ std::string PathSeparatedPrefixRouteEntryImpl::currentUrlPathAfterRewrite(
}

RouteConstSharedPtr
PathSeparatedPrefixRouteEntryImpl::matches(const Http::RequestHeaderMap& headers,
PathSeparatedPrefixRouteEntryImpl::matches(const RouteMatchContext& route_match_context,
const StreamInfo::StreamInfo& stream_info,
uint64_t random_value) const {
if (!RouteEntryImplBase::matchRoute(headers, stream_info, random_value)) {
if (!RouteEntryImplBase::matchRoute(route_match_context, stream_info, random_value)) {
return nullptr;
}
absl::string_view sanitized_path = sanitizePathBeforePathMatching(
Http::PathUtil::removeQueryAndFragment(headers.getPathValue()));
const absl::string_view sanitized_path = route_match_context.sanitizedPathWithoutQuery();
const size_t sanitized_size = sanitized_path.size();
const size_t matcher_size = matcher().size();
if (sanitized_size >= matcher_size && path_matcher_->match(sanitized_path) &&
(sanitized_size == matcher_size || sanitized_path[matcher_size] == '/')) {
return clusterEntry(headers, stream_info, random_value);
return clusterEntry(route_match_context.headers(), stream_info, random_value);
}
return nullptr;
}
Expand Down Expand Up @@ -1800,15 +1795,16 @@ VirtualHostImpl::VirtualHostImpl(const envoy::config::route::v3::VirtualHost& vi
}

RouteConstSharedPtr VirtualHostImpl::getRouteFromRoutes(
const RouteCallback& cb, const Http::RequestHeaderMap& headers,
const RouteCallback& cb, const RouteMatchContext& route_match_context,
const StreamInfo::StreamInfo& stream_info, uint64_t random_value,
absl::Span<const RouteEntryImplBaseConstSharedPtr> routes) const {
for (auto route = routes.begin(); route != routes.end(); ++route) {
if (!headers.Path() && !(*route)->supportsPathlessHeaders()) {
if (!route_match_context.headers().Path() && !(*route)->supportsPathlessHeaders()) {
continue;
}

RouteConstSharedPtr route_entry = (*route)->matches(headers, stream_info, random_value);
RouteConstSharedPtr route_entry =
(*route)->matches(route_match_context, stream_info, random_value);
if (route_entry == nullptr) {
continue;
}
Expand Down Expand Up @@ -1859,6 +1855,11 @@ RouteConstSharedPtr VirtualHostImpl::getRouteFromEntries(const RouteCallback& cb
return ssl_redirect_route_;
}

// Constructed once per request; derived values (query params, cookies, etc.) are computed
// lazily on first access and reused across all route entries evaluated for this request.
const RouteMatchContext route_match_context(
headers, shared_virtual_host_->globalRouteConfig().ignorePathParametersInPathMatching());

if (matcher_) {
Http::Matching::HttpMatchingDataImpl data(stream_info);
data.onRequestHeaders(headers);
Expand All @@ -1870,11 +1871,12 @@ RouteConstSharedPtr VirtualHostImpl::getRouteFromEntries(const RouteCallback& cb
const auto result = match_result.actionByMove();
if (result->typeUrl() == RouteMatchAction::staticTypeUrl()) {
return getRouteFromRoutes(
cb, headers, stream_info, random_value,
cb, route_match_context, stream_info, random_value,
{std::dynamic_pointer_cast<const RouteEntryImplBase>(std::move(result))});
} else if (result->typeUrl() == RouteListMatchAction::staticTypeUrl()) {
const RouteListMatchAction& action = result->getTyped<RouteListMatchAction>();
return getRouteFromRoutes(cb, headers, stream_info, random_value, action.routes());
return getRouteFromRoutes(cb, route_match_context, stream_info, random_value,
action.routes());
}
PANIC("Action in router matcher should be Route or RouteList");
}
Expand All @@ -1886,7 +1888,7 @@ RouteConstSharedPtr VirtualHostImpl::getRouteFromEntries(const RouteCallback& cb
}

// Check for a route that matches the request.
return getRouteFromRoutes(cb, headers, stream_info, random_value, routes_);
return getRouteFromRoutes(cb, route_match_context, stream_info, random_value, routes_);
}

const VirtualHostImpl* RouteMatcher::findWildcardVirtualHost(
Expand Down
Loading
Loading