问题
Is it possible using the net/http package and/or any of the gorilla libraries to make some code execute on EVERY URL before going to the handler? For example, to check if a connection is coming from a black listed IP address?
回答1:
Create a handler that invokes another handler after checking the IP address:
type checker struct {
h http.Handler
}
func (c checker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if blackListed(r.RemoteAddr) {
http.Error(w, "not authorized", http.StatusForbidden)
return
}
c.h.ServeHTTP(w, r)
}
Pass this handler to ListenAndServe instead of your original handler. For example, if you had:
err := http.ListenAndServe(addr, mux)
change the code to
err := http.ListenAndServe(addr, checker{mux})
This also applies to all the variations of ListenAndServe. It works with http.ServeMux, Gorilla mux and other routers.
回答2:
If you want to use the default muxer, which i find is common, you can create middleware like so:
func mustBeLoggedIn(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
// Am i logged in?
if ...not logged in... {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
// Pass through to the original handler.
handler(w, r)
}
}
Use it like so:
http.HandleFunc("/some/priveliged/action", mustBeLoggedIn(myVanillaHandler))
http.ListenAndServe(":80", nil)
来源:https://stackoverflow.com/questions/28070923/golang-net-http-and-gorilla-run-code-before-handler