svn commit: r701564 - in /ofbiz/trunk/framework: base/config/ofbiz-containers.xml catalina/src/org/ofbiz/catalina/container/CatalinaContainer.java catalina/src/org/ofbiz/catalina/container/CrossSubdomainSessionValve.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r701564 - in /ofbiz/trunk/framework: base/config/ofbiz-containers.xml catalina/src/org/ofbiz/catalina/container/CatalinaContainer.java catalina/src/org/ofbiz/catalina/container/CrossSubdomainSessionValve.java

lektran
Author: lektran
Date: Fri Oct  3 16:08:36 2008
New Revision: 701564

URL: http://svn.apache.org/viewvc?rev=701564&view=rev
Log:
OFBIZ-1980: CrossSubdomainSessionValve for Tomcat, allows a session cookie to be shared across multiple subdomains.  

Thanks to Mridul Pathak for the patch, Pranay Pandey and Chirag Manocha for testing and Andrew Zeneski for guidance and review.

Note: I made one small change, switched from logInfo to logVerbose to reduce the amount of noise created in the logs

Added:
    ofbiz/trunk/framework/catalina/src/org/ofbiz/catalina/container/CrossSubdomainSessionValve.java
Modified:
    ofbiz/trunk/framework/base/config/ofbiz-containers.xml
    ofbiz/trunk/framework/catalina/src/org/ofbiz/catalina/container/CatalinaContainer.java

Modified: ofbiz/trunk/framework/base/config/ofbiz-containers.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/config/ofbiz-containers.xml?rev=701564&r1=701563&r2=701564&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/config/ofbiz-containers.xml (original)
+++ ofbiz/trunk/framework/base/config/ofbiz-containers.xml Fri Oct  3 16:08:36 2008
@@ -128,6 +128,7 @@
             </property>
             -->
             <!-- <property name="ssl-accelerator-port" value="8443"/> -->
+            <property name="enable-session-valve" value="true"/>
         </property>
         <!-- all connectors support type, host, port, enable-lookups -->
         <property name="ajp-connector" value="connector">

Modified: ofbiz/trunk/framework/catalina/src/org/ofbiz/catalina/container/CatalinaContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/catalina/src/org/ofbiz/catalina/container/CatalinaContainer.java?rev=701564&r1=701563&r2=701564&view=diff
==============================================================================
--- ofbiz/trunk/framework/catalina/src/org/ofbiz/catalina/container/CatalinaContainer.java (original)
+++ ofbiz/trunk/framework/catalina/src/org/ofbiz/catalina/container/CatalinaContainer.java Fri Oct  3 16:08:36 2008
@@ -295,6 +295,13 @@
             engine.addValve(rdv);
         }
 
+        // configure the CrossSubdomainSessionValve
+        boolean enableSessionValve = ContainerConfig.getPropertyValue(engineConfig, "enable-session-valve", false);
+        if (enableSessionValve) {
+            CrossSubdomainSessionValve sessionValve = new CrossSubdomainSessionValve();
+            engine.addValve(sessionValve);
+        }
+        
         // configure the access log valve
         String logDir = ContainerConfig.getPropertyValue(engineConfig, "access-log-dir", null);
         AccessLogValve al = null;

Added: ofbiz/trunk/framework/catalina/src/org/ofbiz/catalina/container/CrossSubdomainSessionValve.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/catalina/src/org/ofbiz/catalina/container/CrossSubdomainSessionValve.java?rev=701564&view=auto
==============================================================================
--- ofbiz/trunk/framework/catalina/src/org/ofbiz/catalina/container/CrossSubdomainSessionValve.java (added)
+++ ofbiz/trunk/framework/catalina/src/org/ofbiz/catalina/container/CrossSubdomainSessionValve.java Fri Oct  3 16:08:36 2008
@@ -0,0 +1,99 @@
+package org.ofbiz.catalina.container;
+
+import java.io.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.apache.catalina.*;
+import org.apache.catalina.connector.*;
+import org.apache.catalina.valves.*;
+import org.apache.tomcat.util.buf.*;
+import org.apache.tomcat.util.http.*;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+
+public class CrossSubdomainSessionValve extends ValveBase {
+
+    public static final String module = CrossSubdomainSessionValve.class.getName();
+
+    public CrossSubdomainSessionValve() {
+        super();
+    }
+
+    /** @Override */
+    public void invoke(Request request, Response response) throws IOException, ServletException {
+
+        // this will cause Request.doGetSession to create the session cookie if necessary
+        request.getSession(true);
+
+        // replace any Tomcat-generated session cookies with our own
+        Cookie[] cookies = response.getCookies();
+        if (cookies != null) {
+            for (int i = 0; i < cookies.length; i++) {
+                Cookie cookie = cookies[i];
+                if (Globals.SESSION_COOKIE_NAME.equals(cookie.getName())) {
+                    replaceCookie(request, response, cookie);
+                }
+            }
+        }
+
+        // process the next valve
+        getNext().invoke(request, response);
+    }
+
+    protected void replaceCookie(Request request, Response response, Cookie cookie) {
+
+        // copy the existing session cookie, but use a different domain
+        Cookie newCookie = new Cookie(cookie.getName(), cookie.getValue());
+        if (cookie.getPath() != null) {
+            newCookie.setPath(cookie.getPath());
+        }
+
+        String cookieDomain = null;
+        cookieDomain = UtilProperties.getPropertyValue("url", "cookie.domain", "");
+
+        if (UtilValidate.isEmpty(cookieDomain)) {
+            cookieDomain = getCookieDomain(request);
+        }
+
+        newCookie.setDomain(cookieDomain);
+        newCookie.setMaxAge(cookie.getMaxAge());
+        newCookie.setVersion(cookie.getVersion());
+        if (cookie.getComment() != null) {
+            newCookie.setComment(cookie.getComment());
+        }
+        newCookie.setSecure(cookie.getSecure());
+
+        // if the response has already been committed, our replacement strategy will have no effect
+        if (response.isCommitted()) {
+            Debug.logError("CrossSubdomainSessionValve: response was already committed!", module);
+        }
+
+        // find the Set-Cookie header for the existing cookie and replace its value with new cookie
+        MimeHeaders mimeHeaders = response.getCoyoteResponse().getMimeHeaders();
+        for (int i = 0, size = mimeHeaders.size(); i < size; i++) {
+            if (mimeHeaders.getName(i).equals("Set-Cookie")) {
+                MessageBytes value = mimeHeaders.getValue(i);
+                if (value.indexOf(cookie.getName()) >= 0) {
+                    StringBuffer buffer = new StringBuffer();
+                    ServerCookie.appendCookieValue(buffer, newCookie.getVersion(), newCookie.getName(), newCookie.getValue(), newCookie.getPath(),
+                            newCookie.getDomain(), newCookie.getComment(), newCookie.getMaxAge(), newCookie.getSecure());
+                    Debug.logVerbose("CrossSubdomainSessionValve: old Set-Cookie value: " + value.toString(), module);
+                    Debug.logVerbose("CrossSubdomainSessionValve: new Set-Cookie value: " + buffer, module);
+                    value.setString(buffer.toString());
+                }
+            }
+        }
+    }
+
+    protected String getCookieDomain(Request request) {
+        String cookieDomain = request.getServerName();
+        String[] domainArray = cookieDomain.split("\\.");
+        if (domainArray.length >= 2) {
+            cookieDomain = domainArray[domainArray.length - 2] + "." + domainArray[domainArray.length - 1];
+        }
+        return "." + cookieDomain;
+    }
+}
\ No newline at end of file