Skip to content

Instantly share code, notes, and snippets.

@mtilson
Last active December 31, 2019 02:58
Show Gist options
  • Save mtilson/d6bf0308dd6f855f4274a723ce1435ef to your computer and use it in GitHub Desktop.
Save mtilson/d6bf0308dd6f855f4274a723ce1435ef to your computer and use it in GitHub Desktop.
how to create middleware with net/http HandleFunc() [golang]
package main
import (
"log"
"net/http"
)
func main() {
http.HandleFunc("/abc", abcMiddleware(doABC))
http.HandleFunc("/abc/by-pass-abc-middleware", doABC)
http.HandleFunc("/xyz", xyzMiddleware(doXYZ))
http.HandleFunc("/xyz/by-pass-xyz-middleware", doXYZ)
http.ListenAndServe(":8080", nil)
}
func doABC(w http.ResponseWriter, r *http.Request) {
log.Println("do something every time ABC handler invoked")
w.WriteHeader(http.StatusOK)
}
func abcMiddleware(next http.HandlerFunc) http.HandlerFunc {
log.Println("do something only once on ABC middleware init")
return func(w http.ResponseWriter, r *http.Request) {
log.Println("do something every time middleware for ABC handler invoked ")
next(w, r)
}
}
func doXYZ(w http.ResponseWriter, r *http.Request) {
log.Println("do something every time XYZ handler invoked")
w.WriteHeader(http.StatusOK)
}
func xyzMiddleware(next http.HandlerFunc) http.HandlerFunc {
log.Println("do something only once on XYZ middleware init")
return func(w http.ResponseWriter, r *http.Request) {
log.Println("do something every time middleware for XYZ handler invoked ")
next(w, r)
}
}
$ go run ./m1/*.go
2019/12/31 05:54:33 do something only once on ABC middleware init
2019/12/31 05:54:33 do something only once on XYZ middleware init
>>>
>>> get http://localhost:8080/abc
>>>
2019/12/31 05:55:34 do something every time middleware for ABC handler invoked
2019/12/31 05:55:34 do something every time ABC handler invoked
>>>
>>> get http://localhost:8080/abc/by-pass-abc-middleware
>>>
2019/12/31 05:56:28 do something every time ABC handler invoked
>>>
>>> get http://localhost:8080/xyz
>>>
2019/12/31 05:57:21 do something every time middleware for XYZ handler invoked
2019/12/31 05:57:21 do something every time XYZ handler invoked
>>>
>>> get http://localhost:8080/xyz/by-pass-xyz-middleware
>>>
2019/12/31 05:58:02 do something every time XYZ handler invoked
@mtilson
Copy link
Author

mtilson commented Dec 20, 2019

Avoid usage of DefaultServeMux in production code due to its security risk

  • DefaultServeMux is global variable and if you accidentally import any compromised third-party package, it could potentially register a route in DefaultServeMux and expose to the world some malicious handler
  • You can use ServeMux locally scoped (to the func main() in the example above) and returned with http.NewServeMux()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment