NewBee
NewBee

Reputation: 270

Istio Envoy Filter Lua - Updating Response Body get stuck

By following envoy filter to intercept upstream response I was able to create envoy filter and it's partially working as well. I can see my https request is being interpreted by the envoy filter and can see the updated response getting printed in the logs.

However, in the Postman I am not getting response back and it is waiting indefinitely. The access logs shows the 400 response being logged. Wondering why the postman is not receiving the response body.

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: test-http-filter
  namespace: test
spec:
  workloadSelector:
    labels:
      app: istio
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: envoy.filters.network.http_connection_manager
            subfilter: 
              name: envoy.filters.http.router
    patch:
      operation: INSERT_AFTER  # INSER_BEFORE also tried
      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") == "404" or response_handle:headers():get(":status") == "400" then
                    local body = response_handle:body()
                    local jsonString = tostring(body:getBytes(0, body:length()))
                    response_handle:logErr("Status: "..response_handle:headers():get(":status"))
                    response_handle:logErr("JSONString: "..jsonString)
                    jsonString = jsonString:gsub("mystring", "myUpdatedstring")
                    response_handle:body():setBytes(jsonString)
                  end
                end

Anyone experienced similar issue with response_bandle:body():setBytes() . The original post had response_handle():set() which is throwing error in my case.

Upvotes: 0

Views: 2507

Answers (1)

Nataraj Medayhal
Nataraj Medayhal

Reputation: 1221

Please change patch operation from "operation: INSERT_AFTER" to "operation: INSERT_BEFORE" as the filter is getting applied after sending the response. Update the envoy filter as below

patch:
  operation: INSERT_BEFORE

Corrected the Envoy Filter

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: test-http-filter
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: envoy.filters.network.http_connection_manager
    patch:
      operation: INSERT_BEFORE
      value: 
       name: envoy.lua
       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") == "404" or response_handle:headers():get(":status") == "400" then
                    local body = response_handle:body()
                    local jsonString = tostring(body:getBytes(0, body:length()))
                    response_handle:logErr("Status: "..response_handle:headers():get(":status"))
                    response_handle:logErr("JSONString: "..jsonString)
                    jsonString = jsonString:gsub("mystring", "myUpdatedstring")
                    response_handle:body():setBytes(jsonString)
                  end
                end

Upvotes: 2

Related Questions