mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-14 06:46:27 +03:00
http: Make path matcher case-insensitive
Adds tests for both the path matcher and host matcher for case insensitivity. If case sensitivity is required for the path, a regexp matcher can be used instead. This is the v2 equivalent fix of PR #2882.
This commit is contained in:
parent
ad90b273db
commit
0fc97211ab
2 changed files with 45 additions and 6 deletions
|
@ -33,10 +33,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// MatchHost matches requests by the Host value.
|
// MatchHost matches requests by the Host value (case-insensitive).
|
||||||
MatchHost []string
|
MatchHost []string
|
||||||
|
|
||||||
// MatchPath matches requests by the URI's path.
|
// MatchPath matches requests by the URI's path (case-insensitive).
|
||||||
MatchPath []string
|
MatchPath []string
|
||||||
|
|
||||||
// MatchPathRE matches requests by a regular expression on the URI's path.
|
// MatchPathRE matches requests by a regular expression on the URI's path.
|
||||||
|
@ -154,20 +154,29 @@ func (MatchPath) CaddyModule() caddy.ModuleInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Provision lower-cases the paths in m to ensure case-insensitive matching.
|
||||||
|
func (m MatchPath) Provision(_ caddy.Context) error {
|
||||||
|
for i := range m {
|
||||||
|
m[i] = strings.ToLower(m[i])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Match returns true if r matches m.
|
// Match returns true if r matches m.
|
||||||
func (m MatchPath) Match(r *http.Request) bool {
|
func (m MatchPath) Match(r *http.Request) bool {
|
||||||
|
lowerPath := strings.ToLower(r.URL.Path)
|
||||||
for _, matchPath := range m {
|
for _, matchPath := range m {
|
||||||
// as a special case, if the first character is a
|
// as a special case, if the first character is a
|
||||||
// wildcard, treat it as a quick suffix match
|
// wildcard, treat it as a quick suffix match
|
||||||
if strings.HasPrefix(matchPath, "*") {
|
if strings.HasPrefix(matchPath, "*") {
|
||||||
return strings.HasSuffix(r.URL.Path, matchPath[1:])
|
return strings.HasSuffix(lowerPath, matchPath[1:])
|
||||||
}
|
}
|
||||||
// can ignore error here because we can't handle it anyway
|
// can ignore error here because we can't handle it anyway
|
||||||
matches, _ := filepath.Match(matchPath, r.URL.Path)
|
matches, _ := filepath.Match(matchPath, lowerPath)
|
||||||
if matches {
|
if matches {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(r.URL.Path, matchPath) {
|
if strings.HasPrefix(lowerPath, matchPath) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,16 @@ func TestHostMatcher(t *testing.T) {
|
||||||
input: "example.com",
|
input: "example.com",
|
||||||
expect: true,
|
expect: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
match: MatchHost{"EXAMPLE.COM"},
|
||||||
|
input: "example.com",
|
||||||
|
expect: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: MatchHost{"example.com"},
|
||||||
|
input: "EXAMPLE.COM",
|
||||||
|
expect: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
match: MatchHost{"example.com"},
|
match: MatchHost{"example.com"},
|
||||||
input: "foo.example.com",
|
input: "foo.example.com",
|
||||||
|
@ -72,6 +82,11 @@ func TestHostMatcher(t *testing.T) {
|
||||||
input: "example.com",
|
input: "example.com",
|
||||||
expect: false,
|
expect: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
match: MatchHost{"*.example.com"},
|
||||||
|
input: "SUB.EXAMPLE.COM",
|
||||||
|
expect: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
match: MatchHost{"*.example.com"},
|
match: MatchHost{"*.example.com"},
|
||||||
input: "foo.example.com",
|
input: "foo.example.com",
|
||||||
|
@ -174,7 +189,12 @@ func TestPathMatcher(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
match: MatchPath{"*.ext"},
|
match: MatchPath{"*.ext"},
|
||||||
input: "foo.ext",
|
input: "/foo.ext",
|
||||||
|
expect: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: MatchPath{"*.php"},
|
||||||
|
input: "/index.PHP",
|
||||||
expect: true,
|
expect: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -192,6 +212,16 @@ func TestPathMatcher(t *testing.T) {
|
||||||
input: "/foo/bar/bam",
|
input: "/foo/bar/bam",
|
||||||
expect: false,
|
expect: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
match: MatchPath{"/foo"},
|
||||||
|
input: "/FOO",
|
||||||
|
expect: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: MatchPath{"/foo/bar.txt"},
|
||||||
|
input: "/foo/BAR.txt",
|
||||||
|
expect: true,
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
req := &http.Request{URL: &url.URL{Path: tc.input}}
|
req := &http.Request{URL: &url.URL{Path: tc.input}}
|
||||||
actual := tc.match.Match(req)
|
actual := tc.match.Match(req)
|
||||||
|
|
Loading…
Reference in a new issue