3

As the title says, I would like an HTTP filter to apply only if the request is for a certain URL path. Doing this at the route level is not possible, because my route is defined like this:

- match: prefix: "/api/" route: cluster: some_backend_service prefix_rewrite: "/" 

But I would like to apply different (security related) filters for /api/foo than for /api/bar. I can't seem to find a way to do this looking at the documentation, is it even possible? Thanks.

1 Answer 1

5

The Composite Filter is exactly what you are looking for. Please refer to this page: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/composite_filter.html
An example: 3 Lua filters are configured in a composite filter, they are adding a response header "triggered" of value "action-1" for /get/action1, "action-2" for /get/action2, "no-match" for other paths

static_resources: listeners: - name: listener_0 address: socket_address: protocol: TCP address: 0.0.0.0 port_value: 8080 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 route_config: name: local_route virtual_hosts: - name: local_service domains: ["*"] routes: - match: prefix: "/" route: cluster: upstream timeout: 1s name: default_route http_filters: - name: composite typed_config: "@type": type.googleapis.com/envoy.extensions.common.matching.v3.ExtensionWithMatcher extension_config: name: composite typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.composite.v3.Composite matcher: on_no_match: action: name: action-no-match typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.composite.v3.ExecuteFilterAction typed_config: name: envoy.filters.http.lua typed_config: "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua" inlineCode: | function envoy_on_request(request_handle) end function envoy_on_response(response_handle) response_handle:headers():add("triggered", "no-match") end matcher_list: matchers: - predicate: single_predicate: input: name: "action1-matcher" typed_config: "@type": type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput header_name: :path value_match: prefix: /get/action1 ignore_case: true on_match: action: name: composite-action-1 typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.composite.v3.ExecuteFilterAction typed_config: name: envoy.filters.http.lua typed_config: "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua" inlineCode: | function envoy_on_request(request_handle) end function envoy_on_response(response_handle) response_handle:headers():add("triggered", "action-1") end - predicate: single_predicate: input: name: "action2-matcher" typed_config: "@type": type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput header_name: :path value_match: prefix: /get/action2 ignore_case: true on_match: action: name: composite-action-2 typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.composite.v3.ExecuteFilterAction typed_config: name: envoy.filters.http.lua typed_config: "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua" inlineCode: | function envoy_on_request(request_handle) end function envoy_on_response(response_handle) response_handle:headers():add("triggered", "action-2") end - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router clusters: - name: upstream http2_protocol_options: {} connect_timeout: seconds: 10 type: STRICT_DNS transport_socket: name: envoy.transport_sockets.tls typed_config: '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext load_assignment: cluster_name: upstream endpoints: - lb_endpoints: - endpoint: address: socket_address: address: httpbin.org port_value: 443 lb_policy: ROUND_ROBIN 
3
  • I've read the docs and at the moment they support only matching for HTTP headers. Can't find any way to match by URL prefix. Commented Sep 8, 2022 at 22:18
  • @MitchSitin I think you could try matching ":path" pseudo header Commented Sep 10, 2022 at 1:27
  • I am trying to get that work too, would either of you have their sample configs they could add to the accepted answer? Commented Mar 14, 2024 at 6:29

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.