diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java index 1c0bae8ec70..8e5791af051 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java @@ -450,6 +450,7 @@ public class MongoSessionIdManager extends AbstractSessionIdManager /** * is the session id known to mongo, and is it valid */ + @Override public boolean idInUse(String sessionId) { /* @@ -473,6 +474,7 @@ public class MongoSessionIdManager extends AbstractSessionIdManager } /* ------------------------------------------------------------ */ + @Override public void addSession(HttpSession session) { if (session == null) @@ -494,6 +496,7 @@ public class MongoSessionIdManager extends AbstractSessionIdManager } /* ------------------------------------------------------------ */ + @Override public void removeSession(HttpSession session) { if (session == null) @@ -508,6 +511,7 @@ public class MongoSessionIdManager extends AbstractSessionIdManager } /* ------------------------------------------------------------ */ + @Override public void invalidateAll(String sessionId) { synchronized (_sessionsIds) @@ -520,7 +524,7 @@ public class MongoSessionIdManager extends AbstractSessionIdManager Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class); for (int i=0; contexts!=null && i0)?nodeId.substring(0,dot):nodeId; - } - - /* ------------------------------------------------------------ */ - // TODO not sure if this is correct - public String getNodeId(String clusterId, HttpServletRequest request) - { - if (_workerName!=null) - return clusterId+'.'+_workerName; - - return clusterId; - } - + } /* ------------------------------------------------------------ */ @Override @@ -563,6 +548,24 @@ public class MongoSessionIdManager extends AbstractSessionIdManager synchronized (_sessionsIds) { _sessionsIds.remove(oldClusterId);//remove the old one from the list + + /* ------------------------------------------------------------ */ + // TODO not sure if this is correct + public String getClusterId(String nodeId) + { + int dot=nodeId.lastIndexOf('.'); + return (dot>0)?nodeId.substring(0,dot):nodeId; + } + + /* ------------------------------------------------------------ */ + // TODO not sure if this is correct + public String getNodeId(String clusterId, HttpServletRequest request) + { + if (_workerName!=null) + return clusterId+'.'+_workerName; + + return clusterId; + } _sessionsIds.add(newClusterId); //add in the new session id to the list //tell all contexts to update the id diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java index 6c3cc5c558e..ee3c4c64f85 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java @@ -35,6 +35,7 @@ import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.session.AbstractSessionIdManager; import org.eclipse.jetty.server.session.HashSessionIdManager; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; @@ -99,7 +100,7 @@ public class BalancerServletTest if (nodeName != null) { - HashSessionIdManager sessionIdManager = new HashSessionIdManager(); + AbstractSessionIdManager sessionIdManager = new HashSessionIdManager(); sessionIdManager.setWorkerName(nodeName); server.setSessionIdManager(sessionIdManager); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java index e3df34f98cd..3ddc0bd5ddf 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java @@ -37,6 +37,7 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme protected Random _random; protected boolean _weakRandom; protected String _workerName; + protected String _workerAttr; protected long _reseed=100000L; /* ------------------------------------------------------------ */ @@ -58,6 +59,7 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme * * @return String or null */ + @Override public String getWorkerName() { return _workerName; @@ -67,11 +69,16 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme /** * Set 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. + * 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 + * customiser. * * @param workerName */ public void setWorkerName(String workerName) { + if (isRunning()) + throw new IllegalStateException(getState()); if (workerName.contains(".")) throw new IllegalArgumentException("Name cannot contain '.'"); _workerName=workerName; @@ -114,27 +121,28 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme * * @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) - { - // 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=getClusterId(requested_id); - if (idInUse(cluster_id)) - return cluster_id; - } + if (request==null) + return newSessionId(created); - // Else reuse any new session ID already defined for this request. - String new_id=(String)request.getAttribute(__NEW_SESSION_ID); - if (new_id!=null&&idInUse(new_id)) - return new_id; + // 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=getClusterId(requested_id); + if (idInUse(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&&idInUse(new_id)) + return new_id; + // pick a new unique ID! String id = newSessionId(request.hashCode()); @@ -190,15 +198,16 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme /* ------------------------------------------------------------ */ + @Override public abstract void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request); - /* ------------------------------------------------------------ */ @Override protected void doStart() throws Exception { initRandom(); + _workerAttr=(_workerName!=null && _workerName.startsWith("$"))?_workerName.substring(1):null; } /* ------------------------------------------------------------ */ @@ -232,5 +241,39 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme _random.setSeed(_random.nextLong()^System.currentTimeMillis()^hashCode()^Runtime.getRuntime().freeMemory()); } + /** Get the session ID with any worker ID. + * + * @param clusterId + * @param request + * @return sessionId plus any worker ID. + */ + @Override + public String getNodeId(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 nodeId the node id + * @return sessionId without any worker ID. + */ + @Override + public String getClusterId(String nodeId) + { + int dot=nodeId.lastIndexOf('.'); + return (dot>0)?nodeId.substring(0,dot):nodeId; + } + } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java index 218fe3ddefb..0ebd29b3cd8 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java @@ -81,38 +81,7 @@ public class HashSessionIdManager extends AbstractSessionIdManager } return sessions; } - /* ------------------------------------------------------------ */ - /** Get the session ID with any worker ID. - * - * @param clusterId - * @param request - * @return sessionId plus any worker ID. - */ - public String getNodeId(String clusterId,HttpServletRequest request) - { - // used in Ajp13Parser - String worker=request==null?null:(String)request.getAttribute("org.eclipse.jetty.ajp.JVMRoute"); - if (worker!=null) - return clusterId+'.'+worker; - - if (_workerName!=null) - return clusterId+'.'+_workerName; - - return clusterId; - } - - /* ------------------------------------------------------------ */ - /** Get the session ID without any worker ID. - * - * @param nodeId the node id - * @return sessionId without any worker ID. - */ - public String getClusterId(String nodeId) - { - int dot=nodeId.lastIndexOf('.'); - return (dot>0)?nodeId.substring(0,dot):nodeId; - } - + /* ------------------------------------------------------------ */ @Override protected void doStart() throws Exception @@ -132,6 +101,7 @@ public class HashSessionIdManager extends AbstractSessionIdManager /** * @see SessionIdManager#idInUse(String) */ + @Override public boolean idInUse(String id) { synchronized (this) @@ -144,6 +114,7 @@ public class HashSessionIdManager extends AbstractSessionIdManager /** * @see SessionIdManager#addSession(HttpSession) */ + @Override public void addSession(HttpSession session) { String id = getClusterId(session.getId()); @@ -165,6 +136,7 @@ public class HashSessionIdManager extends AbstractSessionIdManager /** * @see SessionIdManager#removeSession(HttpSession) */ + @Override public void removeSession(HttpSession session) { String id = getClusterId(session.getId()); @@ -199,6 +171,7 @@ public class HashSessionIdManager extends AbstractSessionIdManager /** * @see SessionIdManager#invalidateAll(String) */ + @Override public void invalidateAll(String id) { Collection> sessions; @@ -221,6 +194,7 @@ public class HashSessionIdManager extends AbstractSessionIdManager /* ------------------------------------------------------------ */ + @Override public void renewSessionId (String oldClusterId, String oldNodeId, HttpServletRequest request) { //generate a new id diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java index 15deaefb557..6590e2420e2 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java @@ -29,11 +29,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import java.util.ArrayList; -import java.util.Collection; import java.util.HashSet; -import java.util.Iterator; -import java.util.List; import java.util.Locale; import java.util.Random; import java.util.Set; @@ -380,6 +376,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager } + @Override public void addSession(HttpSession session) { if (session == null) @@ -422,6 +419,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager + @Override public void removeSession(HttpSession session) { if (session == null) @@ -456,32 +454,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager } - /** - * Get the session id without any node identifier suffix. - * - * @see org.eclipse.jetty.server.SessionIdManager#getClusterId(java.lang.String) - */ - public String getClusterId(String nodeId) - { - int dot=nodeId.lastIndexOf('.'); - return (dot>0)?nodeId.substring(0,dot):nodeId; - } - - - /** - * Get the session id, including this node's id as a suffix. - * - * @see org.eclipse.jetty.server.SessionIdManager#getNodeId(java.lang.String, javax.servlet.http.HttpServletRequest) - */ - public String getNodeId(String clusterId, HttpServletRequest request) - { - if (_workerName!=null) - return clusterId+'.'+_workerName; - - return clusterId; - } - - + @Override public boolean idInUse(String id) { if (id == null) @@ -515,6 +488,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager * * @see org.eclipse.jetty.server.SessionIdManager#invalidateAll(java.lang.String) */ + @Override public void invalidateAll(String id) { //take the id out of the list of known sessionids for this node @@ -527,7 +501,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class); for (int i=0; contexts!=null && i0)?nodeId.substring(0,dot):nodeId; - } - - /** - * @see org.eclipse.jetty.server.SessionIdManager#getNodeId(java.lang.String, javax.servlet.http.HttpServletRequest) - */ - public String getNodeId(String clusterId, HttpServletRequest request) - { - return clusterId+'.'+_workerName; - } - @Override public void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request) { @@ -119,6 +106,7 @@ public class SessionCookieTest /** * @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSession) */ + @Override protected void addSession(AbstractSession session) { @@ -127,6 +115,7 @@ public class SessionCookieTest /** * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSession(java.lang.String) */ + @Override public AbstractSession getSession(String idInCluster) { return null; @@ -135,6 +124,7 @@ public class SessionCookieTest /** * @see org.eclipse.jetty.server.session.AbstractSessionManager#invalidateSessions() */ + @Override protected void invalidateSessions() throws Exception { @@ -143,6 +133,7 @@ public class SessionCookieTest /** * @see org.eclipse.jetty.server.session.AbstractSessionManager#newSession(javax.servlet.http.HttpServletRequest) */ + @Override protected AbstractSession newSession(HttpServletRequest request) { return null; @@ -151,6 +142,7 @@ public class SessionCookieTest /** * @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String) */ + @Override protected boolean removeSession(String idInCluster) { return false;