tcp tunneling: optionally move response header to downstream info#23118
tcp tunneling: optionally move response header to downstream info#23118ggreenway merged 14 commits intoenvoyproxy:mainfrom
Conversation
Signed-off-by: Kuat Yessenov <kuat@google.com>
|
CC @envoyproxy/api-shepherds: Your approval is needed for changes made to |
alyssawilk
left a comment
There was a problem hiding this comment.
Thanks for picking this up!
Now that I think about it this could be useful for the http11 connect filter: @Augustyniak was just writing an EM integraion test which added to CONNECT response headers and there was no way to validate them elsewhere. If we end up sticking with per-header-name configuration I think it may be worth defining the message somewhere in the base codec protos rather than in the tcp proxy proto for eventual reuse.
/wait
source/common/tcp_proxy/upstream.h
Outdated
| // Http::ResponseDecoder | ||
| void decode1xxHeaders(Http::ResponseHeaderMapPtr&&) override {} | ||
| void decodeHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) override { | ||
| parent_.config_.copyResponseHeaders(*headers, parent_.downstream_info_.filterState()); |
There was a problem hiding this comment.
Once we finish this function, don't we largely throw the headers away?
Would it make sense just to move the entire headers in the filter, with a well known name, rather than coping one bit of metadata at a time?
There was a problem hiding this comment.
Yeah, I think we could do that with little performance impact. One annoying issue is that we don't have a generic way to traverse the filter state that is a map of string to string. That latter issue has been a long standing blocker for replacing dynamic metadata with filter state so maybe we should just fix that as well.
There was a problem hiding this comment.
do we need a map of string to string? we could just create a filter state object "connect_headers" which we std::move the headers into?
There was a problem hiding this comment.
Yes, that's what I want to do. But then, for example, access log printers can only print it as a whole. It's not a problem for internal filter consumption, just generic inspectors like access log, etc.
| // Defines the mapping from the header value to a filter state object key. | ||
| message HeaderToFilterState { | ||
| // Filter state object key, prefixed with ``envoy.tcp_proxy.tunnel_response_header.``. | ||
| string key = 1 [(validate.rules).string = {min_len: 1}]; |
There was a problem hiding this comment.
If we do with putting in individual headers, is there value in being able to configure the key rather than just sticking header name at the end of the string?
There was a problem hiding this comment.
I'll try a complete bag copy, and in that case we can use one key for all of them.
| "envoy.config.filter.network.tcp_proxy.v2.TcpProxy.TunnelingConfig"; | ||
|
|
||
| // Defines the mapping from the header value to a filter state object key. | ||
| message HeaderToFilterState { |
There was a problem hiding this comment.
probably want a release note for this one once we've settled on API
|
|
||
| // Emit response headers to the downstream info filter state for consumption | ||
| // by the network filters. The filter state key is ``envoy.tcp_proxy.tunnel_response_headers``. | ||
| bool emit_response_headers = 4; |
There was a problem hiding this comment.
I'd lean towards something akin to
save_connect_headers but I'll defer to api shephards on this one :-)
There was a problem hiding this comment.
@markdroth For API review and deciding on naming.
There was a problem hiding this comment.
How about calling this propagate_response_headers?
alyssawilk
left a comment
There was a problem hiding this comment.
LGTM (though I still don't love emit - @markdroth ?)
Passing to Greg for !google pass
Signed-off-by: Kuat Yessenov <kuat@google.com>
|
/lgtm api |
alyssawilk
left a comment
There was a problem hiding this comment.
Yeah I like this better - thanks for your patience with naming
CI looks unhappy?
/wait
| [(validate.rules).repeated = {max_items: 1000}]; | ||
|
|
||
| // Save the response headers to the downstream info filter state for consumption | ||
| // by the network filters. The filter state key is ``envoy.tcp_proxy.tunnel_response_headers``. |
There was a problem hiding this comment.
maybe make the key propagate as well?
changelogs/current.yaml
Outdated
| added support for quit command to the redis proxy. | ||
| - area: tcp_proxy | ||
| change: | | ||
| added support for emitting the response headers in :ref:`TunnelingConfig |
There was a problem hiding this comment.
emitting -> propagating ?
|
/lgtm api |
ggreenway
left a comment
There was a problem hiding this comment.
Please add a test validating that headers are not propagated when the new setting is disabled.
/wait
|
|
||
| // Save the response headers to the downstream info filter state for consumption | ||
| // by the network filters. The filter state key is ``envoy.tcp_proxy.propagate_response_headers``. | ||
| bool propagate_response_headers = 4; |
There was a problem hiding this comment.
Why not do this unconditionally? Performance?
There was a problem hiding this comment.
Yes, for long-living streams, we're adding extra memory per stream since the filter state lives till connection closes.
Signed-off-by: Kuat Yessenov <kuat@google.com>
Signed-off-by: Kuat Yessenov kuat@google.com
Commit Message: Add support to save response headers from CONNECT tunnels in
tcp_proxy. Fixes #23116Additional Description: The use case is saving "baggage" header which provides additional metadata about the upstream endpoint for telemetry purposes.
Risk Level: low (opt-in)
Testing: unit, integration
Docs Changes: none
Release Notes: yes