aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--modules/caddyhttp/matchers.go20
-rw-r--r--modules/caddyhttp/matchers_test.go9
2 files changed, 23 insertions, 6 deletions
diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go
index b1da14686..392312b6c 100644
--- a/modules/caddyhttp/matchers.go
+++ b/modules/caddyhttp/matchers.go
@@ -34,6 +34,7 @@ import (
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
+ "golang.org/x/net/idna"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
@@ -239,13 +240,20 @@ func (m *MatchHost) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
func (m MatchHost) Provision(_ caddy.Context) error {
// check for duplicates; they are nonsensical and reduce efficiency
// (we could just remove them, but the user should know their config is erroneous)
- seen := make(map[string]int)
- for i, h := range m {
- h = strings.ToLower(h)
- if firstI, ok := seen[h]; ok {
- return fmt.Errorf("host at index %d is repeated at index %d: %s", firstI, i, h)
+ seen := make(map[string]int, len(m))
+ for i, host := range m {
+ asciiHost, err := idna.ToASCII(host)
+ if err != nil {
+ return fmt.Errorf("converting hostname '%s' to ASCII: %v", host, err)
+ }
+ if asciiHost != host {
+ m[i] = asciiHost
+ }
+ normalizedHost := strings.ToLower(asciiHost)
+ if firstI, ok := seen[normalizedHost]; ok {
+ return fmt.Errorf("host at index %d is repeated at index %d: %s", firstI, i, host)
}
- seen[h] = i
+ seen[normalizedHost] = i
}
if m.large() {
diff --git a/modules/caddyhttp/matchers_test.go b/modules/caddyhttp/matchers_test.go
index 5f76a36b1..05eaade5b 100644
--- a/modules/caddyhttp/matchers_test.go
+++ b/modules/caddyhttp/matchers_test.go
@@ -79,6 +79,11 @@ func TestHostMatcher(t *testing.T) {
expect: false,
},
{
+ match: MatchHost{"éxàmplê.com"},
+ input: "xn--xmpl-0na6cm.com",
+ expect: true,
+ },
+ {
match: MatchHost{"*.example.com"},
input: "example.com",
expect: false,
@@ -149,6 +154,10 @@ func TestHostMatcher(t *testing.T) {
ctx := context.WithValue(req.Context(), caddy.ReplacerCtxKey, repl)
req = req.WithContext(ctx)
+ if err := tc.match.Provision(caddy.Context{}); err != nil {
+ t.Errorf("Test %d %v: provisioning failed: %v", i, tc.match, err)
+ }
+
actual := tc.match.Match(req)
if actual != tc.expect {
t.Errorf("Test %d %v: Expected %t, got %t for '%s'", i, tc.match, tc.expect, actual, tc.input)