@Test public void testClientNetSocketCloseRemovesFromThePool() throws Exception { testHttpClientResponseThrowsExceptionInHandler(null, (resp, latch) -> { NetSocket socket = resp.netSocket(); socket.closeHandler(v -> { latch.countDown(); }); socket.close(); }); }
void connect(SocketAddress address) { startEchoServer(testAddress, s -> { final int numConnections = 100; final AtomicInteger connCount = new AtomicInteger(0); for (int i = 0; i < numConnections; i++) { Handler<AsyncResult<NetSocket>> handler = res -> { if (res.succeeded()) { res.result().close(); if (connCount.incrementAndGet() == numConnections) { testComplete(); } } }; client.connect(address, handler); } }); await(); }
void clientCloseHandlers(boolean closeFromClient) { client.connect(testAddress, onSuccess(so -> { AtomicInteger counter = new AtomicInteger(0); so.endHandler(v -> assertEquals(1, counter.incrementAndGet())); so.closeHandler(v -> { assertEquals(2, counter.incrementAndGet()); testComplete(); }); if (closeFromClient) { so.close(); } })); }
@Test public void testServerCloseHandlersCloseFromClient() { serverCloseHandlers(false, s -> client.connect(testAddress, ar -> ar.result().close())); await(); }
void serverCloseHandlers(boolean closeFromServer, Handler<AsyncResult<NetServer>> listenHandler) { server.connectHandler((sock) -> { AtomicInteger counter = new AtomicInteger(0); sock.endHandler(v -> assertEquals(1, counter.incrementAndGet())); sock.closeHandler(v -> { assertEquals(2, counter.incrementAndGet()); testComplete(); }); if (closeFromServer) { sock.close(); } }).listen(testAddress, listenHandler); }
@Test public void testConnectionCloseHttp_1_1_Close() throws Exception { testConnectionClose(HttpClientRequest::end, socket -> { AtomicBoolean firstRequest = new AtomicBoolean(true); socket.handler(RecordParser.newDelimited("\r\n\r\n", buffer -> { if (firstRequest.getAndSet(false)) { socket.write("HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 3\r\n" + "\r\n" + "xxx"); } else { socket.write("HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 0\r\n" + "Connection: close\r\n" + "\r\n"); socket.close(); } })); }); }
private void testNet(String hostname) throws Exception { NetClient client = vertx.createNetClient(); NetServer server = vertx.createNetServer().connectHandler(so -> { so.handler(buff -> { so.write(buff); so.close(); }); }); try { CountDownLatch listenLatch = new CountDownLatch(1); server.listen(1234, hostname, onSuccess(s -> { listenLatch.countDown(); })); awaitLatch(listenLatch); client.connect(1234, hostname, onSuccess(so -> { Buffer buffer = Buffer.buffer(); so.handler(buffer::appendBuffer); so.closeHandler(v -> { assertEquals(Buffer.buffer("foo"), buffer); testComplete(); }); so.write(Buffer.buffer("foo")); })); await(); } finally { client.close(); server.close(); } }
@Test public void testExceptionCaught() throws Exception { vertx.createNetClient(new NetClientOptions().setSoLinger(0)).connect(8080, "localhost", onSuccess(socket -> { vertx.setTimer(2000, id -> { socket.close(); }); })); awaitLatch(resetLatch); assertThat(caught.get(), instanceOf(IOException.class)); }
@Test public void testRemoteAddress() { server.connectHandler(socket -> { SocketAddress addr = socket.remoteAddress(); assertEquals("127.0.0.1", addr.host()); socket.close(); }).listen(1234, "localhost", ar -> { assertTrue(ar.succeeded()); vertx.createNetClient(new NetClientOptions()).connect(1234, "localhost", onSuccess(socket -> { SocketAddress addr = socket.remoteAddress(); assertEquals("127.0.0.1", addr.host()); assertEquals(addr.port(), 1234); socket.closeHandler(v -> testComplete()); })); }); await(); }
@Test public void testIncorrectHttpVersion() throws Exception { server.requestHandler(req -> { NetSocket so = req.netSocket(); so.write(Buffer.buffer("HTTP/1.2 200 OK\r\nContent-Length:5\r\n\r\nHELLO")); so.close(); }); startServer(); AtomicBoolean a = new AtomicBoolean(); HttpClientRequest req = client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onFailure(err -> { if (a.compareAndSet(false, true)) { assertTrue("message " + err.getMessage() + " should contain HTTP/1.2", err.getMessage().contains("HTTP/1.2")); } })); req.exceptionHandler(err -> { fail("Should not be called"); }).putHeader("connection", "close") .connectionHandler(conn -> conn.closeHandler(v -> testComplete())) .end(); await(); }
@Test public void testTLSHostnameCertCheckIncorrect() { server.close(); server = vertx.createNetServer(new NetServerOptions().setSsl(true).setPort(4043) .setKeyCertOptions(Cert.SERVER_JKS_ROOT_CA.get())); server.connectHandler(netSocket -> netSocket.close()).listen(ar -> { NetClientOptions options = new NetClientOptions() .setHostnameVerificationAlgorithm("HTTPS") .setTrustOptions(Trust.SERVER_JKS_ROOT_CA.get()); NetClient client = vertx.createNetClient(options); client.connect(4043, "127.0.0.1", arSocket -> { if (arSocket.succeeded()) { NetSocket ns = arSocket.result(); ns.closeHandler(v -> { testComplete(); }); ns.upgradeToSsl(v -> { fail("this test should fail"); }); } else { fail(ar.cause()); } }); }); await(); }
@Test public void testWriteHandlerFailure() throws Exception { CompletableFuture<Void> close = new CompletableFuture<>(); server.connectHandler(socket -> { socket.pause(); close.thenAccept(v -> { socket.close(); }); }); startServer(); client.connect(testAddress, onSuccess(so -> { writeUntilFull(so, v -> { so.write(Buffer.buffer("lost buffer"), onFailure(err -> { testComplete(); })); close.complete(null); }); })); await(); }
private void testNetServer(VertxOptions options) { vertx = Vertx.vertx(options); NetServer server = vertx.createNetServer(); server.connectHandler(so -> { so.handler(buff -> { assertEquals("ping", buff.toString()); so.write("pong"); }); so.closeHandler(v -> { testComplete(); }); }); server.listen(1234, onSuccess(v -> { NetClient client = vertx.createNetClient(); client.connect(1234, "localhost", onSuccess(so -> { so.write("ping"); so.handler(buff -> { assertEquals("pong", buff.toString()); so.close(); }); })); })); await(); }
@Test public void testConnectionCloseHttp_1_0_Close() throws Exception { testConnectionClose(req -> { req.putHeader("Connection", "close"); req.end(); }, socket -> { AtomicBoolean firstRequest = new AtomicBoolean(true); socket.handler(RecordParser.newDelimited("\r\n\r\n", buffer -> { if (firstRequest.getAndSet(false)) { socket.write("HTTP/1.0 200 OK\n" + "Content-Type: text/plain\n" + "Content-Length: 4\n" + "Connection: keep-alive\n" + "\n" + "xxx\n"); } else { socket.write("HTTP/1.0 200 OK\n" + "Content-Type: text/plain\n" + "Content-Length: 1\n" + "\n" + "\n"); socket.close(); } })); }); }
@Test public void testClientLocalAddress() { String expectedAddress = TestUtils.loopbackAddress(); NetClientOptions clientOptions = new NetClientOptions().setLocalAddress(expectedAddress); client.close(); client = vertx.createNetClient(clientOptions); server.connectHandler(sock -> { assertEquals(expectedAddress, sock.remoteAddress().host()); sock.close(); }); server.listen(1234, "localhost", onSuccess(v -> { client.connect(1234, "localhost", onSuccess(socket -> { socket.closeHandler(v2 -> { testComplete(); }); })); })); await(); }
@Test public void testSendFileFailsWhenClientClosesConnection() throws Exception { // 10 megs final File f = setupFile("file.pdf", TestUtils.randomUnicodeString(10 * 1024 * 1024)); server.requestHandler(req -> { try { req.response().sendFile(f.getAbsolutePath(), ar -> { if (ar.failed()) { // Broken pipe testComplete(); } else { fail(new Exception("It should not reach this point")); } }); } catch (Exception e) { // this was the bug reported with issues/issue-80 fail(e); } }); startServer(); vertx.createNetClient().connect(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, socket -> { socket.result().write("GET / HTTP/1.1\r\n\r\n").close(); }); await(); }
client.connect(testAddress, onSuccess(so -> { vertx.setTimer(1000, id -> { so.close(); }); }));
@Test public void testWorkerClient() throws Exception { String expected = TestUtils.randomAlphaString(2000); server.connectHandler(so -> { so.write(expected).close(); }); startServer(); vertx.deployVerticle(new AbstractVerticle() { @Override public void start() throws Exception { NetClient client = vertx.createNetClient(); client.connect(testAddress, onSuccess(so ->{ Buffer received = Buffer.buffer(); so.handler(received::appendBuffer); so.closeHandler(v -> { assertEquals(expected, received.toString()); testComplete(); }); try { Thread.sleep(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } })); } }, new DeploymentOptions().setWorker(true)); await(); }
@Test public void testWorkerServer() throws Exception { String expected = TestUtils.randomAlphaString(2000); vertx.deployVerticle(new AbstractVerticle() { @Override public void start(Future<Void> startFuture) throws Exception { NetServer server = vertx.createNetServer(); server.connectHandler(so -> { Buffer received = Buffer.buffer(); so.handler(received::appendBuffer); so.closeHandler(v -> { assertEquals(expected, received.toString()); testComplete(); }); try { Thread.sleep(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); server.listen(testAddress, ar -> startFuture.handle(ar.mapEmpty())); } }, new DeploymentOptions().setWorker(true), onSuccess(v -> { client.connect(testAddress, onSuccess(so -> { so.write(expected).close(); })); })); await(); }
@Test public void testTLSHostnameCertCheckCorrect() { server.close(); server = vertx.createNetServer(new NetServerOptions().setSsl(true).setPort(4043) .setKeyCertOptions(Cert.SERVER_JKS_ROOT_CA.get())); server.connectHandler(netSocket -> netSocket.close()).listen(ar -> { NetClientOptions options = new NetClientOptions() .setHostnameVerificationAlgorithm("HTTPS") .setTrustOptions(Trust.SERVER_JKS_ROOT_CA.get()); NetClient client = vertx.createNetClient(options); client.connect(4043, "localhost", arSocket -> { if (arSocket.succeeded()) { NetSocket ns = arSocket.result(); ns.exceptionHandler(th -> { fail(th); }); ns.upgradeToSsl(v -> { testComplete(); }); } else { fail(ar.cause()); } }); }); await(); }