summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/reverseproxy/hosts.go
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2019-10-11 14:25:39 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2019-10-11 14:25:39 -0600
commit1e31be8de0d1d5587348619225456a793cb30f7f (patch)
treefa3fca930b8ae02649471698950a60cce8afc539 /modules/caddyhttp/reverseproxy/hosts.go
parent4aa3af4b78addcf65ce6b254be10f006bae1c9ac (diff)
reverse_proxy: Allow dynamic backends (closes #990 and #1539)
This PR enables the use of placeholders in an upstream's Dial address. A Dial address must represent precisely one socket after replacements. See also #998 and #1639.
Diffstat (limited to 'modules/caddyhttp/reverseproxy/hosts.go')
-rw-r--r--modules/caddyhttp/reverseproxy/hosts.go62
1 files changed, 37 insertions, 25 deletions
diff --git a/modules/caddyhttp/reverseproxy/hosts.go b/modules/caddyhttp/reverseproxy/hosts.go
index a8349bd..a16bed0 100644
--- a/modules/caddyhttp/reverseproxy/hosts.go
+++ b/modules/caddyhttp/reverseproxy/hosts.go
@@ -72,7 +72,6 @@ type Upstream struct {
healthCheckPolicy *PassiveHealthChecks
cb CircuitBreaker
- dialInfo DialInfo
}
// Available returns true if the remote host
@@ -149,8 +148,7 @@ func (uh *upstreamHost) CountFail(delta int) error {
}
// SetHealthy sets the upstream has healthy or unhealthy
-// and returns true if the value was different from before,
-// or an error if the adjustment failed.
+// and returns true if the new value is different.
func (uh *upstreamHost) SetHealthy(healthy bool) (bool, error) {
var unhealthy, compare int32 = 1, 0
if healthy {
@@ -167,8 +165,12 @@ func (uh *upstreamHost) SetHealthy(healthy bool) (bool, error) {
// a host that can be represented in a URL, but
// they certainly have a network name and address).
type DialInfo struct {
- // The network to use. This should be one of the
- // values that is accepted by net.Dial:
+ // Upstream is the Upstream associated with
+ // this DialInfo. It may be nil.
+ Upstream *Upstream
+
+ // The network to use. This should be one of
+ // the values that is accepted by net.Dial:
// https://golang.org/pkg/net/#Dial
Network string
@@ -176,33 +178,43 @@ type DialInfo struct {
// semantics and rules as net.Dial.
Address string
- // Host and Port are components of Address,
- // pre-split for convenience.
+ // Host and Port are components of Address.
Host, Port string
}
-// NewDialInfo creates and populates a DialInfo
-// for the given network and address. It splits
-// the address into host and port values if the
-// network type supports them, or uses the whole
-// address as the port if splitting fails.
-func NewDialInfo(network, address string) DialInfo {
- var addrHost, addrPort string
- if !strings.Contains(network, "unix") {
- var err error
- addrHost, addrPort, err = net.SplitHostPort(address)
- if err != nil {
- addrHost = address // assume there was no port
- }
- }
- return DialInfo{network, address, addrHost, addrPort}
-}
-
// String returns the Caddy network address form
// by joining the network and address with a
// forward slash.
func (di DialInfo) String() string {
- return di.Network + "/" + di.Address
+ return caddy.JoinNetworkAddress(di.Network, di.Host, di.Port)
+}
+
+// fillDialInfo returns a filled DialInfo for the given upstream, using
+// the given Replacer. Note that the returned value is not a pointer.
+func fillDialInfo(upstream *Upstream, repl caddy.Replacer) (DialInfo, error) {
+ dial := repl.ReplaceAll(upstream.Dial, "")
+ netw, addrs, err := caddy.ParseNetworkAddress(dial)
+ if err != nil {
+ return DialInfo{}, fmt.Errorf("upstream %s: invalid dial address %s: %v", upstream.Dial, dial, err)
+ }
+ if len(addrs) != 1 {
+ return DialInfo{}, fmt.Errorf("upstream %s: dial address must represent precisely one socket: %s represents %d",
+ upstream.Dial, dial, len(addrs))
+ }
+ var dialHost, dialPort string
+ if !strings.Contains(netw, "unix") {
+ dialHost, dialPort, err = net.SplitHostPort(addrs[0])
+ if err != nil {
+ dialHost = addrs[0] // assume there was no port
+ }
+ }
+ return DialInfo{
+ Upstream: upstream,
+ Network: netw,
+ Address: addrs[0],
+ Host: dialHost,
+ Port: dialPort,
+ }, nil
}
// DialInfoCtxKey is used to store a DialInfo