SocksAuthRequest constructor occasionally throws IllegalStateException (#9558)
Motivation: There appears to be a thread-safety issue in the way that `SocksAuthRequest` is using its `CharsetEncoder` instance. `CharsetUtil#encoder` returns a cached thread-local encoder instance, so it is not correct to store this instance in a static member variable and reuse it across multiple threads. The result is an occasional `IllegalStateException` as in the following example: ``` java.lang.IllegalStateException: Current state = RESET, new state = FLUSHED at java.base/java.nio.charset.CharsetEncoder.throwIllegalStateException(CharsetEncoder.java:989) at java.base/java.nio.charset.CharsetEncoder.flush(CharsetEncoder.java:672) at java.base/java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:801) at java.base/java.nio.charset.CharsetEncoder.canEncode(CharsetEncoder.java:907) at java.base/java.nio.charset.CharsetEncoder.canEncode(CharsetEncoder.java:982) at io.netty.handler.codec.socks.SocksAuthRequest.<init>(SocksAuthRequest.java:43) ``` Modification: Instead of retrieving the thread-local encoder instance once and storing it as a static member instance, the encoder should be retrieved each time the constructor is invoked. This change prevents any potential concurrency issues where multiple threads may end up using the same encoder instance. Result: Fixes #9556.
This commit is contained in:
parent
38e5983463
commit
4a60152dd8
@ -29,7 +29,6 @@ import java.nio.charset.CharsetEncoder;
|
||||
* @see SocksAuthRequestDecoder
|
||||
*/
|
||||
public final class SocksAuthRequest extends SocksRequest {
|
||||
private static final CharsetEncoder asciiEncoder = CharsetUtil.encoder(CharsetUtil.US_ASCII);
|
||||
private static final SocksSubnegotiationVersion SUBNEGOTIATION_VERSION = SocksSubnegotiationVersion.AUTH_PASSWORD;
|
||||
private final String username;
|
||||
private final String password;
|
||||
@ -38,6 +37,8 @@ public final class SocksAuthRequest extends SocksRequest {
|
||||
super(SocksRequestType.AUTH);
|
||||
requireNonNull(username, "username");
|
||||
requireNonNull(password, "password");
|
||||
|
||||
final CharsetEncoder asciiEncoder = CharsetUtil.encoder(CharsetUtil.US_ASCII);
|
||||
if (!asciiEncoder.canEncode(username) || !asciiEncoder.canEncode(password)) {
|
||||
throw new IllegalArgumentException(
|
||||
"username: " + username + " or password: **** values should be in pure ascii");
|
||||
|
Loading…
Reference in New Issue
Block a user