X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Fserver%2Fsession%2FAbstractSessionManager.java;fp=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Fserver%2Fsession%2FAbstractSessionManager.java;h=1f966c5957d68b59b39a2a439ddd082cf08b0269;hp=0000000000000000000000000000000000000000;hb=73ef54a38e3930a1a789cdc6b5fa23cdd4c9d086;hpb=515007c7c1351045420669d65b59c08fa46850f2 diff --git a/lib/jetty/org/eclipse/jetty/server/session/AbstractSessionManager.java b/lib/jetty/org/eclipse/jetty/server/session/AbstractSessionManager.java new file mode 100644 index 00000000..1f966c59 --- /dev/null +++ b/lib/jetty/org/eclipse/jetty/server/session/AbstractSessionManager.java @@ -0,0 +1,1052 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 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.SessionManager; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.annotation.ManagedAttribute; +import org.eclipse.jetty.util.annotation.ManagedObject; +import org.eclipse.jetty.util.annotation.ManagedOperation; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.statistic.CounterStatistic; +import org.eclipse.jetty.util.statistic.SampleStatistic; + +/* ------------------------------------------------------------ */ +/** + * An Abstract implementation of SessionManager. The partial implementation of + * SessionManager interface provides the majority of the handling required to + * implement a SessionManager. Concrete implementations of SessionManager based + * on AbstractSessionManager need only implement the newSession method to return + * a specialised version of the Session inner class that provides an attribute + * Map. + *

+ */ +@SuppressWarnings("deprecation") +@ManagedObject("Abstract Session Manager") +public abstract class AbstractSessionManager extends ContainerLifeCycle implements SessionManager +{ + final static Logger __log = SessionHandler.LOG; + + public Set __defaultSessionTrackingModes = + Collections.unmodifiableSet( + new HashSet( + 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); + } + }; + + private boolean _usingCookies=true; + + /* ------------------------------------------------------------ */ + // 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 _sessionAttributeListeners = new CopyOnWriteArrayList(); + protected final List _sessionListeners= new CopyOnWriteArrayList(); + protected final List _sessionIdListeners = new CopyOnWriteArrayList(); + + protected ClassLoader _loader; + protected ContextHandler.Context _context; + 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; + + public Set _sessionTrackingModes; + + private boolean _usingURLs; + + protected final CounterStatistic _sessionsStats = new CounterStatistic(); + protected final SampleStatistic _sessionTimeStats = new SampleStatistic(); + + + /* ------------------------------------------------------------ */ + public AbstractSessionManager() + { + 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(); + + AbstractSession 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) + { + AbstractSession s = ((SessionIf)session).getSession(); + s.complete(); + } + + /* ------------------------------------------------------------ */ + @Override + public void doStart() throws Exception + { + _context=ContextHandler.getCurrentContext(); + _loader=Thread.currentThread().getContextClassLoader(); + + if (_sessionIdManager==null) + { + final Server server=getSessionHandler().getServer(); + synchronized (server) + { + _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.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(SessionManager.__SessionCookieProperty); + if (tmp!=null) + _sessionCookie=tmp; + + tmp=_context.getInitParameter(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(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(SessionManager.__SessionDomainProperty); + + // set up the sessionPath if it isn't already + if (_sessionPath==null) + _sessionPath=_context.getInitParameter(SessionManager.__SessionPathProperty); + + tmp=_context.getInitParameter(SessionManager.__CheckRemoteSessionEncoding); + if (tmp!=null) + _checkingRemoteSessionIdEncoding=Boolean.parseBoolean(tmp); + } + + super.doStart(); + } + + /* ------------------------------------------------------------ */ + @Override + public void doStop() throws Exception + { + super.doStop(); + + shutdownSessions(); + + _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 nodeId) + { + String cluster_id = getSessionIdManager().getClusterId(nodeId); + + AbstractSession session = getSession(cluster_id); + if (session!=null && !session.getNodeId().equals(nodeId)) + 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("defailt maximum time a session may be idle for (in s)") + public int getMaxInactiveInterval() + { + return _dftMaxIdleSecs; + } + + /* ------------------------------------------------------------ */ + /** + * @return maximum number of sessions + */ + @ManagedAttribute("maximum number of simultaneous sessions") + public int getSessionsMax() + { + return (int)_sessionsStats.getMax(); + } + + /* ------------------------------------------------------------ */ + /** + * @return total number of sessions + */ + @ManagedAttribute("total number of sessions") + public int getSessionsTotal() + { + return (int)_sessionsStats.getTotal(); + } + + /* ------------------------------------------------------------ */ + @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. + */ + 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: + *

    + *
  1. SessionCookieConfig.setSecure == true
  2. + *
  3. SessionCookieConfig.setSecure == false && _secureRequestOnly==true && request is HTTPS
  4. + *
+ * 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." + * + * For case 2, you can use _secureRequestOnly to determine if you want the + * Servlet Spec 3.0 default behaviour when SessionCookieConfig.setSecure==false, + * which is: + * "they shall be marked as secure only if the request that initiated the + * corresponding session was also secure" + * + * The default for _secureRequestOnly is true, which gives the above behaviour. 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 = getNodeId(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 currently active sessions") + public int getSessions() + { + return (int)_sessionsStats.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) + { + AbstractSession s = ((SessionIf)session).getSession(); + return s.isValid(); + } + + /* ------------------------------------------------------------ */ + @Override + public String getClusterId(HttpSession session) + { + AbstractSession s = ((SessionIf)session).getSession(); + return s.getClusterId(); + } + + /* ------------------------------------------------------------ */ + @Override + public String getNodeId(HttpSession session) + { + AbstractSession s = ((SessionIf)session).getSession(); + return s.getNodeId(); + } + + /* ------------------------------------------------------------ */ + /** + * Create a new HttpSession for a request + */ + @Override + public HttpSession newHttpSession(HttpServletRequest request) + { + AbstractSession session=newSession(request); + session.setMaxInactiveInterval(_dftMaxIdleSecs); + addSession(session,true); + return session; + } + + /* ------------------------------------------------------------ */ + @Override + public void removeEventListener(EventListener listener) + { + if (listener instanceof HttpSessionAttributeListener) + _sessionAttributeListeners.remove(listener); + if (listener instanceof HttpSessionListener) + _sessionListeners.remove(listener); + } + + /* ------------------------------------------------------------ */ + /** + * Reset statistics values + */ + @ManagedOperation(value="reset statistics", impact="ACTION") + public void statsReset() + { + _sessionsStats.reset(getSessions()); + _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; + } + + /* ------------------------------------------------------------ */ + /** + * @param seconds + */ + @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; + } + + + protected abstract void addSession(AbstractSession session); + + /* ------------------------------------------------------------ */ + /** + * Add the session Registers the session with this manager and registers the + * session ID with the sessionIDManager; + */ + protected void addSession(AbstractSession session, boolean created) + { + synchronized (_sessionIdManager) + { + _sessionIdManager.addSession(session); + addSession(session); + } + + if (created) + { + _sessionsStats.increment(); + if (_sessionListeners!=null) + { + HttpSessionEvent event=new HttpSessionEvent(session); + for (HttpSessionListener listener : _sessionListeners) + listener.sessionCreated(event); + } + } + } + + /* ------------------------------------------------------------ */ + /** + * Get a known existing session + * @param idInCluster The session ID in the cluster, stripped of any worker name. + * @return A Session or null if none exists. + */ + public abstract AbstractSession getSession(String idInCluster); + + /** + * Prepare sessions for session manager shutdown + * + * @throws Exception + */ + protected abstract void shutdownSessions() throws Exception; + + + /* ------------------------------------------------------------ */ + /** + * Create a new session instance + * @param request + * @return the new session + */ + protected abstract AbstractSession newSession(HttpServletRequest request); + + + /* ------------------------------------------------------------ */ + /** + * @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 session The session to remove + * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and + * {@link SessionIdManager#invalidateAll(String)} should be called. + */ + public void removeSession(HttpSession session, boolean invalidate) + { + AbstractSession s = ((SessionIf)session).getSession(); + removeSession(s,invalidate); + } + + /* ------------------------------------------------------------ */ + /** Remove session from manager + * @param session The session to remove + * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and + * {@link SessionIdManager#invalidateAll(String)} should be called. + */ + public boolean removeSession(AbstractSession session, boolean invalidate) + { + // Remove session from context and global maps + boolean removed = removeSession(session.getClusterId()); + + if (removed) + { + _sessionsStats.decrement(); + _sessionTimeStats.set(round((System.currentTimeMillis() - session.getCreationTime())/1000.0)); + + // Remove session from all context and global id maps + _sessionIdManager.removeSession(session); + if (invalidate) + _sessionIdManager.invalidateAll(session.getClusterId()); + + if (invalidate && _sessionListeners!=null) + { + HttpSessionEvent event=new HttpSessionEvent(session); + for (int i = _sessionListeners.size()-1; i>=0; i--) + { + _sessionListeners.get(i).sessionDestroyed(event); + } + } + } + + return removed; + } + + /* ------------------------------------------------------------ */ + protected abstract boolean removeSession(String idInCluster); + + /* ------------------------------------------------------------ */ + /** + * @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 getDefaultSessionTrackingModes() + { + return __defaultSessionTrackingModes; + } + + /* ------------------------------------------------------------ */ + @Override + public Set getEffectiveSessionTrackingModes() + { + return Collections.unmodifiableSet(_sessionTrackingModes); + } + + /* ------------------------------------------------------------ */ + @Override + public void setSessionTrackingModes(Set sessionTrackingModes) + { + _sessionTrackingModes=new HashSet(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; + } + + + /* ------------------------------------------------------------ */ + /** + * Tell the HttpSessionIdListeners the id changed. + * NOTE: this method must be called LAST in subclass overrides, after the session has been updated + * with the new id. + * @see org.eclipse.jetty.server.SessionManager#renewSessionId(java.lang.String, java.lang.String, java.lang.String, java.lang.String) + */ + @Override + public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId) + { + if (!_sessionIdListeners.isEmpty()) + { + AbstractSession session = getSession(newClusterId); + HttpSessionEvent event = new HttpSessionEvent(session); + for (HttpSessionIdListener l:_sessionIdListeners) + { + l.sessionIdChanged(event, oldClusterId); + } + } + + } + + /** + * 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 AbstractSession getSession(); + } + + public void doSessionAttributeListeners(AbstractSession 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); + } + } + } + + @Override + @Deprecated + public SessionIdManager getMetaManager() + { + throw new UnsupportedOperationException(); + } +}