allow setting a custom go-redis client at Iris go redis sessions driver as request at https://chat.iris-go.com

This commit is contained in:
Gerasimos (Makis) Maropoulos 2022-08-15 00:58:49 +03:00
parent 16af6d017f
commit 057fa462f4
No known key found for this signature in database
GPG Key ID: 403EEB7885C79503
4 changed files with 37 additions and 16 deletions

View File

@ -28,6 +28,7 @@ The codebase for Dependency Injection, Internationalization and localization and
## Fixes and Improvements ## Fixes and Improvements
- Enable setting a custom "go-redis" client through `SetClient` go redis driver method or `Client` struct field on sessions/database/redis driver as requested at [chat](https://chat.iris-go.com).
- Ignore `"csrf.token"` form data key when missing on `ctx.ReadForm` by default as requested at [#1941](https://github.com/kataras/iris/issues/1941). - Ignore `"csrf.token"` form data key when missing on `ctx.ReadForm` by default as requested at [#1941](https://github.com/kataras/iris/issues/1941).
- Fix [CVE-2020-5398](https://github.com/advisories/GHSA-8wx2-9q48-vm9r). - Fix [CVE-2020-5398](https://github.com/advisories/GHSA-8wx2-9q48-vm9r).

View File

@ -30,11 +30,16 @@ func main() {
Password: "", Password: "",
Database: "", Database: "",
Prefix: "myapp-", Prefix: "myapp-",
Driver: redis.GoRedis(), // defaults. Driver: redis.GoRedis(), // defaults to this driver.
// To set a custom, existing go-redis client, use the "SetClient" method:
// Driver: redis.GoRedis().SetClient(customGoRedisClient)
}) })
// Optionally configure the underline driver: // Optionally configure the underline driver:
// driver := redis.GoRedis() // driver := redis.GoRedis()
// // To set a custom client:
// driver.SetClient(customGoRedisClient)
// OR:
// driver.ClientOptions = redis.Options{...} // driver.ClientOptions = redis.Options{...}
// driver.ClusterOptions = redis.ClusterOptions{...} // driver.ClusterOptions = redis.ClusterOptions{...}
// redis.New(redis.Config{Driver: driver, ...}) // redis.New(redis.Config{Driver: driver, ...})

View File

@ -30,6 +30,7 @@ type Config struct {
Addr string Addr string
// Clusters a list of network addresses for clusters. // Clusters a list of network addresses for clusters.
// If not empty "Addr" is ignored and Redis clusters feature is used instead. // If not empty "Addr" is ignored and Redis clusters feature is used instead.
// Note that this field is ignored when setgging a custom `GoRedisClient`.
Clusters []string Clusters []string
// Use the specified Username to authenticate the current connection // Use the specified Username to authenticate the current connection
// with one of the connections defined in the ACL list when connecting // with one of the connections defined in the ACL list when connecting

View File

@ -27,7 +27,9 @@ type GoRedisClient interface {
// for the go-redis redis driver. See driver.go file. // for the go-redis redis driver. See driver.go file.
type GoRedisDriver struct { type GoRedisDriver struct {
// Both Client and ClusterClient implements this interface. // Both Client and ClusterClient implements this interface.
client GoRedisClient // Custom one can be directly passed but if so, the
// Connect method does nothing (so all connection and client settings are ignored).
Client GoRedisClient
// Customize any go-redis fields manually // Customize any go-redis fields manually
// before Connect. // before Connect.
ClientOptions Options ClientOptions Options
@ -111,12 +113,24 @@ func (r *GoRedisDriver) mergeClusterOptions(c Config) *ClusterOptions {
return &opts return &opts
} }
// SetClient sets an existing go redis client to the sessions redis driver.
//
// Returns itself.
func (r *GoRedisDriver) SetClient(goRedisClient GoRedisClient) *GoRedisDriver {
r.Client = goRedisClient
return r
}
// Connect initializes the redis client. // Connect initializes the redis client.
func (r *GoRedisDriver) Connect(c Config) error { func (r *GoRedisDriver) Connect(c Config) error {
if r.Client != nil { // if a custom one was given through SetClient.
return nil
}
if len(c.Clusters) > 0 { if len(c.Clusters) > 0 {
r.client = redis.NewClusterClient(r.mergeClusterOptions(c)) r.Client = redis.NewClusterClient(r.mergeClusterOptions(c))
} else { } else {
r.client = redis.NewClient(r.mergeClientOptions(c)) r.Client = redis.NewClient(r.mergeClientOptions(c))
} }
return nil return nil
@ -125,29 +139,29 @@ func (r *GoRedisDriver) Connect(c Config) error {
// PingPong sends a ping message and reports whether // PingPong sends a ping message and reports whether
// the PONG message received successfully. // the PONG message received successfully.
func (r *GoRedisDriver) PingPong() (bool, error) { func (r *GoRedisDriver) PingPong() (bool, error) {
pong, err := r.client.Ping(defaultContext).Result() pong, err := r.Client.Ping(defaultContext).Result()
return pong == "PONG", err return pong == "PONG", err
} }
// CloseConnection terminates the underline redis connection. // CloseConnection terminates the underline redis connection.
func (r *GoRedisDriver) CloseConnection() error { func (r *GoRedisDriver) CloseConnection() error {
return r.client.Close() return r.Client.Close()
} }
// Set stores a "value" based on the session's "key". // Set stores a "value" based on the session's "key".
// The value should be type of []byte, so unmarshal can happen. // The value should be type of []byte, so unmarshal can happen.
func (r *GoRedisDriver) Set(sid, key string, value interface{}) error { func (r *GoRedisDriver) Set(sid, key string, value interface{}) error {
return r.client.HSet(defaultContext, sid, key, value).Err() return r.Client.HSet(defaultContext, sid, key, value).Err()
} }
// Get returns the associated value of the session's given "key". // Get returns the associated value of the session's given "key".
func (r *GoRedisDriver) Get(sid, key string) (interface{}, error) { func (r *GoRedisDriver) Get(sid, key string) (interface{}, error) {
return r.client.HGet(defaultContext, sid, key).Bytes() return r.Client.HGet(defaultContext, sid, key).Bytes()
} }
// Exists reports whether a session exists or not. // Exists reports whether a session exists or not.
func (r *GoRedisDriver) Exists(sid string) bool { func (r *GoRedisDriver) Exists(sid string) bool {
n, err := r.client.Exists(defaultContext, sid).Result() n, err := r.Client.Exists(defaultContext, sid).Result()
if err != nil { if err != nil {
return false return false
} }
@ -157,7 +171,7 @@ func (r *GoRedisDriver) Exists(sid string) bool {
// TTL returns any TTL value of the session. // TTL returns any TTL value of the session.
func (r *GoRedisDriver) TTL(sid string) time.Duration { func (r *GoRedisDriver) TTL(sid string) time.Duration {
dur, err := r.client.TTL(defaultContext, sid).Result() dur, err := r.Client.TTL(defaultContext, sid).Result()
if err != nil { if err != nil {
return 0 return 0
} }
@ -167,29 +181,29 @@ func (r *GoRedisDriver) TTL(sid string) time.Duration {
// UpdateTTL sets expiration duration of the session. // UpdateTTL sets expiration duration of the session.
func (r *GoRedisDriver) UpdateTTL(sid string, newLifetime time.Duration) error { func (r *GoRedisDriver) UpdateTTL(sid string, newLifetime time.Duration) error {
_, err := r.client.Expire(defaultContext, sid, newLifetime).Result() _, err := r.Client.Expire(defaultContext, sid, newLifetime).Result()
return err return err
} }
// GetAll returns all the key values under the session. // GetAll returns all the key values under the session.
func (r *GoRedisDriver) GetAll(sid string) (map[string]string, error) { func (r *GoRedisDriver) GetAll(sid string) (map[string]string, error) {
return r.client.HGetAll(defaultContext, sid).Result() return r.Client.HGetAll(defaultContext, sid).Result()
} }
// GetKeys returns all keys under the session. // GetKeys returns all keys under the session.
func (r *GoRedisDriver) GetKeys(sid string) ([]string, error) { func (r *GoRedisDriver) GetKeys(sid string) ([]string, error) {
return r.client.HKeys(defaultContext, sid).Result() return r.Client.HKeys(defaultContext, sid).Result()
} }
// Len returns the total length of key-values of the session. // Len returns the total length of key-values of the session.
func (r *GoRedisDriver) Len(sid string) int { func (r *GoRedisDriver) Len(sid string) int {
return int(r.client.HLen(defaultContext, sid).Val()) return int(r.Client.HLen(defaultContext, sid).Val())
} }
// Delete removes a value from the redis store. // Delete removes a value from the redis store.
func (r *GoRedisDriver) Delete(sid, key string) error { func (r *GoRedisDriver) Delete(sid, key string) error {
if key == "" { if key == "" {
return r.client.Del(defaultContext, sid).Err() return r.Client.Del(defaultContext, sid).Err()
} }
return r.client.HDel(defaultContext, sid, key).Err() return r.Client.HDel(defaultContext, sid, key).Err()
} }