]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: make Transport return proper error on cancel before response headers
authorBrad Fitzpatrick <bradfitz@golang.org>
Thu, 23 Jul 2015 01:04:33 +0000 (18:04 -0700)
committerRuss Cox <rsc@golang.org>
Mon, 27 Jul 2015 16:26:56 +0000 (16:26 +0000)
Fixes #11020

Change-Id: I52760a01420a11f3c979f678812b3775a3af61e4
Reviewed-on: https://go-review.googlesource.com/12545
Reviewed-by: Russ Cox <rsc@golang.org>
src/net/http/transport.go
src/net/http/transport_test.go

index 6f181efc1a128e0a10c10482e506aad29f5b8e2a..e7ee5c2825974b7da02791f0ed247f5008b826db 100644 (file)
@@ -1205,6 +1205,9 @@ WaitResponse:
                                }
                        default:
                                re = responseAndError{err: errClosed}
+                               if pc.isCanceled() {
+                                       re = responseAndError{err: errRequestCanceled}
+                               }
                        }
                        break WaitResponse
                case <-respHeaderTimer:
index cae254b4daf00c1f71a8c27eac2cad47f444a8b4..0950d2de2346d8211b37c0ef540bda72ee792dd2 100644 (file)
@@ -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.