gogo-chi

go-chi: accept url path parameter with backslashes in it


I have a path parameter in the format of a distinguished name, and this contains backslash characters.

CN=CS.Test Company Hello,OU=World,O=Hello,dnQualifier=m1Ws\+nFSkqy1xBrYUTbxGpzLEcg=

I have the path pattern in go-chi server setup like: router.Get("/companies/{companyId}", handlers.GetCompanyByID)

If I make the API call with this path value uri-encoded in postman,

GET https://localhost:8080/v1/companies/CN%3DCS.Test%20Company%20Hello%2COU%3DWorld%2CO%3DHello%2CdnQualifier%3Dm1Ws%5C%2BnFSkqy1xBrYUTbxGpzLEcg%3D

I get 404 Not Found, meaning it's not looking in the right place/calling the expected handler. If I use a uuid in the same path param (or even the same DN String with no backslash), it is calling the handler properly.

I need to have this DN string value inside my handler, Is there a regex pattern that will match the path string or Is there any other solution to handle this?. TIA.


Solution

  • Looks like the route works correctly.

    See this demo:

    package main
    
    import (
        "fmt"
        "net/http"
    
        "github.com/go-chi/chi/v5"
        "github.com/go-chi/chi/v5/middleware"
    )
    
    func main() {
        r := chi.NewRouter()
        r.Use(middleware.Logger)
        r.Use(middleware.Recoverer)
    
        r.Get("/v1/companies/{companyId}", func(w http.ResponseWriter, r *http.Request) {
            companyID := chi.URLParam(r, "companyId")
            fmt.Println("companyId:", companyID)
            _, _ = w.Write([]byte(companyID))
        })
    
        http.ListenAndServe(":8080", r)
    }
    

    Sending request with cURL:

    $ curl -i 'http://localhost:8080/v1/companies/CN%3DCS.Test%20Company%20Hello%2COU%3DWorld%2CO%3DHello%2CdnQualifier%3Dm1Ws%5C%2BnFSkqy1xBrYUTbxGpzLEcg%3D' 
    HTTP/1.1 200 OK
    Date: Thu, 24 Aug 2023 03:44:33 GMT
    Content-Length: 107
    Content-Type: text/plain; charset=utf-8
    
    CN%3DCS.Test%20Company%20Hello%2COU%3DWorld%2CO%3DHello%2CdnQualifier%3Dm1Ws%5C%2BnFSkqy1xBrYUTbxGpzLEcg%3D
    

    BTW, please note that the value is used in a path, not in a query. If you encode the value in JavaScript, you should use encodeURI instead of encodeURIComponent. The snippet below shows the difference:

    console.log(encodeURI('CN=CS.Test Company Hello,OU=World,O=Hello,dnQualifier=m1Ws\\+nFSkqy1xBrYUTbxGpzLEcg='));
    // CN=CS.Test%20Company%20Hello,OU=World,O=Hello,dnQualifier=m1Ws%5C+nFSkqy1xBrYUTbxGpzLEcg=
    
    console.log(encodeURIComponent('CN=CS.Test Company Hello,OU=World,O=Hello,dnQualifier=m1Ws\\+nFSkqy1xBrYUTbxGpzLEcg='));
    // CN%3DCS.Test%20Company%20Hello%2COU%3DWorld%2CO%3DHello%2CdnQualifier%3Dm1Ws%5C%2BnFSkqy1xBrYUTbx

    And use the value returned from encodeURI:

    $ curl -i 'http://localhost:8080/v1/companies/CN=CS.Test%20Company%20Hello,OU=World,O=Hello,dnQualifier=m1Ws%5C+nFSkqy1xBrYUTbxGpzLEcg='
    HTTP/1.1 200 OK
    Date: Thu, 24 Aug 2023 03:54:59 GMT
    Content-Length: 83
    Content-Type: text/plain; charset=utf-8
    
    CN=CS.Test Company Hello,OU=World,O=Hello,dnQualifier=m1Ws\+nFSkqy1xBrYUTbxGpzLEcg=