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  }