-// 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
// Package http2 implements the HTTP/2 protocol.
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)
numTrailerValues int64
weight uint8
state http2streamState
- resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
- gotTrailerHeader bool // HEADER frame for trailers was seen
- wroteHeaders bool // whether we wrote headers (not status 100)
+ resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
+ gotTrailerHeader bool // HEADER frame for trailers was seen
+ wroteHeaders bool // whether we wrote headers (not status 100)
+ writeDeadline *time.Timer // nil if unused
trailer Header // accumulated trailers
reqTrailer Header // handler's Request.Trailer
loopNum++
select {
case wr := <-sc.wantWriteFrameCh:
+ if se, ok := wr.write.(http2StreamError); ok {
+ sc.resetStream(se)
+ break
+ }
sc.writeFrame(wr)
case spr := <-sc.wantStartPushCh:
sc.startPush(spr)
case http2stateOpen:
st.state = http2stateHalfClosedLocal
- sc.resetStream(http2streamError(st.id, http2ErrCodeCancel))
+
+ sc.resetStream(http2streamError(st.id, http2ErrCodeNo))
case http2stateHalfClosedRemote:
sc.closeStream(st, http2errHandlerComplete)
}
panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
}
st.state = http2stateClosed
+ if st.writeDeadline != nil {
+ st.writeDeadline.Stop()
+ }
if st.isPushed() {
sc.curPushedStreams--
} else {
}
}
+// 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 {
sc.serveG.check()
id := f.StreamID
st.flow.add(sc.initialStreamSendWindowSize)
st.inflow.conn = &sc.inflow
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.writeSched.OpenStream(st.id, http2OpenStreamOptions{PusherID: pusherID})
// Test that the HTTP/2 server RSTs stream on slow write.
func TestHTTP2WriteDeadlineEnforcedPerStream(t *testing.T) {
- t.Skip("disabled until Issue 18437 is fixed")
if testing.Short() {
t.Skip("skipping in short mode")
}
// Test that the HTTP/2 server does not send RST when WriteDeadline not set.
func TestHTTP2NoWriteDeadline(t *testing.T) {
- t.Skip("disabled until Issue 18437 is fixed")
if testing.Short() {
t.Skip("skipping in short mode")
}