-
Notifications
You must be signed in to change notification settings - Fork 115
Open
Description
Consider a little server that models how SSE get sent. When proxying to this, there is a lag on output for 9 seconds (the sleeps) instead of getting an incremental response. This is relevant to lambda streaming, as mentioned in #150.
package main
import (
"flag"
"fmt"
"io"
"log"
"net/http"
"time"
)
func sseHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("Access-Control-Allow-Origin", "*")
clientGone := r.Context().Done()
rc := http.NewResponseController(w)
body, err := io.ReadAll(r.Body)
if err != nil {
body = []byte("Error reading body")
}
defer r.Body.Close()
_, err = fmt.Fprintf(w, "data: === Initial Request Details ===\n")
if err != nil {
return
}
_, err = fmt.Fprintf(w, "data: Method: %s\n", r.Method)
if err != nil {
return
}
_, err = fmt.Fprintf(w, "data: URL: %s\n", r.URL.String())
if err != nil {
return
}
_, err = fmt.Fprintf(w, "data: Headers:\n")
if err != nil {
return
}
for key, values := range r.Header {
for _, value := range values {
_, err = fmt.Fprintf(w, "data: %s: %s\n", key, value)
if err != nil {
return
}
}
}
_, err = fmt.Fprintf(w, "data: Body: %s\n\n", string(body))
if err != nil {
return
}
err = rc.Flush()
if err != nil {
return
}
for i := 1; i <= 3; i++ {
select {
case <-clientGone:
fmt.Println("Client disconnected")
return
case <-time.After(time.Second * 3):
_, err := fmt.Fprintf(w, "data: Chunk %d at %s\n\n", i, time.Now().Format(time.UnixDate))
if err != nil {
return
}
err = rc.Flush()
if err != nil {
return
}
}
}
}
func main() {
var (
port = flag.String("port", "8081", "Port to listen on")
useHTTPS = flag.Bool("https", false, "Enable HTTPS")
certFile = flag.String("cert", "", "Path to TLS certificate file (required for HTTPS)")
keyFile = flag.String("key", "", "Path to TLS key file (required for HTTPS)")
)
flag.Parse()
http.HandleFunc("/events", sseHandler)
addr := ":" + *port
if *useHTTPS {
if *certFile == "" || *keyFile == "" {
log.Fatal("Both -cert and -key are required when using HTTPS")
}
fmt.Printf("Server is running on https://localhost:%s\n", *port)
if err := http.ListenAndServeTLS(addr, *certFile, *keyFile, nil); err != nil {
log.Fatal(err)
}
} else {
fmt.Printf("Server is running on http://localhost:%s\n", *port)
if err := http.ListenAndServe(addr, nil); err != nil {
log.Fatal(err)
}
}
}
Metadata
Metadata
Assignees
Labels
No labels