Skip to content

Instantly share code, notes, and snippets.

@rgarcia
Created September 19, 2016 23:56
Show Gist options
  • Save rgarcia/117e8613b422c4604c2d1dfddf49322d to your computer and use it in GitHub Desktop.
Save rgarcia/117e8613b422c4604c2d1dfddf49322d to your computer and use it in GitHub Desktop.
net/http server context object does not cancel on closed connections, need to listen for closenotify
package main
import (
"context"
"fmt"
"log"
"net/http"
"time"
"golang.org/x/net/context/ctxhttp"
)
func main() {
http.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
cn, ok := w.(http.CloseNotifier)
if !ok {
log.Fatal("don't support CloseNotifier")
}
select {
case <-cn.CloseNotify():
log.Print("server handler returning after close notify")
case <-r.Context().Done():
log.Print("server handler returning after cancellation")
case <-time.After(1 * time.Second):
log.Print("server handler returning after 1 second")
}
fmt.Fprintf(w, "Hello, foo")
})
go func() {
log.Fatal(http.ListenAndServe(":8080", nil))
}()
time.Sleep(1 * time.Second)
// make some client requests
log.Print("test 1: request with no timeout")
resp, err := http.Get("http://localhost:8080/foo")
if err != nil {
log.Fatalf("unexpected error: %s", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
log.Fatalf("unexpected status code: %d", resp.StatusCode)
}
log.Print("test 2: request with a 100ms timeout via context")
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
resp, err = ctxhttp.Get(ctx, http.DefaultClient, "http://localhost:8080/foo")
if err == nil {
log.Fatal("expected an error, got nil")
} else if err.Error() != "context deadline exceeded" {
log.Fatal("expected a a context deadline exceeded error, got nil")
}
log.Print("client is done")
time.Sleep(1 * time.Second)
}
@rgarcia
Copy link
Author

rgarcia commented Sep 19, 2016

output:

2016/09/19 23:55:26 test 1: request with no timeout
2016/09/19 23:55:27 server handler returning after 1 second
2016/09/19 23:55:27 test 2: request with a 100ms timeout via context
2016/09/19 23:55:27 server handler returning after close notify
2016/09/19 23:55:27 client is done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment