diff --git a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java index 402c3d2d8..4d08162d7 100644 --- a/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java +++ b/vertx-pg-client/src/main/java/io/vertx/pgclient/impl/InitiateSslHandler.java @@ -75,10 +75,13 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception } case PgProtocolConstants.MESSAGE_TYPE_SSL_NO: { upgradePromise.fail(new Exception("Postgres Server does not handle SSL connection")); + // The server waits for a startup message on this socket: close it, PREFER reconnects without SSL + ctx.close(); break; } default: upgradePromise.fail(new Exception("Invalid SSL connection message")); + ctx.close(); break; } } diff --git a/vertx-pg-client/src/test/java/io/vertx/tests/pgclient/TLSTest.java b/vertx-pg-client/src/test/java/io/vertx/tests/pgclient/TLSTest.java index 9c1178979..59be2d2b3 100644 --- a/vertx-pg-client/src/test/java/io/vertx/tests/pgclient/TLSTest.java +++ b/vertx-pg-client/src/test/java/io/vertx/tests/pgclient/TLSTest.java @@ -24,9 +24,12 @@ import io.vertx.pgclient.*; import io.vertx.sqlclient.Tuple; import io.vertx.tests.pgclient.junit.ContainerPgRule; +import io.vertx.tests.sqlclient.ProxyServer; import org.junit.*; import org.junit.runner.RunWith; +import java.util.concurrent.atomic.AtomicInteger; + @RunWith(VertxUnitRunner.class) public class TLSTest { @@ -150,6 +153,32 @@ public void testSslModePreferFallback(TestContext ctx) { })); } + @Test + public void testSslModeRequireClosesRefusedSocket(TestContext ctx) { + PgConnectOptions options = ruleSllOff.options() + .setSslMode(SslMode.REQUIRE) + .setSslOptions(new ClientSSLOptions().setTrustAll(true)); + AtomicInteger openSockets = new AtomicInteger(); + ProxyServer proxy = ProxyServer.create(vertx, options.getPort(), options.getHost()); + proxy.proxyHandler(conn -> { + openSockets.incrementAndGet(); + conn.clientCloseHandler(v -> openSockets.decrementAndGet()); + conn.connect(); + }); + Async listen = ctx.async(); + proxy.listen(8080, "localhost", ctx.asyncAssertSuccess(v -> listen.complete())); + listen.awaitSuccess(10000); + options.setPort(8080).setHost("localhost"); + Async async = ctx.async(); + PgConnection.connect(vertx, options).onComplete(ctx.asyncAssertFailure(err -> { + // The server refused SSL: the client must not keep the socket it opened to ask for it + vertx.setTimer(2000, id -> { + ctx.assertEquals(0, openSockets.get()); + async.complete(); + }); + })); + } + @Test public void testSslModeVerifyCaConf(TestContext ctx) { PgConnectOptions options = ruleOptionalSll.options()