feature(plugin): rewrite upstream info with plugin proxy-rewrite (#594)

* test: add `proxy-rewrite` plugin test cases
This commit is contained in:
Janko 2019-09-27 15:14:49 +08:00 committed by YuanSheng Wang
parent 0d36723e6f
commit 25fd6983ea
9 changed files with 469 additions and 1 deletions

View File

@ -54,6 +54,7 @@ plugins: # plugin list
- serverless-pre-function
- serverless-post-function
- openid-connect
- proxy-rewrite
stream_plugins:
- mqtt-proxy

View File

@ -0,0 +1,72 @@
[English](proxy-rewrite.md)
# proxy-rewrite
上游代理信息重写插件。
#### 配置参数
|名字 |可选|说明|
|------- |-----|------|
|scheme |可选| 转发到上游的新`schema` 协议,可以是`http`或`https`,默认`http`协议|
|uri |可选| 转发到上游的新`uri` 地址|
|host |可选| 转发到上游的新`host` 地址,例如:`iresty.com` |
|enable_websocket|可选| 是否启用`websocket`(布尔值),默认不启用|
### 示例
#### 开启插件
下面是一个示例,在指定的 route 上开启了 `proxy rewrite` 插件:
```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -X PUT -d '
{
"methods": ["GET"],
"uri": "/test/index.html",
"plugins": {
"proxy-rewrite": {
"uri": "/test/home.html",
"scheme": "http",
"host": "iresty.com",
"enable_websocket": true
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:80": 1
}
}
}'
```
#### 测试插件
基于上述配置进行测试:
```shell
curl -X GET http://127.0.0.1:9080/test/index.html
```
发送请求,查看上游服务`access.log`,如果输出信息与配置一致:
```
127.0.0.1 - [26/Sep/2019:10:52:20 +0800] iresty.com GET /test/home.html HTTP/1.1 200 38 - curl/7.29.0 - 0.000 199 107
```
即表示 `proxy rewrite` 插件生效了。
#### 禁用插件
当你想去掉 `proxy rewrite` 插件的时候,很简单,在插件的配置中把对应的 json 配置删除即可,无须重启服务,即刻生效:
```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -X PUT -d '
{
"methods": ["GET"],
"uri": "/test/index.html",
"plugins": {},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:80": 1
}
}
}'
```
现在就已经移除了 `proxy rewrite` 插件了。其他插件的开启和移除也是同样的方法。

View File

@ -0,0 +1,73 @@
[中文](proxy-rewrite-cn.md)
# proxy-rewrite
upstream proxy info rewrite plugin.
### Parameters
|Name |Required|Description|
|------- |-----|------|
|scheme |No| Upstream new `schema` forwarding protocol,options can be `http` or `https`,default `http`.|
|uri |No| Upstream new `uri` forwarding address.|
|host |No| Upstream new `host` forwarding address, example `iresty.com`. |
|enable_websocket|No| enable `websocket`(boolean), default `false`.|
### Example
#### Enable Plugin
Here's an example, enable the `proxy rewrite` plugin on the specified route:
```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -X PUT -d '
{
"methods": ["GET"],
"uri": "/test/index.html",
"plugins": {
"proxy-rewrite": {
"uri": "/test/home.html",
"scheme": "http",
"host": "iresty.com",
"enable_websocket": true
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:80": 1
}
}
}'
```
#### Test Plugin
Testing based on the above examples :
```shell
curl -X GET http://127.0.0.1:9080/test/index.html
```
Send the request and see upstream `access.log', if the output information is consistent with the configuration :
```
127.0.0.1 - [26/Sep/2019:10:52:20 +0800] iresty.com GET /test/home.html HTTP/1.1 200 38 - curl/7.29.0 - 0.000 199 107
```
This means that the `proxy rewrite` plugin is in effect.
#### Disable Plugin
When you want to disable the `proxy rewrite` plugin, it is very simple,
you can delete the corresponding json configuration in the plugin configuration,
no need to restart the service, it will take effect immediately :
```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -X PUT -d '
{
"methods": ["GET"],
"uri": "/test/index.html",
"plugins": {},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:80": 1
}
}
}'
```
The `proxy rewrite` plugin has been disabled now. It works for other plugins.

View File

@ -0,0 +1,77 @@
local core = require("apisix.core")
local plugin_name = "proxy-rewrite"
local pairs = pairs
local ipairs = ipairs
local schema = {
type = "object",
properties = {
uri = {
description = "new uri for upstream",
type = "string",
minLength = 1,
maxLength = 4096
},
host = {
description = "new host for upstream",
type = "string",
pattern = "^\\*?[0-9a-zA-Z-.]+$",
},
scheme = {
description = "new scheme for upstream",
type = "string",
enum = {"http", "https"}
},
enable_websocket = {
description = "enable websocket for request",
type = "boolean",
default = false
}
},
minProperties = 1,
}
local _M = {
version = 0.1,
priority = 1008,
name = plugin_name,
schema = schema,
}
function _M.check_schema(conf)
local ok, err = core.schema.check(schema, conf)
if not ok then
return false, err
end
return true
end
do
local upstream_vars = {
uri = "upstream_uri",
scheme = "upstream_scheme",
host = "upstream_host",
upgrade = "upstream_upgrade",
connection = "upstream_connection",
}
local upstream_names = {}
for name, _ in pairs(upstream_vars) do
core.table.insert(upstream_names, name)
end
function _M.rewrite(conf, ctx)
for _, name in ipairs(upstream_names) do
if conf[name] then
ctx.var[upstream_vars[name]] = conf[name]
end
end
if conf.enable_websocket then
ctx.var["upstream_upgrade"] = ctx.var["http_upgrade"]
ctx.var["upstream_connection"] = ctx.var["http_connection"]
end
end
end -- do
return _M

1
t/APISIX.pm vendored
View File

@ -154,6 +154,7 @@ _EOC_
listen 1980;
listen 1981;
listen 1982;
server_name apisix.iresty.com;
server_tokens off;

View File

@ -14,6 +14,6 @@ __DATA__
--- request
GET /apisix/admin/plugins/list
--- response_body_like eval
qr/\["limit-req","limit-count","limit-conn","key-auth","prometheus","node-status","jwt-auth","zipkin","ip-restriction","grpc-transcode","serverless-pre-function","serverless-post-function","openid-connect"\]/
qr/\["limit-req","limit-count","limit-conn","key-auth","prometheus","node-status","jwt-auth","zipkin","ip-restriction","grpc-transcode","serverless-pre-function","serverless-post-function","openid-connect","proxy-rewrite"\]/
--- no_error_log
[error]

1
t/debug-mode.t vendored
View File

@ -44,6 +44,7 @@ loaded plugin and sort by priority: 3000 name: ip-restriction
loaded plugin and sort by priority: 2599 name: openid-connect
loaded plugin and sort by priority: 2510 name: jwt-auth
loaded plugin and sort by priority: 2500 name: key-auth
loaded plugin and sort by priority: 1008 name: proxy-rewrite
loaded plugin and sort by priority: 1003 name: limit-conn
loaded plugin and sort by priority: 1002 name: limit-count
loaded plugin and sort by priority: 1001 name: limit-req

View File

@ -1,4 +1,5 @@
local json_decode = require("cjson").decode
local json_encode = require("cjson").encode
local _M = {}
@ -22,6 +23,11 @@ function _M.limit_conn()
ngx.say("hello world")
end
function _M.plugin_proxy_rewrite()
ngx.say("uri: ", ngx.var.uri)
ngx.say("host: ", ngx.var.host)
ngx.say("scheme: ", ngx.var.scheme)
end
function _M.status()
ngx.say("ok")

237
t/plugin/proxy-rewrite.t Normal file
View File

@ -0,0 +1,237 @@
BEGIN {
if ($ENV{TEST_NGINX_CHECK_LEAK}) {
$SkipReason = "unavailable for the hup tests";
} else {
$ENV{TEST_NGINX_USE_HUP} = 1;
undef $ENV{TEST_NGINX_USE_STAP};
}
}
use t::APISIX 'no_plan';
repeat_each(1);
no_long_string();
no_shuffle();
no_root_location();
run_tests;
__DATA__
=== TEST 1: sanity
--- config
location /t {
content_by_lua_block {
local plugin = require("apisix.plugins.proxy-rewrite")
local ok, err = plugin.check_schema({
uri = '/apisix/home',
host = 'apisix.iresty.com',
enable_websocket = true,
scheme = 'http'
})
if not ok then
ngx.say(err)
end
ngx.say("done")
}
}
--- request
GET /t
--- response_body
done
--- no_error_log
[error]
=== TEST 2: wrong value of key
--- config
location /t {
content_by_lua_block {
local plugin = require("apisix.plugins.proxy-rewrite")
local ok, err = plugin.check_schema({
uri = '/apisix/home',
host = 'apisix.iresty.com',
enable_websocket = true,
scheme = 'tcp'
})
if not ok then
ngx.say(err)
end
ngx.say("done")
}
}
--- request
GET /t
--- response_body
invalid "enum" in docuement at pointer "#/scheme"
done
--- no_error_log
[error]
=== TEST 3: add plugin
--- 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": {
"proxy-rewrite": {
"uri": "/test/add",
"scheme": "https",
"host": "apisix.iresty.com",
"enable_websocket": true
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]
=== TEST 4: update plugin
--- 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": {
"proxy-rewrite": {
"uri": "/test/update",
"scheme": "http",
"host": "apisix.iresty.com",
"enable_websocket": false
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]
=== TEST 5: disable plugin
--- 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": {
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]
=== TEST 6: set route(id: 1)
--- 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,
[[{
"methods": ["GET"],
"plugins": {
"proxy-rewrite": {
"uri": "/plugin_proxy_rewrite",
"scheme": "http",
"host": "apisix.iresty.com",
"enable_websocket": true
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]
=== TEST 7: rewrite
--- request
GET /hello HTTP/1.1
--- response_body
uri: /plugin_proxy_rewrite
host: apisix.iresty.com
scheme: http
--- no_error_log
[error]