• New Feature
  • Status: Open
  • 2 Major
  • Resolution:
  • ehcache-web
  • Reporter: thaiha
  • November 03, 2010
  • 0
  • Watchers: 0
  • October 11, 2011

Description

In my project which using UrlRewriteFilter 3.2.0, ehcache-web 2.0.2 and Spring MVC 3.0.5, there are cases where GzipFilter doesn’t work correctly (i.e. gzipping content more than once).

————- web.xml ——————–

urlrewrite-filter org.tuckey.web.filters.urlrewrite.UrlRewriteFilter compression-filter net.sf.ehcache.constructs.web.filter.GzipFilter urlrewrite-filter /* compression-filter *.html *.jsp REQUEST FORWARD dispatcher-servlet org.springframework.web.servlet.DispatcherServlet contextConfigLocation /WEB-INF/spring/applicationContext-mvc.xml 1 dispatcher-servlet *.html

A scenario where the GzipFilter doesn’t work correctly is below:

  1. A request like /product/ipod is received by web server

  2. The request is rewritten to be /product/5/index.html by UrlRewriter. And a forward to /product/5/index.html is called. (org.tuckey.web.filters.urlrewrite.UrlRewriter calls forward())

  3. GzipFilter is called because dispatcher = FORWARD net.sf.ehcache.constructs.web.filter.GzipFilter: isIncluded() returns false

  4. Spring MVC servlet is called because of mapping “*.html”. And another forward to product.jsp is called. (org.springframework.web.servlet.DispatcherServlet calls forward())

  5. GzipFilter is called because dispatcher = FORWARD net.sf.ehcache.constructs.web.filter.GzipFilter: isIncluded() returns false

* Result: GzipFilter does gzipping twice at steps 3 and 5. * Expected result: GzipFilter should not do gzipping again if it is called again because of RD.forward() calls

At the moment I use a workaround solution by modifying GzipFilter to use a thread local variable to avoid gzipping multiple times. See it below: private static final ThreadLocal gzipFlagHolder = new NamedThreadLocal("gzipFlagHolder"); protected void doFilter(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws Exception { if (!isIncluded(request) && acceptsEncoding(request, "gzip") && !response.isCommitted()) { try { gzipFlagHolder.set(Boolean.TRUE); .... // gzip code here } finally { gzipFlagHolder.remove(); } } else { ... } }

private boolean isIncluded(final HttpServletRequest request) {
    final String uri = (String) request.getAttribute("javax.servlet.include.request_uri");
    final boolean includeRequest = !(uri == null) || (gzipFlagHolder.get() != null);

    if (includeRequest && LOG.isDebugEnabled()) {
        ...
    }
    return includeRequest;
}

If this is not a bug then it should be a nice-to-have feature (maybe a new config option like once-per-thread=true should enable this behavior?)

Comments

Fiona OShea 2011-02-22

MOving unresolved P2 jiras to Ulloa - to be reviewed by Chris, Fiona, Greg soon