Index: CacheFilter.java =================================================================== RCS file: /cvs/oscache/src/core/java/com/opensymphony/oscache/web/filter/CacheFilter.java,v retrieving revision 1.5 diff -u -r1.5 CacheFilter.java --- CacheFilter.java 22 Feb 2005 17:17:02 -0000 1.5 +++ CacheFilter.java 21 Mar 2005 10:47:04 -0000 @@ -35,6 +35,7 @@ // Header public static final String HEADER_LAST_MODIFIED = "Last-Modified"; public static final String HEADER_CONTENT_TYPE = "Content-Type"; + public static final String HEADER_CONTENT_ENCODING = "Content-Encoding"; public static final String HEADER_EXPIRES = "Expires"; public static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since"; @@ -120,7 +121,11 @@ } } - respContent.writeTo(response, fragmentRequest); + boolean supportGZIP = false; + if (respContent.isContentGziped()) { + supportGZIP = isGZIPSupported((HttpServletRequest)request); + } + respContent.writeTo(response, fragmentRequest, supportGZIP); } catch (NeedsRefreshException nre) { boolean updateSucceeded = false; @@ -246,5 +251,19 @@ public boolean isFilteredBefore(ServletRequest request) { return request.getAttribute(REQUEST_FILTERED) != null; } - + + /** + * @param request + * @return true if client supports GZIP + */ + protected boolean isGZIPSupported(HttpServletRequest request) { + String acceptEncoding = request.getHeader("Accept-Encoding"); + + if ((acceptEncoding != null) && (acceptEncoding.indexOf("gzip") != -1)) { + return true; + } + + return false; + } + } Index: CacheHttpServletResponseWrapper.java =================================================================== RCS file: /cvs/oscache/src/core/java/com/opensymphony/oscache/web/filter/CacheHttpServletResponseWrapper.java,v retrieving revision 1.6 diff -u -r1.6 CacheHttpServletResponseWrapper.java --- CacheHttpServletResponseWrapper.java 23 Feb 2005 17:55:29 -0000 1.6 +++ CacheHttpServletResponseWrapper.java 21 Mar 2005 10:47:04 -0000 @@ -143,7 +143,10 @@ if (CacheFilter.HEADER_CONTENT_TYPE.equalsIgnoreCase(name)) { result.setContentType(value); } - + if (CacheFilter.HEADER_CONTENT_ENCODING.equalsIgnoreCase(name)) { + result.setContentEncoding(value); + } + super.setHeader(name, value); } @@ -161,6 +164,9 @@ if (CacheFilter.HEADER_CONTENT_TYPE.equalsIgnoreCase(name)) { result.setContentType(value); } + if (CacheFilter.HEADER_CONTENT_ENCODING.equalsIgnoreCase(name)) { + result.setContentEncoding(value); + } super.addHeader(name, value); } Index: ResponseContent.java =================================================================== RCS file: /cvs/oscache/src/core/java/com/opensymphony/oscache/web/filter/ResponseContent.java,v retrieving revision 1.3 diff -u -r1.3 ResponseContent.java --- ResponseContent.java 22 Feb 2005 17:17:02 -0000 1.3 +++ ResponseContent.java 21 Mar 2005 10:47:04 -0000 @@ -7,9 +7,12 @@ import java.io.*; import java.util.Locale; +import java.util.zip.GZIPInputStream; import javax.servlet.ServletResponse; +import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletRequest; /** * Holds the servlet response in a byte array so that it can be held @@ -23,6 +26,7 @@ private transient ByteArrayOutputStream bout = new ByteArrayOutputStream(1000); private Locale locale = null; private String contentType = null; + private String contentEncoding = null; private byte[] content = null; private long lastModified = -1; private long expires = Long.MAX_VALUE; @@ -35,6 +39,14 @@ contentType = value; } + /** + * Set the content encoding. We capture this so that when we serve this + * data from cache, we can set the correct content encoding on the response. + */ + public void setContentEncoding(String contentEncoding) { + this.contentEncoding = contentEncoding; + } + public long getLastModified() { return lastModified; } @@ -97,10 +109,11 @@ * Writes this cached data out to the supplied ServletResponse. * * @param response The servlet response to output the cached content to. + * @param supportGZIP trus if the client browser supports GZIP * @throws IOException */ - public void writeTo(ServletResponse response) throws IOException { - writeTo(response, false); + public void writeTo(ServletResponse response, boolean supportGZIP) throws IOException { + writeTo(response, false, supportGZIP); } /** @@ -108,9 +121,10 @@ * * @param response The servlet response to output the cached content to. * @param fragment is true if this content a fragment or part of a page + * @param supportGZIP trus if the client browser supports GZIP * @throws IOException */ - public void writeTo(ServletResponse response, boolean fragment) throws IOException { + public void writeTo(ServletResponse response, boolean fragment, boolean supportGZIP) throws IOException { //Send the content type and data to this response if (contentType != null) { response.setContentType(contentType); @@ -128,7 +142,39 @@ } OutputStream out = new BufferedOutputStream(response.getOutputStream()); + + if (isContentGziped()) { + if (supportGZIP) { + ((HttpServletResponse) response).addHeader("Content-Encoding", "gzip"); + } else { + // client doesn't support, so we have to uncompress it + ByteArrayInputStream bais = new ByteArrayInputStream(content); + GZIPInputStream zis = new GZIPInputStream(bais); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int numBytesRead = 0; + byte[] tempBytes = new byte[512]; + + while ((numBytesRead = zis.read(tempBytes, 0, tempBytes.length)) != -1) { + baos.write(tempBytes, 0, numBytesRead); + } + + byte[] result = baos.toByteArray(); + response.setContentLength(result.length); + out.write(result); + out.flush(); + return; + } + } + out.write(content); out.flush(); + } + + /** + * @return true if the content is GZIP compressed + */ + public boolean isContentGziped() { + return "gzip".equals(contentEncoding); } }