1
0
mirror of https://github.com/golang/go synced 2024-11-18 15:54:42 -07:00

net/http: update bundled x/net/http2

This updates the bundled http2 package from git rev
5602c733f70afc6dcec6766be0d5034d4c4f14de of the x/net repo for:

  http2: Use NO_ERROR instead of CANCEL when responding before the request is finished
  https://golang.org/cl/40630

  http2: enforce write deadline per stream
  https://golang.org/cl/34727

Updates golang/go#19948
Fixes golang/go#18437

Change-Id: I14500476e91551fa8f27a1aeb8ae3cac9600b74c
Reviewed-on: https://go-review.googlesource.com/41753
Reviewed-by: Kale Blankenship <kale@lemnisys.com>
Reviewed-by: Tom Bergan <tombergan@google.com>
Run-TryBot: Kale Blankenship <kale@lemnisys.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Brad Fitzpatrick 2017-04-25 20:36:07 +00:00
parent e10af2e862
commit 0d3143ea78
2 changed files with 28 additions and 8 deletions

View File

@ -1,4 +1,4 @@
// Code generated by golang.org/x/tools/cmd/bundle. // Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
//go:generate bundle -o h2_bundle.go -prefix http2 -underscore golang.org/x/net/http2 //go:generate bundle -o h2_bundle.go -prefix http2 -underscore golang.org/x/net/http2
// Package http2 implements the HTTP/2 protocol. // Package http2 implements the HTTP/2 protocol.
@ -2282,7 +2282,11 @@ func (cc *http2ClientConn) Ping(ctx context.Context) error {
return cc.ping(ctx) return cc.ping(ctx)
} }
func http2cloneTLSConfig(c *tls.Config) *tls.Config { return c.Clone() } func http2cloneTLSConfig(c *tls.Config) *tls.Config {
c2 := c.Clone()
c2.GetClientCertificate = c.GetClientCertificate
return c2
}
var _ Pusher = (*http2responseWriter)(nil) var _ Pusher = (*http2responseWriter)(nil)
@ -3439,9 +3443,10 @@ type http2stream struct {
numTrailerValues int64 numTrailerValues int64
weight uint8 weight uint8
state http2streamState state http2streamState
resetQueued bool // RST_STREAM queued for write; set by sc.resetStream resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
gotTrailerHeader bool // HEADER frame for trailers was seen gotTrailerHeader bool // HEADER frame for trailers was seen
wroteHeaders bool // whether we wrote headers (not status 100) wroteHeaders bool // whether we wrote headers (not status 100)
writeDeadline *time.Timer // nil if unused
trailer Header // accumulated trailers trailer Header // accumulated trailers
reqTrailer Header // handler's Request.Trailer reqTrailer Header // handler's Request.Trailer
@ -3698,6 +3703,10 @@ func (sc *http2serverConn) serve() {
loopNum++ loopNum++
select { select {
case wr := <-sc.wantWriteFrameCh: case wr := <-sc.wantWriteFrameCh:
if se, ok := wr.write.(http2StreamError); ok {
sc.resetStream(se)
break
}
sc.writeFrame(wr) sc.writeFrame(wr)
case spr := <-sc.wantStartPushCh: case spr := <-sc.wantStartPushCh:
sc.startPush(spr) sc.startPush(spr)
@ -3939,7 +3948,8 @@ func (sc *http2serverConn) wroteFrame(res http2frameWriteResult) {
case http2stateOpen: case http2stateOpen:
st.state = http2stateHalfClosedLocal st.state = http2stateHalfClosedLocal
sc.resetStream(http2streamError(st.id, http2ErrCodeCancel))
sc.resetStream(http2streamError(st.id, http2ErrCodeNo))
case http2stateHalfClosedRemote: case http2stateHalfClosedRemote:
sc.closeStream(st, http2errHandlerComplete) sc.closeStream(st, http2errHandlerComplete)
} }
@ -4204,6 +4214,9 @@ func (sc *http2serverConn) closeStream(st *http2stream, err error) {
panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state)) panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
} }
st.state = http2stateClosed st.state = http2stateClosed
if st.writeDeadline != nil {
st.writeDeadline.Stop()
}
if st.isPushed() { if st.isPushed() {
sc.curPushedStreams-- sc.curPushedStreams--
} else { } else {
@ -4403,6 +4416,12 @@ func (st *http2stream) copyTrailersToHandlerRequest() {
} }
} }
// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
// when the stream's WriteTimeout has fired.
func (st *http2stream) onWriteTimeout() {
st.sc.writeFrameFromHandler(http2FrameWriteRequest{write: http2streamError(st.id, http2ErrCodeInternal)})
}
func (sc *http2serverConn) processHeaders(f *http2MetaHeadersFrame) error { func (sc *http2serverConn) processHeaders(f *http2MetaHeadersFrame) error {
sc.serveG.check() sc.serveG.check()
id := f.StreamID id := f.StreamID
@ -4547,6 +4566,9 @@ func (sc *http2serverConn) newStream(id, pusherID uint32, state http2streamState
st.flow.add(sc.initialStreamSendWindowSize) st.flow.add(sc.initialStreamSendWindowSize)
st.inflow.conn = &sc.inflow st.inflow.conn = &sc.inflow
st.inflow.add(sc.srv.initialStreamRecvWindowSize()) st.inflow.add(sc.srv.initialStreamRecvWindowSize())
if sc.hs.WriteTimeout != 0 {
st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
}
sc.streams[id] = st sc.streams[id] = st
sc.writeSched.OpenStream(st.id, http2OpenStreamOptions{PusherID: pusherID}) sc.writeSched.OpenStream(st.id, http2OpenStreamOptions{PusherID: pusherID})

View File

@ -661,7 +661,6 @@ func tryTimeouts(t *testing.T, testFunc func(timeout time.Duration) error) {
// Test that the HTTP/2 server RSTs stream on slow write. // Test that the HTTP/2 server RSTs stream on slow write.
func TestHTTP2WriteDeadlineEnforcedPerStream(t *testing.T) { func TestHTTP2WriteDeadlineEnforcedPerStream(t *testing.T) {
t.Skip("disabled until Issue 18437 is fixed")
if testing.Short() { if testing.Short() {
t.Skip("skipping in short mode") t.Skip("skipping in short mode")
} }
@ -723,7 +722,6 @@ func testHTTP2WriteDeadlineEnforcedPerStream(timeout time.Duration) error {
// Test that the HTTP/2 server does not send RST when WriteDeadline not set. // Test that the HTTP/2 server does not send RST when WriteDeadline not set.
func TestHTTP2NoWriteDeadline(t *testing.T) { func TestHTTP2NoWriteDeadline(t *testing.T) {
t.Skip("disabled until Issue 18437 is fixed")
if testing.Short() { if testing.Short() {
t.Skip("skipping in short mode") t.Skip("skipping in short mode")
} }