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

Reply via email to