/*
 * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.grizzly.http.server;

import java.io.File;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.glassfish.grizzly.Grizzly;
import org.glassfish.grizzly.http.Method;
import org.glassfish.grizzly.http.util.Header;
import org.glassfish.grizzly.http.util.HttpStatus;
import org.glassfish.grizzly.utils.ArraySet;

HttpHandler, which processes requests to a static resources.
Author:Jeanfrancois Arcand, Alexey Stashok
/** * {@link HttpHandler}, which processes requests to a static resources. * * @author Jeanfrancois Arcand * @author Alexey Stashok */
public class StaticHttpHandler extends StaticHttpHandlerBase { private static final Logger LOGGER = Grizzly.logger(StaticHttpHandler.class); protected final ArraySet<File> docRoots = new ArraySet<File>(File.class); private boolean directorySlashOff;
Create HttpHandler, which, by default, will handle requests to the static resources located in the current directory.
/** * Create <tt>HttpHandler</tt>, which, by default, will handle requests * to the static resources located in the current directory. */
public StaticHttpHandler() { addDocRoot("."); }
Create a new instance which will look for static pages located under the docRoot. If the docRoot is null - static pages won't be served by this HttpHandler
Params:
  • docRoots – the folder(s) where the static resource are located. If the docRoot is null - static pages won't be served by this HttpHandler
/** * Create a new instance which will look for static pages located * under the <tt>docRoot</tt>. If the <tt>docRoot</tt> is <tt>null</tt> - * static pages won't be served by this <tt>HttpHandler</tt> * * @param docRoots the folder(s) where the static resource are located. * If the <tt>docRoot</tt> is <tt>null</tt> - static pages won't be served * by this <tt>HttpHandler</tt> */
public StaticHttpHandler(String... docRoots) { if (docRoots != null) { for (String docRoot : docRoots) { addDocRoot(docRoot); } } }
Create a new instance which will look for static pages located under the docRoot. If the docRoot is null - static pages won't be served by this HttpHandler
Params:
  • docRoots – the folders where the static resource are located. If the docRoot is empty - static pages won't be served by this HttpHandler
/** * Create a new instance which will look for static pages located * under the <tt>docRoot</tt>. If the <tt>docRoot</tt> is <tt>null</tt> - * static pages won't be served by this <tt>HttpHandler</tt> * * @param docRoots the folders where the static resource are located. * If the <tt>docRoot</tt> is empty - static pages won't be served * by this <tt>HttpHandler</tt> */
@SuppressWarnings("UnusedDeclaration") public StaticHttpHandler(Set<String> docRoots) { if (docRoots != null) { for (String docRoot : docRoots) { addDocRoot(docRoot); } } }
Return the default directory from where files will be serviced.
Returns:the default directory from where file will be serviced.
/** * Return the default directory from where files will be serviced. * @return the default directory from where file will be serviced. */
@SuppressWarnings("UnusedDeclaration") public File getDefaultDocRoot() { final File[] array = docRoots.getArray(); return (array != null && array.length > 0) ? array[0] : null; }
Return the list of directories where files will be serviced from.
Returns:the list of directories where files will be serviced from.
/** * Return the list of directories where files will be serviced from. * * @return the list of directories where files will be serviced from. */
public ArraySet<File> getDocRoots() { return docRoots; }
Add the directory to the list of directories where files will be serviced from.
Params:
  • docRoot – the directory to be added to the list of directories where files will be serviced from.
Returns:return the File representation of the passed docRoot.
/** * Add the directory to the list of directories where files will be serviced from. * * @param docRoot the directory to be added to the list of directories * where files will be serviced from. * * @return return the {@link File} representation of the passed <code>docRoot</code>. */
public final File addDocRoot(String docRoot) { if (docRoot == null) { throw new NullPointerException("docRoot can't be null"); } final File file = new File(docRoot); addDocRoot(file); return file; }
Add the directory to the list of directories where files will be serviced from.
Params:
  • docRoot – the directory to be added to the list of directories where files will be serviced from.
/** * Add the directory to the list of directories where files will be serviced from. * * @param docRoot the directory to be added to the list of directories * where files will be serviced from. */
public final void addDocRoot(File docRoot) { docRoots.add(docRoot); }
Removes the directory from the list of directories where static files will be serviced from.
Params:
  • docRoot – the directory to remove.
/** * Removes the directory from the list of directories where static files will be serviced from. * * @param docRoot the directory to remove. */
@SuppressWarnings("UnusedDeclaration") public void removeDocRoot(File docRoot) { docRoots.remove(docRoot); }
Returns:true if HTTP 301 redirect shouldn't be sent when requested static resource is a directory, or false otherwise
/** * @return <tt>true</tt> if HTTP 301 redirect shouldn't be sent when requested * static resource is a directory, or <tt>false</tt> otherwise */
public boolean isDirectorySlashOff() { return directorySlashOff; }
If the directorySlashOff is true HTTP 301 redirect will not be sent when requested static resource is a directory.
Params:
  • directorySlashOff –
/** * If the directorySlashOff is <tt>true</tt> HTTP 301 redirect will not be * sent when requested static resource is a directory. * * @param directorySlashOff */
public void setDirectorySlashOff(boolean directorySlashOff) { this.directorySlashOff = directorySlashOff; } // ------------------------------------------------------- Protected Methods
{@inheritDoc}
/** * {@inheritDoc} */
@Override protected boolean handle(final String uri, final Request request, final Response response) throws Exception { boolean found = false; final File[] fileFolders = docRoots.getArray(); if (fileFolders == null) { return false; } File resource = null; for (int i = 0; i < fileFolders.length; i++) { final File webDir = fileFolders[i]; // local file resource = new File(webDir, uri); final boolean exists = resource.exists(); final boolean isDirectory = resource.isDirectory(); if (exists && isDirectory) { if (!directorySlashOff && !uri.endsWith("/")) { // redirect to the same url, but with trailing slash response.setStatus(HttpStatus.MOVED_PERMANENTLY_301); response.setHeader(Header.Location, response.encodeRedirectURL(uri + "/")); return true; } final File f = new File(resource, "/index.html"); if (f.exists()) { resource = f; found = true; break; } } if (isDirectory || !exists) { found = false; } else { found = true; break; } } if (!found) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, "File not found {0}", resource); } return false; } assert resource != null; // If it's not HTTP GET - return method is not supported status if (!Method.GET.equals(request.getMethod())) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, "File found {0}, but HTTP method {1} is not allowed", new Object[] {resource, request.getMethod()}); } response.setStatus(HttpStatus.METHOD_NOT_ALLOWED_405); response.setHeader(Header.Allow, "GET"); return true; } pickupContentType(response, resource.getPath()); addToFileCache(request, response, resource); sendFile(response, resource); return true; } }