Package com.google.appengine.tools.development

Source Code of com.google.appengine.tools.development.StaticFileFilter

// Copyright 2009 Google Inc. All rights reserved.

package com.google.appengine.tools.development;

import com.google.apphosting.utils.config.AppEngineWebXml;

import org.mortbay.jetty.handler.ContextHandler;
import org.mortbay.jetty.servlet.Dispatcher;
import org.mortbay.resource.Resource;
import org.mortbay.util.URIUtil;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

/**
* {@code StaticFileFilter} is a {@link Filter} that replicates the
* static file serving logic that is present in the PFE and AppServer.
* This logic was originally implemented in {@link
* LocalResourceFileServlet} but static file serving needs to take
* precedence over all other servlets and filters.
*
*/
public class StaticFileFilter implements Filter {
  private static final Logger logger =
      Logger.getLogger(StaticFileFilter.class.getName());

  private StaticFileUtils staticFileUtils;
  private AppEngineWebXml appEngineWebXml;
  private Resource resourceBase;
  private String[] welcomeFiles;
  private String resourceRoot;
  private ContextHandler.SContext servletContext;

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    servletContext = (ContextHandler.SContext) filterConfig.getServletContext();
    staticFileUtils = new StaticFileUtils(servletContext);

    welcomeFiles = servletContext.getContextHandler().getWelcomeFiles();

    appEngineWebXml = (AppEngineWebXml) servletContext.getAttribute(
        "com.google.appengine.tools.development.appEngineWebXml");
    resourceRoot = appEngineWebXml.getPublicRoot();

    try {
      resourceBase = servletContext.getContextHandler().getResource(URIUtil.SLASH + resourceRoot);
    } catch (MalformedURLException ex) {
      logger.log(Level.WARNING, "Could not initialize:", ex);
      throw new ServletException(ex);
    }
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws ServletException, IOException {
    Boolean forwarded = (Boolean) request.getAttribute(Dispatcher.__FORWARD_JETTY);
    if (forwarded == null) {
      forwarded = Boolean.FALSE;
    }

    Boolean included = (Boolean) request.getAttribute(Dispatcher.__INCLUDE_JETTY);
    if (included == null) {
      included = Boolean.FALSE;
    }

    if (forwarded || included) {
      chain.doFilter(request, response);
      return;
    }

    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;
    String servletPath = httpRequest.getServletPath();
    String pathInfo = httpRequest.getPathInfo();
    String pathInContext = URIUtil.addPaths(servletPath, pathInfo);

    if (maybeServeWelcomeFile(pathInContext, httpRequest, httpResponse)) {
      return;
    }

    Resource resource = null;
    try {
      resource = getResource(pathInContext);

      if (resource != null && resource.exists() && !resource.isDirectory()) {
        if (appEngineWebXml.includesStatic(resourceRoot + pathInContext)) {
          if (staticFileUtils.passConditionalHeaders(httpRequest, httpResponse, resource)) {
            staticFileUtils.sendData(httpRequest, httpResponse, false, resource);
          }
          return;
        }
      }
    } finally {
      if (resource != null) {
        resource.release();
      }
    }
    chain.doFilter(request, response);
  }

  /**
   * Get Resource to serve.
   * @param pathInContext The path to find a resource for.
   * @return The resource to serve.
   */
  private Resource getResource(String pathInContext) {
    try {
      if (resourceBase != null) {
        return resourceBase.addPath(pathInContext);
      }
    } catch (IOException ex) {
      logger.log(Level.WARNING, "Could not find: " + pathInContext, ex);
    }
    return null;
  }

  /**
   * Finds a matching welcome file for the supplied path and, if
   * found, serves it to the user.  This will be the first entry in
   * the list of configured {@link #welcomeFiles welcome files} that
   * exists within the directory referenced by the path.
   * @param path
   * @param request
   * @param response
   * @return true if a welcome file was served, false otherwise
   * @throws IOException
   * @throws MalformedURLException
   */
  private boolean maybeServeWelcomeFile(String path,
                                        HttpServletRequest request,
                                        HttpServletResponse response)
      throws IOException, ServletException {
    if (welcomeFiles == null) {
      return false;
    }

    if (!path.endsWith(URIUtil.SLASH)) {
      path += URIUtil.SLASH;
    }

    for (String welcomeName : welcomeFiles) {
      final String welcomePath = path + welcomeName;

      Resource welcomeFile = getResource(path + welcomeName);
      if (welcomeFile != null && welcomeFile.exists()) {
        if (appEngineWebXml.includesStatic(resourceRoot + welcomePath)) {
          RequestDispatcher dispatcher = servletContext.getNamedDispatcher("_ah_default");
          request = new HttpServletRequestWrapper(request) {
              @Override
              public String getServletPath() {
                return welcomePath;
              }

              @Override
              public String getPathInfo() {
                return "";
              }
          };
          return staticFileUtils.serveWelcomeFileAsForward(dispatcher, false, request, response);
        }
      }
    }

    return false;
  }

  @Override
  public void destroy() {
  }
}
TOP

Related Classes of com.google.appengine.tools.development.StaticFileFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.