content: package ro.isdc.wro.http;
  
  import java.io.BufferedOutputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.util.zip.GZIPOutputStream;
  
  import javax.servlet.Filter;
  import javax.servlet.FilterChain;
  import javax.servlet.FilterConfig;
  import javax.servlet.ServletException;
  import javax.servlet.ServletRequest;
  import javax.servlet.ServletResponse;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.servlet.http.HttpServletResponseWrapper;
  
  import org.apache.commons.io.IOUtils;
  import org.apache.commons.io.output.CountingOutputStream;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import ro.isdc.wro.http.support.HttpHeader;
  import ro.isdc.wro.http.support.RedirectedStreamServletResponseWrapper;
  import ro.isdc.wro.model.resource.locator.support.DispatcherStreamLocator;
  import ro.isdc.wro.util.WroUtil;
  
  
  /**
   * A filter responsible for gzipping all content served through this filter.
   *
   * @author Alex Objelean
   * @created 11 Apr 2013
   * @since 1.7.0
   */
  public class GzipFilter
      implements Filter {
    private static final Logger LOG = LoggerFactory.getLogger(GzipFilter.class);
  
    /**
     * {@inheritDoc}
     */
    public void init(final FilterConfig filterConfig)
        throws ServletException {
    }
  
    /**
     * {@inheritDoc}
     */
    public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
        throws IOException, ServletException {
      final HttpServletRequest request = (HttpServletRequest) req;
      final HttpServletResponse response = (HttpServletResponse) res;
  
      if (isGzipAllowed(request)) {
        doGzipResponse(request, response, chain);
      } else {
        LOG.debug("Gzip not allowed. Proceeding with chain.");
        chain.doFilter(request, response);
      }
    }
  
    /**
     * Performs actual gzip of the filtered content.
     */
    private void doGzipResponse(final HttpServletRequest req, final HttpServletResponse response, final FilterChain chain)
        throws IOException, ServletException {
      LOG.debug("Applying gzip on resource: " + req.getRequestURI());
      response.setHeader(HttpHeader.CONTENT_ENCODING.toString(), "gzip");
      final ByteArrayOutputStream baos = new ByteArrayOutputStream();
      final CountingOutputStream countingStream = new CountingOutputStream(new GZIPOutputStream(new BufferedOutputStream(
          baos)));
      // final GZIPOutputStream gzout = new GZIPOutputStream(new BufferedOutputStream(baos));
      // Perform gzip operation in-memory before sending response
      final HttpServletResponseWrapper wrappedResponse = new RedirectedStreamServletResponseWrapper(countingStream,
          response);
      chain.doFilter(req, wrappedResponse);
      // close underlying stream
      countingStream.close();
      response.setContentLength(countingStream.getCount());
      // avoid NO CONTENT error thrown by jetty when gzipping empty response
      if (countingStream.getCount() > 0) {
        IOUtils.write(baos.toByteArray(), response.getOutputStream());
      }
    }
  
    /**
     * Checks if the request supports gzip and is not a include request (these cannot be gzipped)
     */
    private boolean isGzipAllowed(final HttpServletRequest request) {
      return !DispatcherStreamLocator.isIncludedRequest(request) && WroUtil.isGzipSupported(request);
    }
  
    /**
     * {@inheritDoc}
     */
    public void destroy() {
    }
  
  }
  