Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/net/http2/h2c: h2cHandler does not respect server read/readheader/write timeouts #52868

Open
milesbxf opened this issue May 12, 2022 · 2 comments
Open
Labels
NeedsInvestigation
Milestone

Comments

@milesbxf
Copy link

@milesbxf milesbxf commented May 12, 2022

What version of Go are you using (go version)?

$ go version
go version go1.17.6 darwin/amd64

Does this issue reproduce with the latest release?

Yes (see playground link below)

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE="auto"
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/milesbryant/Library/Caches/go-build"
GOENV="/Users/milesbryant/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/milesbryant/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/milesbryant"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go@1.16/1.16.13/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go@1.16/1.16.13/libexec/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.17.6"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

What did you do?

Reproduction in Go playground

  • Set up a http2.Server and wrap a slow handler in h2c.NewHandler. Set http.Server.WriteTimeout that we expect to hit before the handler returns
  • Send a h2c request

What did you expect to see?

An EOF error indicating that the server hit the WriteTimeout and reset the connection.
This is what we see for both plain http.Server, and http2.Server for full HTTP/2 with TLS.

What did you see instead?

The h2c request succeeds even though the handler takes much longer than the WriteTimeout.

@gopherbot gopherbot added this to the Unreleased milestone May 12, 2022
@milesbxf
Copy link
Author

@milesbxf milesbxf commented May 12, 2022

In http2-land, it looks like the server timeouts are set via http2.ServeConnOpts.BaseConfig (which is a *http.Server which we copy config from).

This gets set for regular http2.Servers via http2.ConfigureServer

However, in h2cHandler.ServeHTTP we leave ServeConnOpts.BaseConfig as nil: https://github.com/golang/net/blob/2871e0cb64e47e47ba7466fad6e11562caf99563/http2/h2c/h2c.go#L87

I'm very happy to have a go at fixing this, but I'd love some guidance on what you think the best way forwards would be. The first challenge I can see is that the h2c package doesn't currently know anything about a *http.Server.

Perhaps we could:

  • add a new constructor h2c.NewHandlerFromServer(h http.Handler, hs *http.Server, h2s *http2.Server)
  • maintain a pointer to h2s as a hs field onh2cHandler
  • call ServeConn with &http2.ServeConnOpts{..., BaseConfig: s.hs}

cc @neild

@heschi heschi added the NeedsInvestigation label May 12, 2022
@AlexanderYastrebov
Copy link
Contributor

@AlexanderYastrebov AlexanderYastrebov commented May 27, 2022

Perhaps we could

This is what we did in our attempt zalando/skipper#1868 to fix some of the h2c long-standing issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation
Projects
None yet
Development

No branches or pull requests

4 participants