ballerina-platform / ballerina-library

The Ballerina Library
https://ballerina.io/learn/api-docs/ballerina/
Apache License 2.0
138 stars 56 forks source link

The `|` character in request path makes the Ballerina listener go unresponsive #4440

Open abeykoon opened 1 year ago

abeykoon commented 1 year ago

Description:

In my scenario, I generate a unique ID for my APIs. example : saas|7f91f8d392fbab5b44b5445703ae4e21

Then I have a service to allow users to fetch API by ID. {{baseUrl}}/apis/<apiID>

Issue is when I send following to the service, the subsequent requests to the same resource (did not check other resources though) does not work.

{{baseUrl}}/apis/saas|7f91f8d392fbab5b44b5445703ae4e21

Steps to reproduce:

  1. Write a simple service with a resource method with above signature
  2. Hit the service with | encoded. (i.e {{baseUrl}}/apis/saas%7C7f91f8d392fbab5b44b5445703ae4e21). Make sure it works.
  3. Hit the service with | not encoded. (i.e {{baseUrl}}/apis/saas|7f91f8d392fbab5b44b5445703ae4e21)
  4. Again try no:2, service is unresponsive.

Affected Versions:

Ballerina 5.0.0

TharmiganK commented 1 year ago
  1. Tried the following sample:
    
    import ballerina/io;
    import ballerina/http;

service /test on new http:Listener(9090) {

resource function get apis/apiId/[string apiId]() returns http:Ok {
    io:println("apiId: " + apiId);
    return http:OK;
}

}


2. Made a request with encoded path
```console
$ curl "http://localhost:9090/test/apis/apiId/saas%7C7f91f8d392fbab5b44b5445703ae4e21"

*   Trying 127.0.0.1:9090...
* Connected to localhost (127.0.0.1) port 9090 (#0)
> GET /test/apis/apiId/saas%7C7f91f8d392fbab5b44b5445703ae4e21 HTTP/1.1
> Host: localhost:9090
> User-Agent: curl/7.87.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: text/plain
< content-length: 57
< server: ballerina
< date: Fri, 12 May 2023 10:46:00 +0530
< 
* Connection #0 to host localhost left intact
Success with apiId: saas|7f91f8d392fbab5b44b5445703ae4e21
  1. Made a request without encoding

    *   Trying 127.0.0.1:9090...
    * Connected to localhost (127.0.0.1) port 9090 (#0)
    > GET /test/apis/apiId/saas|7f91f8d392fbab5b44b5445703ae4e21 HTTP/1.1
    > Host: localhost:9090
    > User-Agent: curl/7.87.0
    > Accept: */*
    > 
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 404 Not Found
    < content-type: text/plain
    < content-length: 100
    < server: ballerina
    < date: Fri, 12 May 2023 10:47:42 +0530
    < 
    * Connection #0 to host localhost left intact
    Illegal character in path at index 28: http:///test/apis/apiId/saas|7f91f8d392fbab5b44b5445703ae4e21

    Note: This error is expected as | is not allowed in the path segment according to the HTTP spec and you should encode the path.

  2. Again tried several times with the encoded path, and the service seems to be responsive

    
    $ curl -v "http://localhost:9090/test/apis/apiId/saas%7C7f91f8d392fbab5b44b5445703ae4e21"

Note: I have checked with Ballerina 2201.5.0

@abeykoon So can you share a reproducible code for this? So in your case the request seems to be hanging right?

abeykoon commented 1 year ago

I used # and did the implementation. BTW - we'll do a catchup after rolling out the implementation on this. Lowering the priority.