RedisDriver connects to REDIS_URL, or else redis://localhost:6379, whatever host, port, password, database and tls say. Only an explicit url is honoured. username is not supported at all.
Cause (src/drivers/redis.ts, v0.1.7; main has no changes to this file)
url: options.url ?? process.env.REDIS_URL ?? 'redis://localhost:6379',url always ends up set, and buildConnectionUrl() returns it before reaching the branch that builds a URL from the other options:
if (this.options.url) {
return this.options.url
}So that branch is dead code. It also has no place for a username: const auth = this.options.password ? :${this.options.password}@ : '', with the password not URL-encoded.
Reproduction (Redis 8.8.0 on 127.0.0.1:56379; another Redis already on 6379)
Through @stacksjs/cache's createRedisCache, which passes these options straight to createCache({ driver: 'redis', ... }). The number of connections the client made to 56379 is total_connections_received before and after, minus the measuring call:
| Options | Connections to 56379 | Result |
|---|---|---|
{ host: '127.0.0.1', port: 56379 } | 0 | MISCONF from the server on 6379 |
+ password | 0 | same |
+ username (an ACL user) | 0 | same |
{ url: 'redis://probe:probe-pass@127.0.0.1:56379/0' } (control) | 1 | stored and read back |
An app whose Redis is on another host, port or database, or behind an ACL user, writes its cache to whatever answers on localhost:6379, or fails.
Expected
- An explicit
urlwins. - Otherwise, if any of
host,port,username,password,databaseortlsis given, the URL is built from them. - Only when none of them is given does the driver fall back to
REDIS_URL, thenredis://localhost:6379. usernameis supported, and both credentials are URL-encoded.
Found while auditing @stacksjs/cache for 1.0 (stacksjs/stacks#1169).