private void testHttpClientResponseThrowsExceptionInHandler( String chunk, BiConsumer<HttpClientResponse, CountDownLatch> handler) throws Exception { server.requestHandler(req -> { HttpServerResponse resp = req.response(); if (chunk != null) { resp.end(chunk); } else { resp.end(); } }); startServer(); int num = 50; CountDownLatch latch = new CountDownLatch(num); for (int i = 0;i < num;i++) { client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/someuri", onSuccess(resp -> { handler.accept(resp, latch); })); } awaitLatch(latch); }
@Test public void testClosingVertxCloseSharedServers() throws Exception { int numServers = 2; Vertx vertx = Vertx.vertx(); List<HttpServerImpl> servers = new ArrayList<>(); for (int i = 0;i < numServers;i++) { HttpServer server = vertx.createHttpServer(createBaseServerOptions()).requestHandler(req -> { }); startServer(server); servers.add((HttpServerImpl) server); } CountDownLatch latch = new CountDownLatch(1); vertx.close(onSuccess(v -> { latch.countDown(); })); awaitLatch(latch); servers.forEach(server -> { assertTrue(server.isClosed()); }); }
private void testHttpServerRequestDecodeError(Handler<NetSocket> bodySender, Handler<List<Throwable>> errorsChecker) throws Exception { AtomicReference<NetSocket> current = new AtomicReference<>(); server.requestHandler(req -> { List<Throwable> errors = new ArrayList<>(); Handler<Throwable> handler = err -> { errors.add(err); if (errors.size() == 2) { errorsChecker.handle(errors); testComplete(); } }; req.exceptionHandler(handler); bodySender.handle(current.get()); }); startServer(); NetClient client = vertx.createNetClient(); client.connect(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, onSuccess(so -> { current.set(so); so.write("POST /somepath HTTP/1.1\r\n"); so.write("Transfer-Encoding: chunked\r\n"); so.write("\r\n"); })); await(); }
private void testHttpClientResponseDecodeError(Handler<Throwable> errorHandler) throws Exception { startServer(); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", onSuccess(resp -> { resp.exceptionHandler(errorHandler); })); await(); }
@Test public void testSetChunkedToFalse() throws Exception { server.requestHandler(req -> req.response().setChunked(false).end()); startServer(); client.get(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/", resp -> { testComplete(); }).setChunked(false).end(); 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(); }
private void testKeepAliveTimeout(HttpClientOptions options, int numReqs) throws Exception { startServer(); client.close(); client = vertx.createHttpClient(options.setPoolCleanerPeriod(1)); AtomicInteger respCount = new AtomicInteger(); for (int i = 0;i < numReqs;i++) { int current = 1 + i; client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { respCount.incrementAndGet(); if (current == numReqs) { long now = System.currentTimeMillis(); resp.request().connection().closeHandler(v -> { long timeout = System.currentTimeMillis() - now; int delta = 500; int low = 3000 - delta; int high = 3000 + delta; assertTrue("Expected actual close timeout " + timeout + " to be > " + low, low < timeout); assertTrue("Expected actual close timeout " + timeout + " + to be < " + high, timeout < high); testComplete(); }); } })); } await(); }
@Test public void testPoolNotExpiring() throws Exception { AtomicLong now = new AtomicLong(); server.requestHandler(req -> { req.response().end(); now.set(System.currentTimeMillis()); vertx.setTimer(2000, id -> { req.connection().close(); }); }); startServer(); client.close(); client = vertx.createHttpClient(new HttpClientOptions().setPoolCleanerPeriod(0).setKeepAliveTimeout(100)); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { resp.endHandler(v1 -> { resp.request().connection().closeHandler(v2 -> { long time = System.currentTimeMillis() - now.get(); assertTrue("Was expecting " + time + " to be > 2000", time >= 2000); testComplete(); }); }); })); await(); }
@Test public void testUnknownContentLengthIsSetToZeroWithHTTP_1_0() throws Exception { server.requestHandler(req -> { req.response().write("Some-String").end(); }); startServer(); client.close(); client = vertx.createHttpClient(new HttpClientOptions().setProtocolVersion(HttpVersion.HTTP_1_0)); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { assertNull(resp.getHeader("Content-Length")); testComplete(); })); await(); }
@Test public void testTooLongContentInHttpServerRequest() throws Exception { server.requestHandler(req -> { req.response().end(); }); server.connectionHandler(conn -> { conn.exceptionHandler(error -> { assertEquals(IllegalArgumentException.class, error.getClass()); testComplete(); }); }); startServer(); NetClient client = vertx.createNetClient(); try { client.connect(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, onSuccess(so -> { so.write("POST / HTTP/1.1\r\nContent-Length: 4\r\n\r\ntoolong\r\n"); })); await(); } finally { client.close(); } } @Test
@Test public void testCompressedResponseWithConnectionCloseAndNoCompressionHeader() throws Exception { Buffer expected = Buffer.buffer(TestUtils.randomAlphaString(2048)); server.close(); server = vertx.createHttpServer(new HttpServerOptions() .setPort(DEFAULT_HTTP_PORT) .setHost(DEFAULT_HTTP_HOST) .setCompressionSupported(true)); server.requestHandler(req -> { req.response().end(expected); }); startServer(); client.get(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { resp.bodyHandler(buff -> { assertEquals(expected, buff); complete(); }); })).putHeader("Connection", "close") .exceptionHandler(this::fail) .end(); await(); }
@Test public void testIdleTimeoutWithPartialH2CRequest() throws Exception { server.close(); server = vertx.createHttpServer(new HttpServerOptions() .setPort(DEFAULT_HTTP_PORT) .setHost(DEFAULT_HTTP_HOST) .setIdleTimeout(1)); server.requestHandler(req -> { testComplete(); }); startServer(); NetClient client = vertx.createNetClient(); client.connect(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, onSuccess(so -> { so.closeHandler(v -> { testComplete(); }); })); await(); }
@Test public void testPartialH2CAmbiguousRequest() throws Exception { server.requestHandler(req -> { assertEquals("POST", req.rawMethod()); testComplete(); }); Buffer fullRequest = Buffer.buffer("POST /whatever HTTP/1.1\r\n\r\n"); startServer(); NetClient client = vertx.createNetClient(); client.connect(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, onSuccess(so -> { so.write(fullRequest.slice(0, 1)); vertx.setTimer(1000, id -> { so.write(fullRequest.slice(1, fullRequest.length())); }); })); await(); }
@Test public void testHttpClientResumeConnectionOnResponseOnLastMessage() throws Exception { server.requestHandler(req -> req.response().end("ok")); startServer(); client.close(); client = vertx.createHttpClient(new HttpClientOptions().setKeepAlive(true).setMaxPoolSize(1)); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp1 -> { resp1.pause(); // The connection resume is asynchronous and the end message will be received before connection resume happens resp1.resume(); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp2 -> { testComplete(); })); })); await(); }
private void testHttpClientResponsePause(Handler<HttpClientResponse> h) throws Exception { server.requestHandler(req -> req.response().end("ok")); startServer(); client.close(); client = vertx.createHttpClient(new HttpClientOptions().setMaxPoolSize(1).setKeepAlive(true)); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp1 -> { h.handle(resp1); vertx.setTimer(10, timerId -> { // The connection should be resumed as it's ended client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp2 -> { assertSame(resp1.request().connection(), resp2.request().connection()); resp2.endHandler(v -> testComplete()); })); }); })); await(); }
@Test public void testDeferredRequestEnd() throws Exception { server.requestHandler(req -> { req.pause(); req.bodyHandler(body -> { assertTrue(req.isEnded()); req.response().end(body); }); vertx.setTimer(10, v -> { assertFalse(req.isEnded()); req.resume(); }); }); startServer(); Buffer expected = Buffer.buffer(TestUtils.randomAlphaString(1024)); client.post(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/", onSuccess(resp -> { resp.bodyHandler(body -> { assertEquals(expected, body); testComplete(); }); })).end(expected); await(); }
@Test public void testPausedHttpServerRequestUnpauseTheConnectionAtRequestEnd() throws Exception { int numRequests = 20; waitFor(numRequests); server.requestHandler(req -> { req.handler(buff -> { assertEquals("small", buff.toString()); req.pause(); }); req.endHandler(v -> { req.response().end(); }); }); startServer(); client.close(); client = vertx.createHttpClient(createBaseClientOptions().setMaxPoolSize(1)); for (int i = 0; i < numRequests; i++) { client.put(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/someuri", resp -> { complete(); }).end("small"); } }
@Test public void testSendFilePipelined() throws Exception { int n = 4; waitFor(n); File sent = TestUtils.tmpFile(".dat", 16 * 1024); server.requestHandler( req -> { req.response().sendFile(sent.getAbsolutePath()); }); startServer(); client.close(); client = vertx.createHttpClient(createBaseClientOptions().setPipelining(true).setMaxPoolSize(1)); for (int i = 0;i < n;i++) { client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { resp.exceptionHandler(this::fail); resp.bodyHandler(body -> { complete(); }); })); } await(); } }
@Test public void testEndServerResponseResumeTheConnection() throws Exception { server.requestHandler(req -> { req.endHandler(v -> { req.pause(); req.response().end(); }); }); startServer(); client.close(); waitFor(2); client = vertx.createHttpClient(new HttpClientOptions().setKeepAlive(true).setMaxPoolSize(1)); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { assertEquals(200, resp.statusCode()); complete(); })); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { assertEquals(200, resp.statusCode()); complete(); })); await(); }
@Test public void testEndServerRequestResumeTheConnection() throws Exception { server.requestHandler(req -> { req.response().end(); req.endHandler(v -> { req.pause(); }); }); startServer(); client.close(); waitFor(2); client = vertx.createHttpClient(new HttpClientOptions().setKeepAlive(true).setMaxPoolSize(1)); client.put(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { assertEquals(200, resp.statusCode()); complete(); })).end("1"); client.put(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { assertEquals(200, resp.statusCode()); complete(); })).end("2"); await(); }