Index: StringUtil.java =================================================================== retrieving revision 1.2 diff -u -r1.2 StringUtil.java --- StringUtil.java 4 Nov 2003 20:06:12 -0000 1.2 +++ StringUtil.java 3 Dec 2003 22:34:04 -0000 @@ -42,4 +42,27 @@ return parts; } + + /** + * Given a string src, replaces all instances of oldStr with newStr. + * + * @param src The string to replace in + * @param oldStr The string to replace + * @param newStr The string to replace with + * @return A string with all instances of oldStr replaced with newStr + */ + public static String replace(String src, String oldStr, String newStr) { + StringBuffer buf = new StringBuffer(src.length()); + + int from = 0; + int to = 0; + + while ((to = src.indexOf(oldStr, from)) != -1) { + buf.append(src.substring(from, to)).append(newStr); + from = to + oldStr.length(); + } + + buf.append(src.substring(from)); + return buf.toString(); + } } Index: src/core/java/com/opensymphony/oscache/util/SessionIdUtil.java =================================================================== RCS file: src/core/java/com/opensymphony/oscache/util/SessionIdUtil.java diff -N src/core/java/com/opensymphony/oscache/util/SessionIdUtil.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/core/java/com/opensymphony/oscache/util/SessionIdUtil.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2002-2003 by OpenSymphony + * All rights reserved. + */ +package com.opensymphony.oscache.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author Alex Burgel + * + * @version $\Id$ + * + */ +public class SessionIdUtil { + private static transient Log log = LogFactory.getLog(SessionIdUtil.class); + private static final String TOKEN = "${JSESSION}"; + + public static String encode(HttpServletRequest request, String content) { + if ((request.getSession(false) == null) || request.isRequestedSessionIdFromCookie()) { + log.debug("not encoding session ids"); + return content; + } else { + log.debug("encoding session ids"); + return tokenizeSessionId(content); + } + } + + public static String decode(HttpServletRequest request, String content, String key) { + if (key.indexOf("jsession") > 0) { + log.debug("decoding session ids"); + + String sessionId = ";jsessionid=" + request.getSession().getId(); + return StringUtil.replace(content, TOKEN, sessionId); + } else { + log.debug("not decoding session ids"); + return content; + } + } + + private static String tokenizeSessionId(String content) { + StringBuffer buf = new StringBuffer(content.length()); + + int from = 0; + int to = 0; + + while ((to = content.indexOf(";jsessionid=", from)) != -1) { + buf.append(content.substring(from, to)).append(TOKEN); + + int i = to + 12; + + for (; i < content.length(); i++) { + if (!Character.isLetterOrDigit(content.charAt(i))) { + break; + } + } + + from = i; + } + + buf.append(content.substring(from)); + + return buf.toString(); + } +} Index: ServletCacheAdministrator.java =================================================================== retrieving revision 1.6 diff -u -r1.6 ServletCacheAdministrator.java --- ServletCacheAdministrator.java 6 Sep 2003 08:06:29 -0000 1.6 +++ ServletCacheAdministrator.java 3 Dec 2003 22:34:26 -0000 @@ -45,6 +45,7 @@ * Constants for properties read/written from/to file */ private final static String CACHE_USE_HOST_DOMAIN_KEY = "cache.use.host.domain.in.key"; + private final static String CACHE_USE_SESSION_FLAG_KEY = "cache.use.session.flag.in.key"; private final static String CACHE_KEY_KEY = "cache.key"; /** @@ -123,6 +124,12 @@ private boolean useHostDomainInKey = false; /** + * Set property cache.use.session.flag.in.key=true to add a flag to key + * indicating a page might contain session IDs encoded in URLs. + */ + private boolean useSessionFlagInKey = false; + + /** * Create the cache administrator. * * This will reset all the flush times and load the properties file. @@ -134,6 +141,7 @@ //this.context = context; flushTimes = new HashMap(); initHostDomainInKey(); + initSessionFlagInKey(); if (log.isInfoEnabled()) { log.info("Constructed ServletCacheAdministrator()"); @@ -207,6 +215,10 @@ } } + public boolean encodeSessionIds() { + return useSessionFlagInKey; + } + /** * Grabs the cache for the specified scope * @@ -502,6 +514,11 @@ cBuffer.append(FILE_SEPARATOR).append(request.getServerName()); } + // For pages that might have session ids encoded in within URLs + if (useSessionFlagInKey && !request.isRequestedSessionIdFromCookie() && (request.getSession(false) != null)) { + cBuffer.append(FILE_SEPARATOR).append("jsession"); + } + if (key != null) { cBuffer.append(FILE_SEPARATOR).append(key); } else { @@ -747,5 +764,15 @@ String propStr = getProperty(CACHE_USE_HOST_DOMAIN_KEY); useHostDomainInKey = "true".equalsIgnoreCase(propStr); + } + + /** + * Set property cache.use.host.domain.in.key=true to add domain information to key + * generation for hosting multiple sites + */ + private void initSessionFlagInKey() { + String propStr = getProperty(CACHE_USE_SESSION_FLAG_KEY); + + useSessionFlagInKey = "true".equalsIgnoreCase(propStr); } } Index: tag/CacheTag.java =================================================================== retrieving revision 1.4 diff -u -r1.4 CacheTag.java --- tag/CacheTag.java 4 Nov 2003 20:05:24 -0000 1.4 +++ tag/CacheTag.java 3 Dec 2003 22:34:26 -0000 @@ -6,6 +6,7 @@ import com.opensymphony.oscache.base.Cache; import com.opensymphony.oscache.base.NeedsRefreshException; +import com.opensymphony.oscache.util.SessionIdUtil; import com.opensymphony.oscache.util.StringUtil; import com.opensymphony.oscache.web.ServletCacheAdministrator; import com.opensymphony.oscache.web.WebEntryRefreshPolicy; @@ -356,12 +357,21 @@ cancelUpdateRequired = false; + // encode session ids in content + String bodyEncoded; + + if (admin.encodeSessionIds()) { + bodyEncoded = SessionIdUtil.encode((HttpServletRequest) pageContext.getRequest(), body); + } else { + bodyEncoded = body; + } + if ((groups == null) || groups.isEmpty()) { - cache.putInCache(actualKey, body, policy); + cache.putInCache(actualKey, bodyEncoded, policy); } else { String[] groupArray = new String[groups.size()]; groups.toArray(groupArray); - cache.putInCache(actualKey, body, groupArray, policy, null); + cache.putInCache(actualKey, bodyEncoded, groupArray, policy, null); } } } @@ -372,7 +382,8 @@ log.info(": Using cached version as instructed, useBody = false : " + actualKey); } - body = content; + // decode encoded session ids in content + body = SessionIdUtil.decode((HttpServletRequest) pageContext.getRequest(), content, actualKey); } // either the cached entry is blank and a subtag has said don't useBody, or body is null else { @@ -480,6 +491,11 @@ } else { // Use the specified refresh period content = (String) cache.getFromCache(actualKey, time, cron); + } + + // decode the encoded session ids in the content + if (admin.encodeSessionIds()) { + content = SessionIdUtil.decode((HttpServletRequest) pageContext.getRequest(), content, actualKey); } try {