/** * Like {@link #sendFile(String)} but providing a handler which will be notified once the file has been completely * written to the wire. * * @param filename path to the file to serve * @param resultHandler handler that will be called on completion * @return a reference to this, so the API can be used fluently */ @Fluent default HttpServerResponse sendFile(String filename, Handler<AsyncResult<Void>> resultHandler) { return sendFile(filename, 0, resultHandler); }
/** * Same as {@link #sendFile(String, long)} using offset @code{0} which means starting from the beginning of the file. * * @param filename path to the file to serve * @return a reference to this, so the API can be used fluently */ @Fluent default HttpServerResponse sendFile(String filename) { return sendFile(filename, 0); }
/** * Same as {@link #sendFile(String, long, long)} using length @code{Long.MAX_VALUE} which means until the end of the * file. * * @param filename path to the file to serve * @param offset offset to start serving from * @return a reference to this, so the API can be used fluently */ @Fluent default HttpServerResponse sendFile(String filename, long offset) { return sendFile(filename, offset, Long.MAX_VALUE); }
/** * Like {@link #sendFile(String, long)} but providing a handler which will be notified once the file has been completely * written to the wire. * * @param filename path to the file to serve * @param offset the offset to serve from * @param resultHandler handler that will be called on completion * @return a reference to this, so the API can be used fluently */ @Fluent default HttpServerResponse sendFile(String filename, long offset, Handler<AsyncResult<Void>> resultHandler) { return sendFile(filename, offset, Long.MAX_VALUE, resultHandler); }
@Override public void start() throws Exception { vertx.createHttpServer().websocketHandler(ws -> ws.handler(ws::writeBinaryMessage)).requestHandler(req -> { if (req.uri().equals("/")) req.response().sendFile("ws.html"); }).listen(8080); } }
@Test public void testServerChainingSendFile() throws Exception { File file = setupFile("test-server-chaining.dat", "blah"); server.requestHandler(req -> { assertTrue(req.response().sendFile(file.getAbsolutePath()) == req.response()); assertTrue(req.response().ended()); file.delete(); testComplete(); }); server.listen(onSuccess(server -> { client.request(HttpMethod.PUT, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, noOpHandler()).end(); })); await(); }
@Test public void testSendFileNotFound() throws Exception { server.requestHandler(req -> { req.response().putHeader("Content-Type", "wibble"); req.response().sendFile("nosuchfile.html"); }); server.listen(onSuccess(s -> { client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onFailure(err -> {})).end(); vertx.setTimer(100, tid -> testComplete()); })); await(); }
@Test public void testSendOpenRangeFileFromClasspath() { vertx.createHttpServer(new HttpServerOptions().setPort(8080)).requestHandler(res -> { res.response().sendFile("webroot/somefile.html", 6); }).listen(onSuccess(res -> { vertx.createHttpClient(new HttpClientOptions()).request(HttpMethod.GET, 8080, "localhost", "/", onSuccess(resp -> { resp.bodyHandler(buff -> { assertTrue(buff.toString().startsWith("<body>blah</body></html>")); testComplete(); }); })).end(); })); await(); }
@Test public void testSendFileFromClasspath() { vertx.createHttpServer(new HttpServerOptions().setPort(8080)).requestHandler(res -> { res.response().sendFile(webRoot + "/somefile.html"); }).listen(onSuccess(res -> { vertx.createHttpClient(new HttpClientOptions()).request(HttpMethod.GET, 8080, "localhost", "/", onSuccess(resp -> { resp.bodyHandler(buff -> { assertTrue(buff.toString().startsWith("<html><body>blah</body></html>")); testComplete(); }); })).end(); })); 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(); }
@Test public void testSendFileDirectoryWithHandler() throws Exception { File dir = testFolder.newFolder(); server.requestHandler(req -> { req.response().putHeader("Content-Type", "wibble"); req.response().sendFile(dir.getAbsolutePath(), onFailure(t -> { assertTrue(t instanceof FileNotFoundException); testComplete(); })); }); server.listen(onSuccess(s -> { client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onFailure(err -> {})).end(); })); await(); }
@Test public void testSendFileNotFoundWithHandler() throws Exception { server.requestHandler(req -> { req.response().putHeader("Content-Type", "wibble"); req.response().sendFile("nosuchfile.html", onFailure(t -> { assertTrue(t instanceof FileNotFoundException); testComplete(); })); }); server.listen(onSuccess(s -> { client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onFailure(resp -> {})).end(); })); await(); }
@Test public void testSendRangeFileFromClasspath() { vertx.createHttpServer(new HttpServerOptions().setPort(8080)).requestHandler(res -> { res.response().sendFile("webroot/somefile.html", 6, 6); }).listen(onSuccess(res -> { vertx.createHttpClient(new HttpClientOptions()).request(HttpMethod.GET, 8080, "localhost", "/", onSuccess(resp -> { resp.bodyHandler(buff -> { assertEquals("<body>", buff.toString()); testComplete(); }); })).end(); })); await(); }
@Test public void testSendNonExistingFile() throws Exception { server.requestHandler(req -> { final Context ctx = vertx.getOrCreateContext(); req.response().sendFile("/not/existing/path", event -> { assertEquals(ctx, vertx.getOrCreateContext()); if (event.failed()) { req.response().end("failed"); } }); }); server.listen(onSuccess(s -> { client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { resp.bodyHandler(buff -> { assertEquals("failed", buff.toString()); testComplete(); }); })).end(); })); await(); }
private void sendFile(String fileName, String contentExpected, boolean useHandler, Function<Handler<AsyncResult<HttpClientResponse>>, HttpClientRequest> requestFact) throws Exception { waitFor(2); File fileToSend = setupFile(fileName, contentExpected); server.requestHandler(req -> { if (useHandler) { Handler<AsyncResult<Void>> completionHandler = onSuccess(v -> complete()); req.response().sendFile(fileToSend.getAbsolutePath(), completionHandler); } else { req.response().sendFile(fileToSend.getAbsolutePath()); complete(); } }); startServer(); requestFact.apply(onSuccess(resp -> { assertEquals(200, resp.statusCode()); assertEquals("text/html", resp.headers().get("Content-Type")); resp.exceptionHandler(this::fail); resp.bodyHandler(buff -> { assertEquals(contentExpected, buff.toString()); assertEquals(fileToSend.length(), Long.parseLong(resp.headers().get("content-length"))); complete(); }); })).end(); await(); }
@Test public void testSendFileOverrideHeaders() throws Exception { String content = TestUtils.randomUnicodeString(10000); File file = setupFile("test-send-file.html", content); server.requestHandler(req -> { req.response().putHeader("Content-Type", "wibble"); req.response().sendFile(file.getAbsolutePath()); }); server.listen(onSuccess(s -> { client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, DEFAULT_TEST_URI, onSuccess(resp -> { assertEquals(file.length(), Long.parseLong(resp.headers().get("content-length"))); assertEquals("wibble", resp.headers().get("content-type")); resp.bodyHandler(buff -> { assertEquals(content, buff.toString()); file.delete(); testComplete(); }); })).end(); })); await(); }
private void checkHttpServerResponse(HttpServerResponse resp) { Buffer buff = Buffer.buffer(); assertIllegalStateException(() -> resp.drainHandler(noOpHandler())); assertIllegalStateException(() -> resp.end()); assertIllegalStateException(() -> resp.end("foo")); assertIllegalStateException(() -> resp.end(buff)); assertIllegalStateException(() -> resp.end("foo", "UTF-8")); assertIllegalStateException(() -> resp.exceptionHandler(noOpHandler())); assertIllegalStateException(() -> resp.setChunked(false)); assertIllegalStateException(() -> resp.setWriteQueueMaxSize(123)); assertIllegalStateException(() -> resp.write(buff)); assertIllegalStateException(() -> resp.write("foo")); assertIllegalStateException(() -> resp.write("foo", "UTF-8")); assertIllegalStateException(() -> resp.write(buff)); assertIllegalStateException(() -> resp.writeQueueFull()); assertIllegalStateException(() -> resp.sendFile("asokdasokd")); }
@Test public void testResponseEndHandlersSendFile() throws Exception { waitFor(2); AtomicInteger cnt = new AtomicInteger(); String content = "iqdioqwdqwiojqwijdwqd"; File toSend = setupFile("somefile.txt", content); server.requestHandler(req -> { req.response().headersEndHandler(v -> { // Insert another header req.response().putHeader("extraheader", "wibble"); assertEquals(0, cnt.getAndIncrement()); }); req.response().bodyEndHandler(v -> { assertEquals(content.length(), req.response().bytesWritten()); assertEquals(1, cnt.getAndIncrement()); complete(); }); req.response().sendFile(toSend.getAbsolutePath()); }).listen(onSuccess(server -> { client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/", onSuccess(res -> { assertEquals(200, res.statusCode()); assertEquals("wibble", res.headers().get("extraheader")); res.bodyHandler(buff -> { assertEquals(Buffer.buffer(content), buff); complete(); }); })).end(); })); await(); }
.requestHandler( req -> { req.response().sendFile(sent.getAbsolutePath()); }); startServer();
@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(); } }