summaryrefslogtreecommitdiff
path: root/caddyconfig/httpcaddyfile/httptype.go
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2022-07-25 17:28:20 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2022-07-25 17:28:20 -0600
commit1e18afb5c862d62be130d563785de5c58f08ae8e (patch)
tree08fe81f7042bd93293ab2034e27836171b8bc3f2 /caddyconfig/httpcaddyfile/httptype.go
parent0bebea0d4c0321b9cd59be4b355020a3e28c0bcd (diff)
httpcaddyfile: Detect ambiguous site definitions (fix #4635)
Previously, our "duplicate key in server block" logic was flawed because it did not account for the site's bind address. We defer this check to when the listener addresses have been assigned, but before we commit a server block to its listener. Also refined how network address parsing and joining works, which was necessary for a less convoluted fix.
Diffstat (limited to 'caddyconfig/httpcaddyfile/httptype.go')
-rw-r--r--caddyconfig/httpcaddyfile/httptype.go30
1 files changed, 19 insertions, 11 deletions
diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go
index 5d78244..b114059 100644
--- a/caddyconfig/httpcaddyfile/httptype.go
+++ b/caddyconfig/httpcaddyfile/httptype.go
@@ -58,22 +58,13 @@ func (st ServerType) Setup(inputServerBlocks []caddyfile.ServerBlock,
gc := counter{new(int)}
state := make(map[string]interface{})
- // load all the server blocks and associate them with a "pile"
- // of config values; also prohibit duplicate keys because they
- // can make a config confusing if more than one server block is
- // chosen to handle a request - we actually will make each
- // server block's route terminal so that only one will run
- sbKeys := make(map[string]struct{})
+ // load all the server blocks and associate them with a "pile" of config values
originalServerBlocks := make([]serverBlock, 0, len(inputServerBlocks))
- for i, sblock := range inputServerBlocks {
+ for _, sblock := range inputServerBlocks {
for j, k := range sblock.Keys {
if j == 0 && strings.HasPrefix(k, "@") {
return nil, warnings, fmt.Errorf("cannot define a matcher outside of a site block: '%s'", k)
}
- if _, ok := sbKeys[k]; ok {
- return nil, warnings, fmt.Errorf("duplicate site address not allowed: '%s' in %v (site block %d, key %d)", k, sblock.Keys, i, j)
- }
- sbKeys[k] = struct{}{}
}
originalServerBlocks = append(originalServerBlocks, serverBlock{
block: sblock,
@@ -420,6 +411,23 @@ func (st *ServerType) serversFromPairings(
}
for i, p := range pairings {
+ // detect ambiguous site definitions: server blocks which
+ // have the same host bound to the same interface (listener
+ // address), otherwise their routes will improperly be added
+ // to the same server (see issue #4635)
+ for j, sblock1 := range p.serverBlocks {
+ for _, key := range sblock1.block.Keys {
+ for k, sblock2 := range p.serverBlocks {
+ if k == j {
+ continue
+ }
+ if sliceContains(sblock2.block.Keys, key) {
+ return nil, fmt.Errorf("ambiguous site definition: %s", key)
+ }
+ }
+ }
+ }
+
srv := &caddyhttp.Server{
Listen: p.addresses,
}