Go version
go version go1.23.4 darwin/amd64
Output of go env in your module/workspace:
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/Users/user/Library/Caches/go-build'
GOENV='/Users/user/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/user/go/pkg/mod'
GOOS='darwin'
GOPATH='/Users/user/go'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/Cellar/go/1.23.4/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/usr/local/Cellar/go/1.23.4/libexec/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.23.4'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/user/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
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 x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/Users/user/Development/temp/go-build2053259560=/tmp/go-build -gno-record-gcc-switches -fno-common'
What did you do?
Start an FCGI server.
listener, err := net.Listen("tcp", ":0")
defer listener.Close()
fcgi.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Emulate some slow operation, waiting for the context to cancel
<-r.Context().Done()
fmt.Println("Done with slow operation")
}))
Using an FCGI client, or a reverse proxy like Apache with FCGI support, issue a request to the server and then close the request. Unfortunately the code for this can get quite verbose as the package only implements the server parts and I'm not sure it provides much context in this case.
What did you see happen?
The string Done with slow operation is never printed as the context is never canceled.
What did you expect to see?
According to the documentation on the http request's context field, the context should be set and canceled when the connection closes or the server closes. As I haven't found any documentation in the fcgi package stating otherwise, I expect the same to be true.
From what I can tell, the issue comes from the fcgi package never setting a context that corresponds to the incoming connection. It relies on the default context.Background() returned by http.Request.Context if it's nil.
|
httpReq, err := cgi.RequestFromMap(req.params) |
|
if err != nil { |
|
// there was an error reading the request |
|
r.WriteHeader(http.StatusInternalServerError) |
|
c.conn.writeRecord(typeStderr, req.reqId, []byte(err.Error())) |
|
} else { |
|
httpReq.Body = body |
|
withoutUsedEnvVars := filterOutUsedEnvVars(req.params) |
|
envVarCtx := context.WithValue(httpReq.Context(), envVarsContextKey{}, withoutUsedEnvVars) |
|
httpReq = httpReq.WithContext(envVarCtx) |
|
c.handler.ServeHTTP(r, httpReq) |
This makes the fcgi package difficult to use when web clients are involved as there's seemingly no way to react on aborted / closed requests, making it difficult to stop ongoing work.
Go version
go version go1.23.4 darwin/amd64
Output of
go envin your module/workspace:What did you do?
Start an FCGI server.
Using an FCGI client, or a reverse proxy like Apache with FCGI support, issue a request to the server and then close the request. Unfortunately the code for this can get quite verbose as the package only implements the server parts and I'm not sure it provides much context in this case.
What did you see happen?
The string
Done with slow operationis never printed as the context is never canceled.What did you expect to see?
According to the documentation on the http request's context field, the context should be set and canceled when the connection closes or the server closes. As I haven't found any documentation in the fcgi package stating otherwise, I expect the same to be true.
From what I can tell, the issue comes from the fcgi package never setting a context that corresponds to the incoming connection. It relies on the default
context.Background()returned byhttp.Request.Contextif it'snil.go/src/net/http/fcgi/child.go
Lines 292 to 302 in 40b3c0e
This makes the fcgi package difficult to use when web clients are involved as there's seemingly no way to react on aborted / closed requests, making it difficult to stop ongoing work.