mirror of
https://github.com/caddyserver/caddy.git
synced 2024-11-26 02:09:47 +08:00
caddyhttp: Convert IDNs to ASCII when provisioning Host matcher
This commit is contained in:
parent
fab6375a8b
commit
99dcdf7e42
|
@ -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)
|
||||
}
|
||||
seen[h] = i
|
||||
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[normalizedHost] = i
|
||||
}
|
||||
|
||||
if m.large() {
|
||||
|
|
|
@ -78,6 +78,11 @@ func TestHostMatcher(t *testing.T) {
|
|||
input: "bar.example.com",
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
match: MatchHost{"éxàmplê.com"},
|
||||
input: "xn--xmpl-0na6cm.com",
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
match: MatchHost{"*.example.com"},
|
||||
input: "example.com",
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue
Block a user