package main import ( "flag" "fmt" "io" "log" "net" "net/http" "os" "time" ) func init() { const usageHeader = ` simple golang http server to log http request bodies and parameters; can optionally respond with static file content author: heqnx - https://heqnx.com ` flag.Usage = func() { fmt.Fprint(os.Stderr, usageHeader) fmt.Fprintf(os.Stderr, "usage of %s:\n", os.Args[0]) flag.PrintDefaults() } flag.CommandLine.SetOutput(os.Stderr) } func main() { listen := flag.String("listen", "0.0.0.0", "interface to listen on (default: 0.0.0.0)") port := flag.String("port", "8080", "port to listen on") cert := flag.String("cert", "", "tls certificate file (for https)") key := flag.String("key", "", "tls key file (for https)") responseFile := flag.String("response", "", "file to use as static HTTP response body") flag.Parse() if flag.NFlag() == 0 && flag.NArg() == 0 { flag.Usage() os.Exit(1) } logFilename := fmt.Sprintf("requests_%s.log", time.Now().Format("2006-01-02T15-04-05")) logFile, err := os.OpenFile(logFilename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { fmt.Printf("[err] filed to open log file: %v\n", err) } defer logFile.Close() multiLog := io.MultiWriter(os.Stdout, logFile) logger := log.New(multiLog, "", 0) var staticResponse []byte if *responseFile != "" { staticResponse, err = os.ReadFile(*responseFile) if err != nil { fmt.Printf("[err] failed to read response file: %v\n", err) } } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { body, _ := io.ReadAll(r.Body) r.Body.Close() host, _, err := net.SplitHostPort(r.RemoteAddr) if err != nil { host = r.RemoteAddr } logger.Printf("%s | %s\n", time.Now().Format("2006/01/02 15:04:05"), host) var logEntry string logEntry += fmt.Sprintf("%s %s %s\n", r.Method, r.URL.RequestURI(), r.Proto) if r.Host != "" { logEntry += fmt.Sprintf("Host: %s\n", r.Host) } for name, values := range r.Header { for _, value := range values { logEntry += fmt.Sprintf("%s: %s\n", name, value) } } logEntry += "\n" + string(body) + "\n\n---\n\n" logger.Print(logEntry) w.WriteHeader(http.StatusOK) if staticResponse != nil { _, _ = w.Write(staticResponse) } else { _, _ = w.Write([]byte("pong\n")) } }) addr := *listen + ":" + *port if *cert != "" && *key != "" { logger.Printf("[inf] starting https server on %s\n", addr) err = http.ListenAndServeTLS(addr, *cert, *key, nil) } else { logger.Printf("[inf] starting http server on %s\n", addr) err = http.ListenAndServe(addr, nil) } if err != nil { fmt.Printf("[err] server failed: %v\n", err) } }