AlinsRan opened a new pull request, #13626:
URL: https://github.com/apache/apisix/pull/13626
### Description
Nginx decodes an URL-encoded slash (`%2F`) into a real `/` in `$uri` *before*
route matching happens. As a result a request like
`/v1/te%2Fst/products/electronics/list` is seen by the router as
`/v1/te/st/products/electronics/list`, which has a different number of path
segments and therefore fails to match a route defined with path parameters
such
as `/v1/:id/products/:type/list` (returns `404 Route Not Found`). This is the
problem reported in #11810, and it cannot be fixed in `lua-resty-radixtree`
(the parameter pattern `[^/]+` must stop at a real slash to keep segmentation
correct) because the information is already lost by the time the router runs.
This PR adds an opt-in `apisix.preserve_encoded_slash` option (default
`false`).
When enabled, the route matching uri is rebuilt from the raw `request_uri`
with
every percent-encoding decoded **except** `%2F`/`%2f`, which is kept encoded
so
it is treated as part of a path parameter instead of a separator. The encoded
slash is then forwarded to the upstream as is.
To stay safe while bypassing Nginx's `$uri` normalization, the rebuild:
- resolves `.` and `..` segments (so an encoded dot like `%2e%2e` cannot be
used
to bypass route rules via path traversal);
- rejects a decoded null byte, matching Nginx's own behaviour;
- only runs when an encoded slash is actually present, so requests without
`%2F`
keep using the already normalized `$uri` with no overhead.
This follows the same access-phase, opt-in pattern as the existing
`normalize_uri_like_servlet` option.
#### Which issue(s) this PR fixes:
Fixes #11810
### Checklist
- [x] I have explained the need for this PR and the problem it solves
- [x] I have explained the changes or the new features added to this PR
- [x] I have added tests corresponding to this change
- [x] I have updated the documentation to reflect this change
- [x] I have verified that this change is backward compatible (the option
defaults to `false`)
--
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]