diff --git a/caddyconfig/httpcaddyfile/addresses.go b/caddyconfig/httpcaddyfile/addresses.go index b33c0f05..c7923e81 100644 --- a/caddyconfig/httpcaddyfile/addresses.go +++ b/caddyconfig/httpcaddyfile/addresses.go @@ -102,12 +102,20 @@ func (st *ServerType) mapAddressToServerBlocks(originalServerBlocks []serverBloc } } + // make a slice of the map keys so we can iterate in sorted order + addrs := make([]string, 0, len(addrToKeys)) + for k := range addrToKeys { + addrs = append(addrs, k) + } + sort.Strings(addrs) + // now that we know which addresses serve which keys of this // server block, we iterate that mapping and create a list of // new server blocks for each address where the keys of the // server block are only the ones which use the address; but // the contents (tokens) are of course the same - for addr, keys := range addrToKeys { + for _, addr := range addrs { + keys := addrToKeys[addr] // parse keys so that we only have to do it once parsedKeys := make([]Address, 0, len(keys)) for _, key := range keys { @@ -161,6 +169,7 @@ func (st *ServerType) consolidateAddrMappings(addrToServerBlocks map[string][]se delete(addrToServerBlocks, otherAddr) } } + sort.Strings(a.addresses) sbaddrs = append(sbaddrs, a) } @@ -208,13 +217,13 @@ func (st *ServerType) listenerAddrsForServerBlockKey(sblock serverBlock, key str } // the bind directive specifies hosts, but is optional - lnHosts := make([]string, 0, len(sblock.pile)) + lnHosts := make([]string, 0, len(sblock.pile["bind"])) for _, cfgVal := range sblock.pile["bind"] { lnHosts = append(lnHosts, cfgVal.Value.([]string)...) } if len(lnHosts) == 0 { - if defaultBind, ok := options["default_bind"].(string); ok { - lnHosts = []string{defaultBind} + if defaultBind, ok := options["default_bind"].([]string); ok { + lnHosts = defaultBind } else { lnHosts = []string{""} } @@ -236,6 +245,7 @@ func (st *ServerType) listenerAddrsForServerBlockKey(sblock serverBlock, key str for lnStr := range listeners { listenersList = append(listenersList, lnStr) } + sort.Strings(listenersList) return listenersList, nil } diff --git a/caddyconfig/httpcaddyfile/options.go b/caddyconfig/httpcaddyfile/options.go index 65b03389..ad52a7b0 100644 --- a/caddyconfig/httpcaddyfile/options.go +++ b/caddyconfig/httpcaddyfile/options.go @@ -29,7 +29,7 @@ func init() { RegisterGlobalOption("debug", parseOptTrue) RegisterGlobalOption("http_port", parseOptHTTPPort) RegisterGlobalOption("https_port", parseOptHTTPSPort) - RegisterGlobalOption("default_bind", parseOptSingleString) + RegisterGlobalOption("default_bind", parseOptStringList) RegisterGlobalOption("grace_period", parseOptDuration) RegisterGlobalOption("default_sni", parseOptSingleString) RegisterGlobalOption("order", parseOptOrder) @@ -279,6 +279,15 @@ func parseOptSingleString(d *caddyfile.Dispenser, _ interface{}) (interface{}, e return val, nil } +func parseOptStringList(d *caddyfile.Dispenser, _ interface{}) (interface{}, error) { + d.Next() // consume parameter name + val := d.RemainingArgs() + if len(val) == 0 { + return "", d.ArgErr() + } + return val, nil +} + func parseOptAdmin(d *caddyfile.Dispenser, _ interface{}) (interface{}, error) { adminCfg := new(caddy.AdminConfig) for d.Next() { diff --git a/caddytest/integration/caddyfile_adapt/global_options_default_bind.txt b/caddytest/integration/caddyfile_adapt/global_options_default_bind.txt index c34186ee..d0b4e269 100644 --- a/caddytest/integration/caddyfile_adapt/global_options_default_bind.txt +++ b/caddytest/integration/caddyfile_adapt/global_options_default_bind.txt @@ -1,5 +1,5 @@ { - default_bind tcp4/0.0.0.0 + default_bind tcp4/0.0.0.0 tcp6/[::] } example.com { @@ -14,7 +14,8 @@ example.org:12345 { "servers": { "srv0": { "listen": [ - "tcp4/0.0.0.0:12345" + "tcp4/0.0.0.0:12345", + "tcp6/[::]:12345" ], "routes": [ { @@ -31,7 +32,8 @@ example.org:12345 { }, "srv1": { "listen": [ - "tcp4/0.0.0.0:443" + "tcp4/0.0.0.0:443", + "tcp6/[::]:443" ], "routes": [ {