Search in sources :

Example 1 with OK

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponseStatus.OK in project flink by apache.

the class HistoryServerStaticFileServerHandler method respondWithFile.

/**
 * Response when running with leading JobManager.
 */
private void respondWithFile(ChannelHandlerContext ctx, HttpRequest request, String requestPath) throws IOException, ParseException, RestHandlerException {
    // make sure we request the "index.html" in case there is a directory request
    if (requestPath.endsWith("/")) {
        requestPath = requestPath + "index.html";
    }
    if (!requestPath.contains(".")) {
        // we assume that the path ends in either .html or .js
        requestPath = requestPath + ".json";
    }
    // convert to absolute path
    final File file = new File(rootPath, requestPath);
    if (!file.exists()) {
        // file does not exist. Try to load it with the classloader
        ClassLoader cl = HistoryServerStaticFileServerHandler.class.getClassLoader();
        try (InputStream resourceStream = cl.getResourceAsStream("web" + requestPath)) {
            boolean success = false;
            try {
                if (resourceStream != null) {
                    URL root = cl.getResource("web");
                    URL requested = cl.getResource("web" + requestPath);
                    if (root != null && requested != null) {
                        URI rootURI = new URI(root.getPath()).normalize();
                        URI requestedURI = new URI(requested.getPath()).normalize();
                        // expected scope.
                        if (!rootURI.relativize(requestedURI).equals(requestedURI)) {
                            LOG.debug("Loading missing file from classloader: {}", requestPath);
                            // ensure that directory to file exists.
                            file.getParentFile().mkdirs();
                            Files.copy(resourceStream, file.toPath());
                            success = true;
                        }
                    }
                }
            } catch (Throwable t) {
                LOG.error("error while responding", t);
            } finally {
                if (!success) {
                    LOG.debug("Unable to load requested file {} from classloader", requestPath);
                    throw new NotFoundException("File not found.");
                }
            }
        }
    }
    StaticFileServerHandler.checkFileValidity(file, rootPath, LOG);
    // cache validation
    final String ifModifiedSince = request.headers().get(IF_MODIFIED_SINCE);
    if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) {
        SimpleDateFormat dateFormatter = new SimpleDateFormat(StaticFileServerHandler.HTTP_DATE_FORMAT, Locale.US);
        Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince);
        // Only compare up to the second because the datetime format we send to the client
        // does not have milliseconds
        long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000;
        long fileLastModifiedSeconds = file.lastModified() / 1000;
        if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Responding 'NOT MODIFIED' for file '" + file.getAbsolutePath() + '\'');
            }
            StaticFileServerHandler.sendNotModified(ctx);
            return;
        }
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("Responding with file '" + file.getAbsolutePath() + '\'');
    }
    // Don't need to close this manually. Netty's DefaultFileRegion will take care of it.
    final RandomAccessFile raf;
    try {
        raf = new RandomAccessFile(file, "r");
    } catch (FileNotFoundException e) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Could not find file {}.", file.getAbsolutePath());
        }
        HandlerUtils.sendErrorResponse(ctx, request, new ErrorResponseBody("File not found."), NOT_FOUND, Collections.emptyMap());
        return;
    }
    try {
        long fileLength = raf.length();
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
        StaticFileServerHandler.setContentTypeHeader(response, file);
        // the job overview should be updated as soon as possible
        if (!requestPath.equals("/joboverview.json")) {
            StaticFileServerHandler.setDateAndCacheHeaders(response, file);
        }
        if (HttpHeaders.isKeepAlive(request)) {
            response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
        }
        HttpHeaders.setContentLength(response, fileLength);
        // write the initial line and the header.
        ctx.write(response);
        // write the content.
        ChannelFuture lastContentFuture;
        if (ctx.pipeline().get(SslHandler.class) == null) {
            ctx.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise());
            lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
        } else {
            lastContentFuture = ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)), ctx.newProgressivePromise());
        // HttpChunkedInput will write the end marker (LastHttpContent) for us.
        }
        // close the connection, if no keep-alive is needed
        if (!HttpHeaders.isKeepAlive(request)) {
            lastContentFuture.addListener(ChannelFutureListener.CLOSE);
        }
    } catch (Exception e) {
        raf.close();
        LOG.error("Failed to serve file.", e);
        throw new RestHandlerException("Internal server error.", INTERNAL_SERVER_ERROR);
    }
}
Also used : ChannelFuture(org.apache.flink.shaded.netty4.io.netty.channel.ChannelFuture) InputStream(java.io.InputStream) ChunkedFile(org.apache.flink.shaded.netty4.io.netty.handler.stream.ChunkedFile) FileNotFoundException(java.io.FileNotFoundException) NotFoundException(org.apache.flink.runtime.rest.NotFoundException) FileNotFoundException(java.io.FileNotFoundException) ErrorResponseBody(org.apache.flink.runtime.rest.messages.ErrorResponseBody) DefaultHttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponse) DefaultFileRegion(org.apache.flink.shaded.netty4.io.netty.channel.DefaultFileRegion) URI(java.net.URI) URL(java.net.URL) Date(java.util.Date) SslHandler(org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslHandler) NotFoundException(org.apache.flink.runtime.rest.NotFoundException) ParseException(java.text.ParseException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) RestHandlerException(org.apache.flink.runtime.rest.handler.RestHandlerException) RestHandlerException(org.apache.flink.runtime.rest.handler.RestHandlerException) HttpChunkedInput(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpChunkedInput) RandomAccessFile(java.io.RandomAccessFile) DefaultHttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultHttpResponse) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) ChunkedFile(org.apache.flink.shaded.netty4.io.netty.handler.stream.ChunkedFile) SimpleDateFormat(java.text.SimpleDateFormat)

Example 2 with OK

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponseStatus.OK in project flink by apache.

the class StaticFileServerHandler method respondToRequest.

/**
 * Response when running with leading JobManager.
 */
private void respondToRequest(ChannelHandlerContext ctx, HttpRequest request, String requestPath) throws IOException, ParseException, URISyntaxException, RestHandlerException {
    // convert to absolute path
    final File file = new File(rootPath, requestPath);
    if (!file.exists()) {
        // file does not exist. Try to load it with the classloader
        ClassLoader cl = StaticFileServerHandler.class.getClassLoader();
        try (InputStream resourceStream = cl.getResourceAsStream("web" + requestPath)) {
            boolean success = false;
            try {
                if (resourceStream != null) {
                    URL root = cl.getResource("web");
                    URL requested = cl.getResource("web" + requestPath);
                    if (root != null && requested != null) {
                        URI rootURI = new URI(root.getPath()).normalize();
                        URI requestedURI = new URI(requested.getPath()).normalize();
                        // expected scope.
                        if (!rootURI.relativize(requestedURI).equals(requestedURI)) {
                            logger.debug("Loading missing file from classloader: {}", requestPath);
                            // ensure that directory to file exists.
                            file.getParentFile().mkdirs();
                            Files.copy(resourceStream, file.toPath());
                            success = true;
                        }
                    }
                }
            } catch (Throwable t) {
                logger.error("error while responding", t);
            } finally {
                if (!success) {
                    logger.debug("Unable to load requested file {} from classloader", requestPath);
                    throw new NotFoundException(String.format("Unable to load requested file %s.", requestPath));
                }
            }
        }
    }
    checkFileValidity(file, rootPath, logger);
    // cache validation
    final String ifModifiedSince = request.headers().get(IF_MODIFIED_SINCE);
    if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) {
        SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US);
        Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince);
        // Only compare up to the second because the datetime format we send to the client
        // does not have milliseconds
        long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000;
        long fileLastModifiedSeconds = file.lastModified() / 1000;
        if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) {
            if (logger.isDebugEnabled()) {
                logger.debug("Responding 'NOT MODIFIED' for file '" + file.getAbsolutePath() + '\'');
            }
            sendNotModified(ctx);
            return;
        }
    }
    if (logger.isDebugEnabled()) {
        logger.debug("Responding with file '" + file.getAbsolutePath() + '\'');
    }
    // Don't need to close this manually. Netty's DefaultFileRegion will take care of it.
    final RandomAccessFile raf;
    try {
        raf = new RandomAccessFile(file, "r");
    } catch (FileNotFoundException e) {
        if (logger.isDebugEnabled()) {
            logger.debug("Could not find file {}.", file.getAbsolutePath());
        }
        throw new NotFoundException("File not found.");
    }
    try {
        long fileLength = raf.length();
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
        setContentTypeHeader(response, file);
        setDateAndCacheHeaders(response, file);
        if (HttpHeaders.isKeepAlive(request)) {
            response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
        }
        HttpHeaders.setContentLength(response, fileLength);
        // write the initial line and the header.
        ctx.write(response);
        // write the content.
        ChannelFuture lastContentFuture;
        if (ctx.pipeline().get(SslHandler.class) == null) {
            ctx.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise());
            lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
        } else {
            lastContentFuture = ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)), ctx.newProgressivePromise());
        // HttpChunkedInput will write the end marker (LastHttpContent) for us.
        }
        // close the connection, if no keep-alive is needed
        if (!HttpHeaders.isKeepAlive(request)) {
            lastContentFuture.addListener(ChannelFutureListener.CLOSE);
        }
    } catch (Exception e) {
        raf.close();
        logger.error("Failed to serve file.", e);
        throw new RestHandlerException("Internal server error.", INTERNAL_SERVER_ERROR);
    }
}
Also used : ChannelFuture(org.apache.flink.shaded.netty4.io.netty.channel.ChannelFuture) InputStream(java.io.InputStream) ChunkedFile(org.apache.flink.shaded.netty4.io.netty.handler.stream.ChunkedFile) FileNotFoundException(java.io.FileNotFoundException) NotFoundException(org.apache.flink.runtime.rest.NotFoundException) FileNotFoundException(java.io.FileNotFoundException) FullHttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.FullHttpResponse) HttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponse) DefaultHttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultHttpResponse) DefaultFullHttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultFullHttpResponse) DefaultFileRegion(org.apache.flink.shaded.netty4.io.netty.channel.DefaultFileRegion) URI(java.net.URI) URL(java.net.URL) Date(java.util.Date) SslHandler(org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslHandler) URISyntaxException(java.net.URISyntaxException) NotFoundException(org.apache.flink.runtime.rest.NotFoundException) ParseException(java.text.ParseException) FileNotFoundException(java.io.FileNotFoundException) RestHandlerException(org.apache.flink.runtime.rest.handler.RestHandlerException) IOException(java.io.IOException) RestHandlerException(org.apache.flink.runtime.rest.handler.RestHandlerException) HttpChunkedInput(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpChunkedInput) RandomAccessFile(java.io.RandomAccessFile) DefaultHttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultHttpResponse) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) ChunkedFile(org.apache.flink.shaded.netty4.io.netty.handler.stream.ChunkedFile) SimpleDateFormat(java.text.SimpleDateFormat)

Example 3 with OK

use of org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponseStatus.OK in project flink by apache.

the class HandlerUtils method transferFile.

public static void transferFile(ChannelHandlerContext ctx, File file, HttpRequest httpRequest) throws FlinkException {
    final RandomAccessFile randomAccessFile;
    try {
        randomAccessFile = new RandomAccessFile(file, "r");
    } catch (FileNotFoundException e) {
        throw new FlinkException("Can not find file " + file + ".", e);
    }
    try {
        final long fileLength = randomAccessFile.length();
        final FileChannel fileChannel = randomAccessFile.getChannel();
        try {
            HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
            response.headers().set(CONTENT_TYPE, "text/plain");
            if (HttpHeaders.isKeepAlive(httpRequest)) {
                response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
            }
            HttpHeaders.setContentLength(response, fileLength);
            // write the initial line and the header.
            ctx.write(response);
            // write the content.
            final ChannelFuture lastContentFuture;
            final GenericFutureListener<Future<? super Void>> completionListener = future -> {
                fileChannel.close();
                randomAccessFile.close();
            };
            if (ctx.pipeline().get(SslHandler.class) == null) {
                ctx.write(new DefaultFileRegion(fileChannel, 0, fileLength), ctx.newProgressivePromise()).addListener(completionListener);
                lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
            } else {
                lastContentFuture = ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(randomAccessFile, 0, fileLength, 8192)), ctx.newProgressivePromise()).addListener(completionListener);
            // HttpChunkedInput will write the end marker (LastHttpContent) for us.
            }
            // close the connection, if no keep-alive is needed
            if (!HttpHeaders.isKeepAlive(httpRequest)) {
                lastContentFuture.addListener(ChannelFutureListener.CLOSE);
            }
        } catch (IOException ex) {
            fileChannel.close();
            throw ex;
        }
    } catch (IOException ioe) {
        try {
            randomAccessFile.close();
        } catch (IOException e) {
            throw new FlinkException("Close file or channel error.", e);
        }
        throw new FlinkException("Could not transfer file " + file + " to the client.", ioe);
    }
}
Also used : ChannelFuture(org.apache.flink.shaded.netty4.io.netty.channel.ChannelFuture) RestMapperUtils(org.apache.flink.runtime.rest.util.RestMapperUtils) FlinkException(org.apache.flink.util.FlinkException) RandomAccessFile(java.io.RandomAccessFile) ChannelFutureListener(org.apache.flink.shaded.netty4.io.netty.channel.ChannelFutureListener) OK(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponseStatus.OK) LastHttpContent(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.LastHttpContent) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) Future(org.apache.flink.shaded.netty4.io.netty.util.concurrent.Future) HTTP_1_1(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpVersion.HTTP_1_1) DefaultHttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultHttpResponse) HttpResponseStatus(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponseStatus) DefaultFileRegion(org.apache.flink.shaded.netty4.io.netty.channel.DefaultFileRegion) HttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponse) HttpHeaders(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpHeaders) ObjectMapper(org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.ObjectMapper) Map(java.util.Map) ConfigConstants(org.apache.flink.configuration.ConfigConstants) HttpRequest(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpRequest) CONNECTION(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION) Nonnull(javax.annotation.Nonnull) ChannelFuture(org.apache.flink.shaded.netty4.io.netty.channel.ChannelFuture) ErrorResponseBody(org.apache.flink.runtime.rest.messages.ErrorResponseBody) ChannelHandlerContext(org.apache.flink.shaded.netty4.io.netty.channel.ChannelHandlerContext) CONTENT_TYPE(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE) HttpChunkedInput(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpChunkedInput) Logger(org.slf4j.Logger) RestConstants(org.apache.flink.runtime.rest.util.RestConstants) GenericFutureListener(org.apache.flink.shaded.netty4.io.netty.util.concurrent.GenericFutureListener) StringWriter(java.io.StringWriter) Unpooled(org.apache.flink.shaded.netty4.io.netty.buffer.Unpooled) IOException(java.io.IOException) ByteBuf(org.apache.flink.shaded.netty4.io.netty.buffer.ByteBuf) SslHandler(org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslHandler) File(java.io.File) FileNotFoundException(java.io.FileNotFoundException) ResponseBody(org.apache.flink.runtime.rest.messages.ResponseBody) ChunkedFile(org.apache.flink.shaded.netty4.io.netty.handler.stream.ChunkedFile) FileChannel(java.nio.channels.FileChannel) FileChannel(java.nio.channels.FileChannel) ChunkedFile(org.apache.flink.shaded.netty4.io.netty.handler.stream.ChunkedFile) FileNotFoundException(java.io.FileNotFoundException) DefaultHttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultHttpResponse) HttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponse) IOException(java.io.IOException) DefaultFileRegion(org.apache.flink.shaded.netty4.io.netty.channel.DefaultFileRegion) FlinkException(org.apache.flink.util.FlinkException) SslHandler(org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslHandler) HttpChunkedInput(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpChunkedInput) RandomAccessFile(java.io.RandomAccessFile) DefaultHttpResponse(org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultHttpResponse) CompletableFuture(java.util.concurrent.CompletableFuture) Future(org.apache.flink.shaded.netty4.io.netty.util.concurrent.Future) ChannelFuture(org.apache.flink.shaded.netty4.io.netty.channel.ChannelFuture)

Aggregations

File (java.io.File)3 FileNotFoundException (java.io.FileNotFoundException)3 IOException (java.io.IOException)3 RandomAccessFile (java.io.RandomAccessFile)3 ChannelFuture (org.apache.flink.shaded.netty4.io.netty.channel.ChannelFuture)3 DefaultFileRegion (org.apache.flink.shaded.netty4.io.netty.channel.DefaultFileRegion)3 DefaultHttpResponse (org.apache.flink.shaded.netty4.io.netty.handler.codec.http.DefaultHttpResponse)3 HttpChunkedInput (org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpChunkedInput)3 HttpResponse (org.apache.flink.shaded.netty4.io.netty.handler.codec.http.HttpResponse)3 SslHandler (org.apache.flink.shaded.netty4.io.netty.handler.ssl.SslHandler)3 ChunkedFile (org.apache.flink.shaded.netty4.io.netty.handler.stream.ChunkedFile)3 InputStream (java.io.InputStream)2 URI (java.net.URI)2 URL (java.net.URL)2 ParseException (java.text.ParseException)2 SimpleDateFormat (java.text.SimpleDateFormat)2 Date (java.util.Date)2 NotFoundException (org.apache.flink.runtime.rest.NotFoundException)2 RestHandlerException (org.apache.flink.runtime.rest.handler.RestHandlerException)2 ErrorResponseBody (org.apache.flink.runtime.rest.messages.ErrorResponseBody)2