Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 11, 14:45 UTC
Merge commit from fork
Normalize exact hosts at provisioning and reqHost in the fast path so case-different Host variants can’t bypass host-gated routes. Co-authored-by: Asim Viladi Oglu Manizada <manizada@users.noreply.github.com>
Asim Viladi Oglu Manizada committed
Feb 20, 2026 at 09:19 UTC
eec32a0bb5a11651c6a7b04ce82dc50610f2b27e
1 file changed
+10
-5
modules/caddyhttp/matchers.go
+10
-5
@@ -262,13 +262,17 @@ func (m MatchHost) Provision(_ caddy.Context) error {
262
if err != nil {
263
return fmt.Errorf("converting hostname '%s' to ASCII: %v", host, err)
264
}
265
- if asciiHost != host {
266
- m[i] = asciiHost
267
- }
265
normalizedHost := strings.ToLower(asciiHost)
266
if firstI, ok := seen[normalizedHost]; ok {
267
return fmt.Errorf("host at index %d is repeated at index %d: %s", firstI, i, host)
268
}
269
+ // Normalize exact hosts for standardized comparison in large-list fastpath later on.
270
+ // Keep wildcards/placeholders untouched.
271
+ if m.fuzzy(asciiHost) {
272
+ m[i] = asciiHost
273
+ } else {
274
+ m[i] = normalizedHost
275
+ }
276
seen[normalizedHost] = i
277
}
278
@@ -312,14 +316,15 @@ func (m MatchHost) MatchWithError(r *http.Request) (bool, error) {
316
}
317
318
if m.large() {
319
+ reqHostLower := strings.ToLower(reqHost)
320
// fast path: locate exact match using binary search (about 100-1000x faster for large lists)
321
pos := sort.Search(len(m), func(i int) bool {
322
if m.fuzzy(m[i]) {
323
return false
324
}
320
- return m[i] >= reqHost
325
+ return m[i] >= reqHostLower
326
})
322
- if pos < len(m) && strings.EqualFold(m[pos], reqHost) {
327
+ if pos < len(m) && m[pos] == reqHostLower {
328
return true, nil
329
}
330
}