diff --git a/apisix/plugins/response-rewrite.lua b/apisix/plugins/response-rewrite.lua index b415c7c28e31..2f767bca33b4 100644 --- a/apisix/plugins/response-rewrite.lua +++ b/apisix/plugins/response-rewrite.lua @@ -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 diff --git a/docs/en/latest/plugins/response-rewrite.md b/docs/en/latest/plugins/response-rewrite.md index f95d6a349968..a05dbdaf71db 100644 --- a/docs/en/latest/plugins/response-rewrite.md +++ b/docs/en/latest/plugins/response-rewrite.md @@ -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 @@ -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" ] @@ -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"} ``` diff --git a/docs/zh/latest/plugins/response-rewrite.md b/docs/zh/latest/plugins/response-rewrite.md index bc352bd4855a..85a03783478f 100644 --- a/docs/zh/latest/plugins/response-rewrite.md +++ b/docs/zh/latest/plugins/response-rewrite.md @@ -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` 字段为空,那么所有的重写动作都会被无条件的执行。 | ## 示例 @@ -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" ] @@ -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"} ``` diff --git a/t/plugin/response-rewrite.t b/t/plugin/response-rewrite.t index d1f23a9853eb..670e536798ef 100644 --- a/t/plugin/response-rewrite.t +++ b/t/plugin/response-rewrite.t @@ -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]