[Opensymphony-oscache] RE: CVS update: /oscache/src/core/java/com/opensymphony/oscache/web/filter/
"March, Andres" <[email protected]>
| Newsgroups | gmane.comp.java.open-symphony.os-cache |
|---|---|
| Message-ID | <7EA6A25EC6360A488E0EBB5F3F21A0DC04933562@mail-sd4.ad.soe.sony.com> |
I didn't think that we came to agreement to how this should work. Are we comfortable with how this is implemented? > -----Original Message----- > From: [email protected] [mailto:[email protected]] > Sent: Monday, March 21, 2005 2:30 PM > To: [email protected] > Subject: CVS update: > /oscache/src/core/java/com/opensymphony/oscache/web/filter/ > > User: ltorunski > Date: 2005/03/21 14:29:58 > > Log: > Support of GZip filters in the filter chain > Issue number: CACHE-155 > Obtained from: Fernando Martins > Submitted by: Lars Torunski > > File Changes: > > Directory: /oscache/src/core/java/com/opensymphony/oscache/web/filter/ > ====================================================================== > > File [changed]: CacheFilter.java > Url: > https://oscache.dev.java.net/source/browse/oscache/src/core/java/com/ope ns > ymphony/oscache/web/filter/CacheFilter.java?r1=1.5&r2=1.6 > Delta lines: +46 -36 > --------------------- > --- CacheFilter.java 22 Feb 2005 17:17:02 -0000 1.5 > +++ CacheFilter.java 21 Mar 2005 22:29:55 -0000 1.6 > @@ -26,15 +26,13 @@ > * @author <a href="mailto:[email protected]">Serge Knystautas</a> > * @author <a href="mailto:[email protected]">Mike Cannon-Brookes</a> > * @author <a href="mailto:[email protected]">Lars Torunski</a> > - * @version $Revision: 1.5 $ > + * @version $Revision: 1.6 $ > */ > public class CacheFilter implements Filter { > - > - private final Log log = LogFactory.getLog(this.getClass()); > - > // 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"; > > @@ -43,17 +41,19 @@ > public static final int FRAGMENT_NO = 0; > public static final int FRAGMENT_YES = 1; > > + // request attribute to avoid reentrance > + private final static String REQUEST_FILTERED = "__oscache_filtered"; > + > + // the policy for the expires header > + private static final ExpiresRefreshPolicy EXPIRES_REFRESH_POLICY = > new ExpiresRefreshPolicy(); > + private final Log log = LogFactory.getLog(this.getClass()); > + > // filter variables > private FilterConfig config; > private ServletCacheAdministrator admin = null; > private int cacheScope = PageContext.APPLICATION_SCOPE; // filter > scope - default is APPLICATION > - private int time = 60 * 60; // time before cache should be refreshed > - default one hour (in seconds) > private int fragment = FRAGMENT_AUTODETECT; // defines if this filter > handles fragments of a page - default is auto detect > - > - // request attribute to avoid reentrance > - private final static String REQUEST_FILTERED = "__oscache_filtered"; > - // the policy for the expires header > - private static final ExpiresRefreshPolicy EXPIRES_REFRESH_POLICY = > new ExpiresRefreshPolicy(); > + private int time = 60 * 60; // time before cache should be refreshed > - default one hour (in seconds) > > /** > * Filter clean-up > @@ -84,6 +84,7 @@ > chain.doFilter(request, response); > return; > } > + > request.setAttribute(REQUEST_FILTERED, Boolean.TRUE); > > HttpServletRequest httpRequest = (HttpServletRequest) request; > @@ -96,6 +97,7 @@ > > // avoid useless session creation for application scope pages > (CACHE-129) > Cache cache; > + > if (cacheScope == PageContext.SESSION_SCOPE) { > cache = > admin.getSessionScopeCache(httpRequest.getSession(true)); > } else { > @@ -109,19 +111,18 @@ > log.info("<cache>: Using cached entry for " + key); > } > > - // only reply with SC_NOT_MODIFIED > - // if the client has already the newest page and the reponse > isn't a fragment in a page > if (!fragmentRequest) { > long clientLastModified = > httpRequest.getDateHeader(HEADER_IF_MODIFIED_SINCE); // will return -1 if > no header... > > + // only reply with SC_NOT_MODIFIED > + // if the client has already the newest page and the > reponse isn't a fragment in a page > if ((clientLastModified != -1) && (clientLastModified >= > respContent.getLastModified())) { > ((HttpServletResponse) > response).setStatus(HttpServletResponse.SC_NOT_MODIFIED); > return; > } > } > > - respContent.writeTo(response, fragmentRequest); > - > + respContent.writeTo(response, fragmentRequest, > acceptsGZipEncoding(httpRequest)); > } catch (NeedsRefreshException nre) { > boolean updateSucceeded = false; > > @@ -194,6 +195,7 @@ > > try { > fragment = > Integer.parseInt(config.getInitParameter("fragment")); > + > if ((fragment < FRAGMENT_AUTODETECT) || (fragment > > FRAGMENT_YES)) { > log.info("Wrong init parameter 'fragment', setting to > 'auto detect':" + fragment); > fragment = FRAGMENT_AUTODETECT; > @@ -201,7 +203,6 @@ > } catch (Exception e) { > log.info("Could not get init parameter 'fragment', defaulting > to 'auto detect'."); > } > - > } > > /** > @@ -226,7 +227,7 @@ > * @param request the to be handled request > * @return true if the request is a fragment in a page > */ > - public boolean isFragment(HttpServletRequest request) { > + protected boolean isFragment(HttpServletRequest request) { > if (fragment == FRAGMENT_AUTODETECT) { > return > request.getAttribute("javax.servlet.include.request_uri") != null; > } else { > @@ -243,8 +244,17 @@ > * @param request checks if the request was filtered before. > * @return true if it is the first execution > */ > - public boolean isFilteredBefore(ServletRequest request) { > + protected boolean isFilteredBefore(ServletRequest request) { > return request.getAttribute(REQUEST_FILTERED) != null; > } > > + /** > + * Check if the client browser support gzip compression. > + * @param request the http request > + * @return true if client browser supports GZIP > + */ > + protected boolean acceptsGZipEncoding(HttpServletRequest request) { > + String acceptEncoding = request.getHeader("Accept-Encoding"); > + return (acceptEncoding != null) && > (acceptEncoding.indexOf("gzip") != -1); > + } > } > > File [changed]: ResponseContent.java > Url: > https://oscache.dev.java.net/source/browse/oscache/src/core/java/com/ope ns > ymphony/oscache/web/filter/ResponseContent.java?r1=1.3&r2=1.4 > Delta lines: +59 -8 > -------------------- > --- ResponseContent.java 22 Feb 2005 17:17:02 -0000 1.3 > +++ ResponseContent.java 21 Mar 2005 22:29:55 -0000 1.4 > @@ -6,9 +6,14 @@ > > import java.io.*; > > +import java.util.Enumeration; > import java.util.Locale; > +import java.util.zip.GZIPInputStream; > +import java.util.zip.ZipException; > > +import javax.servlet.ServletRequest; > import javax.servlet.ServletResponse; > +import javax.servlet.http.HttpServletRequest; > import javax.servlet.http.HttpServletResponse; > > /** > @@ -16,16 +21,17 @@ > * in the cache (and, since this class is serializable, optionally > * persisted to disk). > * > - * @version $Revision: 1.3 $ > + * @version $Revision: 1.4 $ > * @author <a href="mailto:[email protected]">Serge Knystautas</a> > */ > public class ResponseContent implements Serializable { > private transient ByteArrayOutputStream bout = new > ByteArrayOutputStream(1000); > private Locale locale = null; > + private String contentEncoding = null; > private String contentType = null; > private byte[] content = null; > - private long lastModified = -1; > private long expires = Long.MAX_VALUE; > + private long lastModified = -1; > > /** > * Set the content type. We capture this so that when we serve this > @@ -43,6 +49,10 @@ > lastModified = value; > } > > + public void setContentEncoding(String contentEncoding) { > + this.contentEncoding = contentEncoding; > + } > + > /** > * Set the Locale. We capture this so that when we serve this data > from > * cache, we can set the correct locale on the response. > @@ -100,7 +110,7 @@ > * @throws IOException > */ > public void writeTo(ServletResponse response) throws IOException { > - writeTo(response, false); > + writeTo(response, false, false); > } > > /** > @@ -108,27 +118,68 @@ > * > * @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 acceptsGZip is true if client browser supports gzip > compression > * @throws IOException > */ > - public void writeTo(ServletResponse response, boolean fragment) > throws IOException { > + public void writeTo(ServletResponse response, boolean fragment, > boolean acceptsGZip) throws IOException { > //Send the content type and data to this response > if (contentType != null) { > response.setContentType(contentType); > } > > + // Don't support gzip compression if the content is a fragment of > a page > + if (fragment) { > + acceptsGZip = false; > + } > + > // Don't add in the Last-Modified header in a fragment of a page > if ((!fragment) && (response instanceof HttpServletResponse)) { > ((HttpServletResponse) > response).setDateHeader(CacheFilter.HEADER_LAST_MODIFIED, lastModified); > } > > - response.setContentLength(content.length); > - > if (locale != null) { > response.setLocale(locale); > } > > OutputStream out = new > BufferedOutputStream(response.getOutputStream()); > + > + if (isContentGZiped()) { > + if (acceptsGZip) { > + ((HttpServletResponse) response).addHeader("Content- > Encoding", "gzip"); > + response.setContentLength(content.length); > + out.write(content); > + } 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[4196]; > + > + 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); > + } > + } else { > + // the content isn't compressed > + // regardless if the client browser supports gzip we will > just return the content > + response.setContentLength(content.length); > out.write(content); > + } > out.flush(); > + } > + > + > + /** > + * @return true if the content is GZIP compressed > + */ > + public boolean isContentGZiped() { > + return "gzip".equals(contentEncoding); > } > } > > File [changed]: CacheHttpServletResponseWrapper.java > Url: > https://oscache.dev.java.net/source/browse/oscache/src/core/java/com/ope ns > ymphony/oscache/web/filter/CacheHttpServletResponseWrapper.java?r1=1.6&r 2= > 1.7 > Delta lines: +18 -9 > -------------------- > --- CacheHttpServletResponseWrapper.java 23 Feb 2005 17:55:29 -0000 > 1.6 > +++ CacheHttpServletResponseWrapper.java 21 Mar 2005 22:29:55 -0000 > 1.7 > @@ -20,7 +20,7 @@ > * CacheServletResponse is a serialized representation of a response > * > * @author <a href="mailto:[email protected]">Serge Knystautas</a> > - * @version $Revision: 1.6 $ > + * @version $Revision: 1.7 $ > */ > public class CacheHttpServletResponseWrapper extends > HttpServletResponseWrapper { > private final Log log = LogFactory.getLog(this.getClass()); > @@ -32,8 +32,8 @@ > private PrintWriter cachedWriter; > private ResponseContent result = null; > private SplitServletOutputStream cacheOut = null; > - private int status = SC_OK; > private boolean fragment = false; > + private int status = SC_OK; > > /** > * Constructor > @@ -77,6 +77,7 @@ > if (log.isDebugEnabled()) { > log.debug("ContentType: " + value); > } > + > super.setContentType(value); > result.setContentType(value); > } > @@ -144,6 +145,10 @@ > result.setContentType(value); > } > > + if (CacheFilter.HEADER_CONTENT_ENCODING.equalsIgnoreCase(name)) { > + result.setContentEncoding(value); > + } > + > super.setHeader(name, value); > } > > @@ -162,6 +167,10 @@ > result.setContentType(value); > } > > + if (CacheFilter.HEADER_CONTENT_ENCODING.equalsIgnoreCase(name)) { > + result.setContentEncoding(value); > + } > + > super.addHeader(name, value); > } > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected]