You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

chain.go 1.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. package chi
  2. import "net/http"
  3. // Chain returns a Middlewares type from a slice of middleware handlers.
  4. func Chain(middlewares ...func(http.Handler) http.Handler) Middlewares {
  5. return Middlewares(middlewares)
  6. }
  7. // Handler builds and returns a http.Handler from the chain of middlewares,
  8. // with `h http.Handler` as the final handler.
  9. func (mws Middlewares) Handler(h http.Handler) http.Handler {
  10. return &ChainHandler{mws, h, chain(mws, h)}
  11. }
  12. // HandlerFunc builds and returns a http.Handler from the chain of middlewares,
  13. // with `h http.Handler` as the final handler.
  14. func (mws Middlewares) HandlerFunc(h http.HandlerFunc) http.Handler {
  15. return &ChainHandler{mws, h, chain(mws, h)}
  16. }
  17. // ChainHandler is a http.Handler with support for handler composition and
  18. // execution.
  19. type ChainHandler struct {
  20. Middlewares Middlewares
  21. Endpoint http.Handler
  22. chain http.Handler
  23. }
  24. func (c *ChainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  25. c.chain.ServeHTTP(w, r)
  26. }
  27. // chain builds a http.Handler composed of an inline middleware stack and endpoint
  28. // handler in the order they are passed.
  29. func chain(middlewares []func(http.Handler) http.Handler, endpoint http.Handler) http.Handler {
  30. // Return ahead of time if there aren't any middlewares for the chain
  31. if len(middlewares) == 0 {
  32. return endpoint
  33. }
  34. // Wrap the end handler with the middleware chain
  35. h := middlewares[len(middlewares)-1](endpoint)
  36. for i := len(middlewares) - 2; i >= 0; i-- {
  37. h = middlewares[i](h)
  38. }
  39. return h
  40. }