]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: update bundled http2
authorBrad Fitzpatrick <bradfitz@golang.org>
Thu, 10 Nov 2016 22:53:16 +0000 (22:53 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 10 Nov 2016 23:09:26 +0000 (23:09 +0000)
Updates http2 to x/net/http2 git rev 9ef22118 for:

   http2: fix CloseNotify data race
   https://golang.org/cl/33013

   http2: don't overflow stream IDs in server push
   https://golang.org/cl/32488

   http2: disable server push on receiving a GOAWAY
   https://golang.org/cl/32887

   http2: fix state tracking for pushed streams
   https://golang.org/cl/32755

Change-Id: Ie7d675857423c102c9ec164d3c943093c749c7cf
Reviewed-on: https://go-review.googlesource.com/33100
Reviewed-by: Tom Bergan <tombergan@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/net/http/h2_bundle.go

index 6367d20aacf21ab9ad77ff57e72a5895fd0dc7fa..f606098796d9e8612baa25c9420b18a2ac669b79 100644 (file)
@@ -3206,8 +3206,8 @@ type http2serverConn struct {
        advMaxStreams         uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
        curClientStreams      uint32 // number of open streams initiated by the client
        curPushedStreams      uint32 // number of open streams initiated by server push
-       maxStreamID           uint32 // max ever seen from client
-       maxPushPromiseID      uint32 // ID of the last push promise, or 0 if there have been no pushes
+       maxClientStreamID     uint32 // max ever seen from client (odd), or 0 if there have been no client requests
+       maxPushPromiseID      uint32 // ID of the last push promise (even), or 0 if there have been no pushes
        streams               map[uint32]*http2stream
        initialWindowSize     int32
        maxFrameSize          int32
@@ -3295,8 +3295,14 @@ func (sc *http2serverConn) state(streamID uint32) (http2streamState, *http2strea
                return st.state, st
        }
 
-       if streamID <= sc.maxStreamID {
-               return http2stateClosed, nil
+       if streamID%2 == 1 {
+               if streamID <= sc.maxClientStreamID {
+                       return http2stateClosed, nil
+               }
+       } else {
+               if streamID <= sc.maxPushPromiseID {
+                       return http2stateClosed, nil
+               }
        }
        return http2stateIdle, nil
 }
@@ -3797,7 +3803,7 @@ func (sc *http2serverConn) scheduleFrameWrite() {
                        sc.needToSendGoAway = false
                        sc.startFrameWrite(http2FrameWriteRequest{
                                write: &http2writeGoAway{
-                                       maxStreamID: sc.maxStreamID,
+                                       maxStreamID: sc.maxClientStreamID,
                                        code:        sc.goAwayCode,
                                },
                        })
@@ -3938,6 +3944,8 @@ func (sc *http2serverConn) processFrame(f http2Frame) error {
                return sc.processResetStream(f)
        case *http2PriorityFrame:
                return sc.processPriority(f)
+       case *http2GoAwayFrame:
+               return sc.processGoAway(f)
        case *http2PushPromiseFrame:
 
                return http2ConnectionError(http2ErrCodeProtocol)
@@ -4158,6 +4166,19 @@ func (sc *http2serverConn) processData(f *http2DataFrame) error {
        return nil
 }
 
+func (sc *http2serverConn) processGoAway(f *http2GoAwayFrame) error {
+       sc.serveG.check()
+       if f.ErrCode != http2ErrCodeNo {
+               sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f)
+       } else {
+               sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f)
+       }
+       sc.goAwayIn(http2ErrCodeNo, 0)
+
+       sc.pushEnabled = false
+       return nil
+}
+
 // isPushed reports whether the stream is server-initiated.
 func (st *http2stream) isPushed() bool {
        return st.id%2 == 0
@@ -4206,10 +4227,10 @@ func (sc *http2serverConn) processHeaders(f *http2MetaHeadersFrame) error {
                return st.processTrailerHeaders(f)
        }
 
-       if id <= sc.maxStreamID {
+       if id <= sc.maxClientStreamID {
                return http2ConnectionError(http2ErrCodeProtocol)
        }
-       sc.maxStreamID = id
+       sc.maxClientStreamID = id
 
        if sc.idleTimer != nil {
                sc.idleTimer.Stop()
@@ -4926,8 +4947,9 @@ func (w *http2responseWriter) CloseNotify() <-chan bool {
        if ch == nil {
                ch = make(chan bool, 1)
                rws.closeNotifierCh = ch
+               cw := rws.stream.cw
                go func() {
-                       rws.stream.cw.Wait()
+                       cw.Wait()
                        ch <- true
                }()
        }
@@ -5152,6 +5174,10 @@ func (sc *http2serverConn) startPush(msg http2startPushRequest) {
                        return 0, http2ErrPushLimitReached
                }
 
+               if sc.maxPushPromiseID+2 >= 1<<31 {
+                       sc.goAwayIn(http2ErrCodeNo, 0)
+                       return 0, http2ErrPushLimitReached
+               }
                sc.maxPushPromiseID += 2
                promisedID := sc.maxPushPromiseID