Go Get Notified When an HTTP Request Closes

Dec 11 2013

Most web requests by design take only a few dozen milliseconds to process. But sometimes web apps need to leave a connection open for a longer period of time. And sometimes the remote client closes the connection before the server has had time to respond.

On a Go-based webserver, you can receive notifications when the HTTP connection terminates.

Here's how you do it. <!--break-->

Start with an HTTP handler function, and get the channel for close notifications:

func SomeHandler(res http.ResonseWriter, req *http.Request) {
    // Normal stuff
    //...

    notify := res.(CloseNotifier).CloseNotify()

    go func() {
        <-notify
        fmt.Println("HTTP connection just closed.")
    }()
}

The trick here is to get the notify channel from the ResponseWriter. A ResponseWriter is also a CloseNotifier, and a CloseNotifier can return a channel (a chan bool, to be precise) that sends a message when the HTTP connection closes.

So all you need to do is get a handle to that channel and listen for messages. In the code above, we do that in a go routine:

    go func() {
        <-notify
        fmt.Println("HTTP connection just closed.")
    }()

This function waits until it receives a notification (<-notify) and then it prints out a message.

A more sophisticated program would do something on notification, like send messages on other channels to tell long-running routines to quit and clean up.

Update: Just to clarify, ResponseWriter is an interface, and the underlying implementation in the Go library also implements CloseNotifier. There is no guarantee that all implementations of ResponseWriter also implement CloseNotifier.