Search in sources :

Example 1 with ForbiddenException

use of com.blade.exception.ForbiddenException in project blade by biezhi.

the class StaticFileHandler method handle.

/**
 * print static file to client
 *
 * @param webContext web context
 * @throws Exception
 */
@Override
public void handle(WebContext webContext) throws Exception {
    Request request = webContext.getRequest();
    ChannelHandlerContext ctx = webContext.getChannelHandlerContext();
    if (!HttpConst.METHOD_GET.equals(request.method())) {
        sendError(ctx, METHOD_NOT_ALLOWED);
        return;
    }
    Instant start = Instant.now();
    String uri = URLDecoder.decode(request.uri(), "UTF-8");
    String method = StringKit.padRight(request.method(), 6);
    String cleanURL = getCleanURL(request, uri);
    // webjars
    if (cleanURL.startsWith(Const.WEB_JARS)) {
        InputStream input = getResourceStreamFromJar(uri);
        writeWithJarFile(request, ctx, uri, start, cleanURL, method, input);
        return;
    }
    // jar file
    if (BladeKit.runtimeIsJAR()) {
        InputStream input = StaticFileHandler.class.getResourceAsStream(cleanURL);
        writeWithJarFile(request, ctx, uri, start, cleanURL, method, input);
        return;
    }
    // disk file
    final String path = sanitizeUri(cleanURL);
    if (path == null) {
        log403(log, method, uri);
        throw new ForbiddenException();
    }
    File file = new File(path);
    if (file.isHidden() || !file.exists()) {
        // gradle resources path
        File resourcesDirectory = getGradleResourcesDirectory();
        if (resourcesDirectory.isDirectory()) {
            file = new File(resourcesDirectory.getPath() + "/" + cleanURL.substring(1));
            if (file.isHidden() || !file.exists()) {
                throw new NotFoundException(uri);
            }
        } else {
            throw new NotFoundException(uri);
        }
    }
    if (file.isDirectory() && showFileList) {
        sendListing(ctx, uri, getFileMetas(file), cleanURL);
        return;
    }
    if (!file.isFile()) {
        sendError(ctx, FORBIDDEN);
        return;
    }
    // Cache Validation
    if (isHttp304(ctx, request, file.length(), file.lastModified())) {
        log304(log, method, uri);
        return;
    }
    HttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
    setContentTypeHeader(httpResponse, file);
    setDateAndCacheHeaders(httpResponse, file);
    if (request.useGZIP()) {
        File output = new File(file.getPath() + ".gz");
        IOKit.compressGZIP(file, output);
        file = output;
        setGzip(httpResponse);
    }
    RandomAccessFile raf;
    try {
        raf = new RandomAccessFile(file, "r");
    } catch (FileNotFoundException ignore) {
        sendError(ctx, NOT_FOUND);
        return;
    }
    long fileLength = raf.length();
    httpResponse.headers().set(HttpConst.CONTENT_LENGTH, fileLength);
    if (request.keepAlive()) {
        httpResponse.headers().set(HttpConst.CONNECTION, HttpConst.KEEP_ALIVE);
    }
    // Write the initial line and the header.
    ctx.write(httpResponse);
    // Write the content.
    ChannelFuture sendFileFuture;
    ChannelFuture lastContentFuture;
    if (ctx.pipeline().get(SslHandler.class) == null) {
        sendFileFuture = ctx.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise());
        // Write the end marker.
        lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
    } else {
        sendFileFuture = ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)), ctx.newProgressivePromise());
        // HttpChunkedInput will write the end marker (LastHttpContent) for us.
        lastContentFuture = sendFileFuture;
    }
    sendFileFuture.addListener(ProgressiveFutureListener.build(raf));
    // Decide whether to close the connection or not.
    if (!request.keepAlive()) {
        lastContentFuture.addListener(ChannelFutureListener.CLOSE);
    }
    log200AndCost(log, start, method, uri);
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ForbiddenException(com.blade.exception.ForbiddenException) Instant(java.time.Instant) ChunkedFile(io.netty.handler.stream.ChunkedFile) Request(com.blade.mvc.http.Request) NotFoundException(com.blade.exception.NotFoundException) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) DefaultFileRegion(io.netty.channel.DefaultFileRegion) SslHandler(io.netty.handler.ssl.SslHandler) ChunkedFile(io.netty.handler.stream.ChunkedFile) JarFile(java.util.jar.JarFile)

Aggregations

ForbiddenException (com.blade.exception.ForbiddenException)1 NotFoundException (com.blade.exception.NotFoundException)1 Request (com.blade.mvc.http.Request)1 ChannelFuture (io.netty.channel.ChannelFuture)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 DefaultFileRegion (io.netty.channel.DefaultFileRegion)1 SslHandler (io.netty.handler.ssl.SslHandler)1 ChunkedFile (io.netty.handler.stream.ChunkedFile)1 Instant (java.time.Instant)1 JarFile (java.util.jar.JarFile)1