Skip to main content

exit-transformer

The exit-transformer plugin supports the customization of gateway responses based on the status codes, headers, and bodies returned from APISIX plugins. When configured as a global plugin, it also supports the response customization when a route that does not exist is requested.

The transformation logics are defined in the plugin using Lua functions, following the syntax:

return (function(code, body, header) if {{ condition }} then return {{ modified_resp }} end return code, body, header end)(...)

Examples

The examples below demonstrate how you can use exit-transformer for different scenarios.

Modify 404 Route Not Found Response

The following example demonstrates how you can use the plugin to update the 404 Not Found response code and header when the route does not exist. In this case, the plugin needs to be configured as a global rule plugin.

Create a global rule with the exit-transformer plugin, in which the function updates the response status code to 405 and add a custom X-Custom-Header header if the original status code was 404:

curl -i "http://127.0.0.1:9180/apisix/admin/global_rules" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "transform-404-not-found",
"plugins": {
"exit-transformer": {
"functions": ["return (function(code, body, header) if code == 404 then header[\"X-Custom-Header\"] = \"Modified\" return 405, body, header end return code, body, header end)(...)"]
}
}
}'

Send a request to a route that does not exist:

curl -i "http://127.0.0.1:9080/non-existent"

You should receive an HTTP/1.1 405 Not Allowed response and observe the X-Custom-Header: Modified header.

Modify 401 Unauthorized Response for Failed Authentication

The following example demonstrates how you can use the plugin to update the 401 Unauthorized response when authentication fails.

Create a route with the exit-transformer plugin, in which the function updates the response status code to 402 if the original status code was 401; and enable key-auth:

curl -i "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "transform-auth-route",
"uri": "/get",
"plugins": {
"exit-transformer": {
"functions": ["return (function(code, body, header) if code == 401 then return 402, body, header end return code, body, header end)(...)"]
},
"key-auth":{}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'

Create a consumer john:

curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "john"
}'

Configure key-auth credential for the consumer:

curl "http://127.0.0.1:9180/apisix/admin/consumers/john/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-john-key-auth",
"plugins": {
"key-auth": {
"key": "john-key"
}
}
}'

Send a request to the route without the credential:

curl -i "http://127.0.0.1:9080/get"

You should receive an HTTP/1.1 402 Payment Required response for unauthorized access, where the response status code has been modified.

Prevent Malicious Injections

The plugin does not allow the use of coroutine, math, os, string, or table in function, for security reasons.

Suppose you have the following global rule route where the exit-transformer function contains the use of the forbidden string module:

curl -i "http://127.0.0.1:9180/apisix/admin/global_rules" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "bad-exit-transformer-global-route",
"plugins": {
"exit-transformer": {
"functions": ["return (function(code, body, header) string.foo = 1 if code == 404 then return 405 end return code, body, header end)(...)"]
}
}
}'

Send a request to the route:

curl -i "http://127.0.0.1:9080/non-existent"

You should receive an HTTP/1.1 404 Not Found response and observe the following message in the error log:

Can not modify string.foo. Protected by the sandbox.

API7.ai Logo

API Management for Modern Architectures with Edge, API Gateway, Kubernetes, and Service Mesh.

Product

API7 Cloud

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN Ltd. 2019 – 2024. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the

Apache Software Foundation