@@ -33,19 +33,19 @@ type TicketData struct {
3333type SessionStore struct {
3434 CookieCipher *encryption.Cipher
3535 CookieOptions *options.CookieOptions
36− Client *redis.Client
36+ Cmdable redis.Cmdable
3737}
3838
3939// NewRedisSessionStore initialises a new instance of the SessionStore from
4040// the configuration given
4141func NewRedisSessionStore(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessions.SessionStore, error) {
42− client, err := newRedisClient(opts.RedisStoreOptions)
42+ cmdable, err := newRedisCmdable(opts.RedisStoreOptions)
4343 if err != nil {
4444 return nil, fmt.Errorf("error constructing redis client: %v", err)
4545 }
4646
4747 rs := &SessionStore{
48− Client: client,
48+ Cmdable: cmdable,
4949 CookieCipher: opts.Cipher,
5050 CookieOptions: cookieOpts,
5151 }
@@ -53,7 +53,11 @@ func NewRedisSessionStore(opts *options.SessionOptions, cookieOpts *options.Cook
5353
5454}
5555
56−func newRedisClient(opts options.RedisStoreOptions) (*redis.Client, error) {
56+func newRedisCmdable(opts options.RedisStoreOptions) (redis.Cmdable, error) {
57+ if opts.UseSentinel && opts.UseCluster {
58+ return nil, fmt.Errorf("options redis-use-sentinel and redis-use-cluster are mutually exclusive")
59+ }
60+
5761 if opts.UseSentinel {
5862 client := redis.NewFailoverClient(&redis.FailoverOptions{
5963 MasterName: opts.SentinelMasterName,
@@ -62,6 +66,13 @@ func newRedisClient(opts options.RedisStoreOptions) (*redis.Client, error) {
6266 return client, nil
6367 }
6468
69+ if opts.UseCluster {
70+ client := redis.NewClusterClient(&redis.ClusterOptions{
71+ Addrs: opts.ClusterConnectionURLs,
72+ })
73+ return client, nil
74+ }
75+
6576 opt, err := redis.ParseURL(opts.RedisConnectionURL)
6677 if err != nil {
6778 return nil, fmt.Errorf("unable to parse redis url: %s", err)
@@ -152,7 +163,7 @@ func (store *SessionStore) loadSessionFromString(value string) (*sessions.Sessio
152163 return nil, err
153164 }
154165
155− result, err := store.Client.Get(ticket.asHandle(store.CookieOptions.CookieName)).Result()
166+ result, err := store.Cmdable.Get(ticket.asHandle(store.CookieOptions.CookieName)).Result()
156167 if err != nil {
157168 return nil, err
158169 }
@@ -203,7 +214,7 @@ func (store *SessionStore) Clear(rw http.ResponseWriter, req *http.Request) erro
203214 // If there's an issue decoding the ticket, ignore it
204215 ticket, _ := decodeTicket(store.CookieOptions.CookieName, val)
205216 if ticket != nil {
206− _, err := store.Client.Del(ticket.asHandle(store.CookieOptions.CookieName)).Result()
217+ _, err := store.Cmdable.Del(ticket.asHandle(store.CookieOptions.CookieName)).Result()
207218 if err != nil {
208219 return fmt.Errorf("error clearing cookie from redis: %s", err)
209220 }
@@ -243,7 +254,7 @@ func (store *SessionStore) storeValue(value string, expiration time.Duration, re
243254 stream.XORKeyStream(ciphertext, []byte(value))
244255
245256 handle := ticket.asHandle(store.CookieOptions.CookieName)
246− err = store.Client.Set(handle, ciphertext, expiration).Err()
257+ err = store.Cmdable.Set(handle, ciphertext, expiration).Err()
247258 if err != nil {
248259 return "", err
249260 }