Hello :) This patch adds support for configuring session cookie domain and path parameter on per-context basis.
Configuration is done by editing META-INF/context.xml <Context sessionCookiePath="/something" sessionCookieDomain=".domain.tld" /> Applies to 6.0.20. Best regards, Brane
Index: java/org/apache/catalina/core/StandardContext.java =================================================================== --- java/org/apache/catalina/core/StandardContext.java (revision 832150) +++ java/org/apache/catalina/core/StandardContext.java (working copy) @@ -289,8 +289,22 @@ */ private boolean cookies = true; + /** + * Cookie domain for session cookies + `*/ + private String sessionCookieDomain = null; /** + * Forced path for session cookies + */ + private String sessionCookiePath = null; + + /** + * Forced session cookie name + */ + private String sessionCookieName = null; + + /** * Should we allow the <code>ServletContext.getContext()</code> method * to access the context of other web applications in this server? */ @@ -1149,9 +1163,65 @@ } + /** + * Returns cookie domain for session (JSESSIONID) cookies + */ + public String getSessionCookieDomain() { + return sessionCookieDomain; + } + /** + * Sets cookie domain for session (JSESSIONID) cookies + * @param domain session cookie domain name + */ + public void setSessionCookieDomain(String domain) { + if (domain == null || domain.length() < 1) { + throw new IllegalArgumentException("Session cookie domain name cannot be zero-length string."); + } + sessionCookieDomain = domain.trim(); + } /** + * Returns forced session cookie path + */ + public String getSessionCookiePath() { + return sessionCookiePath; + } + + /** + * Returns session cookie name for application context. + */ + public String getSessionCookieName() { + if (sessionCookieName != null) { + return sessionCookieName; + } + return Globals.SESSION_COOKIE_NAME; + } + + /** + * Sets session cookie name for application context + * + * @param name Session cookie name + */ + public void setSessionCookieName(String name) { + if (name == null || name.length() < 1) { + throw new IllegalArgumentException("Session cookie name cannot be zero-length string."); + } + sessionCookieName = name; + } + + /** + * Sets forced session cookie path; + * @param String forced session cookie path. + */ + public void setSessionCookiePath(String forcedPath) { + if (forcedPath == null || forcedPath.length() < 1 || forcedPath.charAt(0) != '/') { + throw new IllegalArgumentException("Session cookie path must be non-zero string starting with / character."); + } + sessionCookiePath = forcedPath; + } + + /** * Return the "allow crossing servlet contexts" flag. */ public boolean getCrossContext() { Index: java/org/apache/catalina/connector/Request.java =================================================================== --- java/org/apache/catalina/connector/Request.java (revision 832150) +++ java/org/apache/catalina/connector/Request.java (working copy) @@ -1663,7 +1663,6 @@ * @param id The new session id */ public void setRequestedSessionId(String id) { - this.requestedSessionId = id; } @@ -2290,6 +2289,24 @@ manager = context.getManager(); if (manager == null) return (null); // Sessions are not supported + + // get context session cookie name and possibly override + // currently set requestedSessionId + String scn = context.getSessionCookieName(); + if (scn != null && ! scn.equals(Globals.SESSION_COOKIE_NAME)) { + // try to fetch cookie scn + Cookie cs[] = getCookies(); + if (cs != null) { + for (Cookie c: cs) { + if (c != null && scn.equals(c.getName())) { + // override requested session id value + requestedSessionId = c.getValue(); + break; + } + } + } + } + if (requestedSessionId != null) { try { session = manager.findSession(requestedSessionId); @@ -2327,7 +2344,7 @@ // Creating a new session cookie based on that session if ((session != null) && (getContext() != null) && getContext().getCookies()) { - Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME, + Cookie cookie = new Cookie(getContext().getSessionCookieName(), session.getIdInternal()); configureSessionCookie(cookie); response.addCookieInternal(cookie, context.getUseHttpOnly()); @@ -2349,18 +2366,39 @@ */ protected void configureSessionCookie(Cookie cookie) { cookie.setMaxAge(-1); - String contextPath = null; - if (!connector.getEmptySessionPath() && (getContext() != null)) { - contextPath = getContext().getEncodedPath(); + + String cookiePath = null; + String cookieDomain = null; + + // check for forced cookie domain and path if we have + // valid context object + if (context != null) { + cookiePath = context.getSessionCookiePath(); + cookieDomain = context.getSessionCookieDomain(); } - if ((contextPath != null) && (contextPath.length() > 0)) { - cookie.setPath(contextPath); - } else { - cookie.setPath("/"); + + if (cookiePath == null) { + // nope, just standard context path + if (!connector.getEmptySessionPath() && (getContext() != null)) { + cookiePath = getContext().getEncodedPath(); + } } + // nothing? set root path... + if (cookiePath == null || cookiePath.length() < 1) { + cookiePath = "/"; + } + + // set cookie path + cookie.setPath(cookiePath); + if (isSecure()) { cookie.setSecure(true); } + + // set cookie domain if necessary + if (cookieDomain != null) { + cookie.setDomain(cookieDomain); + } } protected String unescape(String s) { Index: java/org/apache/catalina/Context.java =================================================================== --- java/org/apache/catalina/Context.java (revision 832150) +++ java/org/apache/catalina/Context.java (working copy) @@ -197,6 +197,41 @@ * for session cookies */ public void setUseHttpOnly(boolean useHttpOnly); + + /** + * Returns cookie domain for session (JSESSIONID) cookies + */ + public String getSessionCookieDomain(); + + /** + * Sets cookie domain for session (JSESSIONID) cookies + * @param domain session cookie domain name + */ + public void setSessionCookieDomain(String domain); + + /** + * Returns forced session cookie path + */ + public String getSessionCookiePath(); + + /** + * Sets forced session cookie path; + * @param String forced session cookie path. + */ + public void setSessionCookiePath(String forcedPath); + + /** + * Returns session cookie name for application context. + */ + public String getSessionCookieName(); + + /** + * Sets session cookie name for application context + * + * @param name Session cookie name + */ + public void setSessionCookieName(String name); + /** * Return the "allow crossing servlet contexts" flag. Index: webapps/docs/config/context.xml =================================================================== --- webapps/docs/config/context.xml (revision 832150) +++ webapps/docs/config/context.xml (working copy) @@ -188,6 +188,28 @@ sufficient.</p> </attribute> + <attribute name="sessionCookieDomain" required="false"> + <p>This Context attribute specifies JSESSION cookie domain parameter for + issued session cookies. Default value is empty, meaning that domain parameter + will not be added to issued session cookies. + </p> + </attribute> + + <attribute name="sessionCookiePath" required="false"> + <p>Set this attribute only if you know what you're doing; This + attribute overrides Path attribute for issued session cookie. Normaly + session cookie path is set to value of context path. + Setting this parameter if you have other webserver in front of Tomcat + and webapp is mounted on other context path than on Tomcat. + </p> + </attribute> + + <attribute name="sessionCookieName" required="false"> + <p>Set this attribute if you want to change name of issued session + cookies. Default is JSESSIONID. + </p> + </attribute> + <attribute name="privileged" required="false"> <p>Set to <code>true</code> to allow this context to use container servlets, like the manager servlet. Use of the <code>privileged</code>
--------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org