protected void testCloseHandlerNotCalledWhenConnectionClosedAfterEnd(int expected) throws Exception { AtomicInteger closeCount = new AtomicInteger(); AtomicInteger endCount = new AtomicInteger(); server.requestHandler(req -> { req.response().closeHandler(v -> { closeCount.incrementAndGet(); }); req.response().endHandler(v -> { endCount.incrementAndGet(); }); req.connection().closeHandler(v -> { assertEquals(expected, closeCount.get()); assertEquals(1, endCount.get()); testComplete(); }); req.response().end("some-data"); }); startServer(); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", onSuccess(resp -> { resp.endHandler(v -> { resp.request().connection().close(); }); })); 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(); }
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 testResponseDataTimeout() { Buffer expected = TestUtils.randomBuffer(1000); server.requestHandler(req -> { req.response().setChunked(true).write(expected); }); server.listen(onSuccess(s -> { Buffer received = Buffer.buffer(); HttpClientRequest req = client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { resp.request().setTimeout(500); resp.handler(received::appendBuffer); })); AtomicInteger count = new AtomicInteger(); req.exceptionHandler(t -> { if (count.getAndIncrement() == 0) { assertTrue(t instanceof TimeoutException); assertEquals(expected, received); testComplete(); } }); req.sendHead(); })); await(); }
@Test public void testClientConnectionClosed() throws Exception { server.requestHandler(req -> { req.response().setChunked(true).write(Buffer.buffer("some-data")); }); startServer(); client = vertx.createHttpClient(createBaseClientOptions().setIdleTimeout(2)); FakeHttpClientMetrics metrics = FakeMetricsBase.getMetrics(client); HttpClientRequest req = client.get(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", onSuccess(resp -> { HttpClientMetric metric = metrics.getMetric(resp.request()); assertNotNull(metric); assertFalse(metric.failed.get()); resp.exceptionHandler(err -> { assertNull(metrics.getMetric(resp.request())); assertTrue(metric.failed.get()); testComplete(); }); })); req.end(); await(); }
private void testClearText(boolean upgrade) throws Exception { ServerBootstrap bootstrap = createH2CServer((dec, enc) -> new Http2EventAdapter() { @Override public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int streamDependency, short weight, boolean exclusive, int padding, boolean endStream) throws Http2Exception { enc.writeHeaders(ctx, streamId, new DefaultHttp2Headers().status("200"), 0, true, ctx.newPromise()); ctx.flush(); } }, upgrade); ChannelFuture s = bootstrap.bind(DEFAULT_HTTP_HOST, DEFAULT_HTTP_PORT).sync(); try { client.close(); client = vertx.createHttpClient(clientOptions.setUseAlpn(false).setSsl(false).setHttp2ClearTextUpgrade(upgrade)); client.get(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", onSuccess(resp1 -> { HttpConnection conn = resp1.request().connection(); assertEquals(HttpVersion.HTTP_2, resp1.version()); client.get(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", onSuccess(resp2 -> { assertSame(((HttpClientConnection)conn).channel(), ((HttpClientConnection)resp2.request().connection()).channel()); testComplete(); })).exceptionHandler(this::fail).end(); })).exceptionHandler(this::fail).end(); await(); } finally { s.channel().close().sync(); } }
@Test public void testKeepAliveTimeout() throws Exception { server.requestHandler(req -> { req.response().end(); }); startServer(); client.close(); client = vertx.createHttpClient(createBaseClientOptions().setHttp2KeepAliveTimeout(3).setPoolCleanerPeriod(1)); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { 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 testFollowRedirectLimit() throws Exception { AtomicInteger redirects = new AtomicInteger(); server.requestHandler(req -> { int val = redirects.incrementAndGet(); if (val > 16) { fail(); } else { String scheme = createBaseServerOptions().isSsl() ? "https" : "http"; req.response().setStatusCode(301).putHeader(HttpHeaders.LOCATION, scheme + "://localhost:8080/otherpath").end(); } }); startServer(); client.get(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", onSuccess(resp -> { assertEquals(16, redirects.get()); assertEquals(301, resp.statusCode()); assertEquals("/otherpath", resp.request().path()); testComplete(); })).setFollowRedirects(true).end(); await(); }
@Test public void testDisableIdleTimeoutInPool() throws Exception { server.requestHandler(req -> { req.response().end(); }); startServer(); client.close(); client = vertx.createHttpClient(createBaseClientOptions() .setIdleTimeout(1) .setMaxPoolSize(1) .setKeepAliveTimeout(10) ); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { resp.endHandler(v1 -> { AtomicBoolean closed = new AtomicBoolean(); resp.request().connection().closeHandler(v2 -> { closed.set(true); }); vertx.setTimer(2000, id -> { assertFalse(closed.get()); testComplete(); }); }); })); await(); }
@Test public void testSendingGoAwayDiscardsTheConnection() throws Exception { AtomicInteger reqCount = new AtomicInteger(); server.requestHandler(req -> { switch (reqCount.getAndIncrement()) { case 0: req.response().setChunked(true).write("some-data"); break; case 1: req.response().end(); break; default: fail(); } }); startServer(); client.getNow(DEFAULT_HTTPS_PORT, DEFAULT_HTTPS_HOST, "/somepath", onSuccess(resp -> { resp.request().connection().goAway(0); client.get(DEFAULT_HTTPS_PORT, DEFAULT_HTTPS_HOST, "/somepath", resp2 -> { testComplete(); }).setTimeout(5000).exceptionHandler(this::fail).end(); })); await(); }
@Test public void testFollowRedirectHost() throws Exception { String scheme = createBaseClientOptions().isSsl() ? "https" : "http"; waitFor(2); HttpServerOptions options = createBaseServerOptions(); int port = options.getPort() + 1; options.setPort(port); AtomicInteger redirects = new AtomicInteger(); server.requestHandler(req -> { redirects.incrementAndGet(); req.response().setStatusCode(301).putHeader(HttpHeaders.LOCATION, scheme + "://localhost:" + port + "/whatever").end(); }); startServer(); HttpServer server2 = vertx.createHttpServer(options); server2.requestHandler(req -> { assertEquals(1, redirects.get()); assertEquals(scheme + "://localhost:" + port + "/whatever", req.absoluteURI()); req.response().end(); complete(); }); startServer(server2); client.get(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", onSuccess(resp -> { assertEquals(scheme + "://localhost:" + port + "/whatever", resp.request().absoluteURI()); complete(); })).setFollowRedirects(true).setHost("localhost:" + options.getPort()).end(); await(); }
@Test public void testRequestEntityTooLarge() { String path = "/some/path"; server = vertx.createHttpServer(new HttpServerOptions().setPort(DEFAULT_HTTP_PORT)).websocketHandler(ws -> fail()); server.listen(onSuccess(ar -> { client.get(DEFAULT_HTTP_PORT, HttpTestBase.DEFAULT_HTTPS_HOST, path, onSuccess(resp -> { assertEquals(413, resp.statusCode()); resp.request().connection().closeHandler(v -> { testComplete(); }); })).putHeader("Upgrade", "Websocket") .putHeader("Connection", "Upgrade") .end(TestUtils.randomBuffer(8192 + 1)); })); await(); }
@Test public void testCloseHandlerWhenConnectionEnds() throws Exception { server.requestHandler(req -> { req.response().closeHandler(v -> { testComplete(); }); req.response().setChunked(true).write("some-data"); }); startServer(); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", onSuccess(resp -> { resp.handler(v -> { resp.request().connection().close(); }); })); await(); }
@Test public void testHttpServerRequestShouldExceptionHandlerWhenTheClosedHandlerIsCalled() { server = vertx.createHttpServer(new HttpServerOptions().setPort(DEFAULT_HTTP_PORT)).requestHandler(req -> { HttpServerResponse resp = req.response(); resp.setChunked(true); CheckingSender sender = new CheckingSender(vertx.getOrCreateContext(), resp); sender.send(); resp.closeHandler(v -> { Throwable failure = sender.close(); if (failure != null) { fail(failure); } else { testComplete(); } }); }); server.listen(onSuccess(s -> { client.getNow(DEFAULT_HTTP_PORT, HttpTestBase.DEFAULT_HTTP_HOST, "/someuri", onSuccess(resp -> { vertx.setTimer(1000, id -> { resp.request().connection().close(); }); })); })); await(); }
@Test public void testDefaultStreamWeightAndDependency() throws Exception { int defaultStreamDependency = 0; short defaultStreamWeight = Http2CodecUtil.DEFAULT_PRIORITY_WEIGHT; waitFor(2); server.requestHandler(req -> { assertEquals(defaultStreamWeight, req.streamPriority().getWeight()); assertEquals(defaultStreamDependency, req.streamPriority().getDependency()); req.response().end(); complete(); }); startServer(); client = vertx.createHttpClient(createBaseClientOptions().setHttp2KeepAliveTimeout(3).setPoolCleanerPeriod(1)); HttpClientRequest request = client.get(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { assertEquals(defaultStreamWeight, resp.request().getStreamPriority().getWeight()); assertEquals(defaultStreamDependency, resp.request().getStreamPriority().getDependency()); complete(); })); request.end(); await(); }
@Test public void testCloseHandlerWhenConnectionClose() throws Exception { server.requestHandler(req -> { HttpServerResponse resp = req.response(); resp.setChunked(true).write("some-data"); resp.closeHandler(v -> { checkHttpServerResponse(resp); testComplete(); }); }); startServer(); client.getNow(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/somepath", onSuccess(resp -> { resp.handler(v -> { resp.request().connection().close(); }); })); await(); }
private void testServerMaxInitialLineLength(int maxInitialLength) { String longParam = TestUtils.randomAlphaString(5000); server.close(); server = vertx.createHttpServer(new HttpServerOptions().setMaxInitialLineLength(maxInitialLength) .setHost("localhost").setPort(8080)).requestHandler(req -> { assertEquals(req.getParam("t"), longParam); req.response().end(); }).listen(onSuccess(res -> { HttpClientRequest req = vertx.createHttpClient(new HttpClientOptions()) .request(HttpMethod.GET, 8080, "localhost", "/?t=" + longParam, onSuccess(resp -> { if (maxInitialLength > HttpServerOptions.DEFAULT_MAX_INITIAL_LINE_LENGTH) { assertEquals(200, resp.statusCode()); testComplete(); } else { assertEquals(414, resp.statusCode()); resp.request().connection().closeHandler(v -> { testComplete(); }); } })); req.end(); })); await(); }
private void testServerMaxHeaderSize(int maxHeaderSize) { String longHeader = TestUtils.randomAlphaString(9000); vertx.createHttpServer(new HttpServerOptions().setMaxHeaderSize(maxHeaderSize) .setHost("localhost").setPort(8080)).requestHandler(req -> { assertEquals(req.getHeader("t"), longHeader); req.response().end(); }).listen(onSuccess(res -> { HttpClientRequest req = vertx.createHttpClient(new HttpClientOptions()) .request(HttpMethod.GET, 8080, "localhost", "/", onSuccess(resp -> { if (maxHeaderSize > HttpServerOptions.DEFAULT_MAX_HEADER_SIZE) { assertEquals(200, resp.statusCode()); testComplete(); } else { assertEquals(400, resp.statusCode()); resp.request().connection().closeHandler(v -> { testComplete(); }); } })); // Add longHeader req.putHeader("t", longHeader); req.end(); })); await(); }
@Test public void testStreamWeightAndDependencyInheritance() throws Exception { int requestStreamDependency = 86; short requestStreamWeight = 53; waitFor(2); server.requestHandler(req -> { assertEquals(requestStreamWeight, req.streamPriority().getWeight()); assertEquals(requestStreamDependency, req.streamPriority().getDependency()); req.response().end(); complete(); }); startServer(); client = vertx.createHttpClient(createBaseClientOptions().setHttp2KeepAliveTimeout(3).setPoolCleanerPeriod(1)); HttpClientRequest request = client.get(DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { assertEquals(requestStreamWeight, resp.request().getStreamPriority().getWeight()); assertEquals(requestStreamDependency, resp.request().getStreamPriority().getDependency()); complete(); })); request.setStreamPriority(new StreamPriority() .setDependency(requestStreamDependency) .setWeight(requestStreamWeight) .setExclusive(false)); request.end(); await(); }