backnero opened a new issue #1508:
URL: https://github.com/apache/incubator-apisix/issues/1508
### Issue description
Based on the proxy-rewriting plugin, the argex_host configuration item is
added, and the purpose is to forward it to a.ns.svc.cluster.local when the user
curl a.test.cp.io to access it.
**The routing configuration is as follows**
```
{
"host": "*.test.me.com",
"methods": [ ],
"uri": "/*",
"plugins": {
"pan-forward": {
"regex_host":
["(.).test.me.com","$1.test.svc.cluster.local"],
"scheme": "http"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"192.168.1.100:3000": 1
}
},
"desc": "test url redirect"
}
```
If upstream is configured, it is not successfully forwarded to the host. If
upstream is not configured, no upstream configuration error is reported in
error.log.
**pan-forward.lua:**
```
local core = require("apisix.core")
local plugin_name = "pan-forward"
local pairs = pairs
local ipairs = ipairs
local ngx = ngx
local type = type
local re_sub = ngx.re.sub
local schema = {
type = "object",
properties = {
uri = {
description = "new uri for upstream",
type = "string",
minLength = 1,
maxLength = 4096,
pattern = [[^\/.*]],
},
regex_uri = {
description = "new uri that substitute from client uri " ..
"for upstream, lower priority than uri property",
type = "array",
maxItems = 2,
minItems = 2,
items = {
description = "regex uri",
type = "string",
}
},
host = {
description = "new host for upstream",
type = "string",
pattern = "^[0-9a-zA-Z-.]+$",
},
regex_host ={
description = "new host that substitute from client host " ..
"for upstream, lower priority than host property",
type = "array",
maxItems = 2,
minItems = 2,
items = {
description = "regex host",
type = "string",
}
},
scheme = {
description = "new scheme for upstream",
type = "string",
enum = {"http", "https"}
},
headers = {
description = "new headers for request",
type = "object",
minProperties = 1,
},
},
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
if conf.regex_uri and #conf.regex_uri > 0 then
local _, _, err = re_sub("/fake_uri", conf.regex_uri[1],
conf.regex_uri[2], "jo")
if err then
return false, "invalid regex_uri(" .. conf.regex_uri[1] ..
", " .. conf.regex_uri[2] .. "): " .. err
end
end
if conf.regex_host and #conf.regex_host > 0 then
local _, _, err = re_sub("featue.test.qisuyun.cn",
conf.regex_host[1],
conf.regex_host[2], "jo")
if err then
return false, "invalid regex_host(" .. conf.regex_host[1] ..
", " .. conf.regex_host[2] .. "): " .. err
end
end
--reform header from object into array, so can avoid use pairs, which is
NYI
if conf.headers then
conf.headers_arr = {}
for field, value in pairs(conf.headers) do
if type(field) == 'string'
and (type(value) == 'string' or type(value) == 'number') then
if #field == 0 then
return false, 'invalid field length in header'
end
core.table.insert(conf.headers_arr, field)
core.table.insert(conf.headers_arr, value)
else
return false, 'invalid type as header value'
end
end
end
return true
end
do
local upstream_vars = {
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
-- 重写host
local upstream_host = ctx.var.host
if conf.host ~= nil then
upstream_host = conf.host
elseif conf.regex_host ~= nil then
local host, _, err = re_sub(ctx.var.host, conf.regex_host[1],
conf.regex_host[2], "jo")
if host then
upstream_host = host
print(upstream_host)
else
local msg = "failed to substitute the host " .. ctx.var.host ..
" (" .. conf.regex_host[1] .. ") with " ..
conf.regex_host[2] .. " : " .. err
core.log.error(msg)
return 500, {message = msg}
end
end
-- 重写url
local upstream_uri = ctx.var.uri
if conf.uri ~= nil then
upstream_uri = conf.uri
elseif conf.regex_uri ~= nil then
local uri, _, err = re_sub(ctx.var.uri, conf.regex_uri[1],
conf.regex_uri[2], "jo")
if uri then
upstream_uri = uri
else
local msg = "failed to substitute the uri " .. ctx.var.uri ..
" (" .. conf.regex_uri[1] .. ") with " ..
conf.regex_uri[2] .. " : " .. err
core.log.error(msg)
return 500, {message = msg}
end
end
if ctx.var.is_args == "?" then
ctx.var.upstream_uri = upstream_uri .. "?" .. (ctx.var.args or "")
else
ctx.var.upstream_uri = upstream_uri
end
if conf.headers_arr then
local field_cnt = #conf.headers_arr
for i = 1, field_cnt, 2 do
ngx.req.set_header(conf.headers_arr[i], conf.headers_arr[i+1])
end
end
end
end -- do
return _M
```
### Environment
* apisix version (cmd: `apisix version`): 1.2
* OS: centos7
* Docker
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]