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.

strip.go 1.7KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package middleware
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/go-chi/chi/v5"
  6. )
  7. // StripSlashes is a middleware that will match request paths with a trailing
  8. // slash, strip it from the path and continue routing through the mux, if a route
  9. // matches, then it will serve the handler.
  10. func StripSlashes(next http.Handler) http.Handler {
  11. fn := func(w http.ResponseWriter, r *http.Request) {
  12. var path string
  13. rctx := chi.RouteContext(r.Context())
  14. if rctx != nil && rctx.RoutePath != "" {
  15. path = rctx.RoutePath
  16. } else {
  17. path = r.URL.Path
  18. }
  19. if len(path) > 1 && path[len(path)-1] == '/' {
  20. newPath := path[:len(path)-1]
  21. if rctx == nil {
  22. r.URL.Path = newPath
  23. } else {
  24. rctx.RoutePath = newPath
  25. }
  26. }
  27. next.ServeHTTP(w, r)
  28. }
  29. return http.HandlerFunc(fn)
  30. }
  31. // RedirectSlashes is a middleware that will match request paths with a trailing
  32. // slash and redirect to the same path, less the trailing slash.
  33. //
  34. // NOTE: RedirectSlashes middleware is *incompatible* with http.FileServer,
  35. // see https://github.com/go-chi/chi/issues/343
  36. func RedirectSlashes(next http.Handler) http.Handler {
  37. fn := func(w http.ResponseWriter, r *http.Request) {
  38. var path string
  39. rctx := chi.RouteContext(r.Context())
  40. if rctx != nil && rctx.RoutePath != "" {
  41. path = rctx.RoutePath
  42. } else {
  43. path = r.URL.Path
  44. }
  45. if len(path) > 1 && path[len(path)-1] == '/' {
  46. if r.URL.RawQuery != "" {
  47. path = fmt.Sprintf("%s?%s", path[:len(path)-1], r.URL.RawQuery)
  48. } else {
  49. path = path[:len(path)-1]
  50. }
  51. redirectURL := fmt.Sprintf("//%s%s", r.Host, path)
  52. http.Redirect(w, r, redirectURL, 301)
  53. return
  54. }
  55. next.ServeHTTP(w, r)
  56. }
  57. return http.HandlerFunc(fn)
  58. }