net/http: fix Transport data race, double cancel panic, cancel error message

Fixes #9496
Fixes #9946
Fixes #10474
Fixes #10405

Change-Id: I4e65f1706e46499811d9ebf4ad6d83a5dfb2ddaa
Reviewed-on: https://go-review.googlesource.com/8550
Reviewed-by: Daniel Morsing <daniel.morsing@gmail.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/src/net/http/npn_test.go b/src/net/http/npn_test.go
index 98b8930..e2e911d 100644
--- a/src/net/http/npn_test.go
+++ b/src/net/http/npn_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bufio"
+	"bytes"
 	"crypto/tls"
 	"fmt"
 	"io"
@@ -17,6 +18,7 @@
 )
 
 func TestNextProtoUpgrade(t *testing.T) {
+	defer afterTest(t)
 	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
 		fmt.Fprintf(w, "path=%s,proto=", r.URL.Path)
 		if r.TLS != nil {
@@ -38,12 +40,12 @@
 	ts.StartTLS()
 	defer ts.Close()
 
-	tr := newTLSTransport(t, ts)
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-
 	// Normal request, without NPN.
 	{
+		tr := newTLSTransport(t, ts)
+		defer tr.CloseIdleConnections()
+		c := &Client{Transport: tr}
+
 		res, err := c.Get(ts.URL)
 		if err != nil {
 			t.Fatal(err)
@@ -60,11 +62,17 @@
 	// Request to an advertised but unhandled NPN protocol.
 	// Server will hang up.
 	{
-		tr.CloseIdleConnections()
+		tr := newTLSTransport(t, ts)
 		tr.TLSClientConfig.NextProtos = []string{"unhandled-proto"}
-		_, err := c.Get(ts.URL)
+		defer tr.CloseIdleConnections()
+		c := &Client{Transport: tr}
+
+		res, err := c.Get(ts.URL)
 		if err == nil {
-			t.Errorf("expected error on unhandled-proto request")
+			defer res.Body.Close()
+			var buf bytes.Buffer
+			res.Write(&buf)
+			t.Errorf("expected error on unhandled-proto request; got: %s", buf.Bytes())
 		}
 	}