~hduran-8/+junk/caddy

« back to all changes in this revision

Viewing changes to debian/gocode/src/golang.org/x/net/http2/server.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:
2
2
// Use of this source code is governed by a BSD-style
3
3
// license that can be found in the LICENSE file.
4
4
 
5
 
// TODO: replace all <-sc.doneServing with reads from the stream's cw
6
 
// instead, and make sure that on close we close all open
7
 
// streams. then remove doneServing?
8
 
 
9
 
// TODO: re-audit GOAWAY support. Consider each incoming frame type and
10
 
// whether it should be ignored during graceful shutdown.
11
 
 
12
 
// TODO: disconnect idle clients. GFE seems to do 4 minutes. make
13
 
// configurable?  or maximum number of idle clients and remove the
14
 
// oldest?
15
 
 
16
5
// TODO: turn off the serve goroutine when idle, so
17
6
// an idle conn only has the readFrames goroutine active. (which could
18
7
// also be optimized probably to pin less memory in crypto/tls). This
44
33
        "fmt"
45
34
        "io"
46
35
        "log"
 
36
        "math"
47
37
        "net"
48
38
        "net/http"
49
39
        "net/textproto"
114
104
        // PermitProhibitedCipherSuites, if true, permits the use of
115
105
        // cipher suites prohibited by the HTTP/2 spec.
116
106
        PermitProhibitedCipherSuites bool
 
107
 
 
108
        // IdleTimeout specifies how long until idle clients should be
 
109
        // closed with a GOAWAY frame. PING frames are not considered
 
110
        // activity for the purposes of IdleTimeout.
 
111
        IdleTimeout time.Duration
 
112
 
 
113
        // NewWriteScheduler constructs a write scheduler for a connection.
 
114
        // If nil, a default scheduler is chosen.
 
115
        NewWriteScheduler func() WriteScheduler
117
116
}
118
117
 
119
118
func (s *Server) maxReadFrameSize() uint32 {
136
135
//
137
136
// ConfigureServer must be called before s begins serving.
138
137
func ConfigureServer(s *http.Server, conf *Server) error {
 
138
        if s == nil {
 
139
                panic("nil *http.Server")
 
140
        }
139
141
        if conf == nil {
140
142
                conf = new(Server)
141
143
        }
 
144
        if err := configureServer18(s, conf); err != nil {
 
145
                return err
 
146
        }
142
147
 
143
148
        if s.TLSConfig == nil {
144
149
                s.TLSConfig = new(tls.Config)
183
188
        if !haveNPN {
184
189
                s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)
185
190
        }
186
 
        // h2-14 is temporary (as of 2015-03-05) while we wait for all browsers
187
 
        // to switch to "h2".
188
 
        s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "h2-14")
189
191
 
190
192
        if s.TLSNextProto == nil {
191
193
                s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}
200
202
                })
201
203
        }
202
204
        s.TLSNextProto[NextProtoTLS] = protoHandler
203
 
        s.TLSNextProto["h2-14"] = protoHandler // temporary; see above.
204
205
        return nil
205
206
}
206
207
 
254
255
        defer cancel()
255
256
 
256
257
        sc := &serverConn{
257
 
                srv:              s,
258
 
                hs:               opts.baseConfig(),
259
 
                conn:             c,
260
 
                baseCtx:          baseCtx,
261
 
                remoteAddrStr:    c.RemoteAddr().String(),
262
 
                bw:               newBufferedWriter(c),
263
 
                handler:          opts.handler(),
264
 
                streams:          make(map[uint32]*stream),
265
 
                readFrameCh:      make(chan readFrameResult),
266
 
                wantWriteFrameCh: make(chan frameWriteMsg, 8),
267
 
                wroteFrameCh:     make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
268
 
                bodyReadCh:       make(chan bodyReadMsg),         // buffering doesn't matter either way
269
 
                doneServing:      make(chan struct{}),
270
 
                advMaxStreams:    s.maxConcurrentStreams(),
271
 
                writeSched: writeScheduler{
272
 
                        maxFrameSize: initialMaxFrameSize,
273
 
                },
 
258
                srv:               s,
 
259
                hs:                opts.baseConfig(),
 
260
                conn:              c,
 
261
                baseCtx:           baseCtx,
 
262
                remoteAddrStr:     c.RemoteAddr().String(),
 
263
                bw:                newBufferedWriter(c),
 
264
                handler:           opts.handler(),
 
265
                streams:           make(map[uint32]*stream),
 
266
                readFrameCh:       make(chan readFrameResult),
 
267
                wantWriteFrameCh:  make(chan FrameWriteRequest, 8),
 
268
                wantStartPushCh:   make(chan startPushRequest, 8),
 
269
                wroteFrameCh:      make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync
 
270
                bodyReadCh:        make(chan bodyReadMsg),         // buffering doesn't matter either way
 
271
                doneServing:       make(chan struct{}),
 
272
                clientMaxStreams:  math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value"
 
273
                advMaxStreams:     s.maxConcurrentStreams(),
274
274
                initialWindowSize: initialWindowSize,
 
275
                maxFrameSize:      initialMaxFrameSize,
275
276
                headerTableSize:   initialHeaderTableSize,
276
277
                serveG:            newGoroutineLock(),
277
278
                pushEnabled:       true,
278
279
        }
279
280
 
 
281
        // The net/http package sets the write deadline from the
 
282
        // http.Server.WriteTimeout during the TLS handshake, but then
 
283
        // passes the connection off to us with the deadline already
 
284
        // set. Disarm it here so that it is not applied to additional
 
285
        // streams opened on this connection.
 
286
        // TODO: implement WriteTimeout fully. See Issue 18437.
 
287
        if sc.hs.WriteTimeout != 0 {
 
288
                sc.conn.SetWriteDeadline(time.Time{})
 
289
        }
 
290
 
 
291
        if s.NewWriteScheduler != nil {
 
292
                sc.writeSched = s.NewWriteScheduler()
 
293
        } else {
 
294
                sc.writeSched = NewRandomWriteScheduler()
 
295
        }
 
296
 
280
297
        sc.flow.add(initialWindowSize)
281
298
        sc.inflow.add(initialWindowSize)
282
299
        sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
356
373
        handler          http.Handler
357
374
        baseCtx          contextContext
358
375
        framer           *Framer
359
 
        doneServing      chan struct{}         // closed when serverConn.serve ends
360
 
        readFrameCh      chan readFrameResult  // written by serverConn.readFrames
361
 
        wantWriteFrameCh chan frameWriteMsg    // from handlers -> serve
362
 
        wroteFrameCh     chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
363
 
        bodyReadCh       chan bodyReadMsg      // from handlers -> serve
364
 
        testHookCh       chan func(int)        // code to run on the serve loop
365
 
        flow             flow                  // conn-wide (not stream-specific) outbound flow control
366
 
        inflow           flow                  // conn-wide inbound flow control
367
 
        tlsState         *tls.ConnectionState  // shared by all handlers, like net/http
 
376
        doneServing      chan struct{}          // closed when serverConn.serve ends
 
377
        readFrameCh      chan readFrameResult   // written by serverConn.readFrames
 
378
        wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve
 
379
        wantStartPushCh  chan startPushRequest  // from handlers -> serve
 
380
        wroteFrameCh     chan frameWriteResult  // from writeFrameAsync -> serve, tickles more frame writes
 
381
        bodyReadCh       chan bodyReadMsg       // from handlers -> serve
 
382
        testHookCh       chan func(int)         // code to run on the serve loop
 
383
        flow             flow                   // conn-wide (not stream-specific) outbound flow control
 
384
        inflow           flow                   // conn-wide inbound flow control
 
385
        tlsState         *tls.ConnectionState   // shared by all handlers, like net/http
368
386
        remoteAddrStr    string
 
387
        writeSched       WriteScheduler
369
388
 
370
389
        // Everything following is owned by the serve loop; use serveG.check():
371
390
        serveG                goroutineLock // used to verify funcs are on serve()
375
394
        unackedSettings       int    // how many SETTINGS have we sent without ACKs?
376
395
        clientMaxStreams      uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
377
396
        advMaxStreams         uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
378
 
        curOpenStreams        uint32 // client's number of open streams
379
 
        maxStreamID           uint32 // max ever seen
 
397
        curClientStreams      uint32 // number of open streams initiated by the client
 
398
        curPushedStreams      uint32 // number of open streams initiated by server push
 
399
        maxClientStreamID     uint32 // max ever seen from client (odd), or 0 if there have been no client requests
 
400
        maxPushPromiseID      uint32 // ID of the last push promise (even), or 0 if there have been no pushes
380
401
        streams               map[uint32]*stream
381
402
        initialWindowSize     int32
 
403
        maxFrameSize          int32
382
404
        headerTableSize       uint32
383
405
        peerMaxHeaderListSize uint32            // zero means unknown (default)
384
406
        canonHeader           map[string]string // http2-lower-case -> Go-Canonical-Case
385
 
        writingFrame          bool              // started write goroutine but haven't heard back on wroteFrameCh
 
407
        writingFrame          bool              // started writing a frame (on serve goroutine or separate)
 
408
        writingFrameAsync     bool              // started a frame on its own goroutine but haven't heard back on wroteFrameCh
386
409
        needsFrameFlush       bool              // last frame write wasn't a flush
387
 
        writeSched            writeScheduler
388
 
        inGoAway              bool // we've started to or sent GOAWAY
389
 
        needToSendGoAway      bool // we need to schedule a GOAWAY frame write
 
410
        inGoAway              bool              // we've started to or sent GOAWAY
 
411
        inFrameScheduleLoop   bool              // whether we're in the scheduleFrameWrite loop
 
412
        needToSendGoAway      bool              // we need to schedule a GOAWAY frame write
390
413
        goAwayCode            ErrCode
391
414
        shutdownTimerCh       <-chan time.Time // nil until used
392
415
        shutdownTimer         *time.Timer      // nil until used
393
 
        freeRequestBodyBuf    []byte           // if non-nil, a free initialWindowSize buffer for getRequestBodyBuf
 
416
        idleTimer             *time.Timer      // nil if unused
 
417
        idleTimerCh           <-chan time.Time // nil if unused
394
418
 
395
419
        // Owned by the writeFrameAsync goroutine:
396
420
        headerWriteBuf bytes.Buffer
409
433
        return uint32(n + typicalHeaders*perFieldOverhead)
410
434
}
411
435
 
 
436
func (sc *serverConn) curOpenStreams() uint32 {
 
437
        sc.serveG.check()
 
438
        return sc.curClientStreams + sc.curPushedStreams
 
439
}
 
440
 
412
441
// stream represents a stream. This is the minimal metadata needed by
413
442
// the serve goroutine. Most of the actual stream state is owned by
414
443
// the http.Handler's goroutine in the responseWriter. Because the
434
463
        numTrailerValues int64
435
464
        weight           uint8
436
465
        state            streamState
437
 
        sentReset        bool // only true once detached from streams map
438
 
        gotReset         bool // only true once detacted from streams map
439
 
        gotTrailerHeader bool // HEADER frame for trailers was seen
440
 
        wroteHeaders     bool // whether we wrote headers (not status 100)
441
 
        reqBuf           []byte
 
466
        resetQueued      bool   // RST_STREAM queued for write; set by sc.resetStream
 
467
        gotTrailerHeader bool   // HEADER frame for trailers was seen
 
468
        wroteHeaders     bool   // whether we wrote headers (not status 100)
 
469
        reqBuf           []byte // if non-nil, body pipe buffer to return later at EOF
442
470
 
443
471
        trailer    http.Header // accumulated trailers
444
472
        reqTrailer http.Header // handler's Request.Trailer
453
481
 
454
482
func (sc *serverConn) state(streamID uint32) (streamState, *stream) {
455
483
        sc.serveG.check()
456
 
        // http://http2.github.io/http2-spec/#rfc.section.5.1
 
484
        // http://tools.ietf.org/html/rfc7540#section-5.1
457
485
        if st, ok := sc.streams[streamID]; ok {
458
486
                return st.state, st
459
487
        }
463
491
        // a client sends a HEADERS frame on stream 7 without ever sending a
464
492
        // frame on stream 5, then stream 5 transitions to the "closed"
465
493
        // state when the first frame for stream 7 is sent or received."
466
 
        if streamID <= sc.maxStreamID {
467
 
                return stateClosed, nil
 
494
        if streamID%2 == 1 {
 
495
                if streamID <= sc.maxClientStreamID {
 
496
                        return stateClosed, nil
 
497
                }
 
498
        } else {
 
499
                if streamID <= sc.maxPushPromiseID {
 
500
                        return stateClosed, nil
 
501
                }
468
502
        }
469
503
        return stateIdle, nil
470
504
}
603
637
 
604
638
// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
605
639
type frameWriteResult struct {
606
 
        wm  frameWriteMsg // what was written (or attempted)
607
 
        err error         // result of the writeFrame call
 
640
        wr  FrameWriteRequest // what was written (or attempted)
 
641
        err error             // result of the writeFrame call
608
642
}
609
643
 
610
644
// writeFrameAsync runs in its own goroutine and writes a single frame
611
645
// and then reports when it's done.
612
646
// At most one goroutine can be running writeFrameAsync at a time per
613
647
// serverConn.
614
 
func (sc *serverConn) writeFrameAsync(wm frameWriteMsg) {
615
 
        err := wm.write.writeFrame(sc)
616
 
        sc.wroteFrameCh <- frameWriteResult{wm, err}
 
648
func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest) {
 
649
        err := wr.write.writeFrame(sc)
 
650
        sc.wroteFrameCh <- frameWriteResult{wr, err}
617
651
}
618
652
 
619
653
func (sc *serverConn) closeAllStreamsOnConnClose() {
657
691
                sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
658
692
        }
659
693
 
660
 
        sc.writeFrame(frameWriteMsg{
 
694
        sc.writeFrame(FrameWriteRequest{
661
695
                write: writeSettings{
662
696
                        {SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
663
697
                        {SettingMaxConcurrentStreams, sc.advMaxStreams},
682
716
        sc.setConnState(http.StateActive)
683
717
        sc.setConnState(http.StateIdle)
684
718
 
 
719
        if sc.srv.IdleTimeout != 0 {
 
720
                sc.idleTimer = time.NewTimer(sc.srv.IdleTimeout)
 
721
                defer sc.idleTimer.Stop()
 
722
                sc.idleTimerCh = sc.idleTimer.C
 
723
        }
 
724
 
 
725
        var gracefulShutdownCh <-chan struct{}
 
726
        if sc.hs != nil {
 
727
                gracefulShutdownCh = h1ServerShutdownChan(sc.hs)
 
728
        }
 
729
 
685
730
        go sc.readFrames() // closed by defer sc.conn.Close above
686
731
 
687
732
        settingsTimer := time.NewTimer(firstSettingsTimeout)
689
734
        for {
690
735
                loopNum++
691
736
                select {
692
 
                case wm := <-sc.wantWriteFrameCh:
693
 
                        sc.writeFrame(wm)
 
737
                case wr := <-sc.wantWriteFrameCh:
 
738
                        sc.writeFrame(wr)
 
739
                case spr := <-sc.wantStartPushCh:
 
740
                        sc.startPush(spr)
694
741
                case res := <-sc.wroteFrameCh:
695
742
                        sc.wroteFrame(res)
696
743
                case res := <-sc.readFrameCh:
707
754
                case <-settingsTimer.C:
708
755
                        sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr())
709
756
                        return
 
757
                case <-gracefulShutdownCh:
 
758
                        gracefulShutdownCh = nil
 
759
                        sc.startGracefulShutdown()
710
760
                case <-sc.shutdownTimerCh:
711
761
                        sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr())
712
762
                        return
 
763
                case <-sc.idleTimerCh:
 
764
                        sc.vlogf("connection is idle")
 
765
                        sc.goAway(ErrCodeNo)
713
766
                case fn := <-sc.testHookCh:
714
767
                        fn(loopNum)
715
768
                }
 
769
 
 
770
                if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame {
 
771
                        return
 
772
                }
716
773
        }
717
774
}
718
775
 
760
817
        ch := errChanPool.Get().(chan error)
761
818
        writeArg := writeDataPool.Get().(*writeData)
762
819
        *writeArg = writeData{stream.id, data, endStream}
763
 
        err := sc.writeFrameFromHandler(frameWriteMsg{
 
820
        err := sc.writeFrameFromHandler(FrameWriteRequest{
764
821
                write:  writeArg,
765
822
                stream: stream,
766
823
                done:   ch,
796
853
        return err
797
854
}
798
855
 
799
 
// writeFrameFromHandler sends wm to sc.wantWriteFrameCh, but aborts
 
856
// writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts
800
857
// if the connection has gone away.
801
858
//
802
859
// This must not be run from the serve goroutine itself, else it might
803
860
// deadlock writing to sc.wantWriteFrameCh (which is only mildly
804
861
// buffered and is read by serve itself). If you're on the serve
805
862
// goroutine, call writeFrame instead.
806
 
func (sc *serverConn) writeFrameFromHandler(wm frameWriteMsg) error {
 
863
func (sc *serverConn) writeFrameFromHandler(wr FrameWriteRequest) error {
807
864
        sc.serveG.checkNotOn() // NOT
808
865
        select {
809
 
        case sc.wantWriteFrameCh <- wm:
 
866
        case sc.wantWriteFrameCh <- wr:
810
867
                return nil
811
868
        case <-sc.doneServing:
812
869
                // Serve loop is gone.
823
880
// make it onto the wire
824
881
//
825
882
// If you're not on the serve goroutine, use writeFrameFromHandler instead.
826
 
func (sc *serverConn) writeFrame(wm frameWriteMsg) {
 
883
func (sc *serverConn) writeFrame(wr FrameWriteRequest) {
827
884
        sc.serveG.check()
828
885
 
 
886
        // If true, wr will not be written and wr.done will not be signaled.
829
887
        var ignoreWrite bool
830
888
 
 
889
        // We are not allowed to write frames on closed streams. RFC 7540 Section
 
890
        // 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on
 
891
        // a closed stream." Our server never sends PRIORITY, so that exception
 
892
        // does not apply.
 
893
        //
 
894
        // The serverConn might close an open stream while the stream's handler
 
895
        // is still running. For example, the server might close a stream when it
 
896
        // receives bad data from the client. If this happens, the handler might
 
897
        // attempt to write a frame after the stream has been closed (since the
 
898
        // handler hasn't yet been notified of the close). In this case, we simply
 
899
        // ignore the frame. The handler will notice that the stream is closed when
 
900
        // it waits for the frame to be written.
 
901
        //
 
902
        // As an exception to this rule, we allow sending RST_STREAM after close.
 
903
        // This allows us to immediately reject new streams without tracking any
 
904
        // state for those streams (except for the queued RST_STREAM frame). This
 
905
        // may result in duplicate RST_STREAMs in some cases, but the client should
 
906
        // ignore those.
 
907
        if wr.StreamID() != 0 {
 
908
                _, isReset := wr.write.(StreamError)
 
909
                if state, _ := sc.state(wr.StreamID()); state == stateClosed && !isReset {
 
910
                        ignoreWrite = true
 
911
                }
 
912
        }
 
913
 
831
914
        // Don't send a 100-continue response if we've already sent headers.
832
915
        // See golang.org/issue/14030.
833
 
        switch wm.write.(type) {
 
916
        switch wr.write.(type) {
834
917
        case *writeResHeaders:
835
 
                wm.stream.wroteHeaders = true
 
918
                wr.stream.wroteHeaders = true
836
919
        case write100ContinueHeadersFrame:
837
 
                if wm.stream.wroteHeaders {
 
920
                if wr.stream.wroteHeaders {
 
921
                        // We do not need to notify wr.done because this frame is
 
922
                        // never written with wr.done != nil.
 
923
                        if wr.done != nil {
 
924
                                panic("wr.done != nil for write100ContinueHeadersFrame")
 
925
                        }
838
926
                        ignoreWrite = true
839
927
                }
840
928
        }
841
929
 
842
930
        if !ignoreWrite {
843
 
                sc.writeSched.add(wm)
 
931
                sc.writeSched.Push(wr)
844
932
        }
845
933
        sc.scheduleFrameWrite()
846
934
}
847
935
 
848
 
// startFrameWrite starts a goroutine to write wm (in a separate
 
936
// startFrameWrite starts a goroutine to write wr (in a separate
849
937
// goroutine since that might block on the network), and updates the
850
 
// serve goroutine's state about the world, updated from info in wm.
851
 
func (sc *serverConn) startFrameWrite(wm frameWriteMsg) {
 
938
// serve goroutine's state about the world, updated from info in wr.
 
939
func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {
852
940
        sc.serveG.check()
853
941
        if sc.writingFrame {
854
942
                panic("internal error: can only be writing one frame at a time")
855
943
        }
856
944
 
857
 
        st := wm.stream
 
945
        st := wr.stream
858
946
        if st != nil {
859
947
                switch st.state {
860
948
                case stateHalfClosedLocal:
861
 
                        panic("internal error: attempt to send frame on half-closed-local stream")
 
949
                        switch wr.write.(type) {
 
950
                        case StreamError, handlerPanicRST, writeWindowUpdate:
 
951
                                // RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE
 
952
                                // in this state. (We never send PRIORITY from the server, so that is not checked.)
 
953
                        default:
 
954
                                panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", wr))
 
955
                        }
862
956
                case stateClosed:
863
 
                        if st.sentReset || st.gotReset {
864
 
                                // Skip this frame.
865
 
                                sc.scheduleFrameWrite()
866
 
                                return
867
 
                        }
868
 
                        panic(fmt.Sprintf("internal error: attempt to send a write %v on a closed stream", wm))
 
957
                        panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", wr))
 
958
                }
 
959
        }
 
960
        if wpp, ok := wr.write.(*writePushPromise); ok {
 
961
                var err error
 
962
                wpp.promisedID, err = wpp.allocatePromisedID()
 
963
                if err != nil {
 
964
                        sc.writingFrameAsync = false
 
965
                        wr.replyToWriter(err)
 
966
                        return
869
967
                }
870
968
        }
871
969
 
872
970
        sc.writingFrame = true
873
971
        sc.needsFrameFlush = true
874
 
        go sc.writeFrameAsync(wm)
 
972
        if wr.write.staysWithinBuffer(sc.bw.Available()) {
 
973
                sc.writingFrameAsync = false
 
974
                err := wr.write.writeFrame(sc)
 
975
                sc.wroteFrame(frameWriteResult{wr, err})
 
976
        } else {
 
977
                sc.writingFrameAsync = true
 
978
                go sc.writeFrameAsync(wr)
 
979
        }
875
980
}
876
981
 
877
982
// errHandlerPanicked is the error given to any callers blocked in a read from
887
992
                panic("internal error: expected to be already writing a frame")
888
993
        }
889
994
        sc.writingFrame = false
890
 
 
891
 
        wm := res.wm
892
 
        st := wm.stream
893
 
 
894
 
        closeStream := endsStream(wm.write)
895
 
 
896
 
        if _, ok := wm.write.(handlerPanicRST); ok {
897
 
                sc.closeStream(st, errHandlerPanicked)
898
 
        }
899
 
 
900
 
        // Reply (if requested) to the blocked ServeHTTP goroutine.
901
 
        if ch := wm.done; ch != nil {
902
 
                select {
903
 
                case ch <- res.err:
904
 
                default:
905
 
                        panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wm.write))
906
 
                }
907
 
        }
908
 
        wm.write = nil // prevent use (assume it's tainted after wm.done send)
909
 
 
910
 
        if closeStream {
 
995
        sc.writingFrameAsync = false
 
996
 
 
997
        wr := res.wr
 
998
 
 
999
        if writeEndsStream(wr.write) {
 
1000
                st := wr.stream
911
1001
                if st == nil {
912
1002
                        panic("internal error: expecting non-nil stream")
913
1003
                }
916
1006
                        // Here we would go to stateHalfClosedLocal in
917
1007
                        // theory, but since our handler is done and
918
1008
                        // the net/http package provides no mechanism
919
 
                        // for finishing writing to a ResponseWriter
920
 
                        // while still reading data (see possible TODO
921
 
                        // at top of this file), we go into closed
922
 
                        // state here anyway, after telling the peer
923
 
                        // we're hanging up on them.
924
 
                        st.state = stateHalfClosedLocal // won't last long, but necessary for closeStream via resetStream
925
 
                        errCancel := streamError(st.id, ErrCodeCancel)
926
 
                        sc.resetStream(errCancel)
 
1009
                        // for closing a ResponseWriter while still
 
1010
                        // reading data (see possible TODO at top of
 
1011
                        // this file), we go into closed state here
 
1012
                        // anyway, after telling the peer we're
 
1013
                        // hanging up on them. We'll transition to
 
1014
                        // stateClosed after the RST_STREAM frame is
 
1015
                        // written.
 
1016
                        st.state = stateHalfClosedLocal
 
1017
                        sc.resetStream(streamError(st.id, ErrCodeCancel))
927
1018
                case stateHalfClosedRemote:
928
1019
                        sc.closeStream(st, errHandlerComplete)
929
1020
                }
 
1021
        } else {
 
1022
                switch v := wr.write.(type) {
 
1023
                case StreamError:
 
1024
                        // st may be unknown if the RST_STREAM was generated to reject bad input.
 
1025
                        if st, ok := sc.streams[v.StreamID]; ok {
 
1026
                                sc.closeStream(st, v)
 
1027
                        }
 
1028
                case handlerPanicRST:
 
1029
                        sc.closeStream(wr.stream, errHandlerPanicked)
 
1030
                }
930
1031
        }
931
1032
 
 
1033
        // Reply (if requested) to unblock the ServeHTTP goroutine.
 
1034
        wr.replyToWriter(res.err)
 
1035
 
932
1036
        sc.scheduleFrameWrite()
933
1037
}
934
1038
 
946
1050
// flush the write buffer.
947
1051
func (sc *serverConn) scheduleFrameWrite() {
948
1052
        sc.serveG.check()
949
 
        if sc.writingFrame {
950
 
                return
951
 
        }
952
 
        if sc.needToSendGoAway {
953
 
                sc.needToSendGoAway = false
954
 
                sc.startFrameWrite(frameWriteMsg{
955
 
                        write: &writeGoAway{
956
 
                                maxStreamID: sc.maxStreamID,
957
 
                                code:        sc.goAwayCode,
958
 
                        },
959
 
                })
960
 
                return
961
 
        }
962
 
        if sc.needToSendSettingsAck {
963
 
                sc.needToSendSettingsAck = false
964
 
                sc.startFrameWrite(frameWriteMsg{write: writeSettingsAck{}})
965
 
                return
966
 
        }
967
 
        if !sc.inGoAway {
968
 
                if wm, ok := sc.writeSched.take(); ok {
969
 
                        sc.startFrameWrite(wm)
970
 
                        return
971
 
                }
972
 
        }
973
 
        if sc.needsFrameFlush {
974
 
                sc.startFrameWrite(frameWriteMsg{write: flushFrameWriter{}})
975
 
                sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
976
 
                return
977
 
        }
 
1053
        if sc.writingFrame || sc.inFrameScheduleLoop {
 
1054
                return
 
1055
        }
 
1056
        sc.inFrameScheduleLoop = true
 
1057
        for !sc.writingFrameAsync {
 
1058
                if sc.needToSendGoAway {
 
1059
                        sc.needToSendGoAway = false
 
1060
                        sc.startFrameWrite(FrameWriteRequest{
 
1061
                                write: &writeGoAway{
 
1062
                                        maxStreamID: sc.maxClientStreamID,
 
1063
                                        code:        sc.goAwayCode,
 
1064
                                },
 
1065
                        })
 
1066
                        continue
 
1067
                }
 
1068
                if sc.needToSendSettingsAck {
 
1069
                        sc.needToSendSettingsAck = false
 
1070
                        sc.startFrameWrite(FrameWriteRequest{write: writeSettingsAck{}})
 
1071
                        continue
 
1072
                }
 
1073
                if !sc.inGoAway || sc.goAwayCode == ErrCodeNo {
 
1074
                        if wr, ok := sc.writeSched.Pop(); ok {
 
1075
                                sc.startFrameWrite(wr)
 
1076
                                continue
 
1077
                        }
 
1078
                }
 
1079
                if sc.needsFrameFlush {
 
1080
                        sc.startFrameWrite(FrameWriteRequest{write: flushFrameWriter{}})
 
1081
                        sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
 
1082
                        continue
 
1083
                }
 
1084
                break
 
1085
        }
 
1086
        sc.inFrameScheduleLoop = false
 
1087
}
 
1088
 
 
1089
// startGracefulShutdown sends a GOAWAY with ErrCodeNo to tell the
 
1090
// client we're gracefully shutting down. The connection isn't closed
 
1091
// until all current streams are done.
 
1092
func (sc *serverConn) startGracefulShutdown() {
 
1093
        sc.goAwayIn(ErrCodeNo, 0)
978
1094
}
979
1095
 
980
1096
func (sc *serverConn) goAway(code ErrCode) {
981
1097
        sc.serveG.check()
982
 
        if sc.inGoAway {
983
 
                return
984
 
        }
 
1098
        var forceCloseIn time.Duration
985
1099
        if code != ErrCodeNo {
986
 
                sc.shutDownIn(250 * time.Millisecond)
 
1100
                forceCloseIn = 250 * time.Millisecond
987
1101
        } else {
988
1102
                // TODO: configurable
989
 
                sc.shutDownIn(1 * time.Second)
 
1103
                forceCloseIn = 1 * time.Second
 
1104
        }
 
1105
        sc.goAwayIn(code, forceCloseIn)
 
1106
}
 
1107
 
 
1108
func (sc *serverConn) goAwayIn(code ErrCode, forceCloseIn time.Duration) {
 
1109
        sc.serveG.check()
 
1110
        if sc.inGoAway {
 
1111
                return
 
1112
        }
 
1113
        if forceCloseIn != 0 {
 
1114
                sc.shutDownIn(forceCloseIn)
990
1115
        }
991
1116
        sc.inGoAway = true
992
1117
        sc.needToSendGoAway = true
1002
1127
 
1003
1128
func (sc *serverConn) resetStream(se StreamError) {
1004
1129
        sc.serveG.check()
1005
 
        sc.writeFrame(frameWriteMsg{write: se})
 
1130
        sc.writeFrame(FrameWriteRequest{write: se})
1006
1131
        if st, ok := sc.streams[se.StreamID]; ok {
1007
 
                st.sentReset = true
1008
 
                sc.closeStream(st, se)
 
1132
                st.resetQueued = true
1009
1133
        }
1010
1134
}
1011
1135
 
1090
1214
                return sc.processResetStream(f)
1091
1215
        case *PriorityFrame:
1092
1216
                return sc.processPriority(f)
 
1217
        case *GoAwayFrame:
 
1218
                return sc.processGoAway(f)
1093
1219
        case *PushPromiseFrame:
1094
1220
                // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
1095
1221
                // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
1115
1241
                // PROTOCOL_ERROR."
1116
1242
                return ConnectionError(ErrCodeProtocol)
1117
1243
        }
1118
 
        sc.writeFrame(frameWriteMsg{write: writePingAck{f}})
 
1244
        if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
 
1245
                return nil
 
1246
        }
 
1247
        sc.writeFrame(FrameWriteRequest{write: writePingAck{f}})
1119
1248
        return nil
1120
1249
}
1121
1250
 
1123
1252
        sc.serveG.check()
1124
1253
        switch {
1125
1254
        case f.StreamID != 0: // stream-level flow control
1126
 
                st := sc.streams[f.StreamID]
 
1255
                state, st := sc.state(f.StreamID)
 
1256
                if state == stateIdle {
 
1257
                        // Section 5.1: "Receiving any frame other than HEADERS
 
1258
                        // or PRIORITY on a stream in this state MUST be
 
1259
                        // treated as a connection error (Section 5.4.1) of
 
1260
                        // type PROTOCOL_ERROR."
 
1261
                        return ConnectionError(ErrCodeProtocol)
 
1262
                }
1127
1263
                if st == nil {
1128
1264
                        // "WINDOW_UPDATE can be sent by a peer that has sent a
1129
1265
                        // frame bearing the END_STREAM flag. This means that a
1157
1293
                return ConnectionError(ErrCodeProtocol)
1158
1294
        }
1159
1295
        if st != nil {
1160
 
                st.gotReset = true
1161
1296
                st.cancelCtx()
1162
1297
                sc.closeStream(st, streamError(f.StreamID, f.ErrCode))
1163
1298
        }
1170
1305
                panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
1171
1306
        }
1172
1307
        st.state = stateClosed
1173
 
        sc.curOpenStreams--
1174
 
        if sc.curOpenStreams == 0 {
 
1308
        if st.isPushed() {
 
1309
                sc.curPushedStreams--
 
1310
        } else {
 
1311
                sc.curClientStreams--
 
1312
        }
 
1313
        delete(sc.streams, st.id)
 
1314
        if len(sc.streams) == 0 {
1175
1315
                sc.setConnState(http.StateIdle)
 
1316
                if sc.srv.IdleTimeout != 0 {
 
1317
                        sc.idleTimer.Reset(sc.srv.IdleTimeout)
 
1318
                }
 
1319
                if h1ServerKeepAlivesDisabled(sc.hs) {
 
1320
                        sc.startGracefulShutdown()
 
1321
                }
1176
1322
        }
1177
 
        delete(sc.streams, st.id)
1178
1323
        if p := st.body; p != nil {
1179
1324
                // Return any buffered unread bytes worth of conn-level flow control.
1180
1325
                // See golang.org/issue/16481
1183
1328
                p.CloseWithError(err)
1184
1329
        }
1185
1330
        st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
1186
 
        sc.writeSched.forgetStream(st.id)
1187
 
        if st.reqBuf != nil {
1188
 
                // Stash this request body buffer (64k) away for reuse
1189
 
                // by a future POST/PUT/etc.
1190
 
                //
1191
 
                // TODO(bradfitz): share on the server? sync.Pool?
1192
 
                // Server requires locks and might hurt contention.
1193
 
                // sync.Pool might work, or might be worse, depending
1194
 
                // on goroutine CPU migrations. (get and put on
1195
 
                // separate CPUs).  Maybe a mix of strategies. But
1196
 
                // this is an easy win for now.
1197
 
                sc.freeRequestBodyBuf = st.reqBuf
1198
 
        }
 
1331
        sc.writeSched.CloseStream(st.id)
1199
1332
}
1200
1333
 
1201
1334
func (sc *serverConn) processSettings(f *SettingsFrame) error {
1237
1370
        case SettingInitialWindowSize:
1238
1371
                return sc.processSettingInitialWindowSize(s.Val)
1239
1372
        case SettingMaxFrameSize:
1240
 
                sc.writeSched.maxFrameSize = s.Val
 
1373
                sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31
1241
1374
        case SettingMaxHeaderListSize:
1242
1375
                sc.peerMaxHeaderListSize = s.Val
1243
1376
        default:
1281
1414
 
1282
1415
func (sc *serverConn) processData(f *DataFrame) error {
1283
1416
        sc.serveG.check()
 
1417
        if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
 
1418
                return nil
 
1419
        }
1284
1420
        data := f.Data()
1285
1421
 
1286
1422
        // "If a DATA frame is received whose stream is not in "open"
1287
1423
        // or "half closed (local)" state, the recipient MUST respond
1288
1424
        // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
1289
1425
        id := f.Header().StreamID
1290
 
        st, ok := sc.streams[id]
1291
 
        if !ok || st.state != stateOpen || st.gotTrailerHeader {
 
1426
        state, st := sc.state(id)
 
1427
        if id == 0 || state == stateIdle {
 
1428
                // Section 5.1: "Receiving any frame other than HEADERS
 
1429
                // or PRIORITY on a stream in this state MUST be
 
1430
                // treated as a connection error (Section 5.4.1) of
 
1431
                // type PROTOCOL_ERROR."
 
1432
                return ConnectionError(ErrCodeProtocol)
 
1433
        }
 
1434
        if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {
1292
1435
                // This includes sending a RST_STREAM if the stream is
1293
1436
                // in stateHalfClosedLocal (which currently means that
1294
1437
                // the http.Handler returned, so it's done reading &
1308
1451
                sc.inflow.take(int32(f.Length))
1309
1452
                sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
1310
1453
 
 
1454
                if st != nil && st.resetQueued {
 
1455
                        // Already have a stream error in flight. Don't send another.
 
1456
                        return nil
 
1457
                }
1311
1458
                return streamError(id, ErrCodeStreamClosed)
1312
1459
        }
1313
1460
        if st.body == nil {
1350
1497
        return nil
1351
1498
}
1352
1499
 
 
1500
func (sc *serverConn) processGoAway(f *GoAwayFrame) error {
 
1501
        sc.serveG.check()
 
1502
        if f.ErrCode != ErrCodeNo {
 
1503
                sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f)
 
1504
        } else {
 
1505
                sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f)
 
1506
        }
 
1507
        sc.startGracefulShutdown()
 
1508
        // http://tools.ietf.org/html/rfc7540#section-6.8
 
1509
        // We should not create any new streams, which means we should disable push.
 
1510
        sc.pushEnabled = false
 
1511
        return nil
 
1512
}
 
1513
 
 
1514
// isPushed reports whether the stream is server-initiated.
 
1515
func (st *stream) isPushed() bool {
 
1516
        return st.id%2 == 0
 
1517
}
 
1518
 
1353
1519
// endStream closes a Request.Body's pipe. It is called when a DATA
1354
1520
// frame says a request body is over (or after trailers).
1355
1521
func (st *stream) endStream() {
1379
1545
 
1380
1546
func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
1381
1547
        sc.serveG.check()
1382
 
        id := f.Header().StreamID
 
1548
        id := f.StreamID
1383
1549
        if sc.inGoAway {
1384
1550
                // Ignore.
1385
1551
                return nil
1386
1552
        }
1387
 
        // http://http2.github.io/http2-spec/#rfc.section.5.1.1
 
1553
        // http://tools.ietf.org/html/rfc7540#section-5.1.1
1388
1554
        // Streams initiated by a client MUST use odd-numbered stream
1389
1555
        // identifiers. [...] An endpoint that receives an unexpected
1390
1556
        // stream identifier MUST respond with a connection error
1396
1562
        // send a trailer for an open one. If we already have a stream
1397
1563
        // open, let it process its own HEADERS frame (trailers at this
1398
1564
        // point, if it's valid).
1399
 
        st := sc.streams[f.Header().StreamID]
1400
 
        if st != nil {
 
1565
        if st := sc.streams[f.StreamID]; st != nil {
 
1566
                if st.resetQueued {
 
1567
                        // We're sending RST_STREAM to close the stream, so don't bother
 
1568
                        // processing this frame.
 
1569
                        return nil
 
1570
                }
1401
1571
                return st.processTrailerHeaders(f)
1402
1572
        }
1403
1573
 
1406
1576
        // endpoint has opened or reserved. [...]  An endpoint that
1407
1577
        // receives an unexpected stream identifier MUST respond with
1408
1578
        // a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
1409
 
        if id <= sc.maxStreamID {
 
1579
        if id <= sc.maxClientStreamID {
1410
1580
                return ConnectionError(ErrCodeProtocol)
1411
1581
        }
1412
 
        sc.maxStreamID = id
1413
 
 
1414
 
        ctx, cancelCtx := contextWithCancel(sc.baseCtx)
1415
 
        st = &stream{
1416
 
                sc:        sc,
1417
 
                id:        id,
1418
 
                state:     stateOpen,
1419
 
                ctx:       ctx,
1420
 
                cancelCtx: cancelCtx,
1421
 
        }
1422
 
        if f.StreamEnded() {
1423
 
                st.state = stateHalfClosedRemote
1424
 
        }
1425
 
        st.cw.Init()
1426
 
 
1427
 
        st.flow.conn = &sc.flow // link to conn-level counter
1428
 
        st.flow.add(sc.initialWindowSize)
1429
 
        st.inflow.conn = &sc.inflow      // link to conn-level counter
1430
 
        st.inflow.add(initialWindowSize) // TODO: update this when we send a higher initial window size in the initial settings
1431
 
 
1432
 
        sc.streams[id] = st
1433
 
        if f.HasPriority() {
1434
 
                adjustStreamPriority(sc.streams, st.id, f.Priority)
1435
 
        }
1436
 
        sc.curOpenStreams++
1437
 
        if sc.curOpenStreams == 1 {
1438
 
                sc.setConnState(http.StateActive)
1439
 
        }
1440
 
        if sc.curOpenStreams > sc.advMaxStreams {
1441
 
                // "Endpoints MUST NOT exceed the limit set by their
1442
 
                // peer. An endpoint that receives a HEADERS frame
1443
 
                // that causes their advertised concurrent stream
1444
 
                // limit to be exceeded MUST treat this as a stream
1445
 
                // error (Section 5.4.2) of type PROTOCOL_ERROR or
1446
 
                // REFUSED_STREAM."
 
1582
        sc.maxClientStreamID = id
 
1583
 
 
1584
        if sc.idleTimer != nil {
 
1585
                sc.idleTimer.Stop()
 
1586
        }
 
1587
 
 
1588
        // http://tools.ietf.org/html/rfc7540#section-5.1.2
 
1589
        // [...] Endpoints MUST NOT exceed the limit set by their peer. An
 
1590
        // endpoint that receives a HEADERS frame that causes their
 
1591
        // advertised concurrent stream limit to be exceeded MUST treat
 
1592
        // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR
 
1593
        // or REFUSED_STREAM.
 
1594
        if sc.curClientStreams+1 > sc.advMaxStreams {
1447
1595
                if sc.unackedSettings == 0 {
1448
1596
                        // They should know better.
1449
 
                        return streamError(st.id, ErrCodeProtocol)
 
1597
                        return streamError(id, ErrCodeProtocol)
1450
1598
                }
1451
1599
                // Assume it's a network race, where they just haven't
1452
1600
                // received our last SETTINGS update. But actually
1453
1601
                // this can't happen yet, because we don't yet provide
1454
1602
                // a way for users to adjust server parameters at
1455
1603
                // runtime.
1456
 
                return streamError(st.id, ErrCodeRefusedStream)
 
1604
                return streamError(id, ErrCodeRefusedStream)
 
1605
        }
 
1606
 
 
1607
        initialState := stateOpen
 
1608
        if f.StreamEnded() {
 
1609
                initialState = stateHalfClosedRemote
 
1610
        }
 
1611
        st := sc.newStream(id, 0, initialState)
 
1612
 
 
1613
        if f.HasPriority() {
 
1614
                if err := checkPriority(f.StreamID, f.Priority); err != nil {
 
1615
                        return err
 
1616
                }
 
1617
                sc.writeSched.AdjustStream(st.id, f.Priority)
1457
1618
        }
1458
1619
 
1459
1620
        rw, req, err := sc.newWriterAndRequest(st, f)
1471
1632
        if f.Truncated {
1472
1633
                // Their header list was too long. Send a 431 error.
1473
1634
                handler = handleHeaderListTooLong
1474
 
        } else if err := checkValidHTTP2Request(req); err != nil {
 
1635
        } else if err := checkValidHTTP2RequestHeaders(req.Header); err != nil {
1475
1636
                handler = new400Handler(err)
1476
1637
        }
1477
1638
 
1478
1639
        // The net/http package sets the read deadline from the
1479
1640
        // http.Server.ReadTimeout during the TLS handshake, but then
1480
1641
        // passes the connection off to us with the deadline already
1481
 
        // set. Disarm it here after the request headers are read, similar
1482
 
        // to how the http1 server works.
1483
 
        // Unlike http1, though, we never re-arm it yet, though.
1484
 
        // TODO(bradfitz): figure out golang.org/issue/14204
1485
 
        // (IdleTimeout) and how this relates. Maybe the default
1486
 
        // IdleTimeout is ReadTimeout.
 
1642
        // set. Disarm it here after the request headers are read,
 
1643
        // similar to how the http1 server works. Here it's
 
1644
        // technically more like the http1 Server's ReadHeaderTimeout
 
1645
        // (in Go 1.8), though. That's a more sane option anyway.
1487
1646
        if sc.hs.ReadTimeout != 0 {
1488
1647
                sc.conn.SetReadDeadline(time.Time{})
1489
1648
        }
1522
1681
        return nil
1523
1682
}
1524
1683
 
 
1684
func checkPriority(streamID uint32, p PriorityParam) error {
 
1685
        if streamID == p.StreamDep {
 
1686
                // Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat
 
1687
                // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR."
 
1688
                // Section 5.3.3 says that a stream can depend on one of its dependencies,
 
1689
                // so it's only self-dependencies that are forbidden.
 
1690
                return streamError(streamID, ErrCodeProtocol)
 
1691
        }
 
1692
        return nil
 
1693
}
 
1694
 
1525
1695
func (sc *serverConn) processPriority(f *PriorityFrame) error {
1526
 
        adjustStreamPriority(sc.streams, f.StreamID, f.PriorityParam)
 
1696
        if sc.inGoAway {
 
1697
                return nil
 
1698
        }
 
1699
        if err := checkPriority(f.StreamID, f.PriorityParam); err != nil {
 
1700
                return err
 
1701
        }
 
1702
        sc.writeSched.AdjustStream(f.StreamID, f.PriorityParam)
1527
1703
        return nil
1528
1704
}
1529
1705
 
1530
 
func adjustStreamPriority(streams map[uint32]*stream, streamID uint32, priority PriorityParam) {
1531
 
        st, ok := streams[streamID]
1532
 
        if !ok {
1533
 
                // TODO: not quite correct (this streamID might
1534
 
                // already exist in the dep tree, but be closed), but
1535
 
                // close enough for now.
1536
 
                return
1537
 
        }
1538
 
        st.weight = priority.Weight
1539
 
        parent := streams[priority.StreamDep] // might be nil
1540
 
        if parent == st {
1541
 
                // if client tries to set this stream to be the parent of itself
1542
 
                // ignore and keep going
1543
 
                return
1544
 
        }
1545
 
 
1546
 
        // section 5.3.3: If a stream is made dependent on one of its
1547
 
        // own dependencies, the formerly dependent stream is first
1548
 
        // moved to be dependent on the reprioritized stream's previous
1549
 
        // parent. The moved dependency retains its weight.
1550
 
        for piter := parent; piter != nil; piter = piter.parent {
1551
 
                if piter == st {
1552
 
                        parent.parent = st.parent
1553
 
                        break
1554
 
                }
1555
 
        }
1556
 
        st.parent = parent
1557
 
        if priority.Exclusive && (st.parent != nil || priority.StreamDep == 0) {
1558
 
                for _, openStream := range streams {
1559
 
                        if openStream != st && openStream.parent == st.parent {
1560
 
                                openStream.parent = st
1561
 
                        }
1562
 
                }
1563
 
        }
 
1706
func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream {
 
1707
        sc.serveG.check()
 
1708
        if id == 0 {
 
1709
                panic("internal error: cannot create stream with id 0")
 
1710
        }
 
1711
 
 
1712
        ctx, cancelCtx := contextWithCancel(sc.baseCtx)
 
1713
        st := &stream{
 
1714
                sc:        sc,
 
1715
                id:        id,
 
1716
                state:     state,
 
1717
                ctx:       ctx,
 
1718
                cancelCtx: cancelCtx,
 
1719
        }
 
1720
        st.cw.Init()
 
1721
        st.flow.conn = &sc.flow // link to conn-level counter
 
1722
        st.flow.add(sc.initialWindowSize)
 
1723
        st.inflow.conn = &sc.inflow      // link to conn-level counter
 
1724
        st.inflow.add(initialWindowSize) // TODO: update this when we send a higher initial window size in the initial settings
 
1725
 
 
1726
        sc.streams[id] = st
 
1727
        sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID})
 
1728
        if st.isPushed() {
 
1729
                sc.curPushedStreams++
 
1730
        } else {
 
1731
                sc.curClientStreams++
 
1732
        }
 
1733
        if sc.curOpenStreams() == 1 {
 
1734
                sc.setConnState(http.StateActive)
 
1735
        }
 
1736
 
 
1737
        return st
1564
1738
}
1565
1739
 
1566
1740
func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) {
1567
1741
        sc.serveG.check()
1568
1742
 
1569
 
        method := f.PseudoValue("method")
1570
 
        path := f.PseudoValue("path")
1571
 
        scheme := f.PseudoValue("scheme")
1572
 
        authority := f.PseudoValue("authority")
 
1743
        rp := requestParam{
 
1744
                method:    f.PseudoValue("method"),
 
1745
                scheme:    f.PseudoValue("scheme"),
 
1746
                authority: f.PseudoValue("authority"),
 
1747
                path:      f.PseudoValue("path"),
 
1748
        }
1573
1749
 
1574
 
        isConnect := method == "CONNECT"
 
1750
        isConnect := rp.method == "CONNECT"
1575
1751
        if isConnect {
1576
 
                if path != "" || scheme != "" || authority == "" {
 
1752
                if rp.path != "" || rp.scheme != "" || rp.authority == "" {
1577
1753
                        return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
1578
1754
                }
1579
 
        } else if method == "" || path == "" ||
1580
 
                (scheme != "https" && scheme != "http") {
 
1755
        } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
1581
1756
                // See 8.1.2.6 Malformed Requests and Responses:
1582
1757
                //
1583
1758
                // Malformed requests or responses that are detected
1592
1767
        }
1593
1768
 
1594
1769
        bodyOpen := !f.StreamEnded()
1595
 
        if method == "HEAD" && bodyOpen {
 
1770
        if rp.method == "HEAD" && bodyOpen {
1596
1771
                // HEAD requests can't have bodies
1597
1772
                return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
1598
1773
        }
 
1774
 
 
1775
        rp.header = make(http.Header)
 
1776
        for _, hf := range f.RegularFields() {
 
1777
                rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
 
1778
        }
 
1779
        if rp.authority == "" {
 
1780
                rp.authority = rp.header.Get("Host")
 
1781
        }
 
1782
 
 
1783
        rw, req, err := sc.newWriterAndRequestNoBody(st, rp)
 
1784
        if err != nil {
 
1785
                return nil, nil, err
 
1786
        }
 
1787
        if bodyOpen {
 
1788
                st.reqBuf = getRequestBodyBuf()
 
1789
                req.Body.(*requestBody).pipe = &pipe{
 
1790
                        b: &fixedBuffer{buf: st.reqBuf},
 
1791
                }
 
1792
 
 
1793
                if vv, ok := rp.header["Content-Length"]; ok {
 
1794
                        req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64)
 
1795
                } else {
 
1796
                        req.ContentLength = -1
 
1797
                }
 
1798
        }
 
1799
        return rw, req, nil
 
1800
}
 
1801
 
 
1802
type requestParam struct {
 
1803
        method                  string
 
1804
        scheme, authority, path string
 
1805
        header                  http.Header
 
1806
}
 
1807
 
 
1808
func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*responseWriter, *http.Request, error) {
 
1809
        sc.serveG.check()
 
1810
 
1599
1811
        var tlsState *tls.ConnectionState // nil if not scheme https
1600
 
 
1601
 
        if scheme == "https" {
 
1812
        if rp.scheme == "https" {
1602
1813
                tlsState = sc.tlsState
1603
1814
        }
1604
1815
 
1605
 
        header := make(http.Header)
1606
 
        for _, hf := range f.RegularFields() {
1607
 
                header.Add(sc.canonicalHeader(hf.Name), hf.Value)
1608
 
        }
1609
 
 
1610
 
        if authority == "" {
1611
 
                authority = header.Get("Host")
1612
 
        }
1613
 
        needsContinue := header.Get("Expect") == "100-continue"
 
1816
        needsContinue := rp.header.Get("Expect") == "100-continue"
1614
1817
        if needsContinue {
1615
 
                header.Del("Expect")
 
1818
                rp.header.Del("Expect")
1616
1819
        }
1617
1820
        // Merge Cookie headers into one "; "-delimited value.
1618
 
        if cookies := header["Cookie"]; len(cookies) > 1 {
1619
 
                header.Set("Cookie", strings.Join(cookies, "; "))
 
1821
        if cookies := rp.header["Cookie"]; len(cookies) > 1 {
 
1822
                rp.header.Set("Cookie", strings.Join(cookies, "; "))
1620
1823
        }
1621
1824
 
1622
1825
        // Setup Trailers
1623
1826
        var trailer http.Header
1624
 
        for _, v := range header["Trailer"] {
 
1827
        for _, v := range rp.header["Trailer"] {
1625
1828
                for _, key := range strings.Split(v, ",") {
1626
1829
                        key = http.CanonicalHeaderKey(strings.TrimSpace(key))
1627
1830
                        switch key {
1636
1839
                        }
1637
1840
                }
1638
1841
        }
1639
 
        delete(header, "Trailer")
 
1842
        delete(rp.header, "Trailer")
 
1843
 
 
1844
        var url_ *url.URL
 
1845
        var requestURI string
 
1846
        if rp.method == "CONNECT" {
 
1847
                url_ = &url.URL{Host: rp.authority}
 
1848
                requestURI = rp.authority // mimic HTTP/1 server behavior
 
1849
        } else {
 
1850
                var err error
 
1851
                url_, err = url.ParseRequestURI(rp.path)
 
1852
                if err != nil {
 
1853
                        return nil, nil, streamError(st.id, ErrCodeProtocol)
 
1854
                }
 
1855
                requestURI = rp.path
 
1856
        }
1640
1857
 
1641
1858
        body := &requestBody{
1642
1859
                conn:          sc,
1643
1860
                stream:        st,
1644
1861
                needsContinue: needsContinue,
1645
1862
        }
1646
 
        var url_ *url.URL
1647
 
        var requestURI string
1648
 
        if isConnect {
1649
 
                url_ = &url.URL{Host: authority}
1650
 
                requestURI = authority // mimic HTTP/1 server behavior
1651
 
        } else {
1652
 
                var err error
1653
 
                url_, err = url.ParseRequestURI(path)
1654
 
                if err != nil {
1655
 
                        return nil, nil, streamError(f.StreamID, ErrCodeProtocol)
1656
 
                }
1657
 
                requestURI = path
1658
 
        }
1659
1863
        req := &http.Request{
1660
 
                Method:     method,
 
1864
                Method:     rp.method,
1661
1865
                URL:        url_,
1662
1866
                RemoteAddr: sc.remoteAddrStr,
1663
 
                Header:     header,
 
1867
                Header:     rp.header,
1664
1868
                RequestURI: requestURI,
1665
1869
                Proto:      "HTTP/2.0",
1666
1870
                ProtoMajor: 2,
1667
1871
                ProtoMinor: 0,
1668
1872
                TLS:        tlsState,
1669
 
                Host:       authority,
 
1873
                Host:       rp.authority,
1670
1874
                Body:       body,
1671
1875
                Trailer:    trailer,
1672
1876
        }
1673
1877
        req = requestWithContext(req, st.ctx)
1674
 
        if bodyOpen {
1675
 
                // Disabled, per golang.org/issue/14960:
1676
 
                // st.reqBuf = sc.getRequestBodyBuf()
1677
 
                // TODO: remove this 64k of garbage per request (again, but without a data race):
1678
 
                buf := make([]byte, initialWindowSize)
1679
 
 
1680
 
                body.pipe = &pipe{
1681
 
                        b: &fixedBuffer{buf: buf},
1682
 
                }
1683
 
 
1684
 
                if vv, ok := header["Content-Length"]; ok {
1685
 
                        req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64)
1686
 
                } else {
1687
 
                        req.ContentLength = -1
1688
 
                }
1689
 
        }
1690
1878
 
1691
1879
        rws := responseWriterStatePool.Get().(*responseWriterState)
1692
1880
        bwSave := rws.bw
1702
1890
        return rw, req, nil
1703
1891
}
1704
1892
 
1705
 
func (sc *serverConn) getRequestBodyBuf() []byte {
1706
 
        sc.serveG.check()
1707
 
        if buf := sc.freeRequestBodyBuf; buf != nil {
1708
 
                sc.freeRequestBodyBuf = nil
1709
 
                return buf
1710
 
        }
1711
 
        return make([]byte, initialWindowSize)
 
1893
var reqBodyCache = make(chan []byte, 8)
 
1894
 
 
1895
func getRequestBodyBuf() []byte {
 
1896
        select {
 
1897
        case b := <-reqBodyCache:
 
1898
                return b
 
1899
        default:
 
1900
                return make([]byte, initialWindowSize)
 
1901
        }
 
1902
}
 
1903
 
 
1904
func putRequestBodyBuf(b []byte) {
 
1905
        select {
 
1906
        case reqBodyCache <- b:
 
1907
        default:
 
1908
        }
1712
1909
}
1713
1910
 
1714
1911
// Run on its own goroutine.
1718
1915
                rw.rws.stream.cancelCtx()
1719
1916
                if didPanic {
1720
1917
                        e := recover()
1721
 
                        // Same as net/http:
1722
 
                        const size = 64 << 10
1723
 
                        buf := make([]byte, size)
1724
 
                        buf = buf[:runtime.Stack(buf, false)]
1725
 
                        sc.writeFrameFromHandler(frameWriteMsg{
 
1918
                        sc.writeFrameFromHandler(FrameWriteRequest{
1726
1919
                                write:  handlerPanicRST{rw.rws.stream.id},
1727
1920
                                stream: rw.rws.stream,
1728
1921
                        })
1729
 
                        sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
 
1922
                        // Same as net/http:
 
1923
                        if shouldLogPanic(e) {
 
1924
                                const size = 64 << 10
 
1925
                                buf := make([]byte, size)
 
1926
                                buf = buf[:runtime.Stack(buf, false)]
 
1927
                                sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
 
1928
                        }
1730
1929
                        return
1731
1930
                }
1732
1931
                rw.handlerDone()
1757
1956
                // mutates it.
1758
1957
                errc = errChanPool.Get().(chan error)
1759
1958
        }
1760
 
        if err := sc.writeFrameFromHandler(frameWriteMsg{
 
1959
        if err := sc.writeFrameFromHandler(FrameWriteRequest{
1761
1960
                write:  headerData,
1762
1961
                stream: st,
1763
1962
                done:   errc,
1780
1979
 
1781
1980
// called from handler goroutines.
1782
1981
func (sc *serverConn) write100ContinueHeaders(st *stream) {
1783
 
        sc.writeFrameFromHandler(frameWriteMsg{
 
1982
        sc.writeFrameFromHandler(FrameWriteRequest{
1784
1983
                write:  write100ContinueHeadersFrame{st.id},
1785
1984
                stream: st,
1786
1985
        })
1796
1995
// called from handler goroutines.
1797
1996
// Notes that the handler for the given stream ID read n bytes of its body
1798
1997
// and schedules flow control tokens to be sent.
1799
 
func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int) {
 
1998
func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int, err error) {
1800
1999
        sc.serveG.checkNotOn() // NOT on
1801
 
        select {
1802
 
        case sc.bodyReadCh <- bodyReadMsg{st, n}:
1803
 
        case <-sc.doneServing:
 
2000
        if n > 0 {
 
2001
                select {
 
2002
                case sc.bodyReadCh <- bodyReadMsg{st, n}:
 
2003
                case <-sc.doneServing:
 
2004
                }
 
2005
        }
 
2006
        if err == io.EOF {
 
2007
                if buf := st.reqBuf; buf != nil {
 
2008
                        st.reqBuf = nil // shouldn't matter; field unused by other
 
2009
                        putRequestBodyBuf(buf)
 
2010
                }
1804
2011
        }
1805
2012
}
1806
2013
 
1843
2050
        if st != nil {
1844
2051
                streamID = st.id
1845
2052
        }
1846
 
        sc.writeFrame(frameWriteMsg{
 
2053
        sc.writeFrame(FrameWriteRequest{
1847
2054
                write:  writeWindowUpdate{streamID: streamID, n: uint32(n)},
1848
2055
                stream: st,
1849
2056
        })
1858
2065
        }
1859
2066
}
1860
2067
 
 
2068
// requestBody is the Handler's Request.Body type.
 
2069
// Read and Close may be called concurrently.
1861
2070
type requestBody struct {
1862
2071
        stream        *stream
1863
2072
        conn          *serverConn
1864
 
        closed        bool
 
2073
        closed        bool  // for use by Close only
 
2074
        sawEOF        bool  // for use by Read only
1865
2075
        pipe          *pipe // non-nil if we have a HTTP entity message body
1866
2076
        needsContinue bool  // need to send a 100-continue
1867
2077
}
1868
2078
 
1869
2079
func (b *requestBody) Close() error {
1870
 
        if b.pipe != nil {
 
2080
        if b.pipe != nil && !b.closed {
1871
2081
                b.pipe.BreakWithError(errClosedBody)
1872
2082
        }
1873
2083
        b.closed = true
1879
2089
                b.needsContinue = false
1880
2090
                b.conn.write100ContinueHeaders(b.stream)
1881
2091
        }
1882
 
        if b.pipe == nil {
 
2092
        if b.pipe == nil || b.sawEOF {
1883
2093
                return 0, io.EOF
1884
2094
        }
1885
2095
        n, err = b.pipe.Read(p)
1886
 
        if n > 0 {
1887
 
                b.conn.noteBodyReadFromHandler(b.stream, n)
1888
 
        }
 
2096
        if err == io.EOF {
 
2097
                b.sawEOF = true
 
2098
        }
 
2099
        if b.conn == nil && inTests {
 
2100
                return
 
2101
        }
 
2102
        b.conn.noteBodyReadFromHandler(b.stream, n, err)
1889
2103
        return
1890
2104
}
1891
2105
 
2123
2337
        if ch == nil {
2124
2338
                ch = make(chan bool, 1)
2125
2339
                rws.closeNotifierCh = ch
 
2340
                cw := rws.stream.cw
2126
2341
                go func() {
2127
 
                        rws.stream.cw.Wait() // wait for close
 
2342
                        cw.Wait() // wait for close
2128
2343
                        ch <- true
2129
2344
                }()
2130
2345
        }
2220
2435
        responseWriterStatePool.Put(rws)
2221
2436
}
2222
2437
 
 
2438
// Push errors.
 
2439
var (
 
2440
        ErrRecursivePush    = errors.New("http2: recursive push not allowed")
 
2441
        ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
 
2442
)
 
2443
 
 
2444
// pushOptions is the internal version of http.PushOptions, which we
 
2445
// cannot include here because it's only defined in Go 1.8 and later.
 
2446
type pushOptions struct {
 
2447
        Method string
 
2448
        Header http.Header
 
2449
}
 
2450
 
 
2451
func (w *responseWriter) push(target string, opts pushOptions) error {
 
2452
        st := w.rws.stream
 
2453
        sc := st.sc
 
2454
        sc.serveG.checkNotOn()
 
2455
 
 
2456
        // No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream."
 
2457
        // http://tools.ietf.org/html/rfc7540#section-6.6
 
2458
        if st.isPushed() {
 
2459
                return ErrRecursivePush
 
2460
        }
 
2461
 
 
2462
        // Default options.
 
2463
        if opts.Method == "" {
 
2464
                opts.Method = "GET"
 
2465
        }
 
2466
        if opts.Header == nil {
 
2467
                opts.Header = http.Header{}
 
2468
        }
 
2469
        wantScheme := "http"
 
2470
        if w.rws.req.TLS != nil {
 
2471
                wantScheme = "https"
 
2472
        }
 
2473
 
 
2474
        // Validate the request.
 
2475
        u, err := url.Parse(target)
 
2476
        if err != nil {
 
2477
                return err
 
2478
        }
 
2479
        if u.Scheme == "" {
 
2480
                if !strings.HasPrefix(target, "/") {
 
2481
                        return fmt.Errorf("target must be an absolute URL or an absolute path: %q", target)
 
2482
                }
 
2483
                u.Scheme = wantScheme
 
2484
                u.Host = w.rws.req.Host
 
2485
        } else {
 
2486
                if u.Scheme != wantScheme {
 
2487
                        return fmt.Errorf("cannot push URL with scheme %q from request with scheme %q", u.Scheme, wantScheme)
 
2488
                }
 
2489
                if u.Host == "" {
 
2490
                        return errors.New("URL must have a host")
 
2491
                }
 
2492
        }
 
2493
        for k := range opts.Header {
 
2494
                if strings.HasPrefix(k, ":") {
 
2495
                        return fmt.Errorf("promised request headers cannot include pseudo header %q", k)
 
2496
                }
 
2497
                // These headers are meaningful only if the request has a body,
 
2498
                // but PUSH_PROMISE requests cannot have a body.
 
2499
                // http://tools.ietf.org/html/rfc7540#section-8.2
 
2500
                // Also disallow Host, since the promised URL must be absolute.
 
2501
                switch strings.ToLower(k) {
 
2502
                case "content-length", "content-encoding", "trailer", "te", "expect", "host":
 
2503
                        return fmt.Errorf("promised request headers cannot include %q", k)
 
2504
                }
 
2505
        }
 
2506
        if err := checkValidHTTP2RequestHeaders(opts.Header); err != nil {
 
2507
                return err
 
2508
        }
 
2509
 
 
2510
        // The RFC effectively limits promised requests to GET and HEAD:
 
2511
        // "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]"
 
2512
        // http://tools.ietf.org/html/rfc7540#section-8.2
 
2513
        if opts.Method != "GET" && opts.Method != "HEAD" {
 
2514
                return fmt.Errorf("method %q must be GET or HEAD", opts.Method)
 
2515
        }
 
2516
 
 
2517
        msg := startPushRequest{
 
2518
                parent: st,
 
2519
                method: opts.Method,
 
2520
                url:    u,
 
2521
                header: cloneHeader(opts.Header),
 
2522
                done:   errChanPool.Get().(chan error),
 
2523
        }
 
2524
 
 
2525
        select {
 
2526
        case <-sc.doneServing:
 
2527
                return errClientDisconnected
 
2528
        case <-st.cw:
 
2529
                return errStreamClosed
 
2530
        case sc.wantStartPushCh <- msg:
 
2531
        }
 
2532
 
 
2533
        select {
 
2534
        case <-sc.doneServing:
 
2535
                return errClientDisconnected
 
2536
        case <-st.cw:
 
2537
                return errStreamClosed
 
2538
        case err := <-msg.done:
 
2539
                errChanPool.Put(msg.done)
 
2540
                return err
 
2541
        }
 
2542
}
 
2543
 
 
2544
type startPushRequest struct {
 
2545
        parent *stream
 
2546
        method string
 
2547
        url    *url.URL
 
2548
        header http.Header
 
2549
        done   chan error
 
2550
}
 
2551
 
 
2552
func (sc *serverConn) startPush(msg startPushRequest) {
 
2553
        sc.serveG.check()
 
2554
 
 
2555
        // http://tools.ietf.org/html/rfc7540#section-6.6.
 
2556
        // PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
 
2557
        // is in either the "open" or "half-closed (remote)" state.
 
2558
        if msg.parent.state != stateOpen && msg.parent.state != stateHalfClosedRemote {
 
2559
                // responseWriter.Push checks that the stream is peer-initiaed.
 
2560
                msg.done <- errStreamClosed
 
2561
                return
 
2562
        }
 
2563
 
 
2564
        // http://tools.ietf.org/html/rfc7540#section-6.6.
 
2565
        if !sc.pushEnabled {
 
2566
                msg.done <- http.ErrNotSupported
 
2567
                return
 
2568
        }
 
2569
 
 
2570
        // PUSH_PROMISE frames must be sent in increasing order by stream ID, so
 
2571
        // we allocate an ID for the promised stream lazily, when the PUSH_PROMISE
 
2572
        // is written. Once the ID is allocated, we start the request handler.
 
2573
        allocatePromisedID := func() (uint32, error) {
 
2574
                sc.serveG.check()
 
2575
 
 
2576
                // Check this again, just in case. Technically, we might have received
 
2577
                // an updated SETTINGS by the time we got around to writing this frame.
 
2578
                if !sc.pushEnabled {
 
2579
                        return 0, http.ErrNotSupported
 
2580
                }
 
2581
                // http://tools.ietf.org/html/rfc7540#section-6.5.2.
 
2582
                if sc.curPushedStreams+1 > sc.clientMaxStreams {
 
2583
                        return 0, ErrPushLimitReached
 
2584
                }
 
2585
 
 
2586
                // http://tools.ietf.org/html/rfc7540#section-5.1.1.
 
2587
                // Streams initiated by the server MUST use even-numbered identifiers.
 
2588
                // A server that is unable to establish a new stream identifier can send a GOAWAY
 
2589
                // frame so that the client is forced to open a new connection for new streams.
 
2590
                if sc.maxPushPromiseID+2 >= 1<<31 {
 
2591
                        sc.startGracefulShutdown()
 
2592
                        return 0, ErrPushLimitReached
 
2593
                }
 
2594
                sc.maxPushPromiseID += 2
 
2595
                promisedID := sc.maxPushPromiseID
 
2596
 
 
2597
                // http://tools.ietf.org/html/rfc7540#section-8.2.
 
2598
                // Strictly speaking, the new stream should start in "reserved (local)", then
 
2599
                // transition to "half closed (remote)" after sending the initial HEADERS, but
 
2600
                // we start in "half closed (remote)" for simplicity.
 
2601
                // See further comments at the definition of stateHalfClosedRemote.
 
2602
                promised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote)
 
2603
                rw, req, err := sc.newWriterAndRequestNoBody(promised, requestParam{
 
2604
                        method:    msg.method,
 
2605
                        scheme:    msg.url.Scheme,
 
2606
                        authority: msg.url.Host,
 
2607
                        path:      msg.url.RequestURI(),
 
2608
                        header:    cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
 
2609
                })
 
2610
                if err != nil {
 
2611
                        // Should not happen, since we've already validated msg.url.
 
2612
                        panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err))
 
2613
                }
 
2614
 
 
2615
                go sc.runHandler(rw, req, sc.handler.ServeHTTP)
 
2616
                return promisedID, nil
 
2617
        }
 
2618
 
 
2619
        sc.writeFrame(FrameWriteRequest{
 
2620
                write: &writePushPromise{
 
2621
                        streamID:           msg.parent.id,
 
2622
                        method:             msg.method,
 
2623
                        url:                msg.url,
 
2624
                        h:                  msg.header,
 
2625
                        allocatePromisedID: allocatePromisedID,
 
2626
                },
 
2627
                stream: msg.parent,
 
2628
                done:   msg.done,
 
2629
        })
 
2630
}
 
2631
 
2223
2632
// foreachHeaderElement splits v according to the "#rule" construction
2224
2633
// in RFC 2616 section 2.1 and calls fn for each non-empty element.
2225
2634
func foreachHeaderElement(v string, fn func(string)) {
2247
2656
        "Upgrade",
2248
2657
}
2249
2658
 
2250
 
// checkValidHTTP2Request checks whether req is a valid HTTP/2 request,
 
2659
// checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request,
2251
2660
// per RFC 7540 Section 8.1.2.2.
2252
2661
// The returned error is reported to users.
2253
 
func checkValidHTTP2Request(req *http.Request) error {
2254
 
        for _, h := range connHeaders {
2255
 
                if _, ok := req.Header[h]; ok {
2256
 
                        return fmt.Errorf("request header %q is not valid in HTTP/2", h)
 
2662
func checkValidHTTP2RequestHeaders(h http.Header) error {
 
2663
        for _, k := range connHeaders {
 
2664
                if _, ok := h[k]; ok {
 
2665
                        return fmt.Errorf("request header %q is not valid in HTTP/2", k)
2257
2666
                }
2258
2667
        }
2259
 
        te := req.Header["Te"]
 
2668
        te := h["Te"]
2260
2669
        if len(te) > 0 && (len(te) > 1 || (te[0] != "trailers" && te[0] != "")) {
2261
2670
                return errors.New(`request header "TE" may only be "trailers" in HTTP/2`)
2262
2671
        }
2303
2712
        "Transfer-Encoding":   true,
2304
2713
        "Www-Authenticate":    true,
2305
2714
}
 
2715
 
 
2716
// h1ServerShutdownChan returns a channel that will be closed when the
 
2717
// provided *http.Server wants to shut down.
 
2718
//
 
2719
// This is a somewhat hacky way to get at http1 innards. It works
 
2720
// when the http2 code is bundled into the net/http package in the
 
2721
// standard library. The alternatives ended up making the cmd/go tool
 
2722
// depend on http Servers. This is the lightest option for now.
 
2723
// This is tested via the TestServeShutdown* tests in net/http.
 
2724
func h1ServerShutdownChan(hs *http.Server) <-chan struct{} {
 
2725
        if fn := testh1ServerShutdownChan; fn != nil {
 
2726
                return fn(hs)
 
2727
        }
 
2728
        var x interface{} = hs
 
2729
        type I interface {
 
2730
                getDoneChan() <-chan struct{}
 
2731
        }
 
2732
        if hs, ok := x.(I); ok {
 
2733
                return hs.getDoneChan()
 
2734
        }
 
2735
        return nil
 
2736
}
 
2737
 
 
2738
// optional test hook for h1ServerShutdownChan.
 
2739
var testh1ServerShutdownChan func(hs *http.Server) <-chan struct{}
 
2740
 
 
2741
// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
 
2742
// disabled. See comments on h1ServerShutdownChan above for why
 
2743
// the code is written this way.
 
2744
func h1ServerKeepAlivesDisabled(hs *http.Server) bool {
 
2745
        var x interface{} = hs
 
2746
        type I interface {
 
2747
                doKeepAlives() bool
 
2748
        }
 
2749
        if hs, ok := x.(I); ok {
 
2750
                return !hs.doKeepAlives()
 
2751
        }
 
2752
        return false
 
2753
}