45 lines
1.4 KiB
Go
45 lines
1.4 KiB
Go
|
package middleware
|
||
|
|
||
|
import "net/http"
|
||
|
|
||
|
type (
|
||
|
// Interceptor intercepts an HTTP handler invocation, it is passed both
|
||
|
// response writer and request which after interception can be passed
|
||
|
// onto the handler function.
|
||
|
Interceptor func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
|
||
|
|
||
|
// HandlerFunc builds on top of http.HandlerFunc, and exposes API to
|
||
|
// intercept with Interceptor. This allows building complex long chains
|
||
|
// without complicated struct manipulation.
|
||
|
HandlerFunc http.HandlerFunc
|
||
|
|
||
|
// Chain is a collection of interceptors that will be invoked in there
|
||
|
// index order.
|
||
|
Chain []Interceptor
|
||
|
|
||
|
// Skipper is a requests checker for middleware configurations. true
|
||
|
// return force middleware to skip any actions with current request.
|
||
|
Skipper func(r *http.Request) bool
|
||
|
)
|
||
|
|
||
|
var DefaultSkipper Skipper = func(_ *http.Request) bool { return false }
|
||
|
|
||
|
// Intercept returns back a continuation that will call install middleware to
|
||
|
// intercept the continuation call.
|
||
|
func (hf HandlerFunc) Intercept(i Interceptor) HandlerFunc {
|
||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||
|
i(w, r, http.HandlerFunc(hf))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Handler allows hooking multiple middleware in single call.
|
||
|
func (c Chain) Handler(hf http.HandlerFunc) http.Handler {
|
||
|
current := HandlerFunc(hf)
|
||
|
|
||
|
for i := len(c) - 1; i >= 0; i-- {
|
||
|
current = current.Intercept(c[i])
|
||
|
}
|
||
|
|
||
|
return http.HandlerFunc(current)
|
||
|
}
|