Home | History | Annotate | Download | only in session
      1 //
      2 //  ========================================================================
      3 //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
      4 //  ------------------------------------------------------------------------
      5 //  All rights reserved. This program and the accompanying materials
      6 //  are made available under the terms of the Eclipse Public License v1.0
      7 //  and Apache License v2.0 which accompanies this distribution.
      8 //
      9 //      The Eclipse Public License is available at
     10 //      http://www.eclipse.org/legal/epl-v10.html
     11 //
     12 //      The Apache License v2.0 is available at
     13 //      http://www.opensource.org/licenses/apache2.0.php
     14 //
     15 //  You may elect to redistribute this code under either of these licenses.
     16 //  ========================================================================
     17 //
     18 
     19 package org.eclipse.jetty.server.session;
     20 
     21 import java.io.IOException;
     22 import java.util.EnumSet;
     23 import java.util.EventListener;
     24 import javax.servlet.DispatcherType;
     25 import javax.servlet.ServletException;
     26 import javax.servlet.SessionTrackingMode;
     27 import javax.servlet.http.Cookie;
     28 import javax.servlet.http.HttpServletRequest;
     29 import javax.servlet.http.HttpServletResponse;
     30 import javax.servlet.http.HttpSession;
     31 
     32 import org.eclipse.jetty.http.HttpCookie;
     33 import org.eclipse.jetty.server.Request;
     34 import org.eclipse.jetty.server.Server;
     35 import org.eclipse.jetty.server.SessionManager;
     36 import org.eclipse.jetty.server.handler.ScopedHandler;
     37 import org.eclipse.jetty.util.log.Log;
     38 import org.eclipse.jetty.util.log.Logger;
     39 
     40 /* ------------------------------------------------------------ */
     41 /**
     42  * SessionHandler.
     43  */
     44 public class SessionHandler extends ScopedHandler
     45 {
     46     final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
     47 
     48     public final static EnumSet<SessionTrackingMode> DEFAULT_TRACKING = EnumSet.of(SessionTrackingMode.COOKIE,SessionTrackingMode.URL);
     49 
     50     /* -------------------------------------------------------------- */
     51     private SessionManager _sessionManager;
     52 
     53     /* ------------------------------------------------------------ */
     54     /**
     55      * Constructor. Construct a SessionHandler witha a HashSessionManager with a standard java.util.Random generator is created.
     56      */
     57     public SessionHandler()
     58     {
     59         this(new HashSessionManager());
     60     }
     61 
     62     /* ------------------------------------------------------------ */
     63     /**
     64      * @param manager
     65      *            The session manager
     66      */
     67     public SessionHandler(SessionManager manager)
     68     {
     69         setSessionManager(manager);
     70     }
     71 
     72     /* ------------------------------------------------------------ */
     73     /**
     74      * @return Returns the sessionManager.
     75      */
     76     public SessionManager getSessionManager()
     77     {
     78         return _sessionManager;
     79     }
     80 
     81     /* ------------------------------------------------------------ */
     82     /**
     83      * @param sessionManager
     84      *            The sessionManager to set.
     85      */
     86     public void setSessionManager(SessionManager sessionManager)
     87     {
     88         if (isStarted())
     89             throw new IllegalStateException();
     90         SessionManager old_session_manager = _sessionManager;
     91 
     92         if (getServer() != null)
     93             getServer().getContainer().update(this,old_session_manager,sessionManager,"sessionManager",true);
     94 
     95         if (sessionManager != null)
     96             sessionManager.setSessionHandler(this);
     97 
     98         _sessionManager = sessionManager;
     99 
    100         if (old_session_manager != null)
    101             old_session_manager.setSessionHandler(null);
    102     }
    103 
    104     /* ------------------------------------------------------------ */
    105     @Override
    106     public void setServer(Server server)
    107     {
    108         Server old_server = getServer();
    109         if (old_server != null && old_server != server)
    110             old_server.getContainer().update(this,_sessionManager,null,"sessionManager",true);
    111         super.setServer(server);
    112         if (server != null && server != old_server)
    113             server.getContainer().update(this,null,_sessionManager,"sessionManager",true);
    114     }
    115 
    116     /* ------------------------------------------------------------ */
    117     /*
    118      * @see org.eclipse.thread.AbstractLifeCycle#doStart()
    119      */
    120     @Override
    121     protected void doStart() throws Exception
    122     {
    123         _sessionManager.start();
    124         super.doStart();
    125     }
    126 
    127     /* ------------------------------------------------------------ */
    128     /*
    129      * @see org.eclipse.thread.AbstractLifeCycle#doStop()
    130      */
    131     @Override
    132     protected void doStop() throws Exception
    133     {
    134         // Destroy sessions before destroying servlets/filters see JETTY-1266
    135         _sessionManager.stop();
    136         super.doStop();
    137     }
    138 
    139     /* ------------------------------------------------------------ */
    140     /*
    141      * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
    142      */
    143     @Override
    144     public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    145     {
    146         SessionManager old_session_manager = null;
    147         HttpSession old_session = null;
    148         HttpSession access = null;
    149         try
    150         {
    151             old_session_manager = baseRequest.getSessionManager();
    152             old_session = baseRequest.getSession(false);
    153 
    154             if (old_session_manager != _sessionManager)
    155             {
    156                 // new session context
    157                 baseRequest.setSessionManager(_sessionManager);
    158                 baseRequest.setSession(null);
    159                 checkRequestedSessionId(baseRequest,request);
    160             }
    161 
    162             // access any existing session
    163             HttpSession session = null;
    164             if (_sessionManager != null)
    165             {
    166                 session = baseRequest.getSession(false);
    167                 if (session != null)
    168                 {
    169                     if (session != old_session)
    170                     {
    171                         access = session;
    172                         HttpCookie cookie = _sessionManager.access(session,request.isSecure());
    173                         if (cookie != null) // Handle changed ID or max-age refresh
    174                             baseRequest.getResponse().addCookie(cookie);
    175                     }
    176                 }
    177                 else
    178                 {
    179                     session = baseRequest.recoverNewSession(_sessionManager);
    180                     if (session != null)
    181                         baseRequest.setSession(session);
    182                 }
    183             }
    184 
    185             if (LOG.isDebugEnabled())
    186             {
    187                 LOG.debug("sessionManager=" + _sessionManager);
    188                 LOG.debug("session=" + session);
    189             }
    190 
    191             // start manual inline of nextScope(target,baseRequest,request,response);
    192             if (_nextScope != null)
    193                 _nextScope.doScope(target,baseRequest,request,response);
    194             else if (_outerScope != null)
    195                 _outerScope.doHandle(target,baseRequest,request,response);
    196             else
    197                 doHandle(target,baseRequest,request,response);
    198             // end manual inline (pathentic attempt to reduce stack depth)
    199 
    200         }
    201         finally
    202         {
    203             if (access != null)
    204                 _sessionManager.complete(access);
    205 
    206             HttpSession session = baseRequest.getSession(false);
    207             if (session != null && old_session == null && session != access)
    208                 _sessionManager.complete(session);
    209 
    210             if (old_session_manager != null && old_session_manager != _sessionManager)
    211             {
    212                 baseRequest.setSessionManager(old_session_manager);
    213                 baseRequest.setSession(old_session);
    214             }
    215         }
    216     }
    217 
    218     /* ------------------------------------------------------------ */
    219     /*
    220      * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
    221      */
    222     @Override
    223     public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    224     {
    225         // start manual inline of nextHandle(target,baseRequest,request,response);
    226         if (never())
    227             nextHandle(target,baseRequest,request,response);
    228         else if (_nextScope != null && _nextScope == _handler)
    229             _nextScope.doHandle(target,baseRequest,request,response);
    230         else if (_handler != null)
    231             _handler.handle(target,baseRequest,request,response);
    232         // end manual inline
    233     }
    234 
    235     /* ------------------------------------------------------------ */
    236     /**
    237      * Look for a requested session ID in cookies and URI parameters
    238      *
    239      * @param baseRequest
    240      * @param request
    241      */
    242     protected void checkRequestedSessionId(Request baseRequest, HttpServletRequest request)
    243     {
    244         String requested_session_id = request.getRequestedSessionId();
    245 
    246         SessionManager sessionManager = getSessionManager();
    247 
    248         if (requested_session_id != null && sessionManager != null)
    249         {
    250             HttpSession session = sessionManager.getHttpSession(requested_session_id);
    251             if (session != null && sessionManager.isValid(session))
    252                 baseRequest.setSession(session);
    253             return;
    254         }
    255         else if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()))
    256             return;
    257 
    258         boolean requested_session_id_from_cookie = false;
    259         HttpSession session = null;
    260 
    261         // Look for session id cookie
    262         if (_sessionManager.isUsingCookies())
    263         {
    264             Cookie[] cookies = request.getCookies();
    265             if (cookies != null && cookies.length > 0)
    266             {
    267                 final String sessionCookie=sessionManager.getSessionCookieConfig().getName();
    268                 for (int i = 0; i < cookies.length; i++)
    269                 {
    270                     if (sessionCookie.equalsIgnoreCase(cookies[i].getName()))
    271                     {
    272                         requested_session_id = cookies[i].getValue();
    273                         requested_session_id_from_cookie = true;
    274 
    275                         LOG.debug("Got Session ID {} from cookie",requested_session_id);
    276 
    277                         if (requested_session_id != null)
    278                         {
    279                             session = sessionManager.getHttpSession(requested_session_id);
    280 
    281                             if (session != null && sessionManager.isValid(session))
    282                             {
    283                                 break;
    284                             }
    285                         }
    286                         else
    287                         {
    288                             LOG.warn("null session id from cookie");
    289                         }
    290                     }
    291                 }
    292             }
    293         }
    294 
    295         if (requested_session_id == null || session == null)
    296         {
    297             String uri = request.getRequestURI();
    298 
    299             String prefix = sessionManager.getSessionIdPathParameterNamePrefix();
    300             if (prefix != null)
    301             {
    302                 int s = uri.indexOf(prefix);
    303                 if (s >= 0)
    304                 {
    305                     s += prefix.length();
    306                     int i = s;
    307                     while (i < uri.length())
    308                     {
    309                         char c = uri.charAt(i);
    310                         if (c == ';' || c == '#' || c == '?' || c == '/')
    311                             break;
    312                         i++;
    313                     }
    314 
    315                     requested_session_id = uri.substring(s,i);
    316                     requested_session_id_from_cookie = false;
    317                     session = sessionManager.getHttpSession(requested_session_id);
    318                     if (LOG.isDebugEnabled())
    319                         LOG.debug("Got Session ID {} from URL",requested_session_id);
    320                 }
    321             }
    322         }
    323 
    324         baseRequest.setRequestedSessionId(requested_session_id);
    325         baseRequest.setRequestedSessionIdFromCookie(requested_session_id != null && requested_session_id_from_cookie);
    326         if (session != null && sessionManager.isValid(session))
    327             baseRequest.setSession(session);
    328     }
    329 
    330     /* ------------------------------------------------------------ */
    331     /**
    332      * @param listener
    333      */
    334     public void addEventListener(EventListener listener)
    335     {
    336         if (_sessionManager != null)
    337             _sessionManager.addEventListener(listener);
    338     }
    339 
    340     /* ------------------------------------------------------------ */
    341     public void clearEventListeners()
    342     {
    343         if (_sessionManager != null)
    344             _sessionManager.clearEventListeners();
    345     }
    346 }
    347