Skip to content

Commit 4e61336

Browse files
committed
refactor uri parsing, log error when database index is provided incorrectly
1 parent af83c5c commit 4e61336

File tree

2 files changed

+40
-29
lines changed

2 files changed

+40
-29
lines changed

modules/nosql/manager_redis.go

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"strconv"
1212
"strings"
1313

14+
"code.gitea.io/gitea/modules/log"
15+
1416
"github.com/go-redis/redis/v8"
1517
)
1618

@@ -76,30 +78,13 @@ func (m *Manager) GetRedisClient(connection string) redis.UniversalClient {
7678
opts.TLSConfig = tlsConfig
7779
fallthrough
7880
case "redis+sentinel":
79-
if uri.Host != "" {
80-
opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...)
81-
}
82-
if uri.Path != "" {
83-
if db, err := strconv.Atoi(uri.Path[1:]); err == nil {
84-
opts.DB = db
85-
}
86-
}
87-
8881
client.UniversalClient = redis.NewFailoverClient(opts.Failover())
8982
case "redis+clusters":
9083
fallthrough
9184
case "rediss+cluster":
9285
opts.TLSConfig = tlsConfig
9386
fallthrough
9487
case "redis+cluster":
95-
if uri.Host != "" {
96-
opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...)
97-
}
98-
if uri.Path != "" {
99-
if db, err := strconv.Atoi(uri.Path[1:]); err == nil {
100-
opts.DB = db
101-
}
102-
}
10388
client.UniversalClient = redis.NewClusterClient(opts.Cluster())
10489
case "redis+socket":
10590
simpleOpts := opts.Simple()
@@ -110,14 +95,6 @@ func (m *Manager) GetRedisClient(connection string) redis.UniversalClient {
11095
opts.TLSConfig = tlsConfig
11196
fallthrough
11297
case "redis":
113-
if uri.Host != "" {
114-
opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...)
115-
}
116-
if uri.Path != "" {
117-
if db, err := strconv.Atoi(uri.Path[1:]); err == nil {
118-
opts.DB = db
119-
}
120-
}
12198
client.UniversalClient = redis.NewClient(opts.Simple())
12299
default:
123100
return nil
@@ -215,6 +192,22 @@ func getRedisOptions(uri *url.URL) *redis.UniversalOptions {
215192
}
216193
}
217194

195+
if uri.Host != "" {
196+
opts.Addrs = append(opts.Addrs, strings.Split(uri.Host, ",")...)
197+
}
198+
199+
// A redis connection string uses the path section of the URI in two different ways. In a TCP-based connection, the
200+
// path will be a database index to automatically have the client SELECT. In a Unix socket connection, it will be the
201+
// file path. We only want to try to coerce this to the database index when we're not expecting a file path so that
202+
// the error log stays clean.
203+
if uri.Path != "" && uri.Scheme != "redis+socket" {
204+
if db, err := strconv.Atoi(uri.Path[1:]); err == nil {
205+
opts.DB = db
206+
} else {
207+
log.Error("Provided database identifier '%s' is not a valid integer. Gitea will ignore this option.", uri.Path)
208+
}
209+
}
210+
218211
return opts
219212
}
220213

modules/nosql/manager_redis_test.go

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func TestRedisUsernameOpt(t *testing.T) {
1313
uri, _ := url.Parse("redis://redis:password@myredis/0")
1414
opts := getRedisOptions(uri)
1515

16-
if "redis" != opts.Username {
16+
if opts.Username != "redis" {
1717
t.Fail()
1818
}
1919
}
@@ -22,7 +22,7 @@ func TestRedisPasswordOpt(t *testing.T) {
2222
uri, _ := url.Parse("redis://redis:password@myredis/0")
2323
opts := getRedisOptions(uri)
2424

25-
if "password" != opts.Password {
25+
if opts.Password != "password" {
2626
t.Fail()
2727
}
2828
}
@@ -31,7 +31,7 @@ func TestRedisSentinelUsernameOpt(t *testing.T) {
3131
uri, _ := url.Parse("redis+sentinel://redis:password@myredis/0?sentinelusername=suser&sentinelpassword=spass")
3232
opts := getRedisOptions(uri).Failover()
3333

34-
if "suser" != opts.SentinelUsername {
34+
if opts.SentinelUsername != "suser" {
3535
t.Fail()
3636
}
3737
}
@@ -40,7 +40,25 @@ func TestRedisSentinelPasswordOpt(t *testing.T) {
4040
uri, _ := url.Parse("redis+sentinel://redis:password@myredis/0?sentinelusername=suser&sentinelpassword=spass")
4141
opts := getRedisOptions(uri).Failover()
4242

43-
if "spass" != opts.SentinelPassword {
43+
if opts.SentinelPassword != "spass" {
44+
t.Fail()
45+
}
46+
}
47+
48+
func TestRedisDatabaseIndexTcp(t *testing.T) {
49+
uri, _ := url.Parse("redis://redis:password@myredis/12")
50+
opts := getRedisOptions(uri)
51+
52+
if opts.DB != 12 {
53+
t.Fail()
54+
}
55+
}
56+
57+
func TestRedisDatabaseIndexUnix(t *testing.T) {
58+
uri, _ := url.Parse("redis+socket:///var/run/redis.sock?database=12")
59+
opts := getRedisOptions(uri)
60+
61+
if opts.DB != 12 {
4462
t.Fail()
4563
}
4664
}

0 commit comments

Comments
 (0)