Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
15 changes: 15 additions & 0 deletions apisix/plugins/proxy-rewrite.lua
Original file line number Diff line number Diff line change
Expand Up @@ -284,13 +284,28 @@ function _M.rewrite(conf, ctx)

local upstream_uri = ctx.var.uri
local separator_escaped = false

-- resolve_var() below drops the query string, so keep the original one from
-- real_request_uri to re-append it when conf.uri is set.
local query_string = ""
if conf.use_real_request_uri_unsafe then
upstream_uri = ctx.var.real_request_uri
local index = str_find(upstream_uri, "?")
query_string = index and sub_str(upstream_uri, index) or ""
end

if conf.uri ~= nil then
separator_escaped = true
upstream_uri = core.utils.resolve_var(conf.uri, ctx.var, escape_separator)
if query_string ~= "" then
-- merge with '&' when conf.uri already carries its own query string,
-- otherwise append the original query string as-is
if str_find(upstream_uri, "?") then
upstream_uri = upstream_uri .. "&" .. sub_str(query_string, 2)
else
upstream_uri = upstream_uri .. query_string
end
end

elseif conf.regex_uri ~= nil then
if not str_find(upstream_uri, "?") then
Expand Down
285 changes: 285 additions & 0 deletions t/plugin/proxy-rewrite.t
Original file line number Diff line number Diff line change
Expand Up @@ -1231,3 +1231,288 @@ GET /hello
uri: /uri
host: test.com:6443
x-real-ip: 127.0.0.1



=== TEST 45: set route(rewrite uri args with unsafe allowed)
--- 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": "/plugin_proxy_rewrite_args",
"use_real_request_uri_unsafe": 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



=== TEST 46: rewrite uri args
Comment thread
AlinsRan marked this conversation as resolved.
--- request
GET /hello?q=apisix&a=iresty HTTP/1.1
--- response_body
uri: /plugin_proxy_rewrite_args
a: iresty
q: apisix



=== TEST 47: set route(rewrite uri empty args with unsafe allowed)
--- 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": "/plugin_proxy_rewrite_args",
"use_real_request_uri_unsafe": 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



=== TEST 48: rewrite uri empty args
--- request
GET /hello HTTP/1.1
--- response_body
uri: /plugin_proxy_rewrite_args



=== TEST 49: set route(conf.uri carries its own query, use_real_request_uri_unsafe)
--- 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": "/plugin_proxy_rewrite_args?x=1",
"use_real_request_uri_unsafe": 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



=== TEST 50: merge conf.uri query with incoming query (use '&', not double '?')
--- request
GET /hello?q=apisix HTTP/1.1
--- response_body
uri: /plugin_proxy_rewrite_args
q: apisix
x: 1



=== TEST 51: set route(use_real_request_uri_unsafe only, no conf.uri)
--- 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": {
"use_real_request_uri_unsafe": true
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/plugin_proxy_rewrite_args"
}]]
)

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



=== TEST 52: query string reaches upstream exactly once without conf.uri
--- request
GET /plugin_proxy_rewrite_args?q=apisix HTTP/1.1
--- response_body
uri: /plugin_proxy_rewrite_args
q: apisix



=== TEST 53: set route(conf.uri echoing raw request_uri, use_real_request_uri_unsafe)
--- 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": "/print_uri_detailed",
"use_real_request_uri_unsafe": 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



=== TEST 54: query with special characters passed through unchanged (unsafe)
--- request
GET /hello?name=a%20b&x=%E4%B8%AD HTTP/1.1
--- response_body
ngx.var.uri: /print_uri_detailed
ngx.var.request_uri: /print_uri_detailed?name=a%20b&x=%E4%B8%AD



=== TEST 55: query with multiple '?' passed through unchanged (unsafe)
--- request
GET /hello?a=1?b=2 HTTP/1.1
--- response_body
ngx.var.uri: /print_uri_detailed
ngx.var.request_uri: /print_uri_detailed?a=1?b=2



=== TEST 56: set route(same conf.uri with use_real_request_uri_unsafe disabled)
--- 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": "/print_uri_detailed",
"use_real_request_uri_unsafe": 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



=== TEST 57: query preserved with use_real_request_uri_unsafe disabled (both variants consistent)
--- request
GET /hello?name=a%20b&x=1 HTTP/1.1
--- response_body
ngx.var.uri: /print_uri_detailed
ngx.var.request_uri: /print_uri_detailed?name=a%20b&x=1
48 changes: 46 additions & 2 deletions t/plugin/proxy-rewrite3.t
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ plugin_proxy_rewrite get method: POST



=== TEST 8: set route(unsafe uri not normalized at request)
=== TEST 8: set route(unsafe uri not normalized at request with unsafe allowed)
--- config
location /t {
content_by_lua_block {
Expand Down Expand Up @@ -243,7 +243,7 @@ ngx.var.request_uri: /print%5Furi%5Fdetailed



=== TEST 10: set route(safe uri not normalized at request)
=== TEST 10: set route(safe uri not normalized at request with unsafe allowed)
--- config
location /t {
content_by_lua_block {
Expand Down Expand Up @@ -999,3 +999,47 @@ GET /hello/%ED%85%8C%EC%8A%A4%ED%8A%B8 HTTP/1.1
}
--- response_body
/hello?unsafe_variable=%ED%85%8C%EC%8A%A4%ED%8A%B8



=== TEST 42: set route(unsafe uri normalized at request with unsafe not allowed)
--- 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": {
"use_real_request_uri_unsafe": false
}
},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/print_uri_detailed"
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- response_body
passed



=== TEST 43: unsafe uri normalized at request
--- request
GET /print%5Furi%5Fdetailed HTTP/1.1
--- response_body
ngx.var.uri: /print_uri_detailed
ngx.var.request_uri: /print_uri_detailed
Loading