package main import ( "flag" "fmt" "io" "log" "net/http" "strings" ) var ( ports = flag.String("ports", "", "comma-separated list of ports to listen on") ) type CatHandler struct{} var _ http.Handler = &CatHandler{} func (cs *CatHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { log.Printf("[%s] %s %s", req.Host, req.Method, req.URL.Path) w.Write([]byte(fmt.Sprintf("%s %s %s\n", req.Proto, req.Method, req.URL.Path))) for k, v := range req.Header { w.Write([]byte(fmt.Sprintf("%s: %s\n", k, strings.Join(v, "; ")))) } w.Write([]byte{'\n'}) if req.Body != nil { io.Copy(w, req.Body) } } func main() { flag.Parse() errch := make(chan error) done := make(chan struct{}) for _, p := range strings.Split(*ports, ",") { port := strings.TrimSpace(p) if port[0] != ':' { port = ":" + port } go func() { log.Printf("listening on %s\n", port) if err := http.ListenAndServe(port, new(CatHandler)); err != nil { log.Println(err) errch <- err } }() } go func() { <-errch done <- struct{}{} }() <-done }