@marcel91200 / caddy Mirror · read-only / commits / eec32a0b
Fork 0

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 }