Renaming from temporary session.x package
This commit is contained in:
parent
305b7bb776
commit
c5489bd7b2
|
@ -138,7 +138,7 @@ public class InfinispanSessionIdManager extends AbstractSessionIdManager
|
||||||
if (id == null)
|
if (id == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
String clusterId = getClusterId(id);
|
String clusterId = getId(id);
|
||||||
|
|
||||||
//ask the cluster - this should also tickle the idle expiration timer on the sessionid entry
|
//ask the cluster - this should also tickle the idle expiration timer on the sessionid entry
|
||||||
//keeping it valid
|
//keeping it valid
|
||||||
|
|
|
@ -22,11 +22,11 @@ import org.eclipse.jetty.nosql.mongodb.MongoSessionManager;
|
||||||
import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
|
import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.server.session.SessionHandler;
|
import org.eclipse.jetty.server.session.SessionHandler;
|
||||||
import org.eclipse.jetty.server.session.jmx.AbstractSessionManagerMBean;
|
import org.eclipse.jetty.server.session.jmx.SessionManagerMBean;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||||
|
|
||||||
@ManagedObject("Mongo Session Manager MBean")
|
@ManagedObject("Mongo Session Manager MBean")
|
||||||
public class MongoSessionManagerMBean extends AbstractSessionManagerMBean
|
public class MongoSessionManagerMBean extends SessionManagerMBean
|
||||||
{
|
{
|
||||||
|
|
||||||
public MongoSessionManagerMBean(Object managedObject)
|
public MongoSessionManagerMBean(Object managedObject)
|
||||||
|
|
|
@ -29,7 +29,7 @@ import org.eclipse.jetty.security.LoginService;
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
import org.eclipse.jetty.server.Response;
|
import org.eclipse.jetty.server.Response;
|
||||||
import org.eclipse.jetty.server.UserIdentity;
|
import org.eclipse.jetty.server.UserIdentity;
|
||||||
import org.eclipse.jetty.server.session.AbstractSession;
|
import org.eclipse.jetty.server.session.Session;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
|
@ -109,17 +109,17 @@ public abstract class LoginAuthenticator implements Authenticator
|
||||||
{
|
{
|
||||||
//if we should renew sessions, and there is an existing session that may have been seen by non-authenticated users
|
//if we should renew sessions, and there is an existing session that may have been seen by non-authenticated users
|
||||||
//(indicated by SESSION_SECURED not being set on the session) then we should change id
|
//(indicated by SESSION_SECURED not being set on the session) then we should change id
|
||||||
if (httpSession.getAttribute(AbstractSession.SESSION_CREATED_SECURE)!=Boolean.TRUE)
|
if (httpSession.getAttribute(Session.SESSION_CREATED_SECURE)!=Boolean.TRUE)
|
||||||
{
|
{
|
||||||
if (httpSession instanceof AbstractSession)
|
if (httpSession instanceof Session)
|
||||||
{
|
{
|
||||||
AbstractSession abstractSession = (AbstractSession)httpSession;
|
Session s = (Session)httpSession;
|
||||||
String oldId = abstractSession.getId();
|
String oldId = s.getId();
|
||||||
abstractSession.renewId(request);
|
s.renewId(request);
|
||||||
abstractSession.setAttribute(AbstractSession.SESSION_CREATED_SECURE, Boolean.TRUE);
|
s.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
|
||||||
if (abstractSession.isIdChanged() && response != null && (response instanceof Response))
|
if (s.isIdChanged() && response != null && (response instanceof Response))
|
||||||
((Response)response).addCookie(abstractSession.getSessionManager().getSessionCookie(abstractSession, request.getContextPath(), request.isSecure()));
|
((Response)response).addCookie(s.getSessionManager().getSessionCookie(s, request.getContextPath(), request.isSecure()));
|
||||||
LOG.debug("renew {}->{}",oldId,abstractSession.getId());
|
LOG.debug("renew {}->{}",oldId,s.getId());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LOG.warn("Unable to renew session "+httpSession);
|
LOG.warn("Unable to renew session "+httpSession);
|
||||||
|
|
|
@ -33,7 +33,7 @@ import org.eclipse.jetty.security.AbstractUserAuthentication;
|
||||||
import org.eclipse.jetty.security.LoginService;
|
import org.eclipse.jetty.security.LoginService;
|
||||||
import org.eclipse.jetty.security.SecurityHandler;
|
import org.eclipse.jetty.security.SecurityHandler;
|
||||||
import org.eclipse.jetty.server.UserIdentity;
|
import org.eclipse.jetty.server.UserIdentity;
|
||||||
import org.eclipse.jetty.server.session.AbstractSession;
|
import org.eclipse.jetty.server.session.Session;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ public class SessionAuthentication extends AbstractUserAuthentication implements
|
||||||
if (security!=null)
|
if (security!=null)
|
||||||
security.logout(this);
|
security.logout(this);
|
||||||
if (_session!=null)
|
if (_session!=null)
|
||||||
_session.removeAttribute(AbstractSession.SESSION_CREATED_SECURE);
|
_session.removeAttribute(Session.SESSION_CREATED_SECURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -76,7 +76,7 @@ import org.eclipse.jetty.http.MetaData;
|
||||||
import org.eclipse.jetty.http.MimeTypes;
|
import org.eclipse.jetty.http.MimeTypes;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
||||||
import org.eclipse.jetty.server.session.AbstractSession;
|
import org.eclipse.jetty.server.session.Session;
|
||||||
import org.eclipse.jetty.util.Attributes;
|
import org.eclipse.jetty.util.Attributes;
|
||||||
import org.eclipse.jetty.util.AttributesMap;
|
import org.eclipse.jetty.util.AttributesMap;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
|
@ -1494,14 +1494,14 @@ public class Request implements HttpServletRequest
|
||||||
if (session == null)
|
if (session == null)
|
||||||
throw new IllegalStateException("No session");
|
throw new IllegalStateException("No session");
|
||||||
|
|
||||||
if (session instanceof AbstractSession)
|
if (session instanceof Session)
|
||||||
{
|
{
|
||||||
AbstractSession abstractSession = ((AbstractSession)session);
|
Session s = ((Session)session);
|
||||||
abstractSession.renewId(this);
|
s.renewId(this);
|
||||||
if (getRemoteUser() != null)
|
if (getRemoteUser() != null)
|
||||||
abstractSession.setAttribute(AbstractSession.SESSION_CREATED_SECURE, Boolean.TRUE);
|
s.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
|
||||||
if (abstractSession.isIdChanged())
|
if (s.isIdChanged())
|
||||||
_channel.getResponse().addCookie(_sessionManager.getSessionCookie(abstractSession, getContextPath(), isSecure()));
|
_channel.getResponse().addCookie(_sessionManager.getSessionCookie(s, getContextPath(), isSecure()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return session.getId();
|
return session.getId();
|
||||||
|
@ -1697,7 +1697,7 @@ public class Request implements HttpServletRequest
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
HttpSession session = getSession(false);
|
HttpSession session = getSession(false);
|
||||||
return (session != null && _sessionManager.getSessionIdManager().getClusterId(_requestedSessionId).equals(_sessionManager.getClusterId(session)));
|
return (session != null && _sessionManager.getSessionIdManager().getId(_requestedSessionId).equals(_sessionManager.getId(session)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
|
@ -449,7 +449,7 @@ public class Response implements HttpServletResponse
|
||||||
if (!sessionManager.isValid(session))
|
if (!sessionManager.isValid(session))
|
||||||
return url;
|
return url;
|
||||||
|
|
||||||
String id = sessionManager.getNodeId(session);
|
String id = sessionManager.getExtendedId(session);
|
||||||
|
|
||||||
if (uri == null)
|
if (uri == null)
|
||||||
uri = new HttpURI(url);
|
uri = new HttpURI(url);
|
||||||
|
|
|
@ -216,17 +216,17 @@ public interface SessionManager extends LifeCycle
|
||||||
/**
|
/**
|
||||||
* @param session the session object
|
* @param session the session object
|
||||||
* @return the unique id of the session within the cluster, extended with an optional node id.
|
* @return the unique id of the session within the cluster, extended with an optional node id.
|
||||||
* @see #getClusterId(HttpSession)
|
* @see #getId(HttpSession)
|
||||||
*/
|
*/
|
||||||
public String getNodeId(HttpSession session);
|
public String getExtendedId(HttpSession session);
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* @param session the session object
|
* @param session the session object
|
||||||
* @return the unique id of the session within the cluster (without a node id extension)
|
* @return the unique id of the session within the cluster (without a node id extension)
|
||||||
* @see #getNodeId(HttpSession)
|
* @see #getExtendedId(HttpSession)
|
||||||
*/
|
*/
|
||||||
public String getClusterId(HttpSession session);
|
public String getId(HttpSession session);
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,664 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2015 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 java.util.ArrayList;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpSessionActivationListener;
|
|
||||||
import javax.servlet.http.HttpSessionBindingEvent;
|
|
||||||
import javax.servlet.http.HttpSessionBindingListener;
|
|
||||||
import javax.servlet.http.HttpSessionContext;
|
|
||||||
import javax.servlet.http.HttpSessionEvent;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.server.SessionManager;
|
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Implements {@link javax.servlet.http.HttpSession} from the <code>javax.servlet</code> package.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public abstract class AbstractSession implements AbstractSessionManager.SessionIf
|
|
||||||
{
|
|
||||||
final static Logger LOG = SessionHandler.LOG;
|
|
||||||
public final static String SESSION_CREATED_SECURE="org.eclipse.jetty.security.sessionCreatedSecure";
|
|
||||||
private String _clusterId; // ID without any node (ie "worker") id appended
|
|
||||||
private String _nodeId; // ID of session with node(ie "worker") id appended
|
|
||||||
private final AbstractSessionManager _manager;
|
|
||||||
private boolean _idChanged;
|
|
||||||
private final long _created;
|
|
||||||
private long _cookieSet;
|
|
||||||
private long _accessed; // the time of the last access
|
|
||||||
private long _lastAccessed; // the time of the last access excluding this one
|
|
||||||
private boolean _invalid;
|
|
||||||
private boolean _doInvalidate;
|
|
||||||
private long _maxIdleMs;
|
|
||||||
private boolean _newSession;
|
|
||||||
private int _requests;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
protected AbstractSession(AbstractSessionManager abstractSessionManager, HttpServletRequest request)
|
|
||||||
{
|
|
||||||
_manager = abstractSessionManager;
|
|
||||||
|
|
||||||
_newSession=true;
|
|
||||||
_created=System.currentTimeMillis();
|
|
||||||
_clusterId=_manager._sessionIdManager.newSessionId(request,_created);
|
|
||||||
_nodeId=_manager._sessionIdManager.getExtendedId(_clusterId,request);
|
|
||||||
_accessed=_created;
|
|
||||||
_lastAccessed=_created;
|
|
||||||
_requests=1;
|
|
||||||
_maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("new session & id "+_nodeId+" "+_clusterId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
protected AbstractSession(AbstractSessionManager abstractSessionManager, long created, long accessed, String clusterId)
|
|
||||||
{
|
|
||||||
_manager = abstractSessionManager;
|
|
||||||
_created=created;
|
|
||||||
_clusterId=clusterId;
|
|
||||||
_nodeId=_manager._sessionIdManager.getExtendedId(_clusterId,null);
|
|
||||||
_accessed=accessed;
|
|
||||||
_lastAccessed=accessed;
|
|
||||||
_requests=1;
|
|
||||||
_maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("new session "+_nodeId+" "+_clusterId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* asserts that the session is valid
|
|
||||||
* @throws IllegalStateException if the sesion is invalid
|
|
||||||
*/
|
|
||||||
protected void checkValid() throws IllegalStateException
|
|
||||||
{
|
|
||||||
if (_invalid)
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
/** Check to see if session has expired as at the time given.
|
|
||||||
* @param time the time in milliseconds
|
|
||||||
* @return true if expired
|
|
||||||
*/
|
|
||||||
protected boolean checkExpiry(long time)
|
|
||||||
{
|
|
||||||
if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < time)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Override
|
|
||||||
public AbstractSession getSession()
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public long getAccessed()
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
return _accessed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public abstract Map<String,Object> getAttributeMap();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public abstract int getAttributes();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public abstract Set<String> getNames();
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public long getCookieSetTime()
|
|
||||||
{
|
|
||||||
return _cookieSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public void setCookieSetTime(long time)
|
|
||||||
{
|
|
||||||
_cookieSet = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Override
|
|
||||||
public long getCreationTime() throws IllegalStateException
|
|
||||||
{
|
|
||||||
checkValid();
|
|
||||||
return _created;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public String getId() throws IllegalStateException
|
|
||||||
{
|
|
||||||
return _manager._nodeIdInSessionId?_nodeId:_clusterId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public String getNodeId()
|
|
||||||
{
|
|
||||||
return _nodeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public String getClusterId()
|
|
||||||
{
|
|
||||||
return _clusterId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Override
|
|
||||||
public long getLastAccessedTime() throws IllegalStateException
|
|
||||||
{
|
|
||||||
checkValid();
|
|
||||||
return _lastAccessed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public void setLastAccessedTime(long time)
|
|
||||||
{
|
|
||||||
_lastAccessed = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Override
|
|
||||||
public int getMaxInactiveInterval()
|
|
||||||
{
|
|
||||||
return (int)(_maxIdleMs/1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/*
|
|
||||||
* @see javax.servlet.http.HttpSession#getServletContext()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ServletContext getServletContext()
|
|
||||||
{
|
|
||||||
return _manager._context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public HttpSessionContext getSessionContext() throws IllegalStateException
|
|
||||||
{
|
|
||||||
checkValid();
|
|
||||||
return AbstractSessionManager.__nullSessionContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* @deprecated As of Version 2.2, this method is replaced by
|
|
||||||
* {@link #getAttribute}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public Object getValue(String name) throws IllegalStateException
|
|
||||||
{
|
|
||||||
return getAttribute(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public void renewId(HttpServletRequest request)
|
|
||||||
{
|
|
||||||
_manager._sessionIdManager.renewSessionId(getClusterId(), getNodeId(), request);
|
|
||||||
setIdChanged(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public SessionManager getSessionManager()
|
|
||||||
{
|
|
||||||
return _manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
protected void setClusterId (String clusterId)
|
|
||||||
{
|
|
||||||
_clusterId = clusterId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
protected void setNodeId (String nodeId)
|
|
||||||
{
|
|
||||||
_nodeId = nodeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
protected boolean access(long time)
|
|
||||||
{
|
|
||||||
synchronized(this)
|
|
||||||
{
|
|
||||||
if (_invalid)
|
|
||||||
return false;
|
|
||||||
_newSession=false;
|
|
||||||
_lastAccessed=_accessed;
|
|
||||||
_accessed=time;
|
|
||||||
|
|
||||||
if (checkExpiry(time))
|
|
||||||
{
|
|
||||||
invalidate();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_requests++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
protected void complete()
|
|
||||||
{
|
|
||||||
synchronized(this)
|
|
||||||
{
|
|
||||||
_requests--;
|
|
||||||
if (_doInvalidate && _requests<=0 )
|
|
||||||
doInvalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
protected void timeout() throws IllegalStateException
|
|
||||||
{
|
|
||||||
// remove session from context and invalidate other sessions with same ID.
|
|
||||||
_manager.removeSession(this,true);
|
|
||||||
|
|
||||||
// Notify listeners and unbind values
|
|
||||||
boolean do_invalidate=false;
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (!_invalid)
|
|
||||||
{
|
|
||||||
if (_requests<=0)
|
|
||||||
do_invalidate=true;
|
|
||||||
else
|
|
||||||
_doInvalidate=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (do_invalidate)
|
|
||||||
doInvalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Override
|
|
||||||
public void invalidate() throws IllegalStateException
|
|
||||||
{
|
|
||||||
checkValid();
|
|
||||||
// remove session from context and invalidate other sessions with same ID.
|
|
||||||
_manager.removeSession(this,true);
|
|
||||||
doInvalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
protected void doInvalidate() throws IllegalStateException
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("invalidate {}",_clusterId);
|
|
||||||
if (isValid())
|
|
||||||
clearAttributes();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
// mark as invalid
|
|
||||||
_invalid=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public abstract void clearAttributes();
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public boolean isIdChanged()
|
|
||||||
{
|
|
||||||
return _idChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Override
|
|
||||||
public boolean isNew() throws IllegalStateException
|
|
||||||
{
|
|
||||||
checkValid();
|
|
||||||
return _newSession;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* @deprecated As of Version 2.2, this method is replaced by
|
|
||||||
* {@link #setAttribute}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException
|
|
||||||
{
|
|
||||||
changeAttribute(name,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public void removeAttribute(String name)
|
|
||||||
{
|
|
||||||
setAttribute(name,null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* @deprecated As of Version 2.2, this method is replaced by
|
|
||||||
* {@link #removeAttribute}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public void removeValue(java.lang.String name) throws IllegalStateException
|
|
||||||
{
|
|
||||||
removeAttribute(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public Enumeration<String> getAttributeNames()
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
checkValid();
|
|
||||||
return doGetAttributeNames();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* @deprecated As of Version 2.2, this method is replaced by
|
|
||||||
* {@link #getAttributeNames}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public String[] getValueNames() throws IllegalStateException
|
|
||||||
{
|
|
||||||
synchronized(this)
|
|
||||||
{
|
|
||||||
checkValid();
|
|
||||||
Enumeration<String> anames = doGetAttributeNames();
|
|
||||||
if (anames == null)
|
|
||||||
return new String[0];
|
|
||||||
ArrayList<String> names = new ArrayList<String>();
|
|
||||||
while (anames.hasMoreElements())
|
|
||||||
names.add(anames.nextElement());
|
|
||||||
return names.toArray(new String[names.size()]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public abstract Object doPutOrRemove(String name, Object value);
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public abstract Object doGet(String name);
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public abstract Enumeration<String> doGetAttributeNames();
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public Object getAttribute(String name)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
checkValid();
|
|
||||||
return doGet(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public void setAttribute(String name, Object value)
|
|
||||||
{
|
|
||||||
changeAttribute(name,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @param name the name of the attribute
|
|
||||||
* @param value the value of the attribute
|
|
||||||
* @return true if attribute changed
|
|
||||||
* @deprecated use changeAttribute(String,Object) instead
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
protected boolean updateAttribute (String name, Object value)
|
|
||||||
{
|
|
||||||
Object old=null;
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
checkValid();
|
|
||||||
old=doPutOrRemove(name,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value==null || !value.equals(old))
|
|
||||||
{
|
|
||||||
if (old!=null)
|
|
||||||
unbindValue(name,old);
|
|
||||||
if (value!=null)
|
|
||||||
bindValue(name,value);
|
|
||||||
|
|
||||||
_manager.doSessionAttributeListeners(this,name,old,value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* Either set (perhaps replace) or remove the value of the attribute
|
|
||||||
* in the session. The appropriate session attribute listeners are
|
|
||||||
* also called.
|
|
||||||
*
|
|
||||||
* @param name the name of the attribute
|
|
||||||
* @param value the value of the attribute
|
|
||||||
* @return the old value for the attribute
|
|
||||||
*/
|
|
||||||
protected Object changeAttribute (String name, Object value)
|
|
||||||
{
|
|
||||||
Object old=null;
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
checkValid();
|
|
||||||
old=doPutOrRemove(name,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
callSessionAttributeListeners(name, value, old);
|
|
||||||
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* Call binding and attribute listeners based on the new and old
|
|
||||||
* values of the attribute.
|
|
||||||
*
|
|
||||||
* @param name name of the attribute
|
|
||||||
* @param newValue new value of the attribute
|
|
||||||
* @param oldValue previous value of the attribute
|
|
||||||
*/
|
|
||||||
protected void callSessionAttributeListeners (String name, Object newValue, Object oldValue)
|
|
||||||
{
|
|
||||||
if (newValue==null || !newValue.equals(oldValue))
|
|
||||||
{
|
|
||||||
if (oldValue!=null)
|
|
||||||
unbindValue(name,oldValue);
|
|
||||||
if (newValue!=null)
|
|
||||||
bindValue(name,newValue);
|
|
||||||
|
|
||||||
_manager.doSessionAttributeListeners(this,name,oldValue,newValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public void setIdChanged(boolean changed)
|
|
||||||
{
|
|
||||||
_idChanged=changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Override
|
|
||||||
public void setMaxInactiveInterval(int secs)
|
|
||||||
{
|
|
||||||
_maxIdleMs=(long)secs*1000L;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return this.getClass().getName()+":"+getId()+"@"+hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* Bind value if value implements {@link HttpSessionBindingListener} (calls {@link HttpSessionBindingListener#valueBound(HttpSessionBindingEvent)})
|
|
||||||
* @param name the name with which the object is bound or unbound
|
|
||||||
* @param value the bound value
|
|
||||||
*/
|
|
||||||
public void bindValue(java.lang.String name, Object value)
|
|
||||||
{
|
|
||||||
if (value!=null&&value instanceof HttpSessionBindingListener)
|
|
||||||
((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public boolean isValid()
|
|
||||||
{
|
|
||||||
return !_invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
protected void cookieSet()
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
_cookieSet=_accessed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public int getRequests()
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
return _requests;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public void setRequests(int requests)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
_requests=requests;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* Unbind value if value implements {@link HttpSessionBindingListener} (calls {@link HttpSessionBindingListener#valueUnbound(HttpSessionBindingEvent)})
|
|
||||||
* @param name the name with which the object is bound or unbound
|
|
||||||
* @param value the bound value
|
|
||||||
*/
|
|
||||||
public void unbindValue(java.lang.String name, Object value)
|
|
||||||
{
|
|
||||||
if (value!=null&&value instanceof HttpSessionBindingListener)
|
|
||||||
((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public void willPassivate()
|
|
||||||
{
|
|
||||||
synchronized(this)
|
|
||||||
{
|
|
||||||
HttpSessionEvent event = new HttpSessionEvent(this);
|
|
||||||
for (Iterator<Object> iter = getAttributeMap().values().iterator(); iter.hasNext();)
|
|
||||||
{
|
|
||||||
Object value = iter.next();
|
|
||||||
if (value instanceof HttpSessionActivationListener)
|
|
||||||
{
|
|
||||||
HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
|
|
||||||
listener.sessionWillPassivate(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
public void didActivate()
|
|
||||||
{
|
|
||||||
synchronized(this)
|
|
||||||
{
|
|
||||||
HttpSessionEvent event = new HttpSessionEvent(this);
|
|
||||||
for (Iterator<Object> iter = getAttributeMap().values().iterator(); iter.hasNext();)
|
|
||||||
{
|
|
||||||
Object value = iter.next();
|
|
||||||
if (value instanceof HttpSessionActivationListener)
|
|
||||||
{
|
|
||||||
HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
|
|
||||||
listener.sessionDidActivate(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
||||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||||
|
@ -60,7 +60,7 @@ public abstract class AbstractSessionDataStore extends AbstractLifeCycle impleme
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#store(java.lang.String, org.eclipse.jetty.server.session.x.SessionData)
|
* @see org.eclipse.jetty.server.session.SessionDataStore#store(java.lang.String, org.eclipse.jetty.server.session.SessionData)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void store(SessionKey key, SessionData data) throws Exception
|
public void store(SessionKey key, SessionData data) throws Exception
|
|
@ -23,7 +23,10 @@ import java.util.Random;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Handler;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.SessionIdManager;
|
import org.eclipse.jetty.server.SessionIdManager;
|
||||||
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
@ -39,6 +42,8 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
|
||||||
protected String _workerName;
|
protected String _workerName;
|
||||||
protected String _workerAttr;
|
protected String _workerAttr;
|
||||||
protected long _reseed=100000L;
|
protected long _reseed=100000L;
|
||||||
|
protected Server _server;
|
||||||
|
protected SessionScavenger _scavenger;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public AbstractSessionIdManager()
|
public AbstractSessionIdManager()
|
||||||
|
@ -52,10 +57,23 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setServer (Server server)
|
||||||
|
{
|
||||||
|
_server = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Server getServer ()
|
||||||
|
{
|
||||||
|
return _server;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setSessionScavenger (SessionScavenger scavenger)
|
||||||
|
{
|
||||||
|
_scavenger = scavenger;
|
||||||
|
_scavenger.setSessionIdManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public abstract void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request);
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -212,14 +230,26 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
|
||||||
@Override
|
@Override
|
||||||
protected void doStart() throws Exception
|
protected void doStart() throws Exception
|
||||||
{
|
{
|
||||||
|
if (_server == null)
|
||||||
|
throw new IllegalStateException("No Server for SessionIdManager");
|
||||||
initRandom();
|
initRandom();
|
||||||
_workerAttr=(_workerName!=null && _workerName.startsWith("$"))?_workerName.substring(1):null;
|
_workerAttr=(_workerName!=null && _workerName.startsWith("$"))?_workerName.substring(1):null;
|
||||||
|
|
||||||
|
if (_scavenger == null)
|
||||||
|
{
|
||||||
|
LOG.warn("No SessionScavenger set, using defaults");
|
||||||
|
_scavenger = new SessionScavenger();
|
||||||
|
_scavenger.setSessionIdManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_scavenger.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
protected void doStop() throws Exception
|
protected void doStop() throws Exception
|
||||||
{
|
{
|
||||||
|
_scavenger.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -281,5 +311,82 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
|
||||||
return (dot>0)?extendedId.substring(0,dot):extendedId;
|
return (dot>0)?extendedId.substring(0,dot):extendedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an id from use by telling all contexts to remove a session with this id.
|
||||||
|
*
|
||||||
|
* @see org.eclipse.jetty.server.SessionIdManager#expireAll(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void expireAll(String id)
|
||||||
|
{
|
||||||
|
//take the id out of the list of known sessionids for this node
|
||||||
|
removeId(id);
|
||||||
|
|
||||||
|
//tell all contexts that may have a session object with this id to
|
||||||
|
//get rid of them
|
||||||
|
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
||||||
|
for (int i=0; contexts!=null && i<contexts.length; i++)
|
||||||
|
{
|
||||||
|
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
|
||||||
|
if (sessionHandler != null)
|
||||||
|
{
|
||||||
|
SessionManager manager = (SessionManager)sessionHandler.getSessionManager();
|
||||||
|
|
||||||
|
if (manager != null)
|
||||||
|
{
|
||||||
|
manager.invalidate(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void invalidateAll (String id)
|
||||||
|
{
|
||||||
|
//take the id out of the list of known sessionids for this node
|
||||||
|
removeId(id);
|
||||||
|
//tell all contexts that may have a session object with this id to
|
||||||
|
//get rid of them
|
||||||
|
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
||||||
|
for (int i=0; contexts!=null && i<contexts.length; i++)
|
||||||
|
{
|
||||||
|
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
|
||||||
|
if (sessionHandler != null)
|
||||||
|
{
|
||||||
|
SessionManager manager = (SessionManager)sessionHandler.getSessionManager();
|
||||||
|
|
||||||
|
if (manager != null)
|
||||||
|
{
|
||||||
|
manager.invalidate(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.server.SessionIdManager#renewSessionId(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void renewSessionId (String oldClusterId, String oldNodeId, HttpServletRequest request)
|
||||||
|
{
|
||||||
|
//generate a new id
|
||||||
|
String newClusterId = newSessionId(request.hashCode());
|
||||||
|
|
||||||
|
removeId(oldClusterId);//remove the old one from the list (and database)
|
||||||
|
|
||||||
|
//tell all contexts to update the id
|
||||||
|
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
||||||
|
for (int i=0; contexts!=null && i<contexts.length; i++)
|
||||||
|
{
|
||||||
|
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
|
||||||
|
if (sessionHandler != null)
|
||||||
|
{
|
||||||
|
SessionManager manager = (SessionManager)sessionHandler.getSessionManager();
|
||||||
|
|
||||||
|
if (manager != null)
|
||||||
|
{
|
||||||
|
manager.renewSessionId(oldClusterId, oldNodeId, newClusterId, getExtendedId(newClusterId, request));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -123,7 +123,7 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
||||||
* the data for it from a SessionDataStore associated with the
|
* the data for it from a SessionDataStore associated with the
|
||||||
* session manager.
|
* session manager.
|
||||||
*
|
*
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionStore#get(java.lang.String)
|
* @see org.eclipse.jetty.server.session.SessionStore#get(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Session get(SessionKey key) throws Exception
|
public Session get(SessionKey key) throws Exception
|
||||||
|
@ -147,7 +147,7 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
||||||
* If the session manager supports a session data store, write the
|
* If the session manager supports a session data store, write the
|
||||||
* session data through to the session data store.
|
* session data through to the session data store.
|
||||||
*
|
*
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionStore#put(java.lang.String, org.eclipse.jetty.server.session.x.Session)
|
* @see org.eclipse.jetty.server.session.SessionStore#put(java.lang.String, org.eclipse.jetty.server.session.Session)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void put(SessionKey key, Session session) throws Exception
|
public void put(SessionKey key, Session session) throws Exception
|
||||||
|
@ -187,7 +187,7 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
||||||
*
|
*
|
||||||
* TODO should this check through to the backing store?
|
* TODO should this check through to the backing store?
|
||||||
*
|
*
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionStore#exists(java.lang.String)
|
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean exists(SessionKey key)
|
public boolean exists(SessionKey key)
|
||||||
|
@ -199,7 +199,7 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
||||||
/**
|
/**
|
||||||
* Remove a session object from this store and from any backing store.
|
* Remove a session object from this store and from any backing store.
|
||||||
*
|
*
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionStore#delete(java.lang.String)
|
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean delete(SessionKey key) throws Exception
|
public boolean delete(SessionKey key) throws Exception
|
||||||
|
@ -221,7 +221,7 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionStore#getExpired()
|
* @see org.eclipse.jetty.server.session.SessionStore#getExpired()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<SessionKey> getExpired()
|
public Set<SessionKey> getExpired()
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AlwaysStale
|
* AlwaysStale
|
||||||
|
@ -28,7 +28,7 @@ public class AlwaysStaleStrategy implements StalenessStrategy
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.StalenessStrategy#isStale(org.eclipse.jetty.server.session.x.Session)
|
* @see org.eclipse.jetty.server.session.StalenessStrategy#isStale(org.eclipse.jetty.server.session.Session)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isStale(Session session)
|
public boolean isStale(Session session)
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
|
@ -87,7 +87,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#newSessionData(org.eclipse.jetty.server.session.x.SessionKey, long, long, long, long)
|
* @see org.eclipse.jetty.server.session.SessionDataStore#newSessionData(org.eclipse.jetty.server.session.SessionKey, long, long, long, long)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SessionData newSessionData(SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
public SessionData newSessionData(SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||||
|
@ -96,7 +96,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#delete(org.eclipse.jetty.server.session.x.SessionKey)
|
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(org.eclipse.jetty.server.session.SessionKey)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean delete(SessionKey key) throws Exception
|
public boolean delete(SessionKey key) throws Exception
|
||||||
|
@ -116,7 +116,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#getExpired()
|
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<SessionKey> getExpired(Set<SessionKey> candidates)
|
public Set<SessionKey> getExpired(Set<SessionKey> candidates)
|
||||||
|
@ -127,7 +127,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#load(org.eclipse.jetty.server.session.x.SessionKey)
|
* @see org.eclipse.jetty.server.session.SessionDataStore#load(org.eclipse.jetty.server.session.SessionKey)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SessionData load(SessionKey key) throws Exception
|
public SessionData load(SessionKey key) throws Exception
|
||||||
|
@ -226,7 +226,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.AbstractSessionDataStore#doStore(org.eclipse.jetty.server.session.x.SessionKey, org.eclipse.jetty.server.session.x.SessionData)
|
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.SessionData)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doStore(SessionKey key, SessionData data) throws Exception
|
public void doStore(SessionKey key, SessionData data) throws Exception
|
|
@ -16,88 +16,25 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Handler;
|
|
||||||
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.ConcurrentHashSet;
|
import org.eclipse.jetty.util.ConcurrentHashSet;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* HashSessionIdManager. An in-memory implementation of the session ID manager.
|
* HashSessionIdManager
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class HashSessionIdManager extends AbstractSessionIdManager
|
public class HashSessionIdManager extends AbstractSessionIdManager
|
||||||
{
|
{
|
||||||
private final Set<String> _ids = new ConcurrentHashSet<String>();
|
private final Set<String> _ids = new ConcurrentHashSet<String>();
|
||||||
|
|
||||||
private Server _server;
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public HashSessionIdManager()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public HashSessionIdManager(Random random)
|
|
||||||
{
|
|
||||||
super(random);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setServer (Server server)
|
|
||||||
{
|
|
||||||
_server = server;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* @return Collection of String session IDs
|
* @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String)
|
||||||
*/
|
|
||||||
public Collection<String> getSessions()
|
|
||||||
{
|
|
||||||
return Collections.unmodifiableCollection(_ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
protected void doStart() throws Exception
|
|
||||||
{
|
|
||||||
if (_server == null)
|
|
||||||
throw new IllegalStateException ("No server set on HashSessionIdManager");
|
|
||||||
super.doStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
protected void doStop() throws Exception
|
|
||||||
{
|
|
||||||
_ids.clear();
|
|
||||||
super.doStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @see SessionIdManager#isIdInUse(String)
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isIdInUse(String id)
|
public boolean isIdInUse(String id)
|
||||||
|
@ -105,77 +42,38 @@ public class HashSessionIdManager extends AbstractSessionIdManager
|
||||||
return _ids.contains(id);
|
return _ids.contains(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* @see SessionIdManager#addSession(HttpSession)
|
* @see org.eclipse.jetty.server.session.AbstractSessionIdManager#newSessionId(long)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String newSessionId(long seedTerm)
|
||||||
|
{
|
||||||
|
String id = super.newSessionId(seedTerm);
|
||||||
|
useId(id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.server.SessionIdManager#useId(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void useId(String id)
|
public void useId(String id)
|
||||||
{
|
{
|
||||||
|
if (id == null)
|
||||||
|
return;
|
||||||
|
|
||||||
_ids.add(id);
|
_ids.add(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void removeId(String id)
|
public void removeId(String id)
|
||||||
{
|
{
|
||||||
_ids.remove(id);
|
_ids.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @see SessionIdManager#expireAll(String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void expireAll(String id)
|
|
||||||
{
|
|
||||||
//take the id out of the list of known sessionids for this node
|
|
||||||
removeId(id);
|
|
||||||
|
|
||||||
synchronized (_ids)
|
|
||||||
{
|
|
||||||
//tell all contexts that may have a session object with this id to
|
|
||||||
//get rid of them
|
|
||||||
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
|
||||||
for (int i=0; contexts!=null && i<contexts.length; i++)
|
|
||||||
{
|
|
||||||
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
|
|
||||||
if (sessionHandler != null)
|
|
||||||
{
|
|
||||||
SessionManager manager = sessionHandler.getSessionManager();
|
|
||||||
|
|
||||||
if (manager != null)
|
|
||||||
manager.expire(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public void renewSessionId (String oldClusterId, String oldNodeId, HttpServletRequest request)
|
|
||||||
{
|
|
||||||
//generate a new id
|
|
||||||
String newClusterId = newSessionId(request.hashCode());
|
|
||||||
|
|
||||||
synchronized (_ids)
|
|
||||||
{
|
|
||||||
removeId(oldClusterId);//remove the old one from the list (and database)
|
|
||||||
|
|
||||||
//tell all contexts to update the id
|
|
||||||
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
|
||||||
for (int i=0; contexts!=null && i<contexts.length; i++)
|
|
||||||
{
|
|
||||||
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
|
|
||||||
if (sessionHandler != null)
|
|
||||||
{
|
|
||||||
SessionManager manager = sessionHandler.getSessionManager();
|
|
||||||
if (manager != null)
|
|
||||||
manager.renewSessionId(oldClusterId, oldNodeId, newClusterId, getExtendedId(newClusterId, request));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,688 +16,41 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
|
||||||
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
|
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
|
||||||
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* HashSessionManager
|
* HashSessionManager
|
||||||
*
|
*
|
||||||
* An in-memory implementation of SessionManager.
|
|
||||||
* <p>
|
|
||||||
* This manager supports saving sessions to disk, either periodically or at shutdown.
|
|
||||||
* Sessions can also have their content idle saved to disk to reduce the memory overheads of large idle sessions.
|
|
||||||
* <p>
|
|
||||||
* This manager will create it's own Timer instance to scavenge threads, unless it discovers a shared Timer instance
|
|
||||||
* set as the "org.eclipse.jetty.server.session.timer" attribute of the ContextHandler.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class HashSessionManager extends AbstractSessionManager
|
public class HashSessionManager extends SessionManager
|
||||||
{
|
{
|
||||||
final static Logger LOG = SessionHandler.LOG;
|
protected FileSessionDataStore _sessionDataStore = new FileSessionDataStore();
|
||||||
|
|
||||||
protected final ConcurrentMap<String,HashedSession> _sessions=new ConcurrentHashMap<String,HashedSession>();
|
|
||||||
private Scheduler _timer;
|
|
||||||
private Scheduler.Task _task;
|
|
||||||
long _scavengePeriodMs=30000;
|
|
||||||
long _savePeriodMs=0; //don't do period saves by default
|
|
||||||
long _idleSavePeriodMs = 0; // don't idle save sessions by default.
|
|
||||||
private Scheduler.Task _saveTask;
|
|
||||||
File _storeDir;
|
|
||||||
private boolean _lazyLoad=false;
|
|
||||||
private volatile boolean _sessionsLoaded=false;
|
|
||||||
private boolean _deleteUnrestorableSessions=false;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scavenger
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
protected class Scavenger implements Runnable
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
scavenge();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (_timer != null && _timer.isRunning()) {
|
|
||||||
_task = _timer.schedule(this, _scavengePeriodMs, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saver
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
protected class Saver implements Runnable
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
saveSessions(true);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOG.warn(e);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (_timer != null && _timer.isRunning())
|
|
||||||
_saveTask = _timer.schedule(this, _savePeriodMs, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public HashSessionManager()
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @see AbstractSessionManager#doStart()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void doStart() throws Exception
|
public void doStart() throws Exception
|
||||||
{
|
{
|
||||||
//try shared scheduler from Server first
|
_sessionStore = new MemorySessionStore();
|
||||||
_timer = getSessionHandler().getServer().getBean(Scheduler.class);
|
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
|
||||||
if (_timer == null)
|
|
||||||
{
|
|
||||||
//try one passed into the context
|
|
||||||
ServletContext context = ContextHandler.getCurrentContext();
|
|
||||||
if (context!=null)
|
|
||||||
_timer = (Scheduler)context.getAttribute("org.eclipse.jetty.server.session.timer");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_timer == null)
|
|
||||||
{
|
|
||||||
//make a scheduler if none useable
|
|
||||||
_timer=new ScheduledExecutorScheduler(toString()+"Timer",true);
|
|
||||||
addBean(_timer,true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
addBean(_timer,false);
|
|
||||||
|
|
||||||
super.doStart();
|
super.doStart();
|
||||||
|
|
||||||
setScavengePeriod(getScavengePeriod());
|
|
||||||
|
|
||||||
if (_storeDir!=null)
|
|
||||||
{
|
|
||||||
if (!_storeDir.exists())
|
|
||||||
_storeDir.mkdirs();
|
|
||||||
|
|
||||||
if (!_lazyLoad)
|
|
||||||
restoreSessions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setSavePeriod(getSavePeriod());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @see AbstractSessionManager#doStop()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void doStop() throws Exception
|
public void doStop() throws Exception
|
||||||
{
|
{
|
||||||
// stop the scavengers
|
|
||||||
synchronized(this)
|
|
||||||
{
|
|
||||||
if (_saveTask!=null)
|
|
||||||
_saveTask.cancel();
|
|
||||||
|
|
||||||
_saveTask=null;
|
|
||||||
if (_task!=null)
|
|
||||||
_task.cancel();
|
|
||||||
|
|
||||||
_task=null;
|
|
||||||
_timer=null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// This will callback invalidate sessions - where we decide if we will save
|
|
||||||
super.doStop();
|
super.doStop();
|
||||||
|
|
||||||
_sessions.clear();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* @return the period in seconds at which a check is made for sessions to be invalidated.
|
* Get the SessionDataStore to configure it
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public int getScavengePeriod()
|
public FileSessionDataStore getSessionDataStore()
|
||||||
{
|
{
|
||||||
return (int)(_scavengePeriodMs/1000);
|
return _sessionDataStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public int getSessions()
|
|
||||||
{
|
|
||||||
int sessions=super.getSessions();
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
{
|
|
||||||
if (_sessions.size()!=sessions)
|
|
||||||
LOG.warn("sessions: "+_sessions.size()+"!="+sessions);
|
|
||||||
}
|
|
||||||
return sessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @return seconds Idle period after which a session is saved
|
|
||||||
*/
|
|
||||||
public int getIdleSavePeriod()
|
|
||||||
{
|
|
||||||
if (_idleSavePeriodMs <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (int)(_idleSavePeriodMs / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* Configures the period in seconds after which a session is deemed idle and saved
|
|
||||||
* to save on session memory.
|
|
||||||
*
|
|
||||||
* The session is persisted, the values attribute map is cleared and the session set to idled.
|
|
||||||
*
|
|
||||||
* @param seconds Idle period after which a session is saved
|
|
||||||
*/
|
|
||||||
public void setIdleSavePeriod(int seconds)
|
|
||||||
{
|
|
||||||
_idleSavePeriodMs = seconds * 1000L;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public void setMaxInactiveInterval(int seconds)
|
|
||||||
{
|
|
||||||
super.setMaxInactiveInterval(seconds);
|
|
||||||
if (_dftMaxIdleSecs>0&&_scavengePeriodMs>_dftMaxIdleSecs*1000L)
|
|
||||||
setScavengePeriod((_dftMaxIdleSecs+9)/10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @param seconds the period is seconds at which sessions are periodically saved to disk
|
|
||||||
*/
|
|
||||||
public void setSavePeriod (int seconds)
|
|
||||||
{
|
|
||||||
long period = (seconds * 1000L);
|
|
||||||
if (period < 0)
|
|
||||||
period=0;
|
|
||||||
_savePeriodMs=period;
|
|
||||||
|
|
||||||
if (_timer!=null)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_saveTask!=null)
|
|
||||||
_saveTask.cancel();
|
|
||||||
_saveTask = null;
|
|
||||||
if (_savePeriodMs > 0 && _storeDir!=null) //only save if we have a directory configured
|
|
||||||
{
|
|
||||||
_saveTask = _timer.schedule(new Saver(),_savePeriodMs,TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @return the period in seconds at which sessions are periodically saved to disk
|
|
||||||
*/
|
|
||||||
public int getSavePeriod ()
|
|
||||||
{
|
|
||||||
if (_savePeriodMs<=0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (int)(_savePeriodMs/1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @param seconds the period in seconds at which a check is made for sessions to be invalidated.
|
|
||||||
*/
|
|
||||||
public void setScavengePeriod(int seconds)
|
|
||||||
{
|
|
||||||
if (seconds==0)
|
|
||||||
seconds=60;
|
|
||||||
|
|
||||||
long old_period=_scavengePeriodMs;
|
|
||||||
long period=seconds*1000L;
|
|
||||||
if (period>60000)
|
|
||||||
period=60000;
|
|
||||||
if (period<1000)
|
|
||||||
period=1000;
|
|
||||||
|
|
||||||
_scavengePeriodMs=period;
|
|
||||||
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (_timer!=null && (period!=old_period || _task==null))
|
|
||||||
{
|
|
||||||
if (_task!=null)
|
|
||||||
{
|
|
||||||
_task.cancel();
|
|
||||||
_task = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_task = _timer.schedule(new Scavenger(),_scavengePeriodMs, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* Find sessions that have timed out and invalidate them. This runs in the
|
|
||||||
* SessionScavenger thread.
|
|
||||||
*/
|
|
||||||
protected void scavenge()
|
|
||||||
{
|
|
||||||
//don't attempt to scavenge if we are shutting down
|
|
||||||
if (isStopping() || isStopped())
|
|
||||||
return;
|
|
||||||
|
|
||||||
Thread thread=Thread.currentThread();
|
|
||||||
ClassLoader old_loader=thread.getContextClassLoader();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_loader!=null)
|
|
||||||
thread.setContextClassLoader(_loader);
|
|
||||||
|
|
||||||
// For each session
|
|
||||||
long now=System.currentTimeMillis();
|
|
||||||
__log.debug("Scavenging sessions at {}", now);
|
|
||||||
|
|
||||||
for (Iterator<HashedSession> i=_sessions.values().iterator(); i.hasNext();)
|
|
||||||
{
|
|
||||||
HashedSession session=i.next();
|
|
||||||
long idleTime=session.getMaxInactiveInterval()*1000L;
|
|
||||||
if (idleTime>0&&session.getAccessed()+idleTime<now)
|
|
||||||
{
|
|
||||||
// Found a stale session, add it to the list
|
|
||||||
try
|
|
||||||
{
|
|
||||||
session.timeout();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
__log.warn("Problem scavenging sessions", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_idleSavePeriodMs > 0 && session.getAccessed()+_idleSavePeriodMs < now)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
session.idle();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
__log.warn("Problem idling session "+ session.getId(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
thread.setContextClassLoader(old_loader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
protected void addSession(AbstractSession session)
|
|
||||||
{
|
|
||||||
if (isRunning())
|
|
||||||
_sessions.put(session.getClusterId(),(HashedSession)session);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public AbstractSession getSession(String idInCluster)
|
|
||||||
{
|
|
||||||
if ( _lazyLoad && !_sessionsLoaded)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
restoreSessions();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
LOG.warn(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String,HashedSession> sessions=_sessions;
|
|
||||||
if (sessions==null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
HashedSession session = sessions.get(idInCluster);
|
|
||||||
|
|
||||||
if (session == null && _lazyLoad)
|
|
||||||
session=restoreSession(idInCluster);
|
|
||||||
if (session == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (_idleSavePeriodMs!=0)
|
|
||||||
session.deIdle();
|
|
||||||
|
|
||||||
return session;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
protected void shutdownSessions() throws Exception
|
|
||||||
{
|
|
||||||
// Invalidate all sessions to cause unbind events
|
|
||||||
ArrayList<HashedSession> sessions=new ArrayList<HashedSession>(_sessions.values());
|
|
||||||
int loop=100;
|
|
||||||
while (sessions.size()>0 && loop-->0)
|
|
||||||
{
|
|
||||||
// If we are called from doStop
|
|
||||||
if (isStopping() && _storeDir != null && _storeDir.exists() && _storeDir.canWrite())
|
|
||||||
{
|
|
||||||
// Then we only save and remove the session from memory- it is not invalidated.
|
|
||||||
for (HashedSession session : sessions)
|
|
||||||
{
|
|
||||||
session.save(false);
|
|
||||||
_sessions.remove(session.getClusterId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (HashedSession session : sessions)
|
|
||||||
session.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that no new sessions were created while we were iterating
|
|
||||||
sessions=new ArrayList<HashedSession>(_sessions.values());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @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)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Map<String,HashedSession> sessions=_sessions;
|
|
||||||
if (sessions == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
HashedSession session = sessions.remove(oldClusterId);
|
|
||||||
if (session == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
session.remove(); //delete any previously saved session
|
|
||||||
session.setClusterId(newClusterId); //update ids
|
|
||||||
session.setNodeId(newNodeId);
|
|
||||||
session.save(); //save updated session: TODO consider only saving file if idled
|
|
||||||
sessions.put(newClusterId, session);
|
|
||||||
|
|
||||||
super.renewSessionId(oldClusterId, oldNodeId, newClusterId, newNodeId);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOG.warn(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateSession(String id)
|
|
||||||
{
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
//Called from SessionIdManager when invalidating all sessions with the same id
|
|
||||||
//across contexts
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
protected AbstractSession newSession(HttpServletRequest request)
|
|
||||||
{
|
|
||||||
return new HashedSession(this, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
protected AbstractSession newSession(long created, long accessed, String clusterId)
|
|
||||||
{
|
|
||||||
return new HashedSession(this, created,accessed, clusterId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
protected boolean removeSession(String clusterId)
|
|
||||||
{
|
|
||||||
return _sessions.remove(clusterId)!=null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public void setStoreDirectory (File dir) throws IOException
|
|
||||||
{
|
|
||||||
// CanonicalFile is used to capture the base store directory in a way that will
|
|
||||||
// work on Windows. Case differences may through off later checks using this directory.
|
|
||||||
_storeDir=dir.getCanonicalFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public File getStoreDirectory ()
|
|
||||||
{
|
|
||||||
return _storeDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public void setLazyLoad(boolean lazyLoad)
|
|
||||||
{
|
|
||||||
_lazyLoad = lazyLoad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public boolean isLazyLoad()
|
|
||||||
{
|
|
||||||
return _lazyLoad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public boolean isDeleteUnrestorableSessions()
|
|
||||||
{
|
|
||||||
return _deleteUnrestorableSessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public void setDeleteUnrestorableSessions(boolean deleteUnrestorableSessions)
|
|
||||||
{
|
|
||||||
_deleteUnrestorableSessions = deleteUnrestorableSessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public void restoreSessions () throws Exception
|
|
||||||
{
|
|
||||||
_sessionsLoaded = true;
|
|
||||||
|
|
||||||
if (_storeDir==null || !_storeDir.exists())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_storeDir.canRead())
|
|
||||||
{
|
|
||||||
LOG.warn ("Unable to restore Sessions: Cannot read from Session storage directory "+_storeDir.getAbsolutePath());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] files = _storeDir.list();
|
|
||||||
for (int i=0;files!=null&&i<files.length;i++)
|
|
||||||
{
|
|
||||||
restoreSession(files[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
protected synchronized HashedSession restoreSession(String idInCuster)
|
|
||||||
{
|
|
||||||
File file = new File(_storeDir,idInCuster);
|
|
||||||
|
|
||||||
Exception error = null;
|
|
||||||
if (!file.exists())
|
|
||||||
{
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
{
|
|
||||||
LOG.debug("Not loading: {}",file);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try (FileInputStream in = new FileInputStream(file))
|
|
||||||
{
|
|
||||||
HashedSession session = restoreSession(in,null);
|
|
||||||
addSession(session,false);
|
|
||||||
session.didActivate();
|
|
||||||
return session;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
error = e;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (error != null)
|
|
||||||
{
|
|
||||||
if (isDeleteUnrestorableSessions() && file.exists() && file.getParentFile().equals(_storeDir) )
|
|
||||||
{
|
|
||||||
file.delete();
|
|
||||||
LOG.warn("Deleting file for unrestorable session {} {}",idInCuster,error);
|
|
||||||
__log.debug(error);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
__log.warn("Problem restoring session {} {}",idInCuster, error);
|
|
||||||
__log.debug(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// delete successfully restored file
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public void saveSessions(boolean reactivate) throws Exception
|
|
||||||
{
|
|
||||||
if (_storeDir==null || !_storeDir.exists())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_storeDir.canWrite())
|
|
||||||
{
|
|
||||||
LOG.warn ("Unable to save Sessions: Session persistence storage directory "+_storeDir.getAbsolutePath()+ " is not writeable");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (HashedSession session : _sessions.values())
|
|
||||||
session.save(reactivate);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public HashedSession restoreSession (InputStream is, HashedSession session) throws Exception
|
|
||||||
{
|
|
||||||
DataInputStream di = new DataInputStream(is);
|
|
||||||
|
|
||||||
String clusterId = di.readUTF();
|
|
||||||
di.readUTF(); // nodeId
|
|
||||||
|
|
||||||
long created = di.readLong();
|
|
||||||
long accessed = di.readLong();
|
|
||||||
int requests = di.readInt();
|
|
||||||
|
|
||||||
if (session == null)
|
|
||||||
session = (HashedSession)newSession(created, accessed, clusterId);
|
|
||||||
|
|
||||||
session.setRequests(requests);
|
|
||||||
|
|
||||||
// Attributes
|
|
||||||
int size = di.readInt();
|
|
||||||
|
|
||||||
restoreSessionAttributes(di, size, session);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int maxIdle = di.readInt();
|
|
||||||
session.setMaxInactiveInterval(maxIdle);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
LOG.debug("No maxInactiveInterval persisted for session "+clusterId);
|
|
||||||
LOG.ignore(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return session;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
|
||||||
private void restoreSessionAttributes (InputStream is, int size, HashedSession session)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
if (size>0)
|
|
||||||
{
|
|
||||||
// input stream should not be closed here
|
|
||||||
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is);
|
|
||||||
for (int i=0; i<size;i++)
|
|
||||||
{
|
|
||||||
String key = ois.readUTF();
|
|
||||||
Object value = ois.readObject();
|
|
||||||
session.setAttribute(key,value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,286 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2015 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 java.io.DataOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.IO;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
|
||||||
|
|
||||||
public class HashedSession extends MemSession
|
|
||||||
{
|
|
||||||
private static final Logger LOG = Log.getLogger(HashedSession.class);
|
|
||||||
|
|
||||||
private final HashSessionManager _hashSessionManager;
|
|
||||||
|
|
||||||
/** Whether the session has been saved because it has been deemed idle;
|
|
||||||
* in which case its attribute map will have been saved and cleared. */
|
|
||||||
private transient boolean _idled = false;
|
|
||||||
|
|
||||||
/** Whether there has already been an attempt to save this session
|
|
||||||
* which has failed. If there has, there will be no more save attempts
|
|
||||||
* for this session. This is to stop the logs being flooded with errors
|
|
||||||
* due to serialization failures that are most likely caused by user
|
|
||||||
* data stored in the session that is not serializable. */
|
|
||||||
private transient boolean _saveFailed = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if an attempt has been made to de-idle a session and it failed. Once
|
|
||||||
* true, the session will not be attempted to be de-idled again.
|
|
||||||
*/
|
|
||||||
private transient boolean _deIdleFailed = false;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
protected HashedSession(HashSessionManager hashSessionManager, HttpServletRequest request)
|
|
||||||
{
|
|
||||||
super(hashSessionManager,request);
|
|
||||||
_hashSessionManager = hashSessionManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
protected HashedSession(HashSessionManager hashSessionManager, long created, long accessed, String clusterId)
|
|
||||||
{
|
|
||||||
super(hashSessionManager,created, accessed, clusterId);
|
|
||||||
_hashSessionManager = hashSessionManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
protected void checkValid()
|
|
||||||
{
|
|
||||||
if (!_deIdleFailed && _hashSessionManager._idleSavePeriodMs!=0)
|
|
||||||
deIdle();
|
|
||||||
super.checkValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Override
|
|
||||||
public void setMaxInactiveInterval(int secs)
|
|
||||||
{
|
|
||||||
super.setMaxInactiveInterval(secs);
|
|
||||||
if (getMaxInactiveInterval()>0&&(getMaxInactiveInterval()*1000L/10)<_hashSessionManager._scavengePeriodMs)
|
|
||||||
_hashSessionManager.setScavengePeriod((secs+9)/10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
protected void doInvalidate()
|
|
||||||
throws IllegalStateException
|
|
||||||
{
|
|
||||||
super.doInvalidate();
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* Remove from the disk
|
|
||||||
*/
|
|
||||||
synchronized void remove ()
|
|
||||||
{
|
|
||||||
if (_hashSessionManager._storeDir!=null && getId()!=null)
|
|
||||||
{
|
|
||||||
String id=getId();
|
|
||||||
File f = new File(_hashSessionManager._storeDir, id);
|
|
||||||
f.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
synchronized void save(boolean reactivate)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
// Only idle the session if not already idled and no previous save/idle has failed
|
|
||||||
if (!isIdled() && !_saveFailed)
|
|
||||||
{
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("Saving {} {}",super.getId(),reactivate);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
willPassivate();
|
|
||||||
save();
|
|
||||||
if (reactivate)
|
|
||||||
didActivate();
|
|
||||||
else
|
|
||||||
clearAttributes();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOG.warn("Problem saving session " + super.getId(), e);
|
|
||||||
_idled=false; // assume problem was before _values.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
synchronized void save ()
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
File file = null;
|
|
||||||
if (!_saveFailed && _hashSessionManager._storeDir != null)
|
|
||||||
{
|
|
||||||
file = new File(_hashSessionManager._storeDir, super.getId());
|
|
||||||
if (file.exists())
|
|
||||||
{
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
try(FileOutputStream fos = new FileOutputStream(file,false))
|
|
||||||
{
|
|
||||||
save(fos);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
saveFailed(); // We won't try again for this session
|
|
||||||
if (file != null)
|
|
||||||
file.delete(); // No point keeping the file if we didn't save the whole session
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public synchronized void save(OutputStream os) throws IOException
|
|
||||||
{
|
|
||||||
DataOutputStream out = new DataOutputStream(os);
|
|
||||||
out.writeUTF(getClusterId());
|
|
||||||
out.writeUTF(getNodeId());
|
|
||||||
out.writeLong(getCreationTime());
|
|
||||||
out.writeLong(getAccessed());
|
|
||||||
|
|
||||||
/* Don't write these out, as they don't make sense to store because they
|
|
||||||
* either they cannot be true or their value will be restored in the
|
|
||||||
* Session constructor.
|
|
||||||
*/
|
|
||||||
//out.writeBoolean(_invalid);
|
|
||||||
//out.writeBoolean(_doInvalidate);
|
|
||||||
//out.writeBoolean( _newSession);
|
|
||||||
out.writeInt(getRequests());
|
|
||||||
out.writeInt(getAttributes());
|
|
||||||
ObjectOutputStream oos = new ObjectOutputStream(out);
|
|
||||||
Enumeration<String> e=getAttributeNames();
|
|
||||||
while(e.hasMoreElements())
|
|
||||||
{
|
|
||||||
String key=e.nextElement();
|
|
||||||
oos.writeUTF(key);
|
|
||||||
oos.writeObject(doGet(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
out.writeInt(getMaxInactiveInterval());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public synchronized void deIdle()
|
|
||||||
{
|
|
||||||
if (isIdled() && !_deIdleFailed)
|
|
||||||
{
|
|
||||||
// Access now to prevent race with idling period
|
|
||||||
access(System.currentTimeMillis());
|
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("De-idling " + super.getId());
|
|
||||||
|
|
||||||
FileInputStream fis = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File file = new File(_hashSessionManager._storeDir, super.getId());
|
|
||||||
if (!file.exists() || !file.canRead())
|
|
||||||
throw new FileNotFoundException(file.getName());
|
|
||||||
|
|
||||||
fis = new FileInputStream(file);
|
|
||||||
_idled = false;
|
|
||||||
_hashSessionManager.restoreSession(fis, this);
|
|
||||||
IO.close(fis);
|
|
||||||
|
|
||||||
didActivate();
|
|
||||||
|
|
||||||
// If we are doing period saves, then there is no point deleting at this point
|
|
||||||
if (_hashSessionManager._savePeriodMs == 0)
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
deIdleFailed();
|
|
||||||
LOG.warn("Problem de-idling session " + super.getId(), e);
|
|
||||||
if (fis != null) IO.close(fis);//Must ensure closed before invalidate
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* Idle the session to reduce session memory footprint.
|
|
||||||
*
|
|
||||||
* The session is idled by persisting it, then clearing the session values attribute map and finally setting
|
|
||||||
* it to an idled state.
|
|
||||||
* @throws Exception if unable to save session
|
|
||||||
*/
|
|
||||||
public synchronized void idle()
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
save(false);
|
|
||||||
_idled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public synchronized boolean isIdled()
|
|
||||||
{
|
|
||||||
return _idled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public synchronized boolean isSaveFailed()
|
|
||||||
{
|
|
||||||
return _saveFailed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public synchronized void saveFailed()
|
|
||||||
{
|
|
||||||
_saveFailed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public synchronized void deIdleFailed()
|
|
||||||
{
|
|
||||||
_deIdleFailed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public synchronized boolean isDeIdleFailed()
|
|
||||||
{
|
|
||||||
return _deIdleFailed;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
@ -522,7 +522,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#newSessionData(org.eclipse.jetty.server.session.x.SessionKey, long, long, long, long)
|
* @see org.eclipse.jetty.server.session.SessionDataStore#newSessionData(org.eclipse.jetty.server.session.SessionKey, long, long, long, long)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SessionData newSessionData(SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
public SessionData newSessionData(SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||||
|
@ -576,7 +576,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#load(org.eclipse.jetty.server.session.x.SessionKey)
|
* @see org.eclipse.jetty.server.session.SessionDataStore#load(org.eclipse.jetty.server.session.SessionKey)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SessionData load(SessionKey key) throws Exception
|
public SessionData load(SessionKey key) throws Exception
|
||||||
|
@ -645,7 +645,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#delete(java.lang.String)
|
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean delete(SessionKey key) throws Exception
|
public boolean delete(SessionKey key) throws Exception
|
||||||
|
@ -665,7 +665,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.AbstractSessionDataStore#doStore()
|
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doStore(SessionKey key, SessionData data) throws Exception
|
public void doStore(SessionKey key, SessionData data) throws Exception
|
||||||
|
@ -776,7 +776,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#getExpired()
|
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<SessionKey> getExpired(Set<SessionKey> candidates)
|
public Set<SessionKey> getExpired(Set<SessionKey> candidates)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,146 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2015 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 java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MemSession
|
|
||||||
*
|
|
||||||
* A session whose data is kept in memory
|
|
||||||
*/
|
|
||||||
public class MemSession extends AbstractSession
|
|
||||||
{
|
|
||||||
|
|
||||||
private final Map<String,Object> _attributes=new HashMap<String, Object>();
|
|
||||||
|
|
||||||
protected MemSession(AbstractSessionManager abstractSessionManager, HttpServletRequest request)
|
|
||||||
{
|
|
||||||
super(abstractSessionManager, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MemSession(AbstractSessionManager abstractSessionManager, long created, long accessed, String clusterId)
|
|
||||||
{
|
|
||||||
super(abstractSessionManager, created, accessed, clusterId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Override
|
|
||||||
public Map<String,Object> getAttributeMap()
|
|
||||||
{
|
|
||||||
return _attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public int getAttributes()
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
checkValid();
|
|
||||||
return _attributes.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@SuppressWarnings({ "unchecked" })
|
|
||||||
@Override
|
|
||||||
public Enumeration<String> doGetAttributeNames()
|
|
||||||
{
|
|
||||||
List<String> names=_attributes==null?Collections.EMPTY_LIST:new ArrayList<String>(_attributes.keySet());
|
|
||||||
return Collections.enumeration(names);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public Set<String> getNames()
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
return new HashSet<String>(_attributes.keySet());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
@Override
|
|
||||||
public void clearAttributes()
|
|
||||||
{
|
|
||||||
while (_attributes!=null && _attributes.size()>0)
|
|
||||||
{
|
|
||||||
ArrayList<String> keys;
|
|
||||||
synchronized(this)
|
|
||||||
{
|
|
||||||
keys=new ArrayList<String>(_attributes.keySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator<String> iter=keys.iterator();
|
|
||||||
while (iter.hasNext())
|
|
||||||
{
|
|
||||||
String key=(String)iter.next();
|
|
||||||
|
|
||||||
Object value;
|
|
||||||
synchronized(this)
|
|
||||||
{
|
|
||||||
value=doPutOrRemove(key,null);
|
|
||||||
}
|
|
||||||
unbindValue(key,value);
|
|
||||||
|
|
||||||
((AbstractSessionManager)getSessionManager()).doSessionAttributeListeners(this,key,value,null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_attributes!=null)
|
|
||||||
_attributes.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public void addAttributes(Map<String,Object> map)
|
|
||||||
{
|
|
||||||
_attributes.putAll(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public Object doPutOrRemove(String name, Object value)
|
|
||||||
{
|
|
||||||
return value==null?_attributes.remove(name):_attributes.put(name,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
public Object doGet(String name)
|
|
||||||
{
|
|
||||||
return _attributes.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -82,7 +82,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.AbstractSessionStore#doGet(java.lang.String)
|
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doGet(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Session doGet(SessionKey key)
|
public Session doGet(SessionKey key)
|
||||||
|
@ -101,7 +101,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.AbstractSessionStore#doPut(java.lang.String, org.eclipse.jetty.server.session.x.Session)
|
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doPut(java.lang.String, org.eclipse.jetty.server.session.Session)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doPut(SessionKey key, Session session)
|
public void doPut(SessionKey key, Session session)
|
||||||
|
@ -110,7 +110,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.AbstractSessionStore#doExists(java.lang.String)
|
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doExists(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean doExists(SessionKey key)
|
public boolean doExists(SessionKey key)
|
||||||
|
@ -119,7 +119,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.AbstractSessionStore#doDelete(java.lang.String)
|
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doDelete(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doDelete(SessionKey key)
|
public void doDelete(SessionKey key)
|
||||||
|
@ -194,7 +194,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionStore#newSession(java.lang.String)
|
* @see org.eclipse.jetty.server.session.SessionStore#newSession(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Session newSession(SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
public Session newSession(SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||||
|
@ -206,7 +206,7 @@ public class MemorySessionStore extends AbstractSessionStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.AbstractSessionStore#newSession(org.eclipse.jetty.server.session.x.SessionData)
|
* @see org.eclipse.jetty.server.session.AbstractSessionStore#newSession(org.eclipse.jetty.server.session.SessionData)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Session newSession(SessionData data)
|
public Session newSession(SessionData data)
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NeverStale
|
* NeverStale
|
||||||
|
@ -28,7 +28,7 @@ public class NeverStaleStrategy implements StalenessStrategy
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.StalenessStrategy#isStale(org.eclipse.jetty.server.session.x.Session)
|
* @see org.eclipse.jetty.server.session.StalenessStrategy#isStale(org.eclipse.jetty.server.session.Session)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isStale(Session session)
|
public boolean isStale(Session session)
|
|
@ -17,9 +17,8 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,7 +30,7 @@ public class NullSessionDataStore extends AbstractSessionDataStore
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#load(java.lang.String)
|
* @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SessionData load(SessionKey key) throws Exception
|
public SessionData load(SessionKey key) throws Exception
|
||||||
|
@ -41,7 +40,7 @@ public class NullSessionDataStore extends AbstractSessionDataStore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#newSessionData(org.eclipse.jetty.server.session.x.SessionKey, long, long, long, long)
|
* @see org.eclipse.jetty.server.session.SessionDataStore#newSessionData(org.eclipse.jetty.server.session.SessionKey, long, long, long, long)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SessionData newSessionData(SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
public SessionData newSessionData(SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||||
|
@ -50,7 +49,7 @@ public class NullSessionDataStore extends AbstractSessionDataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#delete(java.lang.String)
|
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean delete(SessionKey key) throws Exception
|
public boolean delete(SessionKey key) throws Exception
|
||||||
|
@ -59,7 +58,7 @@ public class NullSessionDataStore extends AbstractSessionDataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.AbstractSessionDataStore#doStore()
|
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void doStore(SessionKey key, SessionData data) throws Exception
|
public void doStore(SessionKey key, SessionData data) throws Exception
|
||||||
|
@ -68,7 +67,7 @@ public class NullSessionDataStore extends AbstractSessionDataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.SessionDataStore#getExpired()
|
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<SessionKey> getExpired(Set<SessionKey> candidates)
|
public Set<SessionKey> getExpired(Set<SessionKey> candidates)
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
@ -32,6 +32,7 @@ import javax.servlet.http.HttpSessionBindingListener;
|
||||||
import javax.servlet.http.HttpSessionContext;
|
import javax.servlet.http.HttpSessionContext;
|
||||||
import javax.servlet.http.HttpSessionEvent;
|
import javax.servlet.http.HttpSessionEvent;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.session.SessionManager.SessionIf;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
|
@ -387,6 +388,13 @@ public class Session implements SessionManager.SessionIf
|
||||||
return SessionManager.__nullSessionContext;
|
return SessionManager.__nullSessionContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public SessionManager getSessionManager()
|
||||||
|
{
|
||||||
|
return _manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
* asserts that the session is valid
|
* asserts that the session is valid
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import static java.lang.Math.round;
|
import static java.lang.Math.round;
|
||||||
|
|
||||||
|
@ -46,8 +46,6 @@ import org.eclipse.jetty.http.HttpCookie;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.SessionIdManager;
|
import org.eclipse.jetty.server.SessionIdManager;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.server.session.HashSessionIdManager;
|
|
||||||
import org.eclipse.jetty.server.session.SessionHandler;
|
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedOperation;
|
import org.eclipse.jetty.util.annotation.ManagedOperation;
|
||||||
|
@ -507,7 +505,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
||||||
{
|
{
|
||||||
String sessionPath = (_cookieConfig.getPath()==null) ? contextPath : _cookieConfig.getPath();
|
String sessionPath = (_cookieConfig.getPath()==null) ? contextPath : _cookieConfig.getPath();
|
||||||
sessionPath = (sessionPath==null||sessionPath.length()==0) ? "/" : sessionPath;
|
sessionPath = (sessionPath==null||sessionPath.length()==0) ? "/" : sessionPath;
|
||||||
String id = getNodeId(session);
|
String id = getExtendedId(session);
|
||||||
HttpCookie cookie = null;
|
HttpCookie cookie = null;
|
||||||
if (_sessionComment == null)
|
if (_sessionComment == null)
|
||||||
{
|
{
|
||||||
|
@ -596,7 +594,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public String getClusterId(HttpSession session)
|
public String getId(HttpSession session)
|
||||||
{
|
{
|
||||||
Session s = ((SessionIf)session).getSession();
|
Session s = ((SessionIf)session).getSession();
|
||||||
return s.getId();
|
return s.getId();
|
||||||
|
@ -604,7 +602,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public String getNodeId(HttpSession session)
|
public String getExtendedId(HttpSession session)
|
||||||
{
|
{
|
||||||
Session s = ((SessionIf)session).getSession();
|
Session s = ((SessionIf)session).getSession();
|
||||||
return s.getExtendedId();
|
return s.getExtendedId();
|
|
@ -17,16 +17,14 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.server.SessionIdManager;
|
import org.eclipse.jetty.server.SessionIdManager;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.server.session.SessionHandler;
|
|
||||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StalePeriodStrategy
|
* StalePeriodStrategy
|
||||||
|
@ -29,7 +29,7 @@ public class StalePeriodStrategy implements StalenessStrategy
|
||||||
protected long _staleMs = 0;
|
protected long _staleMs = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.x.StalenessStrategy#isStale(org.eclipse.jetty.server.session.x.Session)
|
* @see org.eclipse.jetty.server.session.StalenessStrategy#isStale(org.eclipse.jetty.server.session.Session)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isStale (Session session)
|
public boolean isStale (Session session)
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StalenessStrategy
|
* StalenessStrategy
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UnreadableSessionData
|
* UnreadableSessionData
|
|
@ -17,7 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session.x;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UnwriteableSessionDataException
|
* UnwriteableSessionDataException
|
|
@ -21,12 +21,12 @@ package org.eclipse.jetty.server.session.jmx;
|
||||||
import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
|
import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.server.handler.jmx.AbstractHandlerMBean;
|
import org.eclipse.jetty.server.handler.jmx.AbstractHandlerMBean;
|
||||||
import org.eclipse.jetty.server.session.AbstractSessionManager;
|
import org.eclipse.jetty.server.session.SessionManager;
|
||||||
import org.eclipse.jetty.server.session.SessionHandler;
|
import org.eclipse.jetty.server.session.SessionHandler;
|
||||||
|
|
||||||
public class AbstractSessionManagerMBean extends AbstractHandlerMBean
|
public class SessionManagerMBean extends AbstractHandlerMBean
|
||||||
{
|
{
|
||||||
public AbstractSessionManagerMBean(Object managedObject)
|
public SessionManagerMBean(Object managedObject)
|
||||||
{
|
{
|
||||||
super(managedObject);
|
super(managedObject);
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,9 @@ public class AbstractSessionManagerMBean extends AbstractHandlerMBean
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public String getObjectContextBasis()
|
public String getObjectContextBasis()
|
||||||
{
|
{
|
||||||
if (_managed != null && _managed instanceof AbstractSessionManager)
|
if (_managed != null && _managed instanceof SessionManager)
|
||||||
{
|
{
|
||||||
AbstractSessionManager manager = (AbstractSessionManager)_managed;
|
SessionManager manager = (SessionManager)_managed;
|
||||||
|
|
||||||
String basis = null;
|
String basis = null;
|
||||||
SessionHandler handler = manager.getSessionHandler();
|
SessionHandler handler = manager.getSessionHandler();
|
|
@ -1,393 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2015 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.x;
|
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Handler;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.server.SessionIdManager;
|
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
|
||||||
import org.eclipse.jetty.server.session.SessionHandler;
|
|
||||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
|
||||||
|
|
||||||
public abstract class AbstractSessionIdManager extends AbstractLifeCycle implements SessionIdManager
|
|
||||||
{
|
|
||||||
private static final Logger LOG = Log.getLogger(AbstractSessionIdManager.class);
|
|
||||||
|
|
||||||
private final static String __NEW_SESSION_ID="org.eclipse.jetty.server.newSessionId";
|
|
||||||
|
|
||||||
protected Random _random;
|
|
||||||
protected boolean _weakRandom;
|
|
||||||
protected String _workerName;
|
|
||||||
protected String _workerAttr;
|
|
||||||
protected long _reseed=100000L;
|
|
||||||
protected Server _server;
|
|
||||||
protected SessionScavenger _scavenger;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public AbstractSessionIdManager()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public AbstractSessionIdManager(Random random)
|
|
||||||
{
|
|
||||||
_random=random;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setServer (Server server)
|
|
||||||
{
|
|
||||||
_server = server;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Server getServer ()
|
|
||||||
{
|
|
||||||
return _server;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setSessionScavenger (SessionScavenger scavenger)
|
|
||||||
{
|
|
||||||
_scavenger = scavenger;
|
|
||||||
_scavenger.setSessionIdManager(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* Get the workname. If set, the workername is dot appended to the session
|
|
||||||
* ID and can be used to assist session affinity in a load balancer.
|
|
||||||
*
|
|
||||||
* @return String or null
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getWorkerName()
|
|
||||||
{
|
|
||||||
return _workerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* Set the workername. If set, the workername is dot appended to the session
|
|
||||||
* ID and can be used to assist session affinity in a load balancer.
|
|
||||||
* A worker name starting with $ is used as a request attribute name to
|
|
||||||
* lookup the worker name that can be dynamically set by a request
|
|
||||||
* Customizer.
|
|
||||||
*
|
|
||||||
* @param workerName the name of the worker
|
|
||||||
*/
|
|
||||||
public void setWorkerName(String workerName)
|
|
||||||
{
|
|
||||||
if (isRunning())
|
|
||||||
throw new IllegalStateException(getState());
|
|
||||||
if (workerName.contains("."))
|
|
||||||
throw new IllegalArgumentException("Name cannot contain '.'");
|
|
||||||
_workerName=workerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public Random getRandom()
|
|
||||||
{
|
|
||||||
return _random;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public synchronized void setRandom(Random random)
|
|
||||||
{
|
|
||||||
_random=random;
|
|
||||||
_weakRandom=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @return the reseed probability
|
|
||||||
*/
|
|
||||||
public long getReseed()
|
|
||||||
{
|
|
||||||
return _reseed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/** Set the reseed probability.
|
|
||||||
* @param reseed If non zero then when a random long modulo the reseed value == 1, the {@link SecureRandom} will be reseeded.
|
|
||||||
*/
|
|
||||||
public void setReseed(long reseed)
|
|
||||||
{
|
|
||||||
_reseed = reseed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* Create a new session id if necessary.
|
|
||||||
*
|
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#newSessionId(javax.servlet.http.HttpServletRequest, long)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String newSessionId(HttpServletRequest request, long created)
|
|
||||||
{
|
|
||||||
synchronized (this)
|
|
||||||
{
|
|
||||||
if (request==null)
|
|
||||||
return newSessionId(created);
|
|
||||||
|
|
||||||
// A requested session ID can only be used if it is in use already.
|
|
||||||
String requested_id=request.getRequestedSessionId();
|
|
||||||
if (requested_id!=null)
|
|
||||||
{
|
|
||||||
String cluster_id=getId(requested_id);
|
|
||||||
if (isIdInUse(cluster_id))
|
|
||||||
return cluster_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Else reuse any new session ID already defined for this request.
|
|
||||||
String new_id=(String)request.getAttribute(__NEW_SESSION_ID);
|
|
||||||
if (new_id!=null&&isIdInUse(new_id))
|
|
||||||
return new_id;
|
|
||||||
|
|
||||||
// pick a new unique ID!
|
|
||||||
String id = newSessionId(request.hashCode());
|
|
||||||
|
|
||||||
request.setAttribute(__NEW_SESSION_ID,id);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public String newSessionId(long seedTerm)
|
|
||||||
{
|
|
||||||
// pick a new unique ID!
|
|
||||||
String id=null;
|
|
||||||
while (id==null||id.length()==0||isIdInUse(id))
|
|
||||||
{
|
|
||||||
long r0=_weakRandom
|
|
||||||
?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^((seedTerm)<<32))
|
|
||||||
:_random.nextLong();
|
|
||||||
if (r0<0)
|
|
||||||
r0=-r0;
|
|
||||||
|
|
||||||
// random chance to reseed
|
|
||||||
if (_reseed>0 && (r0%_reseed)== 1L)
|
|
||||||
{
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("Reseeding {}",this);
|
|
||||||
if (_random instanceof SecureRandom)
|
|
||||||
{
|
|
||||||
SecureRandom secure = (SecureRandom)_random;
|
|
||||||
secure.setSeed(secure.generateSeed(8));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_random.setSeed(_random.nextLong()^System.currentTimeMillis()^seedTerm^Runtime.getRuntime().freeMemory());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
long r1=_weakRandom
|
|
||||||
?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^((seedTerm)<<32))
|
|
||||||
:_random.nextLong();
|
|
||||||
if (r1<0)
|
|
||||||
r1=-r1;
|
|
||||||
|
|
||||||
id=Long.toString(r0,36)+Long.toString(r1,36);
|
|
||||||
|
|
||||||
//add in the id of the node to ensure unique id across cluster
|
|
||||||
//NOTE this is different to the node suffix which denotes which node the request was received on
|
|
||||||
if (_workerName!=null)
|
|
||||||
id=_workerName + id;
|
|
||||||
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
protected void doStart() throws Exception
|
|
||||||
{
|
|
||||||
if (_server == null)
|
|
||||||
throw new IllegalStateException("No Server for SessionIdManager");
|
|
||||||
initRandom();
|
|
||||||
_workerAttr=(_workerName!=null && _workerName.startsWith("$"))?_workerName.substring(1):null;
|
|
||||||
|
|
||||||
if (_scavenger == null)
|
|
||||||
{
|
|
||||||
LOG.warn("No SessionScavenger set, using defaults");
|
|
||||||
_scavenger = new SessionScavenger();
|
|
||||||
_scavenger.setSessionIdManager(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
_scavenger.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
|
||||||
protected void doStop() throws Exception
|
|
||||||
{
|
|
||||||
_scavenger.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* Set up a random number generator for the sessionids.
|
|
||||||
*
|
|
||||||
* By preference, use a SecureRandom but allow to be injected.
|
|
||||||
*/
|
|
||||||
public void initRandom ()
|
|
||||||
{
|
|
||||||
if (_random==null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_random=new SecureRandom();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOG.warn("Could not generate SecureRandom for session-id randomness",e);
|
|
||||||
_random=new Random();
|
|
||||||
_weakRandom=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_random.setSeed(_random.nextLong()^System.currentTimeMillis()^hashCode()^Runtime.getRuntime().freeMemory());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get the session ID with any worker ID.
|
|
||||||
*
|
|
||||||
* @param clusterId the cluster id
|
|
||||||
* @param request the request
|
|
||||||
* @return sessionId plus any worker ID.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getExtendedId(String clusterId, HttpServletRequest request)
|
|
||||||
{
|
|
||||||
if (_workerName!=null)
|
|
||||||
{
|
|
||||||
if (_workerAttr==null)
|
|
||||||
return clusterId+'.'+_workerName;
|
|
||||||
|
|
||||||
String worker=(String)request.getAttribute(_workerAttr);
|
|
||||||
if (worker!=null)
|
|
||||||
return clusterId+'.'+worker;
|
|
||||||
}
|
|
||||||
|
|
||||||
return clusterId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get the session ID without any worker ID.
|
|
||||||
*
|
|
||||||
* @param extendedId the session id with the worker extension
|
|
||||||
* @return sessionId without any worker ID.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getId(String extendedId)
|
|
||||||
{
|
|
||||||
int dot=extendedId.lastIndexOf('.');
|
|
||||||
return (dot>0)?extendedId.substring(0,dot):extendedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove an id from use by telling all contexts to remove a session with this id.
|
|
||||||
*
|
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#expireAll(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void expireAll(String id)
|
|
||||||
{
|
|
||||||
//take the id out of the list of known sessionids for this node
|
|
||||||
removeId(id);
|
|
||||||
|
|
||||||
//tell all contexts that may have a session object with this id to
|
|
||||||
//get rid of them
|
|
||||||
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
|
||||||
for (int i=0; contexts!=null && i<contexts.length; i++)
|
|
||||||
{
|
|
||||||
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
|
|
||||||
if (sessionHandler != null)
|
|
||||||
{
|
|
||||||
SessionManager manager = (SessionManager)sessionHandler.getSessionManager();
|
|
||||||
|
|
||||||
if (manager != null)
|
|
||||||
{
|
|
||||||
manager.invalidate(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void invalidateAll (String id)
|
|
||||||
{
|
|
||||||
//take the id out of the list of known sessionids for this node
|
|
||||||
removeId(id);
|
|
||||||
//tell all contexts that may have a session object with this id to
|
|
||||||
//get rid of them
|
|
||||||
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
|
||||||
for (int i=0; contexts!=null && i<contexts.length; i++)
|
|
||||||
{
|
|
||||||
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
|
|
||||||
if (sessionHandler != null)
|
|
||||||
{
|
|
||||||
SessionManager manager = (SessionManager)sessionHandler.getSessionManager();
|
|
||||||
|
|
||||||
if (manager != null)
|
|
||||||
{
|
|
||||||
manager.invalidate(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#renewSessionId(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void renewSessionId (String oldClusterId, String oldNodeId, HttpServletRequest request)
|
|
||||||
{
|
|
||||||
//generate a new id
|
|
||||||
String newClusterId = newSessionId(request.hashCode());
|
|
||||||
|
|
||||||
removeId(oldClusterId);//remove the old one from the list (and database)
|
|
||||||
|
|
||||||
//tell all contexts to update the id
|
|
||||||
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
|
||||||
for (int i=0; contexts!=null && i<contexts.length; i++)
|
|
||||||
{
|
|
||||||
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
|
|
||||||
if (sessionHandler != null)
|
|
||||||
{
|
|
||||||
SessionManager manager = (SessionManager)sessionHandler.getSessionManager();
|
|
||||||
|
|
||||||
if (manager != null)
|
|
||||||
{
|
|
||||||
manager.renewSessionId(oldClusterId, oldNodeId, newClusterId, getExtendedId(newClusterId, request));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2015 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.x;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.ConcurrentHashSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HashSessionIdManager
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class HashSessionIdManager extends AbstractSessionIdManager
|
|
||||||
{
|
|
||||||
private final Set<String> _ids = new ConcurrentHashSet<String>();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isIdInUse(String id)
|
|
||||||
{
|
|
||||||
return _ids.contains(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.session.x.AbstractSessionIdManager#newSessionId(long)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String newSessionId(long seedTerm)
|
|
||||||
{
|
|
||||||
String id = super.newSessionId(seedTerm);
|
|
||||||
useId(id);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#useId(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void useId(String id)
|
|
||||||
{
|
|
||||||
if (id == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_ids.add(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void removeId(String id)
|
|
||||||
{
|
|
||||||
_ids.remove(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2015 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.x;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HashSessionManager
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class HashSessionManager extends SessionManager
|
|
||||||
{
|
|
||||||
protected FileSessionDataStore _sessionDataStore = new FileSessionDataStore();
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doStart() throws Exception
|
|
||||||
{
|
|
||||||
_sessionStore = new MemorySessionStore();
|
|
||||||
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
|
|
||||||
|
|
||||||
super.doStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doStop() throws Exception
|
|
||||||
{
|
|
||||||
super.doStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the SessionDataStore to configure it
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public FileSessionDataStore getSessionDataStore()
|
|
||||||
{
|
|
||||||
return _sessionDataStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,439 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2015 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.x;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.sql.Blob;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DatabaseMetaData;
|
|
||||||
import java.sql.Driver;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.naming.InitialContext;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Handler;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.server.SessionManager;
|
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
|
||||||
import org.eclipse.jetty.server.session.SessionHandler;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
|
||||||
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JDBCSessionIdManager
|
|
||||||
*
|
|
||||||
* SessionIdManager implementation that uses a database to store in-use session ids,
|
|
||||||
* to support distributed sessions.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class JDBCSessionIdManager extends org.eclipse.jetty.server.session.x.AbstractSessionIdManager
|
|
||||||
{
|
|
||||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
|
||||||
|
|
||||||
public final static int MAX_INTERVAL_NOT_SET = -999;
|
|
||||||
|
|
||||||
protected final HashSet<String> _sessionIds = new HashSet<String>();
|
|
||||||
protected Server _server;
|
|
||||||
protected SessionScavenger _scavenger;
|
|
||||||
|
|
||||||
private DatabaseAdaptor _dbAdaptor = new DatabaseAdaptor();
|
|
||||||
|
|
||||||
protected SessionIdTableSchema _sessionIdTableSchema = new SessionIdTableSchema();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SessionIdTableSchema
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static class SessionIdTableSchema
|
|
||||||
{
|
|
||||||
protected String _tableName = "JettySessionIds";
|
|
||||||
protected String _idColumn = "id";
|
|
||||||
protected DatabaseAdaptor _jdbc;
|
|
||||||
|
|
||||||
public String getIdColumn()
|
|
||||||
{
|
|
||||||
return _idColumn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIdColumn(String idColumn)
|
|
||||||
{
|
|
||||||
checkNotNull(idColumn);
|
|
||||||
_idColumn = idColumn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTableName()
|
|
||||||
{
|
|
||||||
return _tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTableName(String tableName)
|
|
||||||
{
|
|
||||||
checkNotNull(tableName);
|
|
||||||
_tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getInsertStatementAsString ()
|
|
||||||
{
|
|
||||||
return "insert into "+_tableName+" ("+_idColumn+") values (?)";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDeleteStatementAsString ()
|
|
||||||
{
|
|
||||||
return "delete from "+_tableName+" where "+_idColumn+" = ?";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSelectStatementAsString ()
|
|
||||||
{
|
|
||||||
return "select * from "+_tableName+" where "+_idColumn+" = ?";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCreateStatementAsString ()
|
|
||||||
{
|
|
||||||
return "create table "+_tableName+" ("+_idColumn+" varchar(120), primary key("+_idColumn+"))";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void prepareTables (DatabaseAdaptor jdbc)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
_jdbc = jdbc;
|
|
||||||
try (Connection connection = _jdbc.getConnection();
|
|
||||||
Statement statement = connection.createStatement())
|
|
||||||
{
|
|
||||||
//make the id table
|
|
||||||
connection.setAutoCommit(true);
|
|
||||||
DatabaseMetaData metaData = connection.getMetaData();
|
|
||||||
_jdbc.adaptTo(metaData);
|
|
||||||
|
|
||||||
|
|
||||||
//checking for table existence is case-sensitive, but table creation is not
|
|
||||||
String tableName = _jdbc.convertIdentifier(getTableName());
|
|
||||||
try (ResultSet result = metaData.getTables(null, null, tableName, null))
|
|
||||||
{
|
|
||||||
if (!result.next())
|
|
||||||
{
|
|
||||||
//table does not exist, so create it
|
|
||||||
statement.executeUpdate(getCreateStatementAsString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkNotNull(String s)
|
|
||||||
{
|
|
||||||
if (s == null)
|
|
||||||
throw new IllegalArgumentException(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public JDBCSessionIdManager(Server server)
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
_server=server;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JDBCSessionIdManager(Server server, Random random)
|
|
||||||
{
|
|
||||||
super(random);
|
|
||||||
_server=server;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SessionIdTableSchema getSessionIdTableSchema()
|
|
||||||
{
|
|
||||||
return _sessionIdTableSchema;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String newSessionId(long seedTerm)
|
|
||||||
{
|
|
||||||
String id = super.newSessionId(seedTerm);
|
|
||||||
useId(id);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Record the session id as being in use
|
|
||||||
*
|
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#useId(java.lang.String)
|
|
||||||
*/
|
|
||||||
public void useId (String id)
|
|
||||||
{
|
|
||||||
if (id == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
synchronized (_sessionIds)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
insert(id);
|
|
||||||
_sessionIds.add(id);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOG.warn("Problem storing session id="+id, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the id from in-use set
|
|
||||||
*
|
|
||||||
* Prevents another context from using this id
|
|
||||||
*
|
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void removeId (String id)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (id == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
synchronized (_sessionIds)
|
|
||||||
{
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("Removing sessionid="+id);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_sessionIds.remove(id);
|
|
||||||
delete(id);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOG.warn("Problem removing session id="+id, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert a new used session id into the table.
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @throws SQLException
|
|
||||||
*/
|
|
||||||
private void insert (String id)
|
|
||||||
throws SQLException
|
|
||||||
{
|
|
||||||
try (Connection connection = _dbAdaptor.getConnection();
|
|
||||||
PreparedStatement query = connection.prepareStatement(_sessionIdTableSchema.getSelectStatementAsString()))
|
|
||||||
{
|
|
||||||
connection.setAutoCommit(true);
|
|
||||||
query.setString(1, id);
|
|
||||||
try (ResultSet result = query.executeQuery())
|
|
||||||
{
|
|
||||||
//only insert the id if it isn't in the db already
|
|
||||||
if (!result.next())
|
|
||||||
{
|
|
||||||
try (PreparedStatement statement = connection.prepareStatement(_sessionIdTableSchema.getInsertStatementAsString()))
|
|
||||||
{
|
|
||||||
statement.setString(1, id);
|
|
||||||
statement.executeUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a session id from the table.
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @throws SQLException
|
|
||||||
*/
|
|
||||||
private void delete (String id)
|
|
||||||
throws SQLException
|
|
||||||
{
|
|
||||||
try (Connection connection = _dbAdaptor.getConnection();
|
|
||||||
PreparedStatement statement = connection.prepareStatement(_sessionIdTableSchema.getDeleteStatementAsString()))
|
|
||||||
{
|
|
||||||
connection.setAutoCommit(true);
|
|
||||||
statement.setString(1, id);
|
|
||||||
statement.executeUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a session id exists.
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @return
|
|
||||||
* @throws SQLException
|
|
||||||
*/
|
|
||||||
private boolean exists (String id)
|
|
||||||
throws SQLException
|
|
||||||
{
|
|
||||||
try (Connection connection = _dbAdaptor.getConnection();
|
|
||||||
PreparedStatement statement = connection.prepareStatement(_sessionIdTableSchema.getSelectStatementAsString()))
|
|
||||||
{
|
|
||||||
connection.setAutoCommit(true);
|
|
||||||
statement.setString(1, id);
|
|
||||||
try (ResultSet result = statement.executeQuery())
|
|
||||||
{
|
|
||||||
return result.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isIdInUse(String id)
|
|
||||||
{
|
|
||||||
if (id == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
String sessionId = getId(id);
|
|
||||||
boolean inUse = false;
|
|
||||||
synchronized (_sessionIds)
|
|
||||||
{
|
|
||||||
inUse = _sessionIds.contains(sessionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (inUse)
|
|
||||||
return true; //optimisation - if this session is one we've been managing, we can check locally
|
|
||||||
|
|
||||||
//otherwise, we need to go to the database to check
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return exists(sessionId);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LOG.warn("Problem checking inUse for id="+sessionId, e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invalidate the session matching the id on all contexts.
|
|
||||||
*
|
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#expireAll(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void expireAll(String id)
|
|
||||||
{
|
|
||||||
synchronized (_sessionIds)
|
|
||||||
{
|
|
||||||
super.expireAll(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request)
|
|
||||||
{
|
|
||||||
synchronized (_sessionIds)
|
|
||||||
{
|
|
||||||
super.renewSessionId(oldClusterId, oldNodeId, request);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the database adaptor in order to configure it
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public DatabaseAdaptor getDatabaseAdaptor ()
|
|
||||||
{
|
|
||||||
return _dbAdaptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start up the id manager.
|
|
||||||
*
|
|
||||||
* Makes necessary database tables and starts a Session
|
|
||||||
* scavenger thread.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doStart()
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
_dbAdaptor.initialize();
|
|
||||||
_sessionIdTableSchema.prepareTables(_dbAdaptor);
|
|
||||||
|
|
||||||
super.doStart();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void doStop ()
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
_sessionIds.clear();
|
|
||||||
|
|
||||||
super.doStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param sql
|
|
||||||
* @param atoms
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
private String fillInClause (String sql, String[] literals, int start, int end)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
StringBuffer buff = new StringBuffer();
|
|
||||||
buff.append(sql);
|
|
||||||
buff.append("(");
|
|
||||||
for (int i=start; i<end; i++)
|
|
||||||
{
|
|
||||||
buff.append("'"+(literals[i])+"'");
|
|
||||||
if (i+1<end)
|
|
||||||
buff.append(",");
|
|
||||||
}
|
|
||||||
buff.append(")");
|
|
||||||
return buff.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2015 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.x;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JDBCSessionManager
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class JDBCSessionManager extends SessionManager
|
|
||||||
{
|
|
||||||
|
|
||||||
protected DatabaseAdaptor _db = new DatabaseAdaptor();
|
|
||||||
protected JDBCSessionDataStore _sessionDataStore = new JDBCSessionDataStore();
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doStart() throws Exception
|
|
||||||
{
|
|
||||||
_sessionStore = new MemorySessionStore();
|
|
||||||
_sessionDataStore.setDatabaseAdaptor(_db);
|
|
||||||
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
|
|
||||||
|
|
||||||
super.doStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doStop() throws Exception
|
|
||||||
{
|
|
||||||
super.doStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the db adaptor to configure jdbc settings
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public DatabaseAdaptor getDatabaseAdaptor()
|
|
||||||
{
|
|
||||||
return _db;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the SessionDataStore to configure it
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public JDBCSessionDataStore getSessionDataStore ()
|
|
||||||
{
|
|
||||||
return _sessionDataStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -55,7 +55,8 @@ import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.server.session.HashSessionIdManager;
|
import org.eclipse.jetty.server.session.HashSessionIdManager;
|
||||||
import org.eclipse.jetty.server.session.HashSessionManager;
|
import org.eclipse.jetty.server.session.HashSessionManager;
|
||||||
import org.eclipse.jetty.server.session.HashedSession;
|
import org.eclipse.jetty.server.session.Session;
|
||||||
|
import org.eclipse.jetty.server.session.SessionData;
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
import org.eclipse.jetty.util.thread.TimerScheduler;
|
import org.eclipse.jetty.util.thread.TimerScheduler;
|
||||||
|
@ -835,11 +836,12 @@ public class ResponseTest
|
||||||
return new Response(_channel, _channel.getResponse().getHttpOutput());
|
return new Response(_channel, _channel.getResponse().getHttpOutput());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestSession extends HashedSession
|
private static class TestSession extends Session
|
||||||
{
|
{
|
||||||
protected TestSession(HashSessionManager hashSessionManager, String id)
|
protected TestSession(HashSessionManager hashSessionManager, String id)
|
||||||
{
|
{
|
||||||
super(hashSessionManager, 0L, 0L, id);
|
super(new SessionData(id, "", "0.0.0.0", 0, 0, 0, 300));
|
||||||
|
setSessionManager(hashSessionManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,11 @@ public class HashSessionManagerTest
|
||||||
public void testDangerousSessionIdRemoval() throws Exception
|
public void testDangerousSessionIdRemoval() throws Exception
|
||||||
{
|
{
|
||||||
final HashSessionManager manager = new HashSessionManager();
|
final HashSessionManager manager = new HashSessionManager();
|
||||||
manager.setDeleteUnrestorableSessions(true);
|
manager.getSessionDataStore().setDeleteUnrestorableFiles(true);
|
||||||
manager.setLazyLoad(true);
|
//manager.setLazyLoad(true);
|
||||||
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
|
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
|
||||||
testDir.mkdirs();
|
testDir.mkdirs();
|
||||||
manager.setStoreDirectory(testDir);
|
manager.getSessionDataStore().setStoreDir(testDir);
|
||||||
|
|
||||||
MavenTestingUtils.getTargetFile("dangerFile.session").createNewFile();
|
MavenTestingUtils.getTargetFile("dangerFile.session").createNewFile();
|
||||||
|
|
||||||
|
@ -54,12 +54,12 @@ public class HashSessionManagerTest
|
||||||
public void testValidSessionIdRemoval() throws Exception
|
public void testValidSessionIdRemoval() throws Exception
|
||||||
{
|
{
|
||||||
final HashSessionManager manager = new HashSessionManager();
|
final HashSessionManager manager = new HashSessionManager();
|
||||||
manager.setDeleteUnrestorableSessions(true);
|
manager.getSessionDataStore().setDeleteUnrestorableFiles(true);
|
||||||
manager.setLazyLoad(true);
|
// manager.setLazyLoad(true);
|
||||||
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
|
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
|
||||||
FS.ensureEmpty(testDir);
|
FS.ensureEmpty(testDir);
|
||||||
|
|
||||||
manager.setStoreDirectory(testDir);
|
manager.getSessionDataStore().setStoreDir(testDir);
|
||||||
|
|
||||||
Assert.assertTrue(new File(testDir, "validFile.session").createNewFile());
|
Assert.assertTrue(new File(testDir, "validFile.session").createNewFile());
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ public class HashSessionManagerTest
|
||||||
SessionHandler handler = new SessionHandler();
|
SessionHandler handler = new SessionHandler();
|
||||||
handler.setServer(server);
|
handler.setServer(server);
|
||||||
HashSessionManager manager = new HashSessionManager();
|
HashSessionManager manager = new HashSessionManager();
|
||||||
manager.setStoreDirectory(testDir);
|
manager.getSessionDataStore().setStoreDir(testDir);
|
||||||
manager.setMaxInactiveInterval(5);
|
manager.setMaxInactiveInterval(5);
|
||||||
Assert.assertTrue(testDir.exists());
|
Assert.assertTrue(testDir.exists());
|
||||||
Assert.assertTrue(testDir.canWrite());
|
Assert.assertTrue(testDir.canWrite());
|
||||||
|
@ -95,7 +95,7 @@ public class HashSessionManagerTest
|
||||||
server.start();
|
server.start();
|
||||||
manager.start();
|
manager.start();
|
||||||
|
|
||||||
HashedSession session = (HashedSession)manager.newHttpSession(new Request(null, null));
|
Session session = (Session)manager.newHttpSession(new Request(null, null));
|
||||||
String sessionId = session.getId();
|
String sessionId = session.getId();
|
||||||
|
|
||||||
session.setAttribute("one", new Integer(1));
|
session.setAttribute("one", new Integer(1));
|
||||||
|
@ -107,10 +107,11 @@ public class HashSessionManagerTest
|
||||||
|
|
||||||
Assert.assertTrue("File should exist!", new File(testDir, session.getId()).exists());
|
Assert.assertTrue("File should exist!", new File(testDir, session.getId()).exists());
|
||||||
|
|
||||||
//start will restore sessions
|
|
||||||
manager.start();
|
manager.start();
|
||||||
|
|
||||||
HashedSession restoredSession = (HashedSession)manager.getSession(sessionId);
|
//restore session
|
||||||
|
Session restoredSession = (Session)manager.getSession(sessionId);
|
||||||
Assert.assertNotNull(restoredSession);
|
Assert.assertNotNull(restoredSession);
|
||||||
|
|
||||||
Object o = restoredSession.getAttribute("one");
|
Object o = restoredSession.getAttribute("one");
|
||||||
|
|
|
@ -37,102 +37,95 @@ import org.junit.Test;
|
||||||
*/
|
*/
|
||||||
public class SessionCookieTest
|
public class SessionCookieTest
|
||||||
{
|
{
|
||||||
public class MockSession extends AbstractSession
|
|
||||||
|
|
||||||
|
|
||||||
|
public class MockSessionStore extends AbstractSessionStore
|
||||||
{
|
{
|
||||||
protected MockSession(AbstractSessionManager abstractSessionManager, long created, long accessed, String clusterId)
|
|
||||||
{
|
|
||||||
super(abstractSessionManager, created, accessed, clusterId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see javax.servlet.http.HttpSession#getAttribute(java.lang.String)
|
* @see org.eclipse.jetty.server.session.SessionStore#newSession(org.eclipse.jetty.server.session.SessionKey, long, long, long, long)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object getAttribute(String name)
|
public Session newSession(SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||||
{
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see javax.servlet.http.HttpSession#getAttributeNames()
|
* @see org.eclipse.jetty.server.session.SessionStore#shutdown()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Enumeration<String> getAttributeNames()
|
public void shutdown()
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getValueNames()
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSession#getAttributeMap()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> getAttributeMap()
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSession#getAttributes()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int getAttributes()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSession#getNames()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Set<String> getNames()
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSession#clearAttributes()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void clearAttributes()
|
|
||||||
{
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSession#doPutOrRemove(java.lang.String, java.lang.Object)
|
* @see org.eclipse.jetty.server.session.AbstractSessionStore#newSession(org.eclipse.jetty.server.session.SessionData)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object doPutOrRemove(String name, Object value)
|
public Session newSession(SessionData data)
|
||||||
{
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSession#doGet(java.lang.String)
|
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doGet(org.eclipse.jetty.server.session.SessionKey)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object doGet(String name)
|
public Session doGet(SessionKey key)
|
||||||
{
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSession#doGetAttributeNames()
|
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doPut(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.Session)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Enumeration<String> doGetAttributeNames()
|
public void doPut(SessionKey key, Session session)
|
||||||
{
|
{
|
||||||
return null;
|
// TODO Auto-generated method stub
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doExists(org.eclipse.jetty.server.session.SessionKey)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean doExists(SessionKey key)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doDelete(org.eclipse.jetty.server.session.SessionKey)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void doDelete(SessionKey key)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doGetExpiredCandidates()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Set<SessionKey> doGetExpiredCandidates()
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class MockSessionIdManager extends AbstractSessionIdManager
|
public class MockSessionIdManager extends AbstractSessionIdManager
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -145,24 +138,6 @@ public class SessionCookieTest
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#addSession(javax.servlet.http.HttpSession)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void addSession(HttpSession session)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#removeSession(javax.servlet.http.HttpSession)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void removeSession(HttpSession session)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.SessionIdManager#expireAll(java.lang.String)
|
* @see org.eclipse.jetty.server.SessionIdManager#expireAll(java.lang.String)
|
||||||
*/
|
*/
|
||||||
|
@ -179,64 +154,37 @@ public class SessionCookieTest
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MockSessionManager extends AbstractSessionManager
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSession)
|
* @see org.eclipse.jetty.server.SessionIdManager#useId(java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void addSession(AbstractSession session)
|
public void useId(String id)
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSessionManager#getSession(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public AbstractSession getSession(String idInCluster)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSessionManager#shutdownSessions()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void shutdownSessions() throws Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSessionManager#newSession(javax.servlet.http.HttpServletRequest)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected AbstractSession newSession(HttpServletRequest request)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected boolean removeSession(String idInCluster)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
|
|
||||||
{
|
{
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void removeId(String id)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MockSessionManager extends SessionManager
|
||||||
|
{
|
||||||
|
public MockSessionManager()
|
||||||
|
{
|
||||||
|
_sessionStore = new MockSessionStore();
|
||||||
|
((AbstractSessionStore)_sessionStore).setSessionDataStore(new NullSessionDataStore());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSecureSessionCookie () throws Exception
|
public void testSecureSessionCookie () throws Exception
|
||||||
|
@ -245,7 +193,10 @@ public class SessionCookieTest
|
||||||
idMgr.setWorkerName("node1");
|
idMgr.setWorkerName("node1");
|
||||||
MockSessionManager mgr = new MockSessionManager();
|
MockSessionManager mgr = new MockSessionManager();
|
||||||
mgr.setSessionIdManager(idMgr);
|
mgr.setSessionIdManager(idMgr);
|
||||||
MockSession session = new MockSession(mgr, System.currentTimeMillis(), System.currentTimeMillis(), "node1123"); //clusterId
|
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
|
Session session = new Session(new SessionData("123", "_foo", "0.0.0.0", now, now, now, 30));
|
||||||
|
|
||||||
SessionCookieConfig sessionCookieConfig = mgr.getSessionCookieConfig();
|
SessionCookieConfig sessionCookieConfig = mgr.getSessionCookieConfig();
|
||||||
sessionCookieConfig.setSecure(true);
|
sessionCookieConfig.setSecure(true);
|
||||||
|
|
Loading…
Reference in New Issue