Skip to content

net/http: TimeoutHandler prevents use of ResponseController #69777

Open
@Acconut

Description

@Acconut

Go version

go version go1.23.1 darwin/arm64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/marius/Library/Caches/go-build'
GOENV='/Users/marius/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/marius/workspace/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/marius/workspace/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.23.1/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.23.1/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.23.1'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/marius/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/9c/rl48j6r51g37vvhq4vdywz280000gn/T/go-build1640827140=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

I have a http.Handler that uses http.NewResponseController on the response writer to control the response behavior. If my handler is wrapped in a http.TimeoutHandler, calls to ResponseController.SetReadTimeout, ResponseController.EnableFullDuplex return an error saying feature not supported.

https://go.dev/play/p/Bar7glioldQ contains an example for reproduction. Unfortunately, running the code in the playground often fails with an i/o timeout, but locally this problem does not appear.

What did you see happen?

Any interaction with the response controller functions returns an error saying feature not supported. Running the linked code locally produces the following output:

2024/10/04 10:35:12 feature not supported
Hello, client

The reason seems to be that TimeoutHandler wraps the response writer into its own timeoutWriter (https://cs.opensource.google/go/go/+/refs/tags/go1.23.2:src/net/http/server.go;l=3658), which neither implements the methods for ResponseController (https://pkg.go.dev/net/http#NewResponseController) nor an Unwrap function returning the original response writer. The easiest solution might be to add an Unwrap method to timeoutWriter.

I also checked if other handler wrappers in net/http interfere with ResponseController. AllowQuerySemicolons, StripPrefix, and MaxBytesHandler don't cause issues as they don't wrap the response writer.

What did you expect to see?

ResponseController should be usable together with TimeoutHandler. Running the linked code should produce the following output:

Hello, client

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions