Skip to content
Merged
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
2 changes: 2 additions & 0 deletions DEPRECATED.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ A logged warning is expected for each deprecated item that is in deprecation win
[HttpConnectionManager](https://github.com/envoyproxy/envoy/blob/master/api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto)
instead.
* Setting hosts via `hosts` field in `Cluster` is deprecated. Use `load_assignment` instead.
* Use of `response_headers_to_*` and `request_headers_to_add` are deprecated at the `RouteAction`
level. Please use the configuration options at the `Route` level.

## Version 1.7.0

Expand Down
58 changes: 33 additions & 25 deletions api/envoy/api/v2/route/route.proto
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ message VirtualHost {

// Specifies a list of HTTP headers that should be added to each request
// handled by this virtual host. Headers specified at this level are applied
// after headers from enclosed :ref:`envoy_api_msg_route.RouteAction` and before headers from the
// after headers from enclosed :ref:`envoy_api_msg_route.Route` and before headers from the
// enclosing :ref:`envoy_api_msg_RouteConfiguration`. For more information, including
// details on header value syntax, see the documentation on :ref:`custom request headers
// <config_http_conn_man_headers_custom_request_headers>`.
repeated core.HeaderValueOption request_headers_to_add = 7;

// Specifies a list of HTTP headers that should be added to each response
// handled by this virtual host. Headers specified at this level are applied
// after headers from enclosed :ref:`envoy_api_msg_route.RouteAction` and before headers from the
// after headers from enclosed :ref:`envoy_api_msg_route.Route` and before headers from the
// enclosing :ref:`envoy_api_msg_RouteConfiguration`. For more information, including
// details on header value syntax, see the documentation on :ref:`custom request headers
// <config_http_conn_man_headers_custom_request_headers>`.
Expand Down Expand Up @@ -148,6 +148,26 @@ message Route {
// specific; see the :ref:`HTTP filter documentation <config_http_filters>` for
// if and how it is utilized.
map<string, google.protobuf.Struct> per_filter_config = 8;

// Specifies a set of headers that will be added to requests matching this
// route. Headers specified at this level are applied before headers from the
// enclosing :ref:`envoy_api_msg_route.VirtualHost` and
// :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on
// header value syntax, see the documentation on :ref:`custom request headers
// <config_http_conn_man_headers_custom_request_headers>`.
repeated core.HeaderValueOption request_headers_to_add = 9;

// Specifies a set of headers that will be added to responses to requests
// matching this route. Headers specified at this level are applied before
// headers from the enclosing :ref:`envoy_api_msg_route.VirtualHost` and
// :ref:`envoy_api_msg_RouteConfiguration`. For more information, including
// details on header value syntax, see the documentation on
// :ref:`custom request headers <config_http_conn_man_headers_custom_request_headers>`.
repeated core.HeaderValueOption response_headers_to_add = 10;

// Specifies a list of HTTP headers that should be removed from each response
// to requests matching this route.
repeated string response_headers_to_remove = 11;
}

// Compared to the :ref:`cluster <envoy_api_field_route.RouteAction.cluster>` field that specifies a
Expand Down Expand Up @@ -176,8 +196,7 @@ message WeightedCluster {
// Specifies a list of headers to be added to requests when this cluster is selected
// through the enclosing :ref:`envoy_api_msg_route.RouteAction`.
// Headers specified at this level are applied before headers from the enclosing
// :ref:`envoy_api_msg_route.RouteAction`,
// :ref:`envoy_api_msg_route.VirtualHost`, and
// :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_route.VirtualHost`, and
// :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on
// header value syntax, see the documentation on :ref:`custom request headers
// <config_http_conn_man_headers_custom_request_headers>`.
Expand All @@ -186,8 +205,7 @@ message WeightedCluster {
// Specifies a list of headers to be added to responses when this cluster is selected
// through the enclosing :ref:`envoy_api_msg_route.RouteAction`.
// Headers specified at this level are applied before headers from the enclosing
// :ref:`envoy_api_msg_route.RouteAction`,
// :ref:`envoy_api_msg_route.VirtualHost`, and
// :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_route.VirtualHost`, and
// :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on
// header value syntax, see the documentation on :ref:`custom request headers
// <config_http_conn_man_headers_custom_request_headers>`.
Expand Down Expand Up @@ -492,25 +510,14 @@ message RouteAction {
// https://github.com/lyft/protoc-gen-validate/issues/42 is resolved.]
core.RoutingPriority priority = 11;

// Specifies a set of headers that will be added to requests matching this
// route. Headers specified at this level are applied before headers from the
// enclosing :ref:`envoy_api_msg_route.VirtualHost` and
// :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on
// header value syntax, see the documentation on :ref:`custom request headers
// <config_http_conn_man_headers_custom_request_headers>`.
repeated core.HeaderValueOption request_headers_to_add = 12;
// [#not-implemented-hide:]
repeated core.HeaderValueOption request_headers_to_add = 12 [deprecated = true];

// Specifies a set of headers that will be added to responses to requests
// matching this route. Headers specified at this level are applied before
// headers from the enclosing :ref:`envoy_api_msg_route.VirtualHost` and
// :ref:`envoy_api_msg_RouteConfiguration`. For more information, including
// details on header value syntax, see the documentation on
// :ref:`custom request headers <config_http_conn_man_headers_custom_request_headers>`.
repeated core.HeaderValueOption response_headers_to_add = 18;
// [#not-implemented-hide:]
repeated core.HeaderValueOption response_headers_to_add = 18 [deprecated = true];

// Specifies a list of HTTP headers that should be removed from each response
// to requests matching this route.
repeated string response_headers_to_remove = 19;
// [#not-implemented-hide:]
repeated string response_headers_to_remove = 19 [deprecated = true];

// Specifies a set of rate limit configurations that could be applied to the
// route.
Expand Down Expand Up @@ -711,8 +718,9 @@ message DirectResponseAction {
//
// .. note::
//
// Headers can be specified using *response_headers_to_add* in
// :ref:`envoy_api_msg_RouteConfiguration`.
// Headers can be specified using *response_headers_to_add* in the enclosing
// :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_RouteConfiguration` or
// :ref:`envoy_api_msg_route.VirtualHost`.
core.DataSource body = 2;
}

Expand Down
1 change: 1 addition & 0 deletions docs/root/intro/version_history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Version history
:ref:`use_data_plane_proto<envoy_api_field_config.ratelimit.v2.RateLimitServiceConfig.use_data_plane_proto>`
boolean flag in the ratelimit configuration.
Support for the legacy proto :repo:`source/common/ratelimit/ratelimit.proto` is deprecated and will be removed at the start of the 1.9.0 release cycle.
* router: added ability to set request/response headers at the :ref:`envoy_api_msg_route.Route` level.
* tracing: added support for configuration of :ref:`tracing sampling
<envoy_api_field_config.filter.network.http_connection_manager.v2.HttpConnectionManager.tracing>`.
* upstream: added configuration option to the subset load balancer to take locality weights into account when
Expand Down
20 changes: 15 additions & 5 deletions source/common/router/config_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,13 @@ RouteEntryImplBase::RouteEntryImplBase(const VirtualHostImpl& vhost,
priority_(ConfigUtility::parsePriority(route.route().priority())),
total_cluster_weight_(
PROTOBUF_GET_WRAPPED_OR_DEFAULT(route.route().weighted_clusters(), total_weight, 100UL)),
request_headers_parser_(HeaderParser::configure(route.route().request_headers_to_add())),
response_headers_parser_(HeaderParser::configure(route.route().response_headers_to_add(),
route.route().response_headers_to_remove())),
route_action_request_headers_parser_(
HeaderParser::configure(route.route().request_headers_to_add())),
route_action_response_headers_parser_(HeaderParser::configure(
route.route().response_headers_to_add(), route.route().response_headers_to_remove())),
request_headers_parser_(HeaderParser::configure(route.request_headers_to_add())),
response_headers_parser_(HeaderParser::configure(route.response_headers_to_add(),
route.response_headers_to_remove())),
opaque_config_(parseOpaqueConfig(route)), decorator_(parseDecorator(route)),
direct_response_code_(ConfigUtility::parseDirectResponseCode(route)),
direct_response_body_(ConfigUtility::parseDirectResponseBody(route)),
Expand Down Expand Up @@ -369,8 +373,10 @@ Http::WebSocketProxyPtr RouteEntryImplBase::createWebSocketProxy(
void RouteEntryImplBase::finalizeRequestHeaders(Http::HeaderMap& headers,
const RequestInfo::RequestInfo& request_info,
bool insert_envoy_original_path) const {
// Append user-specified request headers in the following order: route-level headers,
// virtual host level headers and finally global connection manager level headers.
// Append user-specified request headers in the following order: route-action-level headers,
// route-level headers, virtual host level headers and finally global connection manager level
// headers.
route_action_request_headers_parser_->evaluateHeaders(headers, request_info);
request_headers_parser_->evaluateHeaders(headers, request_info);
vhost_.requestHeaderParser().evaluateHeaders(headers, request_info);
vhost_.globalRouteConfig().requestHeaderParser().evaluateHeaders(headers, request_info);
Expand All @@ -386,6 +392,10 @@ void RouteEntryImplBase::finalizeRequestHeaders(Http::HeaderMap& headers,

void RouteEntryImplBase::finalizeResponseHeaders(
Http::HeaderMap& headers, const RequestInfo::RequestInfo& request_info) const {
// Append user-specified response headers in the following order: route-action-level headers,
// route-level headers, virtual host level headers and finally global connection manager level
// headers.
route_action_response_headers_parser_->evaluateHeaders(headers, request_info);
response_headers_parser_->evaluateHeaders(headers, request_info);
vhost_.responseHeaderParser().evaluateHeaders(headers, request_info);
vhost_.globalRouteConfig().responseHeaderParser().evaluateHeaders(headers, request_info);
Expand Down
4 changes: 2 additions & 2 deletions source/common/router/config_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,6 @@ class RouteEntryImplBase : public RouteEntry,

void finalizePathHeader(Http::HeaderMap& headers, const std::string& matched_path,
bool insert_envoy_original_path) const;
const HeaderParser& requestHeaderParser() const { return *request_headers_parser_; };
const HeaderParser& responseHeaderParser() const { return *response_headers_parser_; };

private:
struct RuntimeData {
Expand Down Expand Up @@ -535,6 +533,8 @@ class RouteEntryImplBase : public RouteEntry,
const uint64_t total_cluster_weight_;
std::unique_ptr<const HashPolicyImpl> hash_policy_;
MetadataMatchCriteriaConstPtr metadata_match_criteria_;
HeaderParserPtr route_action_request_headers_parser_;
HeaderParserPtr route_action_response_headers_parser_;
HeaderParserPtr request_headers_parser_;
HeaderParserPtr response_headers_parser_;
envoy::api::v2::core::Metadata metadata_;
Expand Down
62 changes: 42 additions & 20 deletions test/common/router/config_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ TEST(RouteMatcherTest, TestRoutesWithInvalidRegex) {
EnvoyException, "Invalid regex '\\^/\\(\\+invalid\\)':");
}

// Validates behavior of request_headers_to_add at router, vhost, and route levels.
// Validates behavior of request_headers_to_add at router, vhost, and route action levels.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, we need to add tests for the route level too.

TEST(RouteMatcherTest, TestAddRemoveRequestHeaders) {
std::string json = R"EOF(
{
Expand All @@ -552,14 +552,14 @@ TEST(RouteMatcherTest, TestAddRemoveRequestHeaders) {
"request_headers_to_add": [
{"key": "x-global-header1", "value": "route-override"},
{"key": "x-vhost-header1", "value": "route-override"},
{"key": "x-route-header", "value": "route-new_endpoint"}
{"key": "x-route-action-header", "value": "route-new_endpoint"}
]
},
{
"path": "/",
"cluster": "root_www2",
"request_headers_to_add": [
{"key": "x-route-header", "value": "route-allpath"}
{"key": "x-route-action-header", "value": "route-allpath"}
]
},
{
Expand All @@ -579,7 +579,7 @@ TEST(RouteMatcherTest, TestAddRemoveRequestHeaders) {
"prefix": "/",
"cluster": "www2_staging",
"request_headers_to_add": [
{"key": "x-route-header", "value": "route-allprefix"}
{"key": "x-route-action-header", "value": "route-allprefix"}
]
}
]
Expand Down Expand Up @@ -629,7 +629,7 @@ TEST(RouteMatcherTest, TestAddRemoveRequestHeaders) {
route->finalizeRequestHeaders(headers, request_info, true);
EXPECT_EQ("route-override", headers.get_("x-global-header1"));
EXPECT_EQ("route-override", headers.get_("x-vhost-header1"));
EXPECT_EQ("route-new_endpoint", headers.get_("x-route-header"));
EXPECT_EQ("route-new_endpoint", headers.get_("x-route-action-header"));
}

// Multiple routes can have same route-level headers with different values.
Expand All @@ -639,7 +639,7 @@ TEST(RouteMatcherTest, TestAddRemoveRequestHeaders) {
route->finalizeRequestHeaders(headers, request_info, true);
EXPECT_EQ("vhost-override", headers.get_("x-global-header1"));
EXPECT_EQ("vhost1-www2", headers.get_("x-vhost-header1"));
EXPECT_EQ("route-allpath", headers.get_("x-route-header"));
EXPECT_EQ("route-allpath", headers.get_("x-route-action-header"));
}

// Multiple virtual hosts can have same virtual host level headers with different values.
Expand All @@ -649,7 +649,7 @@ TEST(RouteMatcherTest, TestAddRemoveRequestHeaders) {
route->finalizeRequestHeaders(headers, request_info, true);
EXPECT_EQ("global1", headers.get_("x-global-header1"));
EXPECT_EQ("vhost1-www2_staging", headers.get_("x-vhost-header1"));
EXPECT_EQ("route-allprefix", headers.get_("x-route-header"));
EXPECT_EQ("route-allprefix", headers.get_("x-route-action-header"));
}

// Global headers.
Expand All @@ -662,8 +662,8 @@ TEST(RouteMatcherTest, TestAddRemoveRequestHeaders) {
}
}

// Validates behavior of request_headers_to_add at router, vhost, and route levels when append
// is disabled.
// Validates behavior of request_headers_to_add at router, vhost, route, and route action levels
// when append is disabled.
TEST(RouteMatcherTest, TestRequestHeadersToAddWithAppendFalse) {
std::string yaml = R"EOF(
name: foo
Expand All @@ -681,20 +681,36 @@ name: foo
append: false
routes:
- match: { prefix: "/endpoint" }
request_headers_to_add:
- header:
key: x-global-header
value: route-endpoint
append: false
- header:
key: x-vhost-header
value: route-endpoint
append: false
- header:
key: x-route-header
value: route-endpoint
append: false
route:
cluster: www2
request_headers_to_add:
- header:
key: x-global-header
value: route-endpoint
value: route-action-endpoint
append: false
- header:
key: x-vhost-header
value: route-endpoint
value: route-action-endpoint
append: false
- header:
key: x-route-header
value: route-endpoint
value: route-action-endpoint
- header:
key: x-route-action-header
value: route-action-endpoint
append: false
- match: { prefix: "/" }
route: { cluster: www2 }
Expand All @@ -714,14 +730,15 @@ name: foo

// Request header manipulation testing.
{
// Global and virtual host override route.
// Global and virtual host override route, route overrides route action.
{
Http::TestHeaderMapImpl headers = genHeaders("www.lyft.com", "/endpoint", "GET");
const RouteEntry* route = config.route(headers, 0)->routeEntry();
route->finalizeRequestHeaders(headers, request_info, true);
EXPECT_EQ("global", headers.get_("x-global-header"));
EXPECT_EQ("vhost-www2", headers.get_("x-vhost-header"));
EXPECT_EQ("route-endpoint", headers.get_("x-route-header"));
EXPECT_EQ("route-action-endpoint", headers.get_("x-route-action-header"));
}

// Global overrides virtual host.
Expand All @@ -736,7 +753,7 @@ name: foo
}

// Validates behavior of response_headers_to_add and response_headers_to_remove at router, vhost,
// and route levels.
// route, and route action levels.
TEST(RouteMatcherTest, TestAddRemoveResponseHeaders) {
std::string yaml = R"EOF(
name: foo
Expand All @@ -753,6 +770,10 @@ name: foo
response_headers_to_remove: ["x-vhost-remove"]
routes:
- match: { prefix: "/new_endpoint" }
response_headers_to_add:
- header:
key: x-route-header
value: route-override
route:
prefix_rewrite: "/api/new_endpoint"
cluster: www2
Expand All @@ -764,14 +785,14 @@ name: foo
key: x-vhost-header1
value: route-override
- header:
key: x-route-header
key: x-route-action-header
value: route-new_endpoint
- match: { path: "/" }
route:
cluster: root_www2
response_headers_to_add:
- header:
key: x-route-header
key: x-route-action-header
value: route-allpath
response_headers_to_remove: ["x-route-remove"]
- match: { prefix: "/" }
Expand All @@ -788,7 +809,7 @@ name: foo
cluster: www2_staging
response_headers_to_add:
- header:
key: x-route-header
key: x-route-action-header
value: route-allprefix
- name: default
domains: ["*"]
Expand Down Expand Up @@ -817,7 +838,8 @@ response_headers_to_remove: ["x-global-remove"]
route->finalizeResponseHeaders(headers, request_info);
EXPECT_EQ("route-override", headers.get_("x-global-header1"));
EXPECT_EQ("route-override", headers.get_("x-vhost-header1"));
EXPECT_EQ("route-new_endpoint", headers.get_("x-route-header"));
EXPECT_EQ("route-new_endpoint", headers.get_("x-route-action-header"));
EXPECT_EQ("route-override", headers.get_("x-route-header"));
}

// Multiple routes can have same route-level headers with different values.
Expand All @@ -828,7 +850,7 @@ response_headers_to_remove: ["x-global-remove"]
route->finalizeResponseHeaders(headers, request_info);
EXPECT_EQ("vhost-override", headers.get_("x-global-header1"));
EXPECT_EQ("vhost1-www2", headers.get_("x-vhost-header1"));
EXPECT_EQ("route-allpath", headers.get_("x-route-header"));
EXPECT_EQ("route-allpath", headers.get_("x-route-action-header"));
}

// Multiple virtual hosts can have same virtual host level headers with different values.
Expand All @@ -839,7 +861,7 @@ response_headers_to_remove: ["x-global-remove"]
route->finalizeResponseHeaders(headers, request_info);
EXPECT_EQ("global1", headers.get_("x-global-header1"));
EXPECT_EQ("vhost1-www2_staging", headers.get_("x-vhost-header1"));
EXPECT_EQ("route-allprefix", headers.get_("x-route-header"));
EXPECT_EQ("route-allprefix", headers.get_("x-route-action-header"));
}

// Global headers.
Expand Down