Context Cancellation Signal Loss in HTTP Requests with Body
While developing an HTTP server in Go, a concern arose: the context.Done() channel failed to capture client disconnection signals for requests with a body. This behavior differed from GET requests, which successfully detected client departures.
Underlying Cause
This inconsistency stems from the functioning of the net/http server. Its connection check mechanism initiates only when the application reads the request body. Since GET requests have no body, the connection check triggers immediately, allowing the server to promptly detect client cancellation. However, for POST requests, the server waits until the body is read before commencing connection checks.
Solution
To resolve this issue, it is necessary to manually read the request body to stimulate the server's connection check process. The following code snippet demonstrates this:
func handler(w http.ResponseWriter, r *http.Request) { go func(done <-chan struct{}) { <-done fmt.Println("message", "client connection has gone away, request got cancelled") }(r.Context().Done()) io.Copy(ioutil.Discard, r.Body) // Read the body time.Sleep(30 * time.Second) fmt.Fprintf(w, "Hi there, I love %s!\n", r.URL.Path[1:]) }
By explicitly reading the request body, the server can detect client disconnections promptly, even for requests with a body. This allows for proper cleanup and resource release on the server side.
The above is the detailed content of Why Do HTTP POST Requests Miss Context Cancellation Signals in Go?. For more information, please follow other related articles on the PHP Chinese website!