Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URL encoded parameters not working #77

Closed
philicious opened this issue Nov 3, 2014 · 20 comments
Closed

URL encoded parameters not working #77

philicious opened this issue Nov 3, 2014 · 20 comments

Comments

@philicious
Copy link

if you have sth like
Router.HandleFunc("/bla/{foo}", someHandler)

the "foo" parameter cant be an URL-encoded string like "hmm%2Fstrange"

@vip8439
Copy link

vip8439 commented Dec 2, 2014

I'm having the same issue. Did you figure out a workaround?

@philicious
Copy link
Author

@vip8439 no I didnt. I used a POST request instead and put the URL in the POST data

@vip8439
Copy link

vip8439 commented Dec 2, 2014

@philicious I ended up using query parameters instead. My co-worker found (https://golang.org/pkg/net/url/#URL). See the last part of URL. The issue is probably related to that and not gorilla mux itself. If I get the time I'll look at the gorilla mux source and verify whether it's using that.

@gulyasm
Copy link

gulyasm commented Jan 23, 2015

I believe this is definietly the reason.
https://github.com/gorilla/mux/blob/master/route.go#L466-L483

I don't see any obvious fix, I'll try to look into it tomorrow. For now, moving the parameter after the ? as a GET parameter solves the issue.

@echlebek
Copy link

I think @vip8439 is correct. See http://play.golang.org/p/syfazuTMbV

Also see golang/go#7356.

It seems to me that gorilla is doing the right thing here.

@echlebek
Copy link

Actually, I guess it's not doing the right thing since it ends up responding with 301 instead of 404. So that should probably be fixed.

@gulyasm
Copy link

gulyasm commented May 17, 2015

I will try to fix this next week or the one after that. But I am a little confused what the correct behaviour should be. Returning 404 is obvious, but the URL should be resolved correctly or this is something we can't / shouldn't change? I'm still not convinced by golang/go#7356 that this is the correct way of handling the Path parameters. Ideas? @kisielk ?

@rogierlommers
Copy link

Same problem here; indeed a bug of the net/url package. I tried to implement a workaround: not using urlencoded data, but base64 strings. Unfortunately this does not work for me. I have created an issue for this: #96

@echlebek
Copy link

Are you using base64 encoded strings or base64url encoded strings? You
cannot use base64 as it includes '/' in its charset.

On Monday, May 18, 2015, Rogier Lommers notifications@github.com wrote:

Same problem here; indeed a bug of the net/url package. I tried to
implement a workaround: not using urlencoded data, but base64 strings.
Unfortunately this does not work for me. I have created an issue for this:


Reply to this email directly or view it on GitHub
#77 (comment).

@rogierlommers
Copy link

Well, my source string is var url="https://www.youtube.com/watch?v=TmiK9skef3s". I need a way to pass this string to my Go program as a parameter. r.HandleFunc("/add/{value}". I have tried several ways to encode the string through JavaScript (I need to do this through JavaScript, because it's done through a bookmarklet).

urlEscaped(url): https%3A//www.youtube.com/watch%3Fv%3DTmiK9skef3s

encodeURIComponent(url): https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DTmiK9skef3s

btoa(url): aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1UbWlLOXNrZWYzcw==

Now what is the safest way to encode the string so I can decode it in Golang (and how?)

@garyburd
Copy link

In Javascript, encode the value with encodeURIComponent and pass it as a query parameter.

In the Go code, call req.FormValue("parameterName") to get the decoded value.

Passing encoded values as a path element is tricky because of the design error in the net/url package. It's simpler to use query parameters.

@rogierlommers
Copy link

Thanks; working fine with query parameters, instead of path parameters.

@kisielk kisielk closed this as completed Aug 7, 2015
@derekdowling
Copy link

I'm running Go 1.5.1 which claims to have been the issue here #77 (comment) and I am still seeing this issue.

Example:

    // router build
    router = mux.NewRouter()
    router.HandleFunc("/status", status).Methods("GET")

    apiRouter := mux.NewRouter()
    apiRouter.HandleFunc("/foo", getFooList).Methods("GET")
    apiRouter.HandleFunc("/foo/{bar}", getFoo).Methods("GET")

    router.PathPrefix("/foo").Handler(negroni.New(
        OAuthRequired(config.OAuth),
        negroni.Wrap(apiRouter),
    ))

    url := httptest.NewServer(router).URL
    url1 := strings.Join([]string{url, "/foo/bar%2ftest"}, "")
    // url2 := strings.Join([]string{url, "/foo/bar.test}", "")

    req, err := http.NewRequest("GET", url1, nil)

    client := &http.Client{}
    req, err := client.Do(req)
    fmt.Printf("Req: %+v \n Err: %+v \n", req, err)

If I use url1 I get a 404, if I use url2 I get a 200. Thoughts? I am using Ember-Data to generate API calls so short of performing a huge hack on both ends, I need this to work properly, or alternatively to find a new router.

@highway900
Copy link

Sorry to bring this up again. But this is still a bug. @garyburd can you explain this a little more? "Passing encoded values as a path element is tricky because of the design error in the net/url package. It's simpler to use query parameters."

@garyburd
Copy link

garyburd commented Nov 29, 2017

@highway900 Unescaping a path to a string is a lossy operation.

A specific example is that it's not possible to distinguish a "/" in a path element from a "/" used as a path element separator. A workaround was added in 0a192a1 and updated in c9183aa.

@tulov
Copy link

tulov commented Aug 20, 2019

if you have sth like
Router.HandleFunc("/bla/{foo}", someHandler)

the "foo" parameter cant be an URL-encoded string like "hmm%2Fstrange"

I solved this problem like this:
Router.HandleFunc("/bla/{foo:.+}", someHandler)

This only works if the parameter goes last.

@suibh
Copy link

suibh commented Nov 1, 2019

Can also use

router = mux.NewRouter().UseEncodedPath()

Have to then use url.QueryUnescape in the route

@d681
Copy link

d681 commented Jan 1, 2020

url.QueryUnescape doesn't seem to work either ;(.

@elithrar
Copy link
Contributor

elithrar commented Jan 1, 2020

@d681 - please open a new issue with your example, as "doesn't seem to work" doesn't help us help you :)

@d681
Copy link

d681 commented Jan 1, 2020

Turns out I had an outdated version of Gorilla mux. Updating the package made it work. Thanks and sorry for the bother.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests