/* * Copyright LGPL3 * YES Technology Association * http://yestech.org * * http://www.opensource.org/licenses/lgpl-3.0.html */ package org.yestech.lib.web.filter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.yestech.lib.web.GenericResponseWrapper; import static org.yestech.lib.web.RequestUtils.*; import static org.yestech.lib.web.ResponseUtils.*; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPOutputStream; /** * Provides compression of responses. Currently only GZip is supported. In the future other compression * algorithms will be integrated. * <p/> * See the filter-mappings.xml entry for the gzip filter for the URL patterns * which will be gzipped. At present this includes .jsp, .js and .css. * <p/> * * @author Artie Copeland * @version $Revision: $ */ public class CompressionFilter implements Filter { final private static Logger logger = LoggerFactory.getLogger(CompressionFilter.class); @Override public void init(FilterConfig filterConfig) throws ServletException { //To change body of implemented methods use File | Settings | File Templates. } @Override public void doFilter(ServletRequest rawRequest, ServletResponse rawResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) rawRequest; HttpServletResponse response = (HttpServletResponse) rawResponse; if (!isIncluded(request) && acceptsEncoding(request, "gzip")) { // Client accepts zipped content if (logger.isDebugEnabled()) { logger.debug(request.getRequestURL() + ". Writing with gzip compression"); } // Create a gzip stream final ByteArrayOutputStream compressed = new ByteArrayOutputStream(); final GZIPOutputStream gzout = new GZIPOutputStream(compressed); // Handle the request final GenericResponseWrapper wrapper = new GenericResponseWrapper(response, gzout); chain.doFilter(request, wrapper); wrapper.flush(); gzout.close(); //return on error or redirect code, because response is already committed int statusCode = wrapper.getStatus(); if (statusCode != HttpServletResponse.SC_OK) { return; } //Saneness checks byte[] compressedBytes = compressed.toByteArray(); boolean shouldGzippedBodyBeZero = shouldGzippedBodyBeZero(compressedBytes, request); boolean shouldBodyBeZero = shouldBodyBeZero(request, wrapper.getStatus()); if (shouldGzippedBodyBeZero || shouldBodyBeZero) { compressedBytes = new byte[0]; } // Write the zipped body addGzipHeader(response); response.setContentLength(compressedBytes.length); response.getOutputStream().write(compressedBytes); } else { // Client does not accept zipped content - don't bother zipping if (logger.isDebugEnabled()) { logger.debug(request.getRequestURL() + ". Writing without gzip compression because the request does not accept gzip."); } chain.doFilter(request, response); } } @Override public void destroy() { //To change body of implemented methods use File | Settings | File Templates. } }