405422 Implement servlet3.1 spec sections 4.4.3 and 8.1.4 for new HttpSessionIdListener class

This commit is contained in:
Jan Bartel 2013-05-03 18:27:51 +10:00
parent 0d181d9a75
commit f544d6e701
8 changed files with 73 additions and 6 deletions

View File

@ -23,6 +23,7 @@ import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionIdListener;
import javax.servlet.http.HttpSessionListener;
import org.eclipse.jetty.util.log.Log;
@ -78,7 +79,8 @@ public class WebListenerAnnotation extends DiscoveredAnnotation
ServletRequestListener.class.isAssignableFrom(clazz) ||
ServletRequestAttributeListener.class.isAssignableFrom(clazz) ||
HttpSessionListener.class.isAssignableFrom(clazz) ||
HttpSessionAttributeListener.class.isAssignableFrom(clazz))
HttpSessionAttributeListener.class.isAssignableFrom(clazz) ||
HttpSessionIdListener.class.isAssignableFrom(clazz))
{
java.util.EventListener listener = (java.util.EventListener)clazz.newInstance();
MetaData metaData = _context.getMetaData();

View File

@ -332,6 +332,7 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme
__log.warn(e);
}
}
super.renewSessionId(oldClusterId, oldNodeId, newClusterId, newNodeId);
}

View File

@ -51,8 +51,8 @@ public abstract class AbstractSession implements AbstractSessionManager.SessionI
{
final static Logger LOG = SessionHandler.LOG;
public final static String SESSION_KNOWN_ONLY_TO_AUTHENTICATED="org.eclipse.jetty.security.sessionKnownOnlytoAuthenticated";
private String _clusterId; // ID unique within cluster
private String _nodeId; // ID unique within node
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 final Map<String,Object> _attributes=new HashMap<String, Object>();
private boolean _idChanged;

View File

@ -38,6 +38,7 @@ import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionIdListener;
import javax.servlet.http.HttpSessionListener;
import org.eclipse.jetty.http.HttpCookie;
@ -107,6 +108,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
protected final List<HttpSessionAttributeListener> _sessionAttributeListeners = new CopyOnWriteArrayList<HttpSessionAttributeListener>();
protected final List<HttpSessionListener> _sessionListeners= new CopyOnWriteArrayList<HttpSessionListener>();
protected final List<HttpSessionIdListener> _sessionIdListeners = new CopyOnWriteArrayList<HttpSessionIdListener>();
protected ClassLoader _loader;
protected ContextHandler.Context _context;
@ -191,6 +193,8 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
_sessionAttributeListeners.add((HttpSessionAttributeListener)listener);
if (listener instanceof HttpSessionListener)
_sessionListeners.add((HttpSessionListener)listener);
if (listener instanceof HttpSessionIdListener)
_sessionIdListeners.add((HttpSessionIdListener)listener);
}
/* ------------------------------------------------------------ */
@ -198,6 +202,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
{
_sessionAttributeListeners.clear();
_sessionListeners.clear();
_sessionIdListeners.clear();
}
/* ------------------------------------------------------------ */
@ -990,6 +995,29 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement
{
_checkingRemoteSessionIdEncoding=remote;
}
/* ------------------------------------------------------------ */
/**
* Tell the HttpSessionIdListeners the id changed.
* NOTE: this method must be called LAST in subclass overrides, after the session has been updated
* with the new id.
* @see org.eclipse.jetty.server.SessionManager#renewSessionId(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
{
if (!_sessionIdListeners.isEmpty())
{
AbstractSession session = getSession(newClusterId);
HttpSessionEvent event = new HttpSessionEvent(session);
for (HttpSessionIdListener l:_sessionIdListeners)
{
l.sessionIdChanged(event, oldClusterId);
}
}
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */

View File

@ -439,6 +439,8 @@ public class HashSessionManager extends AbstractSessionManager
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)
{

View File

@ -645,6 +645,8 @@ public class JDBCSessionManager extends AbstractSessionManager
LOG.warn(e);
}
}
super.renewSessionId(oldClusterId, oldNodeId, newClusterId, newNodeId);
}

View File

@ -41,6 +41,7 @@ import javax.servlet.ServletSecurityElement;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionIdListener;
import javax.servlet.http.HttpSessionListener;
import org.eclipse.jetty.security.ConstraintAware;
@ -1058,7 +1059,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
if ((listener instanceof HttpSessionActivationListener)
|| (listener instanceof HttpSessionAttributeListener)
|| (listener instanceof HttpSessionBindingListener)
|| (listener instanceof HttpSessionListener))
|| (listener instanceof HttpSessionListener)
|| (listener instanceof HttpSessionIdListener))
{
if (_sessionHandler!=null)
_sessionHandler.addEventListener(listener);
@ -1072,7 +1074,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
if ((listener instanceof HttpSessionActivationListener)
|| (listener instanceof HttpSessionAttributeListener)
|| (listener instanceof HttpSessionBindingListener)
|| (listener instanceof HttpSessionListener))
|| (listener instanceof HttpSessionListener)
|| (listener instanceof HttpSessionIdListener))
{
if (_sessionHandler!=null)
_sessionHandler.removeEventListener(listener);

View File

@ -32,11 +32,14 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionIdListener;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.webapp.WebAppContext;
public abstract class AbstractSessionRenewTest
@ -49,8 +52,11 @@ public abstract class AbstractSessionRenewTest
String servletMapping = "/server";
int scavengePeriod = 3;
AbstractTestServer server = createServer(0, 1, scavengePeriod);
ServletContextHandler context = server.addContext(contextPath);
WebAppContext context = server.addWebAppContext(".", contextPath);
context.addServlet(TestServlet.class, servletMapping);
TestHttpSessionIdListener testListener = new TestHttpSessionIdListener();
context.addEventListener(testListener);
HttpClient client = new HttpClient();
@ -67,6 +73,7 @@ public abstract class AbstractSessionRenewTest
String sessionCookie = response.getHeaders().getStringField("Set-Cookie");
assertTrue(sessionCookie != null);
assertFalse(testListener.isCalled());
//make a request to change the sessionid
Request request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=renew");
@ -76,6 +83,7 @@ public abstract class AbstractSessionRenewTest
String renewSessionCookie = renewResponse.getHeaders().getStringField("Set-Cookie");
assertNotNull(renewSessionCookie);
assertNotSame(sessionCookie, renewSessionCookie);
assertTrue(testListener.isCalled());
}
finally
{
@ -84,9 +92,30 @@ public abstract class AbstractSessionRenewTest
}
}
public static class TestHttpSessionIdListener implements HttpSessionIdListener
{
boolean called = false;
@Override
public void sessionIdChanged(HttpSessionEvent event, String oldSessionId)
{
assertNotNull(event.getSession());
assertNotSame(oldSessionId, event.getSession().getId());
called = true;
}
public boolean isCalled()
{
return called;
}
}
public static class TestServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{