From 4d60d936edce2ab49cb36c47d0d1bdc0029a0ed2 Mon Sep 17 00:00:00 2001 From: "Muhammad Syafri, S.Kom" <105954036+Jualhosting@users.noreply.github.com> Date: Wed, 27 May 2026 21:20:33 +0700 Subject: [PATCH 1/2] perf(replacer): optimize memory allocation for file placeholders (#7773) Co-authored-by: jalikajalika5 <105954036+jalikajalika5@users.noreply.github.com> --- replacer.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/replacer.go b/replacer.go index 2ab02b602..2fa8ef137 100644 --- a/replacer.go +++ b/replacer.go @@ -427,14 +427,10 @@ func readFileIntoBuffer(filename string, size int) ([]byte, error) { } defer file.Close() - buffer := make([]byte, size) - n, err := file.Read(buffer) - if err != nil && err != io.EOF { - return nil, err - } - - // slice the buffer to the actual size - return buffer[:n], nil + // io.LimitReader ensures we never read more than 'size' bytes. + // io.ReadAll starts with a small buffer and grows it as needed, + // preventing a massive 1MB allocation for small files. + return io.ReadAll(io.LimitReader(file, int64(size))) } // ReplacementFunc is a function that is called when a From 86121c860f59fb109602497f603c02571464e3cf Mon Sep 17 00:00:00 2001 From: gelsomino Date: Thu, 28 May 2026 09:18:09 +0800 Subject: [PATCH 2/2] caddytls: skip idna.ToASCII for pure ASCII SNI values (#7770) SNI is always ASCII on the wire (RFC 6066), and most config patterns are also ASCII. For pure ASCII input, idna.ToASCII only validates and lowercases, which is equivalent to a simple strings.ToLower. Add a fast path to avoid the overhead of idna.ToASCII in the common case. --- modules/caddytls/matchers.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/caddytls/matchers.go b/modules/caddytls/matchers.go index 597450ef7..466292e41 100644 --- a/modules/caddytls/matchers.go +++ b/modules/caddytls/matchers.go @@ -85,7 +85,15 @@ func asciiServerNameForMatch(name string) string { return name } - // SNI is ASCII on the wire, but config can use Unicode IDNs. + // Fast path: if the name is pure ASCII, skip idna.ToASCII. + // SNI values on the wire are always ASCII (RFC 6066), and most + // config patterns are also ASCII. For pure ASCII input, idna.ToASCII + // only validates and lowercases, which is equivalent to our fallback. + if isPureASCII(name) { + return strings.ToLower(name) + } + + // Config can use Unicode IDNs. ascii, err := idna.ToASCII(name) if err == nil { return strings.ToLower(ascii) @@ -109,6 +117,15 @@ func asciiServerNameForMatch(name string) string { return strings.Join(labels, ".") } +func isPureASCII(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] >= 0x80 { + return false + } + } + return true +} + // UnmarshalCaddyfile sets up the MatchServerName from Caddyfile tokens. Syntax: // // sni