2 // ========================================================================
3 // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
19 package org.eclipse.jetty.server.session;
21 import java.io.IOException;
22 import java.util.EnumSet;
23 import java.util.EventListener;
25 import javax.servlet.DispatcherType;
26 import javax.servlet.ServletException;
27 import javax.servlet.SessionTrackingMode;
28 import javax.servlet.http.Cookie;
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletResponse;
31 import javax.servlet.http.HttpSession;
32 import javax.servlet.http.HttpSessionAttributeListener;
33 import javax.servlet.http.HttpSessionIdListener;
34 import javax.servlet.http.HttpSessionListener;
36 import org.eclipse.jetty.http.HttpCookie;
37 import org.eclipse.jetty.server.Request;
38 import org.eclipse.jetty.server.SessionManager;
39 import org.eclipse.jetty.server.handler.ScopedHandler;
40 import org.eclipse.jetty.util.log.Log;
41 import org.eclipse.jetty.util.log.Logger;
43 /* ------------------------------------------------------------ */
47 public class SessionHandler extends ScopedHandler
49 final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
51 public final static EnumSet<SessionTrackingMode> DEFAULT_TRACKING = EnumSet.of(SessionTrackingMode.COOKIE,SessionTrackingMode.URL);
53 @SuppressWarnings("unchecked")
54 public static final Class<? extends EventListener>[] SESSION_LISTENER_TYPES =
55 new Class[] {HttpSessionAttributeListener.class,
56 HttpSessionIdListener.class,
57 HttpSessionListener.class};
61 /* -------------------------------------------------------------- */
62 private SessionManager _sessionManager;
64 /* ------------------------------------------------------------ */
66 * Constructor. Construct a SessionHandler witha a HashSessionManager with a standard java.util.Random generator is created.
68 public SessionHandler()
70 this(new HashSessionManager());
73 /* ------------------------------------------------------------ */
78 public SessionHandler(SessionManager manager)
80 setSessionManager(manager);
83 /* ------------------------------------------------------------ */
85 * @return Returns the sessionManager.
87 public SessionManager getSessionManager()
89 return _sessionManager;
92 /* ------------------------------------------------------------ */
94 * @param sessionManager
95 * The sessionManager to set.
97 public void setSessionManager(SessionManager sessionManager)
100 throw new IllegalStateException();
101 if (sessionManager != null)
102 sessionManager.setSessionHandler(this);
103 updateBean(_sessionManager,sessionManager);
104 _sessionManager=sessionManager;
107 /* ------------------------------------------------------------ */
109 * @see org.eclipse.thread.AbstractLifeCycle#doStart()
112 protected void doStart() throws Exception
114 if (_sessionManager==null)
115 setSessionManager(new HashSessionManager());
119 /* ------------------------------------------------------------ */
121 * @see org.eclipse.thread.AbstractLifeCycle#doStop()
124 protected void doStop() throws Exception
126 // Destroy sessions before destroying servlets/filters see JETTY-1266
131 /* ------------------------------------------------------------ */
133 * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
136 public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
138 SessionManager old_session_manager = null;
139 HttpSession old_session = null;
140 HttpSession access = null;
143 old_session_manager = baseRequest.getSessionManager();
144 old_session = baseRequest.getSession(false);
146 if (old_session_manager != _sessionManager)
148 // new session context
149 baseRequest.setSessionManager(_sessionManager);
150 baseRequest.setSession(null);
151 checkRequestedSessionId(baseRequest,request);
154 // access any existing session
155 HttpSession session = null;
156 if (_sessionManager != null)
158 session = baseRequest.getSession(false);
161 if (session != old_session)
164 HttpCookie cookie = _sessionManager.access(session,request.isSecure());
165 if (cookie != null) // Handle changed ID or max-age refresh
166 baseRequest.getResponse().addCookie(cookie);
171 session = baseRequest.recoverNewSession(_sessionManager);
173 baseRequest.setSession(session);
177 if (LOG.isDebugEnabled())
179 LOG.debug("sessionManager=" + _sessionManager);
180 LOG.debug("session=" + session);
183 // start manual inline of nextScope(target,baseRequest,request,response);
184 if (_nextScope != null)
185 _nextScope.doScope(target,baseRequest,request,response);
186 else if (_outerScope != null)
187 _outerScope.doHandle(target,baseRequest,request,response);
189 doHandle(target,baseRequest,request,response);
190 // end manual inline (pathentic attempt to reduce stack depth)
196 _sessionManager.complete(access);
198 HttpSession session = baseRequest.getSession(false);
199 if (session != null && old_session == null && session != access)
200 _sessionManager.complete(session);
202 if (old_session_manager != null && old_session_manager != _sessionManager)
204 baseRequest.setSessionManager(old_session_manager);
205 baseRequest.setSession(old_session);
210 /* ------------------------------------------------------------ */
212 * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
215 public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
217 // start manual inline of nextHandle(target,baseRequest,request,response);
219 nextHandle(target,baseRequest,request,response);
220 else if (_nextScope != null && _nextScope == _handler)
221 _nextScope.doHandle(target,baseRequest,request,response);
222 else if (_handler != null)
223 _handler.handle(target,baseRequest,request,response);
227 /* ------------------------------------------------------------ */
229 * Look for a requested session ID in cookies and URI parameters
234 protected void checkRequestedSessionId(Request baseRequest, HttpServletRequest request)
236 String requested_session_id = request.getRequestedSessionId();
238 SessionManager sessionManager = getSessionManager();
240 if (requested_session_id != null && sessionManager != null)
242 HttpSession session = sessionManager.getHttpSession(requested_session_id);
243 if (session != null && sessionManager.isValid(session))
244 baseRequest.setSession(session);
247 else if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()))
250 boolean requested_session_id_from_cookie = false;
251 HttpSession session = null;
253 // Look for session id cookie
254 if (_sessionManager.isUsingCookies())
256 Cookie[] cookies = request.getCookies();
257 if (cookies != null && cookies.length > 0)
259 final String sessionCookie=sessionManager.getSessionCookieConfig().getName();
260 for (int i = 0; i < cookies.length; i++)
262 if (sessionCookie.equalsIgnoreCase(cookies[i].getName()))
264 requested_session_id = cookies[i].getValue();
265 requested_session_id_from_cookie = true;
267 if (LOG.isDebugEnabled())
268 LOG.debug("Got Session ID {} from cookie",requested_session_id);
270 if (requested_session_id != null)
272 session = sessionManager.getHttpSession(requested_session_id);
274 if (session != null && sessionManager.isValid(session))
281 LOG.warn("null session id from cookie");
288 if (requested_session_id == null || session == null)
290 String uri = request.getRequestURI();
292 String prefix = sessionManager.getSessionIdPathParameterNamePrefix();
295 int s = uri.indexOf(prefix);
298 s += prefix.length();
300 while (i < uri.length())
302 char c = uri.charAt(i);
303 if (c == ';' || c == '#' || c == '?' || c == '/')
308 requested_session_id = uri.substring(s,i);
309 requested_session_id_from_cookie = false;
310 session = sessionManager.getHttpSession(requested_session_id);
311 if (LOG.isDebugEnabled())
312 LOG.debug("Got Session ID {} from URL",requested_session_id);
317 baseRequest.setRequestedSessionId(requested_session_id);
318 baseRequest.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie);
319 if (session != null && sessionManager.isValid(session))
320 baseRequest.setSession(session);
323 /* ------------------------------------------------------------ */
327 public void addEventListener(EventListener listener)
329 if (_sessionManager != null)
330 _sessionManager.addEventListener(listener);
333 /* ------------------------------------------------------------ */
337 public void removeEventListener(EventListener listener)
339 if (_sessionManager != null)
340 _sessionManager.removeEventListener(listener);
343 /* ------------------------------------------------------------ */
344 public void clearEventListeners()
346 if (_sessionManager != null)
347 _sessionManager.clearEventListeners();