Skip to content

Instantly share code, notes, and snippets.

@perillo
Created January 7, 2020 14:40
Show Gist options
  • Save perillo/d111f6400d5b25eef45214c4b0c6d381 to your computer and use it in GitHub Desktop.
Save perillo/d111f6400d5b25eef45214c4b0c6d381 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io"
"log"
"net/http"
"time"
)
type handler func(http.ResponseWriter, *http.Request)
func newReader(delay time.Duration) io.Reader {
r, w := io.Pipe()
go func() {
for {
n, err := w.Write([]byte("x\n"))
if err != nil {
log.Printf("writing request body: %v", n)
continue
}
fmt.Printf("wrote %d bytes to request body\n", n)
time.Sleep(delay)
}
w.Close()
}()
return r
}
func client(addr string, delay time.Duration) error {
addr = "http://" + addr // make a correct URL from a IP address
body := newReader(delay)
fmt.Println("starting client")
_, err := http.Post(addr, "text/plain", body)
if err != nil {
log.Fatal(err)
}
return err
}
func server(addr string, handler handler, timeout time.Duration) error {
srv := http.Server{
Addr: addr,
Handler: http.HandlerFunc(handler),
ReadTimeout: timeout,
}
fmt.Println("starting server")
return srv.ListenAndServe()
}
func handler(w http.ResponseWriter, req *http.Request) {
buf := make([]byte, 2)
ctx := req.Context()
go func() {
// A simple concurrent worker.
for {
select {
case <-ctx.Done():
log.Printf("cancelling job")
return
default:
n, err := req.Body.Read(buf)
if err != nil {
log.Printf("reading request body: %v", err)
continue // give ctx.Done a chance
}
fmt.Printf("read %d bytes from request body\n", n)
}
}
}()
// The handler will never send a response to the poor client.
select {}
}
func main() {
const (
addr = "127.0.0.1:8080"
delay = time.Second
timeout = 3 * time.Second
)
log.SetFlags(0)
go func() {
if err := server(addr, handler); err != nil {
log.Fatal(err)
}
}()
time.Sleep(1 * time.Second) // poor man synchronization with the server
client(addr) // the client will wait forever for the server response
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment