public static Future<LocalFile> readFile(FileSystem fs, String filefullPathName) { LocalFile localFile = new LocalFile(); return Future.<FileProps>future(future -> { fs.props(filefullPathName, future); }).compose(props -> { localFile.setSize(props.size()); return Future.<AsyncFile>future(future -> { fs.open(filefullPathName, new OpenOptions().setRead(true).setWrite(false).setCreate(false), future); }); }).compose(fileStream -> { localFile.setFile(fileStream); return Future.succeededFuture(localFile); }); }
void ls(Vertx vertx, String currentFile, String pathArg, Handler<AsyncResult<Map<String, FileProps>>> filesHandler) { Path base = currentFile != null ? new File(currentFile).toPath() : rootDir; String path = base.resolve(pathArg).toAbsolutePath().normalize().toString(); vertx.executeBlocking(fut -> { FileSystem fs = vertx.fileSystem(); if (fs.propsBlocking(path).isDirectory()) { LinkedHashMap<String, FileProps> result = new LinkedHashMap<>(); for (String file : fs.readDirBlocking(path)) { result.put(file, fs.propsBlocking(file)); } fut.complete(result); } else { throw new RuntimeException(path + ": No such file or directory"); } }, filesHandler); }
@org.junit.Test public void testReportToFile() { FileSystem fs = vertx.fileSystem(); String file = "target"; assertTrue(fs.existsBlocking(file)); assertTrue(fs.propsBlocking(file).isDirectory()); suite.run(vertx, new TestOptions().addReporter(new ReportOptions().setTo("file:" + file))); String path = file + File.separator + "my_suite.txt"; assertTrue(fs.existsBlocking(path)); int count = 1000; while (true) { FileProps props = fs.propsBlocking(path); if (props.isRegularFile() && props.size() > 0) { break; } else { if (count-- > 0) { try { Thread.sleep(1); } catch (InterruptedException ignore) { } } else { fail(); } } } }
/** * Create all required header so content can be cache by Caching servers or Browsers * * @param request base HttpServerRequest * @param props file properties */ private void writeCacheHeaders(HttpServerRequest request, FileProps props) { MultiMap headers = request.response().headers(); if (cachingEnabled) { // We use cache-control and last-modified // We *do not use* etags and expires (since they do the same thing - redundant) headers.set("cache-control", "public, max-age=" + maxAgeSeconds); headers.set("last-modified", dateTimeFormatter.format(props.lastModifiedTime())); // We send the vary header (for intermediate caches) // (assumes that most will turn on compression when using static handler) if (sendVaryHeader && request.headers().contains("accept-encoding")) { headers.set("vary", "accept-encoding"); } } // date header is mandatory headers.set("date", dateTimeFormatter.format(new Date())); }
@Override public void getOne(String path, Handler<AsyncResult<ChunkReadStream>> handler) { String absolutePath = Paths.get(root, path).toString(); // check if chunk exists FileSystem fs = vertx.fileSystem(); ObservableFuture<Boolean> observable = RxHelper.observableFuture(); fs.exists(absolutePath, observable.toHandler()); observable .flatMap(exists -> { if (!exists) { return Observable.error(new FileNotFoundException("Could not find chunk: " + path)); } return Observable.just(exists); }) .flatMap(exists -> { // get chunk's size ObservableFuture<FileProps> propsObservable = RxHelper.observableFuture(); fs.props(absolutePath, propsObservable.toHandler()); return propsObservable; }) .map(props -> props.size()) .flatMap(size -> { // open chunk ObservableFuture<AsyncFile> openObservable = RxHelper.observableFuture(); OpenOptions openOptions = new OpenOptions().setCreate(false).setWrite(false); fs.open(absolutePath, openOptions, openObservable.toHandler()); return openObservable.map(f -> new FileChunkReadStream(size, f)); }) .subscribe(readStream -> { // send chunk to peer handler.handle(Future.succeededFuture(readStream)); }, err -> { handler.handle(Future.failedFuture(err)); }); }
private PropReadFileStream(FileProps props, AsyncFile file, String path) { this.props = props; this.file = file; this.path = path; }
void complete(Vertx vertx, String currentPath, String _prefix, Handler<AsyncResult<Map<String, Boolean>>> handler) { vertx.executeBlocking(fut -> { FileSystem fs = vertx.fileSystem(); Path base = (currentPath != null ? new File(currentPath).toPath() : rootDir); int index = _prefix.lastIndexOf('/'); String prefix; if (index == 0) { handler.handle(Future.failedFuture("todo")); return; } else if (index > 0) { base = base.resolve(_prefix.substring(0, index)); prefix = _prefix.substring(index + 1); } else { prefix = _prefix; } LinkedHashMap<String, Boolean> matches = new LinkedHashMap<>(); for (String path : fs.readDirBlocking(base.toAbsolutePath().normalize().toString())) { String name = path.substring(path.lastIndexOf('/') + 1); if (name.startsWith(prefix)) { FileProps props = fs.propsBlocking(path); matches.put(name.substring(prefix.length()) + (props.isDirectory() ? "/" : ""), props.isRegularFile()); } } if (matches.size() > 1) { String common = Completion.findLongestCommonPrefix(matches.keySet()); if (common.length() > 0) { matches.clear(); matches.put(common, false); } else { LinkedHashMap<String, Boolean> tmp = new LinkedHashMap<>(); matches.forEach((suffix, terminal) -> { tmp.put(prefix + suffix, terminal); }); matches = tmp; } } fut.complete(matches); }, handler); }
private void sendStatic(RoutingContext context, String path) { String file = null; if (!includeHidden) { file = getFile(path, context); int idx = file.lastIndexOf('/'); String name = file.substring(idx + 1); if (name.length() > 0 && name.charAt(0) == '.') { // skip context.next(); return; } } // Look in cache CacheEntry entry; if (cachingEnabled) { entry = propsCache().get(path); if (entry != null) { HttpServerRequest request = context.request(); if ((filesReadOnly || !entry.isOutOfDate()) && entry.shouldUseCached(request)) { context.response().setStatusCode(NOT_MODIFIED.code()).end(); return; } } } if (file == null) { file = getFile(path, context); } final String sfile = file; // verify if the file exists isFileExisting(context, sfile, exists -> { if (exists.failed()) { context.fail(exists.cause()); return; } // file does not exist, continue... if (!exists.result()) { context.next(); return; } // Need to read the props from the filesystem getFileProps(context, sfile, res -> { if (res.succeeded()) { FileProps fprops = res.result(); if (fprops == null) { // File does not exist context.next(); } else if (fprops.isDirectory()) { sendDirectory(context, path, sfile); } else { propsCache().put(path, new CacheEntry(fprops, System.currentTimeMillis())); sendFile(context, sfile, fprops); } } else { context.fail(res.cause()); } }); }); }
private CacheEntry(FileProps props, long createDate) { this.props = props; this.createDate = createDate; }
/** * Gets the filesystem props * * @return */ public FileProps getProps() { return props; }