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.HttpConnection;
28  import org.eclipse.jetty.server.Request;
29  import org.eclipse.jetty.server.Server;
30  import org.eclipse.jetty.server.SessionManager;
31  import org.eclipse.jetty.server.handler.HandlerWrapper;
32  import org.eclipse.jetty.util.log.Log;
33  
34  /* ------------------------------------------------------------ */
35  /** SessionHandler.
36   *
37   * 
38   *
39   */
40  public class SessionHandler extends HandlerWrapper
41  {
42      /* -------------------------------------------------------------- */
43      private SessionManager _sessionManager;
44  
45      /* ------------------------------------------------------------ */
46      /** Constructor.
47       * Construct a SessionHandler witha a HashSessionManager with a standard
48       * java.util.Random generator is created.
49       */
50      public SessionHandler()
51      {
52          this(new HashSessionManager());
53      }
54  
55      /* ------------------------------------------------------------ */
56      /**
57       * @param manager The session manager
58       */
59      public SessionHandler(SessionManager manager)
60      {
61          setSessionManager(manager);
62      }
63  
64      /* ------------------------------------------------------------ */
65      /**
66       * @return Returns the sessionManager.
67       */
68      public SessionManager getSessionManager()
69      {
70          return _sessionManager;
71      }
72  
73      /* ------------------------------------------------------------ */
74      /**
75       * @param sessionManager The sessionManager to set.
76       */
77      public void setSessionManager(SessionManager sessionManager)
78      {
79          if (isStarted())
80              throw new IllegalStateException();
81          SessionManager old_session_manager = _sessionManager;
82  
83          if (getServer()!=null)
84              getServer().getContainer().update(this, old_session_manager, sessionManager, "sessionManager",true);
85  
86          if (sessionManager!=null)
87              sessionManager.setSessionHandler(this);
88  
89          _sessionManager = sessionManager;
90  
91          if (old_session_manager!=null)
92              old_session_manager.setSessionHandler(null);
93      }
94  
95  
96      /* ------------------------------------------------------------ */
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     protected void doStart() throws Exception
113     {
114         _sessionManager.start();
115         super.doStart();
116     }
117     /* ------------------------------------------------------------ */
118     /*
119      * @see org.eclipse.thread.AbstractLifeCycle#doStop()
120      */
121     protected void doStop() throws Exception
122     {
123         super.doStop();
124         _sessionManager.stop();
125     }
126 
127     /* ------------------------------------------------------------ */
128     /*
129      * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
130      */
131     public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
132             throws IOException, ServletException
133     {
134         setRequestedId(request);
135 
136         SessionManager old_session_manager=null;
137         HttpSession old_session=null;
138 
139         try
140         {
141             old_session_manager = baseRequest.getSessionManager();
142             old_session = baseRequest.getSession(false);
143 
144             if (old_session_manager != _sessionManager)
145             {
146                 // new session context
147                 baseRequest.setSessionManager(_sessionManager);
148                 baseRequest.setSession(null);
149             }
150 
151             // access any existing session
152             HttpSession session=null;
153             if (_sessionManager!=null)
154             {
155                 session=baseRequest.getSession(false);
156                 if (session!=null)
157                 {
158                     if(session!=old_session)
159                     {
160                         HttpCookie cookie = _sessionManager.access(session,request.isSecure());
161                         if (cookie!=null ) // Handle changed ID or max-age refresh
162                             baseRequest.getResponse().addCookie(cookie);
163                     }
164                 }
165                 else
166                 {
167                     session=baseRequest.recoverNewSession(_sessionManager);
168                     if (session!=null)
169                         baseRequest.setSession(session);
170                 }
171             }
172 
173             if(Log.isDebugEnabled())
174             {
175                 Log.debug("sessionManager="+_sessionManager);
176                 Log.debug("session="+session);
177             }
178 
179             getHandler().handle(target, baseRequest, request, response);
180         }
181         finally
182         {
183             HttpSession session=request.getSession(false);
184 
185             if (old_session_manager != _sessionManager)
186             {
187                 //leaving context, free up the session
188                 if (session!=null)
189                     _sessionManager.complete(session);
190                 baseRequest.setSessionManager(old_session_manager);
191                 baseRequest.setSession(old_session);
192             }
193         }
194     }
195 
196     /* ------------------------------------------------------------ */
197     /** Look for a requested session ID in cookies and URI parameters
198      * @param request
199      * @param dispatch
200      */
201     protected void setRequestedId(HttpServletRequest request)
202     {
203         Request baseRequest = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
204         String requested_session_id=request.getRequestedSessionId();
205         if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()) || requested_session_id!=null)
206         {
207             return;
208         }
209 
210         SessionManager sessionManager = getSessionManager();
211         boolean requested_session_id_from_cookie=false;
212 
213         // Look for session id cookie
214         if (_sessionManager.isUsingCookies())
215         {
216             Cookie[] cookies=request.getCookies();
217             if (cookies!=null && cookies.length>0)
218             {
219                 for (int i=0;i<cookies.length;i++)
220                 {
221                     if (sessionManager.getSessionCookie().equalsIgnoreCase(cookies[i].getName()))
222                     {
223                         if (requested_session_id!=null)
224                         {
225                             // Multiple jsessionid cookies. Probably due to
226                             // multiple paths and/or domains. Pick the first
227                             // known session or the last defined cookie.
228                             if (sessionManager.getHttpSession(requested_session_id)!=null)
229                                 break;
230                         }
231 
232                         requested_session_id=cookies[i].getValue();
233                         requested_session_id_from_cookie = true;
234                         if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from cookie");
235                     }
236                 }
237             }
238         }
239 
240         if (requested_session_id==null)
241         {
242             String uri = request.getRequestURI();
243 
244             int semi = uri.lastIndexOf(';');
245             if (semi>=0)
246             {
247                 String path_params=uri.substring(semi+1);
248 
249                 // check if there is a url encoded session param.
250                 String param=sessionManager.getSessionIdPathParameterName();
251                 if (param!=null && path_params!=null && path_params.startsWith(param))
252                 {
253                     requested_session_id = path_params.substring(sessionManager.getSessionIdPathParameterName().length()+1);
254                     if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from URL");
255                 }
256             }
257         }
258 
259         baseRequest.setRequestedSessionId(requested_session_id);
260         baseRequest.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie);
261     }
262 
263     /* ------------------------------------------------------------ */
264     /**
265      * @param listener
266      */
267     public void addEventListener(EventListener listener)
268     {
269         if(_sessionManager!=null)
270             _sessionManager.addEventListener(listener);
271     }
272 
273     /* ------------------------------------------------------------ */
274     public void clearEventListeners()
275     {
276         if(_sessionManager!=null)
277             _sessionManager.clearEventListeners();
278     }
279 }