1
0
Fork 0

Support domain configuration for sticky cookies

This commit is contained in:
Jorge 2025-03-06 09:38:04 +01:00 committed by GitHub
parent fa76ed57d3
commit 740b4cfd25
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 184 additions and 0 deletions

View file

@ -199,6 +199,9 @@ type Cookie struct {
// When not provided the cookie will be sent on every request to the domain.
// More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#pathpath-value
Path *string `json:"path,omitempty" toml:"path,omitempty" yaml:"path,omitempty" export:"true"`
// Domain defines the host to which the cookie will be sent.
// More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value
Domain string `json:"domain,omitempty" toml:"domain,omitempty" yaml:"domain,omitempty"`
}
// SetDefaults set the default values for a Cookie.

View file

@ -179,6 +179,7 @@ func TestDecodeConfiguration(t *testing.T) {
"traefik.http.services.Service0.loadbalancer.sticky.cookie.name": "foobar",
"traefik.http.services.Service0.loadbalancer.sticky.cookie.secure": "true",
"traefik.http.services.Service0.loadbalancer.sticky.cookie.path": "/foobar",
"traefik.http.services.Service0.loadbalancer.sticky.cookie.domain": "foo.com",
"traefik.http.services.Service0.loadbalancer.serversTransport": "foobar",
"traefik.http.services.Service1.loadbalancer.healthcheck.headers.name0": "foobar",
"traefik.http.services.Service1.loadbalancer.healthcheck.headers.name1": "foobar",
@ -684,6 +685,7 @@ func TestDecodeConfiguration(t *testing.T) {
Name: "foobar",
Secure: true,
HTTPOnly: false,
Domain: "foo.com",
Path: func(v string) *string { return &v }("/foobar"),
},
},
@ -1224,6 +1226,7 @@ func TestEncodeConfiguration(t *testing.T) {
Cookie: &dynamic.Cookie{
Name: "foobar",
HTTPOnly: true,
Domain: "foo.com",
Path: func(v string) *string { return &v }("/foobar"),
},
},
@ -1479,6 +1482,7 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.Secure": "false",
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.MaxAge": "0",
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.Path": "/foobar",
"traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.Domain": "foo.com",
"traefik.HTTP.Services.Service0.LoadBalancer.ServersTransport": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name0": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name1": "foobar",

View file

@ -260,6 +260,7 @@ func (c configBuilder) buildServicesLB(ctx context.Context, namespace string, tS
HTTPOnly: tService.Weighted.Sticky.Cookie.HTTPOnly,
SameSite: tService.Weighted.Sticky.Cookie.SameSite,
MaxAge: tService.Weighted.Sticky.Cookie.MaxAge,
Domain: tService.Weighted.Sticky.Cookie.Domain,
},
}
sticky.Cookie.SetDefaults()
@ -382,6 +383,7 @@ func (c configBuilder) buildServersLB(namespace string, svc traefikv1alpha1.Load
HTTPOnly: svc.Sticky.Cookie.HTTPOnly,
SameSite: svc.Sticky.Cookie.SameSite,
MaxAge: svc.Sticky.Cookie.MaxAge,
Domain: svc.Sticky.Cookie.Domain,
},
}
lb.Sticky.Cookie.SetDefaults()

View file

@ -121,6 +121,7 @@ func Test_parseServiceConfig(t *testing.T) {
"traefik.ingress.kubernetes.io/service.sticky.cookie.name": "foobar",
"traefik.ingress.kubernetes.io/service.sticky.cookie.secure": "true",
"traefik.ingress.kubernetes.io/service.sticky.cookie.samesite": "none",
"traefik.ingress.kubernetes.io/service.sticky.cookie.domain": "foo.com",
"traefik.ingress.kubernetes.io/service.sticky.cookie.path": "foobar",
},
expected: &ServiceConfig{
@ -131,6 +132,7 @@ func Test_parseServiceConfig(t *testing.T) {
Secure: true,
HTTPOnly: true,
SameSite: "none",
Domain: "foo.com",
Path: pointer("foobar"),
},
},

View file

@ -30,6 +30,7 @@ type stickyCookie struct {
sameSite string
maxAge int
path string
domain string
}
func convertSameSite(sameSite string) http.SameSite {
@ -87,6 +88,7 @@ func New(sticky *dynamic.Sticky, wantHealthCheck bool) *Balancer {
sameSite: sticky.Cookie.SameSite,
maxAge: sticky.Cookie.MaxAge,
path: "/",
domain: sticky.Cookie.Domain,
}
if sticky.Cookie.Path != nil {
balancer.stickyCookie.path = *sticky.Cookie.Path
@ -281,6 +283,7 @@ func (b *Balancer) writeStickyCookie(w http.ResponseWriter, handler *namedHandle
Secure: b.stickyCookie.secure,
SameSite: convertSameSite(b.stickyCookie.sameSite),
MaxAge: b.stickyCookie.maxAge,
Domain: b.stickyCookie.domain,
}
http.SetCookie(w, cookie)
}

View file

@ -239,6 +239,7 @@ func TestSticky(t *testing.T) {
Secure: true,
HTTPOnly: true,
SameSite: "none",
Domain: "foo.com",
MaxAge: 42,
Path: func(v string) *string { return &v }("/foo"),
},
@ -276,6 +277,7 @@ func TestSticky(t *testing.T) {
assert.Equal(t, 3, recorder.save["second"])
assert.True(t, recorder.cookies["test"].HttpOnly)
assert.True(t, recorder.cookies["test"].Secure)
assert.Equal(t, "foo.com", recorder.cookies["test"].Domain)
assert.Equal(t, http.SameSiteNoneMode, recorder.cookies["test"].SameSite)
assert.Equal(t, 42, recorder.cookies["test"].MaxAge)
assert.Equal(t, "/foo", recorder.cookies["test"].Path)