Skip to content

bug: As a user, I want to use '%2F' in a path parameter #11810

Description

@mikyll

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status
    ✅ Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions