View Javadoc

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