diff --git a/middleware/proxy/policy.go b/middleware/proxy/policy.go index 806055e2..27e02a17 100644 --- a/middleware/proxy/policy.go +++ b/middleware/proxy/policy.go @@ -5,6 +5,7 @@ import ( "sync/atomic" ) +// HostPool is a collection of UpstreamHosts. type HostPool []*UpstreamHost // Policy decides how a host will be selected from a pool. @@ -12,9 +13,10 @@ type Policy interface { Select(pool HostPool) *UpstreamHost } -// The random policy randomly selected an up host from the pool. +// Random is a policy that selects up hosts from a pool at random. type Random struct{} +// Select selects an up host at random from the specified pool. func (r *Random) Select(pool HostPool) *UpstreamHost { // instead of just generating a random index // this is done to prevent selecting a down host @@ -37,11 +39,12 @@ func (r *Random) Select(pool HostPool) *UpstreamHost { return randHost } -// The least_conn policy selects a host with the least connections. -// If multiple hosts have the least amount of connections, one is randomly -// chosen. +// LeastConn is a policy that selects the host with the least connections. type LeastConn struct{} +// Select selects the up host with the least number of connections in the +// pool. If more than one host has the same least number of connections, +// one of the hosts is chosen at random. func (r *LeastConn) Select(pool HostPool) *UpstreamHost { var bestHost *UpstreamHost count := 0 @@ -71,11 +74,12 @@ func (r *LeastConn) Select(pool HostPool) *UpstreamHost { return bestHost } -// The round_robin policy selects a host based on round robin ordering. +// RoundRobin is a policy that selects hosts based on round robin ordering. type RoundRobin struct { Robin uint32 } +// Select selects an up host from the pool using a round robin ordering scheme. func (r *RoundRobin) Select(pool HostPool) *UpstreamHost { poolLen := uint32(len(pool)) selection := atomic.AddUint32(&r.Robin, 1) % poolLen diff --git a/middleware/proxy/proxy.go b/middleware/proxy/proxy.go index bf36b1d8..389faaf9 100644 --- a/middleware/proxy/proxy.go +++ b/middleware/proxy/proxy.go @@ -19,18 +19,19 @@ type Proxy struct { Upstreams []Upstream } -// An upstream manages a pool of proxy upstream hosts. Select should return a +// Upstream manages a pool of proxy upstream hosts. Select should return a // suitable upstream host, or nil if no such hosts are available. type Upstream interface { - //The path this upstream host should be routed on + // The path this upstream host should be routed on From() string // Selects an upstream host to be routed to. Select() *UpstreamHost } +// UpstreamHostDownFunc can be used to customize how Down behaves. type UpstreamHostDownFunc func(*UpstreamHost) bool -// An UpstreamHost represents a single proxy upstream +// UpstreamHost represents a single proxy upstream type UpstreamHost struct { // The hostname of this upstream host Name string @@ -43,6 +44,9 @@ type UpstreamHost struct { CheckDown UpstreamHostDownFunc } +// Down checks whether the upstream host is down or not. +// Down will try to use uh.CheckDown first, and will fall +// back to some default criteria if necessary. func (uh *UpstreamHost) Down() bool { if uh.CheckDown == nil { // Default settings @@ -70,10 +74,10 @@ func (p Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { proxy := host.ReverseProxy r.Host = host.Name - if baseUrl, err := url.Parse(host.Name); err == nil { - r.Host = baseUrl.Host + if baseURL, err := url.Parse(host.Name); err == nil { + r.Host = baseURL.Host if proxy == nil { - proxy = NewSingleHostReverseProxy(baseUrl) + proxy = NewSingleHostReverseProxy(baseURL) } } else if proxy == nil { return http.StatusInternalServerError, err diff --git a/middleware/proxy/upstream.go b/middleware/proxy/upstream.go index b49beaa0..c724da78 100644 --- a/middleware/proxy/upstream.go +++ b/middleware/proxy/upstream.go @@ -1,7 +1,6 @@ package proxy import ( - "github.com/mholt/caddy/config/parse" "io" "io/ioutil" "net/http" @@ -9,6 +8,8 @@ import ( "strconv" "strings" "time" + + "github.com/mholt/caddy/config/parse" ) type staticUpstream struct { @@ -24,7 +25,7 @@ type staticUpstream struct { } } -// newStaticUpstreams parses the configuration input and sets up +// NewStaticUpstreams parses the configuration input and sets up // static upstreams for the proxy middleware. func NewStaticUpstreams(c parse.Dispenser) ([]Upstream, error) { var upstreams []Upstream @@ -130,8 +131,8 @@ func NewStaticUpstreams(c parse.Dispenser) ([]Upstream, error) { } }(upstream), } - if baseUrl, err := url.Parse(uh.Name); err == nil { - uh.ReverseProxy = NewSingleHostReverseProxy(baseUrl) + if baseURL, err := url.Parse(uh.Name); err == nil { + uh.ReverseProxy = NewSingleHostReverseProxy(baseURL) } else { return upstreams, err } @@ -152,8 +153,8 @@ func (u *staticUpstream) From() string { func (u *staticUpstream) healthCheck() { for _, host := range u.Hosts { - hostUrl := host.Name + u.HealthCheck.Path - if r, err := http.Get(hostUrl); err == nil { + hostURL := host.Name + u.HealthCheck.Path + if r, err := http.Get(hostURL); err == nil { io.Copy(ioutil.Discard, r.Body) r.Body.Close() host.Unhealthy = r.StatusCode < 200 || r.StatusCode >= 400 @@ -199,7 +200,6 @@ func (u *staticUpstream) Select() *UpstreamHost { if u.Policy == nil { return (&Random{}).Select(pool) - } else { - return u.Policy.Select(pool) } + return u.Policy.Select(pool) }