Transform client requests before they reach the upstream server. The plugin lets you match portions of incoming requests using regular expressions, save those matched strings into variables, and substitute the strings into transformed requests via flexible templates.
The Request Transformer Advanced plugin builds on the open-source Request Transformer plugin with the following enhanced capability:
- Limit the list of allowed parameters in the request body. Set this up with the
allow.body
configuration parameter.
Notes:
- If the value contains a
,
(comma), then the comma-separated format for lists cannot be used. The array notation must be used instead. - The
X-Forwarded-*
fields are non-standard header fields written by Nginx to inform the upstream about client details and can’t be overwritten by this plugin. If you need to overwrite these header fields, see the post-function plugin in Serverless Functions.
Template as Value
You can use any of the current request headers, query parameters, and captured URI groups as templates to populate supported config fields.
Request Parameter | Template |
---|---|
header | $(headers.<header-name>) or $(headers["<header-name>"]) ) |
querystring | $(query_params.<query-param-name>) or $(query_params["<query-param-name>"]) ) |
captured URIs | $(uri_captures.<group-name>) or $(uri_captures["<group-name>"]) ) |
To escape a template, wrap it inside quotes and pass inside another template. For example:
$('$(something_that_needs_to_escaped)')
Note: The plugin creates a non-mutable table of request headers, query strings, and captured URIs before transformation. So any update or removal of parameters used in the template does not affect the rendered value of template.
Advanced templates
The content of the placeholder $(...)
is evaluated as a Lua expression, so
logical operators may be used. For example:
Header-Name:$(uri_captures["user-id"] or query_params["user"] or "unknown")
This will first look for the path parameter (uri_captures
); if not found, it will
return the query parameter; or if that also doesn’t exist, it returns the default
value ‘“unknown”’.
Constant parts can be specified as part of the template outside the dynamic
placeholders. For example, creating a basic-auth header from a query parameter
called auth
that only contains the base64-encoded part:
Authorization:Basic $(query_params["auth"])
Lambdas are also supported if wrapped as an expression like this:
$((function() ... implementation here ... end)())
A complete lambda example for prefixing a header value with “Basic “ if not already there:
Authorization:$((function()
local value = headers.Authorization
if not value then
return
end
if value:sub(1, 6) == "Basic " then
return value -- was already properly formed
end
return "Basic " .. value -- added proper prefix
end)())
Note: Especially in multi-line templates like the example above, make sure not to add any trailing white-space or new-lines. Since these would be outside the placeholders, they would be considered part of the template, and hence would be appended to the generated value.
The environment is sandboxed, meaning that Lambda’s will not have access to any
library functions, except for the string methods (like sub()
in the example
above).
Examples Using Template as Value
Add a Service named test
which routes requests to the mockbin.com upstream service:
curl -X POST http://localhost:8001/services \
--data 'name=test' \
--data 'url=http://mockbin.com/requests'
Create a route for the test
service, capturing a user_id
field from the third segment of the request path:
Kubernetes users: Version
v1beta1
of the Ingress specification does not allow the use of named regex capture groups in paths. If you use the ingress controller, you should use unnamed groups, e.g.(\w+)/
instead of(?<user_id>\w+)
. You can access these based on their order in the URL path. For example$(uri_captures[1])
obtains the value of the first capture group.
curl -X POST http://localhost:8001/services/test/routes --data "name=test_user" \
--data-urlencode 'paths=~/requests/user/(?<user_id>\w+)'
Enable the request-transformer-advanced
plugin to add a new header, x-user-id
,
whose value is being set from the captured group in the route path specified above:
curl -XPOST http://localhost:8001/routes/test_user/plugins --data "name=request-transformer-advanced" --data "config.add.headers=x-user-id:\$(uri_captures['user_id'])"
Now send a request with a user id in the route path:
curl -i -X GET localhost:8000/requests/user/foo
You should notice in the response that the x-user-id
header has been added with a value of foo
.
Order of Execution
This plugin performs the response transformation in the following order:
- remove → rename → replace → add → append
Configuration Examples
Add multiple headers by passing each header:value pair separately:
curl -X POST http://localhost:8001/services/mockbin/plugins \
--data "name=request-transformer-advanced" \
--data "config.add.headers[1]=h1:v1" \
--data "config.add.headers[2]=h2:v1"
Incoming Request Headers | Upstream Proxied Headers |
---|---|
h1: v1 | h1: v1, h2: v1 |
Add multiple headers by passing comma separated header:value pair:
curl -X POST http://localhost:8001/services/mockbin/plugins \
--data "name=request-transformer-advanced" \
--data "config.add.headers=h1:v1,h2:v2"
Incoming Request Headers | Upstream Proxied Headers |
---|---|
h1: v1 | h1: v1, h2: v1 |
Add multiple headers passing config as a JSON body:
curl -X POST http://localhost:8001/services/mockbin/plugins \
--header 'content-type: application/json' \
--data '{"name": "request-transformer-advanced", "config": {"add": {"headers": ["h1:v2", "h2:v1"]}}}'
Incoming Request Headers | Upstream Proxied Headers |
---|---|
h1: v1 | h1: v1, h2: v1 |
Add a query string and a header:
curl -X POST http://localhost:8001/services/mockbin/plugins \
--data "name=request-transformer-advanced" \
--data "config.add.querystring=q1:v2,q2=v1" \
--data "config.add.headers=h1:v1"
Incoming Request Headers | Upstream Proxied Headers |
---|---|
h1: v1 | h1: v1, h2: v1 |
h3: v1 | h1: v1, h2: v1, h3: v1 |
Incoming Request Query String | Upstream Proxied Query String |
---|---|
?q1=v1 | ?q1=v1&q2=v1 |
?q1=v2&q2=v1 |
Append multiple headers and remove a body parameter:
curl -X POST http://localhost:8001/services/mockbin/plugins \
--data "name=request-transformer-advanced" \
--data "config.add.headers=h1:v2,h2:v1" \
--data "config.remove.body=p1" \
Incoming Request Headers | Upstream Proxied Headers |
---|---|
h1: v1 | h1: v1, h1: v2, h2: v1 |
Incoming URL Encoded Body | Upstream Proxied URL Encoded Body |
---|---|
p1=v1&p2=v1 | p2=v1 |
p2=v1 | p2=v1 |
Add multiple headers and query string parameters if not already set:
curl -X POST http://localhost:8001/services/mockbin/plugins \
--data "name=request-transformer-advanced" \
--data "config.add.headers=h1:v1,h2:v1" \
--data "config.add.querystring=q1:v2,q2:v1" \
Incoming Request Headers | Upstream Proxied Headers |
---|---|
h1: v1 | h1: v1, h2: v1 |
h3: v1 | h1: v1, h2: v1, h3: v1 |
Incoming Request Query String | Upstream Proxied Query String |
---|---|
?q1=v1 | ?q1=v1&q2=v1 |
?q1=v2&q2=v1 |