github.com/scottcagno/storage@v1.8.0/pkg/web/middleware.go (about) 1 package web 2 3 import ( 4 "net/http" 5 ) 6 7 func IfOK(next http.Handler, ok bool) http.Handler { 8 fn := func(w http.ResponseWriter, r *http.Request) { 9 if !ok { 10 code := http.StatusMethodNotAllowed 11 http.Error(w, http.StatusText(code), code) 12 return 13 } 14 next.ServeHTTP(w, r) 15 } 16 return http.HandlerFunc(fn) 17 } 18 19 // StaticHandler is just a static folder handler helper 20 func StaticHandler(prefix, path string) http.Handler { 21 return http.StripPrefix(prefix, http.FileServer(http.Dir(path))) 22 } 23 24 // Middleware is a piece of middleware. 25 type Middleware func(http.Handler) http.Handler 26 27 // Chain acts as a list of http.Handler middlewares. It's effectively immutable. 28 type Chain struct { 29 mw []Middleware 30 } 31 32 // NewChain creates a new chain, memorizing the given list of middleware handlers. 33 // New serves no other function, middlewares are only called upon a call to Then(). 34 func NewChain(mw ...Middleware) *Chain { 35 return &Chain{ 36 mw: append(([]Middleware)(nil), mw...), 37 } 38 } 39 40 // Then chains the middleware and returns the final http.Handler. 41 // Then() treats nil as http.DefaultServeMux. 42 func (c *Chain) Then(handler http.Handler) http.Handler { 43 if handler == nil { 44 handler = http.DefaultServeMux 45 } 46 for i := range c.mw { 47 handler = c.mw[len(c.mw)-1-i](handler) 48 } 49 return handler 50 } 51 52 // ThenFunc works identically to Then, but takes 53 // a HandlerFunc instead of a Handler. 54 func (c *Chain) ThenFunc(handler http.HandlerFunc) http.Handler { 55 if handler == nil { 56 return c.Then(nil) 57 } 58 return c.Then(handler) 59 } 60 61 // Append extends a chain, adding the specified constructors 62 // as the last ones in the request flow. 63 func (c *Chain) Append(mw ...Middleware) *Chain { 64 nc := make([]Middleware, 0, len(c.mw)+len(mw)) 65 nc = append(nc, c.mw...) 66 nc = append(nc, mw...) 67 68 return &Chain{ 69 mw: nc, 70 } 71 } 72 73 // Extend extends a chain by adding the specified chain 74 // as the last one in the request flow. 75 func (c *Chain) Extend(chain *Chain) *Chain { 76 return c.Append(chain.mw...) 77 }