1
0
Fork 0

HttpOnly and Secure flags on the affinity cookie

This commit is contained in:
Amir Keibi 2019-06-12 15:42:06 -07:00 committed by Traefiker Bot
parent cad3704efd
commit d18edd6f77
7 changed files with 68 additions and 11 deletions

View file

@ -97,7 +97,9 @@ type ResponseForwarding struct {
// Stickiness holds the stickiness configuration.
type Stickiness struct {
CookieName string `json:"cookieName,omitempty" toml:",omitempty"`
CookieName string `json:"cookieName,omitempty" toml:",omitempty"`
SecureCookie bool `json:"secureCookie,omitempty" toml:",omitempty"`
HTTPOnlyCookie bool `json:"httpOnlyCookie,omitempty" toml:",omitempty"`
}
// Server holds the server configuration.

View file

@ -143,6 +143,7 @@ func TestDecodeConfiguration(t *testing.T) {
"traefik.http.services.Service0.loadbalancer.server.scheme": "foobar",
"traefik.http.services.Service0.loadbalancer.server.port": "8080",
"traefik.http.services.Service0.loadbalancer.stickiness.cookiename": "foobar",
"traefik.http.services.Service0.loadbalancer.stickiness.securecookie": "true",
"traefik.http.services.Service1.loadbalancer.healthcheck.headers.name0": "foobar",
"traefik.http.services.Service1.loadbalancer.healthcheck.headers.name1": "foobar",
"traefik.http.services.Service1.loadbalancer.healthcheck.hostname": "foobar",
@ -505,7 +506,9 @@ func TestDecodeConfiguration(t *testing.T) {
"Service0": {
LoadBalancer: &config.LoadBalancerService{
Stickiness: &config.Stickiness{
CookieName: "foobar",
CookieName: "foobar",
SecureCookie: true,
HTTPOnlyCookie: false,
},
Servers: []config.Server{
{
@ -897,7 +900,8 @@ func TestEncodeConfiguration(t *testing.T) {
"Service0": {
LoadBalancer: &config.LoadBalancerService{
Stickiness: &config.Stickiness{
CookieName: "foobar",
CookieName: "foobar",
HTTPOnlyCookie: true,
},
Servers: []config.Server{
{
@ -1086,6 +1090,8 @@ func TestEncodeConfiguration(t *testing.T) {
"traefik.HTTP.Services.Service0.LoadBalancer.server.Port": "8080",
"traefik.HTTP.Services.Service0.LoadBalancer.server.Scheme": "foobar",
"traefik.HTTP.Services.Service0.LoadBalancer.Stickiness.CookieName": "foobar",
"traefik.HTTP.Services.Service0.LoadBalancer.Stickiness.HTTPOnlyCookie": "true",
"traefik.HTTP.Services.Service0.LoadBalancer.Stickiness.SecureCookie": "false",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name0": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name1": "foobar",
"traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Hostname": "foobar",

View file

@ -192,7 +192,8 @@ func (m *Manager) getLoadBalancer(ctx context.Context, serviceName string, servi
var cookieName string
if stickiness := service.Stickiness; stickiness != nil {
cookieName = cookie.GetName(stickiness.CookieName, serviceName)
options = append(options, roundrobin.EnableStickySession(roundrobin.NewStickySession(cookieName)))
opts := roundrobin.CookieOptions{HTTPOnly: stickiness.HTTPOnlyCookie, Secure: stickiness.SecureCookie}
options = append(options, roundrobin.EnableStickySession(roundrobin.NewStickySessionWithOptions(cookieName, opts)))
logger.Debugf("Sticky session cookie name: %v", cookieName)
}

View file

@ -4,6 +4,7 @@ import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/containous/traefik/pkg/config"
@ -103,8 +104,10 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
defer serverPassHostFalse.Close()
type ExpectedResult struct {
StatusCode int
XFrom string
StatusCode int
XFrom string
SecureCookie bool
HTTPOnlyCookie bool
}
testCases := []struct {
@ -192,6 +195,26 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
},
},
},
{
desc: "Sticky Cookie's options set correctly",
serviceName: "test",
service: &config.LoadBalancerService{
Stickiness: &config.Stickiness{HTTPOnlyCookie: true, SecureCookie: true},
Servers: []config.Server{
{
URL: server1.URL,
},
},
},
expected: []ExpectedResult{
{
StatusCode: http.StatusOK,
XFrom: "first",
SecureCookie: true,
HTTPOnlyCookie: true,
},
},
},
{
desc: "PassHost passes the host instead of the IP",
serviceName: "test",
@ -249,8 +272,11 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
assert.Equal(t, expected.StatusCode, recorder.Code)
assert.Equal(t, expected.XFrom, recorder.Header().Get("X-From"))
if len(recorder.Header().Get("Set-Cookie")) > 0 {
req.Header.Set("Cookie", recorder.Header().Get("Set-Cookie"))
cookieHeader := recorder.Header().Get("Set-Cookie")
if len(cookieHeader) > 0 {
req.Header.Set("Cookie", cookieHeader)
assert.Equal(t, expected.SecureCookie, strings.Contains(cookieHeader, "Secure"))
assert.Equal(t, expected.HTTPOnlyCookie, strings.Contains(cookieHeader, "HttpOnly"))
}
}
})