Skip to content

Commit

Permalink
feat(reponse-rewrite): allow using variable in the header (#4194)
Browse files Browse the repository at this point in the history
* feat(reponse-rewrite): allow using variable in the header

Fix #3727

Signed-off-by: spacewander <[email protected]>
  • Loading branch information
spacewander authored May 10, 2021
1 parent 28ebf3e commit db5a5a9
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 5 deletions.
3 changes: 2 additions & 1 deletion apisix/plugins/response-rewrite.lua
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ function _M.header_filter(conf, ctx)

local field_cnt = #conf.headers_arr
for i = 1, field_cnt, 2 do
ngx.header[conf.headers_arr[i]] = conf.headers_arr[i+1]
local val = core.utils.resolve_var(conf.headers_arr[i+1], ctx.var)
ngx.header[conf.headers_arr[i]] = val
end
end

Expand Down
6 changes: 4 additions & 2 deletions docs/en/latest/plugins/response-rewrite.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ response rewrite plugin, rewrite the content returned by the upstream as well as
| status_code | integer | optional | | [200, 598] | New `status code` to client, keep the original response code by default. |
| body | string | optional | | | New `body` to client, and the content-length will be reset too. |
| body_base64 | boolean | optional | false | | Identify if `body` in configuration need base64 decoded before rewrite to client. |
| headers | object | optional | | | Set the new `headers` for client, can set up multiple. If it exists already from upstream, will rewrite the header, otherwise will add the header. You can set the corresponding value to an empty string to remove a header. |
| headers | object | optional | | | Set the new `headers` for client, can set up multiple. If it exists already from upstream, will rewrite the header, otherwise will add the header. You can set the corresponding value to an empty string to remove a header. The value can contain Nginx variables in `$var` format, like `$remote_addr $balancer_ip` |
| vars | array[] | optional | | | A DSL to evaluate with the given ngx.var. See `vars` [lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list). if the `vars` is empty, then all rewrite operations will be executed unconditionally |

## How To Enable
Expand All @@ -63,7 +63,8 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f1
"body": "{\"code\":\"ok\",\"message\":\"new json body\"}",
"headers": {
"X-Server-id": 3,
"X-Server-status": "on"
"X-Server-status": "on",
"X-Server-balancer_addr": "$balancer_ip:$balancer_port"
},
"vars":[
[ "status","==","200" ]
Expand Down Expand Up @@ -97,6 +98,7 @@ Transfer-Encoding: chunked
Connection: keep-alive
X-Server-id: 3
X-Server-status: on
X-Server-balancer_addr: 127.0.0.1:80
{"code":"ok","message":"new json body"}
```
Expand Down
6 changes: 4 additions & 2 deletions docs/zh/latest/plugins/response-rewrite.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ title: response-rewrite
| status_code | integer | 可选 | | [200, 598] | 修改上游返回状态码,默认保留原始响应代码。 |
| body | string | 可选 | | | 修改上游返回的 `body` 内容,如果设置了新内容,header 里面的 content-length 字段也会被去掉 |
| body_base64 | boolean | 可选 | false | | 描述 `body` 字段是否需要 base64 解码之后再返回给客户端,用在某些图片和 Protobuffer 场景 |
| headers | object | 可选 | | | 返回给客户端的 `headers`,这里可以设置多个。头信息如果存在将重写,不存在则添加。想要删除某个 header 的话,把对应的值设置为空字符串即可 |
| headers | object | 可选 | | | 返回给客户端的 `headers`,这里可以设置多个。头信息如果存在将重写,不存在则添加。想要删除某个 header 的话,把对应的值设置为空字符串即可。这个值能够以 `$var` 的格式包含 Nginx 变量,比如 `$remote_addr $balancer_ip` |
| vars | array[] | 可选 | | | `vars` 是一个表达式列表,只有满足条件的请求和响应才会修改 body 和 header 信息,来自 [lua-resty-expr](https://github.com/api7/lua-resty-expr#operator-list)。如果 `vars` 字段为空,那么所有的重写动作都会被无条件的执行。 |

## 示例
Expand All @@ -64,7 +64,8 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f1
"body": "{\"code\":\"ok\",\"message\":\"new json body\"}",
"headers": {
"X-Server-id": 3,
"X-Server-status": "on"
"X-Server-status": "on",
"X-Server-balancer_addr": "$balancer_ip:$balancer_port"
},
"vars":[
[ "status","==","200" ]
Expand Down Expand Up @@ -97,6 +98,7 @@ Transfer-Encoding: chunked
Connection: keep-alive
X-Server-id: 3
X-Server-status: on
X-Server-balancer_addr: 127.0.0.1:80

{"code":"ok","message":"new json body"}
```
Expand Down
52 changes: 52 additions & 0 deletions t/plugin/response-rewrite.t
Original file line number Diff line number Diff line change
Expand Up @@ -676,3 +676,55 @@ GET /t
invalid base64 content
--- no_error_log
[error]



=== TEST 24: rewrite header with variables
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"response-rewrite": {
"headers" : {
"X-A": "$remote_addr",
"X-B": "from $remote_addr to $balancer_ip:$balancer_port"
}
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/with_header"
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]



=== TEST 25: hit
--- request
GET /with_header
--- response_headers
X-A: 127.0.0.1
X-B: from 127.0.0.1 to 127.0.0.1:1980
--- no_error_log
[error]

0 comments on commit db5a5a9

Please sign in to comment.