You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by sh...@il.ibm.com on 2000/02/07 14:40:50 UTC

Session state bug and patch



Hi all,

There is a bug in the current implementation of the tomcat session-state.
When the user switches between two contexts (say A and B) the new session
id (cookie) of context B erase the id of context A.

This problem happens because the cookie carrying the session ID has a
single name (JSESSIONID) and a path of "/". Jserv solved a similar problem
by appending the name of the zone to the name of the cookie but we can not
do that (section 7.1.2 of the servlet spec.) Instead we need to set the
cookie's path to the context path (meaning the context /examples will have
the path /examples in it's session state cookie).

Another problem is that tomcat does not use the "route" environment variables
sent by the web server plugin, (this actually makes support for
Session-JVM-affinity "impossible" and broken for Tomcat) since the fix goes into
the same files I added (partial) support for the jvm route parameter.

The fix for these problems is in
org/apache/tomcat/request/SessionInterceptor.java
org/apache/tomcat/core/Request.java
org/apache/tomcat/core/RequestImpl.java


Here is the diff result:

For SessionInterceptor.java
81c81,83
<
---
>
>     static char SESSIONID_ROUTE_SEP = '.';
>
86c88
<
---
>
88,89c90,91
<    // look for session id -- cookies only right now
<    String sessionId = null;
---
>         // look for session id -- cookies only right now
>         String sessionId = null;
91,104c93,127
<    Cookie cookies[]=request.getCookies(); // assert !=null
<
<    for( int i=0; i<cookies.length; i++ ) {
<        Cookie cookie = cookies[i];
<
<        if (cookie.getName().equals(
<                        org.apache.tomcat.core.Constants.SESSION_COOKIE_NAME))
{
<         sessionId = cookie.getValue();
<
<         if (sessionId != null) {
<             request.setRequestedSessionId(sessionId);
<         }
<        }
<    }
---
>         Cookie cookies[]=request.getCookies(); // assert !=null
>
>         for( int i=0; i<cookies.length; i++ ) {
>             Cookie cookie = cookies[i];
>
>             if (cookie.getName().equals(
>                 org.apache.tomcat.core.Constants.SESSION_COOKIE_NAME)) {
>                 sessionId = cookie.getValue();
>
>                 // GS, We piggyback the JVM id on top of the session cookie
>                 // Separate them ...
>                 if(null != sessionId) {
>                     int idex = sessionId.lastIndexOf(SESSIONID_ROUTE_SEP);
>                     if(idex > 0) {
>                         sessionId = sessionId.substring(0, idex);
>                     }
>                 }
>
>                 if (sessionId != null) {
>
>                     // GS, We are in a problem here, we may actually get
>                     // multiple Session cookies (one for the root
>                     // context and one for the real context... or old session
>                     // cookie. We must check for validity in the current
context.
>                     Context ctx = request.getContext();
>                    SessionManager sM = ctx.getSessionManager();
>
>                     if(null != sM.findSession(ctx, sessionId)) {
>                         sM.accessed(ctx, request, sessionId );
>
>                         request.setRequestedSessionId(sessionId);
>                     }
>                 }
>             }
>         }
105a129
>     /*
111a136
>    */
113c138
<    return 0;
---
>        return 0;
121a147,148
>    String jvmRoute = rrequest.getJvmRoute();
>
124c151,164
<
---
>
>     // GS, set the path attribute to the cookie. This way
>     // multiple session cookies can be used, one for each
>     // context.
>    String sessionPath = rrequest.getContext().getPath();
>    if(sessionPath.length() == 0) {
>        sessionPath = "/";
>    }
>
>     // GS, piggyback the jvm route on the session id.
>     if(null != jvmRoute) {
>         reqSessionId = reqSessionId + SESSIONID_ROUTE_SEP + jvmRoute;
>     }
>
128c168,169
<    cookie.setPath("/");
---
>    cookie.setPath(sessionPath);
>    //cookie.setPath("/");

for Request

RCS file:
/home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/core/Request.java,v
retrieving revision 1.25
diff -r1.25 Request.java
76a77,80
>     // -------------------- Multiple JVM support --------------------
>     // GS, used by the load balancing layer
>     public String getJvmRoute();
>

for RequestImpl

RCS file:
/home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/core/RequestImpl.java,v
retrieving revision 1.14
diff -r1.14 RequestImpl.java
2c2
<  * $Header:
/home/cvspublic/jakarta-tomcat/src/share/org/apache/tomcat/core/RequestImpl.java,v

1.14 2000/02/03 23:05:27 costin Exp $
---
>  * $Header:
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/RequestImpl.java,v
1.14 2000/02/03 23:05:27 costin Exp $
84a85,89
>
>     // GS, used by the load balancing layer in the Web Servers
>     // jvmRoute == the name of the JVM inside the plugin.
>     protected String jvmRoute;
>
152a158,161
>     public String getJvmRoute() {
>         return jvmRoute;
>     }
>
539a549,550
>
>     jvmRoute = null;
542,547c553,558
<         contentLength = -1;
<         contentType = null;
<         charEncoding = null;
<         authType = null;
<         remoteUser = null;
<         reqSessionId = null;
---
>     contentLength = -1;
>     contentType = null;
>     charEncoding = null;
>     authType = null;
>     remoteUser = null;
>     reqSessionId = null;

     Gal Shachor

-------------------------------
Gal Shachor
IBM Research, Haifa Lab.
Email: shachor@il.ibm.com
Notes: Gal Shachor/Haifa/IBM@IBMIL
Phone: +972-4-8296164
Fax: +972-4-8550070
Address: IBM Haifa Research Lab, Matam, Haifa 31905, Israel



Session timeout not getting set?

Posted by "Michael P. McCutcheon" <mi...@value.net>.
Does the session configuration in the server.xml file work?

I have the following in my server.xml file:

<Context path="/" docBase=""
  defaultSessionTimeOut="1" isWARExpanded="true"
   isWARValidated="false" isInvokerEnabled="true"
   isWorkDirPersistent="false"/>

However, I don't see my objects getting unbound from the session after one minute.

When I manually set the timeout with:

session.setMaxInactiveInterval(), it works and I see my objects getting unbound from
the session.

Is there a bug with the sessiontimeout in the server.xml config file?

Mike