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:
Matthew Holt
2019-11-15 12:47:06 -07:00
parent ad90b273db
commit 0fc97211ab
2 changed files with 45 additions and 6 deletions

View File

@ -33,10 +33,10 @@ import (
)
type (
// MatchHost matches requests by the Host value.
// MatchHost matches requests by the Host value (case-insensitive).
MatchHost []string
// MatchPath matches requests by the URI's path.
// MatchPath matches requests by the URI's path (case-insensitive).
MatchPath []string
// 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.
func (m MatchPath) Match(r *http.Request) bool {
lowerPath := strings.ToLower(r.URL.Path)
for _, matchPath := range m {
// as a special case, if the first character is a
// wildcard, treat it as a quick suffix match
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
matches, _ := filepath.Match(matchPath, r.URL.Path)
matches, _ := filepath.Match(matchPath, lowerPath)
if matches {
return true
}
if strings.HasPrefix(r.URL.Path, matchPath) {
if strings.HasPrefix(lowerPath, matchPath) {
return true
}
}