Skip to content

Commit

Permalink
fix: redirect http to https but port not change (#7065)
Browse files Browse the repository at this point in the history
Signed-off-by: Wei Jiang <machowei01@gmail.com>

Co-authored-by: 罗泽轩 <spacewanderlzx@gmail.com>
Co-authored-by: tzssangglass <tzssangglass@gmail.com>
Co-authored-by: Alex Zhang <tokers@apache.org>
  • Loading branch information
4 people authored May 18, 2022
1 parent 250db3b commit 435565d
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 24 deletions.
41 changes: 39 additions & 2 deletions apisix/plugins/redirect.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
-- limitations under the License.
--
local core = require("apisix.core")
local plugin = require("apisix.plugin")
local tab_insert = table.insert
local tab_concat = table.concat
local string_format = string.format
Expand All @@ -24,7 +25,8 @@ local ipairs = ipairs
local ngx = ngx
local str_find = core.string.find
local str_sub = string.sub
local tonumber = tonumber
local type = type
local math_random = math.random

local lrucache = core.lrucache.new({
ttl = 300, count = 100
Expand Down Expand Up @@ -143,12 +145,47 @@ local function concat_new_uri(uri, ctx)
return tab_concat(tmp, "")
end

local function get_port(attr)
local port
if attr then
port = attr.https_port
end

if port then
return port
end

local local_conf = core.config.local_conf()
local ssl = core.table.try_read_attr(local_conf, "apisix", "ssl")
if not ssl or not ssl["enable"] then
return port
end

port = ssl["listen_port"]
if port then
return port
end

local ports = ssl["listen"]
if ports and #ports > 0 then
local idx = math_random(1, #ports)
port = ports[idx]
if type(port) == "table" then
port = port.port
end
end

return port
end

function _M.rewrite(conf, ctx)
core.log.info("plugin rewrite phase, conf: ", core.json.delay_encode(conf))

local ret_code = conf.ret_code
local ret_port = tonumber(ctx.var["var_x_forwarded_port"])

local attr = plugin.plugin_attr(plugin_name)
local ret_port = get_port(attr)

local uri = conf.uri
local regex_uri = conf.regex_uri

Expand Down
2 changes: 2 additions & 0 deletions conf/config-default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -470,3 +470,5 @@ plugin_attr:
connect: 60s
read: 60s
send: 60s
# redirect:
# https_port: 8443 # the default port for use by HTTP redirects to HTTPS
5 changes: 4 additions & 1 deletion docs/en/latest/plugins/redirect.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ The `redirect` Plugin can be used to configure redirects.

Only one of `http_to_https`, `uri` and `regex_uri` can be configured.

* When enabling `http_to_https`, the port in the redirect URL will be the value of header `X-Forwarded-Port` or the port of the server.
* When enabling `http_to_https`, the ports in the redirect URL will pick a value in the following order (in descending order of priority)
* Read `plugin_attr.redirect.https_port` from the configuration file (`conf/config.yaml`).
* If `apisix.ssl` is enabled, read `apisix.ssl.listen_port` first, and if it does not exist, read `apisix.ssl.listen` and select a port randomly from it.
* Use 443 as the default https port.

:::

Expand Down
5 changes: 4 additions & 1 deletion docs/zh/latest/plugins/redirect.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ description: 本文介绍了关于 Apache APISIX `redirect` 插件的基本信

`http_to_https``uri``regex_uri` 只能配置其中一个属性。

* 当开启 `http_to_https` 时,重定向 URL 中的端口将是 `X-Forwarded-Port` 请求头的值或服务器的端口。
* 当开启 `http_to_https` 时,重定向 URL 中的端口将按如下顺序选取一个值(按优先级从高到低排列)
* 从配置文件(`conf/config.yaml`)中读取 `plugin_attr.redirect.https_port`
* 如果 `apisix.ssl` 处于开启状态,先读取 `apisix.ssl.listen_port`,如果没有,再读取 `apisix.ssl.listen` 并从中随机选一个 `port`
* 使用 443 作为默认 `https port`

:::

Expand Down
61 changes: 41 additions & 20 deletions t/plugin/redirect.t
Original file line number Diff line number Diff line change
Expand Up @@ -428,59 +428,80 @@ passed



=== TEST 18: redirect
=== TEST 18: redirect(port using `plugin_attr.redirect.https_port`)
--- extra_yaml_config
plugin_attr:
redirect:
https_port: 8443
--- request
GET /hello
--- more_headers
Host: foo.com
--- error_code: 301
--- response_headers
Location: https://foo.com:1984/hello
Location: https://foo.com:8443/hello



=== TEST 19: redirect(pass well-known port 443 to x-forwarded-port)
=== TEST 19: redirect(port using `apisix.ssl.listen_port`)
--- yaml_config
apisix:
ssl:
enable: true
listen_port: 9445
--- request
GET /hello
--- more_headers
Host: foo.com
x-forwarded-port: 443
--- error_code: 301
--- response_headers
Location: https://foo.com/hello
Location: https://foo.com:9445/hello



=== TEST 20: redirect(pass negative number to x-forwarded-port)
=== TEST 20: redirect(port using `apisix.ssl.listen` when listen length is one)
--- request
GET /hello
--- more_headers
Host: foo.com
x-forwarded-port: -443
--- error_code: 301
--- response_headers
Location: https://foo.com/hello
Location: https://foo.com:9443/hello



=== TEST 21: redirect(pass number more than 65535 to x-forwarded-port)
=== TEST 21: redirect(port using `apisix.ssl.listen` when listen length more than one)
--- yaml_config
apisix:
ssl:
enable: true
listen:
- 6443
- 7443
- port: 8443
- port: 9443
--- request
GET /hello
--- more_headers
Host: foo.com
x-forwarded-port: 65536
--- error_code: 301
--- response_headers
Location: https://foo.com/hello
--- response_headers_like
Location: https://foo.com:[6-9]443/hello



=== TEST 22: redirect(pass invalid non-number to x-forwarded-port)
=== TEST 22: redirect(port using `https default port`)
--- yaml_config
apisix:
ssl:
enable: null
--- extra_yaml_config
plugin_attr:
redirect: null
--- request
GET /hello
--- more_headers
Host: foo.com
x-forwarded-port: ok
--- error_code: 301
--- response_headers
Location: https://foo.com/hello
Expand Down Expand Up @@ -528,7 +549,7 @@ GET /hello
Host: foo.com
--- error_code: 301
--- response_headers
Location: https://foo.com:1984/hello
Location: https://foo.com:9443/hello



Expand Down Expand Up @@ -613,7 +634,7 @@ GET /hello
Host: test.com
--- error_code: 301
--- response_headers
Location: https://test.com:1984/hello
Location: https://test.com:9443/hello



Expand Down Expand Up @@ -763,7 +784,7 @@ POST /hello-https
--- more_headers
Host: test.com
--- response_headers
Location: https://test.com:1984/hello-https
Location: https://test.com:9443/hello-https
--- error_code: 308
--- no_error_log
[error]
Expand All @@ -776,7 +797,7 @@ GET /hello-https
--- more_headers
Host: test.com
--- response_headers
Location: https://test.com:1984/hello-https
Location: https://test.com:9443/hello-https
--- error_code: 301
--- no_error_log
[error]
Expand All @@ -789,7 +810,7 @@ HEAD /hello-https
--- more_headers
Host: test.com
--- response_headers
Location: https://test.com:1984/hello-https
Location: https://test.com:9443/hello-https
--- error_code: 301
--- no_error_log
[error]
Expand Down Expand Up @@ -1092,4 +1113,4 @@ Host: foo.com
X-Forwarded-Proto: http
--- error_code: 301
--- response_headers
Location: https://foo.com:1984/hello
Location: https://foo.com:9443/hello

0 comments on commit 435565d

Please sign in to comment.