View Javadoc

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