Exemplo n.º 1
0
  @Override
  public void doFilter(
      ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
      throws IOException, ServletException {

    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;

    String url = httpServletRequest.getRequestURI();

    httpServletResponse.setHeader(CACHE_HEADER, CacheState.SKIPPED.toString());

    if (!isURLAccepted(url)
        || !isQueryStringAccepted(httpServletRequest.getQueryString())
        || !isUserAgentAccepted(httpServletRequest.getHeader(Constants.HTTP_USER_AGENT_HEADER))) {
      LOGGER.debug("Skipping Cache filter for: {}?{}", url, httpServletRequest.getQueryString());
      LOGGER.debug("URL, QueryString or UserAgent not accepted");
      filterChain.doFilter(servletRequest, servletResponse);
      return;
    }

    long now = new Date().getTime();

    CacheObject cacheObject = cache.getIfPresent(url);

    boolean expireCache = httpServletRequest.getParameter(Constants.PARAM_EXPIRE_CACHE) != null;

    if (expireCache) {
      LOGGER.trace("Removing Cache for {}  due to URL parameter.", url);
      cache.invalidate(url);
    }

    boolean resetCache =
        httpServletRequest.getParameter(Constants.PARAM_RESET_CACHE) != null
            || resetTime > 0 && (now - lastResetTime) / 1000 > resetTime;

    if (resetCache) {
      LOGGER.trace("Resetting whole Cache for {} due to URL parameter.", url);
      cache.invalidateAll(); // fixme: we don't need reset since cache values are soft referenced.
      lastResetTime = now;
    }

    boolean skipCache =
        httpServletRequest.getParameter(Constants.PARAM_DEBUG) != null
            || httpServletRequest.getParameter(Constants.PARAM_SKIP_CACHE) != null;

    if (skipCache) {
      filterChain.doFilter(servletRequest, servletResponse);
      LOGGER.trace("Skipping Cache for {} due to URL parameter.", url);
      return;
    }

    List<String> requestedResources =
        findResourcesToMerge(httpServletRequest.getContextPath(), url);
    ServletContext context = filterConfig.getServletContext();
    String extensionOrPath = detectExtension(url); // in case of non js/css files it null
    if (extensionOrPath == null) {
      extensionOrPath =
          requestedResources.get(
              0); // non grouped i.e. non css/js file, we refer it's path in that case
    }

    JSCSSMergeServlet.ResourceStatus status =
        JSCSSMergeServlet.isNotModified(context, httpServletRequest, requestedResources, false);
    if (status.isNotModified()) {
      LOGGER.trace("Resources Not Modified. Sending 304.");
      cache.invalidate(url);
      JSCSSMergeServlet.sendNotModified(
          httpServletResponse,
          extensionOrPath,
          status.getActualETag(),
          DEFAULT_EXPIRES_MINUTES,
          DEFAULT_CACHE_CONTROL);
      return;
    }

    boolean cacheFound = false;

    if (cacheObject != null && cacheObject.getWebUtilitiesResponseWrapper() != null) {
      if (requestedResources != null
          && isAnyResourceModifiedSince(requestedResources, cacheObject.getTime(), context)) {
        LOGGER.trace("Some resources have been modified since last cache: {}", url);
        cache.invalidate(url);
        cacheFound = false;
      } else {
        LOGGER.trace("Found valid cached response.");
        // cacheObject.increaseAccessCount();
        cacheFound = true;
      }
    }

    if (cacheFound) {
      LOGGER.debug("Returning Cached response.");
      cacheObject.getWebUtilitiesResponseWrapper().fill(httpServletResponse);
      httpServletResponse.setHeader(CACHE_HEADER, CacheState.FOUND.toString());
      // fillResponseFromCache(httpServletResponse, cacheObject.getModuleResponse());
    } else {
      LOGGER.trace("Cache not found or invalidated");
      httpServletResponse.setHeader(CACHE_HEADER, CacheState.NOT_FOUND.toString());
      WebUtilitiesResponseWrapper wrapper = new WebUtilitiesResponseWrapper(httpServletResponse);
      filterChain.doFilter(servletRequest, wrapper);

      // some filters return no status code, but we believe that it is "200 OK"
      if (wrapper.getStatus() == 0) {
        wrapper.setStatus(200);
      }

      if (isMIMEAccepted(wrapper.getContentType())
          && !expireCache
          && !resetCache
          && wrapper.getStatus() == 200) { // Cache only 200 status response
        cache.put(url, new CacheObject(getLastModifiedFor(requestedResources, context), wrapper));
        LOGGER.debug("Cache added for: {}", url);
        httpServletResponse.setHeader(CACHE_HEADER, CacheState.ADDED.toString());
      } else {
        LOGGER.trace("Cache NOT added for: {}", url);
        LOGGER.trace("is MIME not accepted: {}", isMIMEAccepted(wrapper.getContentType()));
        LOGGER.trace("is expireCache: {}", expireCache);
        LOGGER.trace("is resetCache: {}", resetCache);
      }
      wrapper.fill(httpServletResponse);
    }
  }