diff --git a/caddyhttp/proxy/policy.go b/caddyhttp/proxy/policy.go index 1737c6c5..337ad1e8 100644 --- a/caddyhttp/proxy/policy.go +++ b/caddyhttp/proxy/policy.go @@ -121,18 +121,13 @@ func (r *IPHash) Select(pool HostPool, request *http.Request) *UpstreamHost { if err != nil { clientIP = request.RemoteAddr } - hash := hash(clientIP) - for { - if poolLen == 0 { - break - } - index := hash % poolLen - host := pool[index] + index := hash(clientIP) % poolLen + for i := uint32(0); i < poolLen; i++ { + index += i + host := pool[index%poolLen] if host.Available() { return host } - pool = append(pool[:index], pool[index+1:]...) - poolLen-- } return nil } diff --git a/caddyhttp/proxy/policy_test.go b/caddyhttp/proxy/policy_test.go index a736d8ca..2a8dfe61 100644 --- a/caddyhttp/proxy/policy_test.go +++ b/caddyhttp/proxy/policy_test.go @@ -163,14 +163,14 @@ func TestIPHashPolicy(t *testing.T) { request.RemoteAddr = "172.0.0.1" pool[1].Unhealthy = true h = ipHash.Select(pool, request) - if h != pool[0] { - t.Error("Expected ip hash policy host to be the first host.") + if h != pool[2] { + t.Error("Expected ip hash policy host to be the third host.") } request.RemoteAddr = "172.0.0.2" h = ipHash.Select(pool, request) - if h != pool[1] { - t.Error("Expected ip hash policy host to be the second host.") + if h != pool[2] { + t.Error("Expected ip hash policy host to be the third host.") } pool[1].Unhealthy = false @@ -182,8 +182,8 @@ func TestIPHashPolicy(t *testing.T) { } request.RemoteAddr = "172.0.0.4" h = ipHash.Select(pool, request) - if h != pool[0] { - t.Error("Expected ip hash policy host to be the first host.") + if h != pool[1] { + t.Error("Expected ip hash policy host to be the second host.") } // We should be able to resize the host pool and still be able to predict