From bcc44d9f8d63856b43d5079cf34c5f6b97adf138 Mon Sep 17 00:00:00 2001 From: Justin Sievenpiper Date: Tue, 22 Mar 2022 22:19:23 -0700 Subject: [PATCH 01/10] Upgrade go-redis to v8.11.5 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 0edd0dc2dc55b..e57867ed31aa7 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/go-git/go-billy/v5 v5.3.1 github.com/go-git/go-git/v5 v5.4.3-0.20210630082519-b4368b2a2ca4 github.com/go-ldap/ldap/v3 v3.4.2 - github.com/go-redis/redis/v8 v8.11.4 + github.com/go-redis/redis/v8 v8.11.5 github.com/go-sql-driver/mysql v1.6.0 github.com/go-swagger/go-swagger v0.29.0 github.com/go-testfixtures/testfixtures/v3 v3.6.1 diff --git a/go.sum b/go.sum index 19ed2271c8848..0ef43321cabbf 100644 --- a/go.sum +++ b/go.sum @@ -595,6 +595,8 @@ github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8w github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M= github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg= github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= From 9ba086acd9e12c4024188b977eb699f1736ac56f Mon Sep 17 00:00:00 2001 From: Justin Sievenpiper Date: Fri, 25 Mar 2022 12:35:21 -0700 Subject: [PATCH 02/10] Add redis sentinel authentication support --- modules/nosql/manager_redis.go | 168 +++++++++++++++++----------- modules/nosql/manager_redis_test.go | 46 ++++++++ 2 files changed, 151 insertions(+), 63 deletions(-) create mode 100644 modules/nosql/manager_redis_test.go diff --git a/modules/nosql/manager_redis.go b/modules/nosql/manager_redis.go index b4852cecc849e..e639eadee4e8b 100644 --- a/modules/nosql/manager_redis.go +++ b/modules/nosql/manager_redis.go @@ -6,6 +6,7 @@ package nosql import ( "crypto/tls" + "net/url" "path" "strconv" "strings" @@ -59,8 +60,84 @@ func (m *Manager) GetRedisClient(connection string) redis.UniversalClient { name: []string{connection, uri.String()}, } + opts := getRedisOptions(uri) + tlsConfig := getRedisTlsOptions(uri) + + clientName := uri.Query()["clientname"] + + if nil != clientName && 0 < len(clientName) { + client.name = append(client.name, clientName[0]) + } + + switch uri.Scheme { + case "redis+sentinels": + fallthrough + case "rediss+sentinel": + opts.TLSConfig = tlsConfig + fallthrough + case "redis+sentinel": + if uri.Host != "" { + opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...) + } + if uri.Path != "" { + if db, err := strconv.Atoi(uri.Path[1:]); err == nil { + opts.DB = db + } + } + + client.UniversalClient = redis.NewFailoverClient(opts.Failover()) + case "redis+clusters": + fallthrough + case "rediss+cluster": + opts.TLSConfig = tlsConfig + fallthrough + case "redis+cluster": + if uri.Host != "" { + opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...) + } + if uri.Path != "" { + if db, err := strconv.Atoi(uri.Path[1:]); err == nil { + opts.DB = db + } + } + client.UniversalClient = redis.NewClusterClient(opts.Cluster()) + case "redis+socket": + simpleOpts := opts.Simple() + simpleOpts.Network = "unix" + simpleOpts.Addr = path.Join(uri.Host, uri.Path) + client.UniversalClient = redis.NewClient(simpleOpts) + case "rediss": + opts.TLSConfig = tlsConfig + fallthrough + case "redis": + if uri.Host != "" { + opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...) + } + if uri.Path != "" { + if db, err := strconv.Atoi(uri.Path[1:]); err == nil { + opts.DB = db + } + } + client.UniversalClient = redis.NewClient(opts.Simple()) + default: + return nil + } + + for _, name := range client.name { + m.RedisConnections[name] = client + } + + client.count++ + + return client +} + +// getRedisOptions pulls various configuration options based on the RedisUri format and converts them to go-redis's +// UniversalOptions fields. This function explicitly excludes fields related to TLS configuration, which is +// conditionally attached to this options struct before being converted to the specific type for the redis scheme being +// used, and only in scenarios where TLS is applicable (e.g. rediss://, redis+clusters://). +func getRedisOptions(uri *url.URL) *redis.UniversalOptions { opts := &redis.UniversalOptions{} - tlsConfig := &tls.Config{} // Handle username/password if password, ok := uri.User.Password(); ok { @@ -131,75 +208,40 @@ func (m *Manager) GetRedisClient(connection string) redis.UniversalClient { fallthrough case "mastername": opts.MasterName = v[0] - case "skipverify": - fallthrough - case "insecureskipverify": - insecureSkipVerify, _ := strconv.ParseBool(v[0]) - tlsConfig.InsecureSkipVerify = insecureSkipVerify - case "clientname": - client.name = append(client.name, v[0]) + case "sentinelusername": + opts.SentinelUsername = v[0] + case "sentinelpassword": + opts.SentinelPassword = v[0] } } - switch uri.Scheme { - case "redis+sentinels": - fallthrough - case "rediss+sentinel": - opts.TLSConfig = tlsConfig - fallthrough - case "redis+sentinel": - if uri.Host != "" { - opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...) - } - if uri.Path != "" { - if db, err := strconv.Atoi(uri.Path[1:]); err == nil { - opts.DB = db - } - } + return opts +} - client.UniversalClient = redis.NewFailoverClient(opts.Failover()) - case "redis+clusters": - fallthrough - case "rediss+cluster": - opts.TLSConfig = tlsConfig - fallthrough - case "redis+cluster": - if uri.Host != "" { - opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...) - } - if uri.Path != "" { - if db, err := strconv.Atoi(uri.Path[1:]); err == nil { - opts.DB = db - } - } - client.UniversalClient = redis.NewClusterClient(opts.Cluster()) - case "redis+socket": - simpleOpts := opts.Simple() - simpleOpts.Network = "unix" - simpleOpts.Addr = path.Join(uri.Host, uri.Path) - client.UniversalClient = redis.NewClient(simpleOpts) - case "rediss": - opts.TLSConfig = tlsConfig - fallthrough - case "redis": - if uri.Host != "" { - opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...) - } - if uri.Path != "" { - if db, err := strconv.Atoi(uri.Path[1:]); err == nil { - opts.DB = db - } +// getRedisTlsOptions parses RedisUri TLS configuration parameters and converts them to the go TLS configuration +// equivalent fields. +func getRedisTlsOptions(uri *url.URL) *tls.Config { + tlsConfig := &tls.Config{} + + skipverify := uri.Query()["skipverify"] + + if nil != skipverify && 0 < len(skipverify) { + skipverify, err := strconv.ParseBool(skipverify[0]) + + if nil != err { + tlsConfig.InsecureSkipVerify = skipverify } - client.UniversalClient = redis.NewClient(opts.Simple()) - default: - return nil } - for _, name := range client.name { - m.RedisConnections[name] = client - } + insecureskipverify := uri.Query()["insecureskipverify"] - client.count++ + if nil != insecureskipverify && 0 < len(insecureskipverify) { + insecureskipverify, err := strconv.ParseBool(insecureskipverify[0]) - return client + if nil != err { + tlsConfig.InsecureSkipVerify = insecureskipverify + } + } + + return tlsConfig } diff --git a/modules/nosql/manager_redis_test.go b/modules/nosql/manager_redis_test.go new file mode 100644 index 0000000000000..34303ef3a9770 --- /dev/null +++ b/modules/nosql/manager_redis_test.go @@ -0,0 +1,46 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package nosql + +import ( + "net/url" + "testing" +) + +func TestRedisUsernameOpt(t *testing.T) { + uri, _ := url.Parse("redis://redis:password@myredis/0") + opts := getRedisOptions(uri) + + if "redis" != opts.Username { + t.Fail() + } +} + +func TestRedisPasswordOpt(t *testing.T) { + uri, _ := url.Parse("redis://redis:password@myredis/0") + opts := getRedisOptions(uri) + + if "password" != opts.Password { + t.Fail() + } +} + +func TestRedisSentinelUsernameOpt(t *testing.T) { + uri, _ := url.Parse("redis+sentinel://redis:password@myredis/0?sentinelusername=suser&sentinelpassword=spass") + opts := getRedisOptions(uri).Failover() + + if "suser" != opts.SentinelUsername { + t.Fail() + } +} + +func TestRedisSentinelPasswordOpt(t *testing.T) { + uri, _ := url.Parse("redis+sentinel://redis:password@myredis/0?sentinelusername=suser&sentinelpassword=spass") + opts := getRedisOptions(uri).Failover() + + if "spass" != opts.SentinelPassword { + t.Fail() + } +} From 3897675861ef6c8d2f95ccfdb634fb44ef491ebc Mon Sep 17 00:00:00 2001 From: Justin Sievenpiper Date: Fri, 25 Mar 2022 12:50:55 -0700 Subject: [PATCH 03/10] tls->TLS go lint --- modules/nosql/manager_redis.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/nosql/manager_redis.go b/modules/nosql/manager_redis.go index e639eadee4e8b..e7fce8d05cd43 100644 --- a/modules/nosql/manager_redis.go +++ b/modules/nosql/manager_redis.go @@ -61,7 +61,7 @@ func (m *Manager) GetRedisClient(connection string) redis.UniversalClient { } opts := getRedisOptions(uri) - tlsConfig := getRedisTlsOptions(uri) + tlsConfig := getRedisTLSOptions(uri) clientName := uri.Query()["clientname"] @@ -220,7 +220,7 @@ func getRedisOptions(uri *url.URL) *redis.UniversalOptions { // getRedisTlsOptions parses RedisUri TLS configuration parameters and converts them to the go TLS configuration // equivalent fields. -func getRedisTlsOptions(uri *url.URL) *tls.Config { +func getRedisTLSOptions(uri *url.URL) *tls.Config { tlsConfig := &tls.Config{} skipverify := uri.Query()["skipverify"] From ab58dccbbe48bf8d2b304a17af6dc1bcb602d421 Mon Sep 17 00:00:00 2001 From: Justin Sievenpiper Date: Fri, 25 Mar 2022 12:51:48 -0700 Subject: [PATCH 04/10] update go sum --- go.sum | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/go.sum b/go.sum index 0ef43321cabbf..5c052a33e1e36 100644 --- a/go.sum +++ b/go.sum @@ -593,8 +593,6 @@ github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8w github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M= -github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg= -github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -760,6 +758,7 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -1235,15 +1234,18 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= -github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= From 6a88bb7c4a0b88882816e2995687b2e9f26affd6 Mon Sep 17 00:00:00 2001 From: Justin Sievenpiper Date: Fri, 25 Mar 2022 13:53:31 -0700 Subject: [PATCH 05/10] code style re: zeripath --- modules/nosql/manager_redis.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/nosql/manager_redis.go b/modules/nosql/manager_redis.go index e7fce8d05cd43..958fb79587f24 100644 --- a/modules/nosql/manager_redis.go +++ b/modules/nosql/manager_redis.go @@ -65,7 +65,7 @@ func (m *Manager) GetRedisClient(connection string) redis.UniversalClient { clientName := uri.Query()["clientname"] - if nil != clientName && 0 < len(clientName) { + if clientName != nil && len(clientName) > 0 { client.name = append(client.name, clientName[0]) } @@ -225,20 +225,20 @@ func getRedisTLSOptions(uri *url.URL) *tls.Config { skipverify := uri.Query()["skipverify"] - if nil != skipverify && 0 < len(skipverify) { + if skipverify != nil && len(skipverify) > 0 { skipverify, err := strconv.ParseBool(skipverify[0]) - if nil != err { + if err != nil { tlsConfig.InsecureSkipVerify = skipverify } } insecureskipverify := uri.Query()["insecureskipverify"] - if nil != insecureskipverify && 0 < len(insecureskipverify) { + if insecureskipverify != nil && len(insecureskipverify) > 0 { insecureskipverify, err := strconv.ParseBool(insecureskipverify[0]) - if nil != err { + if err != nil { tlsConfig.InsecureSkipVerify = insecureskipverify } } From a0d24930f60331e8854f27fbfaab317dae454baa Mon Sep 17 00:00:00 2001 From: Justin Sievenpiper Date: Mon, 28 Mar 2022 11:46:25 -0700 Subject: [PATCH 06/10] idiomatic go re: wxiaoguang --- modules/nosql/manager_redis.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/nosql/manager_redis.go b/modules/nosql/manager_redis.go index 958fb79587f24..eed95053d68f8 100644 --- a/modules/nosql/manager_redis.go +++ b/modules/nosql/manager_redis.go @@ -63,10 +63,10 @@ func (m *Manager) GetRedisClient(connection string) redis.UniversalClient { opts := getRedisOptions(uri) tlsConfig := getRedisTLSOptions(uri) - clientName := uri.Query()["clientname"] + clientName := uri.Query().Get("clientname") - if clientName != nil && len(clientName) > 0 { - client.name = append(client.name, clientName[0]) + if len(clientName) > 0 { + client.name = append(client.name, clientName) } switch uri.Scheme { @@ -223,20 +223,20 @@ func getRedisOptions(uri *url.URL) *redis.UniversalOptions { func getRedisTLSOptions(uri *url.URL) *tls.Config { tlsConfig := &tls.Config{} - skipverify := uri.Query()["skipverify"] + skipverify := uri.Query().Get("skipverify") - if skipverify != nil && len(skipverify) > 0 { - skipverify, err := strconv.ParseBool(skipverify[0]) + if len(skipverify) > 0 { + skipverify, err := strconv.ParseBool(skipverify) if err != nil { tlsConfig.InsecureSkipVerify = skipverify } } - insecureskipverify := uri.Query()["insecureskipverify"] + insecureskipverify := uri.Query().Get("insecureskipverify") - if insecureskipverify != nil && len(insecureskipverify) > 0 { - insecureskipverify, err := strconv.ParseBool(insecureskipverify[0]) + if len(insecureskipverify) > 0 { + insecureskipverify, err := strconv.ParseBool(insecureskipverify) if err != nil { tlsConfig.InsecureSkipVerify = insecureskipverify From 44d368ebfee7af49847e49081d5547b7379c05c2 Mon Sep 17 00:00:00 2001 From: Justin Sievenpiper Date: Mon, 28 Mar 2022 11:47:44 -0700 Subject: [PATCH 07/10] update copyright header --- modules/nosql/manager_redis_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nosql/manager_redis_test.go b/modules/nosql/manager_redis_test.go index 34303ef3a9770..d656a16a6b70b 100644 --- a/modules/nosql/manager_redis_test.go +++ b/modules/nosql/manager_redis_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Gitea Authors. All rights reserved. +// Copyright 2021 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. From 1ca938e0fab2d4f648eae2762a8b61ceb3e31418 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Mon, 28 Mar 2022 20:08:11 +0100 Subject: [PATCH 08/10] fix format Signed-off-by: Andrew Thornton --- modules/nosql/manager_redis.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/nosql/manager_redis.go b/modules/nosql/manager_redis.go index eed95053d68f8..40b18e93ad461 100644 --- a/modules/nosql/manager_redis.go +++ b/modules/nosql/manager_redis.go @@ -227,7 +227,6 @@ func getRedisTLSOptions(uri *url.URL) *tls.Config { if len(skipverify) > 0 { skipverify, err := strconv.ParseBool(skipverify) - if err != nil { tlsConfig.InsecureSkipVerify = skipverify } @@ -237,7 +236,6 @@ func getRedisTLSOptions(uri *url.URL) *tls.Config { if len(insecureskipverify) > 0 { insecureskipverify, err := strconv.ParseBool(insecureskipverify) - if err != nil { tlsConfig.InsecureSkipVerify = insecureskipverify } From af83c5c3faa8852e6dae7b1584cf29c59c521201 Mon Sep 17 00:00:00 2001 From: Justin Sievenpiper Date: Mon, 28 Mar 2022 13:24:11 -0700 Subject: [PATCH 09/10] update date to 2022 --- modules/nosql/manager_redis_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nosql/manager_redis_test.go b/modules/nosql/manager_redis_test.go index d656a16a6b70b..6e645f0071d82 100644 --- a/modules/nosql/manager_redis_test.go +++ b/modules/nosql/manager_redis_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 The Gitea Authors. All rights reserved. +// Copyright 2022 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. From 4e61336cc1f8904bb9048841510a7c02d3bee001 Mon Sep 17 00:00:00 2001 From: Justin Sievenpiper Date: Wed, 30 Mar 2022 10:49:41 -0700 Subject: [PATCH 10/10] refactor uri parsing, log error when database index is provided incorrectly --- modules/nosql/manager_redis.go | 43 ++++++++++++----------------- modules/nosql/manager_redis_test.go | 26 ++++++++++++++--- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/modules/nosql/manager_redis.go b/modules/nosql/manager_redis.go index 40b18e93ad461..0ff01dcac2396 100644 --- a/modules/nosql/manager_redis.go +++ b/modules/nosql/manager_redis.go @@ -11,6 +11,8 @@ import ( "strconv" "strings" + "code.gitea.io/gitea/modules/log" + "github.com/go-redis/redis/v8" ) @@ -76,15 +78,6 @@ func (m *Manager) GetRedisClient(connection string) redis.UniversalClient { opts.TLSConfig = tlsConfig fallthrough case "redis+sentinel": - if uri.Host != "" { - opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...) - } - if uri.Path != "" { - if db, err := strconv.Atoi(uri.Path[1:]); err == nil { - opts.DB = db - } - } - client.UniversalClient = redis.NewFailoverClient(opts.Failover()) case "redis+clusters": fallthrough @@ -92,14 +85,6 @@ func (m *Manager) GetRedisClient(connection string) redis.UniversalClient { opts.TLSConfig = tlsConfig fallthrough case "redis+cluster": - if uri.Host != "" { - opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...) - } - if uri.Path != "" { - if db, err := strconv.Atoi(uri.Path[1:]); err == nil { - opts.DB = db - } - } client.UniversalClient = redis.NewClusterClient(opts.Cluster()) case "redis+socket": simpleOpts := opts.Simple() @@ -110,14 +95,6 @@ func (m *Manager) GetRedisClient(connection string) redis.UniversalClient { opts.TLSConfig = tlsConfig fallthrough case "redis": - if uri.Host != "" { - opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...) - } - if uri.Path != "" { - if db, err := strconv.Atoi(uri.Path[1:]); err == nil { - opts.DB = db - } - } client.UniversalClient = redis.NewClient(opts.Simple()) default: return nil @@ -215,6 +192,22 @@ func getRedisOptions(uri *url.URL) *redis.UniversalOptions { } } + if uri.Host != "" { + opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...) + } + + // A redis connection string uses the path section of the URI in two different ways. In a TCP-based connection, the + // path will be a database index to automatically have the client SELECT. In a Unix socket connection, it will be the + // file path. We only want to try to coerce this to the database index when we're not expecting a file path so that + // the error log stays clean. + if uri.Path != "" && uri.Scheme != "redis+socket" { + if db, err := strconv.Atoi(uri.Path[1:]); err == nil { + opts.DB = db + } else { + log.Error("Provided database identifier '%s' is not a valid integer. Gitea will ignore this option.", uri.Path) + } + } + return opts } diff --git a/modules/nosql/manager_redis_test.go b/modules/nosql/manager_redis_test.go index 6e645f0071d82..3d94532135162 100644 --- a/modules/nosql/manager_redis_test.go +++ b/modules/nosql/manager_redis_test.go @@ -13,7 +13,7 @@ func TestRedisUsernameOpt(t *testing.T) { uri, _ := url.Parse("redis://redis:password@myredis/0") opts := getRedisOptions(uri) - if "redis" != opts.Username { + if opts.Username != "redis" { t.Fail() } } @@ -22,7 +22,7 @@ func TestRedisPasswordOpt(t *testing.T) { uri, _ := url.Parse("redis://redis:password@myredis/0") opts := getRedisOptions(uri) - if "password" != opts.Password { + if opts.Password != "password" { t.Fail() } } @@ -31,7 +31,7 @@ func TestRedisSentinelUsernameOpt(t *testing.T) { uri, _ := url.Parse("redis+sentinel://redis:password@myredis/0?sentinelusername=suser&sentinelpassword=spass") opts := getRedisOptions(uri).Failover() - if "suser" != opts.SentinelUsername { + if opts.SentinelUsername != "suser" { t.Fail() } } @@ -40,7 +40,25 @@ func TestRedisSentinelPasswordOpt(t *testing.T) { uri, _ := url.Parse("redis+sentinel://redis:password@myredis/0?sentinelusername=suser&sentinelpassword=spass") opts := getRedisOptions(uri).Failover() - if "spass" != opts.SentinelPassword { + if opts.SentinelPassword != "spass" { + t.Fail() + } +} + +func TestRedisDatabaseIndexTcp(t *testing.T) { + uri, _ := url.Parse("redis://redis:password@myredis/12") + opts := getRedisOptions(uri) + + if opts.DB != 12 { + t.Fail() + } +} + +func TestRedisDatabaseIndexUnix(t *testing.T) { + uri, _ := url.Parse("redis+socket:///var/run/redis.sock?database=12") + opts := getRedisOptions(uri) + + if opts.DB != 12 { t.Fail() } }