1
0
mirror of https://github.com/golang/go synced 2024-10-02 14:38:33 -06:00

net/http: fix panic when status without description for proxied HTTPS responses

Check to ensure that Status is set
when parsing a proxied HTTPS response
that a CONNECT proxy-authorization.

Fixes #21701

Change-Id: Id91700b83425420101e0b0d46e12aaf5d20fd3a3
Reviewed-on: https://go-review.googlesource.com/59990
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: Tom Bergan <tombergan@google.com>
This commit is contained in:
soluchok 2017-08-29 21:35:42 +03:00 committed by Tom Bergan
parent 302f0d1646
commit eb695819a5
2 changed files with 71 additions and 0 deletions

View File

@ -1199,6 +1199,9 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (*persistCon
if resp.StatusCode != 200 { if resp.StatusCode != 200 {
f := strings.SplitN(resp.Status, " ", 2) f := strings.SplitN(resp.Status, " ", 2)
conn.Close() conn.Close()
if len(f) < 2 {
return nil, errors.New("unknown status code")
}
return nil, errors.New(f[1]) return nil, errors.New(f[1])
} }
} }

View File

@ -4269,3 +4269,71 @@ var rgz = []byte{
0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00, 0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
0x00, 0x00, 0x00, 0x00,
} }
// Ensure that a missing status doesn't make the server panic
// See Issue https://golang.org/issues/21701
func TestMissingStatusNoPanic(t *testing.T) {
t.Parallel()
const want = "unknown status code"
ln := newLocalListener(t)
addr := ln.Addr().String()
shutdown := make(chan bool, 1)
done := make(chan bool)
fullAddrURL := fmt.Sprintf("http://%s", addr)
raw := `HTTP/1.1 400
Date: Wed, 30 Aug 2017 19:09:27 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 10
Last-Modified: Wed, 30 Aug 2017 19:02:02 GMT
Vary: Accept-Encoding` + "\r\n\r\nAloha Olaa"
go func() {
defer func() {
ln.Close()
close(done)
}()
conn, _ := ln.Accept()
if conn != nil {
io.WriteString(conn, raw)
ioutil.ReadAll(conn)
conn.Close()
}
}()
proxyURL, err := url.Parse(fullAddrURL)
if err != nil {
t.Fatalf("proxyURL: %v", err)
}
tr := &Transport{Proxy: ProxyURL(proxyURL)}
req, _ := NewRequest("GET", "https://golang.org/", nil)
res, err, panicked := doFetchCheckPanic(tr, req)
if panicked {
t.Error("panicked, expecting an error")
}
if res != nil && res.Body != nil {
io.Copy(ioutil.Discard, res.Body)
res.Body.Close()
}
if err == nil || !strings.Contains(err.Error(), want) {
t.Errorf("got=%v want=%q", err, want)
}
close(shutdown)
<-done
}
func doFetchCheckPanic(tr *Transport, req *Request) (res *Response, err error, panicked bool) {
defer func() {
if r := recover(); r != nil {
panicked = true
}
}()
res, err = tr.RoundTrip(req)
return
}