-
Notifications
You must be signed in to change notification settings - Fork 1k
Closed
Description
Bug Report
Current Behavior
Howdy - I get a RedisConnectionException
when using a RedisCredentialsProvider
trying to connect over SSL. If I use an ImmediateRedisCredentialsProvider
instead, the ssl connection works fine.
Also, the same RedisCredentialsProvider
instance that fails with ssl connection, works fine for non-ssl connection.
I included some simple code that i used to recreate the issue.
Stack trace
// your stack trace here;
io.lettuce.core.RedisConnectionException: my.redis.server/<unresolved>:443
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78)
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56)
at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:350)
at io.lettuce.core.RedisClient.connect(RedisClient.java:216)
at io.lettuce.core.RedisClient.connect(RedisClient.java:201)
at RedisCredentialsProviderTest.testIt(RedisCredentialsProviderTest.java:49)
at RedisCredentialsProviderTest.main(RedisCredentialsProviderTest.java:27)
Caused by: io.lettuce.core.RedisCommandExecutionException: ERR unknown command 'HELLO'
at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:147)
at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:116)
at io.lettuce.core.protocol.AsyncCommand.completeResult(AsyncCommand.java:120)
at io.lettuce.core.protocol.AsyncCommand.complete(AsyncCommand.java:111)
at io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:747)
at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:682)
at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:599)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1373)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1236)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1285)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:519)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:458)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:280)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
Input Code
Input Code
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisCredentials;
import io.lettuce.core.RedisCredentialsProvider;
import io.lettuce.core.RedisCredentialsProvider.ImmediateRedisCredentialsProvider;
import io.lettuce.core.RedisURI;
import reactor.core.publisher.Mono;
public class RedisCredentialsProviderTest {
public static void main(String[] args) {
var sslServer = "ssl server";
var sslPort = 443;
var notSslServer = "no ssl server";
var notSslPort = 6379;
var provider = new MyRedisCredentialsProvider("username", "password");
var immediateProvider = new MyImmediateRedisCredentialsProvider("username", "password");
// this first one fails
testIt(sslServer, sslPort, true, provider, "SSL with MyRedisCredentialsProvider");
testIt(sslServer, sslPort, true, immediateProvider, "SSL with MyImmediateRedisCredentialsProvider");
testIt(notSslServer, notSslPort, false, provider, "No SSL with MyRedisCredentialsProvider");
testIt(notSslServer, notSslPort, false, immediateProvider, "No SSL with MyImmediateRedisCredentialsProvider");
}
static void testIt(String server, int port, boolean withSsl, RedisCredentialsProvider provider, String testMsg) {
var redisUri = RedisURI.Builder
.redis(server, port)
.withAuthentication(provider)
.withSsl(withSsl)
.build();
try(var client = RedisClient.create(redisUri)) {
var commands = client.connect().sync();
System.out.println(String.format("%s - Ping: %s", testMsg, commands.ping()));
} catch (Exception e) {
System.out.println(testMsg + " - Ping failed:");
e.printStackTrace();
}
}
static class MyRedisCredentialsProvider implements RedisCredentialsProvider {
String username;
String password;
public MyRedisCredentialsProvider(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public Mono<RedisCredentials> resolveCredentials() {
return Mono.just(RedisCredentials.just(username, password));
}
}
static class MyImmediateRedisCredentialsProvider implements ImmediateRedisCredentialsProvider {
String username;
String password;
public MyImmediateRedisCredentialsProvider(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public RedisCredentials resolveCredentialsNow() {
return RedisCredentials.just(username, password);
}
}
}
Expected behavior/code
I would expect connectivity to work equally well whether I use a RedisCredentialsProvider
that returns a Mono<RedisCredentials>
, or an ImmediateRedisCredentialsProvider
that return a RedisCredentials
Environment
- Lettuce version(s): 6.2.1.RELEASE
- Redis version: 6.2.5
Possible Solution
Additional context
Metadata
Metadata
Assignees
Labels
type: bugA general bugA general bug