View Javadoc

1   //========================================================================
2   //$Id: SessionHandler.java,v 1.5 2005/11/11 22:55:39 gregwilkins Exp $
3   //Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
4   //------------------------------------------------------------------------
5   //Licensed under the Apache License, Version 2.0 (the "License");
6   //you may not use this file except in compliance with the License.
7   //You may obtain a copy of the License at 
8   //http://www.apache.org/licenses/LICENSE-2.0
9   //Unless required by applicable law or agreed to in writing, software
10  //distributed under the License is distributed on an "AS IS" BASIS,
11  //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  //See the License for the specific language governing permissions and
13  //limitations under the License.
14  //========================================================================
15  
16  package org.mortbay.jetty.servlet;
17  
18  import java.io.IOException;
19  import java.util.EventListener;
20  
21  import javax.servlet.ServletException;
22  import javax.servlet.http.Cookie;
23  import javax.servlet.http.HttpServletRequest;
24  import javax.servlet.http.HttpServletResponse;
25  import javax.servlet.http.HttpSession;
26  
27  import org.mortbay.jetty.HttpConnection;
28  import org.mortbay.jetty.Request;
29  import org.mortbay.jetty.RetryRequest;
30  import org.mortbay.jetty.Server;
31  import org.mortbay.jetty.SessionManager;
32  import org.mortbay.jetty.handler.HandlerWrapper;
33  import org.mortbay.log.Log;
34  
35  /* ------------------------------------------------------------ */
36  /** SessionHandler.
37   * 
38   * @author gregw
39   *
40   */
41  public class SessionHandler extends HandlerWrapper
42  {
43      /* -------------------------------------------------------------- */
44      private SessionManager _sessionManager;
45  
46      /* ------------------------------------------------------------ */
47      /** Constructor.
48       * Construct a SessionHandler witha a HashSessionManager with a standard
49       * java.util.Random generator is created.
50       */
51      public SessionHandler()
52      {   
53          this(new HashSessionManager());
54      }
55      
56      /* ------------------------------------------------------------ */
57      /**
58       * @param manager The session manager
59       */
60      public SessionHandler(SessionManager manager)
61      {
62          setSessionManager(manager);
63      }
64      
65      /* ------------------------------------------------------------ */
66      /**
67       * @return Returns the sessionManager.
68       */
69      public SessionManager getSessionManager()
70      {
71          return _sessionManager;
72      }
73      
74      /* ------------------------------------------------------------ */
75      /**
76       * @param sessionManager The sessionManager to set.
77       */
78      public void setSessionManager(SessionManager sessionManager)
79      {
80          if (isStarted())
81              throw new IllegalStateException();
82          SessionManager old_session_manager = _sessionManager;
83          
84          if (getServer()!=null)
85              getServer().getContainer().update(this, old_session_manager, sessionManager, "sessionManager",true);
86          
87          if (sessionManager!=null)
88              sessionManager.setSessionHandler(this);
89          
90          _sessionManager = sessionManager;
91          
92          if (old_session_manager!=null)
93              old_session_manager.setSessionHandler(null);
94      }
95  
96  
97      /* ------------------------------------------------------------ */
98      public void setServer(Server server)
99      {
100         Server old_server=getServer();
101         if (old_server!=null && old_server!=server)
102             old_server.getContainer().update(this, _sessionManager, null, "sessionManager",true);
103         super.setServer(server);
104         if (server!=null && server!=old_server)
105             server.getContainer().update(this, null,_sessionManager, "sessionManager",true);
106     }
107     
108     
109     /* ------------------------------------------------------------ */
110     /* 
111      * @see org.mortbay.thread.AbstractLifeCycle#doStart()
112      */
113     protected void doStart() throws Exception
114     {
115         _sessionManager.start();
116         super.doStart();
117     }
118     /* ------------------------------------------------------------ */
119     /* 
120      * @see org.mortbay.thread.AbstractLifeCycle#doStop()
121      */
122     protected void doStop() throws Exception
123     {
124         super.doStop();
125         _sessionManager.stop();
126     }
127     
128     /* ------------------------------------------------------------ */
129     /* 
130      * @see org.mortbay.jetty.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
131      */
132     public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch)
133             throws IOException, ServletException
134     {
135         setRequestedId(request, dispatch);
136         
137         Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
138         SessionManager old_session_manager=null;
139         HttpSession old_session=null;
140         
141         try
142         {
143             old_session_manager = base_request.getSessionManager();
144             old_session = base_request.getSession(false);
145             
146             if (old_session_manager != _sessionManager)
147             {
148                 // new session context
149                 base_request.setSessionManager(_sessionManager);
150                 base_request.setSession(null);
151             }
152             
153             // access any existing session
154             HttpSession session=null;
155             if (_sessionManager!=null)
156             {
157                 session=base_request.getSession(false);
158                 if (session!=null)
159                 {
160                     if(session!=old_session)
161                     {
162                         Cookie cookie = _sessionManager.access(session,request.isSecure());
163                         if (cookie!=null ) // Handle changed ID or max-age refresh
164                             response.addCookie(cookie);
165                     }
166                 }
167                 else 
168                 {
169                     session=base_request.recoverNewSession(_sessionManager);
170                     if (session!=null)
171                         base_request.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, request, response, dispatch);
182         }
183         catch (RetryRequest r)
184         {
185             HttpSession session=base_request.getSession(false);
186             if (session!=null && session.isNew())
187                 base_request.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                 base_request.setSessionManager(old_session_manager);
200                 base_request.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, int dispatch) 
211     {
212         Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
213         String requested_session_id=request.getRequestedSessionId();
214         if (dispatch!=REQUEST || 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.getSessionURL();
260                 if (param!=null && path_params!=null && path_params.startsWith(param))
261                 {
262                     requested_session_id = path_params.substring(sessionManager.getSessionURL().length()+1);
263                     if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from URL");
264                 }
265             }
266         }
267         
268         base_request.setRequestedSessionId(requested_session_id);
269         base_request.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 }