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, HttpServletRequest request, HttpServletResponse response)
134             throws IOException, ServletException
135     {
136         setRequestedId(request);
137 
138         Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
139         SessionManager old_session_manager=null;
140         HttpSession old_session=null;
141 
142         try
143         {
144             old_session_manager = base_request.getSessionManager();
145             old_session = base_request.getSession(false);
146 
147             if (old_session_manager != _sessionManager)
148             {
149                 // new session context
150                 base_request.setSessionManager(_sessionManager);
151                 base_request.setSession(null);
152             }
153 
154             // access any existing session
155             HttpSession session=null;
156             if (_sessionManager!=null)
157             {
158                 session=base_request.getSession(false);
159                 if (session!=null)
160                 {
161                     if(session!=old_session)
162                     {
163                         HttpCookie cookie = _sessionManager.access(session,request.isSecure());
164                         if (cookie!=null ) // Handle changed ID or max-age refresh
165                             base_request.getResponse().addCookie(cookie);
166                     }
167                 }
168                 else
169                 {
170                     session=base_request.recoverNewSession(_sessionManager);
171                     if (session!=null)
172                         base_request.setSession(session);
173                 }
174             }
175 
176             if(Log.isDebugEnabled())
177             {
178                 Log.debug("sessionManager="+_sessionManager);
179                 Log.debug("session="+session);
180             }
181 
182             getHandler().handle(target, request, response);
183         }
184         catch (RetryRequest r)
185         {
186             HttpSession session=base_request.getSession(false);
187             if (session!=null && session.isNew())
188                 base_request.saveNewSession(_sessionManager,session);
189             throw r;
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                 base_request.setSessionManager(old_session_manager);
201                 base_request.setSession(old_session);
202             }
203         }
204     }
205 
206     /* ------------------------------------------------------------ */
207     /** Look for a requested session ID in cookies and URI parameters
208      * @param request
209      * @param dispatch
210      */
211     protected void setRequestedId(HttpServletRequest request)
212     {
213         Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
214         String requested_session_id=request.getRequestedSessionId();
215         if (!DispatcherType.REQUEST.equals(base_request.getDispatcherType()) || requested_session_id!=null)
216         {
217             return;
218         }
219 
220         SessionManager sessionManager = getSessionManager();
221         boolean requested_session_id_from_cookie=false;
222 
223         // Look for session id cookie
224         if (_sessionManager.isUsingCookies())
225         {
226             Cookie[] cookies=request.getCookies();
227             if (cookies!=null && cookies.length>0)
228             {
229                 for (int i=0;i<cookies.length;i++)
230                 {
231                     if (sessionManager.getSessionCookie().equalsIgnoreCase(cookies[i].getName()))
232                     {
233                         if (requested_session_id!=null)
234                         {
235                             // Multiple jsessionid cookies. Probably due to
236                             // multiple paths and/or domains. Pick the first
237                             // known session or the last defined cookie.
238                             if (sessionManager.getHttpSession(requested_session_id)!=null)
239                                 break;
240                         }
241 
242                         requested_session_id=cookies[i].getValue();
243                         requested_session_id_from_cookie = true;
244                         if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from cookie");
245                     }
246                 }
247             }
248         }
249 
250         if (requested_session_id==null)
251         {
252             String uri = request.getRequestURI();
253 
254             int semi = uri.lastIndexOf(';');
255             if (semi>=0)
256             {
257                 String path_params=uri.substring(semi+1);
258 
259                 // check if there is a url encoded session param.
260                 String param=sessionManager.getSessionIdPathParameterName();
261                 if (param!=null && path_params!=null && path_params.startsWith(param))
262                 {
263                     requested_session_id = path_params.substring(sessionManager.getSessionIdPathParameterName().length()+1);
264                     if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from URL");
265                 }
266             }
267         }
268 
269         base_request.setRequestedSessionId(requested_session_id);
270         base_request.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie);
271     }
272 
273     /* ------------------------------------------------------------ */
274     /**
275      * @param listener
276      */
277     public void addEventListener(EventListener listener)
278     {
279         if(_sessionManager!=null)
280             _sessionManager.addEventListener(listener);
281     }
282 
283     /* ------------------------------------------------------------ */
284     public void clearEventListeners()
285     {
286         if(_sessionManager!=null)
287             _sessionManager.clearEventListeners();
288     }
289 }