diff options
author | Jan Bartel | 2013-05-03 08:27:51 +0000 |
---|---|---|
committer | Jan Bartel | 2013-05-03 08:27:51 +0000 |
commit | f544d6e7010753a0b23f6aa923b81d8962358807 (patch) | |
tree | 6f749554bb3cb8dd1c700080c74b15cc43bbf8b3 | |
parent | 0d181d9a75e50a7a0ae332703f9e3547f5f64b57 (diff) | |
download | org.eclipse.jetty.project-f544d6e7010753a0b23f6aa923b81d8962358807.tar.gz org.eclipse.jetty.project-f544d6e7010753a0b23f6aa923b81d8962358807.tar.xz org.eclipse.jetty.project-f544d6e7010753a0b23f6aa923b81d8962358807.zip |
405422 Implement servlet3.1 spec sections 4.4.3 and 8.1.4 for new HttpSessionIdListener class
8 files changed, 73 insertions, 6 deletions
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java index b82fd1104a..c55bca29c7 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java @@ -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(); diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java index e5f0e17fd5..48acc817da 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java @@ -332,6 +332,7 @@ public abstract class NoSqlSessionManager extends AbstractSessionManager impleme __log.warn(e); } } + super.renewSessionId(oldClusterId, oldNodeId, newClusterId, newNodeId); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java index 9830df24f2..9f013221e7 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java @@ -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; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java index a81453e22f..2ffddd354f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java @@ -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); + } + } + + } /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java index 1954894aaf..7acf6e98ac 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java @@ -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) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java index afe7ae2c0a..d1a2708f0e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java @@ -645,6 +645,8 @@ public class JDBCSessionManager extends AbstractSessionManager LOG.warn(e); } } + + super.renewSessionId(oldClusterId, oldNodeId, newClusterId, newNodeId); } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java index 2489138e49..650c6a0873 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java @@ -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); diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java index 070ddf1a5c..34cae2bddd 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java @@ -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 { |