Skip to content

Custom response filter does not expose existing local reply body #45346

Description

@marvin-roesch

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:

  1. Create a filter chain with a custom response filter that uses a body_format with the %LOCAL_REPLY_BODY% variable
  2. Add a route with a direct_response action and some body value
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions