Title: Custom response filter does not expose existing local reply body
Description:
When configuring a custom response filter with a local response policy that uses the %LOCAL_REPLY_BODY% substitution variable in its body_format, that always results in an empty value for that substitution. This prevents the body of a direct_response route action or some filter output (e.g. for the RBAC filter) from being included in the custom response.
Repro steps:
- Create a filter chain with a custom response filter that uses a
body_format with the %LOCAL_REPLY_BODY% variable
- Add a route with a
direct_response action and some body value
GET that route and observe that the route action's body is not included in the response
Config:
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 10000 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: direct_response
domains: ["*"]
routes:
- match: { prefix: "/test" }
direct_response:
status: 200
body:
inline_string: "foobar"
http_filters:
- name: envoy.filters.http.custom_response
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.custom_response.v3.CustomResponse
custom_response_matcher:
matcher_list:
matchers:
- predicate:
single_predicate:
input:
name: local_reply
typed_config:
"@type": type.googleapis.com/envoy.type.matcher.v3.HttpResponseLocalReplyMatchInput
value_match:
exact: "true"
on_match:
action:
name: action
typed_config:
"@type": type.googleapis.com/envoy.extensions.http.custom_response.local_response_policy.v3.LocalResponsePolicy
body_format:
text_format: "%LOCAL_REPLY_BODY%"
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
I had a brief look at trying to fix this myself and the issue lies in this line:
|
std::string body; |
|
Envoy::Http::Code code = getStatusCodeForLocalReply(headers); |
|
formatBody(encoder_callbacks->streamInfo().getRequestHeaders() == nullptr |
|
? *Envoy::Http::StaticEmptyHeaders::get().request_headers |
|
: *encoder_callbacks->streamInfo().getRequestHeaders(), |
|
headers, encoder_callbacks->streamInfo(), encoder_callbacks->activeSpan(), body); |
The problem being that the body never gets initialized with some non-empty value, so only the body and format from the local response policy itself get used. I'm not sure if/how the "current" local reply body can be accessed from there.
Title: Custom response filter does not expose existing local reply body
Description:
When configuring a custom response filter with a local response policy that uses the
%LOCAL_REPLY_BODY%substitution variable in itsbody_format, that always results in an empty value for that substitution. This prevents the body of adirect_responseroute action or some filter output (e.g. for the RBAC filter) from being included in the custom response.Repro steps:
body_formatwith the%LOCAL_REPLY_BODY%variabledirect_responseaction and some body valueGETthat route and observe that the route action's body is not included in the responseConfig:
I had a brief look at trying to fix this myself and the issue lies in this line:
envoy/source/extensions/http/custom_response/local_response_policy/local_response_policy.cc
Lines 73 to 78 in c4e3e8e
The problem being that the
bodynever gets initialized with some non-empty value, so only the body and format from the local response policy itself get used. I'm not sure if/how the "current" local reply body can be accessed from there.