@marcel91200 / caddy Mirror · read-only / commits / 86121c86
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, 09:45 UTC

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.

gelsomino committed May 28, 2026 at 09:18 UTC 86121c860f59fb109602497f603c02571464e3cf
1 file changed +18 -1
modules/caddytls/matchers.go
+18 -1
@@ -85,7 +85,15 @@ func asciiServerNameForMatch(name string) string {
85 return name
86 }
87
88 - // SNI is ASCII on the wire, but config can use Unicode IDNs.
88 + // Fast path: if the name is pure ASCII, skip idna.ToASCII.
89 + // SNI values on the wire are always ASCII (RFC 6066), and most
90 + // config patterns are also ASCII. For pure ASCII input, idna.ToASCII
91 + // only validates and lowercases, which is equivalent to our fallback.
92 + if isPureASCII(name) {
93 + return strings.ToLower(name)
94 + }
95 +
96 + // Config can use Unicode IDNs.
97 ascii, err := idna.ToASCII(name)
98 if err == nil {
99 return strings.ToLower(ascii)
@@ -109,6 +117,15 @@ func asciiServerNameForMatch(name string) string {
117 return strings.Join(labels, ".")
118 }
119
120 +func isPureASCII(s string) bool {
121 + for i := 0; i < len(s); i++ {
122 + if s[i] >= 0x80 {
123 + return false
124 + }
125 + }
126 + return true
127 +}
128 +
129 // UnmarshalCaddyfile sets up the MatchServerName from Caddyfile tokens. Syntax:
130 //
131 // sni <domains...>