Search in sources :

Example 1 with FileProps

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());
            }
        });
    });
}
Also used : HttpServerRequest(io.vertx.core.http.HttpServerRequest) FileProps(io.vertx.core.file.FileProps)

Example 2 with FileProps

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()));
        }
    }
}
Also used : FileSystem(io.vertx.core.file.FileSystem) FileProps(io.vertx.core.file.FileProps)

Example 3 with FileProps

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());
                    }
                });
            });
        }
    }
}
Also used : HttpServerRequest(io.vertx.core.http.HttpServerRequest) java.util(java.util) io.vertx.core(io.vertx.core) Callable(java.util.concurrent.Callable) RoutingContext(io.vertx.ext.web.RoutingContext) LoggerFactory(io.vertx.core.logging.LoggerFactory) FileProps(io.vertx.core.file.FileProps) Utils(io.vertx.ext.web.impl.Utils) Matcher(java.util.regex.Matcher) Charset(java.nio.charset.Charset) HttpVersion(io.vertx.core.http.HttpVersion) Logger(io.vertx.core.logging.Logger) ParseException(java.text.ParseException) DateFormat(java.text.DateFormat) LRUCache(io.vertx.ext.web.impl.LRUCache) StaticHandler(io.vertx.ext.web.handler.StaticHandler) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) MimeMapping(io.vertx.core.http.impl.MimeMapping) File(java.io.File) JsonArray(io.vertx.core.json.JsonArray) Http2PushMapping(io.vertx.ext.web.Http2PushMapping) HttpMethod(io.vertx.core.http.HttpMethod) HttpServerResponse(io.vertx.core.http.HttpServerResponse) FileSystem(io.vertx.core.file.FileSystem) Pattern(java.util.regex.Pattern) Matcher(java.util.regex.Matcher) HttpServerRequest(io.vertx.core.http.HttpServerRequest) Http2PushMapping(io.vertx.ext.web.Http2PushMapping) HttpServerResponse(io.vertx.core.http.HttpServerResponse)

Example 4 with FileProps

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());
        }
    });
}
Also used : FileSystem(io.vertx.core.file.FileSystem) FileProps(io.vertx.core.file.FileProps)

Example 5 with FileProps

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();
        });
    });
}
Also used : OpenOptions(io.vertx.core.file.OpenOptions) HttpClientRequest(io.vertx.core.http.HttpClientRequest) FileSystem(io.vertx.core.file.FileSystem) AsyncFile(io.vertx.core.file.AsyncFile) FileProps(io.vertx.core.file.FileProps) HttpClientOptions(io.vertx.core.http.HttpClientOptions) Pump(io.vertx.core.streams.Pump)

Aggregations

FileProps (io.vertx.core.file.FileProps)8 FileSystem (io.vertx.core.file.FileSystem)7 OpenOptions (io.vertx.core.file.OpenOptions)3 Buffer (io.vertx.core.buffer.Buffer)2 AsyncFile (io.vertx.core.file.AsyncFile)2 HttpServerRequest (io.vertx.core.http.HttpServerRequest)2 Preconditions (com.google.common.base.Preconditions)1 ConfigConstants (io.georocket.constants.ConfigConstants)1 ChunkReadStream (io.georocket.storage.ChunkReadStream)1 IndexedStore (io.georocket.storage.indexed.IndexedStore)1 PathUtils (io.georocket.util.PathUtils)1 HttpResponseStatus (io.netty.handler.codec.http.HttpResponseStatus)1 io.vertx.core (io.vertx.core)1 AsyncResult (io.vertx.core.AsyncResult)1 Future (io.vertx.core.Future)1 Handler (io.vertx.core.Handler)1 Vertx (io.vertx.core.Vertx)1 HttpClientOptions (io.vertx.core.http.HttpClientOptions)1 HttpClientRequest (io.vertx.core.http.HttpClientRequest)1 HttpMethod (io.vertx.core.http.HttpMethod)1