Anonymous avatar Anonymous committed f32f3fc

Option to specify when to send Expires-Header

Issue number: CACHE-196
Submitted by: Lars Torunski

Comments (0)

Files changed (2)

src/java/com/opensymphony/oscache/web/filter/CacheFilter.java

     public static final int FRAGMENT_NO = 0;
     public static final int FRAGMENT_YES = 1;
     
-    // No cache options
+    // No cache parameter
     public static final int NOCACHE_OFF = 0;
     public static final int NOCACHE_SESSION_ID_IN_URL = 1;
+    
+    // Expires parameter
+    public static final long EXPIRES_OFF = 0;
+    public static final long EXPIRES_ON = 1;
+    public static final long EXPIRES_TIME = -1;
 
     // request attribute to avoid reentrance
     private final static String REQUEST_FILTERED = "__oscache_filtered";
     private int fragment = FRAGMENT_AUTODETECT; // defines if this filter handles fragments of a page - default is auto detect
     private int time = 60 * 60; // time before cache should be refreshed - default one hour (in seconds)
     private int nocache = NOCACHE_OFF; // defines special no cache option for the requests - default is off
+    private long expires = EXPIRES_ON; // defines if the expires-header will be sent - default is on
     private ICacheKeyProvider cacheKeyProvider = this; // the provider of the cache key - default is the CacheFilter itselfs
     private ICacheGroupsProvider cacheGroupsProvider = this; // the provider of the cache groups - default is the CacheFilter itselfs
 
                     log.info("<cache>: New cache entry, cache stale or cache scope flushed for " + key);
                 }
 
-                CacheHttpServletResponseWrapper cacheResponse = new CacheHttpServletResponseWrapper((HttpServletResponse) response, fragmentRequest, time * 1000);
+                CacheHttpServletResponseWrapper cacheResponse = new CacheHttpServletResponseWrapper((HttpServletResponse) response, fragmentRequest, time * 1000, expires);
                 chain.doFilter(request, cacheResponse);
                 cacheResponse.flushBuffer();
 
      * instance and configures the filter based on any initialization parameters.<p>
      * The supported initialization parameters are:
      * <ul>
+     * 
      * <li><b>time</b> - the default time (in seconds) to cache content for. The default
      * value is 3600 seconds (one hour).</li>
+     * 
      * <li><b>scope</b> - the default scope to cache content in. Acceptable values
      * are <code>application</code> (default), <code>session</code>, <code>request</code> and
-     * <code>page</code>.
+     * <code>page</code>.</li>
+     * 
      * <li><b>fragment</b> - defines if this filter handles fragments of a page. Acceptable values
-     * are <code>-1</code> (auto detect), <code>0</code> (false) and <code>1</code> (true).
-     * The default value is auto detect.</li>
+     * are <code>auto</code> (default) for auto detect, <code>no</code> and <code>yes</code>.</li>
+     * 
      * <li><b>nocache</b> - defines which objects shouldn't be cached. Acceptable values
      * are <code>off</code> (default) and <code>sessionIdInURL</code> if the session id is
      * contained in the URL.</li>
+     * 
+     * <li><b>expires</b> - defines if the expires header will be sent in the response. Acceptable values are
+     * <code>off</code> for don't sending the header, even it is set in the filter chain, 
+     * <code>on</code> (default) for sending it if it is set in the filter chain and 
+     * <code>time</code> the expires information will be intialized based on the time parameter and creation time of the content.</li>
+     * 
      * <li><b>ICacheKeyProvider</b> - Class implementing the interface <code>ICacheKeyProvider</code>.
      * A developer can implement a method which provides cache keys based on the request, 
      * the servlect cache administrator and cache.</li>
+     * 
      * <li><b>ICacheGroupsProvider</b> - Class implementing the interface <code>ICacheGroupsProvider</code>.
      * A developer can implement a method which provides cache groups based on the request, 
      * the servlect cache administrator and cache.</li>
 
         // filter parameter fragment
         try {
-            fragment = Integer.parseInt(config.getInitParameter("fragment"));
+            String fragmentString = config.getInitParameter("fragment");
+            
+            if (fragmentString.equals("no")) {
+                fragment = FRAGMENT_NO;
+            } else if (fragmentString.equals("yes")) {
+                fragment = FRAGMENT_YES;
+            } else if (fragmentString.equalsIgnoreCase("auto")) {
+                fragment = FRAGMENT_AUTODETECT;
+            } else {
+                // FIXME in 2.2 RC the values were -1, 0. In 2.2.1 or >= 2.3 delete this code
+                try {
+                    fragment = Integer.parseInt(fragmentString);
 
-            if ((fragment < FRAGMENT_AUTODETECT) || (fragment > FRAGMENT_YES)) {
-                log.info("Wrong init parameter 'fragment', setting to 'auto detect':" + fragment);
-                fragment = FRAGMENT_AUTODETECT;
+                    if ((fragment < FRAGMENT_AUTODETECT) || (fragment > FRAGMENT_YES)) {
+                        log.info("Wrong init parameter 'fragment', setting to 'auto detect': " + fragment);
+                        fragment = FRAGMENT_AUTODETECT;
+                    }
+                    
+                    log.warn("The used value '" + fragmentString + "' for the fragment parameter is deprecated.");
+                } catch (Exception e2) {
+                    log.info("Could not get init parameter 'fragment', defaulting to 'auto detect'.");
+                }
+                // end of deletion
             }
         } catch (Exception e) {
             log.info("Could not get init parameter 'fragment', defaulting to 'auto detect'.");
             log.info("Could not get init parameter 'nocache', defaulting to 'off'.");
         }
 
+        // filter parameter expires
+        try {
+            String expiresString = config.getInitParameter("expires");
+            
+            if (expiresString.equals("off")) {
+                expires = EXPIRES_OFF;
+            } else if (expiresString.equals("on")) {
+                expires = EXPIRES_ON;
+            } else if (expiresString.equalsIgnoreCase("time")) {
+                expires = EXPIRES_TIME;
+            } 
+        } catch (Exception e) {
+            log.info("Could not get init parameter 'expires', defaulting to 'on'.");
+        }
+
         // filter parameter ICacheKeyProvider
         try {
             String className = config.getInitParameter("ICacheKeyProvider");
                 log.error("Class '" + className + "' could not be instantiated because it is not public. Ignoring this cache groups provider.", e);
             }
         } catch (Exception e) {
-            log.info("Could not get init parameter 'ICacheKeyProvider', defaulting to " + this.getClass().getName() + ".");
+            log.info("Could not get init parameter 'ICacheGroupsProvider', defaulting to " + this.getClass().getName() + ".");
         }
     }
 

src/java/com/opensymphony/oscache/web/filter/CacheHttpServletResponseWrapper.java

     private SplitServletOutputStream cacheOut = null;
     private boolean fragment = false;
     private int status = SC_OK;
+    private long expires = CacheFilter.EXPIRES_ON;
 
     /**
      * Constructor
      * @param response The servlet response
      */
     public CacheHttpServletResponseWrapper(HttpServletResponse response) {
-        this(response, false, Long.MAX_VALUE);
+        this(response, false, Long.MAX_VALUE, CacheFilter.EXPIRES_ON);
     }
 
     /**
      * @param response The servlet response
      * @param fragment true if the repsonse indicates that it is a fragement of a page
      * @param time the refresh time in millis
+     * @param expires defines if expires header will be send, @see CacheFilter
      */
-    public CacheHttpServletResponseWrapper(HttpServletResponse response, boolean fragment, long time) {
+    public CacheHttpServletResponseWrapper(HttpServletResponse response, boolean fragment, long time, long expires) {
         super(response);
         result = new ResponseContent();
         this.fragment = fragment;
+        this.expires = expires;
         
         // only set the last modified value, if a complete page is cached
         if (!fragment) {
             result.setLastModified(current * 1000);
             super.setDateHeader(CacheFilter.HEADER_LAST_MODIFIED, result.getLastModified());
             // setting the expires value
-            result.setExpires(result.getLastModified() + time);
-            super.setDateHeader(CacheFilter.HEADER_EXPIRES, result.getExpires());
+            if (expires == CacheFilter.EXPIRES_TIME) {
+                result.setExpires(result.getLastModified() + time);
+                super.setDateHeader(CacheFilter.HEADER_EXPIRES, result.getExpires());
+            }
         }
     }
 
         }
 
         // implement RFC 2616 14.21 Expires (without max-age)
-        if (CacheFilter.HEADER_EXPIRES.equalsIgnoreCase(name)) {
+        if ((expires != CacheFilter.EXPIRES_OFF) && (CacheFilter.HEADER_EXPIRES.equalsIgnoreCase(name))) {
             result.setExpires(value);
         }
 
         }
 
         // implement RFC 2616 14.21 Expires (without max-age)
-        if (CacheFilter.HEADER_EXPIRES.equalsIgnoreCase(name)) {
+        if ((expires != CacheFilter.EXPIRES_OFF) && (CacheFilter.HEADER_EXPIRES.equalsIgnoreCase(name))) {
             result.setExpires(value);
         }
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.