sriba
sriba

Reputation: 775

envoy filter to intercept upstream response

I have written the ext_authz filter for envoy and have basic understanding of how envoy filters done. But now I want to filter the response coming back from the upstream. Specifically, I want to handle two things:

  1. Intercept data/jsonBody coming from upstream and Filter/Modify the responseJsonBody based on some business rule before envoy sends back to downstream.

  2. If upstream is down(when http response code 408-Timeout), I want to save the post-request to async-msg-que and send back a 202-Accepted back to downstream. This way, when the upstream comes back it will process pending post-request from it's async-msg-que.

Is there a existing filter I can use for these purpose or what is the right way to do this using envoy-proxy sidecar.

Thanks.

Upvotes: 1

Views: 4191

Answers (1)

Chris
Chris

Reputation: 5623

You need to write the filter yourself using lua:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: custom-filter
  namespace: some-namespace
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
            subFilter:
              name: "envoy.extAuthz" # name of your ext_authz filter
    patch:
      operation: INSERT_AFTER
      value: 
       name: envoy.custom-resp
       typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
          inlineCode: |
            function envoy_on_response(response_handle) 
              if response_handle:headers():get(":status") == "408" then
                -- send message depending on your queue, eg via httpCall()
                -- Overwrite status and body
                response_handle:headers():replace(":status", "202")
              else 
                -- get response body as jsonString
                local body = response_handle:body()
                local jsonString = tostring(body:getBytes(0, body:length()))
                -- do something, eg replace secret by regex 
                jsonString = jsonString:gsub("(foo|bar)", "")
                response_handle:body():set(jsonString)
              end
            end

Note that you need to handle timeouts of the queue somehow.

Envoy With Lua

httpCall

Lua Docs

Upvotes: 5

Related Questions