Back
Syntax
Study
Editor
Mode:
HTML
CSS
JavaScript
PHP
Reset
Run »
HTML / CSS / JS
package main import ( "fmt" "log" "net/http" "time" ) // responseRecorder wraps ResponseWriter to capture the status code. type responseRecorder struct { http.ResponseWriter status int } func (rr *responseRecorder) WriteHeader(code int) { rr.status = code rr.ResponseWriter.WriteHeader(code) } // loggingMiddleware logs method, path, status, and duration. func loggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() rr := &responseRecorder{ResponseWriter: w, status: http.StatusOK} next.ServeHTTP(rr, r) log.Printf("%s %s %d %v", r.Method, r.URL.Path, rr.status, time.Since(start)) }) } // authMiddleware rejects requests without an API key header. func authMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("X-API-Key") != "secret" { http.Error(w, "unauthorised", http.StatusUnauthorized) return } next.ServeHTTP(w, r) }) } func chain(h http.Handler, mws ...func(http.Handler) http.Handler) http.Handler { for i := len(mws) - 1; i >= 0; i-- { h = mws[i](h) } return h } func main() { hello := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello, authenticated user!") }) mux := http.NewServeMux() mux.Handle("/secure", chain(hello, loggingMiddleware, authMiddleware)) mux.Handle("/public", loggingMiddleware( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello, public!") }), )) log.Println("listening on :8080") log.Fatal(http.ListenAndServe(":8080", mux)) }
Result
Open