From: Brad Fitzpatrick Date: Thu, 23 Jul 2015 01:04:33 +0000 (-0700) Subject: net/http: make Transport return proper error on cancel before response headers X-Git-Tag: go1.5beta3~67 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=9d56c1813e66538cf709d6939440cafa13c275db;p=gostls13.git net/http: make Transport return proper error on cancel before response headers Fixes #11020 Change-Id: I52760a01420a11f3c979f678812b3775a3af61e4 Reviewed-on: https://go-review.googlesource.com/12545 Reviewed-by: Russ Cox --- diff --git a/src/net/http/transport.go b/src/net/http/transport.go index 6f181efc1a..e7ee5c2825 100644 --- a/src/net/http/transport.go +++ b/src/net/http/transport.go @@ -1205,6 +1205,9 @@ WaitResponse: } default: re = responseAndError{err: errClosed} + if pc.isCanceled() { + re = responseAndError{err: errRequestCanceled} + } } break WaitResponse case <-respHeaderTimer: diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go index cae254b4da..0950d2de23 100644 --- a/src/net/http/transport_test.go +++ b/src/net/http/transport_test.go @@ -1552,6 +1552,47 @@ func TestCancelRequestWithChannelBeforeDo(t *testing.T) { } } +// Issue 11020. The returned error message should be errRequestCanceled +func TestTransportCancelBeforeResponseHeaders(t *testing.T) { + defer afterTest(t) + + serverConnCh := make(chan net.Conn, 1) + tr := &Transport{ + Dial: func(network, addr string) (net.Conn, error) { + cc, sc := net.Pipe() + serverConnCh <- sc + return cc, nil + }, + } + defer tr.CloseIdleConnections() + errc := make(chan error, 1) + req, _ := NewRequest("GET", "http://example.com/", nil) + go func() { + _, err := tr.RoundTrip(req) + errc <- err + }() + + sc := <-serverConnCh + verb := make([]byte, 3) + if _, err := io.ReadFull(sc, verb); err != nil { + t.Errorf("Error reading HTTP verb from server: %v", err) + } + if string(verb) != "GET" { + t.Errorf("server received %q; want GET", verb) + } + defer sc.Close() + + tr.CancelRequest(req) + + err := <-errc + if err == nil { + t.Fatalf("unexpected success from RoundTrip") + } + if err != ExportErrRequestCanceled { + t.Errorf("RoundTrip error = %v; want ExportErrRequestCanceled", err) + } +} + // golang.org/issue/3672 -- Client can't close HTTP stream // Calling Close on a Response.Body used to just read until EOF. // Now it actually closes the TCP connection.