Skip to content

Instantly share code, notes, and snippets.

@treywelsh
Created October 2, 2020 10:43
Show Gist options
  • Save treywelsh/473389a2da70cdc386d04f870a43454a to your computer and use it in GitHub Desktop.
Save treywelsh/473389a2da70cdc386d04f870a43454a to your computer and use it in GitHub Desktop.
http server handle req context
package main
import (
"fmt"
"log"
"net"
"net/http"
"time"
)
func slowRespHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("start handle request")
defer fmt.Println("end handle request")
for i := 0; i < 15; i++ {
time.Sleep(time.Duration(1) * time.Second)
// test incoming request context before writing anything
// From the doc:
// "For incoming server requests, the context is canceled when the client's connection closes, the request is canceled (with HTTP/2), or when the ServeHTTP method returns"
select {
case <-r.Context().Done():
fmt.Println("error: request context done, does nothing")
return
default:
}
}
fmt.Printf("send foobar\n")
_, err := fmt.Fprintf(w, "foobar\n")
if err != nil {
log.Fatal("error:", err)
}
fmt.Printf("sent foobar\n")
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/slowresp", slowRespHandler)
srv := &http.Server{
Addr: ":8080",
ConnState: func(conn net.Conn, event http.ConnState) {
// log the connection state
log.Printf("addr: %s, changed state to: %s", conn.RemoteAddr(), event.String())
},
Handler: mux,
}
log.Fatal(srv.ListenAndServe())
}
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
)
func main() {
tmOutCtx, cancel := context.WithTimeout(context.Background(), time.Duration(2)*time.Second)
req, _ := http.NewRequestWithContext(tmOutCtx, "GET", "http://localhost:8080/slowresp", nil)
defer cancel()
println("Do request")
client := http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(bodyBytes))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment