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)
|
||||
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
|
||||
//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.ContextHandler;
|
||||
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;
|
||||
|
||||
@ManagedObject("Mongo Session Manager MBean")
|
||||
public class MongoSessionManagerMBean extends AbstractSessionManagerMBean
|
||||
public class MongoSessionManagerMBean extends SessionManagerMBean
|
||||
{
|
||||
|
||||
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.Response;
|
||||
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.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
|
||||
//(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;
|
||||
String oldId = abstractSession.getId();
|
||||
abstractSession.renewId(request);
|
||||
abstractSession.setAttribute(AbstractSession.SESSION_CREATED_SECURE, Boolean.TRUE);
|
||||
if (abstractSession.isIdChanged() && response != null && (response instanceof Response))
|
||||
((Response)response).addCookie(abstractSession.getSessionManager().getSessionCookie(abstractSession, request.getContextPath(), request.isSecure()));
|
||||
LOG.debug("renew {}->{}",oldId,abstractSession.getId());
|
||||
Session s = (Session)httpSession;
|
||||
String oldId = s.getId();
|
||||
s.renewId(request);
|
||||
s.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
|
||||
if (s.isIdChanged() && response != null && (response instanceof Response))
|
||||
((Response)response).addCookie(s.getSessionManager().getSessionCookie(s, request.getContextPath(), request.isSecure()));
|
||||
LOG.debug("renew {}->{}",oldId,s.getId());
|
||||
}
|
||||
else
|
||||
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.SecurityHandler;
|
||||
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.Logger;
|
||||
|
||||
|
@ -89,7 +89,7 @@ public class SessionAuthentication extends AbstractUserAuthentication implements
|
|||
if (security!=null)
|
||||
security.logout(this);
|
||||
if (_session!=null)
|
||||
_session.removeAttribute(AbstractSession.SESSION_CREATED_SECURE);
|
||||
_session.removeAttribute(Session.SESSION_CREATED_SECURE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -76,7 +76,7 @@ import org.eclipse.jetty.http.MetaData;
|
|||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
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.AttributesMap;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
|
@ -1494,14 +1494,14 @@ public class Request implements HttpServletRequest
|
|||
if (session == null)
|
||||
throw new IllegalStateException("No session");
|
||||
|
||||
if (session instanceof AbstractSession)
|
||||
if (session instanceof Session)
|
||||
{
|
||||
AbstractSession abstractSession = ((AbstractSession)session);
|
||||
abstractSession.renewId(this);
|
||||
Session s = ((Session)session);
|
||||
s.renewId(this);
|
||||
if (getRemoteUser() != null)
|
||||
abstractSession.setAttribute(AbstractSession.SESSION_CREATED_SECURE, Boolean.TRUE);
|
||||
if (abstractSession.isIdChanged())
|
||||
_channel.getResponse().addCookie(_sessionManager.getSessionCookie(abstractSession, getContextPath(), isSecure()));
|
||||
s.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
|
||||
if (s.isIdChanged())
|
||||
_channel.getResponse().addCookie(_sessionManager.getSessionCookie(s, getContextPath(), isSecure()));
|
||||
}
|
||||
|
||||
return session.getId();
|
||||
|
@ -1697,7 +1697,7 @@ public class Request implements HttpServletRequest
|
|||
return 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))
|
||||
return url;
|
||||
|
||||
String id = sessionManager.getNodeId(session);
|
||||
String id = sessionManager.getExtendedId(session);
|
||||
|
||||
if (uri == null)
|
||||
uri = new HttpURI(url);
|
||||
|
|
|
@ -216,17 +216,17 @@ public interface SessionManager extends LifeCycle
|
|||
/**
|
||||
* @param session the session object
|
||||
* @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
|
||||
* @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.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
|
||||
public void store(SessionKey key, SessionData data) throws Exception
|
|
@ -23,7 +23,10 @@ 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.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -39,6 +42,8 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
|
|||
protected String _workerName;
|
||||
protected String _workerAttr;
|
||||
protected long _reseed=100000L;
|
||||
protected Server _server;
|
||||
protected SessionScavenger _scavenger;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
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;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public abstract void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request);
|
||||
|
||||
public void setSessionScavenger (SessionScavenger scavenger)
|
||||
{
|
||||
_scavenger = scavenger;
|
||||
_scavenger.setSessionIdManager(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -212,14 +230,26 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
|
|||
@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();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -281,5 +311,82 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
|
|||
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.Map;
|
||||
|
@ -123,7 +123,7 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
* the data for it from a SessionDataStore associated with the
|
||||
* 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
|
||||
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
|
||||
* 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
|
||||
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?
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.x.SessionStore#exists(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*
|
||||
* @see org.eclipse.jetty.server.session.x.SessionStore#delete(java.lang.String)
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
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
|
||||
public Set<SessionKey> getExpired()
|
|
@ -17,7 +17,7 @@
|
|||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session.x;
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* 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
|
||||
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.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.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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
public void doStore(SessionKey key, SessionData data) throws Exception
|
|
@ -16,166 +16,64 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
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 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;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* HashSessionIdManager. An in-memory implementation of the session ID manager.
|
||||
* HashSessionIdManager
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class HashSessionIdManager extends AbstractSessionIdManager
|
||||
{
|
||||
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
|
||||
*/
|
||||
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)
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean isIdInUse(String id)
|
||||
{
|
||||
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
|
||||
public void useId(String id)
|
||||
{
|
||||
_ids.add(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);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @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));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ids.remove(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,688 +16,41 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
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
|
||||
*
|
||||
* 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 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;
|
||||
protected FileSessionDataStore _sessionDataStore = new FileSessionDataStore();
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
public void doStart() throws Exception
|
||||
{
|
||||
//try shared scheduler from Server first
|
||||
_timer = getSessionHandler().getServer().getBean(Scheduler.class);
|
||||
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);
|
||||
_sessionStore = new MemorySessionStore();
|
||||
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
|
||||
|
||||
super.doStart();
|
||||
|
||||
setScavengePeriod(getScavengePeriod());
|
||||
|
||||
if (_storeDir!=null)
|
||||
{
|
||||
if (!_storeDir.exists())
|
||||
_storeDir.mkdirs();
|
||||
|
||||
if (!_lazyLoad)
|
||||
restoreSessions();
|
||||
}
|
||||
|
||||
setSavePeriod(getSavePeriod());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see AbstractSessionManager#doStop()
|
||||
*/
|
||||
@Override
|
||||
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();
|
||||
|
||||
_sessions.clear();
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return the period in seconds at which a check is made for sessions to be invalidated.
|
||||
*/
|
||||
public int getScavengePeriod()
|
||||
{
|
||||
return (int)(_scavengePeriodMs/1000);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@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)
|
||||
* Get the SessionDataStore to configure it
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
|
||||
public FileSessionDataStore getSessionDataStore()
|
||||
{
|
||||
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
|
||||
return _sessionDataStore;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@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.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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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.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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
public Session newSession(SessionData data)
|
|
@ -17,7 +17,7 @@
|
|||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session.x;
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* 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
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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.Enumeration;
|
||||
|
@ -32,6 +32,7 @@ import javax.servlet.http.HttpSessionBindingListener;
|
|||
import javax.servlet.http.HttpSessionContext;
|
||||
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.Logger;
|
||||
|
||||
|
@ -387,6 +388,13 @@ public class Session implements SessionManager.SessionIf
|
|||
return SessionManager.__nullSessionContext;
|
||||
}
|
||||
|
||||
|
||||
public SessionManager getSessionManager()
|
||||
{
|
||||
return _manager;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/**
|
||||
* 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.Serializable;
|
|
@ -17,7 +17,7 @@
|
|||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session.x;
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
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;
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session.x;
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
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.SessionIdManager;
|
||||
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.annotation.ManagedAttribute;
|
||||
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();
|
||||
sessionPath = (sessionPath==null||sessionPath.length()==0) ? "/" : sessionPath;
|
||||
String id = getNodeId(session);
|
||||
String id = getExtendedId(session);
|
||||
HttpCookie cookie = null;
|
||||
if (_sessionComment == null)
|
||||
{
|
||||
|
@ -596,7 +594,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public String getClusterId(HttpSession session)
|
||||
public String getId(HttpSession session)
|
||||
{
|
||||
Session s = ((SessionIf)session).getSession();
|
||||
return s.getId();
|
||||
|
@ -604,7 +602,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public String getNodeId(HttpSession session)
|
||||
public String getExtendedId(HttpSession session)
|
||||
{
|
||||
Session s = ((SessionIf)session).getSession();
|
||||
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.concurrent.TimeUnit;
|
||||
|
||||
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;
|
|
@ -17,7 +17,7 @@
|
|||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session.x;
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import java.util.Set;
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session.x;
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* StalePeriodStrategy
|
||||
|
@ -29,7 +29,7 @@ public class StalePeriodStrategy implements StalenessStrategy
|
|||
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
|
||||
public boolean isStale (Session session)
|
|
@ -17,7 +17,7 @@
|
|||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session.x;
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* StalenessStrategy
|
|
@ -17,7 +17,7 @@
|
|||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session.x;
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* UnreadableSessionData
|
|
@ -17,7 +17,7 @@
|
|||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session.x;
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
/**
|
||||
* 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.ContextHandler;
|
||||
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;
|
||||
|
||||
public class AbstractSessionManagerMBean extends AbstractHandlerMBean
|
||||
public class SessionManagerMBean extends AbstractHandlerMBean
|
||||
{
|
||||
public AbstractSessionManagerMBean(Object managedObject)
|
||||
public SessionManagerMBean(Object managedObject)
|
||||
{
|
||||
super(managedObject);
|
||||
}
|
||||
|
@ -34,9 +34,9 @@ public class AbstractSessionManagerMBean extends AbstractHandlerMBean
|
|||
/* ------------------------------------------------------------ */
|
||||
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;
|
||||
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.session.HashSessionIdManager;
|
||||
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.thread.Scheduler;
|
||||
import org.eclipse.jetty.util.thread.TimerScheduler;
|
||||
|
@ -835,11 +836,12 @@ public class ResponseTest
|
|||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
final HashSessionManager manager = new HashSessionManager();
|
||||
manager.setDeleteUnrestorableSessions(true);
|
||||
manager.setLazyLoad(true);
|
||||
manager.getSessionDataStore().setDeleteUnrestorableFiles(true);
|
||||
//manager.setLazyLoad(true);
|
||||
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
|
||||
testDir.mkdirs();
|
||||
manager.setStoreDirectory(testDir);
|
||||
manager.getSessionDataStore().setStoreDir(testDir);
|
||||
|
||||
MavenTestingUtils.getTargetFile("dangerFile.session").createNewFile();
|
||||
|
||||
|
@ -54,12 +54,12 @@ public class HashSessionManagerTest
|
|||
public void testValidSessionIdRemoval() throws Exception
|
||||
{
|
||||
final HashSessionManager manager = new HashSessionManager();
|
||||
manager.setDeleteUnrestorableSessions(true);
|
||||
manager.setLazyLoad(true);
|
||||
manager.getSessionDataStore().setDeleteUnrestorableFiles(true);
|
||||
// manager.setLazyLoad(true);
|
||||
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
|
||||
FS.ensureEmpty(testDir);
|
||||
|
||||
manager.setStoreDirectory(testDir);
|
||||
manager.getSessionDataStore().setStoreDir(testDir);
|
||||
|
||||
Assert.assertTrue(new File(testDir, "validFile.session").createNewFile());
|
||||
|
||||
|
@ -81,7 +81,7 @@ public class HashSessionManagerTest
|
|||
SessionHandler handler = new SessionHandler();
|
||||
handler.setServer(server);
|
||||
HashSessionManager manager = new HashSessionManager();
|
||||
manager.setStoreDirectory(testDir);
|
||||
manager.getSessionDataStore().setStoreDir(testDir);
|
||||
manager.setMaxInactiveInterval(5);
|
||||
Assert.assertTrue(testDir.exists());
|
||||
Assert.assertTrue(testDir.canWrite());
|
||||
|
@ -95,7 +95,7 @@ public class HashSessionManagerTest
|
|||
server.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();
|
||||
|
||||
session.setAttribute("one", new Integer(1));
|
||||
|
@ -107,10 +107,11 @@ public class HashSessionManagerTest
|
|||
|
||||
Assert.assertTrue("File should exist!", new File(testDir, session.getId()).exists());
|
||||
|
||||
//start will restore sessions
|
||||
|
||||
manager.start();
|
||||
|
||||
HashedSession restoredSession = (HashedSession)manager.getSession(sessionId);
|
||||
//restore session
|
||||
Session restoredSession = (Session)manager.getSession(sessionId);
|
||||
Assert.assertNotNull(restoredSession);
|
||||
|
||||
Object o = restoredSession.getAttribute("one");
|
||||
|
|
|
@ -37,102 +37,95 @@ import org.junit.Test;
|
|||
*/
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpSession#getAttributeNames()
|
||||
* @see org.eclipse.jetty.server.session.SessionStore#shutdown()
|
||||
*/
|
||||
@Override
|
||||
public Enumeration<String> getAttributeNames()
|
||||
{
|
||||
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()
|
||||
public void shutdown()
|
||||
{
|
||||
// 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
|
||||
public Object doPutOrRemove(String name, Object value)
|
||||
public Session newSession(SessionData data)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
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
|
||||
public Object doGet(String name)
|
||||
public Session doGet(SessionKey key)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
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
|
||||
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
|
||||
{
|
||||
|
||||
|
@ -145,24 +138,6 @@ public class SessionCookieTest
|
|||
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)
|
||||
*/
|
||||
|
@ -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
|
||||
protected void addSession(AbstractSession session)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
public void useId(String id)
|
||||
{
|
||||
// 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
|
||||
public void testSecureSessionCookie () throws Exception
|
||||
|
@ -245,7 +193,10 @@ public class SessionCookieTest
|
|||
idMgr.setWorkerName("node1");
|
||||
MockSessionManager mgr = new MockSessionManager();
|
||||
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.setSecure(true);
|
||||
|
|
Loading…
Reference in New Issue