-
Notifications
You must be signed in to change notification settings - Fork 18k
net/url: do not URL-escape auth info before base64 encoding #5970
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
Labels
Milestone
Comments
Userinfo.String() urlencodes because that's how it's presented in the URL. It would be unwise to change this. The problem is that net/http/client.go directly uses String(), and Base64encodes it. This is a bug. CL: https://golang.org/cl/12397043/ |
Issue #6066 has been merged into this issue. |
This seems to work but it needs tests, both in net/url and net/http. diff -r 045269edbbee src/pkg/net/http/client.go --- a/src/pkg/net/http/client.go Tue Aug 06 14:49:55 2013 -0400 +++ b/src/pkg/net/http/client.go Wed Aug 07 02:30:08 2013 -0400 @@ -10,7 +10,6 @@ package http import ( - "encoding/base64" "errors" "fmt" "io" @@ -161,18 +160,11 @@ } if u := req.URL.User; u != nil { - auth := u.String() - // UserInfo.String() only returns the colon when the - // password is set, so we must add it here. - // - // See 2 (end of page 4) http://www.ietf.org/rfc/rfc2617.txt - // "To receive authorization, the client sends the userid and password, - // separated by a single colon (":") character, within a base64 - // encoded string in the credentials." - if _, hasPassword := u.Password(); !hasPassword { - auth += ":" + auth, err := u.BasicAuth() + if err != nil { + return nil, err } - req.Header.Set("Authorization", "Basic "+base64.URLEncoding.EncodeToString([]byte(auth))) + req.Header.Set("Authorization", "Basic "+auth) } resp, err = t.RoundTrip(req) if err != nil { diff -r 045269edbbee src/pkg/net/url/url.go --- a/src/pkg/net/url/url.go Tue Aug 06 14:49:55 2013 -0400 +++ b/src/pkg/net/url/url.go Wed Aug 07 02:30:08 2013 -0400 @@ -8,6 +8,7 @@ import ( "bytes" + "encoding/base64" "errors" "sort" "strconv" @@ -277,8 +278,8 @@ return "", false } -// String returns the encoded userinfo information in the standard form -// of "username[:password]". +// String returns the user information in the standard form +// of "username[:password]", with special characters URL-encoded. func (u *Userinfo) String() string { s := escape(u.username, encodeUserPassword) if u.passwordSet { @@ -287,6 +288,17 @@ return s } +var errUsername = errors.New("url: invalid user name") + +// BasicAuth returns the user information in the base64-encoded +// form used by the ``Basic'' authorization header. +func (u *Userinfo) BasicAuth() (string, error) { + if strings.Contains(u.username, ":") { + return "", errUsername + } + return base64.URLEncoding.EncodeToString([]byte(u.username + ":" + u.password)), nil +} + // Maybe rawurl is of the form scheme:path. // (Scheme must be [a-zA-Z][a-zA-Z0-9+-.]*) // If so, return scheme, path; else return "", rawurl. |
There are more problems. Sometimes StdEncoding/Decoding is used, sometimes URLEncoding/Decoding. It should be StdEncoding, according to rfc 2045 (from 2617 [4]). Please comment on my CL, https://golang.org/cl/12397043/ |
This issue was closed by revision a08b1d1. Status changed to Fixed. |
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
The text was updated successfully, but these errors were encountered: