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.Request;
28  import org.eclipse.jetty.server.Server;
29  import org.eclipse.jetty.server.SessionManager;
30  import org.eclipse.jetty.server.handler.HandlerWrapper;
31  import org.eclipse.jetty.server.handler.ScopedHandler;
32  import org.eclipse.jetty.util.log.Log;
33  
34  /* ------------------------------------------------------------ */
35  /** SessionHandler.
36   */
37  public class SessionHandler extends ScopedHandler
38  {
39      /* -------------------------------------------------------------- */
40      private SessionManager _sessionManager;
41  
42      /* ------------------------------------------------------------ */
43      /** Constructor.
44       * Construct a SessionHandler witha a HashSessionManager with a standard
45       * java.util.Random generator is created.
46       */
47      public SessionHandler()
48      {
49          this(new HashSessionManager());
50      }
51  
52      /* ------------------------------------------------------------ */
53      /**
54       * @param manager The session manager
55       */
56      public SessionHandler(SessionManager manager)
57      {
58          setSessionManager(manager);
59      }
60  
61      /* ------------------------------------------------------------ */
62      /**
63       * @return Returns the sessionManager.
64       */
65      public SessionManager getSessionManager()
66      {
67          return _sessionManager;
68      }
69  
70      /* ------------------------------------------------------------ */
71      /**
72       * @param sessionManager The sessionManager to set.
73       */
74      public void setSessionManager(SessionManager sessionManager)
75      {
76          if (isStarted())
77              throw new IllegalStateException();
78          SessionManager old_session_manager = _sessionManager;
79  
80          if (getServer()!=null)
81              getServer().getContainer().update(this, old_session_manager, sessionManager, "sessionManager",true);
82  
83          if (sessionManager!=null)
84              sessionManager.setSessionHandler(this);
85  
86          _sessionManager = sessionManager;
87  
88          if (old_session_manager!=null)
89              old_session_manager.setSessionHandler(null);
90      }
91  
92  
93      /* ------------------------------------------------------------ */
94      @Override
95      public void setServer(Server server)
96      {
97          Server old_server=getServer();
98          if (old_server!=null && old_server!=server)
99              old_server.getContainer().update(this, _sessionManager, null, "sessionManager",true);
100         super.setServer(server);
101         if (server!=null && server!=old_server)
102             server.getContainer().update(this, null,_sessionManager, "sessionManager",true);
103     }
104 
105 
106     /* ------------------------------------------------------------ */
107     /*
108      * @see org.eclipse.thread.AbstractLifeCycle#doStart()
109      */
110     @Override
111     protected void doStart() throws Exception
112     {
113         _sessionManager.start();
114         super.doStart();
115     }
116     /* ------------------------------------------------------------ */
117     /*
118      * @see org.eclipse.thread.AbstractLifeCycle#doStop()
119      */
120     @Override
121     protected void doStop() throws Exception
122     {
123         // Destroy sessions before destroying servlets/filters see JETTY-1266
124         _sessionManager.stop();
125         super.doStop();
126     }
127 
128     
129     /* ------------------------------------------------------------ */
130     /*
131      * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
132      */
133     @Override
134     public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
135             throws IOException, ServletException
136     {
137         setRequestedId(baseRequest,request);
138 
139         SessionManager old_session_manager=null;
140         HttpSession old_session=null;
141 
142         try
143         {
144             old_session_manager = baseRequest.getSessionManager();
145             old_session = baseRequest.getSession(false);
146 
147             if (old_session_manager != _sessionManager)
148             {
149                 // new session context
150                 baseRequest.setSessionManager(_sessionManager);
151                 baseRequest.setSession(null);
152             }
153 
154             // access any existing session
155             HttpSession session=null;
156             if (_sessionManager!=null)
157             {
158                 session=baseRequest.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                             baseRequest.getResponse().addCookie(cookie);
166                     }
167                 }
168                 else
169                 {
170                     session=baseRequest.recoverNewSession(_sessionManager);
171                     if (session!=null)
172                         baseRequest.setSession(session);
173                 }
174             }
175 
176             if(Log.isDebugEnabled())
177             {
178                 Log.debug("sessionManager="+_sessionManager);
179                 Log.debug("session="+session);
180             }
181 
182             // start manual inline of nextScope(target,baseRequest,request,response);
183             if (_nextScope!=null)
184                 _nextScope.doScope(target,baseRequest,request, response);
185             else if (_outerScope!=null)
186                 _outerScope.doHandle(target,baseRequest,request, response);
187             else 
188                 doHandle(target,baseRequest,request, response);
189             // end manual inline (pathentic attempt to reduce stack depth)
190             
191         }
192         finally
193         {
194             HttpSession session=request.getSession(false);
195 
196             if (old_session_manager != _sessionManager)
197             {
198                 //leaving context, free up the session
199                 if (session!=null)
200                     _sessionManager.complete(session);
201                 
202                 // Leave last session in place
203                 if (old_session_manager!=null )
204                 {
205                     baseRequest.setSessionManager(old_session_manager);
206                     baseRequest.setSession(old_session);
207                 }
208             }
209         }
210     }
211 
212     /* ------------------------------------------------------------ */
213     /*
214      * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
215      */
216     @Override
217     public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
218             throws IOException, ServletException
219     {
220         // start manual inline of nextHandle(target,baseRequest,request,response);
221         if (never())
222             nextHandle(target,baseRequest,request,response);
223         else if (_nextScope!=null && _nextScope==_handler)
224             _nextScope.doHandle(target,baseRequest,request, response);
225         else if (_handler!=null)
226             _handler.handle(target,baseRequest, request, response);
227         // end manual inline
228     }
229 
230     /* ------------------------------------------------------------ */
231     /** Look for a requested session ID in cookies and URI parameters
232      * @param baseRequest
233      * @param request
234      */
235     protected void setRequestedId(Request baseRequest, HttpServletRequest request)
236     {
237         String requested_session_id=request.getRequestedSessionId();
238         if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()) || requested_session_id!=null)
239             return;
240 
241         SessionManager sessionManager = getSessionManager();
242         boolean requested_session_id_from_cookie=false;
243         HttpSession session=null;
244 
245         // Look for session id cookie
246         if (_sessionManager.isUsingCookies())
247         {
248             Cookie[] cookies=request.getCookies();
249             if (cookies!=null && cookies.length>0)
250             {
251                 for (int i=0;i<cookies.length;i++)
252                 {
253                     if (sessionManager.getSessionCookie().equalsIgnoreCase(cookies[i].getName()))
254                     {
255                         if (requested_session_id!=null)
256                         {
257                             // Multiple jsessionid cookies. Probably due to
258                             // multiple paths and/or domains. Pick the first
259                             // known session or the last defined cookie.
260                             if (sessionManager.getHttpSession(requested_session_id)!=null)
261                                 break;
262                         }
263 
264                         requested_session_id=cookies[i].getValue();
265                         requested_session_id_from_cookie = true;
266                         if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from cookie");
267                         
268                         session=sessionManager.getHttpSession(requested_session_id);
269                         if (session!=null)
270                             baseRequest.setSession(session);
271                     }
272                 }
273             }
274         }
275 
276         if (requested_session_id==null || session==null)
277         {
278             String uri = request.getRequestURI();
279 
280             String prefix=sessionManager.getSessionIdPathParameterNamePrefix();
281             if (prefix!=null)
282             {
283                 int s = uri.indexOf(prefix);
284                 if (s>=0)
285                 {   
286                     s+=prefix.length();
287                     int i=s;
288                     while (i<uri.length())
289                     {
290                         char c=uri.charAt(i);
291                         if (c==';'||c=='#'||c=='?'||c=='/')
292                             break;
293                         i++;
294                     }
295 
296                     requested_session_id = uri.substring(s,i);
297                     requested_session_id_from_cookie = false;
298                     if(Log.isDebugEnabled())
299                         Log.debug("Got Session ID "+requested_session_id+" from URL");                    
300                 }
301             }
302         }
303 
304         baseRequest.setRequestedSessionId(requested_session_id);
305         baseRequest.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie);
306     }
307 
308     /* ------------------------------------------------------------ */
309     /**
310      * @param listener
311      */
312     public void addEventListener(EventListener listener)
313     {
314         if(_sessionManager!=null)
315             _sessionManager.addEventListener(listener);
316     }
317 
318     /* ------------------------------------------------------------ */
319     public void clearEventListeners()
320     {
321         if(_sessionManager!=null)
322             _sessionManager.clearEventListeners();
323     }
324 }