From 3860b235d074209c495d34a3966fc7fb2d5015a5 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Fri, 31 Jul 2020 13:55:01 -0600 Subject: fileserver: Don't assume len(str) == len(ToLower(str)) (fix #3623) We can't use a positional index on an original string that we got from its lower-cased equivalent. Implement our own IndexFold() function b/c the std lib does not have one. --- modules/caddyhttp/fileserver/matcher.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'modules/caddyhttp/fileserver/matcher.go') diff --git a/modules/caddyhttp/fileserver/matcher.go b/modules/caddyhttp/fileserver/matcher.go index 9144ca4..1844421 100644 --- a/modules/caddyhttp/fileserver/matcher.go +++ b/modules/caddyhttp/fileserver/matcher.go @@ -117,11 +117,13 @@ func (m *MatchFile) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return d.ArgErr() } m.TryPolicy = d.Val() - case "split": + case "split_path": m.SplitPath = d.RemainingArgs() if len(m.SplitPath) == 0 { return d.ArgErr() } + default: + return d.Errf("unrecognized subdirective: %s", d.Val()) } } } @@ -279,9 +281,8 @@ func strictFileExists(file string) bool { // in the split value. Returns the path as-is if the // path cannot be split. func (m MatchFile) firstSplit(path string) string { - lowerPath := strings.ToLower(path) for _, split := range m.SplitPath { - if idx := strings.Index(lowerPath, strings.ToLower(split)); idx > -1 { + if idx := indexFold(path, split); idx > -1 { pos := idx + len(split) // skip the split if it's not the final part of the filename if pos != len(path) && !strings.HasPrefix(path[pos:], "/") { @@ -293,6 +294,19 @@ func (m MatchFile) firstSplit(path string) string { return path } +// There is no strings.IndexFold() function like there is strings.EqualFold(), +// but we can use strings.EqualFold() to build our own case-insensitive +// substring search (as of Go 1.14). +func indexFold(haystack, needle string) int { + nlen := len(needle) + for i := 0; i+nlen < len(haystack); i++ { + if strings.EqualFold(haystack[i:i+nlen], needle) { + return i + } + } + return -1 +} + const ( tryPolicyFirstExist = "first_exist" tryPolicyLargestSize = "largest_size" -- cgit v1.2.3