blob: 6df6acd4dad67e0fe92bf3dde284a1a9965d0d15 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import static java.lang.Math.round;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionIdListener;
import javax.servlet.http.HttpSessionListener;
import org.eclipse.jetty.http.HttpCookie;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedOperation;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.statistic.CounterStatistic;
import org.eclipse.jetty.util.statistic.SampleStatistic;
/**
* SessionManager
*
* Handles session lifecycle. There is one SessionManager per context.
*
*/
public class SessionManager extends ContainerLifeCycle implements org.eclipse.jetty.server.SessionManager
{
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
public Set<SessionTrackingMode> __defaultSessionTrackingModes =
Collections.unmodifiableSet(
new HashSet<SessionTrackingMode>(
Arrays.asList(new SessionTrackingMode[]{SessionTrackingMode.COOKIE,SessionTrackingMode.URL})));
/* ------------------------------------------------------------ */
public final static int __distantFuture=60*60*24*7*52*20;
static final HttpSessionContext __nullSessionContext=new HttpSessionContext()
{
@Override
public HttpSession getSession(String sessionId)
{
return null;
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Enumeration getIds()
{
return Collections.enumeration(Collections.EMPTY_LIST);
}
};
/* ------------------------------------------------------------ */
// Setting of max inactive interval for new sessions
// -1 means no timeout
protected int _dftMaxIdleSecs=-1;
protected SessionHandler _sessionHandler;
protected boolean _httpOnly=false;
protected SessionIdManager _sessionIdManager;
protected boolean _secureCookies=false;
protected boolean _secureRequestOnly=true;
protected final List<HttpSessionAttributeListener> _sessionAttributeListeners = new CopyOnWriteArrayList<HttpSessionAttributeListener>();
protected final List<HttpSessionListener> _sessionListeners= new CopyOnWriteArrayList<HttpSessionListener>();
protected final List<HttpSessionIdListener> _sessionIdListeners = new CopyOnWriteArrayList<HttpSessionIdListener>();
protected ClassLoader _loader;
protected ContextHandler.Context _context;
protected SessionContext _sessionContext;
protected String _sessionCookie=__DefaultSessionCookie;
protected String _sessionIdPathParameterName = __DefaultSessionIdPathParameterName;
protected String _sessionIdPathParameterNamePrefix =";"+ _sessionIdPathParameterName +"=";
protected String _sessionDomain;
protected String _sessionPath;
protected int _maxCookieAge=-1;
protected int _refreshCookieAge;
protected boolean _nodeIdInSessionId;
protected boolean _checkingRemoteSessionIdEncoding;
protected String _sessionComment;
protected SessionStore _sessionStore;
protected final SampleStatistic _sessionTimeStats = new SampleStatistic();
protected final CounterStatistic _sessionsCreatedStats = new CounterStatistic();
public Set<SessionTrackingMode> _sessionTrackingModes;
private boolean _usingURLs;
private boolean _usingCookies=true;
/* ------------------------------------------------------------ */
public SessionManager()
{
setSessionTrackingModes(__defaultSessionTrackingModes);
}
/* ------------------------------------------------------------ */
public ContextHandler.Context getContext()
{
return _context;
}
/* ------------------------------------------------------------ */
public ContextHandler getContextHandler()
{
return _context.getContextHandler();
}
/* ------------------------------------------------------------ */
@ManagedAttribute("path of the session cookie, or null for default")
public String getSessionPath()
{
return _sessionPath;
}
/* ------------------------------------------------------------ */
@ManagedAttribute("if greater the zero, the time in seconds a session cookie will last for")
public int getMaxCookieAge()
{
return _maxCookieAge;
}
/* ------------------------------------------------------------ */
@Override
public HttpCookie access(HttpSession session,boolean secure)
{
long now=System.currentTimeMillis();
Session s = ((SessionIf)session).getSession();
if (s.access(now))
{
// Do we need to refresh the cookie?
if (isUsingCookies() &&
(s.isIdChanged() ||
(getSessionCookieConfig().getMaxAge()>0 && getRefreshCookieAge()>0 && ((now-s.getCookieSetTime())/1000>getRefreshCookieAge()))
)
)
{
HttpCookie cookie=getSessionCookie(session,_context==null?"/":(_context.getContextPath()),secure);
s.cookieSet();
s.setIdChanged(false);
return cookie;
}
}
return null;
}
/* ------------------------------------------------------------ */
@Override
public void addEventListener(EventListener listener)
{
if (listener instanceof HttpSessionAttributeListener)
_sessionAttributeListeners.add((HttpSessionAttributeListener)listener);
if (listener instanceof HttpSessionListener)
_sessionListeners.add((HttpSessionListener)listener);
if (listener instanceof HttpSessionIdListener)
_sessionIdListeners.add((HttpSessionIdListener)listener);
addBean(listener,false);
}
/* ------------------------------------------------------------ */
@Override
public void clearEventListeners()
{
for (EventListener e :getBeans(EventListener.class))
removeBean(e);
_sessionAttributeListeners.clear();
_sessionListeners.clear();
_sessionIdListeners.clear();
}
/* ------------------------------------------------------------ */
@Override
public void complete(HttpSession session)
{
Session s = ((SessionIf)session).getSession();
s.complete();
try
{
if (s.isValid())
_sessionStore.put(s.getId(), s);
}
catch (Exception e)
{
LOG.warn(e);
}
}
/* ------------------------------------------------------------ */
@Override
public void doStart() throws Exception
{
if (_sessionStore == null)
throw new IllegalStateException("No session store configured");
_context=ContextHandler.getCurrentContext();
_loader=Thread.currentThread().getContextClassLoader();
final Server server=getSessionHandler().getServer();
synchronized (server)
{
if (_sessionIdManager==null)
{
_sessionIdManager=server.getSessionIdManager();
if (_sessionIdManager==null)
{
//create a default SessionIdManager and set it as the shared
//SessionIdManager for the Server, being careful NOT to use
//the webapp context's classloader, otherwise if the context
//is stopped, the classloader is leaked.
ClassLoader serverLoader = server.getClass().getClassLoader();
try
{
Thread.currentThread().setContextClassLoader(serverLoader);
_sessionIdManager=new HashSessionIdManager(server);
server.setSessionIdManager(_sessionIdManager);
server.manage(_sessionIdManager);
_sessionIdManager.start();
}
finally
{
Thread.currentThread().setContextClassLoader(_loader);
}
}
// server session id is never managed by this manager
addBean(_sessionIdManager,false);
}
}
// Look for a session cookie name
if (_context!=null)
{
String tmp=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__SessionCookieProperty);
if (tmp!=null)
_sessionCookie=tmp;
tmp=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__SessionIdPathParameterNameProperty);
if (tmp!=null)
setSessionIdPathParameterName(tmp);
// set up the max session cookie age if it isn't already
if (_maxCookieAge==-1)
{
tmp=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__MaxAgeProperty);
if (tmp!=null)
_maxCookieAge=Integer.parseInt(tmp.trim());
}
// set up the session domain if it isn't already
if (_sessionDomain==null)
_sessionDomain=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__SessionDomainProperty);
// set up the sessionPath if it isn't already
if (_sessionPath==null)
_sessionPath=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__SessionPathProperty);
tmp=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__CheckRemoteSessionEncoding);
if (tmp!=null)
_checkingRemoteSessionIdEncoding=Boolean.parseBoolean(tmp);
}
_sessionContext = new SessionContext(_sessionIdManager.getWorkerName(), _context);
if (_sessionStore instanceof AbstractSessionStore)
((AbstractSessionStore)_sessionStore).setSessionManager(this);
_sessionStore.initialize(_sessionContext);
_sessionStore.start();
super.doStart();
}
/* ------------------------------------------------------------ */
@Override
public void doStop() throws Exception
{
shutdownSessions();
_sessionStore.stop();
super.doStop();
_loader=null;
}
/* ------------------------------------------------------------ */
/**
* @return Returns the httpOnly.
*/
@Override
@ManagedAttribute("true if cookies use the http only flag")
public boolean getHttpOnly()
{
return _httpOnly;
}
/* ------------------------------------------------------------ */
@Override
public HttpSession getHttpSession(String extendedId)
{
String id = getSessionIdManager().getId(extendedId);
Session session = getSession(id);
if (session!=null && !session.getExtendedId().equals(extendedId))
session.setIdChanged(true);
return session;
}
/* ------------------------------------------------------------ */
/**
* @return Returns the SessionIdManager used for cross context session management
*/
@Override
@ManagedAttribute("Session ID Manager")
public SessionIdManager getSessionIdManager()
{
return _sessionIdManager;
}
/* ------------------------------------------------------------ */
/**
* @return seconds
*/
@Override
@ManagedAttribute("default maximum time a session may be idle for (in s)")
public int getMaxInactiveInterval()
{
return _dftMaxIdleSecs;
}
/* ------------------------------------------------------------ */
@ManagedAttribute("time before a session cookie is re-set (in s)")
public int getRefreshCookieAge()
{
return _refreshCookieAge;
}
/* ------------------------------------------------------------ */
/**
* @return same as SessionCookieConfig.getSecure(). If true, session
* cookies are ALWAYS marked as secure. If false, a session cookie is
* ONLY marked as secure if _secureRequestOnly == true and it is a HTTPS request.
*/
@ManagedAttribute("if true, secure cookie flag is set on session cookies")
public boolean getSecureCookies()
{
return _secureCookies;
}
/* ------------------------------------------------------------ */
/**
* @return true if session cookie is to be marked as secure only on HTTPS requests
*/
public boolean isSecureRequestOnly()
{
return _secureRequestOnly;
}
/* ------------------------------------------------------------ */
/**
* HTTPS request. Can be overridden by setting SessionCookieConfig.setSecure(true),
* in which case the session cookie will be marked as secure on both HTTPS and HTTP.
* @param secureRequestOnly true to set Session Cookie Config as secure
*/
public void setSecureRequestOnly(boolean secureRequestOnly)
{
_secureRequestOnly = secureRequestOnly;
}
/* ------------------------------------------------------------ */
@ManagedAttribute("the set session cookie")
public String getSessionCookie()
{
return _sessionCookie;
}
/* ------------------------------------------------------------ */
/**
* A sessioncookie is marked as secure IFF any of the following conditions are true:
* <ol>
* <li>SessionCookieConfig.setSecure == true</li>
* <li>SessionCookieConfig.setSecure == false &amp;&amp; _secureRequestOnly==true &amp;&amp; request is HTTPS</li>
* </ol>
* According to SessionCookieConfig javadoc, case 1 can be used when:
* "... even though the request that initiated the session came over HTTP,
* is to support a topology where the web container is front-ended by an
* SSL offloading load balancer. In this case, the traffic between the client
* and the load balancer will be over HTTPS, whereas the traffic between the
* load balancer and the web container will be over HTTP."
* <p>
* For case 2, you can use _secureRequestOnly to determine if you want the
* Servlet Spec 3.0 default behavior when SessionCookieConfig.setSecure==false,
* which is:
* <cite>
* "they shall be marked as secure only if the request that initiated the
* corresponding session was also secure"
* </cite>
* <p>
* The default for _secureRequestOnly is true, which gives the above behavior. If
* you set it to false, then a session cookie is NEVER marked as secure, even if
* the initiating request was secure.
*
* @see org.eclipse.jetty.server.SessionManager#getSessionCookie(javax.servlet.http.HttpSession, java.lang.String, boolean)
*/
@Override
public HttpCookie getSessionCookie(HttpSession session, String contextPath, boolean requestIsSecure)
{
if (isUsingCookies())
{
String sessionPath = (_cookieConfig.getPath()==null) ? contextPath : _cookieConfig.getPath();
sessionPath = (sessionPath==null||sessionPath.length()==0) ? "/" : sessionPath;
String id = getExtendedId(session);
HttpCookie cookie = null;
if (_sessionComment == null)
{
cookie = new HttpCookie(
_cookieConfig.getName(),
id,
_cookieConfig.getDomain(),
sessionPath,
_cookieConfig.getMaxAge(),
_cookieConfig.isHttpOnly(),
_cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure));
}
else
{
cookie = new HttpCookie(
_cookieConfig.getName(),
id,
_cookieConfig.getDomain(),
sessionPath,
_cookieConfig.getMaxAge(),
_cookieConfig.isHttpOnly(),
_cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure),
_sessionComment,
1);
}
return cookie;
}
return null;
}
/* ------------------------------------------------------------ */
@ManagedAttribute("domain of the session cookie, or null for the default")
public String getSessionDomain()
{
return _sessionDomain;
}
/* ------------------------------------------------------------ */
/**
* @return Returns the sessionHandler.
*/
public SessionHandler getSessionHandler()
{
return _sessionHandler;
}
/* ------------------------------------------------------------ */
@ManagedAttribute("number of sessions created by this node")
public int getSessionsCreated()
{
return (int) _sessionsCreatedStats.getCurrent();
}
/* ------------------------------------------------------------ */
@Override
@ManagedAttribute("name of use for URL session tracking")
public String getSessionIdPathParameterName()
{
return _sessionIdPathParameterName;
}
/* ------------------------------------------------------------ */
@Override
public String getSessionIdPathParameterNamePrefix()
{
return _sessionIdPathParameterNamePrefix;
}
/* ------------------------------------------------------------ */
/**
* @return Returns the usingCookies.
*/
@Override
public boolean isUsingCookies()
{
return _usingCookies;
}
/* ------------------------------------------------------------ */
@Override
public boolean isValid(HttpSession session)
{
Session s = ((SessionIf)session).getSession();
return s.isValid();
}
/* ------------------------------------------------------------ */
@Override
public String getId(HttpSession session)
{
Session s = ((SessionIf)session).getSession();
return s.getId();
}
/* ------------------------------------------------------------ */
@Override
public String getExtendedId(HttpSession session)
{
Session s = ((SessionIf)session).getSession();
return s.getExtendedId();
}
/* ------------------------------------------------------------ */
/**
* Create a new HttpSession for a request
*/
@Override
public HttpSession newHttpSession(HttpServletRequest request)
{
long created=System.currentTimeMillis();
String id =_sessionIdManager.newSessionId(request,created);
Session session = _sessionStore.newSession(request, id, created, (_dftMaxIdleSecs>0?_dftMaxIdleSecs*1000L:-1));
session.setExtendedId(_sessionIdManager.getExtendedId(id,request));
session.setSessionManager(this);
session.setLastNode(_sessionIdManager.getWorkerName());
session.getSessionData().setExpiry(_dftMaxIdleSecs <= 0 ? 0 : (created + _dftMaxIdleSecs*1000L));
if (request.isSecure())
session.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
try
{
_sessionStore.put(id, session);
_sessionsCreatedStats.increment();
_sessionIdManager.useId(session);
if (_sessionListeners!=null)
{
HttpSessionEvent event=new HttpSessionEvent(session);
for (HttpSessionListener listener : _sessionListeners)
listener.sessionCreated(event);
}
return session;
}
catch (Exception e)
{
LOG.warn(e);
return null;
}
}
/* ------------------------------------------------------------ */
@Override
public void removeEventListener(EventListener listener)
{
if (listener instanceof HttpSessionAttributeListener)
_sessionAttributeListeners.remove(listener);
if (listener instanceof HttpSessionListener)
_sessionListeners.remove(listener);
if (listener instanceof HttpSessionIdListener)
_sessionIdListeners.remove(listener);
removeBean(listener);
}
/* ------------------------------------------------------------ */
/**
* Reset statistics values
*/
@ManagedOperation(value="reset statistics", impact="ACTION")
public void statsReset()
{
_sessionsCreatedStats.reset();
_sessionTimeStats.reset();
}
/* ------------------------------------------------------------ */
/**
* @param httpOnly
* The httpOnly to set.
*/
public void setHttpOnly(boolean httpOnly)
{
_httpOnly=httpOnly;
}
/* ------------------------------------------------------------ */
/**
* @param metaManager The metaManager used for cross context session management.
*/
@Override
public void setSessionIdManager(SessionIdManager metaManager)
{
updateBean(_sessionIdManager, metaManager);
_sessionIdManager=metaManager;
}
/* ------------------------------------------------------------ */
@Override
public void setMaxInactiveInterval(int seconds)
{
_dftMaxIdleSecs=seconds;
}
/* ------------------------------------------------------------ */
public void setRefreshCookieAge(int ageInSeconds)
{
_refreshCookieAge=ageInSeconds;
}
/* ------------------------------------------------------------ */
public void setSessionCookie(String cookieName)
{
_sessionCookie=cookieName;
}
/* ------------------------------------------------------------ */
/**
* @param sessionHandler
* The sessionHandler to set.
*/
@Override
public void setSessionHandler(SessionHandler sessionHandler)
{
_sessionHandler=sessionHandler;
}
/* ------------------------------------------------------------ */
@Override
public void setSessionIdPathParameterName(String param)
{
_sessionIdPathParameterName =(param==null||"none".equals(param))?null:param;
_sessionIdPathParameterNamePrefix =(param==null||"none".equals(param))?null:(";"+ _sessionIdPathParameterName +"=");
}
/* ------------------------------------------------------------ */
/**
* @param usingCookies
* The usingCookies to set.
*/
public void setUsingCookies(boolean usingCookies)
{
_usingCookies=usingCookies;
}
/* ------------------------------------------------------------ */
/**
* Get a known existing session
* @param id The session ID stripped of any worker name.
* @return A Session or null if none exists.
*/
public Session getSession(String id)
{
try
{
Session session = _sessionStore.get(id, true);
if (session != null)
{
//If the session we got back has expired
if (session.isExpiredAt(System.currentTimeMillis()))
{
//Expire the session
try
{
session.invalidate();
}
catch (Exception e)
{
LOG.warn("Invalidating session {} found to be expired when requested", id, e);
}
return null;
}
session.setExtendedId(_sessionIdManager.getExtendedId(id, null)); //TODO not sure if this is OK?
session.setLastNode(_sessionIdManager.getWorkerName()); //TODO write through the change of node?
}
return session;
}
catch (UnreadableSessionDataException e)
{
LOG.warn(e);
//Could not retrieve the session with the given id
//Tell the session id manager that the session id is not to be used by any other threads/contexts
_sessionIdManager.removeId(id);
return null;
}
catch (Exception other)
{
LOG.warn(other);
return null;
}
}
/* ------------------------------------------------------------ */
/**
* Prepare sessions for session manager shutdown
*
* @throws Exception if unable to shutdown sesssions
*/
protected void shutdownSessions() throws Exception
{
_sessionStore.shutdown();
}
/* ------------------------------------------------------------ */
/**
* @return
*/
public SessionStore getSessionStore ()
{
return _sessionStore;
}
/* ------------------------------------------------------------ */
/**
* @return true if the cluster node id (worker id) is returned as part of the session id by {@link HttpSession#getId()}. Default is false.
*/
public boolean isNodeIdInSessionId()
{
return _nodeIdInSessionId;
}
/* ------------------------------------------------------------ */
/**
* @param nodeIdInSessionId true if the cluster node id (worker id) will be returned as part of the session id by {@link HttpSession#getId()}. Default is false.
*/
public void setNodeIdInSessionId(boolean nodeIdInSessionId)
{
_nodeIdInSessionId=nodeIdInSessionId;
}
/* ------------------------------------------------------------ */
/**
* Remove session from manager
* @param id The session to remove
* @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and
* {@link SessionIdManager#expireAll(String)} should be called.
* @return if the session was removed
*/
public Session removeSession(String id, boolean invalidate)
{
try
{
//Remove the Session object from the session store and any backing data store
Session session = _sessionStore.delete(id);
if (session != null)
{
if (invalidate)
{
if (_sessionListeners!=null)
{
HttpSessionEvent event=new HttpSessionEvent(session);
for (int i = _sessionListeners.size()-1; i>=0; i--)
{
_sessionListeners.get(i).sessionDestroyed(event);
}
}
}
}
return session;
}
catch (Exception e)
{
LOG.warn(e);
return null;
}
}
/* ------------------------------------------------------------ */
/**
* @return maximum amount of time session remained valid
*/
@ManagedAttribute("maximum amount of time sessions have remained active (in s)")
public long getSessionTimeMax()
{
return _sessionTimeStats.getMax();
}
/* ------------------------------------------------------------ */
@Override
public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
{
return __defaultSessionTrackingModes;
}
/* ------------------------------------------------------------ */
@Override
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
{
return Collections.unmodifiableSet(_sessionTrackingModes);
}
/* ------------------------------------------------------------ */
@Override
public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes)
{
_sessionTrackingModes=new HashSet<SessionTrackingMode>(sessionTrackingModes);
_usingCookies=_sessionTrackingModes.contains(SessionTrackingMode.COOKIE);
_usingURLs=_sessionTrackingModes.contains(SessionTrackingMode.URL);
}
/* ------------------------------------------------------------ */
@Override
public boolean isUsingURLs()
{
return _usingURLs;
}
/* ------------------------------------------------------------ */
@Override
public SessionCookieConfig getSessionCookieConfig()
{
return _cookieConfig;
}
/* ------------------------------------------------------------ */
private SessionCookieConfig _cookieConfig =
new CookieConfig();
/* ------------------------------------------------------------ */
/**
* @return total amount of time all sessions remained valid
*/
@ManagedAttribute("total time sessions have remained valid")
public long getSessionTimeTotal()
{
return _sessionTimeStats.getTotal();
}
/* ------------------------------------------------------------ */
/**
* @return mean amount of time session remained valid
*/
@ManagedAttribute("mean time sessions remain valid (in s)")
public double getSessionTimeMean()
{
return _sessionTimeStats.getMean();
}
/* ------------------------------------------------------------ */
/**
* @return standard deviation of amount of time session remained valid
*/
@ManagedAttribute("standard deviation a session remained valid (in s)")
public double getSessionTimeStdDev()
{
return _sessionTimeStats.getStdDev();
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.server.SessionManager#isCheckingRemoteSessionIdEncoding()
*/
@Override
@ManagedAttribute("check remote session id encoding")
public boolean isCheckingRemoteSessionIdEncoding()
{
return _checkingRemoteSessionIdEncoding;
}
/* ------------------------------------------------------------ */
/**
* @see org.eclipse.jetty.server.SessionManager#setCheckingRemoteSessionIdEncoding(boolean)
*/
@Override
public void setCheckingRemoteSessionIdEncoding(boolean remote)
{
_checkingRemoteSessionIdEncoding=remote;
}
/* ------------------------------------------------------------ */
/**
* Change the session id and tell the HttpSessionIdListeners the id changed.
*
*/
@Override
public void renewSessionId(String oldId, String oldExtendedId, String newId, String newExtendedId)
{
try
{
Session session =_sessionStore.delete(oldId);
if (session == null)
{
LOG.warn("Unable to renew id to "+newId+" for non-existant session "+oldId);
return;
}
//swap the ids
session.renewId(oldId, oldExtendedId, newId, newExtendedId);
_sessionStore.put(newId, session);
//tell session id manager the id is in use
_sessionIdManager.useId(session);
//inform the listeners
if (!_sessionIdListeners.isEmpty())
{
HttpSessionEvent event = new HttpSessionEvent(session);
for (HttpSessionIdListener l:_sessionIdListeners)
{
l.sessionIdChanged(event, oldId);
}
}
}
catch (Exception e)
{
LOG.warn(e);
}
}
/* ------------------------------------------------------------ */
/**
* Called either when a session has expired, or the app has
* invalidated it.
*
* @param id
*/
public void invalidate (String id)
{
if (StringUtil.isBlank(id))
return;
try
{
//remove the session and call the destroy listeners
Session session = removeSession(id, true);
if (session != null)
{
_sessionTimeStats.set(round((System.currentTimeMillis() - session.getSessionData().getCreated())/1000.0));
session.doInvalidate();
}
}
catch (Exception e)
{
LOG.warn(e);
}
}
/* ------------------------------------------------------------ */
/**
* @return
*/
public Set<String> scavenge ()
{
//don't attempt to scavenge if we are shutting down
if (isStopping() || isStopped())
return Collections.emptySet();
return _sessionStore.getExpired();
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/**
* CookieConfig
*
* Implementation of the javax.servlet.SessionCookieConfig.
*/
public final class CookieConfig implements SessionCookieConfig
{
@Override
public String getComment()
{
return _sessionComment;
}
@Override
public String getDomain()
{
return _sessionDomain;
}
@Override
public int getMaxAge()
{
return _maxCookieAge;
}
@Override
public String getName()
{
return _sessionCookie;
}
@Override
public String getPath()
{
return _sessionPath;
}
@Override
public boolean isHttpOnly()
{
return _httpOnly;
}
@Override
public boolean isSecure()
{
return _secureCookies;
}
@Override
public void setComment(String comment)
{
if (_context != null && _context.getContextHandler().isAvailable())
throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
_sessionComment = comment;
}
@Override
public void setDomain(String domain)
{
if (_context != null && _context.getContextHandler().isAvailable())
throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
_sessionDomain=domain;
}
@Override
public void setHttpOnly(boolean httpOnly)
{
if (_context != null && _context.getContextHandler().isAvailable())
throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
_httpOnly=httpOnly;
}
@Override
public void setMaxAge(int maxAge)
{
if (_context != null && _context.getContextHandler().isAvailable())
throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
_maxCookieAge=maxAge;
}
@Override
public void setName(String name)
{
if (_context != null && _context.getContextHandler().isAvailable())
throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
_sessionCookie=name;
}
@Override
public void setPath(String path)
{
if (_context != null && _context.getContextHandler().isAvailable())
throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
_sessionPath=path;
}
@Override
public void setSecure(boolean secure)
{
if (_context != null && _context.getContextHandler().isAvailable())
throw new IllegalStateException("CookieConfig cannot be set after ServletContext is started");
_secureCookies=secure;
}
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/**
* Interface that any session wrapper should implement so that
* SessionManager may access the Jetty session implementation.
*
*/
public interface SessionIf extends HttpSession
{
public Session getSession();
}
public void doSessionAttributeListeners(Session session, String name, Object old, Object value)
{
if (!_sessionAttributeListeners.isEmpty())
{
HttpSessionBindingEvent event=new HttpSessionBindingEvent(session,name,old==null?value:old);
for (HttpSessionAttributeListener l : _sessionAttributeListeners)
{
if (old==null)
l.attributeAdded(event);
else if (value==null)
l.attributeRemoved(event);
else
l.attributeReplaced(event);
}
}
}
}