/* (non-Javadoc)
   * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
   */
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {

    ServletRequest req = getRequest(request);

    ServletResponse resp = getResponse(request, response);

    request.setAttribute(PROCESSED_ATTR, Boolean.TRUE);

    chain.doFilter(req, resp);

    if (resp instanceof CompressedHttpServletResponseWrapper) {

      CompressedHttpServletResponseWrapper compressedResponseWrapper =
          (CompressedHttpServletResponseWrapper) resp;

      try {

        compressedResponseWrapper.close(); // so that stream is finished and closed.

      } catch (IOException ex) {

        LOGGER.error("Response was already closed: ", ex.toString());
      }

      if (compressedResponseWrapper.isCompressed()) {

        req.setAttribute(COMPRESSED_ATTR, Boolean.TRUE);
      }
    }
  }
  private ServletResponse getResponse(ServletRequest request, ServletResponse response) {
    if (response.isCommitted() || request.getAttribute(PROCESSED_ATTR) != null) {
      LOGGER.trace("No Compression: Response committed or filter has already been applied");
      return response;
    }

    if (!(response instanceof HttpServletResponse) || !(request instanceof HttpServletRequest)) {
      LOGGER.trace("No Compression: non http request/response");
      return response;
    }

    HttpServletResponse httpResponse = (HttpServletResponse) response;

    HttpServletRequest httpRequest = (HttpServletRequest) request;

    String acceptEncoding = httpRequest.getHeader(HTTP_ACCEPT_ENCODING_HEADER);

    String contentEncoding = getAppropriateContentEncoding(acceptEncoding);

    if (contentEncoding == null) {
      LOGGER.trace("No Compression: Accept encoding is : {}", acceptEncoding);
      return response;
    }

    String requestURI = httpRequest.getRequestURI();
    if (!isURLAccepted(requestURI)) {
      LOGGER.trace("No Compression: For path: ", requestURI);
      return response;
    }
    if (!isQueryStringAccepted(httpRequest.getQueryString())) {
      LOGGER.trace("No Compression: For Query String: ", httpRequest.getQueryString());
      return response;
    }
    String userAgent = httpRequest.getHeader(Constants.HTTP_USER_AGENT_HEADER);
    if (!isUserAgentAccepted(userAgent)) {
      LOGGER.trace("No Compression: For User-Agent: {}", userAgent);
      return response;
    }

    EncodedStreamsFactory encodedStreamsFactory =
        EncodedStreamsFactory.getFactoryForContentEncoding(contentEncoding);

    LOGGER.debug("Compressing response: content encoding : {}", contentEncoding);

    return new CompressedHttpServletResponseWrapper(
        httpResponse, encodedStreamsFactory, contentEncoding, compressionThreshold, this);
  }