50 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			50 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package chi
 | |
| 
 | |
| import "net/http"
 | |
| 
 | |
| // Chain returns a Middlewares type from a slice of middleware handlers.
 | |
| func Chain(middlewares ...func(http.Handler) http.Handler) Middlewares {
 | |
| 	return Middlewares(middlewares)
 | |
| }
 | |
| 
 | |
| // Handler builds and returns a http.Handler from the chain of middlewares,
 | |
| // with `h http.Handler` as the final handler.
 | |
| func (mws Middlewares) Handler(h http.Handler) http.Handler {
 | |
| 	return &ChainHandler{mws, h, chain(mws, h)}
 | |
| }
 | |
| 
 | |
| // HandlerFunc builds and returns a http.Handler from the chain of middlewares,
 | |
| // with `h http.Handler` as the final handler.
 | |
| func (mws Middlewares) HandlerFunc(h http.HandlerFunc) http.Handler {
 | |
| 	return &ChainHandler{mws, h, chain(mws, h)}
 | |
| }
 | |
| 
 | |
| // ChainHandler is a http.Handler with support for handler composition and
 | |
| // execution.
 | |
| type ChainHandler struct {
 | |
| 	Middlewares Middlewares
 | |
| 	Endpoint    http.Handler
 | |
| 	chain       http.Handler
 | |
| }
 | |
| 
 | |
| func (c *ChainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | |
| 	c.chain.ServeHTTP(w, r)
 | |
| }
 | |
| 
 | |
| // chain builds a http.Handler composed of an inline middleware stack and endpoint
 | |
| // handler in the order they are passed.
 | |
| func chain(middlewares []func(http.Handler) http.Handler, endpoint http.Handler) http.Handler {
 | |
| 	// Return ahead of time if there aren't any middlewares for the chain
 | |
| 	if len(middlewares) == 0 {
 | |
| 		return endpoint
 | |
| 	}
 | |
| 
 | |
| 	// Wrap the end handler with the middleware chain
 | |
| 	h := middlewares[len(middlewares)-1](endpoint)
 | |
| 	for i := len(middlewares) - 2; i >= 0; i-- {
 | |
| 		h = middlewares[i](h)
 | |
| 	}
 | |
| 
 | |
| 	return h
 | |
| }
 |