/*
* 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.
}
}