From cd59e81a2edf7859b49867178606dec2bcd04c7a Mon Sep 17 00:00:00 2001 From: Yuansheng Wang Date: Wed, 24 Jun 2020 11:40:53 +0800 Subject: [PATCH 1/3] feature: add a new option, decide if we remove the "/" at the end of the URI before route mathing. fix #1765 --- apisix/init.lua | 19 +++-- conf/config.yaml | 2 + t/lib/server.lua | 4 ++ t/router/radixtree-uri-keep-end-slash.t | 95 +++++++++++++++++++++++++ t/router/radixtree-uri-sanity.t | 56 +++++++++++++++ 5 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 t/router/radixtree-uri-keep-end-slash.t diff --git a/apisix/init.lua b/apisix/init.lua index ad1131bc35be..a5149840aead 100644 --- a/apisix/init.lua +++ b/apisix/init.lua @@ -33,8 +33,10 @@ local ipairs = ipairs local tostring = tostring local type = type local ngx_now = ngx.now +local str_byte = string.byte +local str_sub = string.sub local load_balancer - +local local_conf local dns_resolver local lru_resolved_domain @@ -97,7 +99,7 @@ function _M.http_init_worker() require("apisix.debug").init_worker() require("apisix.upstream").init_worker() - local local_conf = core.config.local_conf() + local_conf = core.config.local_conf() local dns_resolver_valid = local_conf and local_conf.apisix and local_conf.apisix.dns_resolver_valid @@ -322,6 +324,15 @@ function _M.http_access_phase() api_ctx.global_rules = router.global_rules end + if local_conf.apisix and local_conf.apisix.delete_uri_tail_slash then + local uri = api_ctx.var.uri + if str_byte(uri, #uri) == str_byte("/") then + api_ctx.var.uri = str_sub(api_ctx.var.uri, 1, #uri - 1) + end + + core.log.info("new uri: ", api_ctx.var.uri) + end + router.router_http.match(api_ctx) core.log.info("matched route: ", @@ -585,7 +596,7 @@ end local function cors_admin() - local local_conf = core.config.local_conf() + local_conf = core.config.local_conf() if local_conf.apisix and not local_conf.apisix.enable_admin_cors then return end @@ -649,7 +660,7 @@ function _M.stream_init_worker() load_balancer = require("apisix.balancer").run - local local_conf = core.config.local_conf() + local_conf = core.config.local_conf() local dns_resolver_valid = local_conf and local_conf.apisix and local_conf.apisix.dns_resolver_valid diff --git a/conf/config.yaml b/conf/config.yaml index 58e113997ea4..10c7a5dd5038 100644 --- a/conf/config.yaml +++ b/conf/config.yaml @@ -74,6 +74,8 @@ apisix: name: "viewer" key: 4054f7cf07e344346cd3f287985e76a2 role: viewer + + delete_uri_tail_slash: true # delete the '/' at the end of the URI router: http: 'radixtree_uri' # radixtree_uri: match route by uri(base on radixtree) # radixtree_host_uri: match route by host + uri(base on radixtree) diff --git a/t/lib/server.lua b/t/lib/server.lua index e34602c30234..dfbead610566 100644 --- a/t/lib/server.lua +++ b/t/lib/server.lua @@ -28,6 +28,10 @@ function _M.hello1() ngx.say("hello1 world") end +function _M.hello_() + ngx.say("hello world") +end + function _M.server_port() ngx.print(ngx.var.server_port) end diff --git a/t/router/radixtree-uri-keep-end-slash.t b/t/router/radixtree-uri-keep-end-slash.t new file mode 100644 index 000000000000..d3c2c6d56c63 --- /dev/null +++ b/t/router/radixtree-uri-keep-end-slash.t @@ -0,0 +1,95 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +use t::APISIX 'no_plan'; + +repeat_each(1); +log_level('info'); +worker_connections(256); +no_root_location(); +no_shuffle(); + +sub read_file($) { + my $infile = shift; + open my $in, $infile + or die "cannot open $infile for reading: $!"; + my $cert = do { local $/; <$in> }; + close $in; + $cert; +} + +our $yaml_config = read_file("conf/config.yaml"); +$yaml_config =~ s/node_listen: 9080/node_listen: 1984/; +$yaml_config =~ s/enable_heartbeat: true/enable_heartbeat: false/; +$yaml_config =~ s/admin_key:/disable_admin_key:/; +$yaml_config =~ s/delete_uri_tail_slash: true/delete_uri_tail_slash: false/; + +run_tests(); + +__DATA__ + +=== TEST 1: set route +--- 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, + [[{ + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- yaml_config eval: $::yaml_config +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 2: hit route +--- request +GET /hello +--- yaml_config eval: $::yaml_config +--- response_body +hello world +--- no_error_log +[error] + + + +=== TEST 3: not hit route +--- request +GET /hello/ +--- yaml_config eval: $::yaml_config +--- error_code: 404 +--- no_error_log +[error] diff --git a/t/router/radixtree-uri-sanity.t b/t/router/radixtree-uri-sanity.t index 7c365a19e0f0..3b0426436434 100644 --- a/t/router/radixtree-uri-sanity.t +++ b/t/router/radixtree-uri-sanity.t @@ -268,3 +268,59 @@ GET /t passed --- no_error_log [error] + + + +=== TEST 13: set route(id: 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, + [[{ + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- yaml_config eval: $::yaml_config +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 14: hit route with /hello +--- request +GET /hello +--- yaml_config eval: $::yaml_config +--- response_body +hello world +--- no_error_log +[error] + + + +=== TEST 15: hit route with /hello/ +--- request +GET /hello/ +--- yaml_config eval: $::yaml_config +--- response_body +hello world +--- no_error_log +[error] From 39caa00f6ab91cb6f476b95e09bb7562c872e492 Mon Sep 17 00:00:00 2001 From: Yuansheng Wang Date: Wed, 24 Jun 2020 11:43:55 +0800 Subject: [PATCH 2/3] change: log with more information. --- apisix/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apisix/init.lua b/apisix/init.lua index a5149840aead..354290dc4c2a 100644 --- a/apisix/init.lua +++ b/apisix/init.lua @@ -328,9 +328,9 @@ function _M.http_access_phase() local uri = api_ctx.var.uri if str_byte(uri, #uri) == str_byte("/") then api_ctx.var.uri = str_sub(api_ctx.var.uri, 1, #uri - 1) + core.log.info("remove the end of uri '/', current uri: ", + api_ctx.var.uri) end - - core.log.info("new uri: ", api_ctx.var.uri) end router.router_http.match(api_ctx) From fc64e16fc060d27a599729f77b3f44981d1b805f Mon Sep 17 00:00:00 2001 From: Yuansheng Wang Date: Sun, 28 Jun 2020 18:21:30 +0800 Subject: [PATCH 3/3] change: use `false` for `delete_uri_tail_slash`. --- conf/config.yaml | 2 +- t/router/radixtree-uri-keep-end-slash.t | 7 ++++--- t/router/radixtree-uri-sanity.t | 5 ++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/conf/config.yaml b/conf/config.yaml index 10c7a5dd5038..aea1e859ff65 100644 --- a/conf/config.yaml +++ b/conf/config.yaml @@ -75,7 +75,7 @@ apisix: key: 4054f7cf07e344346cd3f287985e76a2 role: viewer - delete_uri_tail_slash: true # delete the '/' at the end of the URI + delete_uri_tail_slash: false # delete the '/' at the end of the URI router: http: 'radixtree_uri' # radixtree_uri: match route by uri(base on radixtree) # radixtree_host_uri: match route by host + uri(base on radixtree) diff --git a/t/router/radixtree-uri-keep-end-slash.t b/t/router/radixtree-uri-keep-end-slash.t index d3c2c6d56c63..ec6e9ba72bb8 100644 --- a/t/router/radixtree-uri-keep-end-slash.t +++ b/t/router/radixtree-uri-keep-end-slash.t @@ -35,7 +35,7 @@ our $yaml_config = read_file("conf/config.yaml"); $yaml_config =~ s/node_listen: 9080/node_listen: 1984/; $yaml_config =~ s/enable_heartbeat: true/enable_heartbeat: false/; $yaml_config =~ s/admin_key:/disable_admin_key:/; -$yaml_config =~ s/delete_uri_tail_slash: true/delete_uri_tail_slash: false/; +$yaml_config =~ s/delete_uri_tail_slash: false/delete_uri_tail_slash: true/; run_tests(); @@ -86,10 +86,11 @@ hello world -=== TEST 3: not hit route +=== TEST 3: hit route --- request GET /hello/ --- yaml_config eval: $::yaml_config ---- error_code: 404 +--- response_body +hello world --- no_error_log [error] diff --git a/t/router/radixtree-uri-sanity.t b/t/router/radixtree-uri-sanity.t index 3b0426436434..0cd6101401b9 100644 --- a/t/router/radixtree-uri-sanity.t +++ b/t/router/radixtree-uri-sanity.t @@ -316,11 +316,10 @@ hello world -=== TEST 15: hit route with /hello/ +=== TEST 15: miss route --- request GET /hello/ --- yaml_config eval: $::yaml_config ---- response_body -hello world +--- error_code: 404 --- no_error_log [error]