You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: conf/config.yaml.example
+5Lines changed: 5 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -70,6 +70,11 @@ apisix:
70
70
delete_uri_tail_slash: false # Delete the '/' at the end of the URI
71
71
normalize_uri_like_servlet: false # If true, use the same path normalization rules as the Java
72
72
# servlet specification. See https://github.com/jakartaee/servlet/blob/master/spec/src/main/asciidoc/servlet-spec-body.adoc#352-uri-path-canonicalization, which is used in Tomcat.
73
+
match_uri_encoded_slash: false # If true, keep an URL-encoded slash (%2F) encoded when matching
74
+
# routes, so it is treated as part of a path parameter instead of a
75
+
# path separator. Plugins in the rewrite/access phases still read the
76
+
# normalized (decoded) URI from ctx.var.uri; nginx forwards the
77
+
# original request line, so the upstream receives %2F unchanged.
73
78
max_post_args_readable_size: 64 # Cap (in MB) on the request body read when matching `post_arg.*`
74
79
# route predicates for JSON and multipart requests. Set to 0 to disable the limit.
Copy file name to clipboardExpand all lines: docs/en/latest/router-radixtree.md
+44Lines changed: 44 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -196,6 +196,50 @@ will match both `/blog/dog` and `/blog/cat`.
196
196
197
197
For more details, see https://github.com/api7/lua-resty-radixtree/#parameters-in-path.
198
198
199
+
By default, an URL-encoded slash (`%2F`) inside a parameter is decoded by Nginx
200
+
into a real `/` before route matching, so a request like `/blog/cat%2Fdog` is
201
+
treated as `/blog/cat/dog` and does not match `/blog/:name`. To keep `%2F`
202
+
encoded during matching (so it is treated as part of the parameter value rather
203
+
than a path separator), enable `match_uri_encoded_slash`:
204
+
205
+
```yaml
206
+
apisix:
207
+
match_uri_encoded_slash: true
208
+
router:
209
+
http: 'radixtree_uri_with_parameter'
210
+
```
211
+
212
+
With this enabled, `/blog/cat%2Fdog` matches `/blog/:name` with `name` being
213
+
`cat%2Fdog`. The encoded slash is kept only for route matching and parameter
214
+
capture: plugins in the rewrite/access phases still read the normalized
215
+
(decoded) URI from `ctx.var.uri`. The request line nginx forwards to the
216
+
upstream is the original one, so the upstream receives `%2F` unchanged.
217
+
218
+
This option is global and changes how every route is matched. Because the
219
+
matching URI keeps `%2F` encoded, an exact route such as `/blog/cat/dog` will no
220
+
longer match a request like `/blog/cat%2Fdog` that used to match after Nginx
221
+
decoded the slash. Enable it only when you rely on `%2F` inside path parameters.
222
+
223
+
To stay safe, APISIX does not re-implement Nginx's URI normalization. It keeps
224
+
`%2F`encoded only when a plain full decode of the request path already equals
225
+
the normalized `$uri` — i.e. when Nginx applied nothing beyond percent-decoding.
226
+
If the request also required normalization (dot segments such as `..%2F..%2F` or
227
+
`%2e%2e`, merged consecutive slashes, an absolute-form request line, etc.), the
228
+
matching URI falls back to the normalized `$uri`. Such requests therefore never
229
+
become an encoded-slash match and cannot bypass route rules via path traversal.
230
+
231
+
The kept slash is always normalized to upper-case `%2F`, and radixtree compares
232
+
byte-for-byte, so a route whose URI is authored with a lower-case `%2f` (e.g.
233
+
`/blog/a%2fb`) will not match. Write the encoded slash as upper-case `%2F` in
234
+
route URIs.
235
+
236
+
This option gives way to `delete_uri_tail_slash` and `normalize_uri_like_servlet`:
237
+
the equivalence check compares against the URI those options already produced, so
238
+
when either actually rewrites the URI (a stripped trailing slash, a servlet-style
239
+
`;`parameter) the check no longer holds and the request falls back to normal
240
+
matching without keeping `%2F`. The fallback is safe; the encoded-slash match
241
+
simply does not apply to such requests.
242
+
199
243
### How to filter route by Nginx built-in variable?
200
244
201
245
Nginx provides a variety of built-in variables that can be used to filter routes based on certain criteria. Here is an example of how to filter routes by Nginx built-in variables:
0 commit comments