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  import org.mortbay.util.StringUtil;
35  
36  /* ------------------------------------------------------------ */
37  /** SessionHandler.
38   * 
39   * @author gregw
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.mortbay.thread.AbstractLifeCycle#doStart()
113      */
114     protected void doStart() throws Exception
115     {
116         _sessionManager.start();
117         super.doStart();
118     }
119     /* ------------------------------------------------------------ */
120     /* 
121      * @see org.mortbay.thread.AbstractLifeCycle#doStop()
122      */
123     protected void doStop() throws Exception
124     {
125         super.doStop();
126         _sessionManager.stop();
127     }
128     
129     /* ------------------------------------------------------------ */
130     /* 
131      * @see org.mortbay.jetty.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
132      */
133     public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch)
134             throws IOException, ServletException
135     {
136         setRequestedId(request, dispatch);
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                         Cookie cookie = _sessionManager.access(session,request.isSecure());
164                         if (cookie!=null ) // Handle changed ID or max-age refresh
165                             response.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, dispatch);
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                 
201                 // Leave last session in place
202                 if (old_session_manager != null)
203                 {
204                     base_request.setSessionManager(old_session_manager);
205                     base_request.setSession(old_session);
206                 }
207             }
208         }
209     }
210     
211     /* ------------------------------------------------------------ */
212     /** Look for a requested session ID in cookies and URI parameters
213      * @param request
214      * @param dispatch
215      */
216     protected void setRequestedId(HttpServletRequest request, int dispatch) 
217     {
218         Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
219         String requested_session_id=request.getRequestedSessionId();
220         if (dispatch!=REQUEST || requested_session_id!=null)
221         {
222             return;
223         }
224         
225         final SessionManager sessionManager = getSessionManager();
226         boolean requested_session_id_from_cookie=false;
227         HttpSession session=null;
228         // Look for session id cookie    
229         if (_sessionManager.isUsingCookies())
230         {
231             Cookie[] cookies=request.getCookies();
232             if (cookies!=null && cookies.length>0)
233             {
234                 for (int i=0;i<cookies.length;i++)
235                 {
236                     if (sessionManager.getSessionCookie().equalsIgnoreCase(cookies[i].getName()))
237                     {
238                         if (requested_session_id!=null)
239                         {
240                             // Multiple jsessionid cookies. Probably due to
241                             // multiple paths and/or domains. Pick the first
242                             // known session or the last defined cookie.
243                             if (sessionManager.getHttpSession(requested_session_id)!=null)
244                                 break;
245                         }
246 
247                         requested_session_id=cookies[i].getValue();
248                         requested_session_id_from_cookie = true;
249                         if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from cookie");
250                         
251                         session=sessionManager.getHttpSession(requested_session_id);
252                         if (session!=null)
253                             base_request.setSession(session);
254                     }
255                 }
256             }
257         }
258         
259         if (requested_session_id==null || session==null)
260         {
261             String uri = request.getRequestURI();
262 
263             String prefix=sessionManager.getSessionURLPrefix();
264             if (prefix!=null)
265             {
266                 int s = uri.indexOf(prefix);
267                 if (s>=0)
268                 {   
269                     s+=prefix.length();
270                     int i=s;
271                     while (i<uri.length())
272                     {
273                         char c=uri.charAt(i);
274                         if (c==';'||c=='#'||c=='?'||c=='/')
275                             break;
276                         i++;
277                     }
278 
279                     requested_session_id = uri.substring(s,i);
280                     requested_session_id_from_cookie = false;
281                     if(Log.isDebugEnabled())
282                         Log.debug("Got Session ID "+requested_session_id+" from URL");                    
283                 }
284             }
285         }
286         
287         base_request.setRequestedSessionId(requested_session_id);
288         base_request.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie);
289     }
290     
291     /* ------------------------------------------------------------ */
292     /**
293      * @param listener
294      */
295     public void addEventListener(EventListener listener)
296     {
297         if(_sessionManager!=null)
298             _sessionManager.addEventListener(listener);
299     }
300 
301     /* ------------------------------------------------------------ */
302     public void clearEventListeners()
303     {
304         if(_sessionManager!=null)
305             _sessionManager.clearEventListeners();
306     }
307 }