rewrite.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package middleware
  2. import (
  3. "regexp"
  4. "strings"
  5. "github.com/labstack/echo"
  6. )
  7. type (
  8. // RewriteConfig defines the config for Rewrite middleware.
  9. RewriteConfig struct {
  10. // Skipper defines a function to skip middleware.
  11. Skipper Skipper
  12. // Rules defines the URL path rewrite rules. The values captured in asterisk can be
  13. // retrieved by index e.g. $1, $2 and so on.
  14. // Example:
  15. // "/old": "/new",
  16. // "/api/*": "/$1",
  17. // "/js/*": "/public/javascripts/$1",
  18. // "/users/*/orders/*": "/user/$1/order/$2",
  19. // Required.
  20. Rules map[string]string `yaml:"rules"`
  21. rulesRegex map[*regexp.Regexp]string
  22. }
  23. )
  24. var (
  25. // DefaultRewriteConfig is the default Rewrite middleware config.
  26. DefaultRewriteConfig = RewriteConfig{
  27. Skipper: DefaultSkipper,
  28. }
  29. )
  30. // Rewrite returns a Rewrite middleware.
  31. //
  32. // Rewrite middleware rewrites the URL path based on the provided rules.
  33. func Rewrite(rules map[string]string) echo.MiddlewareFunc {
  34. c := DefaultRewriteConfig
  35. c.Rules = rules
  36. return RewriteWithConfig(c)
  37. }
  38. // RewriteWithConfig returns a Rewrite middleware with config.
  39. // See: `Rewrite()`.
  40. func RewriteWithConfig(config RewriteConfig) echo.MiddlewareFunc {
  41. // Defaults
  42. if config.Rules == nil {
  43. panic("echo: rewrite middleware requires url path rewrite rules")
  44. }
  45. if config.Skipper == nil {
  46. config.Skipper = DefaultBodyDumpConfig.Skipper
  47. }
  48. config.rulesRegex = map[*regexp.Regexp]string{}
  49. // Initialize
  50. for k, v := range config.Rules {
  51. k = strings.Replace(k, "*", "(.*)", -1)
  52. k = k + "$"
  53. config.rulesRegex[regexp.MustCompile(k)] = v
  54. }
  55. return func(next echo.HandlerFunc) echo.HandlerFunc {
  56. return func(c echo.Context) (err error) {
  57. if config.Skipper(c) {
  58. return next(c)
  59. }
  60. req := c.Request()
  61. // Rewrite
  62. for k, v := range config.rulesRegex {
  63. replacer := captureTokens(k, req.URL.Path)
  64. if replacer != nil {
  65. req.URL.Path = replacer.Replace(v)
  66. break
  67. }
  68. }
  69. return next(c)
  70. }
  71. }
  72. }