[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]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.