Skip to content

Commit 7fa635b

Browse files
committed
http2: avoid panic on h2c upgrade failure
When performing an h2c upgrade, we would panic if an error occurred reading the client preface. *serverConn.closeStream assumes that a conn with an IdleTimeout > 0 will have an idleTimer, but in the h2c upgrade case the stream may have been created before the timer. Fixes golang/go#67168 Change-Id: I30b5a701c10753ddc344079b9498285f099155cf Reviewed-on: https://go-review.googlesource.com/c/net/+/584255 Reviewed-by: Jonathan Amsterdam <jba@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1 parent d27919b commit 7fa635b

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

Diff for: http2/server.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1639,7 +1639,7 @@ func (sc *serverConn) closeStream(st *stream, err error) {
16391639
delete(sc.streams, st.id)
16401640
if len(sc.streams) == 0 {
16411641
sc.setConnState(http.StateIdle)
1642-
if sc.srv.IdleTimeout > 0 {
1642+
if sc.srv.IdleTimeout > 0 && sc.idleTimer != nil {
16431643
sc.idleTimer.Reset(sc.srv.IdleTimeout)
16441644
}
16451645
if h1ServerKeepAlivesDisabled(sc.hs) {

Diff for: http2/server_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -4880,3 +4880,23 @@ func TestServerContinuationAfterInvalidHeader(t *testing.T) {
48804880
t.Errorf("connection closed with no GOAWAY frame; want one")
48814881
}
48824882
}
4883+
4884+
func TestServerUpgradeRequestPrefaceFailure(t *testing.T) {
4885+
// An h2c upgrade request fails when the client preface is not as expected.
4886+
s2 := &Server{
4887+
// Setting IdleTimeout triggers #67168.
4888+
IdleTimeout: 60 * time.Minute,
4889+
}
4890+
c1, c2 := net.Pipe()
4891+
donec := make(chan struct{})
4892+
go func() {
4893+
defer close(donec)
4894+
s2.ServeConn(c1, &ServeConnOpts{
4895+
UpgradeRequest: httptest.NewRequest("GET", "/", nil),
4896+
})
4897+
}()
4898+
// The server expects to see the HTTP/2 preface,
4899+
// but we close the connection instead.
4900+
c2.Close()
4901+
<-donec
4902+
}

0 commit comments

Comments
 (0)