diff --git a/caddyhttp/proxy/policy.go b/caddyhttp/proxy/policy.go index 7d34c1d9..85eeb0c9 100644 --- a/caddyhttp/proxy/policy.go +++ b/caddyhttp/proxy/policy.go @@ -183,6 +183,8 @@ type Header struct { Name string } +var roundRobinPolicier RoundRobin + // Select selects the host based on hashing the header value func (r *Header) Select(pool HostPool, request *http.Request) *UpstreamHost { if r.Name == "" { @@ -190,7 +192,8 @@ func (r *Header) Select(pool HostPool, request *http.Request) *UpstreamHost { } val := request.Header.Get(r.Name) if val == "" { - return nil + // fallback to RoundRobin policy in case no Header in request + return roundRobinPolicier.Select(pool, request) } return hostByHashing(pool, val) } diff --git a/caddyhttp/proxy/policy_test.go b/caddyhttp/proxy/policy_test.go index 1205b51a..be6ef947 100644 --- a/caddyhttp/proxy/policy_test.go +++ b/caddyhttp/proxy/policy_test.go @@ -320,21 +320,25 @@ func TestUriPolicy(t *testing.T) { func TestHeaderPolicy(t *testing.T) { pool := testPool() tests := []struct { + Name string Policy *Header RequestHeaderName string RequestHeaderValue string NilHost bool HostIndex int }{ - {&Header{""}, "", "", true, 0}, - {&Header{""}, "Affinity", "somevalue", true, 0}, - {&Header{""}, "Affinity", "", true, 0}, + {"empty config", &Header{""}, "", "", true, 0}, + {"empty config+header+value", &Header{""}, "Affinity", "somevalue", true, 0}, + {"empty config+header", &Header{""}, "Affinity", "", true, 0}, - {&Header{"Affinity"}, "", "", true, 0}, - {&Header{"Affinity"}, "Affinity", "somevalue", false, 1}, - {&Header{"Affinity"}, "Affinity", "somevalue2", false, 0}, - {&Header{"Affinity"}, "Affinity", "somevalue3", false, 2}, - {&Header{"Affinity"}, "Affinity", "", true, 0}, + {"no header(fallback to roundrobin)", &Header{"Affinity"}, "", "", false, 1}, + {"no header(fallback to roundrobin)", &Header{"Affinity"}, "", "", false, 2}, + {"no header(fallback to roundrobin)", &Header{"Affinity"}, "", "", false, 0}, + + {"hash route to host", &Header{"Affinity"}, "Affinity", "somevalue", false, 1}, + {"hash route to host", &Header{"Affinity"}, "Affinity", "somevalue2", false, 0}, + {"hash route to host", &Header{"Affinity"}, "Affinity", "somevalue3", false, 2}, + {"hash route with empty value", &Header{"Affinity"}, "Affinity", "", false, 1}, } for idx, test := range tests {