Skip to content

Instantly share code, notes, and snippets.

@prestonp
Created July 6, 2016 13:38
Show Gist options
  • Save prestonp/504d60b717f3c3c131f685972ebf21eb to your computer and use it in GitHub Desktop.
Save prestonp/504d60b717f3c3c131f685972ebf21eb to your computer and use it in GitHub Desktop.
middleware pattern go
package main
import (
"log"
"net/http"
"github.com/gorilla/mux"
)
// FooList handles listing foos
func FooList(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(200)
response := "OK"
log.Println(response)
w.Write([]byte(response))
}
// Decorator for http.HandlerFunc
type Decorator func(fn http.HandlerFunc) http.HandlerFunc
// Logger middleware
func Logger(s string) Decorator {
return func(fn http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
log.Println(s)
fn.ServeHTTP(w, req)
}
}
}
// Authorize checks Authorization header for a given token
func Authorize(token string) Decorator {
return func(fn http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
log.Println("Checking authorization")
// Check if the token matches one of the Authorization values
for _, val := range req.Header["Authorization"] {
if token == val {
fn.ServeHTTP(w, req)
return
}
}
// No matches, req is unauthorized
w.WriteHeader(401)
w.Write([]byte("Unauthorized"))
}
}
}
// Decorate applies decorations to a http.Handler
func Decorate(h http.HandlerFunc, decorators ...Decorator) http.HandlerFunc {
for _, decorator := range decorators {
h = decorator(h)
}
return h
}
func main() {
router := mux.NewRouter().StrictSlash(true)
// FooList is the end handler, Authorize & Logger are middleware applied in reverse order
router.HandleFunc("/foos", Decorate(FooList, Authorize("penguin"), Logger("GET List of Foos"))).Methods("GET")
log.Fatal(http.ListenAndServe(":8080", router))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment