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.

url_format.go 1.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package middleware
  2. import (
  3. "context"
  4. "net/http"
  5. "strings"
  6. "github.com/go-chi/chi/v5"
  7. )
  8. var (
  9. // URLFormatCtxKey is the context.Context key to store the URL format data
  10. // for a request.
  11. URLFormatCtxKey = &contextKey{"URLFormat"}
  12. )
  13. // URLFormat is a middleware that parses the url extension from a request path and stores it
  14. // on the context as a string under the key `middleware.URLFormatCtxKey`. The middleware will
  15. // trim the suffix from the routing path and continue routing.
  16. //
  17. // Routers should not include a url parameter for the suffix when using this middleware.
  18. //
  19. // Sample usage.. for url paths: `/articles/1`, `/articles/1.json` and `/articles/1.xml`
  20. //
  21. // func routes() http.Handler {
  22. // r := chi.NewRouter()
  23. // r.Use(middleware.URLFormat)
  24. //
  25. // r.Get("/articles/{id}", ListArticles)
  26. //
  27. // return r
  28. // }
  29. //
  30. // func ListArticles(w http.ResponseWriter, r *http.Request) {
  31. // urlFormat, _ := r.Context().Value(middleware.URLFormatCtxKey).(string)
  32. //
  33. // switch urlFormat {
  34. // case "json":
  35. // render.JSON(w, r, articles)
  36. // case "xml:"
  37. // render.XML(w, r, articles)
  38. // default:
  39. // render.JSON(w, r, articles)
  40. // }
  41. // }
  42. //
  43. func URLFormat(next http.Handler) http.Handler {
  44. fn := func(w http.ResponseWriter, r *http.Request) {
  45. ctx := r.Context()
  46. var format string
  47. path := r.URL.Path
  48. if strings.Index(path, ".") > 0 {
  49. base := strings.LastIndex(path, "/")
  50. idx := strings.LastIndex(path[base:], ".")
  51. if idx > 0 {
  52. idx += base
  53. format = path[idx+1:]
  54. rctx := chi.RouteContext(r.Context())
  55. rctx.RoutePath = path[:idx]
  56. }
  57. }
  58. r = r.WithContext(context.WithValue(ctx, URLFormatCtxKey, format))
  59. next.ServeHTTP(w, r)
  60. }
  61. return http.HandlerFunc(fn)
  62. }