diff --git a/middleware/rewrite/rewrite.go b/middleware/rewrite/rewrite.go index 7d9793b2..1c2e2600 100644 --- a/middleware/rewrite/rewrite.go +++ b/middleware/rewrite/rewrite.go @@ -5,6 +5,7 @@ package rewrite import ( "fmt" "net/http" + "net/url" "path" "path/filepath" "regexp" @@ -165,7 +166,17 @@ func (r *ComplexRule) Rewrite(fs http.FileSystem, req *http.Request) (re Result) return default: // set regexp match variables {1}, {2} ... + + // url escaped values of ? and #. + q, f := url.QueryEscape("?"), url.QueryEscape("#") + for i := 1; i < len(matches); i++ { + // Special case of unescaped # and ? by stdlib regexp. + // Reverse the unescape. + if strings.ContainsAny(matches[i], "?#") { + matches[i] = strings.NewReplacer("?", q, "#", f).Replace(matches[i]) + } + replacer.Set(fmt.Sprint(i), matches[i]) } } diff --git a/middleware/rewrite/rewrite_test.go b/middleware/rewrite/rewrite_test.go index 6f03116d..2baf9121 100644 --- a/middleware/rewrite/rewrite_test.go +++ b/middleware/rewrite/rewrite_test.go @@ -34,6 +34,7 @@ func TestRewrite(t *testing.T) { {"/reggrp", `/ad/([0-9]+)([a-z]*)`, "/a{1}/{2}", ""}, {"/reg2grp", `(.*)`, "/{1}", ""}, {"/reg3grp", `(.*)/(.*)/(.*)`, "/{1}{2}{3}", ""}, + {"/hashtest", "(.*)", "/{1}", ""}, } for _, regexpRule := range regexps { @@ -90,6 +91,9 @@ func TestRewrite(t *testing.T) { {"/reg2grp/ad/124abc", "/ad/124abc"}, {"/reg3grp/ad/aa/66", "/adaa66"}, {"/reg3grp/ad612/n1n/ab", "/ad612n1nab"}, + {"/hashtest/a%20%23%20test", "/a%20%23%20test"}, + {"/hashtest/a%20%3F%20test", "/a%20%3F%20test"}, + {"/hashtest/a%20%3F%23test", "/a%20%3F%23test"}, } for i, test := range tests { @@ -154,6 +158,6 @@ func TestRewrite(t *testing.T) { } func urlPrinter(w http.ResponseWriter, r *http.Request) (int, error) { - fmt.Fprintf(w, r.URL.String()) + fmt.Fprint(w, r.URL.String()) return 0, nil }