View Javadoc

    1   //========================================================================
    2   //$Id: SessionHandler.java,v 1.5 2005/11/11 22:55:39 gregwilkins Exp $
    3   //Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
    4   //------------------------------------------------------------------------
    5   //Licensed under the Apache License, Version 2.0 (the "License");
    6   //you may not use this file except in compliance with the License.
    7   //You may obtain a copy of the License at
    8   //http://www.apache.org/licenses/LICENSE-2.0
    9   //Unless required by applicable law or agreed to in writing, software
    10  //distributed under the License is distributed on an "AS IS" BASIS,
    11  //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  //See the License for the specific language governing permissions and
    13  //limitations under the License.
    14  //========================================================================
    15
    16  package org.mortbay.jetty.servlet;
    17
    18  import java.io.IOException;
    19  import java.util.EventListener;
    20
    21  import javax.servlet.ServletException;
    22  import javax.servlet.http.Cookie;
    23  import javax.servlet.http.HttpServletRequest;
    24  import javax.servlet.http.HttpServletResponse;
    25  import javax.servlet.http.HttpSession;
    26
    27  import org.mortbay.jetty.HttpConnection;
    28  import org.mortbay.jetty.Request;
    29  import org.mortbay.jetty.RetryRequest;
    30  import org.mortbay.jetty.Server;
    31  import org.mortbay.jetty.SessionManager;
    32  import org.mortbay.jetty.handler.HandlerWrapper;
    33  import org.mortbay.log.Log;
    34
    35  /* ------------------------------------------------------------ */
    36  /** SessionHandler.
    37   *
    38   * @author gregw
    39   *
    40   */
    41  public class SessionHandler extends HandlerWrapper
    42  {
    43      /* -------------------------------------------------------------- */
    44      private SessionManager _sessionManager;
    45
    46      /* ------------------------------------------------------------ */
    47      /** Constructor.
    48       * Construct a SessionHandler witha a HashSessionManager with a standard
    49       * java.util.Random generator is created.
    50       */
    51      public SessionHandler()
    52      {
    53          this(new HashSessionManager());
    54      }
    55
    56      /* ------------------------------------------------------------ */
    57      /**
    58       * @param manager The session manager
    59       */
    60      public SessionHandler(SessionManager manager)
    61      {
    62          setSessionManager(manager);
    63      }
    64
    65      /* ------------------------------------------------------------ */
    66      /**
    67       * @return Returns the sessionManager.
    68       */
    69      public SessionManager getSessionManager()
    70      {
    71          return _sessionManager;
    72      }
    73
    74      /* ------------------------------------------------------------ */
    75      /**
    76       * @param sessionManager The sessionManager to set.
    77       */
    78      public void setSessionManager(SessionManager sessionManager)
    79      {
    80          if (isStarted())
    81              throw new IllegalStateException();
    82          SessionManager old_session_manager = _sessionManager;
    83
    84          if (getServer()!=null)
    85              getServer().getContainer().update(this, old_session_manager, sessionManager, "sessionManager",true);
    86
    87          if (sessionManager!=null)
    88              sessionManager.setSessionHandler(this);
    89
    90          _sessionManager = sessionManager;
    91
    92          if (old_session_manager!=null)
    93              old_session_manager.setSessionHandler(null);
    94      }
    95
    96
    97      /* ------------------------------------------------------------ */
    98      public void setServer(Server server)
    99      {
    100         Server old_server=getServer();
    101         if (old_server!=null && old_server!=server)
    102             old_server.getContainer().update(this, _sessionManager, null, "sessionManager",true);
    103         super.setServer(server);
    104         if (server!=null && server!=old_server)
    105             server.getContainer().update(this, null,_sessionManager, "sessionManager",true);
    106     }
    107
    108
    109     /* ------------------------------------------------------------ */
    110     /*
    111      * @see org.mortbay.thread.AbstractLifeCycle#doStart()
    112      */
    113     protected void doStart() throws Exception
    114     {
    115         _sessionManager.start();
    116         super.doStart();
    117     }
    118     /* ------------------------------------------------------------ */
    119     /*
    120      * @see org.mortbay.thread.AbstractLifeCycle#doStop()
    121      */
    122     protected void doStop() throws Exception
    123     {
    124         super.doStop();
    125         _sessionManager.stop();
    126     }
    127
    128     /* ------------------------------------------------------------ */
    129     /*
    130      * @see org.mortbay.jetty.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
    131      */
    132     public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch)
    133             throws IOException, ServletException
    134     {
    135         setRequestedId(request, dispatch);
    136
    137         Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
    138         SessionManager old_session_manager=null;
    139         HttpSession old_session=null;
    140
    141         try
    142         {
    143             old_session_manager = base_request.getSessionManager();
    144             old_session = base_request.getSession(false);
    145
    146             if (old_session_manager != _sessionManager)
    147             {
    148                 // new session context
    149                 base_request.setSessionManager(_sessionManager);
    150                 base_request.setSession(null);
    151             }
    152
    153             // access any existing session
    154             HttpSession session=null;
    155             if (_sessionManager!=null)
    156             {
    157                 session=base_request.getSession(false);
    158                 if (session!=null)
    159                 {
    160                     if(session!=old_session)
    161                     {
    162                         Cookie cookie = _sessionManager.access(session,request.isSecure());
    163                         if (cookie!=null ) // Handle changed ID or max-age refresh
    164                             response.addCookie(cookie);
    165                     }
    166                 }
    167                 else
    168                 {
    169                     session=base_request.recoverNewSession(_sessionManager);
    170                     if (session!=null)
    171                         base_request.setSession(session);
    172                 }
    173             }
    174
    175             if(Log.isDebugEnabled())
    176             {
    177                 Log.debug("sessionManager="+_sessionManager);
    178                 Log.debug("session="+session);
    179             }
    180
    181             getHandler().handle(target, request, response, dispatch);
    182         }
    183         catch (RetryRequest r)
    184         {
    185             HttpSession session=base_request.getSession(false);
    186             if (session!=null && session.isNew())
    187                 base_request.saveNewSession(_sessionManager,session);
    188             throw r;
    189         }
    190         finally
    191         {
    192             HttpSession session=request.getSession(false);
    193
    194             if (old_session_manager != _sessionManager)
    195             {
    196                 //leaving context, free up the session
    197                 if (session!=null)
    198                     _sessionManager.complete(session);
    199                 base_request.setSessionManager(old_session_manager);
    200                 base_request.setSession(old_session);
    201             }
    202         }
    203     }
    204
    205     /* ------------------------------------------------------------ */
    206     /** Look for a requested session ID in cookies and URI parameters
    207      * @param request
    208      * @param dispatch
    209      */
    210     protected void setRequestedId(HttpServletRequest request, int dispatch)
    211     {
    212         Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
    213         String requested_session_id=request.getRequestedSessionId();
    214         if (dispatch!=REQUEST || requested_session_id!=null)
    215         {
    216             return;
    217         }
    218
    219         SessionManager sessionManager = getSessionManager();
    220         boolean requested_session_id_from_cookie=false;
    221
    222         // Look for session id cookie
    223         if (_sessionManager.isUsingCookies())
    224         {
    225             Cookie[] cookies=request.getCookies();
    226             if (cookies!=null && cookies.length>0)
    227             {
    228                 for (int i=0;i<cookies.length;i++)
    229                 {
    230                     if (sessionManager.getSessionCookie().equalsIgnoreCase(cookies[i].getName()))
    231                     {
    232                         if (requested_session_id!=null)
    233                         {
    234                             // Multiple jsessionid cookies. Probably due to
    235                             // multiple paths and/or domains. Pick the first
    236                             // known session or the last defined cookie.
    237                             if (sessionManager.getHttpSession(requested_session_id)!=null)
    238                                 break;
    239                         }
    240
    241                         requested_session_id=cookies[i].getValue();
    242                         requested_session_id_from_cookie = true;
    243                         if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from cookie");
    244                     }
    245                 }
    246             }
    247         }
    248
    249         if (requested_session_id==null)
    250         {
    251             String uri = request.getRequestURI();
    252
    253             int semi = uri.lastIndexOf(';');
    254             if (semi>=0)
    255             {
    256                 String path_params=uri.substring(semi+1);
    257
    258                 // check if there is a url encoded session param.
    259                 String param=sessionManager.getSessionURL();
    260                 if (param!=null && path_params!=null && path_params.startsWith(param))
    261                 {
    262                     requested_session_id = path_params.substring(sessionManager.getSessionURL().length()+1);
    263                     if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from URL");
    264                 }
    265             }
    266         }
    267
    268         base_request.setRequestedSessionId(requested_session_id);
    269         base_request.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie);
    270     }
    271
    272     /* ------------------------------------------------------------ */
    273     /**
    274      * @param listener
    275      */
    276     public void addEventListener(EventListener listener)
    277     {
    278         if(_sessionManager!=null)
    279             _sessionManager.addEventListener(listener);
    280     }
    281
    282     /* ------------------------------------------------------------ */
    283     public void clearEventListeners()
    284     {
    285         if(_sessionManager!=null)
    286             _sessionManager.clearEventListeners();
    287     }
    288 }