PageRenderTime 61ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/third_party/gofrontend/libgo/go/net/http/transport_test.go

http://github.com/axw/llgo
Go | 2810 lines | 2370 code | 258 blank | 182 comment | 710 complexity | aa7b25274556186e13ea52a86c49e028 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Tests for transport.go
  5. package http_test
  6. import (
  7. "bufio"
  8. "bytes"
  9. "compress/gzip"
  10. "crypto/rand"
  11. "crypto/tls"
  12. "errors"
  13. "fmt"
  14. "io"
  15. "io/ioutil"
  16. "log"
  17. "net"
  18. . "net/http"
  19. "net/http/httptest"
  20. "net/url"
  21. "os"
  22. "reflect"
  23. "runtime"
  24. "strconv"
  25. "strings"
  26. "sync"
  27. "testing"
  28. "time"
  29. )
  30. // TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close
  31. // and then verify that the final 2 responses get errors back.
  32. // hostPortHandler writes back the client's "host:port".
  33. var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
  34. if r.FormValue("close") == "true" {
  35. w.Header().Set("Connection", "close")
  36. }
  37. w.Header().Set("X-Saw-Close", fmt.Sprint(r.Close))
  38. w.Write([]byte(r.RemoteAddr))
  39. })
  40. // testCloseConn is a net.Conn tracked by a testConnSet.
  41. type testCloseConn struct {
  42. net.Conn
  43. set *testConnSet
  44. }
  45. func (c *testCloseConn) Close() error {
  46. c.set.remove(c)
  47. return c.Conn.Close()
  48. }
  49. // testConnSet tracks a set of TCP connections and whether they've
  50. // been closed.
  51. type testConnSet struct {
  52. t *testing.T
  53. mu sync.Mutex // guards closed and list
  54. closed map[net.Conn]bool
  55. list []net.Conn // in order created
  56. }
  57. func (tcs *testConnSet) insert(c net.Conn) {
  58. tcs.mu.Lock()
  59. defer tcs.mu.Unlock()
  60. tcs.closed[c] = false
  61. tcs.list = append(tcs.list, c)
  62. }
  63. func (tcs *testConnSet) remove(c net.Conn) {
  64. tcs.mu.Lock()
  65. defer tcs.mu.Unlock()
  66. tcs.closed[c] = true
  67. }
  68. // some tests use this to manage raw tcp connections for later inspection
  69. func makeTestDial(t *testing.T) (*testConnSet, func(n, addr string) (net.Conn, error)) {
  70. connSet := &testConnSet{
  71. t: t,
  72. closed: make(map[net.Conn]bool),
  73. }
  74. dial := func(n, addr string) (net.Conn, error) {
  75. c, err := net.Dial(n, addr)
  76. if err != nil {
  77. return nil, err
  78. }
  79. tc := &testCloseConn{c, connSet}
  80. connSet.insert(tc)
  81. return tc, nil
  82. }
  83. return connSet, dial
  84. }
  85. func (tcs *testConnSet) check(t *testing.T) {
  86. tcs.mu.Lock()
  87. defer tcs.mu.Unlock()
  88. for i := 4; i >= 0; i-- {
  89. for i, c := range tcs.list {
  90. if tcs.closed[c] {
  91. continue
  92. }
  93. if i != 0 {
  94. tcs.mu.Unlock()
  95. time.Sleep(50 * time.Millisecond)
  96. tcs.mu.Lock()
  97. continue
  98. }
  99. t.Errorf("TCP connection #%d, %p (of %d total) was not closed", i+1, c, len(tcs.list))
  100. }
  101. }
  102. }
  103. // Two subsequent requests and verify their response is the same.
  104. // The response from the server is our own IP:port
  105. func TestTransportKeepAlives(t *testing.T) {
  106. defer afterTest(t)
  107. ts := httptest.NewServer(hostPortHandler)
  108. defer ts.Close()
  109. for _, disableKeepAlive := range []bool{false, true} {
  110. tr := &Transport{DisableKeepAlives: disableKeepAlive}
  111. defer tr.CloseIdleConnections()
  112. c := &Client{Transport: tr}
  113. fetch := func(n int) string {
  114. res, err := c.Get(ts.URL)
  115. if err != nil {
  116. t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err)
  117. }
  118. body, err := ioutil.ReadAll(res.Body)
  119. if err != nil {
  120. t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err)
  121. }
  122. return string(body)
  123. }
  124. body1 := fetch(1)
  125. body2 := fetch(2)
  126. bodiesDiffer := body1 != body2
  127. if bodiesDiffer != disableKeepAlive {
  128. t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
  129. disableKeepAlive, bodiesDiffer, body1, body2)
  130. }
  131. }
  132. }
  133. func TestTransportConnectionCloseOnResponse(t *testing.T) {
  134. defer afterTest(t)
  135. ts := httptest.NewServer(hostPortHandler)
  136. defer ts.Close()
  137. connSet, testDial := makeTestDial(t)
  138. for _, connectionClose := range []bool{false, true} {
  139. tr := &Transport{
  140. Dial: testDial,
  141. }
  142. c := &Client{Transport: tr}
  143. fetch := func(n int) string {
  144. req := new(Request)
  145. var err error
  146. req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose))
  147. if err != nil {
  148. t.Fatalf("URL parse error: %v", err)
  149. }
  150. req.Method = "GET"
  151. req.Proto = "HTTP/1.1"
  152. req.ProtoMajor = 1
  153. req.ProtoMinor = 1
  154. res, err := c.Do(req)
  155. if err != nil {
  156. t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
  157. }
  158. defer res.Body.Close()
  159. body, err := ioutil.ReadAll(res.Body)
  160. if err != nil {
  161. t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
  162. }
  163. return string(body)
  164. }
  165. body1 := fetch(1)
  166. body2 := fetch(2)
  167. bodiesDiffer := body1 != body2
  168. if bodiesDiffer != connectionClose {
  169. t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
  170. connectionClose, bodiesDiffer, body1, body2)
  171. }
  172. tr.CloseIdleConnections()
  173. }
  174. connSet.check(t)
  175. }
  176. func TestTransportConnectionCloseOnRequest(t *testing.T) {
  177. defer afterTest(t)
  178. ts := httptest.NewServer(hostPortHandler)
  179. defer ts.Close()
  180. connSet, testDial := makeTestDial(t)
  181. for _, connectionClose := range []bool{false, true} {
  182. tr := &Transport{
  183. Dial: testDial,
  184. }
  185. c := &Client{Transport: tr}
  186. fetch := func(n int) string {
  187. req := new(Request)
  188. var err error
  189. req.URL, err = url.Parse(ts.URL)
  190. if err != nil {
  191. t.Fatalf("URL parse error: %v", err)
  192. }
  193. req.Method = "GET"
  194. req.Proto = "HTTP/1.1"
  195. req.ProtoMajor = 1
  196. req.ProtoMinor = 1
  197. req.Close = connectionClose
  198. res, err := c.Do(req)
  199. if err != nil {
  200. t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
  201. }
  202. if got, want := res.Header.Get("X-Saw-Close"), fmt.Sprint(connectionClose); got != want {
  203. t.Errorf("For connectionClose = %v; handler's X-Saw-Close was %v; want %v",
  204. connectionClose, got, !connectionClose)
  205. }
  206. body, err := ioutil.ReadAll(res.Body)
  207. if err != nil {
  208. t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
  209. }
  210. return string(body)
  211. }
  212. body1 := fetch(1)
  213. body2 := fetch(2)
  214. bodiesDiffer := body1 != body2
  215. if bodiesDiffer != connectionClose {
  216. t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
  217. connectionClose, bodiesDiffer, body1, body2)
  218. }
  219. tr.CloseIdleConnections()
  220. }
  221. connSet.check(t)
  222. }
  223. // if the Transport's DisableKeepAlives is set, all requests should
  224. // send Connection: close.
  225. func TestTransportConnectionCloseOnRequestDisableKeepAlive(t *testing.T) {
  226. defer afterTest(t)
  227. ts := httptest.NewServer(hostPortHandler)
  228. defer ts.Close()
  229. tr := &Transport{
  230. DisableKeepAlives: true,
  231. }
  232. c := &Client{Transport: tr}
  233. res, err := c.Get(ts.URL)
  234. if err != nil {
  235. t.Fatal(err)
  236. }
  237. res.Body.Close()
  238. if res.Header.Get("X-Saw-Close") != "true" {
  239. t.Errorf("handler didn't see Connection: close ")
  240. }
  241. }
  242. func TestTransportIdleCacheKeys(t *testing.T) {
  243. defer afterTest(t)
  244. ts := httptest.NewServer(hostPortHandler)
  245. defer ts.Close()
  246. tr := &Transport{DisableKeepAlives: false}
  247. c := &Client{Transport: tr}
  248. if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
  249. t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
  250. }
  251. resp, err := c.Get(ts.URL)
  252. if err != nil {
  253. t.Error(err)
  254. }
  255. ioutil.ReadAll(resp.Body)
  256. keys := tr.IdleConnKeysForTesting()
  257. if e, g := 1, len(keys); e != g {
  258. t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g)
  259. }
  260. if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e {
  261. t.Errorf("Expected idle cache key %q; got %q", e, keys[0])
  262. }
  263. tr.CloseIdleConnections()
  264. if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
  265. t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
  266. }
  267. }
  268. // Tests that the HTTP transport re-uses connections when a client
  269. // reads to the end of a response Body without closing it.
  270. func TestTransportReadToEndReusesConn(t *testing.T) {
  271. defer afterTest(t)
  272. const msg = "foobar"
  273. var addrSeen map[string]int
  274. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  275. addrSeen[r.RemoteAddr]++
  276. if r.URL.Path == "/chunked/" {
  277. w.WriteHeader(200)
  278. w.(Flusher).Flush()
  279. } else {
  280. w.Header().Set("Content-Type", strconv.Itoa(len(msg)))
  281. w.WriteHeader(200)
  282. }
  283. w.Write([]byte(msg))
  284. }))
  285. defer ts.Close()
  286. buf := make([]byte, len(msg))
  287. for pi, path := range []string{"/content-length/", "/chunked/"} {
  288. wantLen := []int{len(msg), -1}[pi]
  289. addrSeen = make(map[string]int)
  290. for i := 0; i < 3; i++ {
  291. res, err := Get(ts.URL + path)
  292. if err != nil {
  293. t.Errorf("Get %s: %v", path, err)
  294. continue
  295. }
  296. // We want to close this body eventually (before the
  297. // defer afterTest at top runs), but not before the
  298. // len(addrSeen) check at the bottom of this test,
  299. // since Closing this early in the loop would risk
  300. // making connections be re-used for the wrong reason.
  301. defer res.Body.Close()
  302. if res.ContentLength != int64(wantLen) {
  303. t.Errorf("%s res.ContentLength = %d; want %d", path, res.ContentLength, wantLen)
  304. }
  305. n, err := res.Body.Read(buf)
  306. if n != len(msg) || err != io.EOF {
  307. t.Errorf("%s Read = %v, %v; want %d, EOF", path, n, err, len(msg))
  308. }
  309. }
  310. if len(addrSeen) != 1 {
  311. t.Errorf("for %s, server saw %d distinct client addresses; want 1", path, len(addrSeen))
  312. }
  313. }
  314. }
  315. func TestTransportMaxPerHostIdleConns(t *testing.T) {
  316. defer afterTest(t)
  317. resch := make(chan string)
  318. gotReq := make(chan bool)
  319. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  320. gotReq <- true
  321. msg := <-resch
  322. _, err := w.Write([]byte(msg))
  323. if err != nil {
  324. t.Fatalf("Write: %v", err)
  325. }
  326. }))
  327. defer ts.Close()
  328. maxIdleConns := 2
  329. tr := &Transport{DisableKeepAlives: false, MaxIdleConnsPerHost: maxIdleConns}
  330. c := &Client{Transport: tr}
  331. // Start 3 outstanding requests and wait for the server to get them.
  332. // Their responses will hang until we write to resch, though.
  333. donech := make(chan bool)
  334. doReq := func() {
  335. resp, err := c.Get(ts.URL)
  336. if err != nil {
  337. t.Error(err)
  338. return
  339. }
  340. if _, err := ioutil.ReadAll(resp.Body); err != nil {
  341. t.Errorf("ReadAll: %v", err)
  342. return
  343. }
  344. donech <- true
  345. }
  346. go doReq()
  347. <-gotReq
  348. go doReq()
  349. <-gotReq
  350. go doReq()
  351. <-gotReq
  352. if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
  353. t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g)
  354. }
  355. resch <- "res1"
  356. <-donech
  357. keys := tr.IdleConnKeysForTesting()
  358. if e, g := 1, len(keys); e != g {
  359. t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g)
  360. }
  361. cacheKey := "|http|" + ts.Listener.Addr().String()
  362. if keys[0] != cacheKey {
  363. t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0])
  364. }
  365. if e, g := 1, tr.IdleConnCountForTesting(cacheKey); e != g {
  366. t.Errorf("after first response, expected %d idle conns; got %d", e, g)
  367. }
  368. resch <- "res2"
  369. <-donech
  370. if e, g := 2, tr.IdleConnCountForTesting(cacheKey); e != g {
  371. t.Errorf("after second response, expected %d idle conns; got %d", e, g)
  372. }
  373. resch <- "res3"
  374. <-donech
  375. if e, g := maxIdleConns, tr.IdleConnCountForTesting(cacheKey); e != g {
  376. t.Errorf("after third response, still expected %d idle conns; got %d", e, g)
  377. }
  378. }
  379. func TestTransportServerClosingUnexpectedly(t *testing.T) {
  380. defer afterTest(t)
  381. ts := httptest.NewServer(hostPortHandler)
  382. defer ts.Close()
  383. tr := &Transport{}
  384. c := &Client{Transport: tr}
  385. fetch := func(n, retries int) string {
  386. condFatalf := func(format string, arg ...interface{}) {
  387. if retries <= 0 {
  388. t.Fatalf(format, arg...)
  389. }
  390. t.Logf("retrying shortly after expected error: "+format, arg...)
  391. time.Sleep(time.Second / time.Duration(retries))
  392. }
  393. for retries >= 0 {
  394. retries--
  395. res, err := c.Get(ts.URL)
  396. if err != nil {
  397. condFatalf("error in req #%d, GET: %v", n, err)
  398. continue
  399. }
  400. body, err := ioutil.ReadAll(res.Body)
  401. if err != nil {
  402. condFatalf("error in req #%d, ReadAll: %v", n, err)
  403. continue
  404. }
  405. res.Body.Close()
  406. return string(body)
  407. }
  408. panic("unreachable")
  409. }
  410. body1 := fetch(1, 0)
  411. body2 := fetch(2, 0)
  412. ts.CloseClientConnections() // surprise!
  413. // This test has an expected race. Sleeping for 25 ms prevents
  414. // it on most fast machines, causing the next fetch() call to
  415. // succeed quickly. But if we do get errors, fetch() will retry 5
  416. // times with some delays between.
  417. time.Sleep(25 * time.Millisecond)
  418. body3 := fetch(3, 5)
  419. if body1 != body2 {
  420. t.Errorf("expected body1 and body2 to be equal")
  421. }
  422. if body2 == body3 {
  423. t.Errorf("expected body2 and body3 to be different")
  424. }
  425. }
  426. // Test for https://golang.org/issue/2616 (appropriate issue number)
  427. // This fails pretty reliably with GOMAXPROCS=100 or something high.
  428. func TestStressSurpriseServerCloses(t *testing.T) {
  429. defer afterTest(t)
  430. if testing.Short() {
  431. t.Skip("skipping test in short mode")
  432. }
  433. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  434. w.Header().Set("Content-Length", "5")
  435. w.Header().Set("Content-Type", "text/plain")
  436. w.Write([]byte("Hello"))
  437. w.(Flusher).Flush()
  438. conn, buf, _ := w.(Hijacker).Hijack()
  439. buf.Flush()
  440. conn.Close()
  441. }))
  442. defer ts.Close()
  443. tr := &Transport{DisableKeepAlives: false}
  444. c := &Client{Transport: tr}
  445. defer tr.CloseIdleConnections()
  446. // Do a bunch of traffic from different goroutines. Send to activityc
  447. // after each request completes, regardless of whether it failed.
  448. // If these are too high, OS X exhausts its ephemeral ports
  449. // and hangs waiting for them to transition TCP states. That's
  450. // not what we want to test. TODO(bradfitz): use an io.Pipe
  451. // dialer for this test instead?
  452. const (
  453. numClients = 20
  454. reqsPerClient = 25
  455. )
  456. activityc := make(chan bool)
  457. for i := 0; i < numClients; i++ {
  458. go func() {
  459. for i := 0; i < reqsPerClient; i++ {
  460. res, err := c.Get(ts.URL)
  461. if err == nil {
  462. // We expect errors since the server is
  463. // hanging up on us after telling us to
  464. // send more requests, so we don't
  465. // actually care what the error is.
  466. // But we want to close the body in cases
  467. // where we won the race.
  468. res.Body.Close()
  469. }
  470. activityc <- true
  471. }
  472. }()
  473. }
  474. // Make sure all the request come back, one way or another.
  475. for i := 0; i < numClients*reqsPerClient; i++ {
  476. select {
  477. case <-activityc:
  478. case <-time.After(5 * time.Second):
  479. t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile")
  480. }
  481. }
  482. }
  483. // TestTransportHeadResponses verifies that we deal with Content-Lengths
  484. // with no bodies properly
  485. func TestTransportHeadResponses(t *testing.T) {
  486. defer afterTest(t)
  487. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  488. if r.Method != "HEAD" {
  489. panic("expected HEAD; got " + r.Method)
  490. }
  491. w.Header().Set("Content-Length", "123")
  492. w.WriteHeader(200)
  493. }))
  494. defer ts.Close()
  495. tr := &Transport{DisableKeepAlives: false}
  496. c := &Client{Transport: tr}
  497. for i := 0; i < 2; i++ {
  498. res, err := c.Head(ts.URL)
  499. if err != nil {
  500. t.Errorf("error on loop %d: %v", i, err)
  501. continue
  502. }
  503. if e, g := "123", res.Header.Get("Content-Length"); e != g {
  504. t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g)
  505. }
  506. if e, g := int64(123), res.ContentLength; e != g {
  507. t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g)
  508. }
  509. if all, err := ioutil.ReadAll(res.Body); err != nil {
  510. t.Errorf("loop %d: Body ReadAll: %v", i, err)
  511. } else if len(all) != 0 {
  512. t.Errorf("Bogus body %q", all)
  513. }
  514. }
  515. }
  516. // TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding
  517. // on responses to HEAD requests.
  518. func TestTransportHeadChunkedResponse(t *testing.T) {
  519. defer afterTest(t)
  520. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  521. if r.Method != "HEAD" {
  522. panic("expected HEAD; got " + r.Method)
  523. }
  524. w.Header().Set("Transfer-Encoding", "chunked") // client should ignore
  525. w.Header().Set("x-client-ipport", r.RemoteAddr)
  526. w.WriteHeader(200)
  527. }))
  528. defer ts.Close()
  529. tr := &Transport{DisableKeepAlives: false}
  530. c := &Client{Transport: tr}
  531. // Ensure that we wait for the readLoop to complete before
  532. // calling Head again
  533. didRead := make(chan bool)
  534. SetReadLoopBeforeNextReadHook(func() { didRead <- true })
  535. defer SetReadLoopBeforeNextReadHook(nil)
  536. res1, err := c.Head(ts.URL)
  537. <-didRead
  538. if err != nil {
  539. t.Fatalf("request 1 error: %v", err)
  540. }
  541. res2, err := c.Head(ts.URL)
  542. <-didRead
  543. if err != nil {
  544. t.Fatalf("request 2 error: %v", err)
  545. }
  546. if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 {
  547. t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2)
  548. }
  549. }
  550. var roundTripTests = []struct {
  551. accept string
  552. expectAccept string
  553. compressed bool
  554. }{
  555. // Requests with no accept-encoding header use transparent compression
  556. {"", "gzip", false},
  557. // Requests with other accept-encoding should pass through unmodified
  558. {"foo", "foo", false},
  559. // Requests with accept-encoding == gzip should be passed through
  560. {"gzip", "gzip", true},
  561. }
  562. // Test that the modification made to the Request by the RoundTripper is cleaned up
  563. func TestRoundTripGzip(t *testing.T) {
  564. defer afterTest(t)
  565. const responseBody = "test response body"
  566. ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
  567. accept := req.Header.Get("Accept-Encoding")
  568. if expect := req.FormValue("expect_accept"); accept != expect {
  569. t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q",
  570. req.FormValue("testnum"), accept, expect)
  571. }
  572. if accept == "gzip" {
  573. rw.Header().Set("Content-Encoding", "gzip")
  574. gz := gzip.NewWriter(rw)
  575. gz.Write([]byte(responseBody))
  576. gz.Close()
  577. } else {
  578. rw.Header().Set("Content-Encoding", accept)
  579. rw.Write([]byte(responseBody))
  580. }
  581. }))
  582. defer ts.Close()
  583. for i, test := range roundTripTests {
  584. // Test basic request (no accept-encoding)
  585. req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil)
  586. if test.accept != "" {
  587. req.Header.Set("Accept-Encoding", test.accept)
  588. }
  589. res, err := DefaultTransport.RoundTrip(req)
  590. var body []byte
  591. if test.compressed {
  592. var r *gzip.Reader
  593. r, err = gzip.NewReader(res.Body)
  594. if err != nil {
  595. t.Errorf("%d. gzip NewReader: %v", i, err)
  596. continue
  597. }
  598. body, err = ioutil.ReadAll(r)
  599. res.Body.Close()
  600. } else {
  601. body, err = ioutil.ReadAll(res.Body)
  602. }
  603. if err != nil {
  604. t.Errorf("%d. Error: %q", i, err)
  605. continue
  606. }
  607. if g, e := string(body), responseBody; g != e {
  608. t.Errorf("%d. body = %q; want %q", i, g, e)
  609. }
  610. if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e {
  611. t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e)
  612. }
  613. if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e {
  614. t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e)
  615. }
  616. }
  617. }
  618. func TestTransportGzip(t *testing.T) {
  619. defer afterTest(t)
  620. const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  621. const nRandBytes = 1024 * 1024
  622. ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
  623. if req.Method == "HEAD" {
  624. if g := req.Header.Get("Accept-Encoding"); g != "" {
  625. t.Errorf("HEAD request sent with Accept-Encoding of %q; want none", g)
  626. }
  627. return
  628. }
  629. if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e {
  630. t.Errorf("Accept-Encoding = %q, want %q", g, e)
  631. }
  632. rw.Header().Set("Content-Encoding", "gzip")
  633. var w io.Writer = rw
  634. var buf bytes.Buffer
  635. if req.FormValue("chunked") == "0" {
  636. w = &buf
  637. defer io.Copy(rw, &buf)
  638. defer func() {
  639. rw.Header().Set("Content-Length", strconv.Itoa(buf.Len()))
  640. }()
  641. }
  642. gz := gzip.NewWriter(w)
  643. gz.Write([]byte(testString))
  644. if req.FormValue("body") == "large" {
  645. io.CopyN(gz, rand.Reader, nRandBytes)
  646. }
  647. gz.Close()
  648. }))
  649. defer ts.Close()
  650. for _, chunked := range []string{"1", "0"} {
  651. c := &Client{Transport: &Transport{}}
  652. // First fetch something large, but only read some of it.
  653. res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked)
  654. if err != nil {
  655. t.Fatalf("large get: %v", err)
  656. }
  657. buf := make([]byte, len(testString))
  658. n, err := io.ReadFull(res.Body, buf)
  659. if err != nil {
  660. t.Fatalf("partial read of large response: size=%d, %v", n, err)
  661. }
  662. if e, g := testString, string(buf); e != g {
  663. t.Errorf("partial read got %q, expected %q", g, e)
  664. }
  665. res.Body.Close()
  666. // Read on the body, even though it's closed
  667. n, err = res.Body.Read(buf)
  668. if n != 0 || err == nil {
  669. t.Errorf("expected error post-closed large Read; got = %d, %v", n, err)
  670. }
  671. // Then something small.
  672. res, err = c.Get(ts.URL + "/?chunked=" + chunked)
  673. if err != nil {
  674. t.Fatal(err)
  675. }
  676. body, err := ioutil.ReadAll(res.Body)
  677. if err != nil {
  678. t.Fatal(err)
  679. }
  680. if g, e := string(body), testString; g != e {
  681. t.Fatalf("body = %q; want %q", g, e)
  682. }
  683. if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
  684. t.Fatalf("Content-Encoding = %q; want %q", g, e)
  685. }
  686. // Read on the body after it's been fully read:
  687. n, err = res.Body.Read(buf)
  688. if n != 0 || err == nil {
  689. t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err)
  690. }
  691. res.Body.Close()
  692. n, err = res.Body.Read(buf)
  693. if n != 0 || err == nil {
  694. t.Errorf("expected Read error after Close; got %d, %v", n, err)
  695. }
  696. }
  697. // And a HEAD request too, because they're always weird.
  698. c := &Client{Transport: &Transport{}}
  699. res, err := c.Head(ts.URL)
  700. if err != nil {
  701. t.Fatalf("Head: %v", err)
  702. }
  703. if res.StatusCode != 200 {
  704. t.Errorf("Head status=%d; want=200", res.StatusCode)
  705. }
  706. }
  707. func TestTransportProxy(t *testing.T) {
  708. defer afterTest(t)
  709. ch := make(chan string, 1)
  710. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  711. ch <- "real server"
  712. }))
  713. defer ts.Close()
  714. proxy := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  715. ch <- "proxy for " + r.URL.String()
  716. }))
  717. defer proxy.Close()
  718. pu, err := url.Parse(proxy.URL)
  719. if err != nil {
  720. t.Fatal(err)
  721. }
  722. c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}}
  723. c.Head(ts.URL)
  724. got := <-ch
  725. want := "proxy for " + ts.URL + "/"
  726. if got != want {
  727. t.Errorf("want %q, got %q", want, got)
  728. }
  729. }
  730. // TestTransportGzipRecursive sends a gzip quine and checks that the
  731. // client gets the same value back. This is more cute than anything,
  732. // but checks that we don't recurse forever, and checks that
  733. // Content-Encoding is removed.
  734. func TestTransportGzipRecursive(t *testing.T) {
  735. defer afterTest(t)
  736. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  737. w.Header().Set("Content-Encoding", "gzip")
  738. w.Write(rgz)
  739. }))
  740. defer ts.Close()
  741. c := &Client{Transport: &Transport{}}
  742. res, err := c.Get(ts.URL)
  743. if err != nil {
  744. t.Fatal(err)
  745. }
  746. body, err := ioutil.ReadAll(res.Body)
  747. if err != nil {
  748. t.Fatal(err)
  749. }
  750. if !bytes.Equal(body, rgz) {
  751. t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x",
  752. body, rgz)
  753. }
  754. if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
  755. t.Fatalf("Content-Encoding = %q; want %q", g, e)
  756. }
  757. }
  758. // golang.org/issue/7750: request fails when server replies with
  759. // a short gzip body
  760. func TestTransportGzipShort(t *testing.T) {
  761. defer afterTest(t)
  762. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  763. w.Header().Set("Content-Encoding", "gzip")
  764. w.Write([]byte{0x1f, 0x8b})
  765. }))
  766. defer ts.Close()
  767. tr := &Transport{}
  768. defer tr.CloseIdleConnections()
  769. c := &Client{Transport: tr}
  770. res, err := c.Get(ts.URL)
  771. if err != nil {
  772. t.Fatal(err)
  773. }
  774. defer res.Body.Close()
  775. _, err = ioutil.ReadAll(res.Body)
  776. if err == nil {
  777. t.Fatal("Expect an error from reading a body.")
  778. }
  779. if err != io.ErrUnexpectedEOF {
  780. t.Errorf("ReadAll error = %v; want io.ErrUnexpectedEOF", err)
  781. }
  782. }
  783. // tests that persistent goroutine connections shut down when no longer desired.
  784. func TestTransportPersistConnLeak(t *testing.T) {
  785. if runtime.GOOS == "plan9" {
  786. t.Skip("skipping test; see https://golang.org/issue/7237")
  787. }
  788. defer afterTest(t)
  789. gotReqCh := make(chan bool)
  790. unblockCh := make(chan bool)
  791. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  792. gotReqCh <- true
  793. <-unblockCh
  794. w.Header().Set("Content-Length", "0")
  795. w.WriteHeader(204)
  796. }))
  797. defer ts.Close()
  798. tr := &Transport{}
  799. c := &Client{Transport: tr}
  800. n0 := runtime.NumGoroutine()
  801. const numReq = 25
  802. didReqCh := make(chan bool)
  803. for i := 0; i < numReq; i++ {
  804. go func() {
  805. res, err := c.Get(ts.URL)
  806. didReqCh <- true
  807. if err != nil {
  808. t.Errorf("client fetch error: %v", err)
  809. return
  810. }
  811. res.Body.Close()
  812. }()
  813. }
  814. // Wait for all goroutines to be stuck in the Handler.
  815. for i := 0; i < numReq; i++ {
  816. <-gotReqCh
  817. }
  818. nhigh := runtime.NumGoroutine()
  819. // Tell all handlers to unblock and reply.
  820. for i := 0; i < numReq; i++ {
  821. unblockCh <- true
  822. }
  823. // Wait for all HTTP clients to be done.
  824. for i := 0; i < numReq; i++ {
  825. <-didReqCh
  826. }
  827. tr.CloseIdleConnections()
  828. time.Sleep(100 * time.Millisecond)
  829. runtime.GC()
  830. runtime.GC() // even more.
  831. nfinal := runtime.NumGoroutine()
  832. growth := nfinal - n0
  833. // We expect 0 or 1 extra goroutine, empirically. Allow up to 5.
  834. // Previously we were leaking one per numReq.
  835. if int(growth) > 5 {
  836. t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
  837. t.Error("too many new goroutines")
  838. }
  839. }
  840. // golang.org/issue/4531: Transport leaks goroutines when
  841. // request.ContentLength is explicitly short
  842. func TestTransportPersistConnLeakShortBody(t *testing.T) {
  843. if runtime.GOOS == "plan9" {
  844. t.Skip("skipping test; see https://golang.org/issue/7237")
  845. }
  846. defer afterTest(t)
  847. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  848. }))
  849. defer ts.Close()
  850. tr := &Transport{}
  851. c := &Client{Transport: tr}
  852. n0 := runtime.NumGoroutine()
  853. body := []byte("Hello")
  854. for i := 0; i < 20; i++ {
  855. req, err := NewRequest("POST", ts.URL, bytes.NewReader(body))
  856. if err != nil {
  857. t.Fatal(err)
  858. }
  859. req.ContentLength = int64(len(body) - 2) // explicitly short
  860. _, err = c.Do(req)
  861. if err == nil {
  862. t.Fatal("Expect an error from writing too long of a body.")
  863. }
  864. }
  865. nhigh := runtime.NumGoroutine()
  866. tr.CloseIdleConnections()
  867. time.Sleep(400 * time.Millisecond)
  868. runtime.GC()
  869. nfinal := runtime.NumGoroutine()
  870. growth := nfinal - n0
  871. // We expect 0 or 1 extra goroutine, empirically. Allow up to 5.
  872. // Previously we were leaking one per numReq.
  873. t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
  874. if int(growth) > 5 {
  875. t.Error("too many new goroutines")
  876. }
  877. }
  878. // This used to crash; https://golang.org/issue/3266
  879. func TestTransportIdleConnCrash(t *testing.T) {
  880. defer afterTest(t)
  881. tr := &Transport{}
  882. c := &Client{Transport: tr}
  883. unblockCh := make(chan bool, 1)
  884. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  885. <-unblockCh
  886. tr.CloseIdleConnections()
  887. }))
  888. defer ts.Close()
  889. didreq := make(chan bool)
  890. go func() {
  891. res, err := c.Get(ts.URL)
  892. if err != nil {
  893. t.Error(err)
  894. } else {
  895. res.Body.Close() // returns idle conn
  896. }
  897. didreq <- true
  898. }()
  899. unblockCh <- true
  900. <-didreq
  901. }
  902. // Test that the transport doesn't close the TCP connection early,
  903. // before the response body has been read. This was a regression
  904. // which sadly lacked a triggering test. The large response body made
  905. // the old race easier to trigger.
  906. func TestIssue3644(t *testing.T) {
  907. defer afterTest(t)
  908. const numFoos = 5000
  909. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  910. w.Header().Set("Connection", "close")
  911. for i := 0; i < numFoos; i++ {
  912. w.Write([]byte("foo "))
  913. }
  914. }))
  915. defer ts.Close()
  916. tr := &Transport{}
  917. c := &Client{Transport: tr}
  918. res, err := c.Get(ts.URL)
  919. if err != nil {
  920. t.Fatal(err)
  921. }
  922. defer res.Body.Close()
  923. bs, err := ioutil.ReadAll(res.Body)
  924. if err != nil {
  925. t.Fatal(err)
  926. }
  927. if len(bs) != numFoos*len("foo ") {
  928. t.Errorf("unexpected response length")
  929. }
  930. }
  931. // Test that a client receives a server's reply, even if the server doesn't read
  932. // the entire request body.
  933. func TestIssue3595(t *testing.T) {
  934. defer afterTest(t)
  935. const deniedMsg = "sorry, denied."
  936. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  937. Error(w, deniedMsg, StatusUnauthorized)
  938. }))
  939. defer ts.Close()
  940. tr := &Transport{}
  941. c := &Client{Transport: tr}
  942. res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a'))
  943. if err != nil {
  944. t.Errorf("Post: %v", err)
  945. return
  946. }
  947. got, err := ioutil.ReadAll(res.Body)
  948. if err != nil {
  949. t.Fatalf("Body ReadAll: %v", err)
  950. }
  951. if !strings.Contains(string(got), deniedMsg) {
  952. t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg)
  953. }
  954. }
  955. // From https://golang.org/issue/4454 ,
  956. // "client fails to handle requests with no body and chunked encoding"
  957. func TestChunkedNoContent(t *testing.T) {
  958. defer afterTest(t)
  959. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  960. w.WriteHeader(StatusNoContent)
  961. }))
  962. defer ts.Close()
  963. for _, closeBody := range []bool{true, false} {
  964. c := &Client{Transport: &Transport{}}
  965. const n = 4
  966. for i := 1; i <= n; i++ {
  967. res, err := c.Get(ts.URL)
  968. if err != nil {
  969. t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err)
  970. } else {
  971. if closeBody {
  972. res.Body.Close()
  973. }
  974. }
  975. }
  976. }
  977. }
  978. func TestTransportConcurrency(t *testing.T) {
  979. defer afterTest(t)
  980. maxProcs, numReqs := 16, 500
  981. if testing.Short() {
  982. maxProcs, numReqs = 4, 50
  983. }
  984. defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
  985. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  986. fmt.Fprintf(w, "%v", r.FormValue("echo"))
  987. }))
  988. defer ts.Close()
  989. var wg sync.WaitGroup
  990. wg.Add(numReqs)
  991. // Due to the Transport's "socket late binding" (see
  992. // idleConnCh in transport.go), the numReqs HTTP requests
  993. // below can finish with a dial still outstanding. To keep
  994. // the leak checker happy, keep track of pending dials and
  995. // wait for them to finish (and be closed or returned to the
  996. // idle pool) before we close idle connections.
  997. SetPendingDialHooks(func() { wg.Add(1) }, wg.Done)
  998. defer SetPendingDialHooks(nil, nil)
  999. tr := &Transport{}
  1000. defer tr.CloseIdleConnections()
  1001. c := &Client{Transport: tr}
  1002. reqs := make(chan string)
  1003. defer close(reqs)
  1004. for i := 0; i < maxProcs*2; i++ {
  1005. go func() {
  1006. for req := range reqs {
  1007. res, err := c.Get(ts.URL + "/?echo=" + req)
  1008. if err != nil {
  1009. t.Errorf("error on req %s: %v", req, err)
  1010. wg.Done()
  1011. continue
  1012. }
  1013. all, err := ioutil.ReadAll(res.Body)
  1014. if err != nil {
  1015. t.Errorf("read error on req %s: %v", req, err)
  1016. wg.Done()
  1017. continue
  1018. }
  1019. if string(all) != req {
  1020. t.Errorf("body of req %s = %q; want %q", req, all, req)
  1021. }
  1022. res.Body.Close()
  1023. wg.Done()
  1024. }
  1025. }()
  1026. }
  1027. for i := 0; i < numReqs; i++ {
  1028. reqs <- fmt.Sprintf("request-%d", i)
  1029. }
  1030. wg.Wait()
  1031. }
  1032. func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
  1033. if runtime.GOOS == "plan9" {
  1034. t.Skip("skipping test; see https://golang.org/issue/7237")
  1035. }
  1036. defer afterTest(t)
  1037. const debug = false
  1038. mux := NewServeMux()
  1039. mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  1040. io.Copy(w, neverEnding('a'))
  1041. })
  1042. ts := httptest.NewServer(mux)
  1043. timeout := 100 * time.Millisecond
  1044. client := &Client{
  1045. Transport: &Transport{
  1046. Dial: func(n, addr string) (net.Conn, error) {
  1047. conn, err := net.Dial(n, addr)
  1048. if err != nil {
  1049. return nil, err
  1050. }
  1051. conn.SetDeadline(time.Now().Add(timeout))
  1052. if debug {
  1053. conn = NewLoggingConn("client", conn)
  1054. }
  1055. return conn, nil
  1056. },
  1057. DisableKeepAlives: true,
  1058. },
  1059. }
  1060. getFailed := false
  1061. nRuns := 5
  1062. if testing.Short() {
  1063. nRuns = 1
  1064. }
  1065. for i := 0; i < nRuns; i++ {
  1066. if debug {
  1067. println("run", i+1, "of", nRuns)
  1068. }
  1069. sres, err := client.Get(ts.URL + "/get")
  1070. if err != nil {
  1071. if !getFailed {
  1072. // Make the timeout longer, once.
  1073. getFailed = true
  1074. t.Logf("increasing timeout")
  1075. i--
  1076. timeout *= 10
  1077. continue
  1078. }
  1079. t.Errorf("Error issuing GET: %v", err)
  1080. break
  1081. }
  1082. _, err = io.Copy(ioutil.Discard, sres.Body)
  1083. if err == nil {
  1084. t.Errorf("Unexpected successful copy")
  1085. break
  1086. }
  1087. }
  1088. if debug {
  1089. println("tests complete; waiting for handlers to finish")
  1090. }
  1091. ts.Close()
  1092. }
  1093. func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
  1094. if runtime.GOOS == "plan9" {
  1095. t.Skip("skipping test; see https://golang.org/issue/7237")
  1096. }
  1097. defer afterTest(t)
  1098. const debug = false
  1099. mux := NewServeMux()
  1100. mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  1101. io.Copy(w, neverEnding('a'))
  1102. })
  1103. mux.HandleFunc("/put", func(w ResponseWriter, r *Request) {
  1104. defer r.Body.Close()
  1105. io.Copy(ioutil.Discard, r.Body)
  1106. })
  1107. ts := httptest.NewServer(mux)
  1108. timeout := 100 * time.Millisecond
  1109. client := &Client{
  1110. Transport: &Transport{
  1111. Dial: func(n, addr string) (net.Conn, error) {
  1112. conn, err := net.Dial(n, addr)
  1113. if err != nil {
  1114. return nil, err
  1115. }
  1116. conn.SetDeadline(time.Now().Add(timeout))
  1117. if debug {
  1118. conn = NewLoggingConn("client", conn)
  1119. }
  1120. return conn, nil
  1121. },
  1122. DisableKeepAlives: true,
  1123. },
  1124. }
  1125. getFailed := false
  1126. nRuns := 5
  1127. if testing.Short() {
  1128. nRuns = 1
  1129. }
  1130. for i := 0; i < nRuns; i++ {
  1131. if debug {
  1132. println("run", i+1, "of", nRuns)
  1133. }
  1134. sres, err := client.Get(ts.URL + "/get")
  1135. if err != nil {
  1136. if !getFailed {
  1137. // Make the timeout longer, once.
  1138. getFailed = true
  1139. t.Logf("increasing timeout")
  1140. i--
  1141. timeout *= 10
  1142. continue
  1143. }
  1144. t.Errorf("Error issuing GET: %v", err)
  1145. break
  1146. }
  1147. req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body)
  1148. _, err = client.Do(req)
  1149. if err == nil {
  1150. sres.Body.Close()
  1151. t.Errorf("Unexpected successful PUT")
  1152. break
  1153. }
  1154. sres.Body.Close()
  1155. }
  1156. if debug {
  1157. println("tests complete; waiting for handlers to finish")
  1158. }
  1159. ts.Close()
  1160. }
  1161. func TestTransportResponseHeaderTimeout(t *testing.T) {
  1162. defer afterTest(t)
  1163. if testing.Short() {
  1164. t.Skip("skipping timeout test in -short mode")
  1165. }
  1166. inHandler := make(chan bool, 1)
  1167. mux := NewServeMux()
  1168. mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) {
  1169. inHandler <- true
  1170. })
  1171. mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) {
  1172. inHandler <- true
  1173. time.Sleep(2 * time.Second)
  1174. })
  1175. ts := httptest.NewServer(mux)
  1176. defer ts.Close()
  1177. tr := &Transport{
  1178. ResponseHeaderTimeout: 500 * time.Millisecond,
  1179. }
  1180. defer tr.CloseIdleConnections()
  1181. c := &Client{Transport: tr}
  1182. tests := []struct {
  1183. path string
  1184. want int
  1185. wantErr string
  1186. }{
  1187. {path: "/fast", want: 200},
  1188. {path: "/slow", wantErr: "timeout awaiting response headers"},
  1189. {path: "/fast", want: 200},
  1190. }
  1191. for i, tt := range tests {
  1192. res, err := c.Get(ts.URL + tt.path)
  1193. select {
  1194. case <-inHandler:
  1195. case <-time.After(5 * time.Second):
  1196. t.Errorf("never entered handler for test index %d, %s", i, tt.path)
  1197. continue
  1198. }
  1199. if err != nil {
  1200. uerr, ok := err.(*url.Error)
  1201. if !ok {
  1202. t.Errorf("error is not an url.Error; got: %#v", err)
  1203. continue
  1204. }
  1205. nerr, ok := uerr.Err.(net.Error)
  1206. if !ok {
  1207. t.Errorf("error does not satisfy net.Error interface; got: %#v", err)
  1208. continue
  1209. }
  1210. if !nerr.Timeout() {
  1211. t.Errorf("want timeout error; got: %q", nerr)
  1212. continue
  1213. }
  1214. if strings.Contains(err.Error(), tt.wantErr) {
  1215. continue
  1216. }
  1217. t.Errorf("%d. unexpected error: %v", i, err)
  1218. continue
  1219. }
  1220. if tt.wantErr != "" {
  1221. t.Errorf("%d. no error. expected error: %v", i, tt.wantErr)
  1222. continue
  1223. }
  1224. if res.StatusCode != tt.want {
  1225. t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want)
  1226. }
  1227. }
  1228. }
  1229. func TestTransportCancelRequest(t *testing.T) {
  1230. defer afterTest(t)
  1231. if testing.Short() {
  1232. t.Skip("skipping test in -short mode")
  1233. }
  1234. unblockc := make(chan bool)
  1235. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1236. fmt.Fprintf(w, "Hello")
  1237. w.(Flusher).Flush() // send headers and some body
  1238. <-unblockc
  1239. }))
  1240. defer ts.Close()
  1241. defer close(unblockc)
  1242. tr := &Transport{}
  1243. defer tr.CloseIdleConnections()
  1244. c := &Client{Transport: tr}
  1245. req, _ := NewRequest("GET", ts.URL, nil)
  1246. res, err := c.Do(req)
  1247. if err != nil {
  1248. t.Fatal(err)
  1249. }
  1250. go func() {
  1251. time.Sleep(1 * time.Second)
  1252. tr.CancelRequest(req)
  1253. }()
  1254. t0 := time.Now()
  1255. body, err := ioutil.ReadAll(res.Body)
  1256. d := time.Since(t0)
  1257. if err != ExportErrRequestCanceled {
  1258. t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  1259. }
  1260. if string(body) != "Hello" {
  1261. t.Errorf("Body = %q; want Hello", body)
  1262. }
  1263. if d < 500*time.Millisecond {
  1264. t.Errorf("expected ~1 second delay; got %v", d)
  1265. }
  1266. // Verify no outstanding requests after readLoop/writeLoop
  1267. // goroutines shut down.
  1268. for tries := 5; tries > 0; tries-- {
  1269. n := tr.NumPendingRequestsForTesting()
  1270. if n == 0 {
  1271. break
  1272. }
  1273. time.Sleep(100 * time.Millisecond)
  1274. if tries == 1 {
  1275. t.Errorf("pending requests = %d; want 0", n)
  1276. }
  1277. }
  1278. }
  1279. func TestTransportCancelRequestInDial(t *testing.T) {
  1280. defer afterTest(t)
  1281. if testing.Short() {
  1282. t.Skip("skipping test in -short mode")
  1283. }
  1284. var logbuf bytes.Buffer
  1285. eventLog := log.New(&logbuf, "", 0)
  1286. unblockDial := make(chan bool)
  1287. defer close(unblockDial)
  1288. inDial := make(chan bool)
  1289. tr := &Transport{
  1290. Dial: func(network, addr string) (net.Conn, error) {
  1291. eventLog.Println("dial: blocking")
  1292. inDial <- true
  1293. <-unblockDial
  1294. return nil, errors.New("nope")
  1295. },
  1296. }
  1297. cl := &Client{Transport: tr}
  1298. gotres := make(chan bool)
  1299. req, _ := NewRequest("GET", "http://something.no-network.tld/", nil)
  1300. go func() {
  1301. _, err := cl.Do(req)
  1302. eventLog.Printf("Get = %v", err)
  1303. gotres <- true
  1304. }()
  1305. select {
  1306. case <-inDial:
  1307. case <-time.After(5 * time.Second):
  1308. t.Fatal("timeout; never saw blocking dial")
  1309. }
  1310. eventLog.Printf("canceling")
  1311. tr.CancelRequest(req)
  1312. tr.CancelRequest(req) // used to panic on second call
  1313. select {
  1314. case <-gotres:
  1315. case <-time.After(5 * time.Second):
  1316. panic("hang. events are: " + logbuf.String())
  1317. }
  1318. got := logbuf.String()
  1319. want := `dial: blocking
  1320. canceling
  1321. Get = Get http://something.no-network.tld/: net/http: request canceled while waiting for connection
  1322. `
  1323. if got != want {
  1324. t.Errorf("Got events:\n%s\nWant:\n%s", got, want)
  1325. }
  1326. }
  1327. func TestCancelRequestWithChannel(t *testing.T) {
  1328. defer afterTest(t)
  1329. if testing.Short() {
  1330. t.Skip("skipping test in -short mode")
  1331. }
  1332. unblockc := make(chan bool)
  1333. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1334. fmt.Fprintf(w, "Hello")
  1335. w.(Flusher).Flush() // send headers and some body
  1336. <-unblockc
  1337. }))
  1338. defer ts.Close()
  1339. defer close(unblockc)
  1340. tr := &Transport{}
  1341. defer tr.CloseIdleConnections()
  1342. c := &Client{Transport: tr}
  1343. req, _ := NewRequest("GET", ts.URL, nil)
  1344. ch := make(chan struct{})
  1345. req.Cancel = ch
  1346. res, err := c.Do(req)
  1347. if err != nil {
  1348. t.Fatal(err)
  1349. }
  1350. go func() {
  1351. time.Sleep(1 * time.Second)
  1352. close(ch)
  1353. }()
  1354. t0 := time.Now()
  1355. body, err := ioutil.ReadAll(res.Body)
  1356. d := time.Since(t0)
  1357. if err != ExportErrRequestCanceled {
  1358. t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  1359. }
  1360. if string(body) != "Hello" {
  1361. t.Errorf("Body = %q; want Hello", body)
  1362. }
  1363. if d < 500*time.Millisecond {
  1364. t.Errorf("expected ~1 second delay; got %v", d)
  1365. }
  1366. // Verify no outstanding requests after readLoop/writeLoop
  1367. // goroutines shut down.
  1368. for tries := 5; tries > 0; tries-- {
  1369. n := tr.NumPendingRequestsForTesting()
  1370. if n == 0 {
  1371. break
  1372. }
  1373. time.Sleep(100 * time.Millisecond)
  1374. if tries == 1 {
  1375. t.Errorf("pending requests = %d; want 0", n)
  1376. }
  1377. }
  1378. }
  1379. func TestCancelRequestWithChannelBeforeDo(t *testing.T) {
  1380. defer afterTest(t)
  1381. unblockc := make(chan bool)
  1382. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1383. <-unblockc
  1384. }))
  1385. defer ts.Close()
  1386. defer close(unblockc)
  1387. // Don't interfere with the next test on plan9.
  1388. // Cf. https://golang.org/issues/11476
  1389. if runtime.GOOS == "plan9" {
  1390. defer time.Sleep(500 * time.Millisecond)
  1391. }
  1392. tr := &Transport{}
  1393. defer tr.CloseIdleConnections()
  1394. c := &Client{Transport: tr}
  1395. req, _ := NewRequest("GET", ts.URL, nil)
  1396. ch := make(chan struct{})
  1397. req.Cancel = ch
  1398. close(ch)
  1399. _, err := c.Do(req)
  1400. if err == nil || !strings.Contains(err.Error(), "canceled") {
  1401. t.Errorf("Do error = %v; want cancelation", err)
  1402. }
  1403. }
  1404. // Issue 11020. The returned error message should be errRequestCanceled
  1405. func TestTransportCancelBeforeResponseHeaders(t *testing.T) {
  1406. t.Skip("Skipping flaky test; see Issue 11894")
  1407. defer afterTest(t)
  1408. serverConnCh := make(chan net.Conn, 1)
  1409. tr := &Transport{
  1410. Dial: func(network, addr string) (net.Conn, error) {
  1411. cc, sc := net.Pipe()
  1412. serverConnCh <- sc
  1413. return cc, nil
  1414. },
  1415. }
  1416. defer tr.CloseIdleConnections()
  1417. errc := make(chan error, 1)
  1418. req, _ := NewRequest("GET", "http://example.com/", nil)
  1419. go func() {
  1420. _, err := tr.RoundTrip(req)
  1421. errc <- err
  1422. }()
  1423. sc := <-serverConnCh
  1424. verb := make([]byte, 3)
  1425. if _, err := io.ReadFull(sc, verb); err != nil {
  1426. t.Errorf("Error reading HTTP verb from server: %v", err)
  1427. }
  1428. if string(verb) != "GET" {
  1429. t.Errorf("server received %q; want GET", verb)
  1430. }
  1431. defer sc.Close()
  1432. tr.CancelRequest(req)
  1433. err := <-errc
  1434. if err == nil {
  1435. t.Fatalf("unexpected success from RoundTrip")
  1436. }
  1437. if err != ExportErrRequestCanceled {
  1438. t.Errorf("RoundTrip error = %v; want ExportErrRequestCanceled", err)
  1439. }
  1440. }
  1441. // golang.org/issue/3672 -- Client can't close HTTP stream
  1442. // Calling Close on a Response.Body used to just read until EOF.
  1443. // Now it actually closes the TCP connection.
  1444. func TestTransportCloseResponseBody(t *testing.T) {
  1445. defer afterTest(t)
  1446. writeErr := make(chan error, 1)
  1447. msg := []byte("young\n")
  1448. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1449. for {
  1450. _, err := w.Write(msg)
  1451. if err != nil {
  1452. writeErr <- err
  1453. return
  1454. }
  1455. w.(Flusher).Flush()
  1456. }
  1457. }))
  1458. defer ts.Close()
  1459. tr := &Transport{}
  1460. defer tr.CloseIdleConnections()
  1461. c := &Client{Transport: tr}
  1462. req, _ := NewRequest("GET", ts.URL, nil)
  1463. defer tr.CancelRequest(req)
  1464. res, err := c.Do(req)
  1465. if err != nil {
  1466. t.Fatal(err)
  1467. }
  1468. const repeats = 3
  1469. buf := make([]byte, len(msg)*repeats)
  1470. want := bytes.Repeat(msg, repeats)
  1471. _, err = io.ReadFull(res.Body, buf)
  1472. if err != nil {
  1473. t.Fatal(err)
  1474. }
  1475. if !bytes.Equal(buf, want) {
  1476. t.Fatalf("read %q; want %q", buf, want)
  1477. }
  1478. didClose := make(chan error, 1)
  1479. go func() {
  1480. didClose <- res.Body.Close()
  1481. }()
  1482. select {
  1483. case err := <-didClose:
  1484. if err != nil {
  1485. t.Errorf("Close = %v", err)
  1486. }
  1487. case <-time.After(10 * time.Second):
  1488. t.Fatal("too long waiting for close")
  1489. }
  1490. select {
  1491. case err := <-writeErr:
  1492. if err == nil {
  1493. t.Errorf("expected non-nil write error")
  1494. }
  1495. case <-time.After(10 * time.Second):
  1496. t.Fatal("too long waiting for write error")
  1497. }
  1498. }
  1499. type fooProto struct{}
  1500. func (fooProto) RoundTrip(req *Request) (*Response, error) {
  1501. res := &Response{
  1502. Status: "200 OK",
  1503. StatusCode: 200,
  1504. Header: make(Header),
  1505. Body: ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())),
  1506. }
  1507. return res, nil
  1508. }
  1509. func TestTransportAltProto(t *testing.T) {
  1510. defer afterTest(t)
  1511. tr := &Transport{}
  1512. c := &Client{Transport: tr}
  1513. tr.RegisterProtocol("foo", fooProto{})
  1514. res, err := c.Get("foo://bar.com/path")
  1515. if err != nil {
  1516. t.Fatal(err)
  1517. }
  1518. bodyb, err := ioutil.ReadAll(res.Body)
  1519. if err != nil {
  1520. t.Fatal(err)
  1521. }
  1522. body := string(bodyb)
  1523. if e := "You wanted foo://bar.com/path"; body != e {
  1524. t.Errorf("got response %q, want %q", body, e)
  1525. }
  1526. }
  1527. func TestTransportNoHost(t *testing.T) {
  1528. defer afterTest(t)
  1529. tr := &Transport{}
  1530. _, err := tr.RoundTrip(&Request{
  1531. Header: make(Header),
  1532. URL: &url.URL{
  1533. Scheme: "http",
  1534. },
  1535. })
  1536. want := "http: no Host in request URL"
  1537. if got := fmt.Sprint(err); got != want {
  1538. t.Errorf("error = %v; want %q", err, want)
  1539. }
  1540. }
  1541. func TestTransportSocketLateBinding(t *testing.T) {
  1542. defer afterTest(t)
  1543. mux := NewServeMux()
  1544. fooGate := make(chan bool, 1)
  1545. mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) {
  1546. w.Header().Set("foo-ipport", r.RemoteAddr)
  1547. w.(Flusher).Flush()
  1548. <-fooGate
  1549. })
  1550. mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) {
  1551. w.Header().Set("bar-ipport", r.RemoteAddr)
  1552. })
  1553. ts := httptest.NewServer(mux)
  1554. defer ts.Close()
  1555. dialGate := make(chan bool, 1)
  1556. tr := &Transport{
  1557. Dial: func(n, addr string) (net.Conn, error) {
  1558. if <-dialGate {
  1559. return net.Dial(n, addr)
  1560. }
  1561. return nil, errors.New("manually closed")
  1562. },
  1563. DisableKeepAlives: false,
  1564. }
  1565. defer tr.CloseIdleConnections()
  1566. c := &Client{
  1567. Transport: tr,
  1568. }
  1569. dialGate <- true // only allow one dial
  1570. fooRes, err := c.Get(ts.URL + "/foo")
  1571. if err != nil {
  1572. t.Fatal(err)
  1573. }
  1574. fooAddr := fooRes.Header.Get("foo-ipport")
  1575. if fooAddr == "" {
  1576. t.Fatal("No addr on /foo request")
  1577. }
  1578. time.AfterFunc(200*time.Millisecond, func() {
  1579. // let the foo response finish so we can use its
  1580. // connection for /bar
  1581. fooGate <- true
  1582. io.Copy(ioutil.Discard, fooRes.Body)
  1583. fooRes.Body.Close()
  1584. })
  1585. barRes, err := c.Get(ts.URL + "/bar")
  1586. if err != nil {
  1587. t.Fatal(err)
  1588. }
  1589. barAddr := barRes.Header.Get("bar-ipport")
  1590. if barAddr != fooAddr {
  1591. t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr)
  1592. }
  1593. barRes.Body.Close()
  1594. dialGate <- false
  1595. }
  1596. // Issue 2184
  1597. func TestTransportReading100Continue(t *testing.T) {
  1598. defer afterTest(t)
  1599. const numReqs = 5
  1600. reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) }
  1601. reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) }
  1602. send100Response := func(w *io.PipeWriter, r *io.PipeReader) {
  1603. defer w.Close()
  1604. defer r.Close()
  1605. br := bufio.NewReader(r)
  1606. n := 0
  1607. for {
  1608. n++
  1609. req, err := ReadRequest(br)
  1610. if err == io.EOF {
  1611. return
  1612. }
  1613. if err != nil {
  1614. t.Error(err)
  1615. return
  1616. }
  1617. slurp, err := ioutil.ReadAll(req.Body)
  1618. if err != nil {
  1619. t.Errorf("Server request body slurp: %v", err)
  1620. return
  1621. }
  1622. id := req.Header.Get("Request-Id")
  1623. resCode := req.Header.Get("X-Want-Response-Code")
  1624. if resCode == "" {
  1625. resCode = "100 Continue"
  1626. if string(slurp) != reqBody(n) {
  1627. t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n))
  1628. }
  1629. }
  1630. body := fmt.Sprintf("Response number %d", n)
  1631. v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s
  1632. Date: Thu, 28 Feb 2013 17:55:41 GMT
  1633. HTTP/1.1 200 OK
  1634. Content-Type: text/html
  1635. Echo-Request-Id: %s
  1636. Content-Length: %d
  1637. %s`, resCode, id, len(body), body), "\n", "\r\n", -1))
  1638. w.Write(v)
  1639. if id == reqID(numReqs) {
  1640. return
  1641. }
  1642. }
  1643. }
  1644. tr := &Transport{
  1645. Dial: func(n, addr string) (net.Conn, error) {
  1646. sr, sw := io.Pipe() // server read/write
  1647. cr, cw := io.Pipe() // client read/write
  1648. conn := &rwTestConn{
  1649. Reader: cr,
  1650. Writer: sw,
  1651. closeFunc: func() error {
  1652. sw.Close()
  1653. cw.Close()
  1654. return nil
  1655. },
  1656. }
  1657. go send100Response(cw, sr)
  1658. return conn, nil
  1659. },
  1660. DisableKeepAlives: false,
  1661. }
  1662. defer tr.CloseIdleConnections()
  1663. c := &Client{Transport: tr}
  1664. testResponse := func(req *Request, name string, wantCode int) {
  1665. res, err := c.Do(req)
  1666. if err != nil {
  1667. t.Fatalf("%s: Do: %v", name, err)
  1668. }
  1669. if res.StatusCode != wantCode {
  1670. t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode)
  1671. }
  1672. if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack {
  1673. t.Errorf("%s: response id %q != request id %q", name, idBack, id)
  1674. }
  1675. _, err = ioutil.ReadAll(res.Body)
  1676. if err != nil {
  1677. t.Fatalf("%s: Slurp error: %v", name, err)
  1678. }
  1679. }
  1680. // Few 100 responses, making sure we're not off-by-one.
  1681. for i := 1; i <= numReqs; i++ {
  1682. req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i)))
  1683. req.Header.Set("Request-Id", reqID(i))
  1684. testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200)
  1685. }
  1686. // And some other informational 1xx but non-100 responses, to test
  1687. // we return them but don't re-use the connection.
  1688. for i := 1; i <= numReqs; i++ {
  1689. req, _ := NewRequest("POST", "http://other.tld/", strings.NewReader(reqBody(i)))
  1690. req.Header.Set("X-Want-Response-Code", "123 Sesame Street")
  1691. testResponse(req, fmt.Sprintf("123, %d/%d", i, numReqs), 123)
  1692. }
  1693. }
  1694. type proxyFromEnvTest struct {
  1695. req string // URL to fetch; blank means "http://example.com"
  1696. env string // HTTP_PROXY
  1697. httpsenv string // HTTPS_PROXY
  1698. noenv string // NO_RPXY
  1699. want string
  1700. wanterr error
  1701. }
  1702. func (t proxyFromEnvTest) String() string {
  1703. var buf bytes.Buffer
  1704. space := func() {
  1705. if buf.Len() > 0 {
  1706. buf.WriteByte(' ')
  1707. }
  1708. }
  1709. if t.env != "" {
  1710. fmt.Fprintf(&buf, "http_proxy=%q", t.env)
  1711. }
  1712. if t.httpsenv != "" {
  1713. space()
  1714. fmt.Fprintf(&buf, "https_proxy=%q", t.httpsenv)
  1715. }
  1716. if t.noenv != "" {
  1717. space()
  1718. fmt.Fprintf(&buf, "no_proxy=%q", t.noenv)
  1719. }
  1720. req := "http://example.com"
  1721. if t.req != "" {
  1722. req = t.req
  1723. }
  1724. space()
  1725. fmt.Fprintf(&buf, "req=%q", req)
  1726. return strings.TrimSpace(buf.String())
  1727. }
  1728. var proxyFromEnvTests = []proxyFromEnvTest{
  1729. {env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  1730. {env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"},
  1731. {env: "cache.corp.example.com", want: "http://cache.corp.example.com"},
  1732. {env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"},
  1733. {env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  1734. {env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"},
  1735. // Don't use secure for http
  1736. {req: "http://insecure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://http.proxy.tld"},
  1737. // Use secure for https.
  1738. {req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://secure.proxy.tld"},
  1739. {req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "https://secure.proxy.tld", want: "https://secure.proxy.tld"},
  1740. {want: "<nil>"},
  1741. {noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  1742. {noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  1743. {noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  1744. {noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"},
  1745. {noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  1746. }
  1747. func TestProxyFromEnvironment(t *testing.T) {
  1748. ResetProxyEnv()
  1749. for _, tt := range proxyFromEnvTests {
  1750. os.Setenv("HTTP_PROXY", tt.env)
  1751. os.Setenv("HTTPS_PROXY", tt.httpsenv)
  1752. os.Setenv("NO_PROXY", tt.noenv)
  1753. ResetCachedEnvironment()
  1754. reqURL := tt.req
  1755. if reqURL == "" {
  1756. reqURL = "http://example.com"
  1757. }
  1758. req, _ := NewRequest("GET", reqURL, nil)
  1759. url, err := ProxyFromEnvironment(req)
  1760. if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e {
  1761. t.Errorf("%v: got error = %q, want %q", tt, g, e)
  1762. continue
  1763. }
  1764. if got := fmt.Sprintf("%s", url); got != tt.want {
  1765. t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want)
  1766. }
  1767. }
  1768. }
  1769. func TestIdleConnChannelLeak(t *testing.T) {
  1770. var mu sync.Mutex
  1771. var n int
  1772. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1773. mu.Lock()
  1774. n++
  1775. mu.Unlock()
  1776. }))
  1777. defer ts.Close()
  1778. const nReqs = 5
  1779. didRead := make(chan bool, nReqs)
  1780. SetReadLoopBeforeNextReadHook(func() { didRead <- true })
  1781. defer SetReadLoopBeforeNextReadHook(nil)
  1782. tr := &Transport{
  1783. Dial: func(netw, addr string) (net.Conn, error) {
  1784. return net.Dial(netw, ts.Listener.Addr().String())
  1785. },
  1786. }
  1787. defer tr.CloseIdleConnections()
  1788. c := &Client{Transport: tr}
  1789. // First, without keep-alives.
  1790. for _, disableKeep := range []bool{true, false} {
  1791. tr.DisableKeepAlives = disableKeep
  1792. for i := 0; i < nReqs; i++ {
  1793. _, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i))
  1794. if err != nil {
  1795. t.Fatal(err)
  1796. }
  1797. // Note: no res.Body.Close is needed here, since the
  1798. // response Content-Length is zero. Perhaps the test
  1799. // should be more explicit and use a HEAD, but tests
  1800. // elsewhere guarantee that zero byte responses generate
  1801. // a "Content-Length: 0" instead of chunking.
  1802. }
  1803. // At this point, each of the 5 Transport.readLoop goroutines
  1804. // are scheduling noting that there are no response bodies (see
  1805. // earlier comment), and are then calling putIdleConn, which
  1806. // decrements this count. Usually that happens quickly, which is
  1807. // why this test has seemed to work for ages. But it's still
  1808. // racey: we have wait for them to finish first. See Issue 10427
  1809. for i := 0; i < nReqs; i++ {
  1810. <-didRead
  1811. }
  1812. if got := tr.IdleConnChMapSizeForTesting(); got != 0 {
  1813. t.Fatalf("ForDisableKeepAlives = %v, map size = %d; want 0", disableKeep, got)
  1814. }
  1815. }
  1816. }
  1817. // Verify the status quo: that the Client.Post function coerces its
  1818. // body into a ReadCloser if it's a Closer, and that the Transport
  1819. // then closes it.
  1820. func TestTransportClosesRequestBody(t *testing.T) {
  1821. defer afterTest(t)
  1822. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1823. io.Copy(ioutil.Discard, r.Body)
  1824. }))
  1825. defer ts.Close()
  1826. tr := &Transport{}
  1827. defer tr.CloseIdleConnections()
  1828. cl := &Client{Transport: tr}
  1829. closes := 0
  1830. res, err := cl.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
  1831. if err != nil {
  1832. t.Fatal(err)
  1833. }
  1834. res.Body.Close()
  1835. if closes != 1 {
  1836. t.Errorf("closes = %d; want 1", closes)
  1837. }
  1838. }
  1839. func TestTransportTLSHandshakeTimeout(t *testing.T) {
  1840. defer afterTest(t)
  1841. if testing.Short() {
  1842. t.Skip("skipping in short mode")
  1843. }
  1844. ln := newLocalListener(t)
  1845. defer ln.Close()
  1846. testdonec := make(chan struct{})
  1847. defer close(testdonec)
  1848. go func() {
  1849. c, err := ln.Accept()
  1850. if err != nil {
  1851. t.Error(err)
  1852. return
  1853. }
  1854. <-testdonec
  1855. c.Close()
  1856. }()
  1857. getdonec := make(chan struct{})
  1858. go func() {
  1859. defer close(getdonec)
  1860. tr := &Transport{
  1861. Dial: func(_, _ string) (net.Conn, error) {
  1862. return net.Dial("tcp", ln.Addr().String())
  1863. },
  1864. TLSHandshakeTimeout: 250 * time.Millisecond,
  1865. }
  1866. cl := &Client{Transport: tr}
  1867. _, err := cl.Get("https://dummy.tld/")
  1868. if err == nil {
  1869. t.Error("expected error")
  1870. return
  1871. }
  1872. ue, ok := err.(*url.Error)
  1873. if !ok {
  1874. t.Errorf("expected url.Error; got %#v", err)
  1875. return
  1876. }
  1877. ne, ok := ue.Err.(net.Error)
  1878. if !ok {
  1879. t.Errorf("expected net.Error; got %#v", err)
  1880. return
  1881. }
  1882. if !ne.Timeout() {
  1883. t.Errorf("expected timeout error; got %v", err)
  1884. }
  1885. if !strings.Contains(err.Error(), "handshake timeout") {
  1886. t.Errorf("expected 'handshake timeout' in error; got %v", err)
  1887. }
  1888. }()
  1889. select {
  1890. case <-getdonec:
  1891. case <-time.After(5 * time.Second):
  1892. t.Error("test timeout; TLS handshake hung?")
  1893. }
  1894. }
  1895. // Trying to repro golang.org/issue/3514
  1896. func TestTLSServerClosesConnection(t *testing.T) {
  1897. defer afterTest(t)
  1898. if runtime.GOOS == "windows" {
  1899. t.Skip("skipping flaky test on Windows; golang.org/issue/7634")
  1900. }
  1901. closedc := make(chan bool, 1)
  1902. ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1903. if strings.Contains(r.URL.Path, "/keep-alive-then-die") {
  1904. conn, _, _ := w.(Hijacker).Hijack()
  1905. conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo"))
  1906. conn.Close()
  1907. closedc <- true
  1908. return
  1909. }
  1910. fmt.Fprintf(w, "hello")
  1911. }))
  1912. defer ts.Close()
  1913. tr := &Transport{
  1914. TLSClientConfig: &tls.Config{
  1915. InsecureSkipVerify: true,
  1916. },
  1917. }
  1918. defer tr.CloseIdleConnections()
  1919. client := &Client{Transport: tr}
  1920. var nSuccess = 0
  1921. var errs []error
  1922. const trials = 20
  1923. for i := 0; i < trials; i++ {
  1924. tr.CloseIdleConnections()
  1925. res, err := client.Get(ts.URL + "/keep-alive-then-die")
  1926. if err != nil {
  1927. t.Fatal(err)
  1928. }
  1929. <-closedc
  1930. slurp, err := ioutil.ReadAll(res.Body)
  1931. if err != nil {
  1932. t.Fatal(err)
  1933. }
  1934. if string(slurp) != "foo" {
  1935. t.Errorf("Got %q, want foo", slurp)
  1936. }
  1937. // Now try again and see if we successfully
  1938. // pick a new connection.
  1939. res, err = client.Get(ts.URL + "/")
  1940. if err != nil {
  1941. errs = append(errs, err)
  1942. continue
  1943. }
  1944. slurp, err = ioutil.ReadAll(res.Body)
  1945. if err != nil {
  1946. errs = append(errs, err)
  1947. continue
  1948. }
  1949. nSuccess++
  1950. }
  1951. if nSuccess > 0 {
  1952. t.Logf("successes = %d of %d", nSuccess, trials)
  1953. } else {
  1954. t.Errorf("All runs failed:")
  1955. }
  1956. for _, err := range errs {
  1957. t.Logf(" err: %v", err)
  1958. }
  1959. }
  1960. // byteFromChanReader is an io.Reader that reads a single byte at a
  1961. // time from the channel. When the channel is closed, the reader
  1962. // returns io.EOF.
  1963. type byteFromChanReader chan byte
  1964. func (c byteFromChanReader) Read(p []byte) (n int, err error) {
  1965. if len(p) == 0 {
  1966. return
  1967. }
  1968. b, ok := <-c
  1969. if !ok {
  1970. return 0, io.EOF
  1971. }
  1972. p[0] = b
  1973. return 1, nil
  1974. }
  1975. // Verifies that the Transport doesn't reuse a connection in the case
  1976. // where the server replies before the request has been fully
  1977. // written. We still honor that reply (see TestIssue3595), but don't
  1978. // send future requests on the connection because it's then in a
  1979. // questionable state.
  1980. // golang.org/issue/7569
  1981. func TestTransportNoReuseAfterEarlyResponse(t *testing.T) {
  1982. defer afterTest(t)
  1983. var sconn struct {
  1984. sync.Mutex
  1985. c net.Conn
  1986. }
  1987. var getOkay bool
  1988. closeConn := func() {
  1989. sconn.Lock()
  1990. defer sconn.Unlock()
  1991. if sconn.c != nil {
  1992. sconn.c.Close()
  1993. sconn.c = nil
  1994. if !getOkay {
  1995. t.Logf("Closed server connection")
  1996. }
  1997. }
  1998. }
  1999. defer closeConn()
  2000. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2001. if r.Method == "GET" {
  2002. io.WriteString(w, "bar")
  2003. return
  2004. }
  2005. conn, _, _ := w.(Hijacker).Hijack()
  2006. sconn.Lock()
  2007. sconn.c = conn
  2008. sconn.Unlock()
  2009. conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive
  2010. go io.Copy(ioutil.Discard, conn)
  2011. }))
  2012. defer ts.Close()
  2013. tr := &Transport{}
  2014. defer tr.CloseIdleConnections()
  2015. client := &Client{Transport: tr}
  2016. const bodySize = 256 << 10
  2017. finalBit := make(byteFromChanReader, 1)
  2018. req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit))
  2019. req.ContentLength = bodySize
  2020. res, err := client.Do(req)
  2021. if err := wantBody(res, err, "foo"); err != nil {
  2022. t.Errorf("POST response: %v", err)
  2023. }
  2024. donec := make(chan bool)
  2025. go func() {
  2026. defer close(donec)
  2027. res, err = client.Get(ts.URL)
  2028. if err := wantBody(res, err, "bar"); err != nil {
  2029. t.Errorf("GET response: %v", err)
  2030. return
  2031. }
  2032. getOkay = true // suppress test noise
  2033. }()
  2034. time.AfterFunc(5*time.Second, closeConn)
  2035. select {
  2036. case <-donec:
  2037. finalBit <- 'x' // unblock the writeloop of the first Post
  2038. close(finalBit)
  2039. case <-time.After(7 * time.Second):
  2040. t.Fatal("timeout waiting for GET request to finish")
  2041. }
  2042. }
  2043. // Tests that we don't leak Transport persistConn.readLoop goroutines
  2044. // when a server hangs up immediately after saying it would keep-alive.
  2045. func TestTransportIssue10457(t *testing.T) {
  2046. defer afterTest(t) // used to fail in goroutine leak check
  2047. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2048. // Send a response with no body, keep-alive
  2049. // (implicit), and then lie and immediately close the
  2050. // connection. This forces the Transport's readLoop to
  2051. // immediately Peek an io.EOF and get to the point
  2052. // that used to hang.
  2053. conn, _, _ := w.(Hijacker).Hijack()
  2054. conn.Write([]byte("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n")) // keep-alive
  2055. conn.Close()
  2056. }))
  2057. defer ts.Close()
  2058. tr := &Transport{}
  2059. defer tr.CloseIdleConnections()
  2060. cl := &Client{Transport: tr}
  2061. res, err := cl.Get(ts.URL)
  2062. if err != nil {
  2063. t.Fatalf("Get: %v", err)
  2064. }
  2065. defer res.Body.Close()
  2066. // Just a sanity check that we at least get the response. The real
  2067. // test here is that the "defer afterTest" above doesn't find any
  2068. // leaked goroutines.
  2069. if got, want := res.Header.Get("Foo"), "Bar"; got != want {
  2070. t.Errorf("Foo header = %q; want %q", got, want)
  2071. }
  2072. }
  2073. type errorReader struct {
  2074. err error
  2075. }
  2076. func (e errorReader) Read(p []byte) (int, error) { return 0, e.err }
  2077. type closerFunc func() error
  2078. func (f closerFunc) Close() error { return f() }
  2079. // Issue 6981
  2080. func TestTransportClosesBodyOnError(t *testing.T) {
  2081. if runtime.GOOS == "plan9" {
  2082. t.Skip("skipping test; see https://golang.org/issue/7782")
  2083. }
  2084. defer afterTest(t)
  2085. readBody := make(chan error, 1)
  2086. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2087. _, err := ioutil.ReadAll(r.Body)
  2088. readBody <- err
  2089. }))
  2090. defer ts.Close()
  2091. fakeErr := errors.New("fake error")
  2092. didClose := make(chan bool, 1)
  2093. req, _ := NewRequest("POST", ts.URL, struct {
  2094. io.Reader
  2095. io.Closer
  2096. }{
  2097. io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), errorReader{fakeErr}),
  2098. closerFunc(func() error {
  2099. select {
  2100. case didClose <- true:
  2101. default:
  2102. }
  2103. return nil
  2104. }),
  2105. })
  2106. res, err := DefaultClient.Do(req)
  2107. if res != nil {
  2108. defer res.Body.Close()
  2109. }
  2110. if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) {
  2111. t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error())
  2112. }
  2113. select {
  2114. case err := <-readBody:
  2115. if err == nil {
  2116. t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'")
  2117. }
  2118. case <-time.After(5 * time.Second):
  2119. t.Error("timeout waiting for server handler to complete")
  2120. }
  2121. select {
  2122. case <-didClose:
  2123. default:
  2124. t.Errorf("didn't see Body.Close")
  2125. }
  2126. }
  2127. func TestTransportDialTLS(t *testing.T) {
  2128. var mu sync.Mutex // guards following
  2129. var gotReq, didDial bool
  2130. ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2131. mu.Lock()
  2132. gotReq = true
  2133. mu.Unlock()
  2134. }))
  2135. defer ts.Close()
  2136. tr := &Transport{
  2137. DialTLS: func(netw, addr string) (net.Conn, error) {
  2138. mu.Lock()
  2139. didDial = true
  2140. mu.Unlock()
  2141. c, err := tls.Dial(netw, addr, &tls.Config{
  2142. InsecureSkipVerify: true,
  2143. })
  2144. if err != nil {
  2145. return nil, err
  2146. }
  2147. return c, c.Handshake()
  2148. },
  2149. }
  2150. defer tr.CloseIdleConnections()
  2151. client := &Client{Transport: tr}
  2152. res, err := client.Get(ts.URL)
  2153. if err != nil {
  2154. t.Fatal(err)
  2155. }
  2156. res.Body.Close()
  2157. mu.Lock()
  2158. if !gotReq {
  2159. t.Error("didn't get request")
  2160. }
  2161. if !didDial {
  2162. t.Error("didn't use dial hook")
  2163. }
  2164. }
  2165. // Test for issue 8755
  2166. // Ensure that if a proxy returns an error, it is exposed by RoundTrip
  2167. func TestRoundTripReturnsProxyError(t *testing.T) {
  2168. badProxy := func(*Request) (*url.URL, error) {
  2169. return nil, errors.New("errorMessage")
  2170. }
  2171. tr := &Transport{Proxy: badProxy}
  2172. req, _ := NewRequest("GET", "http://example.com", nil)
  2173. _, err := tr.RoundTrip(req)
  2174. if err == nil {
  2175. t.Error("Expected proxy error to be returned by RoundTrip")
  2176. }
  2177. }
  2178. // tests that putting an idle conn after a call to CloseIdleConns does return it
  2179. func TestTransportCloseIdleConnsThenReturn(t *testing.T) {
  2180. tr := &Transport{}
  2181. wantIdle := func(when string, n int) bool {
  2182. got := tr.IdleConnCountForTesting("|http|example.com") // key used by PutIdleTestConn
  2183. if got == n {
  2184. return true
  2185. }
  2186. t.Errorf("%s: idle conns = %d; want %d", when, got, n)
  2187. return false
  2188. }
  2189. wantIdle("start", 0)
  2190. if !tr.PutIdleTestConn() {
  2191. t.Fatal("put failed")
  2192. }
  2193. if !tr.PutIdleTestConn() {
  2194. t.Fatal("second put failed")
  2195. }
  2196. wantIdle("after put", 2)
  2197. tr.CloseIdleConnections()
  2198. if !tr.IsIdleForTesting() {
  2199. t.Error("should be idle after CloseIdleConnections")
  2200. }
  2201. wantIdle("after close idle", 0)
  2202. if tr.PutIdleTestConn() {
  2203. t.Fatal("put didn't fail")
  2204. }
  2205. wantIdle("after second put", 0)
  2206. tr.RequestIdleConnChForTesting() // should toggle the transport out of idle mode
  2207. if tr.IsIdleForTesting() {
  2208. t.Error("shouldn't be idle after RequestIdleConnChForTesting")
  2209. }
  2210. if !tr.PutIdleTestConn() {
  2211. t.Fatal("after re-activation")
  2212. }
  2213. wantIdle("after final put", 1)
  2214. }
  2215. // This tests that an client requesting a content range won't also
  2216. // implicitly ask for gzip support. If they want that, they need to do it
  2217. // on their own.
  2218. // golang.org/issue/8923
  2219. func TestTransportRangeAndGzip(t *testing.T) {
  2220. defer afterTest(t)
  2221. reqc := make(chan *Request, 1)
  2222. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2223. reqc <- r
  2224. }))
  2225. defer ts.Close()
  2226. req, _ := NewRequest("GET", ts.URL, nil)
  2227. req.Header.Set("Range", "bytes=7-11")
  2228. res, err := DefaultClient.Do(req)
  2229. if err != nil {
  2230. t.Fatal(err)
  2231. }
  2232. select {
  2233. case r := <-reqc:
  2234. if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
  2235. t.Error("Transport advertised gzip support in the Accept header")
  2236. }
  2237. if r.Header.Get("Range") == "" {
  2238. t.Error("no Range in request")
  2239. }
  2240. case <-time.After(10 * time.Second):
  2241. t.Fatal("timeout")
  2242. }
  2243. res.Body.Close()
  2244. }
  2245. // Previously, we used to handle a logical race within RoundTrip by waiting for 100ms
  2246. // in the case of an error. Changing the order of the channel operations got rid of this
  2247. // race.
  2248. //
  2249. // In order to test that the channel op reordering works, we install a hook into the
  2250. // roundTrip function which gets called if we saw the connection go away and
  2251. // we subsequently received a response.
  2252. func TestTransportResponseCloseRace(t *testing.T) {
  2253. if testing.Short() {
  2254. t.Skip("skipping in short mode")
  2255. }
  2256. defer afterTest(t)
  2257. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2258. }))
  2259. defer ts.Close()
  2260. sawRace := false
  2261. SetInstallConnClosedHook(func() {
  2262. sawRace = true
  2263. })
  2264. defer SetInstallConnClosedHook(nil)
  2265. tr := &Transport{
  2266. DisableKeepAlives: true,
  2267. }
  2268. req, err := NewRequest("GET", ts.URL, nil)
  2269. if err != nil {
  2270. t.Fatal(err)
  2271. }
  2272. // selects are not deterministic, so do this a bunch
  2273. // and see if we handle the logical race at least once.
  2274. for i := 0; i < 10000; i++ {
  2275. resp, err := tr.RoundTrip(req)
  2276. if err != nil {
  2277. t.Fatalf("unexpected error: %s", err)
  2278. continue
  2279. }
  2280. resp.Body.Close()
  2281. if sawRace {
  2282. break
  2283. }
  2284. }
  2285. if !sawRace {
  2286. t.Errorf("didn't see response/connection going away race")
  2287. }
  2288. }
  2289. // Test for issue 10474
  2290. func TestTransportResponseCancelRace(t *testing.T) {
  2291. defer afterTest(t)
  2292. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2293. // important that this response has a body.
  2294. var b [1024]byte
  2295. w.Write(b[:])
  2296. }))
  2297. defer ts.Close()
  2298. tr := &Transport{}
  2299. defer tr.CloseIdleConnections()
  2300. req, err := NewRequest("GET", ts.URL, nil)
  2301. if err != nil {
  2302. t.Fatal(err)
  2303. }
  2304. res, err := tr.RoundTrip(req)
  2305. if err != nil {
  2306. t.Fatal(err)
  2307. }
  2308. // If we do an early close, Transport just throws the connection away and
  2309. // doesn't reuse it. In order to trigger the bug, it has to reuse the connection
  2310. // so read the body
  2311. if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
  2312. t.Fatal(err)
  2313. }
  2314. req2, err := NewRequest("GET", ts.URL, nil)
  2315. if err != nil {
  2316. t.Fatal(err)
  2317. }
  2318. tr.CancelRequest(req)
  2319. res, err = tr.RoundTrip(req2)
  2320. if err != nil {
  2321. t.Fatal(err)
  2322. }
  2323. res.Body.Close()
  2324. }
  2325. func TestTransportDialCancelRace(t *testing.T) {
  2326. defer afterTest(t)
  2327. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  2328. defer ts.Close()
  2329. tr := &Transport{}
  2330. defer tr.CloseIdleConnections()
  2331. req, err := NewRequest("GET", ts.URL, nil)
  2332. if err != nil {
  2333. t.Fatal(err)
  2334. }
  2335. SetEnterRoundTripHook(func() {
  2336. tr.CancelRequest(req)
  2337. })
  2338. defer SetEnterRoundTripHook(nil)
  2339. res, err := tr.RoundTrip(req)
  2340. if err != ExportErrRequestCanceled {
  2341. t.Errorf("expected canceled request error; got %v", err)
  2342. if err == nil {
  2343. res.Body.Close()
  2344. }
  2345. }
  2346. }
  2347. // logWritesConn is a net.Conn that logs each Write call to writes
  2348. // and then proxies to w.
  2349. // It proxies Read calls to a reader it receives from rch.
  2350. type logWritesConn struct {
  2351. net.Conn // nil. crash on use.
  2352. w io.Writer
  2353. rch <-chan io.Reader
  2354. r io.Reader // nil until received by rch
  2355. mu sync.Mutex
  2356. writes []string
  2357. }
  2358. func (c *logWritesConn) Write(p []byte) (n int, err error) {
  2359. c.mu.Lock()
  2360. defer c.mu.Unlock()
  2361. c.writes = append(c.writes, string(p))
  2362. return c.w.Write(p)
  2363. }
  2364. func (c *logWritesConn) Read(p []byte) (n int, err error) {
  2365. if c.r == nil {
  2366. c.r = <-c.rch
  2367. }
  2368. return c.r.Read(p)
  2369. }
  2370. func (c *logWritesConn) Close() error { return nil }
  2371. // Issue 6574
  2372. func TestTransportFlushesBodyChunks(t *testing.T) {
  2373. defer afterTest(t)
  2374. resBody := make(chan io.Reader, 1)
  2375. connr, connw := io.Pipe() // connection pipe pair
  2376. lw := &logWritesConn{
  2377. rch: resBody,
  2378. w: connw,
  2379. }
  2380. tr := &Transport{
  2381. Dial: func(network, addr string) (net.Conn, error) {
  2382. return lw, nil
  2383. },
  2384. }
  2385. bodyr, bodyw := io.Pipe() // body pipe pair
  2386. go func() {
  2387. defer bodyw.Close()
  2388. for i := 0; i < 3; i++ {
  2389. fmt.Fprintf(bodyw, "num%d\n", i)
  2390. }
  2391. }()
  2392. resc := make(chan *Response)
  2393. go func() {
  2394. req, _ := NewRequest("POST", "http://localhost:8080", bodyr)
  2395. req.Header.Set("User-Agent", "x") // known value for test
  2396. res, err := tr.RoundTrip(req)
  2397. if err != nil {
  2398. t.Error("RoundTrip: %v", err)
  2399. close(resc)
  2400. return
  2401. }
  2402. resc <- res
  2403. }()
  2404. // Fully consume the request before checking the Write log vs. want.
  2405. req, err := ReadRequest(bufio.NewReader(connr))
  2406. if err != nil {
  2407. t.Fatal(err)
  2408. }
  2409. io.Copy(ioutil.Discard, req.Body)
  2410. // Unblock the transport's roundTrip goroutine.
  2411. resBody <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n")
  2412. res, ok := <-resc
  2413. if !ok {
  2414. return
  2415. }
  2416. defer res.Body.Close()
  2417. want := []string{
  2418. // Because Request.ContentLength = 0, the body is sniffed for 1 byte to determine whether there's content.
  2419. // That explains the initial "num0" being split into "n" and "um0".
  2420. // The first byte is included with the request headers Write. Perhaps in the future
  2421. // we will want to flush the headers out early if the first byte of the request body is
  2422. // taking a long time to arrive. But not yet.
  2423. "POST / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: x\r\nTransfer-Encoding: chunked\r\nAccept-Encoding: gzip\r\n\r\n" +
  2424. "1\r\nn\r\n",
  2425. "4\r\num0\n\r\n",
  2426. "5\r\nnum1\n\r\n",
  2427. "5\r\nnum2\n\r\n",
  2428. "0\r\n\r\n",
  2429. }
  2430. if !reflect.DeepEqual(lw.writes, want) {
  2431. t.Errorf("Writes differed.\n Got: %q\nWant: %q\n", lw.writes, want)
  2432. }
  2433. }
  2434. // Issue 11745.
  2435. func TestTransportPrefersResponseOverWriteError(t *testing.T) {
  2436. if testing.Short() {
  2437. t.Skip("skipping in short mode")
  2438. }
  2439. defer afterTest(t)
  2440. const contentLengthLimit = 1024 * 1024 // 1MB
  2441. ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2442. if r.ContentLength >= contentLengthLimit {
  2443. w.WriteHeader(StatusBadRequest)
  2444. r.Body.Close()
  2445. return
  2446. }
  2447. w.WriteHeader(StatusOK)
  2448. }))
  2449. defer ts.Close()
  2450. fail := 0
  2451. count := 100
  2452. bigBody := strings.Repeat("a", contentLengthLimit*2)
  2453. for i := 0; i < count; i++ {
  2454. req, err := NewRequest("PUT", ts.URL, strings.NewReader(bigBody))
  2455. if err != nil {
  2456. t.Fatal(err)
  2457. }
  2458. tr := new(Transport)
  2459. defer tr.CloseIdleConnections()
  2460. client := &Client{Transport: tr}
  2461. resp, err := client.Do(req)
  2462. if err != nil {
  2463. fail++
  2464. t.Logf("%d = %#v", i, err)
  2465. if ue, ok := err.(*url.Error); ok {
  2466. t.Logf("urlErr = %#v", ue.Err)
  2467. if ne, ok := ue.Err.(*net.OpError); ok {
  2468. t.Logf("netOpError = %#v", ne.Err)
  2469. }
  2470. }
  2471. } else {
  2472. resp.Body.Close()
  2473. if resp.StatusCode != 400 {
  2474. t.Errorf("Expected status code 400, got %v", resp.Status)
  2475. }
  2476. }
  2477. }
  2478. if fail > 0 {
  2479. t.Errorf("Failed %v out of %v\n", fail, count)
  2480. }
  2481. }
  2482. func wantBody(res *Response, err error, want string) error {
  2483. if err != nil {
  2484. return err
  2485. }
  2486. slurp, err := ioutil.ReadAll(res.Body)
  2487. if err != nil {
  2488. return fmt.Errorf("error reading body: %v", err)
  2489. }
  2490. if string(slurp) != want {
  2491. return fmt.Errorf("body = %q; want %q", slurp, want)
  2492. }
  2493. if err := res.Body.Close(); err != nil {
  2494. return fmt.Errorf("body Close = %v", err)
  2495. }
  2496. return nil
  2497. }
  2498. func newLocalListener(t *testing.T) net.Listener {
  2499. ln, err := net.Listen("tcp", "127.0.0.1:0")
  2500. if err != nil {
  2501. ln, err = net.Listen("tcp6", "[::1]:0")
  2502. }
  2503. if err != nil {
  2504. t.Fatal(err)
  2505. }
  2506. return ln
  2507. }
  2508. type countCloseReader struct {
  2509. n *int
  2510. io.Reader
  2511. }
  2512. func (cr countCloseReader) Close() error {
  2513. (*cr.n)++
  2514. return nil
  2515. }
  2516. // rgz is a gzip quine that uncompresses to itself.
  2517. var rgz = []byte{
  2518. 0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
  2519. 0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
  2520. 0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
  2521. 0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
  2522. 0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
  2523. 0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
  2524. 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
  2525. 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
  2526. 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
  2527. 0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
  2528. 0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
  2529. 0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
  2530. 0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
  2531. 0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
  2532. 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  2533. 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
  2534. 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
  2535. 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
  2536. 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
  2537. 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  2538. 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
  2539. 0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
  2540. 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
  2541. 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
  2542. 0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
  2543. 0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
  2544. 0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
  2545. 0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
  2546. 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
  2547. 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  2548. 0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  2549. 0x00, 0x00,
  2550. }