diff options
Diffstat (limited to 'modules/caddyhttp/reverseproxy')
-rw-r--r-- | modules/caddyhttp/reverseproxy/selectionpolicies.go | 3 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/selectionpolicies_test.go | 29 |
2 files changed, 30 insertions, 2 deletions
diff --git a/modules/caddyhttp/reverseproxy/selectionpolicies.go b/modules/caddyhttp/reverseproxy/selectionpolicies.go index 357ee33..001f7f8 100644 --- a/modules/caddyhttp/reverseproxy/selectionpolicies.go +++ b/modules/caddyhttp/reverseproxy/selectionpolicies.go @@ -523,8 +523,7 @@ func hostByHashing(pool []*Upstream, s string) *Upstream { } index := hash(s) % poolLen for i := uint32(0); i < poolLen; i++ { - index += i - upstream := pool[index%poolLen] + upstream := pool[(index+i)%poolLen] if upstream.Available() { return upstream } diff --git a/modules/caddyhttp/reverseproxy/selectionpolicies_test.go b/modules/caddyhttp/reverseproxy/selectionpolicies_test.go index 70d05ac..60a2702 100644 --- a/modules/caddyhttp/reverseproxy/selectionpolicies_test.go +++ b/modules/caddyhttp/reverseproxy/selectionpolicies_test.go @@ -198,6 +198,35 @@ func TestIPHashPolicy(t *testing.T) { if h != nil { t.Error("Expected ip hash policy host to be nil.") } + + // Reproduce #4135 + pool = UpstreamPool{ + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + {Host: new(upstreamHost)}, + } + pool[0].SetHealthy(false) + pool[1].SetHealthy(false) + pool[2].SetHealthy(false) + pool[3].SetHealthy(false) + pool[4].SetHealthy(false) + pool[5].SetHealthy(false) + pool[6].SetHealthy(false) + pool[7].SetHealthy(false) + pool[8].SetHealthy(true) + + // We should get a result back when there is one healthy host left. + h = ipHash.Select(pool, req, nil) + if h == nil { + // If it is nil, it means we missed a host even though one is available + t.Error("Expected ip hash policy host to not be nil, but it is nil.") + } } func TestFirstPolicy(t *testing.T) { |