"sync/atomic"
"testing"
"time"
+
+ "golang_org/x/net/http/httpguts"
)
// TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close
}
}
+// Test that Transport only sends one "Connection: close", regardless of
+// how "close" was indicated.
+func TestTransportRespectRequestWantsClose(t *testing.T) {
+ tests := []struct {
+ disableKeepAlives bool
+ close bool
+ }{
+ {disableKeepAlives: false, close: false},
+ {disableKeepAlives: false, close: true},
+ {disableKeepAlives: true, close: false},
+ {disableKeepAlives: true, close: true},
+ }
+
+ for _, tc := range tests {
+ t.Run(fmt.Sprintf("DisableKeepAlive=%v,RequestClose=%v", tc.disableKeepAlives, tc.close),
+ func(t *testing.T) {
+ defer afterTest(t)
+ ts := httptest.NewServer(hostPortHandler)
+ defer ts.Close()
+
+ c := ts.Client()
+ c.Transport.(*Transport).DisableKeepAlives = tc.disableKeepAlives
+ req, err := NewRequest("GET", ts.URL, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ count := 0
+ trace := &httptrace.ClientTrace{
+ WroteHeaderField: func(key string, field []string) {
+ if key != "Connection" {
+ return
+ }
+ if httpguts.HeaderValuesContainsToken(field, "close") {
+ count += 1
+ }
+ },
+ }
+ req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
+ req.Close = tc.close
+ res, err := c.Do(req)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer res.Body.Close()
+ if want := tc.disableKeepAlives || tc.close; count > 1 || (count == 1) != want {
+ t.Errorf("expecting want:%v, got 'Connection: close':%d", want, count)
+ }
+ })
+ }
+
+}
+
func TestTransportIdleCacheKeys(t *testing.T) {
defer afterTest(t)
ts := httptest.NewServer(hostPortHandler)