costin      00/11/20 16:31:15

  Modified:    src/etc  server.xml
               src/share/org/apache/tomcat/helper SecurityTools.java
               src/share/org/apache/tomcat/request SessionInterceptor.java
               src/share/org/apache/tomcat/session ServerSession.java
                        ServerSessionManager.java
                        StandardSessionInterceptor.java
  Added:       src/share/org/apache/tomcat/modules/session SessionId.java
                        SimpleSessionStore.java
  Log:
  Renamed the 2 interceptors involved in session management, to avoid future
  confusions.
  
  I'll integrate the changes from 3.2, using the right file ( i.e.
  modules.session.SessionId for cookie/url ID extraction, SessionStore
  for managing the HttpSession objects ).
  
  The original files are still there, as a backup - will be removed as soon
   as the patches from 3.2 are integrated.
  
  Revision  Changes    Path
  1.51      +2 -2      jakarta-tomcat/src/etc/server.xml
  
  Index: server.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/etc/server.xml,v
  retrieving revision 1.50
  retrieving revision 1.51
  diff -u -r1.50 -r1.51
  --- server.xml        2000/10/08 21:24:17     1.50
  +++ server.xml        2000/11/21 00:31:11     1.51
  @@ -138,7 +138,7 @@
                deal with URL rewriting ( by fixing the URL )
             -->
           <RequestInterceptor 
  -            className="org.apache.tomcat.request.SessionInterceptor" />
  +            className="org.apache.tomcat.modules.session.SessionId" />
   
           <!-- Find the container ( context and prefix/extension map ) 
                for a request.
  @@ -181,7 +181,7 @@
                modules.
             -->
           <RequestInterceptor 
  -            className="org.apache.tomcat.session.StandardSessionInterceptor" />
  +            className="org.apache.tomcat.modules.session.SimpleSessionStore" />
   
           <!-- Check if the request requires an authenticated role.
             -->
  
  
  
  1.4       +1 -1      
jakarta-tomcat/src/share/org/apache/tomcat/helper/SecurityTools.java
  
  Index: SecurityTools.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/helper/SecurityTools.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SecurityTools.java        2000/09/25 07:20:30     1.3
  +++ SecurityTools.java        2000/11/21 00:31:12     1.4
  @@ -59,8 +59,8 @@
   package org.apache.tomcat.helper;
   
   import org.apache.tomcat.core.*;
  -import org.apache.tomcat.session.*;
   import org.apache.tomcat.util.*;
  +import org.apache.tomcat.session.ServerSession;
   import org.apache.tomcat.util.xml.*;
   import java.io.*;
   import java.net.*;
  
  
  
  1.1                  
jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionId.java
  
  Index: SessionId.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.tomcat.modules.session;
  
  import org.apache.tomcat.core.*;
  import org.apache.tomcat.util.*;
  import org.apache.tomcat.helper.*;
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  /**
   * Extract the session ID from the request using cookies and
   * session rewriting.
   * 
   * Will process the request and determine the session Id, and set it
   * in the Request. It doesn't marks the session as accessed.
   *
   * This interceptor doesn't deal with any of the Session internals -
   * it just works with the sessionID. A pluggable session manager 
   *  ( or user-space manager !) will deal with marking the session
   * as accessed or setting the session implementation.
   *
   * This implementation only handles Cookies and URL rewriting sessions,
   * please extend or add new interceptors for other methods.
   *
   *
   */
  public class SessionId extends  BaseInterceptor
  {
  
      // GS, separates the session id from the jvm route
      static final char SESSIONID_ROUTE_SEP = '.';
      ContextManager cm;
      
      public SessionId() {
      }
  
      public void setContextManager( ContextManager cm ) {
        this.cm=cm;
      }
  
      /** Extract the session id from the request.
       * SessionInterceptor will have to be called _before_ mapper,
       * to avoid coding session stuff inside the mapper.
       *
       * When we fix the interceptors we'll have to specify something
       * similar with the priority in apache hooks, right now it's just
       * a config issue.
       */
      public int contextMap(Request request ) {
        if( request.getRequestedSessionId() != null ) {
            // probably Apache already did that for us
            return 0;
        }
  
        // fix URL rewriting
        String sig=";jsessionid=";
        int foundAt=-1;
        String uri=request.requestURI().toString();
        String sessionId;
        
        if ((foundAt=uri.indexOf(sig))!=-1){
            sessionId=uri.substring(foundAt+sig.length());
            // I hope the optimizer does it's job:-)
            sessionId = fixSessionId( request, sessionId );
            
            // rewrite URL, do I need to do anything more?
            request.requestURI().setString(uri.substring(0, foundAt));
  
            // No validate now - we just note that this is what the user
            // requested. 
            request.setSessionIdSource( Request.SESSIONID_FROM_URL);
            request.setRequestedSessionId( sessionId );
        }
        return 0;
      }
  
      /** This happens after context map, so we know the context.
       *  We can probably do it later too.
       */
      public int requestMap(Request request ) {
        String sessionId = null;
  
        int count=request.getCookieCount();
        
        // Give priority to cookies. I don't know if that's part
        // of the spec - XXX
        for( int i=0; i<count; i++ ) {
            ServerCookie cookie = request.getCookie(i);
            
            if (cookie.getName().equals("JSESSIONID")) {
                sessionId = cookie.getValue().toString();
                sessionId = fixSessionId( request, sessionId );
  
                // XXX what if we have multiple session cookies ?
                // right now only the first is used
                request.setRequestedSessionId( sessionId );
                request.setSessionIdSource( Request.SESSIONID_FROM_COOKIE);
                break;
            }
        }
  
        return 0;
      }
  
  //     private void findSessionCookie( MimeHeaders headers ) {
  //    int pos=0;
  //    while( pos>=0 ) {
  //        pos=headers.findHeader( "Cookie", pos );
  //        // no more cookie headers headers
  //        if( pos<0 ) break;
  
  //        MessageBytes cookieValue=getValue( pos );
            
  //    }
  //     }
      
      /** Fix the session id. If the session is not valid return null.
       *  It will also clean up the session from load-balancing strings.
       * @return sessionId, or null if not valid
       */
      private String fixSessionId(Request request, String sessionId){
        // GS, We piggyback the JVM id on top of the session cookie
        // Separate them ...
  
        if( debug>0 ) cm.log(" Orig sessionId  " + sessionId );
        if (null != sessionId) {
            int idex = sessionId.lastIndexOf(SESSIONID_ROUTE_SEP);
            if(idex > 0) {
                sessionId = sessionId.substring(0, idex);
            }
        }
        return sessionId;
      }
  
      public int beforeBody( Request rrequest, Response response ) {
        String reqSessionId = rrequest.getSessionId();
        if( debug>0 ) cm.log("Before Body " + reqSessionId );
        if( reqSessionId==null)
            return 0;
  
        
          // 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(!sessionPath.equals("/")) {
              String jvmRoute = rrequest.getJvmRoute();
              if(null != jvmRoute) {
                  reqSessionId = reqSessionId + SESSIONID_ROUTE_SEP + jvmRoute;
              }
          }
  
        // we know reqSessionId doesn't need quoting ( we generate it )
        StringBuffer buf = new StringBuffer();
        buf.append( "JSESSIONID=" ).append( reqSessionId );
        buf.append( ";Version=1" );
        buf.append( ";Path=" );
        CookieTools.maybeQuote( 1 , buf, sessionPath ); // XXX ugly 
        buf.append( ";Discard" );
        // discard results from:        cookie.setMaxAge(-1);
        
        
        response.addHeader( "Set-Cookie2",
                            buf.toString() ); // XXX XXX garbage generator
  
        buf = new StringBuffer();
        buf.append( "JSESSIONID=" ).append( reqSessionId );
        buf.append( ";Path=" ).append(  sessionPath  );
        response.addHeader( "Set-Cookie",
                            buf.toString());
        
        return 0;
      }
  
  
  }
  
  
  
  1.1                  
jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SimpleSessionStore.java
  
  Index: SimpleSessionStore.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  package org.apache.tomcat.modules.session;
  
  import java.io.*;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Vector;
  import org.apache.tomcat.util.*;
  import org.apache.tomcat.util.threads.*;
  import org.apache.tomcat.core.*;
  import org.apache.tomcat.session.*;
  
  
  /**
   * This is the adapter between tomcat and a StandardManager.
   * A session manager should not depend on tomcat internals - so you can
   * use it in other engines and back. All you need to do is
   * create an adapter ( tomcat Interceptor).
   *
   * You can even have multiple session managers per context - the first that
   * recognize the "requestedSessionId" will create it's own HttpSession object.
   * By using standard tomcat interceptor mechanisms you can plug in one or
   * many session managers per context or context manager ( or even per
   * URL - but that's not standard API feature ).
   * 
   * It must be inserted after SessionInterceptor, which does common
   * session stuff ( cookie, rewrite, etc)
   *
   * @author [EMAIL PROTECTED]
   */
  public final class SimpleSessionStore  extends BaseInterceptor {
      int manager_note;
  
      int checkInterval = 60;
      int maxActiveSessions = -1;
      String randomClass=null;
      
      public SimpleSessionStore() {
      }
  
      // -------------------- Configuration properties --------------------
  
      /**
       * Set the check interval (in seconds) for this Manager.
       *
       * @param checkInterval The new check interval
       */
      public void setCheckInterval( int secs ) {
        checkInterval=secs;
      }
  
      public void setMaxActiveSessions( int count ) {
        maxActiveSessions=count;
      }
  
      public final void setRandomClass(String randomClass) {
        this.randomClass=randomClass;
        System.setProperty(ContextManager.RANDOM_CLASS_PROPERTY, randomClass);
      }
  
      
      // -------------------- Tomcat request events --------------------
      public void engineInit( ContextManager cm ) throws TomcatException {
        // set-up a per/container note for StandardManager
        manager_note = cm.getNoteId( ContextManager.CONTAINER_NOTE,
                                     "tomcat.standardManager");
      }
  
      /**
       *  StandardManager will set the HttpSession if one is found.
       */
      public int requestMap(Request request ) {
        String sessionId = null;
        Context ctx=request.getContext();
        if( ctx==null ) {
            log( "Configuration error in StandardSessionInterceptor " +
                 " - no context " + request );
            return 0;
        }
  
        // "access" it and set HttpSession if valid
        sessionId=request.getRequestedSessionId();
  
        if (sessionId != null && sessionId.length()!=0) {
            // 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.
            ServerSessionManager sM = getManager( ctx );    
            ServerSession sess= sM.findSession( sessionId );
            //      log("Try to find: " + sessionId );
            if(null != sess) {
                sess.getTimeStamp().touch( System.currentTimeMillis() );
                //log("Session found " + sessionId );
                // set it only if nobody else did !
                if( null == request.getSession( false ) ) {
                    request.setSession( sess );
                    // XXX use MessageBytes!
                    request.setSessionId( sessionId );
                    //log("Session set " + sessionId );
                }
            }
            return 0;
        }
        return 0;
      }
      
      public void reload( Request req, Context ctx ) {
        ClassLoader newLoader = ctx.getClassLoader();
        ServerSessionManager sM = getManager( ctx );    
  
        // remove all non-serializable objects from session
        Enumeration sessionEnum=sM.getSessions().keys();
        while( sessionEnum.hasMoreElements() ) {
            ServerSession session = (ServerSession)sessionEnum.nextElement();
            Enumeration e = session.getAttributeNames();
            while( e.hasMoreElements() )   {
                String key = (String) e.nextElement();
                Object value = session.getAttribute(key);
                // XXX XXX We don't have to change loader for objects loaded
                // by the parent loader ?
                if (! ( value instanceof Serializable)) {
                    session.removeAttribute( key );
                    // XXX notification!!
                }
            }
        }
  
        // XXX We should change the loader for each object, and
        // avoid accessing object's internals
        // XXX PipeStream !?!
        Hashtable orig= sM.getSessions();
        Object newS = SessionSerializer.doSerialization( newLoader, orig);
        sM.setSessions( (Hashtable)newS );
        
        // Update the request session id
        String reqId=req.getRequestedSessionId();
        ServerSession sS=sM.findSession( reqId );
        if ( sS != null) {
            req.setSession(sS);
            req.setSessionId( reqId );
        }
      }
      
      public int newSessionRequest( Request request, Response response) {
        Context ctx=request.getContext();
        if( ctx==null ) return 0;
        
        ServerSessionManager sM = getManager( ctx );    
  
        if( request.getSession( false ) != null )
            return 0; // somebody already set the session
        ServerSession newS=sM.getNewSession();
        request.setSession( newS );
        request.setSessionId( newS.getId().toString());
        return 0;
      }
  
      //--------------------  Tomcat context events --------------------
      
      /** Init session management stuff for this context. 
       */
      public void contextInit(Context ctx) throws TomcatException {
        // Defaults !!
        ServerSessionManager sm= getManager( ctx );
        
        if( sm == null ) {
            sm=new ServerSessionManager();
            ctx.getContainer().setNote( manager_note, sm );
            sm.setMaxInactiveInterval( (long)ctx.getSessionTimeOut() *
                                       60 * 1000 );
        }
        sm.setMaxActiveSessions( maxActiveSessions );
  
        Expirer expirer=new Expirer();
        expirer.setCheckInterval( checkInterval );
        expirer.setExpireCallback( new Expirer.ExpireCallback() {
                public void expired(TimeStamp o ) {
                    ServerSession sses=(ServerSession)o.getParent();
                    ServerSessionManager ssm=sses.getSessionManager();
                    ssm.removeSession( sses );
                }
            });
        expirer.start();
        sm.setExpirer(expirer);
      }
      
      /** Notification of context shutdown.
       *  We should clean up any resources that are used by our
       *  session management code. 
       */
      public void contextShutdown( Context ctx )
        throws TomcatException
      {
        if( debug > 0 ) ctx.log("Removing sessions from " + ctx );
        ServerSessionManager sm=getManager(ctx);
        sm.getExpirer().stop();
        sm.removeAllSessions();
      }
  
      // -------------------- Internal methods --------------------
      private ServerSessionManager getManager( Context ctx ) {
        return (ServerSessionManager)ctx.getContainer().getNote(manager_note);
      }
  
  
  
  }
  
  
  
  1.30      +5 -0      
jakarta-tomcat/src/share/org/apache/tomcat/request/SessionInterceptor.java
  
  Index: SessionInterceptor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/request/SessionInterceptor.java,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- SessionInterceptor.java   2000/11/02 21:44:50     1.29
  +++ SessionInterceptor.java   2000/11/21 00:31:13     1.30
  @@ -67,6 +67,11 @@
   import java.net.*;
   import java.util.*;
   
  +// XXX
  +// DEPRECATED
  +// REPLACED BY org.apache.tomcat.modules.session.SessionId
  +
  +
   /**
    * Will process the request and determine the session Id, and set it
    * in the Request. It doesn't marks the session as accessed.
  
  
  
  1.7       +5 -0      
jakarta-tomcat/src/share/org/apache/tomcat/session/ServerSession.java
  
  Index: ServerSession.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/session/ServerSession.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ServerSession.java        2000/09/25 06:10:48     1.6
  +++ ServerSession.java        2000/11/21 00:31:14     1.7
  @@ -74,6 +74,11 @@
    *  - recyclable
    *  - serializable ( by external components )
    *
  + * Components:
  + *  - timestamp ( expire )
  + *  - id
  + *  - name/value repository
  + *
    * @author Craig R. McClanahan
    * @author <a href="mailto:[EMAIL PROTECTED]">Jon S. Stevens</a>
    * @author Costin Manolache
  
  
  
  1.12      +2 -2      
jakarta-tomcat/src/share/org/apache/tomcat/session/ServerSessionManager.java
  
  Index: ServerSessionManager.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/session/ServerSessionManager.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- ServerSessionManager.java 2000/11/02 21:45:02     1.11
  +++ ServerSessionManager.java 2000/11/21 00:31:14     1.12
  @@ -141,11 +141,11 @@
       }
   
   
  -    Hashtable getSessions() {
  +    public Hashtable getSessions() {
        return sessions;
       }
       
  -    void setSessions(Hashtable s) {
  +    public void setSessions(Hashtable s) {
        sessions=s;
       }
   
  
  
  
  1.15      +4 -0      
jakarta-tomcat/src/share/org/apache/tomcat/session/StandardSessionInterceptor.java
  
  Index: StandardSessionInterceptor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/session/StandardSessionInterceptor.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- StandardSessionInterceptor.java   2000/11/01 23:36:16     1.14
  +++ StandardSessionInterceptor.java   2000/11/21 00:31:14     1.15
  @@ -66,6 +66,10 @@
   import org.apache.tomcat.util.threads.*;
   import org.apache.tomcat.core.*;
   
  +// XXX
  +// DEPRECATED
  +// REPLACED BY org.apache.tomcat.modules.session.SimpleSessionStore
  +
   
   /**
    * This is the adapter between tomcat and a StandardManager.
  
  
  

Reply via email to