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.

  • Your encoded url contains %5C%5C, i.e. two backslashes, where the DN contains one. So the problem appears to be on the encoding side.

    – 




  • That’s a typo (edited it). Thanks for pointing it out. either way it’s not working.

    – 




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=

Leave a Comment