redis-rb icon indicating copy to clipboard operation
redis-rb copied to clipboard

DB index unintentionally copied over from REDIS_URL env var

Open danhsiung opened this issue 4 years ago • 6 comments

v4.1.4 include a fix for 888, but introduced an issue for me. In my environment, I have REDIS_URL=redis://HOSTNAME:6379/5 which is used for most of my interactions with Redis. However, in one code path I'm connecting to a separate Redis Cluster like this: client = Redis.new({ cluster: "redis://DIFFERENT_HOSTNAME:6379", password: "PASSWORD" })

If I don't specify db: 0 in the initializer, or add a /0 to the end of the cluster string, my new client connects to DB index of 5, which is inadvertently copied over from the REDIS_URL config.

This is likely an uncommon case, and I'm not even sure there is an adequate heuristic that works well, but I figured I'd reach out and see if anyone has an idea on this. Happy to write up a patch if there's a good approach.

danhsiung avatar Oct 20 '21 00:10 danhsiung

Since Redis cluster only uses 0 db, it might be that the following code should be hard-coded zero.

https://github.com/redis/redis-rb/blob/b373362eba86fcef75571af2a2accffc8cee8b78/lib/redis/cluster/option.rb#L66-L68

supercaracal avatar Oct 20 '21 00:10 supercaracal

That could work for db, but I'm wondering if there are cases where other parameters could also be copied over inadvertently. E.g. username. I believe that is usually left blank, but what if the REDIS_URL config specifies one?

danhsiung avatar Oct 20 '21 01:10 danhsiung

REDIS_URL environment variable is used indeed if it is specified.

https://github.com/redis/redis-rb/blob/b373362eba86fcef75571af2a2accffc8cee8b78/lib/redis/client.rb#L454-L477

The option is legitimate even if we specified cluster option. We can overwrite it with cluster option. It might be a bug if we cannot overwrite it with empty value.

supercaracal avatar Oct 20 '21 02:10 supercaracal

https://github.com/redis/redis-rb/blob/b373362eba86fcef75571af2a2accffc8cee8b78/lib/redis/cluster/option.rb#L20-L22

supercaracal avatar Oct 20 '21 02:10 supercaracal

I was just bitten by a similar thing today and came here to file an issue about it, but I'll add on another example to this one instead:

$ cat main.rb 
require 'redis'

# these two are equivalent:
a = Redis.new()
b = Redis.new(url: ENV['REDIS_URL'])
p a, b

# intuitively, I expect these two to be equivalent, but they are not:
c = Redis.new(url: 'redis://explicit-host')
d = Redis.new(host: 'explicit-host')
p c, d
$ REDIS_URL=redis://env-host:12345 bundler exec ruby ./main.rb 
#<Redis client v4.5.1 for redis://env-host:12345/0>
#<Redis client v4.5.1 for redis://env-host:12345/0>
#<Redis client v4.5.1 for redis://explicit-host:6379/0>
#<Redis client v4.5.1 for redis://explicit-host:12345/0>

That's surprising behavior, to say the least. If I pass a hostname but not a port to something, I would expect to get the default port for whatever I'm connecting to, not pulling bits out of an environment variable I thought I was overriding.

emi-wheee avatar Oct 27 '21 16:10 emi-wheee

similar issue: #679

supercaracal avatar Oct 27 '21 23:10 supercaracal

This is solved in 5.0

byroot avatar Aug 17 '22 19:08 byroot