Skip to content

Instantly share code, notes, and snippets.

@alexedwards
Last active September 22, 2022 19:08
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save alexedwards/6f9496caecb2996ac61d to your computer and use it in GitHub Desktop.
Save alexedwards/6f9496caecb2996ac61d to your computer and use it in GitHub Desktop.
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