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