User Story
As a user, I want to include URL-encoded special characters such as %2F in request path parameters.
Example:
- APISIX config:
- running on localhost;
- dataplane exposed on port 9080;
- router
radixtree_uri_with_parameter;
- API definition:
/api/:path_parameter/foo;
- request URL:
http://localhost:9080/api/test%2Ftest/foo;
Problem
Currently, APISIX with radixtree_uri_with_parameter router doesn't support %2F in path parameters.
See:
MRE (Minimal Reproducible Example)
The following MRE demonstrates the issue. For simplicity we use APISIX in standalone mode.
NB: verify that the lib-resty-radixtree version is >= 2.9.2.
File config.yaml:
apisix:
router:
http: radixtree_uri_with_parameter
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
File apisix.yaml:
routes:
# Test path parameters
- id: path-params
uri: /v1/:id/products/:type/list
upstream:
nodes:
"httpbin.org": 1
type: roundrobin
plugins:
proxy-rewrite:
uri: /status/200
method: GET
#END
Test the routes:
-
path parameter without special characters: 🟢
curl -s -i localhost:9080/v1/te%20st/products/electronics/list | grep HTTP
HTTP/1.1 200 OK
-
path parameter with %20 (URL-encoded space ): 🟢
curl -s -i localhost:9080/v1/te%20st/products/electronics/list | grep HTTP
HTTP/1.1 200 OK
-
path parameter with %2F (URL-encoded slash /): 🔴
curl -s -i localhost:9080/v1/te%2Fst/products/electronics/list | grep HTTP
HTTP/1.1 404 Not Found
Additional Information
Why is this feature important?
The current behaviour should ideally be wrong, since the route exists but the request URL is parsed wrongly — contrary to what the 404 status code says. Some frameworks (see the examples below) provide a more expressive implementation, such as allowing further configuration for encoded / and returning 400 Bad Request when it's not allowed.
Other Technologies/Frameworks
How do other technologies handle this?
For reference, we made some test with different technologies among the most popular web servers and frameworks and almost every of them support this behaviour.
We collected some examples in a repository along with instructions for the setup and test of each one (xpicio/routing-with-encoded-slash), and below is a summary of what we have found:
| Technology |
Supports URL-encoded chars |
Usage |
Docs |
| Django (Python) |
🟢 |
Using <path:id> |
Django - Path Converters |
| Fastapi (Python) |
🟢 |
Using {id:path} |
Fastapi - Path Convertor |
| Flask (Python) |
🟢 |
Using <path:id> |
Flask - Variable Rules |
| Express (JS) |
🟢 |
Using :id (default) |
- |
| Fastify (JS) |
🟢 |
Using :id (default) |
- |
| Actix Web (Rust) |
🟢 |
Using {id} (default) |
- |
| ASP.NET Core (C#) |
🟢 |
Using {id} (default) |
- |
| Spring Boot (Java) |
🟢 |
By default requests containing %2F in path parameters return 400: Bad Request, but Tomcat can be configured to allow them |
- |
Our Scenario
Why is this feature important to us?
Our company has some legacy APIs that expect serial numbers containing / (encoded as %2F) in path parameters. Since we maintain serial numbers virtually forever, we cannot change them.
To bypass the problem we defined the routes with * instead of named path parameters, but that makes our APIs definition not homogeneous and introduces the risk of unexpected collisions.
User Story
As a user, I want to include URL-encoded special characters such as
%2Fin request path parameters.Example:
radixtree_uri_with_parameter;/api/:path_parameter/foo;http://localhost:9080/api/test%2Ftest/foo;Problem
Currently, APISIX with radixtree_uri_with_parameter router doesn't support
%2Fin path parameters.See:
MRE (Minimal Reproducible Example)
The following MRE demonstrates the issue. For simplicity we use APISIX in standalone mode.
NB: verify that the
lib-resty-radixtreeversion is >=2.9.2.File
config.yaml:File
apisix.yaml:Test the routes:
path parameter without special characters: 🟢
curl -s -i localhost:9080/v1/te%20st/products/electronics/list | grep HTTP HTTP/1.1 200 OKpath parameter with
%20(URL-encoded space): 🟢curl -s -i localhost:9080/v1/te%20st/products/electronics/list | grep HTTP HTTP/1.1 200 OKpath parameter with
%2F(URL-encoded slash/): 🔴curl -s -i localhost:9080/v1/te%2Fst/products/electronics/list | grep HTTP HTTP/1.1 404 Not FoundAdditional Information
The current behaviour should ideally be wrong, since the route exists but the request URL is parsed wrongly — contrary to what the
404status code says. Some frameworks (see the examples below) provide a more expressive implementation, such as allowing further configuration for encoded/and returning400 Bad Requestwhen it's not allowed.Other Technologies/Frameworks
For reference, we made some test with different technologies among the most popular web servers and frameworks and almost every of them support this behaviour.
We collected some examples in a repository along with instructions for the setup and test of each one (xpicio/routing-with-encoded-slash), and below is a summary of what we have found:
<path:id>{id:path}<path:id>:id(default):id(default){id}(default){id}(default)%2Fin path parameters return400: Bad Request, but Tomcat can be configured to allow themOur Scenario
Our company has some legacy APIs that expect serial numbers containing
/(encoded as%2F) in path parameters. Since we maintain serial numbers virtually forever, we cannot change them.To bypass the problem we defined the routes with
*instead of named path parameters, but that makes our APIs definition not homogeneous and introduces the risk of unexpected collisions.