From 84da507a2ebd52e616bb9f76cbfbcaeb369ecf68 Mon Sep 17 00:00:00 2001 From: chotow Date: Wed, 17 Jun 2020 12:44:24 +0800 Subject: [PATCH 1/3] Fixes the uses of caret(^) in rewrite regex --- middleware/rewrite.go | 4 ++++ middleware/rewrite_test.go | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/middleware/rewrite.go b/middleware/rewrite.go index d1387af0f..241bde9b8 100644 --- a/middleware/rewrite.go +++ b/middleware/rewrite.go @@ -59,7 +59,11 @@ func RewriteWithConfig(config RewriteConfig) echo.MiddlewareFunc { for k, v := range config.Rules { k = regexp.QuoteMeta(k) k = strings.Replace(k, `\*`, "(.*)", -1) + k = strings.Replace(k, `\^`, "^", -1) k = k + "$" + if strings.HasPrefix(k, "/") { + k = "^" + k + } config.rulesRegex[regexp.MustCompile(k)] = v } diff --git a/middleware/rewrite_test.go b/middleware/rewrite_test.go index eb5a46d89..6d89c13cf 100644 --- a/middleware/rewrite_test.go +++ b/middleware/rewrite_test.go @@ -18,6 +18,10 @@ func TestRewrite(t *testing.T) { "/api/*": "/$1", "/js/*": "/public/javascripts/$1", "/users/*/orders/*": "/user/$1/order/$2", + "/foo/*": "/v1/foo/$1", + "/v1/foo/*": "/v1/foo/$1", + "/v2/foo/*": "/v2/foo/$1", + "^/bar/*": "/foobar/$1", }, })) req := httptest.NewRequest(http.MethodGet, "/", nil) @@ -37,6 +41,18 @@ func TestRewrite(t *testing.T) { req.URL.Path = "/api/new users" e.ServeHTTP(rec, req) assert.Equal(t, "/new users", req.URL.Path) + req.URL.Path = "/foo/bar" + e.ServeHTTP(rec, req) + assert.Equal(t, "/v1/foo/bar", req.URL.Path) + req.URL.Path = "/v1/foo/bar" + e.ServeHTTP(rec, req) + assert.Equal(t, "/v1/foo/bar", req.URL.Path) + req.URL.Path = "/v2/foo/bar" + e.ServeHTTP(rec, req) + assert.Equal(t, "/v2/foo/bar", req.URL.Path) + req.URL.Path = "/bar/baz" + e.ServeHTTP(rec, req) + assert.Equal(t, "/foobar/baz", req.URL.Path) } // Issue #1086 From 68e8bce6450e66aa0da1f70e0fb7119a6d34030b Mon Sep 17 00:00:00 2001 From: chotow Date: Fri, 24 Jul 2020 21:55:27 +0800 Subject: [PATCH 2/3] Revert "Fixes the uses of caret(^) in rewrite regex" This reverts commit 1f51469436e3612e8e121413df905dc9f4ffed0b. --- middleware/rewrite.go | 4 ---- middleware/rewrite_test.go | 16 ---------------- 2 files changed, 20 deletions(-) diff --git a/middleware/rewrite.go b/middleware/rewrite.go index 241bde9b8..d1387af0f 100644 --- a/middleware/rewrite.go +++ b/middleware/rewrite.go @@ -59,11 +59,7 @@ func RewriteWithConfig(config RewriteConfig) echo.MiddlewareFunc { for k, v := range config.Rules { k = regexp.QuoteMeta(k) k = strings.Replace(k, `\*`, "(.*)", -1) - k = strings.Replace(k, `\^`, "^", -1) k = k + "$" - if strings.HasPrefix(k, "/") { - k = "^" + k - } config.rulesRegex[regexp.MustCompile(k)] = v } diff --git a/middleware/rewrite_test.go b/middleware/rewrite_test.go index 6d89c13cf..eb5a46d89 100644 --- a/middleware/rewrite_test.go +++ b/middleware/rewrite_test.go @@ -18,10 +18,6 @@ func TestRewrite(t *testing.T) { "/api/*": "/$1", "/js/*": "/public/javascripts/$1", "/users/*/orders/*": "/user/$1/order/$2", - "/foo/*": "/v1/foo/$1", - "/v1/foo/*": "/v1/foo/$1", - "/v2/foo/*": "/v2/foo/$1", - "^/bar/*": "/foobar/$1", }, })) req := httptest.NewRequest(http.MethodGet, "/", nil) @@ -41,18 +37,6 @@ func TestRewrite(t *testing.T) { req.URL.Path = "/api/new users" e.ServeHTTP(rec, req) assert.Equal(t, "/new users", req.URL.Path) - req.URL.Path = "/foo/bar" - e.ServeHTTP(rec, req) - assert.Equal(t, "/v1/foo/bar", req.URL.Path) - req.URL.Path = "/v1/foo/bar" - e.ServeHTTP(rec, req) - assert.Equal(t, "/v1/foo/bar", req.URL.Path) - req.URL.Path = "/v2/foo/bar" - e.ServeHTTP(rec, req) - assert.Equal(t, "/v2/foo/bar", req.URL.Path) - req.URL.Path = "/bar/baz" - e.ServeHTTP(rec, req) - assert.Equal(t, "/foobar/baz", req.URL.Path) } // Issue #1086 From 3dbd5dcf6e134d8b12875700dfc1c8d3f19dccb2 Mon Sep 17 00:00:00 2001 From: chotow Date: Fri, 24 Jul 2020 22:01:19 +0800 Subject: [PATCH 3/3] Fixes the uses of caret(^) at the beginning of the rewrite regex --- middleware/rewrite.go | 3 +++ middleware/rewrite_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/middleware/rewrite.go b/middleware/rewrite.go index d1387af0f..476023f6d 100644 --- a/middleware/rewrite.go +++ b/middleware/rewrite.go @@ -59,6 +59,9 @@ func RewriteWithConfig(config RewriteConfig) echo.MiddlewareFunc { for k, v := range config.Rules { k = regexp.QuoteMeta(k) k = strings.Replace(k, `\*`, "(.*)", -1) + if strings.HasPrefix(k, `\^`) { + k = strings.Replace(k, `\^`, "^", -1) + } k = k + "$" config.rulesRegex[regexp.MustCompile(k)] = v } diff --git a/middleware/rewrite_test.go b/middleware/rewrite_test.go index eb5a46d89..848f0029f 100644 --- a/middleware/rewrite_test.go +++ b/middleware/rewrite_test.go @@ -94,3 +94,30 @@ func TestRewriteWithConfigPreMiddleware_Issue1143(t *testing.T) { assert.Equal(t, "hosts", string(bodyBytes)) } } + +// Issue #1573 +func TestEchoRewriteWithCaret(t *testing.T) { + e := echo.New() + + e.Pre(RewriteWithConfig(RewriteConfig{ + Rules: map[string]string{ + "^/abc/*": "/v1/abc/$1", + }, + })) + + rec := httptest.NewRecorder() + + var req *http.Request + + req = httptest.NewRequest(http.MethodGet, "/abc/test", nil) + e.ServeHTTP(rec, req) + assert.Equal(t, "/v1/abc/test", req.URL.Path) + + req = httptest.NewRequest(http.MethodGet, "/v1/abc/test", nil) + e.ServeHTTP(rec, req) + assert.Equal(t, "/v1/abc/test", req.URL.Path) + + req = httptest.NewRequest(http.MethodGet, "/v2/abc/test", nil) + e.ServeHTTP(rec, req) + assert.Equal(t, "/v2/abc/test", req.URL.Path) +}