Unable to read response body using Lua with EnvoyFilter

Hi there,

I am setting up EnvoyFilters to log request and responses between microservices and also their communication to external services.

As part of the task, I have setup TLS origination on the sidecar so that I can log the request and responses where the microservice inside the mesh starts the communication.

So I followed up the example in the doc https://istio.io/docs/examples/advanced-gateways/egress-tls-origination/#tls-origination-for-egress-traffic

It went well until I add my EnvoyFilter (a simplified version depicting the problem given below). After applying the EnvoyFilter, Envoy started to return HTTP 500! No related error messages are shown even with logging level decreased to debug.

Looking at the logs of sleep pod, I see below. So it turns out that making a call to response_handle:body() causes pipeline to break and Envoy to return 500.

Notably this happens only with http://edition.cnn.com/politics where the response is over 1MB. It works OK when http://httpbin.org/headers is used.

sleep-88ddbcfdd-546hh istio-proxy [2019-04-24 15:26:31.704][103][warning][lua] [external/envoy/source/extensions/filters/http/lua/lua_filter.cc:538] script log: Handling the request
sleep-88ddbcfdd-546hh istio-proxy [2019-04-24 15:26:32.857][103][warning][lua] [external/envoy/source/extensions/filters/http/lua/lua_filter.cc:538] script log: Before reading response body

I thought that it is related with buffer size being not enough for 1MB and I decided to use response_handle:bodyChunks() instead but this leads to another error in my actual setup.

Could you please look at this and tell me what I am missing?


Lua Script

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
  name: sleep-outbound
  namespace: default
    app: sleep
  - filterConfig:
      inlineCode: |
        function envoy_on_request(request_handle)
          request_handle:logWarn("Handling the request")

        function envoy_on_response(response_handle)
          response_handle:logWarn("Before reading response body")
          local bufferResp = response_handle:body()
          response_handle:logWarn("After reading response body") 
    filterName: envoy.lua
    filterType: HTTP
      listenerType: SIDECAR_OUTBOUND
      portNumber: 80

I’ve written a blog about this topic with tested example: HTTP Request Body Logging with Istio & Envoy