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  import org.mortbay.util.StringUtil;
    35
    36  /* ------------------------------------------------------------ */
    37  /** SessionHandler.
    38   *
    39   * @author gregw
    40   *
    41   */
    42  public class SessionHandler extends HandlerWrapper
    43  {
    44      /* -------------------------------------------------------------- */
    45      private SessionManager _sessionManager;
    46
    47      /* ------------------------------------------------------------ */
    48      /** Constructor.
    49       * Construct a SessionHandler witha a HashSessionManager with a standard
    50       * java.util.Random generator is created.
    51       */
    52      public SessionHandler()
    53      {
    54          this(new HashSessionManager());
    55      }
    56
    57      /* ------------------------------------------------------------ */
    58      /**
    59       * @param manager The session manager
    60       */
    61      public SessionHandler(SessionManager manager)
    62      {
    63          setSessionManager(manager);
    64      }
    65
    66      /* ------------------------------------------------------------ */
    67      /**
    68       * @return Returns the sessionManager.
    69       */
    70      public SessionManager getSessionManager()
    71      {
    72          return _sessionManager;
    73      }
    74
    75      /* ------------------------------------------------------------ */
    76      /**
    77       * @param sessionManager The sessionManager to set.
    78       */
    79      public void setSessionManager(SessionManager sessionManager)
    80      {
    81          if (isStarted())
    82              throw new IllegalStateException();
    83          SessionManager old_session_manager = _sessionManager;
    84
    85          if (getServer()!=null)
    86              getServer().getContainer().update(this, old_session_manager, sessionManager, "sessionManager",true);
    87
    88          if (sessionManager!=null)
    89              sessionManager.setSessionHandler(this);
    90
    91          _sessionManager = sessionManager;
    92
    93          if (old_session_manager!=null)
    94              old_session_manager.setSessionHandler(null);
    95      }
    96
    97
    98      /* ------------------------------------------------------------ */
    99      public void setServer(Server server)
    100     {
    101         Server old_server=getServer();
    102         if (old_server!=null && old_server!=server)
    103             old_server.getContainer().update(this, _sessionManager, null, "sessionManager",true);
    104         super.setServer(server);
    105         if (server!=null && server!=old_server)
    106             server.getContainer().update(this, null,_sessionManager, "sessionManager",true);
    107     }
    108
    109
    110     /* ------------------------------------------------------------ */
    111     /*
    112      * @see org.mortbay.thread.AbstractLifeCycle#doStart()
    113      */
    114     protected void doStart() throws Exception
    115     {
    116         _sessionManager.start();
    117         super.doStart();
    118     }
    119     /* ------------------------------------------------------------ */
    120     /*
    121      * @see org.mortbay.thread.AbstractLifeCycle#doStop()
    122      */
    123     protected void doStop() throws Exception
    124     {
    125         super.doStop();
    126         _sessionManager.stop();
    127     }
    128
    129     /* ------------------------------------------------------------ */
    130     /*
    131      * @see org.mortbay.jetty.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
    132      */
    133     public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch)
    134             throws IOException, ServletException
    135     {
    136         setRequestedId(request, dispatch);
    137
    138         Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
    139         SessionManager old_session_manager=null;
    140         HttpSession old_session=null;
    141
    142         try
    143         {
    144             old_session_manager = base_request.getSessionManager();
    145             old_session = base_request.getSession(false);
    146
    147             if (old_session_manager != _sessionManager)
    148             {
    149                 // new session context
    150                 base_request.setSessionManager(_sessionManager);
    151                 base_request.setSession(null);
    152             }
    153
    154             // access any existing session
    155             HttpSession session=null;
    156             if (_sessionManager!=null)
    157             {
    158                 session=base_request.getSession(false);
    159                 if (session!=null)
    160                 {
    161                     if(session!=old_session)
    162                     {
    163                         Cookie cookie = _sessionManager.access(session,request.isSecure());
    164                         if (cookie!=null ) // Handle changed ID or max-age refresh
    165                             response.addCookie(cookie);
    166                     }
    167                 }
    168                 else
    169                 {
    170                     session=base_request.recoverNewSession(_sessionManager);
    171                     if (session!=null)
    172                         base_request.setSession(session);
    173                 }
    174             }
    175
    176             if(Log.isDebugEnabled())
    177             {
    178                 Log.debug("sessionManager="+_sessionManager);
    179                 Log.debug("session="+session);
    180             }
    181
    182             getHandler().handle(target, request, response, dispatch);
    183         }
    184         catch (RetryRequest r)
    185         {
    186             HttpSession session=base_request.getSession(false);
    187             if (session!=null && session.isNew())
    188                 base_request.saveNewSession(_sessionManager,session);
    189             throw r;
    190         }
    191         finally
    192         {
    193             HttpSession session=request.getSession(false);
    194
    195             if (old_session_manager != _sessionManager)
    196             {
    197                 //leaving context, free up the session
    198                 if (session!=null)
    199                     _sessionManager.complete(session);
    200
    201                 // Leave last session in place
    202                 if (old_session_manager != null)
    203                 {
    204                     base_request.setSessionManager(old_session_manager);
    205                     base_request.setSession(old_session);
    206                 }
    207             }
    208         }
    209     }
    210
    211     /* ------------------------------------------------------------ */
    212     /** Look for a requested session ID in cookies and URI parameters
    213      * @param request
    214      * @param dispatch
    215      */
    216     protected void setRequestedId(HttpServletRequest request, int dispatch)
    217     {
    218         Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
    219         String requested_session_id=request.getRequestedSessionId();
    220         if (dispatch!=REQUEST || requested_session_id!=null)
    221         {
    222             return;
    223         }
    224
    225         final SessionManager sessionManager = getSessionManager();
    226         boolean requested_session_id_from_cookie=false;
    227         HttpSession session=null;
    228         // Look for session id cookie
    229         if (_sessionManager.isUsingCookies())
    230         {
    231             Cookie[] cookies=request.getCookies();
    232             if (cookies!=null && cookies.length>0)
    233             {
    234                 for (int i=0;i<cookies.length;i++)
    235                 {
    236                     if (sessionManager.getSessionCookie().equalsIgnoreCase(cookies[i].getName()))
    237                     {
    238                         if (requested_session_id!=null)
    239                         {
    240                             // Multiple jsessionid cookies. Probably due to
    241                             // multiple paths and/or domains. Pick the first
    242                             // known session or the last defined cookie.
    243                             if (sessionManager.getHttpSession(requested_session_id)!=null)
    244                                 break;
    245                         }
    246
    247                         requested_session_id=cookies[i].getValue();
    248                         requested_session_id_from_cookie = true;
    249                         if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from cookie");
    250
    251                         session=sessionManager.getHttpSession(requested_session_id);
    252                         if (session!=null)
    253                             base_request.setSession(session);
    254                     }
    255                 }
    256             }
    257         }
    258
    259         if (requested_session_id==null || session==null)
    260         {
    261             String uri = request.getRequestURI();
    262
    263             String prefix=sessionManager.getSessionURLPrefix();
    264             if (prefix!=null)
    265             {
    266                 int s = uri.indexOf(prefix);
    267                 if (s>=0)
    268                 {
    269                     s+=prefix.length();
    270                     int i=s;
    271                     while (i<uri.length())
    272                     {
    273                         char c=uri.charAt(i);
    274                         if (c==';'||c=='#'||c=='?'||c=='/')
    275                             break;
    276                         i++;
    277                     }
    278
    279                     requested_session_id = uri.substring(s,i);
    280                     requested_session_id_from_cookie = false;
    281                     if(Log.isDebugEnabled())
    282                         Log.debug("Got Session ID "+requested_session_id+" from URL");
    283                 }
    284             }
    285         }
    286
    287         base_request.setRequestedSessionId(requested_session_id);
    288         base_request.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie);
    289     }
    290
    291     /* ------------------------------------------------------------ */
    292     /**
    293      * @param listener
    294      */
    295     public void addEventListener(EventListener listener)
    296     {
    297         if(_sessionManager!=null)
    298             _sessionManager.addEventListener(listener);
    299     }
    300
    301     /* ------------------------------------------------------------ */
    302     public void clearEventListeners()
    303     {
    304         if(_sessionManager!=null)
    305             _sessionManager.clearEventListeners();
    306     }
    307 }