All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.embedded.FastFileServer Maven / Gradle / Ivy

There is a newer version: 9.4.15.v20190215
Show newest version
//
//  ========================================================================
//  Copyright (c) 1995-2016 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.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.resource.Resource;

/**
 * Fast FileServer.
 * 

* 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. *

*

* 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 *

*/ 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); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy