001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.filters;
030:
031: import com.caucho.config.types.Period;
032:
033: import javax.servlet.Filter;
034: import javax.servlet.FilterChain;
035: import javax.servlet.FilterConfig;
036: import javax.servlet.ServletException;
037: import javax.servlet.ServletRequest;
038: import javax.servlet.ServletResponse;
039: import javax.servlet.http.HttpServletResponse;
040: import java.io.IOException;
041:
042: /**
043: * Caches the servlet output for anonymous users. This filter adds
044: * an Expires header and the Cache-Control: x-anonymous header.
045: *
046: * <p>Requests from anonymous users, i.e. users with no JSESSIONID cookie
047: * or ;jsessionid= URL-rewriting, will be cached. So logged-in users
048: * will have customized pages, but anonymous users will see a cached page.
049: * Since there are generally more anonymous users, using the
050: * AnonymousExpiresFilter can dramatically improve performance without
051: * losing the ability to customize pages.
052: *
053: * <p>Pages should call <code>request.getSession(false)</code> to get their
054: * sessions, because a page that creates a session will not be cached.
055: * For the same reason, JSP pages would set
056: * <code><jsp:directive.page session='false'/></code>.
057: *
058: * <p>The cache-time init-parameter configures how long the page should be
059: * cached:
060: *
061: * <pre>
062: * <filter>
063: * <filter-name>anonymous-cache</filter-name>
064: * <filter-class>com.caucho.http.filter.AnonymousExpiresFilter</filter-class>
065: * <init-param cache-time='10s'/>
066: * </filter>
067: * </pre>
068: *
069: * The cache-time allows the standard extensions:
070: *
071: * <table>
072: * <tr><td>s<td>seconds
073: * <tr><td>m<td>minutes
074: * <tr><td>h<td>hours
075: * <tr><td>D<td>days
076: * <tr><td>W<td>weeks
077: * <tr><td>M<td>months
078: * <tr><td>Y<td>years
079: * </table>
080: *
081: * @since Resin 2.0.5
082: */
083: public class AnonymousExpiresFilter implements Filter {
084: /**
085: * How long to cache the file for.
086: */
087: private long _cacheTime = 2000;
088:
089: /**
090: * Sets the file cache time.
091: */
092: public void setCacheTime(Period period) {
093: _cacheTime = period.getPeriod();
094: }
095:
096: /**
097: * Filter init reads the filter configuration
098: */
099: public void init(FilterConfig config) throws ServletException {
100: String time = config.getInitParameter("cache-time");
101:
102: if (time != null) {
103: try {
104: _cacheTime = Period.toPeriod(time);
105: } catch (Exception e) {
106: throw new ServletException(e);
107: }
108: }
109: }
110:
111: /**
112: * The filter add an Expires time in the future and adds
113: * the x-anonymous Cache-Control directive.
114: */
115: public void doFilter(ServletRequest request,
116: ServletResponse response, FilterChain nextFilter)
117: throws ServletException, IOException {
118: if (_cacheTime > 0) {
119: HttpServletResponse res = (HttpServletResponse) response;
120:
121: res.addHeader("Vary", "Cookie");
122: res.addHeader("Cache-Control", "s-maxage=" + _cacheTime);
123: }
124:
125: nextFilter.doFilter(request, response);
126: }
127:
128: /**
129: * Any cleanup for the filter.
130: */
131: public void destroy() {
132: }
133: }
|