private void testClientConnectionHandler(boolean local, boolean global) throws Exception { server.requestHandler(req -> { req.response().end(); }); CountDownLatch listenLatch = new CountDownLatch(1); server.listen(onSuccess(s -> listenLatch.countDown())); awaitLatch(listenLatch); AtomicInteger status = new AtomicInteger(); Handler<HttpConnection> handler = conn -> status.getAndIncrement(); if (global) { client.connectionHandler(handler); } HttpClientRequest req = client.post(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", resp -> { assertEquals((local ? 1 : 0) + (global ? 1 : 0), status.getAndIncrement()); testComplete(); }); if (local) { req.connectionHandler(handler); } req.end(); await(); }
@Test public void testServerConnectionHandler() throws Exception { AtomicInteger status = new AtomicInteger(); AtomicReference<HttpConnection> connRef = new AtomicReference<>(); server.connectionHandler(conn -> { assertEquals(0, status.getAndIncrement()); assertNull(connRef.getAndSet(conn)); }); server.requestHandler(req -> { assertEquals(1, status.getAndIncrement()); assertSame(connRef.get(), req.connection()); req.response().end(); }); CountDownLatch listenLatch = new CountDownLatch(1); server.listen(onSuccess(s -> listenLatch.countDown())); awaitLatch(listenLatch); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", resp -> { testComplete(); }); await(); }
@Test public void testClientMultiThreaded() throws Exception { int numThreads = 10; Thread[] threads = new Thread[numThreads]; CountDownLatch latch = new CountDownLatch(numThreads); server.requestHandler(req -> { req.response().putHeader("count", req.headers().get("count")); req.response().end(); }).listen(ar -> { assertTrue(ar.succeeded()); for (int i = 0; i < numThreads; i++) { int index = i; threads[i] = new Thread() { public void run() { client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/", onSuccess(res -> { assertEquals(200, res.statusCode()); assertEquals(String.valueOf(index), res.headers().get("count")); latch.countDown(); })).putHeader("count", String.valueOf(index)).end(); } }; threads[i].start(); } }); awaitLatch(latch); for (int i = 0; i < numThreads; i++) { threads[i].join(); } }
@Test public void testClientExceptionHandlerCalledWhenServerTerminatesConnection() throws Exception { int numReqs = 10; CountDownLatch latch = new CountDownLatch(numReqs); server.requestHandler(request -> { request.response().close(); }).listen(DEFAULT_HTTP_PORT, onSuccess(s -> { // Exception handler should be called for any requests in the pipeline if connection is closed for (int i = 0; i < numReqs; i++) { client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onFailure(err -> { latch.countDown(); })) .exceptionHandler(error -> fail("Exception handler should not be called")) .end(); } })); awaitLatch(latch); }
@Test public void testClientConnectionClose() throws Exception { // Test client connection close + server close handler CountDownLatch latch = new CountDownLatch(1); server.requestHandler(req -> { AtomicInteger len = new AtomicInteger(); req.handler(buff -> { if (len.addAndGet(buff.length()) == 1024) { latch.countDown(); } }); req.connection().closeHandler(v -> { testComplete(); }); }); CountDownLatch listenLatch = new CountDownLatch(1); server.listen(onSuccess(s -> listenLatch.countDown())); awaitLatch(listenLatch); HttpClientRequest req = client.post(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", onFailure(err -> {})); req.setChunked(true); req.write(TestUtils.randomBuffer(1024)); awaitLatch(latch); req.connection().close(); await(); }
@Test public void testConnectionErrorsGetReportedToHandlers() throws InterruptedException { CountDownLatch latch = new CountDownLatch(3); // This one should cause an error in the Client Exception handler, because it has no exception handler set specifically. HttpClientRequest req1 = client.request(HttpMethod.GET, 9998, DEFAULT_HTTP_HOST, "someurl1", onFailure(resp -> { latch.countDown(); })); req1.exceptionHandler(t -> { fail("Should not be called"); }); HttpClientRequest req2 = client.request(HttpMethod.GET, 9998, DEFAULT_HTTP_HOST, "someurl2", onFailure(resp -> { latch.countDown(); })); AtomicInteger req2Exceptions = new AtomicInteger(); req2.exceptionHandler(t -> { assertEquals("More than one call to req2 exception handler was not expected", 1, req2Exceptions.incrementAndGet()); latch.countDown(); }); req1.end(); req2.sendHead(); awaitLatch(latch); testComplete(); }
@Test public void testServerConnectionClose() throws Exception { // Test server connection close + client close handler server.requestHandler(req -> { req.connection().close(); }); CountDownLatch listenLatch = new CountDownLatch(1); server.listen(onSuccess(s -> listenLatch.countDown())); awaitLatch(listenLatch); client.post(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", onFailure(err -> { })) .connectionHandler(conn -> { conn.closeHandler(v -> { testComplete(); }); }).sendHead(); await(); }
@Test public void testHttpClientRequestTimeoutResetsTheConnection() throws Exception { waitFor(3); server.requestHandler(req -> { AtomicBoolean errored = new AtomicBoolean(); req.exceptionHandler(err -> { if (errored.compareAndSet(false, true)) { complete(); } }); }); startServer(); HttpClientRequest req = client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onFailure(err -> { complete(); })); AtomicBoolean errored = new AtomicBoolean(); req.exceptionHandler(err -> { if (errored.compareAndSet(false, true)) { complete(); } }); CountDownLatch latch = new CountDownLatch(1); req.setChunked(true).sendHead(version -> latch.countDown()); awaitLatch(latch); req.setTimeout(100); await(); }
.setChunked(true) .write(buff1); awaitLatch(latch);
.setChunked(true) .write(buff1); awaitLatch(latch); req.end(buff2); await();
private void testClientConnectionHandler(boolean local, boolean global) throws Exception { server.requestHandler(req -> { req.response().end(); }); CountDownLatch listenLatch = new CountDownLatch(1); server.listen(onSuccess(s -> listenLatch.countDown())); awaitLatch(listenLatch); AtomicInteger status = new AtomicInteger(); Handler<HttpConnection> handler = conn -> status.getAndIncrement(); if (global) { client.connectionHandler(handler); } HttpClientRequest req = client.post(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", resp -> { assertEquals((local ? 1 : 0) + (global ? 1 : 0), status.getAndIncrement()); testComplete(); }); if (local) { req.connectionHandler(handler); } req.end(); await(); }
@Test public void testServerConnectionHandler() throws Exception { AtomicInteger status = new AtomicInteger(); AtomicReference<HttpConnection> connRef = new AtomicReference<>(); server.connectionHandler(conn -> { assertEquals(0, status.getAndIncrement()); assertNull(connRef.getAndSet(conn)); }); server.requestHandler(req -> { assertEquals(1, status.getAndIncrement()); assertSame(connRef.get(), req.connection()); req.response().end(); }); CountDownLatch listenLatch = new CountDownLatch(1); server.listen(onSuccess(s -> listenLatch.countDown())); awaitLatch(listenLatch); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", resp -> { testComplete(); }); await(); }
@Test public void testClientMultiThreaded() throws Exception { int numThreads = 10; Thread[] threads = new Thread[numThreads]; CountDownLatch latch = new CountDownLatch(numThreads); server.requestHandler(req -> { req.response().putHeader("count", req.headers().get("count")); req.response().end(); }).listen(ar -> { assertTrue(ar.succeeded()); for (int i = 0; i < numThreads; i++) { int index = i; threads[i] = new Thread() { public void run() { client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/", res -> { assertEquals(200, res.statusCode()); assertEquals(String.valueOf(index), res.headers().get("count")); latch.countDown(); }).putHeader("count", String.valueOf(index)).end(); } }; threads[i].start(); } }); awaitLatch(latch); for (int i = 0; i < numThreads; i++) { threads[i].join(); } }
@Test public void testClientConnectionClose() throws Exception { // Test client connection close + server close handler CountDownLatch latch = new CountDownLatch(1); server.requestHandler(req -> { AtomicInteger len = new AtomicInteger(); req.handler(buff -> { if (len.addAndGet(buff.length()) == 1024) { latch.countDown(); } }); req.connection().closeHandler(v -> { testComplete(); }); }); CountDownLatch listenLatch = new CountDownLatch(1); server.listen(onSuccess(s -> listenLatch.countDown())); awaitLatch(listenLatch); HttpClientRequest req = client.post(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", resp -> { fail(); }); req.setChunked(true); req.write(TestUtils.randomBuffer(1024)); awaitLatch(latch); req.connection().close(); await(); }
@Test public void testClientExceptionHandlerCalledWhenServerTerminatesConnection() throws Exception { int numReqs = 10; CountDownLatch latch = new CountDownLatch(numReqs); server.requestHandler(request -> { request.response().close(); }).listen(DEFAULT_HTTP_PORT, onSuccess(s -> { // Exception handler should be called for any requests in the pipeline if connection is closed for (int i = 0; i < numReqs; i++) { client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, resp -> fail("Connect should not be called")). exceptionHandler(error -> latch.countDown()).endHandler(done -> fail()).end(); } })); awaitLatch(latch); }
req3.end(); awaitLatch(latch); testComplete();
@Test public void testServerConnectionClose() throws Exception { // Test server connection close + client close handler server.requestHandler(req -> { req.connection().close(); }); CountDownLatch listenLatch = new CountDownLatch(1); server.listen(onSuccess(s -> listenLatch.countDown())); awaitLatch(listenLatch); HttpClientRequest req = client.post(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", resp -> { fail(); }); req.connectionHandler(conn -> { conn.closeHandler(v -> { testComplete(); }); }); req.sendHead(); await(); }
@Test public void testHttpClientRequestTimeoutResetsTheConnection() throws Exception { waitFor(2); server.requestHandler(req -> { AtomicBoolean errored = new AtomicBoolean(); req.exceptionHandler(err -> { if (errored.compareAndSet(false, true)) { complete(); } }); }); startServer(); HttpClientRequest req = client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, resp -> fail("Response should not be handled")); req.exceptionHandler(err -> { complete(); }); CountDownLatch latch = new CountDownLatch(1); req.sendHead(version -> latch.countDown()); awaitLatch(latch); req.setTimeout(100); await(); }
.setChunked(true) .write(buff1); awaitLatch(latch); req.end(buff2); await();
.setChunked(true) .write(buff1); awaitLatch(latch);