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...>