Set sameSite field for wrr load balancer sticky cookie
This commit is contained in:
parent
ca2b9e8e77
commit
d6457e6cbb
2 changed files with 41 additions and 3 deletions
|
@ -22,6 +22,20 @@ type stickyCookie struct {
|
||||||
name string
|
name string
|
||||||
secure bool
|
secure bool
|
||||||
httpOnly bool
|
httpOnly bool
|
||||||
|
sameSite string
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertSameSite(sameSite string) http.SameSite {
|
||||||
|
switch sameSite {
|
||||||
|
case "none":
|
||||||
|
return http.SameSiteNoneMode
|
||||||
|
case "lax":
|
||||||
|
return http.SameSiteLaxMode
|
||||||
|
case "strict":
|
||||||
|
return http.SameSiteStrictMode
|
||||||
|
default:
|
||||||
|
return http.SameSiteDefaultMode
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Balancer is a WeightedRoundRobin load balancer based on Earliest Deadline First (EDF).
|
// Balancer is a WeightedRoundRobin load balancer based on Earliest Deadline First (EDF).
|
||||||
|
@ -57,6 +71,7 @@ func New(sticky *dynamic.Sticky, wantHealthCheck bool) *Balancer {
|
||||||
name: sticky.Cookie.Name,
|
name: sticky.Cookie.Name,
|
||||||
secure: sticky.Cookie.Secure,
|
secure: sticky.Cookie.Secure,
|
||||||
httpOnly: sticky.Cookie.HTTPOnly,
|
httpOnly: sticky.Cookie.HTTPOnly,
|
||||||
|
sameSite: sticky.Cookie.SameSite,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return balancer
|
return balancer
|
||||||
|
@ -214,7 +229,14 @@ func (b *Balancer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.stickyCookie != nil {
|
if b.stickyCookie != nil {
|
||||||
cookie := &http.Cookie{Name: b.stickyCookie.name, Value: server.name, Path: "/", HttpOnly: b.stickyCookie.httpOnly, Secure: b.stickyCookie.secure}
|
cookie := &http.Cookie{
|
||||||
|
Name: b.stickyCookie.name,
|
||||||
|
Value: server.name,
|
||||||
|
Path: "/",
|
||||||
|
HttpOnly: b.stickyCookie.httpOnly,
|
||||||
|
Secure: b.stickyCookie.secure,
|
||||||
|
SameSite: convertSameSite(b.stickyCookie.sameSite),
|
||||||
|
}
|
||||||
http.SetCookie(w, cookie)
|
http.SetCookie(w, cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,12 @@ func TestBalancerAllServersZeroWeight(t *testing.T) {
|
||||||
|
|
||||||
func TestSticky(t *testing.T) {
|
func TestSticky(t *testing.T) {
|
||||||
balancer := New(&dynamic.Sticky{
|
balancer := New(&dynamic.Sticky{
|
||||||
Cookie: &dynamic.Cookie{Name: "test"},
|
Cookie: &dynamic.Cookie{
|
||||||
|
Name: "test",
|
||||||
|
Secure: true,
|
||||||
|
HTTPOnly: true,
|
||||||
|
SameSite: "none",
|
||||||
|
},
|
||||||
}, false)
|
}, false)
|
||||||
|
|
||||||
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
@ -233,7 +238,11 @@ func TestSticky(t *testing.T) {
|
||||||
rw.WriteHeader(http.StatusOK)
|
rw.WriteHeader(http.StatusOK)
|
||||||
}), Int(2))
|
}), Int(2))
|
||||||
|
|
||||||
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}}
|
recorder := &responseRecorder{
|
||||||
|
ResponseRecorder: httptest.NewRecorder(),
|
||||||
|
save: map[string]int{},
|
||||||
|
cookies: make(map[string]*http.Cookie),
|
||||||
|
}
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
|
@ -247,6 +256,9 @@ func TestSticky(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, 0, recorder.save["first"])
|
assert.Equal(t, 0, recorder.save["first"])
|
||||||
assert.Equal(t, 3, recorder.save["second"])
|
assert.Equal(t, 3, recorder.save["second"])
|
||||||
|
assert.Equal(t, true, recorder.cookies["test"].HttpOnly)
|
||||||
|
assert.Equal(t, true, recorder.cookies["test"].Secure)
|
||||||
|
assert.Equal(t, http.SameSiteNoneMode, recorder.cookies["test"].SameSite)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestBalancerBias makes sure that the WRR algorithm spreads elements evenly right from the start,
|
// TestBalancerBias makes sure that the WRR algorithm spreads elements evenly right from the start,
|
||||||
|
@ -282,11 +294,15 @@ type responseRecorder struct {
|
||||||
save map[string]int
|
save map[string]int
|
||||||
sequence []string
|
sequence []string
|
||||||
status []int
|
status []int
|
||||||
|
cookies map[string]*http.Cookie
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *responseRecorder) WriteHeader(statusCode int) {
|
func (r *responseRecorder) WriteHeader(statusCode int) {
|
||||||
r.save[r.Header().Get("server")]++
|
r.save[r.Header().Get("server")]++
|
||||||
r.sequence = append(r.sequence, r.Header().Get("server"))
|
r.sequence = append(r.sequence, r.Header().Get("server"))
|
||||||
r.status = append(r.status, statusCode)
|
r.status = append(r.status, statusCode)
|
||||||
|
for _, cookie := range r.Result().Cookies() {
|
||||||
|
r.cookies[cookie.Name] = cookie
|
||||||
|
}
|
||||||
r.ResponseRecorder.WriteHeader(statusCode)
|
r.ResponseRecorder.WriteHeader(statusCode)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue