mikyll opened a new issue, #11810:
URL: https://github.com/apache/apisix/issues/11810

   ### Description
   
   ## 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](https://apisix.apache.org/docs/apisix/router-radixtree/#5-parameter-match)
 router **doesn't support** `%2F` in path parameters.
   
   See:
   
   - PR [apache/apisix#11788](https://github.com/apache/apisix/pull/11788)
   - Issue 
[api7/lua-resty-radixtree#148](https://github.com/api7/lua-resty-radixtree/issues/148),
 
   
   ### 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`:
   
   ```yaml
   apisix:
     router:
       http: radixtree_uri_with_parameter
   
   deployment:
     role: data_plane
     role_data_plane:
       config_provider: yaml
   ```
   
   File `apisix.yaml`:
   
   ```yaml
   routes:
     # Test path parameters
     - id: path-params
       uri: /v1/:id/products/electronics/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: 🟢 
   
       ```bash
       curl -s -i localhost:9080/v1/test/products/electronics/list | grep HTTP
       HTTP/1.1 200 OK
       ```
   
   - path parameter with `%20` (URL-encoded space ` `): 🟢 
   
       ```bash
       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 `/`): 🔴 
   
       ```bash
       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 
([xpicio/routing-with-encoded-slash](https://github.com/xpicio/routing-with-encoded-slash))
 and below is a summary of what we have found:
   
   | Technology         | Supports URL-encoded chars | Behaviour              | 
Docs |
   | ------------------ | ---------------------------| ---------------------- | 
---- |
   | Django (Python)    | 🟢                         | Using `<path:id>`      | 
[Django - Path 
Converters](https://docs.djangoproject.com/en/5.1/topics/http/urls/#path-converters)
 |
   | Fastapi (Python)   | 🟢                         | Using `{id:path}`      | 
[Fastapi - Path 
Convertor](https://fastapi.tiangolo.com/tutorial/path-params/?h=path+para#path-convertor)
 |
   | Flask (Python)     | 🟢                         | Using `<path:id>`      | 
[Flask - Variable 
Rules](https://flask.palletsprojects.com/en/stable/quickstart/#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**.
   


-- 
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