Save This Page
Home » oscache-2.4.1-full » com.opensymphony.oscache » web » filter » [javadoc | source]
    1   /*
    2    * Copyright (c) 2002-2003 by OpenSymphony
    3    * All rights reserved.
    4    */
    5   package com.opensymphony.oscache.web.filter;
    6   
    7   import java.io;
    8   
    9   import java.util.Locale;
   10   import java.util.zip.GZIPInputStream;
   11   
   12   import javax.servlet.ServletResponse;
   13   import javax.servlet.http.HttpServletResponse;
   14   
   15   /**
   16    * Holds the servlet response in a byte array so that it can be held
   17    * in the cache (and, since this class is serializable, optionally
   18    * persisted to disk).
   19    *
   20    * @version $Revision: 362 $
   21    * @author  <a href="mailto:sergek@lokitech.com">Serge Knystautas</a>
   22    */
   23   public class ResponseContent implements Serializable {
   24       private transient ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
   25       private Locale locale = null;
   26       private String contentEncoding = null;
   27       private String contentType = null;
   28       private byte[] content = null;
   29       private long expires = Long.MAX_VALUE;
   30       private long lastModified = -1;
   31       private long maxAge = -60;
   32   
   33       public String getContentType() {
   34           return contentType;
   35       }
   36       
   37       /**
   38        * Set the content type. We capture this so that when we serve this
   39        * data from cache, we can set the correct content type on the response.
   40        */
   41       public void setContentType(String value) {
   42           contentType = value;
   43       }
   44   
   45       public long getLastModified() {
   46           return lastModified;
   47       }
   48   
   49       public void setLastModified(long value) {
   50           lastModified = value;
   51       }
   52   
   53       public String getContentEncoding() {
   54           return contentEncoding;
   55       }
   56   
   57       public void setContentEncoding(String contentEncoding) {
   58           this.contentEncoding = contentEncoding;
   59       }
   60   
   61       /**
   62        * Set the Locale. We capture this so that when we serve this data from
   63        * cache, we can set the correct locale on the response.
   64        */
   65       public void setLocale(Locale value) {
   66           locale = value;
   67       }
   68   
   69       /**
   70        * @return the expires date and time in miliseconds when the content will be stale
   71        */
   72       public long getExpires() {
   73           return expires;
   74       }
   75   
   76       /**
   77        * Sets the expires date and time in miliseconds.
   78        * @param value time in miliseconds when the content will expire
   79        */
   80       public void setExpires(long value) {
   81           expires = value;
   82       }
   83   
   84   	/**
   85   	 * Returns the max age of the content in miliseconds. If expires header and cache control are
   86   	 * enabled both, both will be equal. 
   87   	 * @return the max age of the content in miliseconds, if -1 max-age is disabled
   88   	 */
   89   	public long getMaxAge() {
   90   		return maxAge;
   91   	}
   92   
   93   	/**
   94   	 * Sets the max age date and time in miliseconds. If the parameter is -1, the max-age parameter
   95   	 * won't be set by default in the Cache-Control header.
   96   	 * @param value sets the intial
   97   	 */
   98   	public void setMaxAge(long value) {
   99   		maxAge = value;
  100   	}
  101   
  102       /**
  103        * Get an output stream. This is used by the {@link SplitServletOutputStream}
  104        * to capture the original (uncached) response into a byte array.
  105        * @return the original (uncached) response, returns null if response is already committed.
  106        */
  107       public OutputStream getOutputStream() {
  108           return bout;
  109       }
  110   
  111       /**
  112        * Gets the size of this cached content.
  113        *
  114        * @return The size of the content, in bytes. If no content
  115        * exists, this method returns <code>-1</code>.
  116        */
  117       public int getSize() {
  118           return (content != null) ? content.length : (-1);
  119       }
  120   
  121       /**
  122        * Called once the response has been written in its entirety. This
  123        * method commits the response output stream by converting the output
  124        * stream into a byte array.
  125        */
  126       public void commit() {
  127           if (bout != null) {
  128               content = bout.toByteArray();
  129               bout = null;
  130           }
  131       }
  132   
  133       /**
  134        * Writes this cached data out to the supplied <code>ServletResponse</code>.
  135        *
  136        * @param response The servlet response to output the cached content to.
  137        * @throws IOException
  138        */
  139       public void writeTo(ServletResponse response) throws IOException {
  140           writeTo(response, false, false);
  141       }
  142   
  143       /**
  144        * Writes this cached data out to the supplied <code>ServletResponse</code>.
  145        *
  146        * @param response The servlet response to output the cached content to.
  147        * @param fragment is true if this content a fragment or part of a page
  148        * @param acceptsGZip is true if client browser supports gzip compression
  149        * @throws IOException
  150        */
  151       public void writeTo(ServletResponse response, boolean fragment, boolean acceptsGZip) throws IOException {
  152           //Send the content type and data to this response
  153           if (contentType != null) {
  154               response.setContentType(contentType);
  155           }
  156           
  157           if (fragment) {
  158               // Don't support gzip compression if the content is a fragment of a page
  159               acceptsGZip = false;
  160           } else {
  161               // add special headers for a complete page
  162               if (response instanceof HttpServletResponse) {
  163                   HttpServletResponse httpResponse = (HttpServletResponse) response;
  164                   
  165                   // add the last modified header
  166                   if (lastModified != -1) {
  167                       httpResponse.setDateHeader(CacheFilter.HEADER_LAST_MODIFIED, lastModified);
  168                   }
  169                   
  170                   // add the expires header
  171                   if (expires != Long.MAX_VALUE) {
  172                       httpResponse.setDateHeader(CacheFilter.HEADER_EXPIRES, expires);
  173                   }
  174                   
  175                   // add the cache-control header for max-age
  176                   if (maxAge == CacheFilter.MAX_AGE_NO_INIT || maxAge == CacheFilter.MAX_AGE_TIME) {
  177                   	// do nothing
  178                   } else if (maxAge > 0) { // set max-age based on life time
  179                   	long currentMaxAge = maxAge / 1000 - System.currentTimeMillis() / 1000;
  180                   	if (currentMaxAge < 0) {
  181                   		currentMaxAge = 0;
  182                   	}
  183                   	httpResponse.addHeader(CacheFilter.HEADER_CACHE_CONTROL, "max-age=" + currentMaxAge);
  184                   } else {
  185                   	httpResponse.addHeader(CacheFilter.HEADER_CACHE_CONTROL, "max-age=" + (-maxAge));
  186                   }
  187                   
  188               }
  189           }
  190   
  191           if (locale != null) {
  192               response.setLocale(locale);
  193           }
  194   
  195           OutputStream out = new BufferedOutputStream(response.getOutputStream());
  196   
  197           if (isContentGZiped()) {
  198               if (acceptsGZip) {
  199                   ((HttpServletResponse) response).addHeader(CacheFilter.HEADER_CONTENT_ENCODING, "gzip");
  200                   response.setContentLength(content.length);
  201                   out.write(content);
  202               } else {
  203                   // client doesn't support, so we have to uncompress it
  204                   ByteArrayInputStream bais = new ByteArrayInputStream(content);
  205                   GZIPInputStream zis = new GZIPInputStream(bais);
  206   
  207                   ByteArrayOutputStream baos = new ByteArrayOutputStream();
  208                   int numBytesRead = 0;
  209                   byte[] tempBytes = new byte[4196];
  210   
  211                   while ((numBytesRead = zis.read(tempBytes, 0, tempBytes.length)) != -1) {
  212                       baos.write(tempBytes, 0, numBytesRead);
  213                   }
  214   
  215                   byte[] result = baos.toByteArray();
  216   
  217                   response.setContentLength(result.length);
  218                   out.write(result);
  219               }
  220           } else {
  221               // the content isn't compressed
  222               // regardless if the client browser supports gzip we will just return the content
  223               response.setContentLength(content.length);
  224               out.write(content);
  225           }
  226           out.flush();
  227       }
  228       
  229       
  230       /**
  231        * @return true if the content is GZIP compressed
  232        */
  233       public boolean isContentGZiped() {
  234           return "gzip".equals(contentEncoding);
  235       }
  236   
  237   }

Save This Page
Home » oscache-2.4.1-full » com.opensymphony.oscache » web » filter » [javadoc | source]