88 "net/http"
99 "net/http/httputil"
1010 "net/url"
11+ "regexp"
12+ "strings"
1113 "sync"
1214 "sync/atomic"
1315 "time"
@@ -26,6 +28,17 @@ type (
2628 // Balancer defines a load balancing technique.
2729 // Required.
2830 Balancer ProxyBalancer
31+
32+ // Rewrite defines URL path rewrite rules. The values captured in asterisk can be
33+ // retrieved by index e.g. $1, $2 and so on.
34+ // Examples:
35+ // "/old": "/new",
36+ // "/api/*": "/$1",
37+ // "/js/*": "/public/javascripts/$1",
38+ // "/users/*/orders/*": "/user/$1/order/$2",
39+ Rewrite map [string ]string
40+
41+ rewriteRegex map [* regexp.Regexp ]string
2942 }
3043
3144 // ProxyTarget defines the upstream target.
@@ -187,6 +200,13 @@ func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc {
187200 if config .Balancer == nil {
188201 panic ("echo: proxy middleware requires balancer" )
189202 }
203+ config .rewriteRegex = map [* regexp.Regexp ]string {}
204+
205+ // Initialize
206+ for k , v := range config .Rewrite {
207+ k = strings .Replace (k , "*" , "(\\ S*)" , - 1 )
208+ config .rewriteRegex [regexp .MustCompile (k )] = v
209+ }
190210
191211 return func (next echo.HandlerFunc ) echo.HandlerFunc {
192212 return func (c echo.Context ) (err error ) {
@@ -198,6 +218,14 @@ func ProxyWithConfig(config ProxyConfig) echo.MiddlewareFunc {
198218 res := c .Response ()
199219 tgt := config .Balancer .Next ()
200220
221+ // Rewrite
222+ for k , v := range config .rewriteRegex {
223+ replacer := captureTokens (k , req .URL .Path )
224+ if replacer != nil {
225+ req .URL .Path = replacer .Replace (v )
226+ }
227+ }
228+
201229 // Fix header
202230 if req .Header .Get (echo .HeaderXRealIP ) == "" {
203231 req .Header .Set (echo .HeaderXRealIP , c .RealIP ())
0 commit comments