Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessing request headers in envoy_on_response (lua HTTP filter). #4613

Open
ashwinphatak opened this issue Oct 5, 2018 · 15 comments
Open
Labels

Comments

@ashwinphatak
Copy link

I'm trying to use a lua HTTP filter to set a response header whose value depends on a request header.

As a simple example, suppose we want to copy a header from the request to the response. How can we do this using a lua filter?

Maybe we can store the request header in a "global" table during envoy_on_request and read it later when envoy_on_response is called. However, even if this approach makes sense, how can we correlate responses with requests to be able to do this?

@junr03 junr03 added the question Questions that are neither investigations, bugs, nor enhancements label Oct 5, 2018
@stale
Copy link

stale bot commented Nov 4, 2018

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions.

@stale stale bot added the stale stalebot believes this issue/PR has not been touched recently label Nov 4, 2018
@stale
Copy link

stale bot commented Nov 11, 2018

This issue has been automatically closed because it has not had activity in the last 37 days. If this issue is still valid, please ping a maintainer and ask them to label it as "help wanted". Thank you for your contributions.

@stale stale bot closed this as completed Nov 11, 2018
@mderazon
Copy link

mderazon commented Sep 20, 2019

This will be very helpful.
One use case for this:
emissary-ingress/emissary#1847

@Stono
Copy link

Stono commented Jan 21, 2020

Could we please reopen this as it's an excellent use case?
For example; we wish to write a response handler which logs information about the request in error scenarios!

@dio dio reopened this Jan 21, 2020
@stale stale bot removed the stale stalebot believes this issue/PR has not been touched recently label Jan 21, 2020
@mattklein123 mattklein123 added area/lua help wanted Needs help! and removed question Questions that are neither investigations, bugs, nor enhancements labels Jan 21, 2020
@vbuciuc
Copy link

vbuciuc commented Apr 21, 2020

see the example here:

https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/lua_filter#set

it stores headers in dynamic metadata in the request handler which are then available in the response handler

1 similar comment
@vbuciuc
Copy link

vbuciuc commented Apr 21, 2020

see the example here:

https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/lua_filter#set

it stores headers in dynamic metadata in the request handler which are then available in the response handler

@ErikXu
Copy link

ErikXu commented Jun 29, 2020

@vbuciuc Works for me. But the filterName in dynamicMetadata:set(filterName, key, value) confuses me. I have my own http filter named my-filter. Which name should I use, my-filter, my-filter.lua or envoy.filters.http.lua? In addition, is the data stored in a lua file?

@dio
Copy link
Member

dio commented Oct 1, 2020

@ErikXu sorry for confusing docs and late reply. So the filterName can be anything, think about a namespace (we need to update the docs).

As an example:

          - name: envoy.filters.http.lua
            typed_config:
              "@type": type.googleapis.com/envoy.config.filter.http.lua.v2.Lua
              inline_code: |
                function envoy_on_request(request_handle)
                  request_handle:streamInfo():dynamicMetadata():set("context", "foo", "bar")
                end
                function envoy_on_response(response_handle)
                  local foo = response_handle:streamInfo():dynamicMetadata():get("context")["foo"]
                  response_handle:logInfo(foo)
                end

@Arsen-Uulu
Copy link

@dio I have this filter and it doesn't seem to be working

        name: envoy.lua
        typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
          inlineCode: |
            function envoy_on_request(request_handle)
              request_handle:streamInfo():dynamicMetadata():set("context","bar ", "foo")
            end
            function envoy_on_response(response_handle)
              local val = response_handle:streamInfo():dynamicMetadata():get("context")["foo"]
              response_handle:headers():add("x-custom-header", val)
            end

@Arsen-Uulu
Copy link

@dio is it possible to get SIDECAR_INBOUND request headers and pass it to SIDECAR_OUTBOUND envoy_on_request() ?

@Stono
Copy link

Stono commented Aug 13, 2021

@Arsen-Uulu i do it by storing them on the dynamic metadata, similar to how you've done it, but i build up a map first

              function envoy_on_request(request_handle)
                local request_headers = request_handle:headers()
                local headers = {}
                for key, value in pairs(request_headers) do
                  headers[key] = value
                end
                request_handle:streamInfo():dynamicMetadata():set("context", "request.info", headers)
              end

              function envoy_on_response(response_handle)
                local request_headers = response_handle:streamInfo():dynamicMetadata():get("context")["request.info"]
                local response_headers = response_handle:headers()
                local status = response_headers:get(":status")
                if not isempty(status) then
                  local asNumber = tonumber(status)
                  if asNumber == 400 or asNumber == 401 or asNumber >= 500 then
                    print_headers(request_headers, response_headers)
                  end
                end
              end

@Arsen-Uulu
Copy link

@Stono Hey than you for suggestion.
I don't wanna handle the response.

What I want is capture req_headers from upstream and when my app makes a new request(outbound) I wanna add that header that I captured from inbound request

@dio
Copy link
Member

dio commented Sep 7, 2021

@dio is it possible to get SIDECAR_INBOUND request headers and pass it to SIDECAR_OUTBOUND envoy_on_request() ?

Hum, seems like you need your service to collaborate? Unless you call it directly using https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/lua_filter#httpcall (not sure if that is what you want).

@631068264
Copy link

@dio I have this filter and it doesn't seem to be working

        name: envoy.lua
        typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
          inlineCode: |
            function envoy_on_request(request_handle)
              request_handle:streamInfo():dynamicMetadata():set("context","bar ", "foo")
            end
            function envoy_on_response(response_handle)
              local val = response_handle:streamInfo():dynamicMetadata():get("context")["foo"]
              response_handle:headers():add("x-custom-header", val)
            end

change context to envoy.lua

@adamf-sendblocks
Copy link

@ErikXu sorry for confusing docs and late reply. So the filterName can be anything, think about a namespace (we need to update the docs).

I found the docs exceptionally unhelpful, but I'm really pleased to have eventually stumbled across this thread!

For the next poor soul, I warmly recommend making it clearer to new users like myself that the header_to_metadata_filter's "namespace" field needs to be the name of the filter that uses it, and ask that you provide an example of chaining a header -> metadata -> lua handler. It might even be worthwhile linking that documentation to the set / get example.

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests