Skip to content

Instantly share code, notes, and snippets.

@alexedwards
Last active Jun 25, 2021
Embed
What would you like to do?
Example of chaining middlware in Go
package main
import (
"io"
"log"
"mime"
"net/http"
"os"
"github.com/goji/httpauth"
"github.com/gorilla/handlers"
)
func main() {
logFile, err := os.OpenFile("server.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0664)
if err != nil {
log.Fatal(err)
}
loggingHandler := newLoggingHandler(logFile)
authHandler := httpauth.SimpleBasicAuth("alice", "pa$$word")
mux := http.NewServeMux()
finalHandler := http.HandlerFunc(final)
mux.Handle("/", loggingHandler(authHandler(enforceJSONHandler(finalHandler))))
log.Println("Listening on :3000...")
err = http.ListenAndServe(":3000", mux)
log.Fatal(err)
}
func enforceJSONHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
contentType := r.Header.Get("Content-Type")
if contentType != "" {
mt, _, err := mime.ParseMediaType(contentType)
if err != nil {
http.Error(w, "Malformed Content-Type header", http.StatusBadRequest)
return
}
if mt != "application/json" {
http.Error(w, "Content-Type header must be application/json", http.StatusUnsupportedMediaType)
return
}
}
next.ServeHTTP(w, r)
})
}
func newLoggingHandler(dst io.Writer) func(http.Handler) http.Handler {
return func(h http.Handler) http.Handler {
return handlers.LoggingHandler(dst, h)
}
}
func final(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment