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.
 
 
 

73 lines
2.4 KiB

  1. package mux
  2. import (
  3. "net/http"
  4. "strings"
  5. )
  6. // MiddlewareFunc is a function which receives an http.Handler and returns another http.Handler.
  7. // Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed
  8. // to it, and then calls the handler passed as parameter to the MiddlewareFunc.
  9. type MiddlewareFunc func(http.Handler) http.Handler
  10. // middleware interface is anything which implements a MiddlewareFunc named Middleware.
  11. type middleware interface {
  12. Middleware(handler http.Handler) http.Handler
  13. }
  14. // Middleware allows MiddlewareFunc to implement the middleware interface.
  15. func (mw MiddlewareFunc) Middleware(handler http.Handler) http.Handler {
  16. return mw(handler)
  17. }
  18. // Use appends a MiddlewareFunc to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router.
  19. func (r *Router) Use(mwf ...MiddlewareFunc) {
  20. for _, fn := range mwf {
  21. r.middlewares = append(r.middlewares, fn)
  22. }
  23. }
  24. // useInterface appends a middleware to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router.
  25. func (r *Router) useInterface(mw middleware) {
  26. r.middlewares = append(r.middlewares, mw)
  27. }
  28. // CORSMethodMiddleware sets the Access-Control-Allow-Methods response header
  29. // on a request, by matching routes based only on paths. It also handles
  30. // OPTIONS requests, by settings Access-Control-Allow-Methods, and then
  31. // returning without calling the next http handler.
  32. func CORSMethodMiddleware(r *Router) MiddlewareFunc {
  33. return func(next http.Handler) http.Handler {
  34. return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
  35. var allMethods []string
  36. err := r.Walk(func(route *Route, _ *Router, _ []*Route) error {
  37. for _, m := range route.matchers {
  38. if _, ok := m.(*routeRegexp); ok {
  39. if m.Match(req, &RouteMatch{}) {
  40. methods, err := route.GetMethods()
  41. if err != nil {
  42. return err
  43. }
  44. allMethods = append(allMethods, methods...)
  45. }
  46. break
  47. }
  48. }
  49. return nil
  50. })
  51. if err == nil {
  52. w.Header().Set("Access-Control-Allow-Methods", strings.Join(append(allMethods, "OPTIONS"), ","))
  53. if req.Method == "OPTIONS" {
  54. return
  55. }
  56. }
  57. next.ServeHTTP(w, req)
  58. })
  59. }
  60. }