3 changed files with 342 additions and 55 deletions
@ -0,0 +1,242 @@ |
|||
// Copyright 2015 Matthew Holt and The Caddy Authors
|
|||
//
|
|||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
// you may not use this file except in compliance with the License.
|
|||
// You may obtain a copy of the License at
|
|||
//
|
|||
// http://www.apache.org/licenses/LICENSE-2.0
|
|||
//
|
|||
// Unless required by applicable law or agreed to in writing, software
|
|||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
// See the License for the specific language governing permissions and
|
|||
// limitations under the License.
|
|||
|
|||
package rewrite |
|||
|
|||
import ( |
|||
"net/http" |
|||
"testing" |
|||
|
|||
"github.com/caddyserver/caddy/v2" |
|||
) |
|||
|
|||
func TestRewrite(t *testing.T) { |
|||
repl := caddy.NewReplacer() |
|||
|
|||
for i, tc := range []struct { |
|||
input, expect *http.Request |
|||
rule Rewrite |
|||
}{ |
|||
{ |
|||
input: newRequest(t, "GET", "/"), |
|||
expect: newRequest(t, "GET", "/"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{Method: "GET", URI: "/"}, |
|||
input: newRequest(t, "GET", "/"), |
|||
expect: newRequest(t, "GET", "/"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{Method: "POST"}, |
|||
input: newRequest(t, "GET", "/"), |
|||
expect: newRequest(t, "POST", "/"), |
|||
}, |
|||
|
|||
{ |
|||
rule: Rewrite{URI: "/foo"}, |
|||
input: newRequest(t, "GET", "/"), |
|||
expect: newRequest(t, "GET", "/foo"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "/foo"}, |
|||
input: newRequest(t, "GET", "/bar"), |
|||
expect: newRequest(t, "GET", "/foo"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "foo"}, |
|||
input: newRequest(t, "GET", "/"), |
|||
expect: newRequest(t, "GET", "foo"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "/foo{http.request.uri.path}"}, |
|||
input: newRequest(t, "GET", "/bar"), |
|||
expect: newRequest(t, "GET", "/foo/bar"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "/?c=d"}, |
|||
input: newRequest(t, "GET", "/"), |
|||
expect: newRequest(t, "GET", "/?c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "/?c=d"}, |
|||
input: newRequest(t, "GET", "/?a=b"), |
|||
expect: newRequest(t, "GET", "/?c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "?c=d"}, |
|||
input: newRequest(t, "GET", "/foo"), |
|||
expect: newRequest(t, "GET", "/foo?c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "/?c=d"}, |
|||
input: newRequest(t, "GET", "/foo"), |
|||
expect: newRequest(t, "GET", "/?c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "/?{http.request.uri.query}&c=d"}, |
|||
input: newRequest(t, "GET", "/"), |
|||
expect: newRequest(t, "GET", "/?c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "/foo?{http.request.uri.query}&c=d"}, |
|||
input: newRequest(t, "GET", "/"), |
|||
expect: newRequest(t, "GET", "/foo?c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "?{http.request.uri.query}&c=d"}, |
|||
input: newRequest(t, "GET", "/foo"), |
|||
expect: newRequest(t, "GET", "/foo?c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "{http.request.uri.path}?{http.request.uri.query}&c=d"}, |
|||
input: newRequest(t, "GET", "/foo"), |
|||
expect: newRequest(t, "GET", "/foo?c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "{http.request.uri.path}{http.request.uri.query_string}&c=d"}, |
|||
input: newRequest(t, "GET", "/foo"), |
|||
expect: newRequest(t, "GET", "/foo?c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "/index.php?{http.request.uri.query}&c=d"}, |
|||
input: newRequest(t, "GET", "/foo"), |
|||
expect: newRequest(t, "GET", "/index.php?c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "?a=b&c=d"}, |
|||
input: newRequest(t, "GET", "/foo"), |
|||
expect: newRequest(t, "GET", "/foo?a=b&c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "/index.php?{http.request.uri.query}&c=d"}, |
|||
input: newRequest(t, "GET", "/?a=b"), |
|||
expect: newRequest(t, "GET", "/index.php?a=b&c=d"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "/index.php?c=d&{http.request.uri.query}"}, |
|||
input: newRequest(t, "GET", "/?a=b"), |
|||
expect: newRequest(t, "GET", "/index.php?c=d&a=b"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URI: "/index.php?{http.request.uri.query}&p={http.request.uri.path}"}, |
|||
input: newRequest(t, "GET", "/foo/bar?a=b"), |
|||
expect: newRequest(t, "GET", "/index.php?a=b&p=/foo/bar"), |
|||
}, |
|||
|
|||
{ |
|||
rule: Rewrite{StripPathPrefix: "/prefix"}, |
|||
input: newRequest(t, "GET", "/foo/bar"), |
|||
expect: newRequest(t, "GET", "/foo/bar"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{StripPathPrefix: "/prefix"}, |
|||
input: newRequest(t, "GET", "/prefix/foo/bar"), |
|||
expect: newRequest(t, "GET", "/foo/bar"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{StripPathPrefix: "/prefix"}, |
|||
input: newRequest(t, "GET", "/foo/prefix/bar"), |
|||
expect: newRequest(t, "GET", "/foo/prefix/bar"), |
|||
}, |
|||
|
|||
{ |
|||
rule: Rewrite{StripPathSuffix: "/suffix"}, |
|||
input: newRequest(t, "GET", "/foo/bar"), |
|||
expect: newRequest(t, "GET", "/foo/bar"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{StripPathSuffix: "suffix"}, |
|||
input: newRequest(t, "GET", "/foo/bar/suffix"), |
|||
expect: newRequest(t, "GET", "/foo/bar/"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{StripPathSuffix: "/suffix"}, |
|||
input: newRequest(t, "GET", "/foo/suffix/bar"), |
|||
expect: newRequest(t, "GET", "/foo/suffix/bar"), |
|||
}, |
|||
|
|||
{ |
|||
rule: Rewrite{URISubstring: []replacer{{Find: "findme", Replace: "replaced"}}}, |
|||
input: newRequest(t, "GET", "/foo/bar"), |
|||
expect: newRequest(t, "GET", "/foo/bar"), |
|||
}, |
|||
{ |
|||
rule: Rewrite{URISubstring: []replacer{{Find: "findme", Replace: "replaced"}}}, |
|||
input: newRequest(t, "GET", "/foo/findme/bar"), |
|||
expect: newRequest(t, "GET", "/foo/replaced/bar"), |
|||
}, |
|||
} { |
|||
// copy the original input just enough so that we can
|
|||
// compare it after the rewrite to see if it changed
|
|||
originalInput := &http.Request{ |
|||
Method: tc.input.Method, |
|||
RequestURI: tc.input.RequestURI, |
|||
URL: &*tc.input.URL, |
|||
} |
|||
|
|||
// populate the replacer just enough for our tests
|
|||
repl.Set("http.request.uri.path", tc.input.URL.Path) |
|||
repl.Set("http.request.uri.query", tc.input.URL.RawQuery) |
|||
repl.Set("http.request.uri.query_string", "?"+tc.input.URL.Query().Encode()) |
|||
|
|||
changed := tc.rule.rewrite(tc.input, repl, nil) |
|||
|
|||
if expected, actual := !reqEqual(originalInput, tc.input), changed; expected != actual { |
|||
t.Errorf("Test %d: Expected changed=%t but was %t", i, expected, actual) |
|||
} |
|||
if expected, actual := tc.expect.Method, tc.input.Method; expected != actual { |
|||
t.Errorf("Test %d: Expected Method='%s' but got '%s'", i, expected, actual) |
|||
} |
|||
if expected, actual := tc.expect.RequestURI, tc.input.RequestURI; expected != actual { |
|||
t.Errorf("Test %d: Expected RequestURI='%s' but got '%s'", i, expected, actual) |
|||
} |
|||
if expected, actual := tc.expect.URL.String(), tc.input.URL.String(); expected != actual { |
|||
t.Errorf("Test %d: Expected URL='%s' but got '%s'", i, expected, actual) |
|||
} |
|||
if expected, actual := tc.expect.URL.RequestURI(), tc.input.URL.RequestURI(); expected != actual { |
|||
t.Errorf("Test %d: Expected URL.RequestURI()='%s' but got '%s'", i, expected, actual) |
|||
} |
|||
} |
|||
} |
|||
|
|||
func newRequest(t *testing.T, method, uri string) *http.Request { |
|||
req, err := http.NewRequest(method, uri, nil) |
|||
if err != nil { |
|||
t.Fatalf("error creating request: %v", err) |
|||
} |
|||
req.RequestURI = req.URL.RequestURI() // simulate incoming request
|
|||
return req |
|||
} |
|||
|
|||
// reqEqual if r1 and r2 are equal enough for our purposes.
|
|||
func reqEqual(r1, r2 *http.Request) bool { |
|||
if r1.Method != r2.Method { |
|||
return false |
|||
} |
|||
if r1.RequestURI != r2.RequestURI { |
|||
return false |
|||
} |
|||
if (r1.URL == nil && r2.URL != nil) || (r1.URL != nil && r2.URL == nil) { |
|||
return false |
|||
} |
|||
if r1.URL == nil && r2.URL == nil { |
|||
return true |
|||
} |
|||
return r1.URL.Scheme == r2.URL.Scheme && |
|||
r1.URL.Host == r2.URL.Host && |
|||
r1.URL.Path == r2.URL.Path && |
|||
r1.URL.RawPath == r2.URL.RawPath && |
|||
r1.URL.RawQuery == r2.URL.RawQuery && |
|||
r1.URL.Fragment == r2.URL.Fragment |
|||
} |
Loading…
Reference in new issue