use of io.vertx.core.file.FileProps in project vertx-web by vert-x3.
the class StaticHandlerImpl method sendStatic.
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());
}
});
});
}
use of io.vertx.core.file.FileProps in project vertx-web by vert-x3.
the class StaticHandlerImpl method getFileProps.
private synchronized void getFileProps(RoutingContext context, String file, Handler<AsyncResult<FileProps>> resultHandler) {
FileSystem fs = context.vertx().fileSystem();
if (alwaysAsyncFS || useAsyncFS) {
wrapInTCCLSwitch(() -> fs.props(file, resultHandler));
} else {
// Use synchronous access - it might well be faster!
long start = 0;
if (tuning) {
start = System.nanoTime();
}
try {
FileProps props = wrapInTCCLSwitch(() -> fs.propsBlocking(file));
if (tuning) {
long end = System.nanoTime();
long dur = end - start;
totalTime += dur;
numServesBlocking++;
if (numServesBlocking == Long.MAX_VALUE) {
// Unlikely.. but...
resetTuning();
} else if (numServesBlocking == nextAvgCheck) {
double avg = (double) totalTime / numServesBlocking;
if (avg > maxAvgServeTimeNanoSeconds) {
useAsyncFS = true;
log.info("Switching to async file system access in static file server as fs access is slow! (Average access time of " + avg + " ns)");
tuning = false;
}
nextAvgCheck += NUM_SERVES_TUNING_FS_ACCESS;
}
}
resultHandler.handle(Future.succeededFuture(props));
} catch (RuntimeException e) {
resultHandler.handle(Future.failedFuture(e.getCause()));
}
}
}
use of io.vertx.core.file.FileProps in project vertx-web by vert-x3.
the class StaticHandlerImpl method sendFile.
private void sendFile(RoutingContext context, String file, FileProps fileProps) {
HttpServerRequest request = context.request();
Long offset = null;
Long end = null;
MultiMap headers = null;
if (rangeSupport) {
// check if the client is making a range request
String range = request.getHeader("Range");
// end byte is length - 1
end = fileProps.size() - 1;
if (range != null) {
Matcher m = RANGE.matcher(range);
if (m.matches()) {
try {
String part = m.group(1);
// offset cannot be empty
offset = Long.parseLong(part);
// offset must fall inside the limits of the file
if (offset < 0 || offset >= fileProps.size()) {
throw new IndexOutOfBoundsException();
}
// length can be empty
part = m.group(2);
if (part != null && part.length() > 0) {
// ranges are inclusive
end = Math.min(end, Long.parseLong(part));
// end offset must not be smaller than start offset
if (end < offset) {
throw new IndexOutOfBoundsException();
}
}
} catch (NumberFormatException | IndexOutOfBoundsException e) {
context.response().putHeader("Content-Range", "bytes */" + fileProps.size());
context.fail(REQUESTED_RANGE_NOT_SATISFIABLE.code());
return;
}
}
}
// notify client we support range requests
headers = request.response().headers();
headers.set("Accept-Ranges", "bytes");
// send the content length even for HEAD requests
headers.set("Content-Length", Long.toString(end + 1 - (offset == null ? 0 : offset)));
}
writeCacheHeaders(request, fileProps);
if (request.method() == HttpMethod.HEAD) {
request.response().end();
} else {
if (rangeSupport && offset != null) {
// must return content range
headers.set("Content-Range", "bytes " + offset + "-" + end + "/" + fileProps.size());
// return a partial response
request.response().setStatusCode(PARTIAL_CONTENT.code());
// Wrap the sendFile operation into a TCCL switch, so the file resolver would find the file from the set
// classloader (if any).
final Long finalOffset = offset;
final Long finalEnd = end;
wrapInTCCLSwitch(() -> {
// guess content type
String contentType = MimeMapping.getMimeTypeForFilename(file);
if (contentType != null) {
if (contentType.startsWith("text")) {
request.response().putHeader("Content-Type", contentType + ";charset=" + defaultContentEncoding);
} else {
request.response().putHeader("Content-Type", contentType);
}
}
return request.response().sendFile(file, finalOffset, finalEnd + 1, res2 -> {
if (res2.failed()) {
context.fail(res2.cause());
}
});
});
} else {
// Wrap the sendFile operation into a TCCL switch, so the file resolver would find the file from the set
// classloader (if any).
wrapInTCCLSwitch(() -> {
// guess content type
String contentType = MimeMapping.getMimeTypeForFilename(file);
if (contentType != null) {
if (contentType.startsWith("text")) {
request.response().putHeader("Content-Type", contentType + ";charset=" + defaultContentEncoding);
} else {
request.response().putHeader("Content-Type", contentType);
}
}
// http2 pushing support
if (request.version() == HttpVersion.HTTP_2 && http2PushMappings != null) {
for (Http2PushMapping dependency : http2PushMappings) {
if (!dependency.isNoPush()) {
final String dep = webRoot + "/" + dependency.getFilePath();
HttpServerResponse response = request.response();
// get the file props
getFileProps(context, dep, filePropsAsyncResult -> {
if (filePropsAsyncResult.succeeded()) {
// push
writeCacheHeaders(request, filePropsAsyncResult.result());
response.push(HttpMethod.GET, "/" + dependency.getFilePath(), pushAsyncResult -> {
if (pushAsyncResult.succeeded()) {
HttpServerResponse res = pushAsyncResult.result();
final String depContentType = MimeMapping.getMimeTypeForExtension(file);
if (depContentType != null) {
if (depContentType.startsWith("text")) {
res.putHeader("Content-Type", contentType + ";charset=" + defaultContentEncoding);
} else {
res.putHeader("Content-Type", contentType);
}
}
res.sendFile(webRoot + "/" + dependency.getFilePath());
}
});
}
});
}
}
} else if (http2PushMappings != null) {
// Link preload when file push is not supported
HttpServerResponse response = request.response();
List<String> links = new ArrayList<>();
for (Http2PushMapping dependency : http2PushMappings) {
final String dep = webRoot + "/" + dependency.getFilePath();
// get the file props
getFileProps(context, dep, filePropsAsyncResult -> {
if (filePropsAsyncResult.succeeded()) {
// push
writeCacheHeaders(request, filePropsAsyncResult.result());
links.add("<" + dependency.getFilePath() + ">; rel=preload; as=" + dependency.getExtensionTarget() + (dependency.isNoPush() ? "; nopush" : ""));
}
});
}
response.putHeader("Link", links);
}
return request.response().sendFile(file, res2 -> {
if (res2.failed()) {
context.fail(res2.cause());
}
});
});
}
}
}
use of io.vertx.core.file.FileProps in project vert.x by eclipse.
the class CoreExamples method exampleFuture2.
public void exampleFuture2(Vertx vertx, Handler<HttpServerRequest> requestHandler) {
FileSystem fs = vertx.fileSystem();
Future<FileProps> future = fs.props("/my_file.txt");
future.onComplete((AsyncResult<FileProps> ar) -> {
if (ar.succeeded()) {
FileProps props = ar.result();
System.out.println("File size = " + props.size());
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
}
use of io.vertx.core.file.FileProps in project vertx-examples by vert-x3.
the class Client method start.
@Override
public void start() throws Exception {
HttpClientRequest req = vertx.createHttpClient(new HttpClientOptions()).put(8080, "localhost", "/someurl", resp -> {
System.out.println("Response " + resp.statusCode());
});
String filename = "upload.txt";
FileSystem fs = vertx.fileSystem();
fs.props(filename, ares -> {
FileProps props = ares.result();
System.out.println("props is " + props);
long size = props.size();
req.headers().set("content-length", "" + size);
fs.open(filename, new OpenOptions(), ares2 -> {
AsyncFile file = ares2.result();
Pump pump = Pump.pump(file, req);
file.endHandler(v -> {
req.end();
});
pump.start();
});
});
}
Aggregations