Open mnovozhylov opened 9 years ago
Hi! Thanks so much for the extremely well researched bug report, and I'm really sorry that it's taken me so long to reply.
This is a tricky one!! Since: it is not clear to me whether its "Right" to consider ";" a separator or not.
Personally, I had never considered semicolon a separator. On the other hand, clearly the Go authors do, and (from your link) the W3C says: "We recommend that HTTP server implementors, and in particular, CGI implementors support the use of ";" in place of "&" to save authors the trouble of escaping "&" characters in this manner." http://www.w3.org/TR/html401/appendix/notes.html#h-B.2.2
Neither choice seems obviously right (or wrong), so we've just got to choose one.
I'm inclined to consider semicolon a separator, primarily because the behavior of url.Query seems like a reasonable precedent to follow for Go programs.
Once we assume that decision, that implies two things:
So, my suggestion is that you change the URL you pass to GET to: https://www.upwork.com/api/profiles/v2/search/jobs.json?paging=1%3B10&q=golang
I hope that this is a reasonable compromise that should allow applications to continue to use semicolon as a separator (by passing ";" raw) or not (by passing %3B).
Please do let me know if this works for you!
@mrjones , unfortunately your suggestion won't work, because by specifying "%3B" in the parameter, means that "%" will be encoded as "%25" and the final url will contain "%253B" - as a result, server side never decodes "%253B" to ";"
i understand that old rfc describes ";" and "&" as delimiters, but it's far from reality nowadays :)
Ah, I think I understand better now. However, I could still be mis-understanding something, if so please let me know.
I just committed change c4fac5ef43dacbdd6dfe0b159fb24b0e33ea5bbb which I hope will help you.
To communicate fully what's happening here, I must point out that as of recently, there are two different ways to make HTTP requests. This all started with 5faa557585ac2fde321eada0a28eb6f1b4176319, when I introduced a second way.
I think the second way is more flexible, and generally "better", but I'd like to keep both ways working. So, there is a function (makeAuthorizedRequestReader) which translates from the old interface to the new one internally.
Correct me if I'm wrong, but I assume that you are using the "old" way (calling Get directly)? People who use the new interface should be able to access to RawQuery directly on the http.Request object, and therefore shouldn't need any special support inside the library.
Assuming I understand correctly: We only need to fix the old interface. Therefore, I applied the exact fix that you recommended (replacing ";" with "%3B" in the RawQuery) in the old-to-new translation method (makeAuthorizedRequestReader).
I hope this will fix your code as it stands. I also believe you could switch to the new http.Client interface, which would enable you to control the escaping yourself by editing RawQuery. You might like other aspects of the new interface as well.
I committed two tests as part of c4fac5ef43dacbdd6dfe0b159fb24b0e33ea5bbb, to demonstrate what I think should happen.
Please do let me know if this fixes your issue!
@mrjones , actually, i use a new method, i.e. MakeHttpClient, and i can move the fix under my hood :) i believed:
p.s. feel free to close the issue in case you don't plan any further updates - thanks!
hey @mrjones ,
first of all, thanks for the nice library! i'm trying to re-use it in upwork/golang-upwork project, and i've found an interesting issue:
jfyi, URL.Query() recognizes ";" and "&" as delimeters (http://stackoverflow.com/questions/3481664/semicolon-as-url-query-separator)
quick fix can look like:
in that case library works as expected
or the library could encode ";" before creating a request (and might decode it before signing a request to have a valid signature created), or smth similar