~hduran-8/+junk/caddy

« back to all changes in this revision

Viewing changes to debian/gocode/src/golang.org/x/net/http2/server_test.go

  • Committer: Horacio Durán
  • Date: 2017-01-20 16:21:20 UTC
  • Revision ID: horacio.duran@canonical.com-20170120162120-l82mfqwmsclnk838
Upgrade to 0.9.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
        t              testing.TB
46
46
        ts             *httptest.Server
47
47
        fr             *Framer
48
 
        logBuf         *bytes.Buffer
49
 
        logFilter      []string   // substrings to filter out
50
 
        scMu           sync.Mutex // guards sc
 
48
        serverLogBuf   bytes.Buffer // logger for httptest.Server
 
49
        logFilter      []string     // substrings to filter out
 
50
        scMu           sync.Mutex   // guards sc
51
51
        sc             *serverConn
52
52
        hpackDec       *hpack.Decoder
53
53
        decodedHeaders [][2]string
54
54
 
 
55
        // If http2debug!=2, then we capture Frame debug logs that will be written
 
56
        // to t.Log after a test fails. The read and write logs use separate locks
 
57
        // and buffers so we don't accidentally introduce synchronization between
 
58
        // the read and write goroutines, which may hide data races.
 
59
        frameReadLogMu   sync.Mutex
 
60
        frameReadLogBuf  bytes.Buffer
 
61
        frameWriteLogMu  sync.Mutex
 
62
        frameWriteLogBuf bytes.Buffer
 
63
 
55
64
        // writing headers:
56
65
        headerBuf bytes.Buffer
57
66
        hpackEnc  *hpack.Encoder
75
84
func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}) *serverTester {
76
85
        resetHooks()
77
86
 
78
 
        logBuf := new(bytes.Buffer)
79
87
        ts := httptest.NewUnstartedServer(handler)
80
88
 
81
89
        tlsConfig := &tls.Config{
82
90
                InsecureSkipVerify: true,
83
 
                // The h2-14 is temporary, until curl is updated. (as used by unit tests
84
 
                // in Docker)
85
 
                NextProtos: []string{NextProtoTLS, "h2-14"},
 
91
                NextProtos:         []string{NextProtoTLS},
86
92
        }
87
93
 
88
94
        var onlyServer, quiet bool
 
95
        h2server := new(Server)
89
96
        for _, opt := range opts {
90
97
                switch v := opt.(type) {
91
98
                case func(*tls.Config):
92
99
                        v(tlsConfig)
93
100
                case func(*httptest.Server):
94
101
                        v(ts)
 
102
                case func(*Server):
 
103
                        v(h2server)
95
104
                case serverTesterOpt:
96
105
                        switch v {
97
106
                        case optOnlyServer:
106
115
                }
107
116
        }
108
117
 
109
 
        ConfigureServer(ts.Config, &Server{})
 
118
        ConfigureServer(ts.Config, h2server)
110
119
 
111
120
        st := &serverTester{
112
 
                t:      t,
113
 
                ts:     ts,
114
 
                logBuf: logBuf,
 
121
                t:  t,
 
122
                ts: ts,
115
123
        }
116
124
        st.hpackEnc = hpack.NewEncoder(&st.headerBuf)
117
125
        st.hpackDec = hpack.NewDecoder(initialHeaderTableSize, st.onHeaderField)
120
128
        if quiet {
121
129
                ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
122
130
        } else {
123
 
                ts.Config.ErrorLog = log.New(io.MultiWriter(stderrv(), twriter{t: t, st: st}, logBuf), "", log.LstdFlags)
 
131
                ts.Config.ErrorLog = log.New(io.MultiWriter(stderrv(), twriter{t: t, st: st}, &st.serverLogBuf), "", log.LstdFlags)
124
132
        }
125
133
        ts.StartTLS()
126
134
 
141
149
                }
142
150
                st.cc = cc
143
151
                st.fr = NewFramer(cc, cc)
 
152
                if !logFrameReads && !logFrameWrites {
 
153
                        st.fr.debugReadLoggerf = func(m string, v ...interface{}) {
 
154
                                m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
 
155
                                st.frameReadLogMu.Lock()
 
156
                                fmt.Fprintf(&st.frameReadLogBuf, m, v...)
 
157
                                st.frameReadLogMu.Unlock()
 
158
                        }
 
159
                        st.fr.debugWriteLoggerf = func(m string, v ...interface{}) {
 
160
                                m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
 
161
                                st.frameWriteLogMu.Lock()
 
162
                                fmt.Fprintf(&st.frameWriteLogBuf, m, v...)
 
163
                                st.frameWriteLogMu.Unlock()
 
164
                        }
 
165
                        st.fr.logReads = true
 
166
                        st.fr.logWrites = true
 
167
                }
144
168
        }
145
169
        return st
146
170
}
200
224
 
201
225
func (st *serverTester) Close() {
202
226
        if st.t.Failed() {
 
227
                st.frameReadLogMu.Lock()
 
228
                if st.frameReadLogBuf.Len() > 0 {
 
229
                        st.t.Logf("Framer read log:\n%s", st.frameReadLogBuf.String())
 
230
                }
 
231
                st.frameReadLogMu.Unlock()
 
232
 
 
233
                st.frameWriteLogMu.Lock()
 
234
                if st.frameWriteLogBuf.Len() > 0 {
 
235
                        st.t.Logf("Framer write log:\n%s", st.frameWriteLogBuf.String())
 
236
                }
 
237
                st.frameWriteLogMu.Unlock()
 
238
 
203
239
                // If we failed already (and are likely in a Fatal,
204
240
                // unwindowing), force close the connection, so the
205
241
                // httptest.Server doesn't wait forever for the conn
253
289
        }
254
290
}
255
291
 
 
292
func (st *serverTester) writePriority(id uint32, p PriorityParam) {
 
293
        if err := st.fr.WritePriority(id, p); err != nil {
 
294
                st.t.Fatalf("Error writing PRIORITY: %v", err)
 
295
        }
 
296
}
 
297
 
256
298
func (st *serverTester) encodeHeaderField(k, v string) {
257
299
        err := st.hpackEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
258
300
        if err != nil {
278
320
// encodeHeader encodes headers and returns their HPACK bytes. headers
279
321
// must contain an even number of key/value pairs.  There may be
280
322
// multiple pairs for keys (e.g. "cookie").  The :method, :path, and
281
 
// :scheme headers default to GET, / and https.
 
323
// :scheme headers default to GET, / and https. The :authority header
 
324
// defaults to st.ts.Listener.Addr().
282
325
func (st *serverTester) encodeHeader(headers ...string) []byte {
283
326
        if len(headers)%2 == 1 {
284
327
                panic("odd number of kv args")
285
328
        }
286
329
 
287
330
        st.headerBuf.Reset()
 
331
        defaultAuthority := st.ts.Listener.Addr().String()
288
332
 
289
333
        if len(headers) == 0 {
290
334
                // Fast path, mostly for benchmarks, so test code doesn't pollute
291
335
                // profiles when we're looking to improve server allocations.
292
336
                st.encodeHeaderField(":method", "GET")
 
337
                st.encodeHeaderField(":scheme", "https")
 
338
                st.encodeHeaderField(":authority", defaultAuthority)
293
339
                st.encodeHeaderField(":path", "/")
294
 
                st.encodeHeaderField(":scheme", "https")
295
340
                return st.headerBuf.Bytes()
296
341
        }
297
342
 
298
343
        if len(headers) == 2 && headers[0] == ":method" {
299
344
                // Another fast path for benchmarks.
300
345
                st.encodeHeaderField(":method", headers[1])
 
346
                st.encodeHeaderField(":scheme", "https")
 
347
                st.encodeHeaderField(":authority", defaultAuthority)
301
348
                st.encodeHeaderField(":path", "/")
302
 
                st.encodeHeaderField(":scheme", "https")
303
349
                return st.headerBuf.Bytes()
304
350
        }
305
351
 
306
352
        pseudoCount := map[string]int{}
307
 
        keys := []string{":method", ":path", ":scheme"}
 
353
        keys := []string{":method", ":scheme", ":authority", ":path"}
308
354
        vals := map[string][]string{
309
 
                ":method": {"GET"},
310
 
                ":path":   {"/"},
311
 
                ":scheme": {"https"},
 
355
                ":method":    {"GET"},
 
356
                ":scheme":    {"https"},
 
357
                ":authority": {defaultAuthority},
 
358
                ":path":      {"/"},
312
359
        }
313
360
        for len(headers) > 0 {
314
361
                k, v := headers[0], headers[1]
503
550
        if !sf.Header().Flags.Has(FlagSettingsAck) {
504
551
                st.t.Fatal("Settings Frame didn't have ACK set")
505
552
        }
 
553
}
506
554
 
 
555
func (st *serverTester) wantPushPromise() *PushPromiseFrame {
 
556
        f, err := st.readFrame()
 
557
        if err != nil {
 
558
                st.t.Fatal(err)
 
559
        }
 
560
        ppf, ok := f.(*PushPromiseFrame)
 
561
        if !ok {
 
562
                st.t.Fatalf("Wanted PushPromise, received %T", ppf)
 
563
        }
 
564
        return ppf
507
565
}
508
566
 
509
567
func TestServer(t *testing.T) {
758
816
        testServerRequest(t, func(st *serverTester) {
759
817
                st.writeHeaders(HeadersFrameParam{
760
818
                        StreamID:      1, // clients send odd numbers
761
 
                        BlockFragment: st.encodeHeader("host", host),
 
819
                        BlockFragment: st.encodeHeader(":authority", "", "host", host),
762
820
                        EndStream:     true,
763
821
                        EndHeaders:    true,
764
822
                })
937
995
 
938
996
func testRejectRequest(t *testing.T, send func(*serverTester)) {
939
997
        st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
940
 
                t.Fatal("server request made it to handler; should've been rejected")
 
998
                t.Error("server request made it to handler; should've been rejected")
941
999
        })
942
1000
        defer st.Close()
943
1001
 
946
1004
        st.wantRSTStream(1, ErrCodeProtocol)
947
1005
}
948
1006
 
 
1007
func testRejectRequestWithProtocolError(t *testing.T, send func(*serverTester)) {
 
1008
        st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
 
1009
                t.Error("server request made it to handler; should've been rejected")
 
1010
        }, optQuiet)
 
1011
        defer st.Close()
 
1012
 
 
1013
        st.greet()
 
1014
        send(st)
 
1015
        gf := st.wantGoAway()
 
1016
        if gf.ErrCode != ErrCodeProtocol {
 
1017
                t.Errorf("err code = %v; want %v", gf.ErrCode, ErrCodeProtocol)
 
1018
        }
 
1019
}
 
1020
 
 
1021
// Section 5.1, on idle connections: "Receiving any frame other than
 
1022
// HEADERS or PRIORITY on a stream in this state MUST be treated as a
 
1023
// connection error (Section 5.4.1) of type PROTOCOL_ERROR."
 
1024
func TestRejectFrameOnIdle_WindowUpdate(t *testing.T) {
 
1025
        testRejectRequestWithProtocolError(t, func(st *serverTester) {
 
1026
                st.fr.WriteWindowUpdate(123, 456)
 
1027
        })
 
1028
}
 
1029
func TestRejectFrameOnIdle_Data(t *testing.T) {
 
1030
        testRejectRequestWithProtocolError(t, func(st *serverTester) {
 
1031
                st.fr.WriteData(123, true, nil)
 
1032
        })
 
1033
}
 
1034
func TestRejectFrameOnIdle_RSTStream(t *testing.T) {
 
1035
        testRejectRequestWithProtocolError(t, func(st *serverTester) {
 
1036
                st.fr.WriteRSTStream(123, ErrCodeCancel)
 
1037
        })
 
1038
}
 
1039
 
949
1040
func TestServer_Request_Connect(t *testing.T) {
950
1041
        testServerRequest(t, func(st *serverTester) {
951
1042
                st.writeHeaders(HeadersFrameParam{
1044
1135
        if gf.ErrCode != ErrCodeFrameSize {
1045
1136
                t.Errorf("GOAWAY err = %v; want %v", gf.ErrCode, ErrCodeFrameSize)
1046
1137
        }
1047
 
        if st.logBuf.Len() != 0 {
 
1138
        if st.serverLogBuf.Len() != 0 {
1048
1139
                // Previously we spun here for a bit until the GOAWAY disconnect
1049
1140
                // timer fired, logging while we fired.
1050
 
                t.Errorf("unexpected server output: %.500s\n", st.logBuf.Bytes())
 
1141
                t.Errorf("unexpected server output: %.500s\n", st.serverLogBuf.Bytes())
1051
1142
        }
1052
1143
}
1053
1144
 
1171
1262
                inHandler <- true
1172
1263
                errc <- handler(w, r)
1173
1264
        })
 
1265
        defer st.Close()
1174
1266
        st.greet()
1175
1267
        st.writeHeaders(HeadersFrameParam{
1176
1268
                StreamID:      1,
1188
1280
        case <-time.After(5 * time.Second):
1189
1281
                t.Fatal("timeout waiting for Handler to return")
1190
1282
        }
1191
 
        st.Close()
1192
1283
}
1193
1284
 
1194
1285
func TestServer_RSTStream_Unblocks_Read(t *testing.T) {
1445
1536
        })
1446
1537
}
1447
1538
 
 
1539
// No PRIORITY on stream 0.
 
1540
func TestServer_Rejects_Priority0(t *testing.T) {
 
1541
        testServerRejectsConn(t, func(st *serverTester) {
 
1542
                st.fr.AllowIllegalWrites = true
 
1543
                st.writePriority(0, PriorityParam{StreamDep: 1})
 
1544
        })
 
1545
}
 
1546
 
 
1547
// No HEADERS frame with a self-dependence.
 
1548
func TestServer_Rejects_HeadersSelfDependence(t *testing.T) {
 
1549
        testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
 
1550
                st.fr.AllowIllegalWrites = true
 
1551
                st.writeHeaders(HeadersFrameParam{
 
1552
                        StreamID:      1,
 
1553
                        BlockFragment: st.encodeHeader(),
 
1554
                        EndStream:     true,
 
1555
                        EndHeaders:    true,
 
1556
                        Priority:      PriorityParam{StreamDep: 1},
 
1557
                })
 
1558
        })
 
1559
}
 
1560
 
 
1561
// No PRIORTY frame with a self-dependence.
 
1562
func TestServer_Rejects_PrioritySelfDependence(t *testing.T) {
 
1563
        testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
 
1564
                st.fr.AllowIllegalWrites = true
 
1565
                st.writePriority(1, PriorityParam{StreamDep: 1})
 
1566
        })
 
1567
}
 
1568
 
1448
1569
func TestServer_Rejects_PushPromise(t *testing.T) {
1449
1570
        testServerRejectsConn(t, func(st *serverTester) {
1450
1571
                pp := PushPromiseParam{
2840
2961
 
2841
2962
        const msg = "Hello, world"
2842
2963
        st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
 
2964
                // Consume the (empty) body from th peer before replying, otherwise
 
2965
                // the server will sometimes (depending on scheduling) send the peer a
 
2966
                // a RST_STREAM with the CANCEL error code.
 
2967
                if n, err := io.Copy(ioutil.Discard, r.Body); n != 0 || err != nil {
 
2968
                        b.Errorf("Copy error; got %v, %v; want 0, nil", n, err)
 
2969
                }
2843
2970
                io.WriteString(w, msg)
2844
2971
        })
2845
2972
        defer st.Close()
3236
3363
 
3237
3364
func TestCheckValidHTTP2Request(t *testing.T) {
3238
3365
        tests := []struct {
3239
 
                req  *http.Request
 
3366
                h    http.Header
3240
3367
                want error
3241
3368
        }{
3242
3369
                {
3243
 
                        req:  &http.Request{Header: http.Header{"Te": {"trailers"}}},
 
3370
                        h:    http.Header{"Te": {"trailers"}},
3244
3371
                        want: nil,
3245
3372
                },
3246
3373
                {
3247
 
                        req:  &http.Request{Header: http.Header{"Te": {"trailers", "bogus"}}},
 
3374
                        h:    http.Header{"Te": {"trailers", "bogus"}},
3248
3375
                        want: errors.New(`request header "TE" may only be "trailers" in HTTP/2`),
3249
3376
                },
3250
3377
                {
3251
 
                        req:  &http.Request{Header: http.Header{"Foo": {""}}},
 
3378
                        h:    http.Header{"Foo": {""}},
3252
3379
                        want: nil,
3253
3380
                },
3254
3381
                {
3255
 
                        req:  &http.Request{Header: http.Header{"Connection": {""}}},
 
3382
                        h:    http.Header{"Connection": {""}},
3256
3383
                        want: errors.New(`request header "Connection" is not valid in HTTP/2`),
3257
3384
                },
3258
3385
                {
3259
 
                        req:  &http.Request{Header: http.Header{"Proxy-Connection": {""}}},
 
3386
                        h:    http.Header{"Proxy-Connection": {""}},
3260
3387
                        want: errors.New(`request header "Proxy-Connection" is not valid in HTTP/2`),
3261
3388
                },
3262
3389
                {
3263
 
                        req:  &http.Request{Header: http.Header{"Keep-Alive": {""}}},
 
3390
                        h:    http.Header{"Keep-Alive": {""}},
3264
3391
                        want: errors.New(`request header "Keep-Alive" is not valid in HTTP/2`),
3265
3392
                },
3266
3393
                {
3267
 
                        req:  &http.Request{Header: http.Header{"Upgrade": {""}}},
 
3394
                        h:    http.Header{"Upgrade": {""}},
3268
3395
                        want: errors.New(`request header "Upgrade" is not valid in HTTP/2`),
3269
3396
                },
3270
3397
        }
3271
3398
        for i, tt := range tests {
3272
 
                got := checkValidHTTP2Request(tt.req)
 
3399
                got := checkValidHTTP2RequestHeaders(tt.h)
3273
3400
                if !reflect.DeepEqual(got, tt.want) {
3274
3401
                        t.Errorf("%d. checkValidHTTP2Request = %v; want %v", i, got, tt.want)
3275
3402
                }
3366
3493
        }
3367
3494
 
3368
3495
}
 
3496
 
 
3497
func TestServerIdleTimeout(t *testing.T) {
 
3498
        if testing.Short() {
 
3499
                t.Skip("skipping in short mode")
 
3500
        }
 
3501
 
 
3502
        st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
 
3503
        }, func(h2s *Server) {
 
3504
                h2s.IdleTimeout = 500 * time.Millisecond
 
3505
        })
 
3506
        defer st.Close()
 
3507
 
 
3508
        st.greet()
 
3509
        ga := st.wantGoAway()
 
3510
        if ga.ErrCode != ErrCodeNo {
 
3511
                t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode)
 
3512
        }
 
3513
}
 
3514
 
 
3515
func TestServerIdleTimeout_AfterRequest(t *testing.T) {
 
3516
        if testing.Short() {
 
3517
                t.Skip("skipping in short mode")
 
3518
        }
 
3519
        const timeout = 250 * time.Millisecond
 
3520
 
 
3521
        st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
 
3522
                time.Sleep(timeout * 2)
 
3523
        }, func(h2s *Server) {
 
3524
                h2s.IdleTimeout = timeout
 
3525
        })
 
3526
        defer st.Close()
 
3527
 
 
3528
        st.greet()
 
3529
 
 
3530
        // Send a request which takes twice the timeout. Verifies the
 
3531
        // idle timeout doesn't fire while we're in a request:
 
3532
        st.bodylessReq1()
 
3533
        st.wantHeaders()
 
3534
 
 
3535
        // But the idle timeout should be rearmed after the request
 
3536
        // is done:
 
3537
        ga := st.wantGoAway()
 
3538
        if ga.ErrCode != ErrCodeNo {
 
3539
                t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode)
 
3540
        }
 
3541
}
 
3542
 
 
3543
// grpc-go closes the Request.Body currently with a Read.
 
3544
// Verify that it doesn't race.
 
3545
// See https://github.com/grpc/grpc-go/pull/938
 
3546
func TestRequestBodyReadCloseRace(t *testing.T) {
 
3547
        for i := 0; i < 100; i++ {
 
3548
                body := &requestBody{
 
3549
                        pipe: &pipe{
 
3550
                                b: new(bytes.Buffer),
 
3551
                        },
 
3552
                }
 
3553
                body.pipe.CloseWithError(io.EOF)
 
3554
 
 
3555
                done := make(chan bool, 1)
 
3556
                buf := make([]byte, 10)
 
3557
                go func() {
 
3558
                        time.Sleep(1 * time.Millisecond)
 
3559
                        body.Close()
 
3560
                        done <- true
 
3561
                }()
 
3562
                body.Read(buf)
 
3563
                <-done
 
3564
        }
 
3565
}
 
3566
 
 
3567
func TestServerGracefulShutdown(t *testing.T) {
 
3568
        shutdownCh := make(chan struct{})
 
3569
        defer func() { testh1ServerShutdownChan = nil }()
 
3570
        testh1ServerShutdownChan = func(*http.Server) <-chan struct{} { return shutdownCh }
 
3571
 
 
3572
        var st *serverTester
 
3573
        handlerDone := make(chan struct{})
 
3574
        st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
 
3575
                defer close(handlerDone)
 
3576
                close(shutdownCh)
 
3577
 
 
3578
                ga := st.wantGoAway()
 
3579
                if ga.ErrCode != ErrCodeNo {
 
3580
                        t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode)
 
3581
                }
 
3582
                if ga.LastStreamID != 1 {
 
3583
                        t.Errorf("GOAWAY LastStreamID = %v; want 1", ga.LastStreamID)
 
3584
                }
 
3585
 
 
3586
                w.Header().Set("x-foo", "bar")
 
3587
        })
 
3588
        defer st.Close()
 
3589
 
 
3590
        st.greet()
 
3591
        st.bodylessReq1()
 
3592
 
 
3593
        <-handlerDone
 
3594
        hf := st.wantHeaders()
 
3595
        goth := st.decodeHeader(hf.HeaderBlockFragment())
 
3596
        wanth := [][2]string{
 
3597
                {":status", "200"},
 
3598
                {"x-foo", "bar"},
 
3599
                {"content-type", "text/plain; charset=utf-8"},
 
3600
                {"content-length", "0"},
 
3601
        }
 
3602
        if !reflect.DeepEqual(goth, wanth) {
 
3603
                t.Errorf("Got headers %v; want %v", goth, wanth)
 
3604
        }
 
3605
 
 
3606
        n, err := st.cc.Read([]byte{0})
 
3607
        if n != 0 || err == nil {
 
3608
                t.Errorf("Read = %v, %v; want 0, non-nil", n, err)
 
3609
        }
 
3610
}