diff --git a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java index 7048288d6..89f55064e 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java @@ -595,8 +595,8 @@ public class VelocityServer implements ProxyServer, ForwardingAudience { this.cm.closeEndpoints(false); } - public HttpClient getHttpClient() { - return cm.getHttpClient(); + public HttpClient createHttpClient() { + return cm.createHttpClient(); } public Ratelimiter getIpAttemptLimiter() { diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/InitialLoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/InitialLoginSessionHandler.java index 6b1ab3707..5cc5371c0 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/InitialLoginSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/InitialLoginSessionHandler.java @@ -43,6 +43,7 @@ import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket; import io.netty.buffer.ByteBuf; import java.net.InetSocketAddress; import java.net.URI; +import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.security.GeneralSecurityException; @@ -213,7 +214,8 @@ public class InitialLoginSessionHandler implements MinecraftSessionHandler { server.getVersion().getName() + "/" + server.getVersion().getVersion()) .uri(URI.create(url)) .build(); - server.getHttpClient().sendAsync(httpRequest, HttpResponse.BodyHandlers.ofString()) + final HttpClient httpClient = server.createHttpClient(); + httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofString()) .whenCompleteAsync((response, throwable) -> { if (mcConnection.isClosed()) { // The player disconnected after we authenticated them. @@ -264,7 +266,18 @@ public class InitialLoginSessionHandler implements MinecraftSessionHandler { response.statusCode(), login.getUsername(), playerIp); inbound.disconnect(Component.translatable("multiplayer.disconnect.authservers_down")); } - }, mcConnection.eventLoop()); + }, mcConnection.eventLoop()) + .thenRun(() -> { + if (httpClient instanceof final AutoCloseable closeable) { + try { + closeable.close(); + } catch (Exception e) { + // In Java 21, the HttpClient does not throw any Exception + // when trying to clean its resources, so this should not happen + logger.error("An unknown error occurred while trying to close an HttpClient", e); + } + } + }); } catch (GeneralSecurityException e) { logger.error("Unable to enable encryption", e); mcConnection.close(true); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/network/ConnectionManager.java b/proxy/src/main/java/com/velocitypowered/proxy/network/ConnectionManager.java index 23fd55c7d..be1db5522 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/network/ConnectionManager.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/network/ConnectionManager.java @@ -62,10 +62,9 @@ public final class ConnectionManager { public final BackendChannelInitializerHolder backendChannelInitializer; private final SeparatePoolInetNameResolver resolver; - private final HttpClient httpClient; /** - * Initalizes the {@code ConnectionManager}. + * Initializes the {@code ConnectionManager}. * * @param server a reference to the Velocity server */ @@ -79,9 +78,6 @@ public final class ConnectionManager { this.backendChannelInitializer = new BackendChannelInitializerHolder( new BackendChannelInitializer(this.server)); this.resolver = new SeparatePoolInetNameResolver(GlobalEventExecutor.INSTANCE); - this.httpClient = HttpClient.newBuilder() - .executor(this.workerGroup) - .build(); } public void logChannelInformation() { @@ -238,8 +234,11 @@ public final class ConnectionManager { return this.serverChannelInitializer; } - public HttpClient getHttpClient() { - return this.httpClient; + @SuppressWarnings("checkstyle:MissingJavadocMethod") + public HttpClient createHttpClient() { + return HttpClient.newBuilder() + .executor(this.workerGroup) + .build(); } public BackendChannelInitializerHolder getBackendChannelInitializer() {