mirror of
https://github.com/golang/go
synced 2024-11-22 20:04:47 -07:00
net/http: Fix basic authentication with empty password
The encoded string must include the : separating the username and the password, even when the latter is empty. See http://www.ietf.org/rfc/rfc2617.txt for more information. R=golang-dev, bradfitz, adg CC=golang-dev https://golang.org/cl/8475043
This commit is contained in:
parent
55c14fde8a
commit
d535bc7af3
@ -161,7 +161,18 @@ func send(req *Request, t RoundTripper) (resp *Response, err error) {
|
||||
}
|
||||
|
||||
if u := req.URL.User; u != nil {
|
||||
req.Header.Set("Authorization", "Basic "+base64.URLEncoding.EncodeToString([]byte(u.String())))
|
||||
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 += ":"
|
||||
}
|
||||
req.Header.Set("Authorization", "Basic "+base64.URLEncoding.EncodeToString([]byte(auth)))
|
||||
}
|
||||
resp, err = t.RoundTrip(req)
|
||||
if err != nil {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -700,3 +701,37 @@ func TestClientHeadContentLength(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyPasswordAuth(t *testing.T) {
|
||||
defer afterTest(t)
|
||||
gopher := "gopher"
|
||||
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||
auth := r.Header.Get("Authorization")
|
||||
if strings.HasPrefix(auth, "Basic ") {
|
||||
encoded := auth[6:]
|
||||
decoded, err := base64.StdEncoding.DecodeString(encoded)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected := gopher + ":"
|
||||
s := string(decoded)
|
||||
if expected != s {
|
||||
t.Errorf("Invalid Authorization header. Got %q, wanted %q", s, expected)
|
||||
}
|
||||
} else {
|
||||
t.Errorf("Invalid auth %q", auth)
|
||||
}
|
||||
}))
|
||||
defer ts.Close()
|
||||
c := &Client{}
|
||||
req, err := NewRequest("GET", ts.URL, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
req.URL.User = url.User(gopher)
|
||||
resp, err := c.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user