AlinsRan commented on code in PR #13626:
URL: https://github.com/apache/apisix/pull/13626#discussion_r3526244076


##########
apisix/init.lua:
##########
@@ -487,6 +490,42 @@ local function normalize_uri_like_servlet(uri)
 end
 
 
+-- Percent-decode every %XX in the path. When keep_slash is true, an encoded
+-- slash (%2F/%2f) is left as the literal text "%2F" instead of being turned
+-- into a real path separator -- Nginx decodes it into '/' in $uri, which makes
+-- it indistinguishable from a real separator and breaks path parameter
+-- matching (see issue #11810). The kept slash is always emitted upper-case so
+-- an exact route written with %2F matches regardless of the client's casing.
+local function percent_decode(path, keep_slash)
+    local decoded = re_gsub(path, [[%([0-9a-fA-F][0-9a-fA-F])]], function(m)
+        local hex = m[1]
+        if keep_slash and (hex == "2f" or hex == "2F") then
+            return "%2F"

Review Comment:
   Added a line to router-radixtree.md (en + zh): the kept slash is normalized 
to upper-case `%2F` and radixtree compares byte-for-byte, so routes must be 
authored with upper-case `%2F`. f0a07aa66



##########
apisix/init.lua:
##########
@@ -784,8 +823,37 @@ function _M.http_access_phase()
 
     handle_x_forwarded_headers(api_ctx)
 
+    -- When match_uri_encoded_slash is on, match the route against a uri that
+    -- keeps the encoded slash (%2F) so it is treated as part of a path
+    -- parameter. This is a router-match-only value: it is swapped in just for
+    -- dispatch and restored right after, so the rewrite/access phases, plugins
+    -- and the upstream keep seeing the normalized ctx.var.uri. Only the 
matched
+    -- route and its captured params (uri_param_*) retain the encoded slash.
+    local match_uri
+    if local_conf.apisix and local_conf.apisix.match_uri_encoded_slash then
+        local path = api_ctx.var.real_request_uri
+        if path then

Review Comment:
   Dropped the guard — `real_request_uri` is assigned unconditionally a few 
lines above, so it is always set. f0a07aa66



##########
apisix/init.lua:
##########
@@ -784,8 +823,37 @@ function _M.http_access_phase()
 
     handle_x_forwarded_headers(api_ctx)
 
+    -- When match_uri_encoded_slash is on, match the route against a uri that
+    -- keeps the encoded slash (%2F) so it is treated as part of a path
+    -- parameter. This is a router-match-only value: it is swapped in just for
+    -- dispatch and restored right after, so the rewrite/access phases, plugins
+    -- and the upstream keep seeing the normalized ctx.var.uri. Only the 
matched
+    -- route and its captured params (uri_param_*) retain the encoded slash.
+    local match_uri
+    if local_conf.apisix and local_conf.apisix.match_uri_encoded_slash then
+        local path = api_ctx.var.real_request_uri
+        if path then
+            local args_pos = core.string.find(path, "?")
+            if args_pos then
+                path = str_sub(path, 1, args_pos - 1)
+            end
+            if str_find(path, "%2f", 1, true)

Review Comment:
   Switched both checks to `core.string.find` and removed the now-unused 
`str_find` import. f0a07aa66



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to