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

feature: support to match IPv6 request. #341

Merged
merged 9 commits into from
Aug 24, 2019
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
6 changes: 5 additions & 1 deletion bin/apisix
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ http {
listen {* port_admin *};

location /apisix/admin/ {
{% for _, allow_ip in ipairs(allow_admin) do %}
{% for _, allow_ip in ipairs(allow_admin or {}) do %}
allow {*allow_ip*};
{% end %}
deny all;
Expand All @@ -161,6 +161,10 @@ http {
server {
listen {* node_listen *};
listen {* node_ssl_listen *} ssl;
{% if enable_ipv6 then %}
listen [::]:{* node_listen *};
listen [::]:{* node_ssl_listen *} ssl;
{% end %}
ssl_certificate cert/apisix.crt;
ssl_certificate_key cert/apisix.key;
ssl_session_cache shared:SSL:1m;
Expand Down
2 changes: 2 additions & 0 deletions conf/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ apisix:
enable_heartbeat: true
enable_admin: true
enable_debug: false
enable_ipv6: true
allow_admin: # http://nginx.org/en/docs/http/ngx_http_access_module.html#allow
- 127.0.0.0/24
- "::/64"
# port_admin: 9180 # use a separate port
real_ip_header: "X-Real-IP" # http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_header
real_ip_from: # http://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from
Expand Down
3 changes: 2 additions & 1 deletion lua/apisix/core/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@ local route = [[{
"anyOf": [
{"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"},
{"pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}]]
.. [[/[0-9]{1,2}$"}
.. [[/[0-9]{1,2}$"},
{"pattern": "^([a-f0-9]{0,4}:){0,8}(:[a-f0-9]{0,4}){0,8}$"}
]
},
"service_id": ]] .. json.encode(id_schema) .. [[,
Expand Down
3 changes: 3 additions & 0 deletions lua/apisix/http/router/r3_host_uri.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ local function push_valid_route(route)
core.table.insert(only_uri_routes, {
path = route.value.uri,
method = route.value.methods,
remote_addr = route.value.remote_addr,
handler = function (params, api_ctx)
api_ctx.matched_params = params
api_ctx.matched_route = route
Expand All @@ -64,6 +65,7 @@ local function push_valid_route(route)
core.table.insert(host_uri_routes, {
path = "/" .. host .. route.value.uri,
method = route.value.methods,
remote_addr = route.value.remote_addr,
handler = function (params, api_ctx)
api_ctx.matched_params = params
api_ctx.matched_route = route
Expand Down Expand Up @@ -104,6 +106,7 @@ function _M.match(api_ctx)

core.table.clear(match_opts)
match_opts.method = api_ctx.var.method
match_opts.remote_addr = api_ctx.var.remote_addr

local host_uri = "/" .. str_reverse(api_ctx.var.host) .. api_ctx.var.uri
local ok = host_uri_router:dispatch2(nil, host_uri, match_opts, api_ctx)
Expand Down
1 change: 1 addition & 0 deletions lua/apisix/http/router/r3_uri.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ function _M.match(api_ctx)
core.table.clear(match_opts)
match_opts.method = api_ctx.var.method
match_opts.host = api_ctx.var.host
match_opts.remote_addr = api_ctx.var.remote_addr

local ok = uri_router:dispatch2(nil, api_ctx.var.uri, match_opts, api_ctx)
if not ok then
Expand Down
2 changes: 2 additions & 0 deletions lua/apisix/http/router/radixtree_uri.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ local function create_radixtree_router(routes)
path = route.value.uri,
method = route.value.methods,
host = route.value.host,
remote_addr = route.value.remote_addr,
handler = function (api_ctx)
api_ctx.matched_params = nil
api_ctx.matched_route = route
Expand Down Expand Up @@ -66,6 +67,7 @@ function _M.match(api_ctx)
core.table.clear(match_opts)
match_opts.method = api_ctx.var.method
match_opts.host = api_ctx.var.host
match_opts.remote_addr = api_ctx.var.remote_addr

local ok = uri_router:dispatch(api_ctx.var.uri, match_opts, api_ctx)
if not ok then
Expand Down
5 changes: 5 additions & 0 deletions t/APISix.pm
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,16 @@ _EOC_
$block->set_value("http_config", $http_config);

my $TEST_NGINX_HTML_DIR = $ENV{TEST_NGINX_HTML_DIR} ||= html_dir();
my $ipv6_listen_conf = '';
if (defined $block->listen_ipv6) {
$ipv6_listen_conf = "listen \[::1\]:12345;"
}

my $wait_etcd_sync = $block->wait_etcd_sync // 0.1;

my $config = $block->config // '';
$config .= <<_EOC_;
$ipv6_listen_conf
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;

ssl_certificate cert/apisix.crt;
Expand Down
43 changes: 43 additions & 0 deletions t/lib/test_admin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,45 @@ local methods = {
}


function _M.test_ipv6(uri)
local sock = ngx.socket.tcp()
local ok, err = sock:connect("[::1]", 12345)
if not ok then
ngx.say("failed to connect: ", err)
return
end

ngx.say("connected: ", ok)

local req = "GET " .. uri .. " HTTP/1.0\r\nHost: localhost\r\n"
.. "Connection: close\r\n\r\n"
-- req = "OK"
-- ngx.log(ngx.WARN, "req: ", req)

local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end

ngx.say("request sent: ", bytes)

while true do
local line, err, part = sock:receive()
if line then
ngx.say("received: ", line)

else
ngx.say("failed to receive a line: ", err, " [", part, "]")
break
end
end

ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
end


function _M.test(uri, method, body, pattern)
if type(body) == "table" then
body = json.encode(body)
Expand Down Expand Up @@ -67,6 +106,10 @@ function _M.test(uri, method, body, pattern)
},
}
)
if not res then
ngx.log(ngx.ERR, "failed http: ", err)
return nil, err
end

if res.status >= 300 then
return res.status, res.body
Expand Down
118 changes: 118 additions & 0 deletions t/node/remote-addr-ipv6.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
use t::APISix;

no_root_location();

my $travis_os_name = $ENV{TRAVIS_OS_NAME};
if ($travis_os_name eq "osx") {
plan 'no_plan';
} else {
plan(skip_all => "skip remote address(IPv6) under linux");
}

run_tests();

__DATA__

=== TEST 1: set route: remote addr = ::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,
[[{
"remote_addr": "::1",
"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 2: IPv6 /not_found
--- listen_ipv6
--- config
location /t {
content_by_lua_block {
ngx.sleep(0.2)
local t = require("lib.test_admin").test_ipv6
t('/not_found')
}
}
--- request
GET /t
--- response_body_like eval
qr{.*404 Not Found.*}
--- no_error_log
[error]



=== TEST 3: IPv4 /not_found
--- listen_ipv6
--- request
GET /not_found
--- error_code: 404
--- response_body_like eval
qr{.*404 Not Found.*}
--- no_error_log
[error]



=== TEST 4: IPv6 /hello
--- listen_ipv6
--- config
location /t {
content_by_lua_block {
ngx.sleep(0.2)
local t = require("lib.test_admin").test_ipv6
t('/hello')
}
}
--- request
GET /t
--- response_body
connected: 1
request sent: 59
received: HTTP/1.1 200 OK
received: Content-Type: text/plain
received: Connection: close
received: Server: openresty
received:
received: hello world
failed to receive a line: closed []
close: 1 nil
--- no_error_log
[error]



=== TEST 5: IPv4 /hello
--- listen_ipv6
--- request
GET /hello
--- error_code: 404
--- response_body_like eval
qr{.*404 Not Found.*}
--- no_error_log
[error]
5 changes: 3 additions & 2 deletions t/node/remote-addr.t
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,9 @@ passed
=== TEST 5: not hit route: 127.0.0.2 =~ 127.0.0.1
--- request
GET /hello
--- response_body
hello world
--- error_code: 404
--- response_body_like eval
qr/404 Not Found/
--- no_error_log
[error]

Expand Down