Kong post function : change code based on body content

hi,

i’m trying to change with a post function http code, and i only succed to change it in header filter

did someone try chnage ttp code on body based content ?

@yroffin If you’re using Kong Gateway Enterprise, there is a plugin to enable this, the Exit Transformer.

If you’re not an Enterprise user, I believe you’ll have to write a custom plugin to accomplish this (if I understand correctly).

Hey there, yes it can be done!

It’s a little complicated and requires buffering the whole response into RAM, but try this:

_format_version: "3.0"
services:
  - name: "echo"
    url: "https://httpbin.org:443/anything"

    routes:
      - name: "echo"
        paths:
          - "~/echo$"
        request_buffering: true
        response_buffering: true

        plugins:
          - name: post-function
            config:
              access:
                - |
                  kong.service.request.enable_buffering()
              header_filter:
                - |
                  local cjson = require("cjson.safe")
                  local body_t, err = cjson.decode(kong.service.response.get_raw_body())

                  if err then
                    kong.response.set_status(500)
                    kong.response.clear_header("Content-Length")  -- convert to chunked
                    kong.ctx.plugin.replacement_body = '{"failure": true, "message": "response is not json"}'

                    return
                  end

                  -- now analyse the response!
                  if not body_t
                      or not body_t.json
                      or not body_t.json.is_dog
                  then
                    kong.response.set_status(400)
                    kong.response.clear_header("Content-Length")  -- convert to chunked
                    kong.ctx.plugin.replacement_body = '{"failure": true, "message": "response object is not a dog"}'

                    return
                  end

              body_filter:
                - |
                  if kong.ctx.plugin.replacement_body then
                    kong.response.set_raw_body(kong.ctx.plugin.replacement_body)
                  end

Explanation:

  1. The access function forces Kong into response buffering mode, where you can access headers and body separately
  2. The header_filter decodes the JSON body, checks for errors, then analyses the body (if not body_t or not body_t.is_dog)
  3. If there is a problem, the header_filter must set the response code and header, but it cannot set the body!!
  4. This is why we use ngx ctx to pass the replacement body JSON (or string or whatever) into the body_filter function at the end, who replaces the body if there has been some issue during header_filter.

:warning: Note: you also have to allow cjson.safe package in the post-function sandbox, by setting this Kong environment variable:

KONG_UNTRUSTED_LUA_SANDBOX_REQUIRES=cjson.safe

1 Like