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