Closed willemveerman closed 1 week ago
The cluster_xxx features in the route action are invoked during the route match. So the headers added in the HTTP filter, which is chosen after the route match, won't affect the behavior of cluster selection.
I don't try them myself but there may be some ways to satisfy your requirement:
break down the adding header logic and cluster selection, so the cluster will be dynamically set via cluster-specific plugin without setting the header.
Yes I think this is the best way. If the ability to read all existing headers is added to the golang cluster_specifier
plugin then I can read the headers, decide on a cluster and then route to it - using only a single filter and within the route action section. This will remove the need to clear the route cache on every request.
I see now from the doc that you shared that a route is chosen before the HTTP filters are run, as stated here:
_When decodeHeaders() is invoked on the router filter, the route selection is finalized and a cluster is picked. The HCM selects a route from its RouteConfiguration at the start of HTTP filter chain execution. This is referred to as the cached route. Filters may modify headers and cause a new route to be selected, by asking HCM to clear the route cache and requesting HCM to reevaluate the route selection._
But it's a bit confusing because in other places in the Envoy docs they strongly imply that the router filter will run after the HTTP filter chain, as per point 6 in the request flow section:
_For each HTTP stream, an Downstream HTTP filter chain is created and runs. The request first passes through CustomFilter which may read and modify the request. The most important HTTP filter is the router filter which sits at the end of the HTTP filter chain. When decodeHeaders is invoked on the router filter, the route is selected and a cluster is picked._
https://github.com/envoyproxy/envoy/commit/6e3d574fb5b30fa7ac8e94248dc407354a11ceeb
HeaderMap.Set
won't clear route cache by default, it's first introduced in 1.30.0.
You need to clear route cache by using ClearRouteCache
instead.
Yep, api.FilterCallbackHandler.ClearRouteCache
enables the header change to take effect
Thank you for the information.
Once the capability to read the entire HeaderMap is added to the cluster_specifier
it will remove the need to clear the route cache
If you are reporting any crash or any potential security issue, do not open an issue in this repo. Please report the issue via emailing envoy-security@googlegroups.com where the issue will be triaged appropriately.
Title: Headers added by Envoy's HTTP filters are ignored by the router filter
Description: Envoy's
cluster_header
config option, as detailed here, will only route requests based on headers which are in the downstream request before it is processed by envoy's HTTP filters. If you add the specified header in thehttp_filters
config section, this is disregarded bycluster_header
.I would expect
cluster_header
to act upon headers which are added in thehttp_filters
section. My use-case is that I have written a golang plugin which adds a header to each request, and I want the request to be routed to a cluster based on the value of the header.Moreover, HTTP filters are processed in order, and the router filter must be placed last, therefore it's surprising that headers being added before
route_config
are being ignored bycluster_header
The golang cluster_specifier plugin behaves in the same way; it will ignore headers which are added within envoy in the
http_filters
section.Repro steps:
image: envoyproxy/envoy:contrib-v1.30.1
listener_0
returns a 503 -curl localhost:10000 -v
curl localhost:10000 -H "simple_test_header: magenta" -v
I would expect 1. to also route to magenta, because the
simple_test_header
has been added to the request.The issue also appears if I try to dynamically add headers using the golang http plugin.
This code snippet within the golang plugin:
with similar envoy config:
produces the same behaviour: the header added by the golang plugin is ignored by
cluster_header
Logs: logs from scenario 1. above
logs from scenario 2.