Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(reponse-rewrite): allow using variable in the header #4194

Merged
merged 2 commits into from
May 10, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 variable in `$var` format, like `$remote_addr $balancer_ip` |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| 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 variable in `$var` format, like `$remote_addr $balancer_ip` |
| 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 variable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
=== TEST 24: rewrite header with variable
=== 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]