Open uriklagnes opened 6 years ago
https://github.com/julienschmidt/httprouter/blob/e1b9828bc9e5904baec057a154c09ca40fe7fae0/router.go#L340 uses req.URL.Path
as the path to match against where req.URL
is a url.URL
. According to the documentation of url.URL
:
Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/. A consequence is that it is impossible to tell which slashes in the Path were slashes in the raw URL and which were %2f. This distinction is rarely important, but when it is, code must not use Path directly. The Parse function sets both Path and RawPath in the URL it returns, and URL's String method uses RawPath if it is a valid encoding of Path, by calling the EscapedPath method.
If you need this behaviour, try replacing that line with the following and seeing if that works:
path := req.URL.EscapedPath()
@uriklagnes You might find this interesting if you are using or can use a gorilla/mux Router. There is this setting available for it: UseEncodedPath
UseEncodedPath tells the router to match the encoded original
path to the routes.
For eg. "/path/foo%2Fbar/to" will match the path "/path/{var}/to".
If not called, the router will match the unencoded path to the
routes. For eg. "/path/foo%2Fbar/to" will match the path
"/path/foo/bar/to"
Judging from the description it seems to solve your problem. I'm soon gonna try it out.
@uriklagnes You might find this interesting if you are using or can use a gorilla/mux Router. There is this setting available for it: UseEncodedPath
UseEncodedPath tells the router to match the encoded original path to the routes. For eg. "/path/foo%2Fbar/to" will match the path "/path/{var}/to". If not called, the router will match the unencoded path to the routes. For eg. "/path/foo%2Fbar/to" will match the path "/path/foo/bar/to"
Judging from the description it seems to solve your problem. I'm soon gonna try it out.
I can confirm that the gorilla/mux router solves this problem. It would be nice if httprouter supports this too.
I opened a PR to implement an option to enable this behavior
Hi,
I'm trying to create an API with scheme POST /some/base/url/{{ some other url encoded here }}
Where the last part of the url is extracted by router, but it is itself an url that has been encoded by front end code.
So {{ some other url encoded here }} will be something like http://www.google.ca
(But the front end will encode this as http%3A%2F%2Fwww.google.ca first)
The problem is, when front end does the POST call, it gets a 404. My hunch is that the router must be "seeing" the URL as the real URL and is trying to match on: /some/base/url/http://www.google.ca <-- it is seeing the two // within url.
Is there a way for me to actually confirm this? Because the 404 is coming from the router not my app. Is there a workaround?
Thanks