Skip to content

Commit

Permalink
feature: support to match IPv6 request. (#341)
Browse files Browse the repository at this point in the history
* CLI: supported to listen IPv6.

* feature: supported to match route by remote address.
  • Loading branch information
membphis authored Aug 24, 2019
1 parent c4cb7cd commit 1002765
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 4 deletions.
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

0 comments on commit 1002765

Please sign in to comment.