package main import ( "html/template" "io" "log" "net/http" ) // RequestData holds all the information we want to display about a request type RequestData struct { Method string URL string Protocol string Scheme string Host string Path string RawQuery string QueryParams map[string][]string Headers map[string][]string Body string HasQuery bool } // collectRequestData extracts all relevant information from the HTTP request func collectRequestData(r *http.Request) (*RequestData, error) { body, err := io.ReadAll(r.Body) if err != nil { return nil, err } defer r.Body.Close() bodyString := string(body) if len(bodyString) == 0 { bodyString = "(empty)" } data := &RequestData{ Method: r.Method, URL: r.URL.String(), Protocol: r.Proto, Scheme: r.URL.Scheme, Host: r.Host, Path: r.URL.Path, RawQuery: r.URL.RawQuery, QueryParams: r.URL.Query(), Headers: r.Header, Body: bodyString, HasQuery: len(r.URL.Query()) > 0, } return data, nil } const echoTemplate = `

Request Echo

Request Line

Method:{{.Method}}

URL:{{.URL}}

Protocol:{{.Protocol}}

URL Components

Scheme:{{.Scheme}}

Host:{{.Host}}

Path:{{.Path}}

RawQuery:{{.RawQuery}}

Query Parameters

{{if .HasQuery}} {{range $key, $values := .QueryParams}} {{range $values}}

{{$key}}:{{.}}

{{end}} {{end}} {{else}}

No query parameters

{{end}}

Headers

{{range $name, $values := .Headers}} {{end}}
Header Value
{{$name}} {{range $i, $v := $values}}{{if $i}}, {{end}}{{$v}}{{end}}

Body

{{.Body}}
` var tmpl *template.Template func init() { var err error tmpl, err = template.New("echo").Parse(echoTemplate) if err != nil { log.Fatal("Error parsing template:", err) } } func echoHandler(w http.ResponseWriter, r *http.Request) { data, err := collectRequestData(r) if err != nil { http.Error(w, "Error reading request body", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") err = tmpl.Execute(w, data) if err != nil { log.Printf("Error executing template: %v", err) http.Error(w, "Error rendering response", http.StatusInternalServerError) } } func main() { http.HandleFunc("/echo", echoHandler) fs := http.FileServer(http.Dir("./frontend")) http.Handle("/", fs) log.Println("Starting server on http://localhost:8080") log.Println("Echo endpoint available at http://localhost:8080/echo") if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal(err) } }