//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.embedded;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.file.StandardOpenOption;

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.resource.Resource;

/**
 * Fast FileServer.
 * <p>
 * This example shows how to use the Jetty APIs for sending static as fast as
 * possible using various strategies for small, medium and large content.
 * </p>
 * <p>
 * The Jetty {@link DefaultServlet} does all this and more, and to a lesser
 * extent so does the {@link ResourceHandler}, so unless you have exceptional
 * circumstances it is best to use those classes for static content
 * </p>
 */
public class FastFileServer
{
    public static void main( String[] args ) throws Exception
    {
        Server server = new Server(8080);

        HandlerList handlers = new HandlerList();
        handlers.setHandlers(new Handler[] {
                new FastFileHandler(new File(System.getProperty("user.dir"))),
                new DefaultHandler() });
        server.setHandler(handlers);

        server.start();
        server.join();
    }

    static class FastFileHandler extends AbstractHandler
    {
        private final MimeTypes mimeTypes = new MimeTypes();
        private final File dir;

        private FastFileHandler( File dir )
        {
            this.dir = dir;
        }

        @Override
        public void handle( String target,
                            Request baseRequest,
                            HttpServletRequest request,
                            HttpServletResponse response ) throws IOException,
                                                          ServletException
        {
            // define small medium and large.
            // This should be turned for your content, JVM and OS, but we will
            // huge HTTP response buffer size as a measure
            final int SMALL = response.getBufferSize();
            final int MEDIUM = 8 * SMALL;

            // What file to serve?
            final File file = new File(this.dir, request.getPathInfo());

            // Only handle existing files
            if (!file.exists())
                return;

            // we will handle this request
            baseRequest.setHandled(true);

            // Handle directories
            if (file.isDirectory())
            {
                if (!request.getPathInfo().endsWith(URIUtil.SLASH))
                {
                    response.sendRedirect(response.encodeRedirectURL(URIUtil
                            .addPaths(request.getRequestURI(), URIUtil.SLASH)));
                    return;
                }
                String listing = Resource.newResource(file).getListHTML(
                        request.getRequestURI(),
                        request.getPathInfo().lastIndexOf("/") > 0);
                response.setContentType("text/html; charset=utf-8");
                response.getWriter().println(listing);
                return;
            }

            // Set some content headers.
            
            // Jetty DefaultServlet will cache formatted date strings, but we
            // will reformat for each request here
            response.setDateHeader("Last-Modified", file.lastModified());
            response.setDateHeader("Content-Length", file.length());
            response.setContentType(mimeTypes.getMimeByExtension(file.getName()));

            // send "small" files blocking directly from an input stream
            if (file.length() < SMALL)
            {
                // need to caste to Jetty output stream for best API
                ((HttpOutput) response.getOutputStream())
                        .sendContent(FileChannel.open(file.toPath(),
                                StandardOpenOption.READ));
                return;
            }

            // send not "small" files asynchronously so we don't hold threads if
            // the client is slow
            final AsyncContext async = request.startAsync();
            Callback completionCB = new Callback()
            {
                @Override
                public void succeeded()
                {
                    // Async content write succeeded, so complete async response
                    async.complete();
                }

                @Override
                public void failed( Throwable x )
                {
                    // log error and complete async response;
                    x.printStackTrace();
                    async.complete();
                }
            };

            // send "medium" files from an input stream
            if (file.length() < MEDIUM)
            {
                // the file channel is closed by the async send
                ((HttpOutput) response.getOutputStream())
                        .sendContent(FileChannel.open(file.toPath(),
                                StandardOpenOption.READ), completionCB);
                return;
            }

            // for "large" files get the file mapped buffer to send Typically
            // the resulting buffer should be cached as allocating kernel memory
            // can be hard to GC on some JVMs. But for this example we will
            // create a new buffer per file
            ByteBuffer buffer;
            try ( RandomAccessFile raf = new RandomAccessFile(file, "r"); )
            {
                buffer = raf.getChannel().map(MapMode.READ_ONLY, 0,
                        raf.length());
            }

            // Assuming the file buffer might be shared cached version, so lets
            // take our own view of it
            buffer = buffer.asReadOnlyBuffer();

            // send the content as a buffer with a callback to complete the
            // async request need to caste to Jetty output stream for best API
            ((HttpOutput) response.getOutputStream()).sendContent(buffer,
                    completionCB);
        }
    }
}
