Skip to content

Commit

Permalink
Propagate exceptions during connection handshake after protocol downg…
Browse files Browse the repository at this point in the history
…rade #2313

We now correctly propagate exceptions that can happen from RESP2 handshake initiator. Previously, these exceptions didn't bubble up and went unnoticed resulting in a handshake timeout.
  • Loading branch information
mp911de committed Jul 25, 2023
1 parent 249e40f commit f43581c
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 19 deletions.
4 changes: 0 additions & 4 deletions src/main/java/io/lettuce/core/RedisCommandBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ Command<K, V, String> asking() {

Command<K, V, String> auth(CharSequence password) {
LettuceAssert.notNull(password, "Password " + MUST_NOT_BE_NULL);
LettuceAssert.notEmpty(password, "Password " + MUST_NOT_BE_EMPTY);

char[] chars = new char[password.length()];
for (int i = 0; i < password.length(); i++) {
Expand All @@ -216,7 +215,6 @@ Command<K, V, String> auth(CharSequence password) {

Command<K, V, String> auth(char[] password) {
LettuceAssert.notNull(password, "Password " + MUST_NOT_BE_NULL);
LettuceAssert.isTrue(password.length > 0, "Password " + MUST_NOT_BE_EMPTY);

CommandArgs<K, V> args = new CommandArgs<>(codec).add(password);
return createCommand(AUTH, new StatusOutput<>(codec), args);
Expand All @@ -226,7 +224,6 @@ Command<K, V, String> auth(String username, CharSequence password) {
LettuceAssert.notNull(username, "Username " + MUST_NOT_BE_NULL);
LettuceAssert.isTrue(!username.isEmpty(), "Username " + MUST_NOT_BE_EMPTY);
LettuceAssert.notNull(password, "Password " + MUST_NOT_BE_NULL);
LettuceAssert.notEmpty(password, "Password " + MUST_NOT_BE_EMPTY);

char[] chars = new char[password.length()];
for (int i = 0; i < password.length(); i++) {
Expand All @@ -239,7 +236,6 @@ Command<K, V, String> auth(String username, char[] password) {
LettuceAssert.notNull(username, "Username " + MUST_NOT_BE_NULL);
LettuceAssert.isTrue(!username.isEmpty(), "Username " + MUST_NOT_BE_EMPTY);
LettuceAssert.notNull(password, "Password " + MUST_NOT_BE_NULL);
LettuceAssert.isTrue(password.length > 0, "Password " + MUST_NOT_BE_EMPTY);

CommandArgs<K, V> args = new CommandArgs<>(codec).add(username).add(password);
return createCommand(AUTH, new StatusOutput<>(codec), args);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/lettuce/core/RedisCredentials.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public interface RedisCredentials {
/**
* Retrieve the Redis password, used to authenticate the user interacting with Redis.
*
* @return the password Can be {@code null} if not set.
* @return the password. Can be {@code null} if not set.
* @see #hasUsername()
*/
char[] getPassword();
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/io/lettuce/core/RedisHandshake.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,12 @@ private CompletionStage<?> tryHandshakeResp3(Channel channel) {

if (throwable != null) {
if (isUnknownCommand(throwable)) {
fallbackToResp2(channel, handshake);
try {
fallbackToResp2(channel, handshake);
} catch (Exception e) {
e.addSuppressed(throwable);
handshake.completeExceptionally(e);
}
} else {
handshake.completeExceptionally(throwable);
}
Expand Down
16 changes: 9 additions & 7 deletions src/main/java/io/lettuce/core/RedisURI.java
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ public char[] getPassword() {
* Sets the password. Use empty string to skip authentication.
* <p>
* This method is deprecated as of Lettuce 6.0. The reason is that {@link String} has a strong caching affinity and the JVM
* cannot easily GC {@code String} instances. Therefore we suggest using either {@code char[]} or a custom
* cannot easily GC {@code String} instances. Therefore, we suggest using either {@code char[]} or a custom
* {@link CharSequence} (e.g. {@link StringBuilder} or netty's {@link io.netty.util.AsciiString}).
*
* @param password the password, must not be {@code null}.
Expand All @@ -487,7 +487,8 @@ public void setPassword(String password) {
}

/**
* Sets the password. Use empty string to skip authentication.
* Sets the password. Use {@code null} to skip authentication. Empty password is supported (although not recommended for
* security reasons).
*
* @param password the password, must not be {@code null}.
* @throws IllegalStateException if a {@link RedisCredentialsProvider} is configured
Expand All @@ -502,7 +503,8 @@ public void setPassword(CharSequence password) {
}

/**
* Sets the password. Use empty char array to skip authentication.
* Sets the password. Use {@code null} to skip authentication. Empty password is supported (although not recommended for
* security reasons).
*
* @param password the password, can be {@code null}.
* @throws IllegalStateException if a {@link RedisCredentialsProvider} is configured
Expand Down Expand Up @@ -1586,7 +1588,7 @@ public Builder withAuthentication(RedisURI source) {
}

/**
* Configures authentication.
* Configures authentication. Empty password is supported (although not recommended for security reasons).
*
* @param username the user name
* @param password the password name
Expand Down Expand Up @@ -1617,7 +1619,7 @@ public Builder withAuthentication(RedisCredentialsProvider credentialsProvider)
}

/**
* Configures authentication.
* Configures authentication. Empty password is supported (although not recommended for security reasons).
* <p>
* This method is deprecated as of Lettuce 6.0. The reason is that {@link String} has a strong caching affinity and the
* JVM cannot easily GC {@code String} instances. Therefore, we suggest using either {@code char[]} or a custom
Expand All @@ -1637,7 +1639,7 @@ public Builder withPassword(String password) {
}

/**
* Configures authentication.
* Configures authentication. Empty password is supported (although not recommended for security reasons).
*
* @param password the password
* @return the builder
Expand All @@ -1656,7 +1658,7 @@ public Builder withPassword(CharSequence password) {
}

/**
* Configures authentication.
* Configures authentication. Empty password is supported (although not recommended for security reasons).
*
* @param password the password
* @return the builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,6 @@ void authNull() {
assertThatThrownBy(() -> redis.auth(null, "x")).isInstanceOf(IllegalArgumentException.class);
}

@Test
void authEmpty() {
assertThatThrownBy(() -> redis.auth("")).isInstanceOf(IllegalArgumentException.class);
assertThatThrownBy(() -> redis.auth("", "x")).isInstanceOf(IllegalArgumentException.class);
}

@Test
void authReconnect() {
WithPassword.run(client, () -> {
Expand Down

0 comments on commit f43581c

Please sign in to comment.