]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: update bundled http2, fixes TestConcurrentReadWriteReqBody_h2
authorBrad Fitzpatrick <bradfitz@golang.org>
Thu, 7 Jan 2016 04:59:25 +0000 (04:59 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 7 Jan 2016 06:07:06 +0000 (06:07 +0000)
Updates http2 to x/net git rev 520af5de654d for
https://golang.org/cl/18370

Fixes #13659

Change-Id: I920eaff6036ac22c500a97449826c6b12f873d7f
Reviewed-on: https://go-review.googlesource.com/18371
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
src/net/http/clientserver_test.go
src/net/http/h2_bundle.go

index 5143c104d045608f86fa5a5ccfe8be958c1defdb..4f7dac20670070f18663f7e8fd741bbb2735f3d7 100644 (file)
@@ -622,10 +622,7 @@ func testResponseBodyReadAfterClose(t *testing.T, h2 bool) {
 }
 
 func TestConcurrentReadWriteReqBody_h1(t *testing.T) { testConcurrentReadWriteReqBody(t, h1Mode) }
-func TestConcurrentReadWriteReqBody_h2(t *testing.T) {
-       t.Skip("known failing; golang.org/issue/13659")
-       testConcurrentReadWriteReqBody(t, h2Mode)
-}
+func TestConcurrentReadWriteReqBody_h2(t *testing.T) { testConcurrentReadWriteReqBody(t, h2Mode) }
 func testConcurrentReadWriteReqBody(t *testing.T, h2 bool) {
        defer afterTest(t)
        const reqBody = "some request body"
@@ -653,7 +650,7 @@ func testConcurrentReadWriteReqBody(t *testing.T, h2 bool) {
                                // our HTTP/1 implementation intentionally
                                // doesn't permit writes during read (mostly
                                // due to it being undefined); if that is ever
-                               // relaxed, fix this.
+                               // relaxed, change this.
                                <-didRead
                        }
                        io.WriteString(w, resBody)
index 030ca207295cf5beb2e10b666f45b14533f677bb..7e7b494d55cce1c3c2e0b08f612c4632282c257d 100644 (file)
@@ -1406,10 +1406,6 @@ func http2parseContinuationFrame(fh http2FrameHeader, p []byte) (http2Frame, err
        return &http2ContinuationFrame{fh, p}, nil
 }
 
-func (f *http2ContinuationFrame) StreamEnded() bool {
-       return f.http2FrameHeader.Flags.Has(http2FlagDataEndStream)
-}
-
 func (f *http2ContinuationFrame) HeaderBlockFragment() []byte {
        f.checkValid()
        return f.headerFragBuf
@@ -4222,8 +4218,8 @@ type http2clientStream struct {
        done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu
 
        // owned by clientConnReadLoop:
-       headersDone  bool // got HEADERS w/ END_HEADERS
-       trailersDone bool // got second HEADERS frame w/ END_HEADERS
+       pastHeaders  bool // got HEADERS w/ END_HEADERS
+       pastTrailers bool // got second HEADERS frame w/ END_HEADERS
 
        trailer    Header // accumulated trailers
        resTrailer Header // client's Response.Trailer
@@ -4923,9 +4919,10 @@ type http2clientConnReadLoop struct {
        hdec *hpack.Decoder
 
        // Fields reset on each HEADERS:
-       nextRes      *Response
-       sawRegHeader bool  // saw non-pseudo header
-       reqMalformed error // non-nil once known to be malformed
+       nextRes              *Response
+       sawRegHeader         bool  // saw non-pseudo header
+       reqMalformed         error // non-nil once known to be malformed
+       lastHeaderEndsStream bool
 }
 
 // readLoop runs in its own goroutine and reads and dispatches frames.
@@ -5018,26 +5015,28 @@ func (rl *http2clientConnReadLoop) run() error {
 func (rl *http2clientConnReadLoop) processHeaders(f *http2HeadersFrame) error {
        rl.sawRegHeader = false
        rl.reqMalformed = nil
+       rl.lastHeaderEndsStream = f.StreamEnded()
        rl.nextRes = &Response{
                Proto:      "HTTP/2.0",
                ProtoMajor: 2,
                Header:     make(Header),
        }
-       return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded(), f.StreamEnded())
+       return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded())
 }
 
 func (rl *http2clientConnReadLoop) processContinuation(f *http2ContinuationFrame) error {
-       return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded(), f.StreamEnded())
+       return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded())
 }
 
-func (rl *http2clientConnReadLoop) processHeaderBlockFragment(frag []byte, streamID uint32, headersEnded, streamEnded bool) error {
+func (rl *http2clientConnReadLoop) processHeaderBlockFragment(frag []byte, streamID uint32, finalFrag bool) error {
        cc := rl.cc
-       cs := cc.streamByID(streamID, streamEnded)
+       streamEnded := rl.lastHeaderEndsStream
+       cs := cc.streamByID(streamID, streamEnded && finalFrag)
        if cs == nil {
 
                return nil
        }
-       if cs.headersDone {
+       if cs.pastHeaders {
                rl.hdec.SetEmitFunc(cs.onNewTrailerField)
        } else {
                rl.hdec.SetEmitFunc(rl.onNewHeaderField)
@@ -5046,22 +5045,25 @@ func (rl *http2clientConnReadLoop) processHeaderBlockFragment(frag []byte, strea
        if err != nil {
                return http2ConnectionError(http2ErrCodeCompression)
        }
-       if err := rl.hdec.Close(); err != nil {
-               return http2ConnectionError(http2ErrCodeCompression)
+       if finalFrag {
+               if err := rl.hdec.Close(); err != nil {
+                       return http2ConnectionError(http2ErrCodeCompression)
+               }
        }
-       if !headersEnded {
+
+       if !finalFrag {
                return nil
        }
 
-       if !cs.headersDone {
-               cs.headersDone = true
+       if !cs.pastHeaders {
+               cs.pastHeaders = true
        } else {
 
-               if cs.trailersDone {
+               if cs.pastTrailers {
 
                        return http2ConnectionError(http2ErrCodeProtocol)
                }
-               cs.trailersDone = true
+               cs.pastTrailers = true
                if !streamEnded {
 
                        return http2ConnectionError(http2ErrCodeProtocol)
@@ -5078,6 +5080,12 @@ func (rl *http2clientConnReadLoop) processHeaderBlockFragment(frag []byte, strea
 
        res := rl.nextRes
 
+       if res.StatusCode == 100 {
+
+               cs.pastHeaders = false
+               return nil
+       }
+
        if !streamEnded || cs.req.Method == "HEAD" {
                res.ContentLength = -1
                if clens := res.Header["Content-Length"]; len(clens) == 1 {