package main import ( "fmt" "io" "log" "net/http" "time" ) const ( backendResponse = "I am the backend" backendStatus = 404 ) func main() { server := &http.Server{ Addr: ":8088", Handler: http.HandlerFunc(backendHandler), } // Run the server in a goroutine log.Println("Starting server on :8088") if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("Server failed to start: %v", err) } } func HandlePost(w http.ResponseWriter, r *http.Request) { // #1 add flusher flusher, ok := w.(http.Flusher) if !ok { panic("expected http.ResponseWriter to be an http.Flusher") } w.Header().Set("Connection", "Keep-Alive") w.Header().Set("Transfer-Encoding", "chunked") w.Header().Set("X-Content-Type-Options", "nosniff") ticker := time.NewTicker(time.Millisecond * 500) go func() { for t := range ticker.C { // #2 add '\n' io.WriteString(w, "Chunk\n") fmt.Println("Tick at", t) if flusher == nil { break } flusher.Flush() } }() time.Sleep(time.Second * 10) ticker.Stop() } func backendHandler(w http.ResponseWriter, r *http.Request) { if len(r.TransferEncoding) > 0 { log.Printf("backend got TransferEncoding: %v", r.TransferEncoding) HandlePost(w, r) return } else { log.Println("No transfer encoding received") } if r.Header.Get("X-Forwarded-For") == "" { log.Println("didn't get X-Forwarded-For header") } if g, e := r.Host, "ce.localhost"; g != e { log.Printf("backend got Host header %q, want %q", g, e) } w.Header().Set("X-Foo", "bar") http.SetCookie(w, &http.Cookie{Name: "flavor", Value: "chocolateChip"}) w.WriteHeader(backendStatus) w.Write([]byte(backendResponse)) }