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.ServletException;
21  import javax.servlet.http.Cookie;
22  import javax.servlet.http.HttpServletRequest;
23  import javax.servlet.http.HttpServletResponse;
24  import javax.servlet.http.HttpSession;
25  
26  import org.eclipse.jetty.http.HttpCookie;
27  import org.eclipse.jetty.server.DispatcherType;
28  import org.eclipse.jetty.server.HttpConnection;
29  import org.eclipse.jetty.server.Request;
30  import org.eclipse.jetty.server.RetryRequest;
31  import org.eclipse.jetty.server.Server;
32  import org.eclipse.jetty.server.SessionManager;
33  import org.eclipse.jetty.server.handler.HandlerWrapper;
34  import org.eclipse.jetty.util.log.Log;
35  
36  /* ------------------------------------------------------------ */
37  /** SessionHandler.
38   *
39   * 
40   *
41   */
42  public class SessionHandler extends HandlerWrapper
43  {
44      /* -------------------------------------------------------------- */
45      private SessionManager _sessionManager;
46  
47      /* ------------------------------------------------------------ */
48      /** Constructor.
49       * Construct a SessionHandler witha a HashSessionManager with a standard
50       * java.util.Random generator is created.
51       */
52      public SessionHandler()
53      {
54          this(new HashSessionManager());
55      }
56  
57      /* ------------------------------------------------------------ */
58      /**
59       * @param manager The session manager
60       */
61      public SessionHandler(SessionManager manager)
62      {
63          setSessionManager(manager);
64      }
65  
66      /* ------------------------------------------------------------ */
67      /**
68       * @return Returns the sessionManager.
69       */
70      public SessionManager getSessionManager()
71      {
72          return _sessionManager;
73      }
74  
75      /* ------------------------------------------------------------ */
76      /**
77       * @param sessionManager The sessionManager to set.
78       */
79      public void setSessionManager(SessionManager sessionManager)
80      {
81          if (isStarted())
82              throw new IllegalStateException();
83          SessionManager old_session_manager = _sessionManager;
84  
85          if (getServer()!=null)
86              getServer().getContainer().update(this, old_session_manager, sessionManager, "sessionManager",true);
87  
88          if (sessionManager!=null)
89              sessionManager.setSessionHandler(this);
90  
91          _sessionManager = sessionManager;
92  
93          if (old_session_manager!=null)
94              old_session_manager.setSessionHandler(null);
95      }
96  
97  
98      /* ------------------------------------------------------------ */
99      public void setServer(Server server)
100     {
101         Server old_server=getServer();
102         if (old_server!=null && old_server!=server)
103             old_server.getContainer().update(this, _sessionManager, null, "sessionManager",true);
104         super.setServer(server);
105         if (server!=null && server!=old_server)
106             server.getContainer().update(this, null,_sessionManager, "sessionManager",true);
107     }
108 
109 
110     /* ------------------------------------------------------------ */
111     /*
112      * @see org.eclipse.thread.AbstractLifeCycle#doStart()
113      */
114     protected void doStart() throws Exception
115     {
116         _sessionManager.start();
117         super.doStart();
118     }
119     /* ------------------------------------------------------------ */
120     /*
121      * @see org.eclipse.thread.AbstractLifeCycle#doStop()
122      */
123     protected void doStop() throws Exception
124     {
125         super.doStop();
126         _sessionManager.stop();
127     }
128 
129     /* ------------------------------------------------------------ */
130     /*
131      * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
132      */
133     public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
134             throws IOException, ServletException
135     {
136         setRequestedId(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             getHandler().handle(target, baseRequest, request, response);
182         }
183         catch (RetryRequest r)
184         {
185             HttpSession session=baseRequest.getSession(false);
186             if (session!=null && session.isNew())
187                 baseRequest.saveNewSession(_sessionManager,session);
188             throw r;
189         }
190         finally
191         {
192             HttpSession session=request.getSession(false);
193 
194             if (old_session_manager != _sessionManager)
195             {
196                 //leaving context, free up the session
197                 if (session!=null)
198                     _sessionManager.complete(session);
199                 baseRequest.setSessionManager(old_session_manager);
200                 baseRequest.setSession(old_session);
201             }
202         }
203     }
204 
205     /* ------------------------------------------------------------ */
206     /** Look for a requested session ID in cookies and URI parameters
207      * @param request
208      * @param dispatch
209      */
210     protected void setRequestedId(HttpServletRequest request)
211     {
212         Request baseRequest = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
213         String requested_session_id=request.getRequestedSessionId();
214         if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()) || requested_session_id!=null)
215         {
216             return;
217         }
218 
219         SessionManager sessionManager = getSessionManager();
220         boolean requested_session_id_from_cookie=false;
221 
222         // Look for session id cookie
223         if (_sessionManager.isUsingCookies())
224         {
225             Cookie[] cookies=request.getCookies();
226             if (cookies!=null && cookies.length>0)
227             {
228                 for (int i=0;i<cookies.length;i++)
229                 {
230                     if (sessionManager.getSessionCookie().equalsIgnoreCase(cookies[i].getName()))
231                     {
232                         if (requested_session_id!=null)
233                         {
234                             // Multiple jsessionid cookies. Probably due to
235                             // multiple paths and/or domains. Pick the first
236                             // known session or the last defined cookie.
237                             if (sessionManager.getHttpSession(requested_session_id)!=null)
238                                 break;
239                         }
240 
241                         requested_session_id=cookies[i].getValue();
242                         requested_session_id_from_cookie = true;
243                         if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from cookie");
244                     }
245                 }
246             }
247         }
248 
249         if (requested_session_id==null)
250         {
251             String uri = request.getRequestURI();
252 
253             int semi = uri.lastIndexOf(';');
254             if (semi>=0)
255             {
256                 String path_params=uri.substring(semi+1);
257 
258                 // check if there is a url encoded session param.
259                 String param=sessionManager.getSessionIdPathParameterName();
260                 if (param!=null && path_params!=null && path_params.startsWith(param))
261                 {
262                     requested_session_id = path_params.substring(sessionManager.getSessionIdPathParameterName().length()+1);
263                     if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from URL");
264                 }
265             }
266         }
267 
268         baseRequest.setRequestedSessionId(requested_session_id);
269         baseRequest.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie);
270     }
271 
272     /* ------------------------------------------------------------ */
273     /**
274      * @param listener
275      */
276     public void addEventListener(EventListener listener)
277     {
278         if(_sessionManager!=null)
279             _sessionManager.addEventListener(listener);
280     }
281 
282     /* ------------------------------------------------------------ */
283     public void clearEventListeners()
284     {
285         if(_sessionManager!=null)
286             _sessionManager.clearEventListeners();
287     }
288 }