diff options
Diffstat (limited to 'jetty-server/src')
13 files changed, 1038 insertions, 974 deletions
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index 5706735437..14dae0b1d1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -1123,31 +1123,25 @@ public class Request implements HttpServletRequest * @see javax.servlet.http.HttpServletRequest#getSession(boolean) */ public HttpSession getSession(boolean create) - { - if (_sessionManager==null && create) - throw new IllegalStateException("No SessionManager"); - - if (_session != null && _sessionManager!=null && _sessionManager.isValid(_session)) - return _session; - - _session=null; - - String id=getRequestedSessionId(); - - if (id != null && _sessionManager!=null) + { + if (_session != null ) { - _session=_sessionManager.getHttpSession(id); - if (_session == null && !create) - return null; + if (_sessionManager!=null && !_sessionManager.isValid(_session)) + _session=null; + else + return _session; } - if (_session == null && _sessionManager!=null && create ) - { - _session=_sessionManager.newHttpSession(this); - HttpCookie cookie=_sessionManager.getSessionCookie(_session,getContextPath(),isSecure()); - if (cookie!=null) - _connection.getResponse().addCookie(cookie); - } + if (!create) + return null; + + if (_sessionManager==null) + throw new IllegalStateException("No SessionManager"); + + _session=_sessionManager.newHttpSession(this); + HttpCookie cookie=_sessionManager.getSessionCookie(_session,getContextPath(),isSecure()); + if (cookie!=null) + _connection.getResponse().addCookie(cookie); return _session; } @@ -1307,7 +1301,7 @@ public class Request implements HttpServletRequest return false; HttpSession session=getSession(false); - return (session != null && _sessionManager.getIdManager().getClusterId(_requestedSessionId).equals(_sessionManager.getClusterId(session))); + return (session != null && _sessionManager.getSessionIdManager().getClusterId(_requestedSessionId).equals(_sessionManager.getClusterId(session))); } /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java index c5c9c68e67..c675b1432a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java @@ -185,18 +185,26 @@ public interface SessionManager extends LifeCycle /* ------------------------------------------------------------ */ /** * @return the cross context session id manager. - * @see #setIdManager(SessionIdManager) + * @see #setSessionIdManager(SessionIdManager) */ - public SessionIdManager getIdManager(); + public SessionIdManager getSessionIdManager(); + + /* ------------------------------------------------------------ */ + /** + * @return the cross context session id manager. + * @deprecated use {@link #getSessionIdManager()} + */ + @Deprecated + public SessionIdManager getMetaManager(); /* ------------------------------------------------------------ */ /** * Sets the cross context session id manager * * @param idManager the cross context session id manager. - * @see #getIdManager() + * @see #getSessionIdManager() */ - public void setIdManager(SessionIdManager idManager); + public void setSessionIdManager(SessionIdManager idManager); /* ------------------------------------------------------------ */ /** 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 new file mode 100644 index 0000000000..e1815df32b --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java @@ -0,0 +1,525 @@ +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.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.util.log.Log; +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; + + private final AbstractSessionManager _manager; + private final String _clusterId; // ID unique within cluster + private final String _nodeId; // ID unique within node + private final Map<String,Object> _attributes=new HashMap<String, Object>(); + 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; + + // TODO remove this. + protected final Map<String,Object> _jdbcAttributes=_attributes; + + /* ------------------------------------------------------------- */ + protected AbstractSession(AbstractSessionManager abstractSessionManager, HttpServletRequest request) + { + _manager = abstractSessionManager; + + _newSession=true; + _created=System.currentTimeMillis(); + _clusterId=_manager._sessionIdManager.newSessionId(request,_created); + _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,request); + _accessed=_created; + _lastAccessed=_created; + _requests=1; + _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000:-1; + __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.getNodeId(_clusterId,null); + _accessed=accessed; + _lastAccessed=accessed; + _requests=1; + __log.debug("new session "+_nodeId+" "+_clusterId); + } + + /* ------------------------------------------------------------- */ + /** + * @return True is the session is invalid or passivated. + */ + protected void checkValid() throws IllegalStateException + { + if (_invalid) + throw new IllegalStateException(); + } + + /* ------------------------------------------------------------- */ + public AbstractSession getSession() + { + return this; + } + + /* ------------------------------------------------------------- */ + public long getAccessed() + { + synchronized (this) + { + return _accessed; + } + } + + /* ------------------------------------------------------------ */ + public Object getAttribute(String name) + { + synchronized (this) + { + checkValid(); + return _attributes.get(name); + } + } + + /* ------------------------------------------------------------ */ + public int getAttributes() + { + synchronized (this) + { + checkValid(); + return _attributes.size(); + } + } + + /* ------------------------------------------------------------ */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Enumeration getAttributeNames() + { + synchronized (this) + { + checkValid(); + List names=_attributes==null?Collections.EMPTY_LIST:new ArrayList(_attributes.keySet()); + return Collections.enumeration(names); + } + } + + /* ------------------------------------------------------------ */ + public Set<String> getNames() + { + synchronized (this) + { + return new HashSet<String>(_attributes.keySet()); + } + } + + /* ------------------------------------------------------------- */ + public long getCookieSetTime() + { + return _cookieSet; + } + + /* ------------------------------------------------------------- */ + public long getCreationTime() throws IllegalStateException + { + return _created; + } + + /* ------------------------------------------------------------ */ + public String getId() throws IllegalStateException + { + return _manager._nodeIdInSessionId?_nodeId:_clusterId; + } + + /* ------------------------------------------------------------- */ + public String getNodeId() + { + return _nodeId; + } + + /* ------------------------------------------------------------- */ + public String getClusterId() + { + return _clusterId; + } + + /* ------------------------------------------------------------- */ + public long getLastAccessedTime() throws IllegalStateException + { + checkValid(); + return _lastAccessed; + } + + /* ------------------------------------------------------------- */ + public int getMaxInactiveInterval() + { + checkValid(); + return (int)(_maxIdleMs/1000); + } + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpSession#getServletContext() + */ + public ServletContext getServletContext() + { + return _manager._context; + } + + /* ------------------------------------------------------------- */ + @Deprecated + public HttpSessionContext getSessionContext() throws IllegalStateException + { + checkValid(); + return AbstractSessionManager.__nullSessionContext; + } + + /* ------------------------------------------------------------- */ + /** + * @deprecated As of Version 2.2, this method is replaced by + * {@link #getAttribute} + */ + @Deprecated + public Object getValue(String name) throws IllegalStateException + { + return getAttribute(name); + } + + /* ------------------------------------------------------------- */ + /** + * @deprecated As of Version 2.2, this method is replaced by + * {@link #getAttributeNames} + */ + @Deprecated + public String[] getValueNames() throws IllegalStateException + { + synchronized(this) + { + checkValid(); + if (_attributes==null) + return new String[0]; + String[] a=new String[_attributes.size()]; + return (String[])_attributes.keySet().toArray(a); + } + } + + /* ------------------------------------------------------------ */ + protected boolean access(long time) + { + synchronized(this) + { + if (_invalid) + return false; + _newSession=false; + _lastAccessed=_accessed; + _accessed=time; + + if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < 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 + synchronized (this) + { + if (!_invalid) + { + if (_requests<=0) + doInvalidate(); + else + _doInvalidate=true; + } + } + } + + /* ------------------------------------------------------------- */ + public void invalidate() throws IllegalStateException + { + // remove session from context and invalidate other sessions with same ID. + _manager.removeSession(this,true); + doInvalidate(); + } + + /* ------------------------------------------------------------- */ + protected void doInvalidate() throws IllegalStateException + { + try + { + __log.debug("invalidate ",_clusterId); + if (isValid()) + clearAttributes(); + } + finally + { + synchronized (this) + { + // mark as invalid + _invalid=true; + } + } + } + + /* ------------------------------------------------------------- */ + 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); + + _manager.doSessionAttributeListeners(this,key,value,null); + } + } + if (_attributes!=null) + _attributes.clear(); + } + + /* ------------------------------------------------------------- */ + public boolean isIdChanged() + { + return _idChanged; + } + + /* ------------------------------------------------------------- */ + public boolean isNew() throws IllegalStateException + { + checkValid(); + return _newSession; + } + + /* ------------------------------------------------------------- */ + /** + * @deprecated As of Version 2.2, this method is replaced by + * {@link #setAttribute} + */ + @Deprecated + public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException + { + setAttribute(name,value); + } + + /* ------------------------------------------------------------ */ + public void removeAttribute(String name) + { + setAttribute(name,null); + } + + /* ------------------------------------------------------------- */ + /** + * @deprecated As of Version 2.2, this method is replaced by + * {@link #removeAttribute} + */ + @Deprecated + public void removeValue(java.lang.String name) throws IllegalStateException + { + removeAttribute(name); + } + + /* ------------------------------------------------------------ */ + protected Object doPutOrRemove(String name, Object value) + { + return value==null?_attributes.remove(name):_attributes.put(name,value); + } + + /* ------------------------------------------------------------ */ + protected Object doGet(String name) + { + return _attributes.get(name); + } + + /* ------------------------------------------------------------ */ + public void setAttribute(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); + + } + } + + /* ------------------------------------------------------------- */ + public void setIdChanged(boolean changed) + { + _idChanged=changed; + } + + /* ------------------------------------------------------------- */ + public void setMaxInactiveInterval(int secs) + { + _maxIdleMs=(long)secs*1000; + } + + /* ------------------------------------------------------------- */ + @Override + public String toString() + { + return this.getClass().getName()+":"+getId()+"@"+hashCode(); + } + + /* ------------------------------------------------------------- */ + /** If value implements HttpSessionBindingListener, call valueBound() */ + 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() + { + _cookieSet=_accessed; + } + + /* ------------------------------------------------------------ */ + public int getRequests() + { + synchronized (this) + { + return _requests; + } + } + + /* ------------------------------------------------------------ */ + public void setRequests(int requests) + { + synchronized (this) + { + _requests=requests; + } + } + + /* ------------------------------------------------------------- */ + /** If value implements HttpSessionBindingListener, call valueUnbound() */ + 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 iter = _attributes.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 iter = _attributes.values().iterator(); iter.hasNext();) + { + Object value = iter.next(); + if (value instanceof HttpSessionActivationListener) + { + HttpSessionActivationListener listener = (HttpSessionActivationListener) value; + listener.sessionDidActivate(event); + } + } + } + } + + +}
\ No newline at end of file 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 60642a2f42..dc929eed3e 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 @@ -15,6 +15,7 @@ package org.eclipse.jetty.server.session; import static java.lang.Math.round; + import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; @@ -31,12 +32,14 @@ import java.util.Set; import javax.servlet.ServletContext; import javax.servlet.SessionCookieConfig; import javax.servlet.SessionTrackingMode; +import java.util.concurrent.CopyOnWriteArrayList; + +import javax.servlet.ServletRequest; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionActivationListener; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; import javax.servlet.http.HttpSessionContext; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; @@ -48,9 +51,8 @@ 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.LazyList; import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.statistic.CounterStatistic; import org.eclipse.jetty.util.statistic.SampleStatistic; @@ -63,10 +65,12 @@ import org.eclipse.jetty.util.statistic.SampleStatistic; * a specialised version of the Session inner class that provides an attribute * Map. * <p> - * */ +@SuppressWarnings("deprecation") public abstract class AbstractSessionManager extends AbstractLifeCycle implements SessionManager { + final static Logger __log = SessionHandler.__log; + public Set<SessionTrackingMode> __defaultSessionTrackingModes = Collections.unmodifiableSet( new HashSet<SessionTrackingMode>( @@ -75,7 +79,21 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement /* ------------------------------------------------------------ */ public final static int __distantFuture=60*60*24*7*52*20; - private static final HttpSessionContext __nullSessionContext=new NullSessionContext(); + static final HttpSessionContext __nullSessionContext=new HttpSessionContext() + { + public HttpSession getSession(String sessionId) + { + return null; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Enumeration getIds() + { + return Collections.enumeration(Collections.EMPTY_LIST); + } + }; + + private boolean _usingCookies=true; /* ------------------------------------------------------------ */ // Setting of max inactive interval for new sessions @@ -85,8 +103,8 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement protected boolean _httpOnly=false; protected SessionIdManager _sessionIdManager; protected boolean _secureCookies=false; - protected Object _sessionAttributeListeners; - protected Object _sessionListeners; + protected final List<HttpSessionAttributeListener> _sessionAttributeListeners = new CopyOnWriteArrayList<HttpSessionAttributeListener>(); + protected final List<HttpSessionListener> _sessionListeners= new CopyOnWriteArrayList<HttpSessionListener>(); protected ClassLoader _loader; protected ContextHandler.Context _context; @@ -103,7 +121,6 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement public Set<SessionTrackingMode> _sessionTrackingModes; - private boolean _usingCookies; private boolean _usingURLs; protected final CounterStatistic _sessionsStats = new CounterStatistic(); @@ -116,26 +133,39 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement } /* ------------------------------------------------------------ */ + public ContextHandler.Context getContext() + { + return _context; + } + + /* ------------------------------------------------------------ */ + public ContextHandler getContextHandler() + { + return _context.getContextHandler(); + } + + /* ------------------------------------------------------------ */ public HttpCookie access(HttpSession session,boolean secure) { long now=System.currentTimeMillis(); - Session s = ((SessionIf)session).getSession(); - s.access(now); + AbstractSession s = ((SessionIf)session).getSession(); - // Do we need to refresh the cookie? - if (isUsingCookies() && - (s.isIdChanged() || - (getSessionCookieConfig().getMaxAge()>0 && getRefreshCookieAge()>0 && ((now-s.getCookieSetTime())/1000>getRefreshCookieAge())) - ) - ) - { - HttpCookie cookie=getSessionCookie(session,_context==null?"/":(_context.getContextPath()),secure); - s.cookieSet(); - s.setIdChanged(false); - return cookie; + if (s.access(now)) + { + // Do we need to refresh the cookie? + if (isUsingCookies() && + (s.isIdChanged() || + (getSessionCookieConfig().getMaxAge()>0 && getRefreshCookieAge()>0 && ((now-s.getCookieSetTime())/1000>getRefreshCookieAge())) + ) + ) + { + HttpCookie cookie=getSessionCookie(session,_context==null?"/":(_context.getContextPath()),secure); + s.cookieSet(); + s.setIdChanged(false); + return cookie; + } } - return null; } @@ -143,22 +173,22 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement public void addEventListener(EventListener listener) { if (listener instanceof HttpSessionAttributeListener) - _sessionAttributeListeners=LazyList.add(_sessionAttributeListeners,listener); + _sessionAttributeListeners.add((HttpSessionAttributeListener)listener); if (listener instanceof HttpSessionListener) - _sessionListeners=LazyList.add(_sessionListeners,listener); + _sessionListeners.add((HttpSessionListener)listener); } /* ------------------------------------------------------------ */ public void clearEventListeners() { - _sessionAttributeListeners=null; - _sessionListeners=null; + _sessionAttributeListeners.clear(); + _sessionListeners.clear(); } /* ------------------------------------------------------------ */ public void complete(HttpSession session) { - Session s = ((SessionIf)session).getSession(); + AbstractSession s = ((SessionIf)session).getSession(); s.complete(); } @@ -243,9 +273,9 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement /* ------------------------------------------------------------ */ public HttpSession getHttpSession(String nodeId) { - String cluster_id = getIdManager().getClusterId(nodeId); + String cluster_id = getSessionIdManager().getClusterId(nodeId); - Session session = getSession(cluster_id); + AbstractSession session = getSession(cluster_id); if (session!=null && !session.getNodeId().equals(nodeId)) session.setIdChanged(true); return session; @@ -254,9 +284,19 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement /* ------------------------------------------------------------ */ /** * @return Returns the metaManager used for cross context session management + * @deprecated Use {@link #getSessionIdManager()} */ public SessionIdManager getIdManager() { + return getSessionIdManager(); + } + + /* ------------------------------------------------------------ */ + /** + * @return Returns the SessionIdManager used for cross context session management + */ + public SessionIdManager getSessionIdManager() + { return _sessionIdManager; } @@ -300,12 +340,12 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement /* ------------------------------------------------------------ */ /** - * @deprecated use {@link #getIdManager()} + * @deprecated use {@link #getSessionIdManager()} */ @Deprecated public SessionIdManager getMetaManager() { - return getIdManager(); + return getSessionIdManager(); } /* ------------------------------------------------------------ */ @@ -376,7 +416,11 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement /** * @deprecated Need to review if it is needed. */ - public abstract Map getSessionMap(); + @SuppressWarnings("rawtypes") + public Map getSessionMap() + { + throw new UnsupportedOperationException(); + } /* ------------------------------------------------------------ */ public int getSessions() @@ -399,21 +443,21 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement /* ------------------------------------------------------------ */ public boolean isValid(HttpSession session) { - Session s = ((SessionIf)session).getSession(); + AbstractSession s = ((SessionIf)session).getSession(); return s.isValid(); } /* ------------------------------------------------------------ */ public String getClusterId(HttpSession session) { - Session s = ((SessionIf)session).getSession(); + AbstractSession s = ((SessionIf)session).getSession(); return s.getClusterId(); } /* ------------------------------------------------------------ */ public String getNodeId(HttpSession session) { - Session s = ((SessionIf)session).getSession(); + AbstractSession s = ((SessionIf)session).getSession(); return s.getNodeId(); } @@ -423,7 +467,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement */ public HttpSession newHttpSession(HttpServletRequest request) { - Session session=newSession(request); + AbstractSession session=newSession(request); session.setMaxInactiveInterval(_dftMaxIdleSecs); addSession(session,true); return session; @@ -433,9 +477,9 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement public void removeEventListener(EventListener listener) { if (listener instanceof HttpSessionAttributeListener) - _sessionAttributeListeners=LazyList.remove(_sessionAttributeListeners,listener); + _sessionAttributeListeners.remove(listener); if (listener instanceof HttpSessionListener) - _sessionListeners=LazyList.remove(_sessionListeners,listener); + _sessionListeners.remove(listener); } /* ------------------------------------------------------------ */ @@ -468,13 +512,22 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement _httpOnly=httpOnly; } - /* ------------------------------------------------------------ */ /** * @param metaManager The metaManager used for cross context session management. + * @deprecated use {@link #setSessionIdManager(SessionIdManager)} */ public void setIdManager(SessionIdManager metaManager) { + setSessionIdManager(metaManager); + } + + /* ------------------------------------------------------------ */ + /** + * @param metaManager The metaManager used for cross context session management. + */ + public void setSessionIdManager(SessionIdManager metaManager) + { _sessionIdManager=metaManager; } @@ -487,6 +540,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement _dftMaxIdleSecs=seconds; } + /* ------------------------------------------------------------ */ public void setRefreshCookieAge(int ageInSeconds) { @@ -548,14 +602,14 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement _sessionIdPathParameterNamePrefix =(param==null||"none".equals(param))?null:(";"+ _sessionIdPathParameterName +"="); } - protected abstract void addSession(Session session); + protected abstract void addSession(AbstractSession session); /* ------------------------------------------------------------ */ /** * Add the session Registers the session with this manager and registers the * session ID with the sessionIDManager; */ - protected void addSession(Session session, boolean created) + protected void addSession(AbstractSession session, boolean created) { synchronized (_sessionIdManager) { @@ -569,8 +623,8 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement if (_sessionListeners!=null) { HttpSessionEvent event=new HttpSessionEvent(session); - for (int i=0; i<LazyList.size(_sessionListeners); i++) - ((HttpSessionListener)LazyList.get(_sessionListeners,i)).sessionCreated(event); + for (HttpSessionListener listener : _sessionListeners) + listener.sessionCreated(event); } } } @@ -581,7 +635,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement * @param idInCluster The session ID in the cluster, stripped of any worker name. * @return A Session or null if none exists. */ - public abstract Session getSession(String idInCluster); + public abstract AbstractSession getSession(String idInCluster); protected abstract void invalidateSessions() throws Exception; @@ -592,7 +646,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement * @param request * @return the new session */ - protected abstract Session newSession(HttpServletRequest request); + protected abstract AbstractSession newSession(HttpServletRequest request); /* ------------------------------------------------------------ */ @@ -621,7 +675,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement */ public void removeSession(HttpSession session, boolean invalidate) { - Session s = ((SessionIf)session).getSession(); + AbstractSession s = ((SessionIf)session).getSession(); removeSession(s,invalidate); } @@ -631,7 +685,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and * {@link SessionIdManager#invalidateAll(String)} should be called. */ - public void removeSession(Session session, boolean invalidate) + public void removeSession(AbstractSession session, boolean invalidate) { // Remove session from context and global maps boolean removed = removeSession(session.getClusterId()); @@ -649,8 +703,8 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement if (invalidate && _sessionListeners!=null) { HttpSessionEvent event=new HttpSessionEvent(session); - for (int i=LazyList.size(_sessionListeners); i-->0;) - ((HttpSessionListener)LazyList.get(_sessionListeners,i)).sessionDestroyed(event); + for (HttpSessionListener listener : _sessionListeners) + listener.sessionCreated(event); } } } @@ -844,41 +898,7 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement { _checkingRemoteSessionIdEncoding=remote; } - - /* ------------------------------------------------------------ */ - /** - * Null returning implementation of HttpSessionContext - * - * - */ - public static class NullSessionContext implements HttpSessionContext - { - /* ------------------------------------------------------------ */ - private NullSessionContext() - { - } - - /* ------------------------------------------------------------ */ - /** - * @deprecated From HttpSessionContext - */ - @Deprecated - public Enumeration getIds() - { - return Collections.enumeration(Collections.EMPTY_LIST); - } - - /* ------------------------------------------------------------ */ - /** - * @deprecated From HttpSessionContext - */ - @Deprecated - public HttpSession getSession(String id) - { - return null; - } - } - + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ @@ -889,496 +909,23 @@ public abstract class AbstractSessionManager extends AbstractLifeCycle implement */ public interface SessionIf extends HttpSession { - public Session getSession(); + public AbstractSession getSession(); } - /* ------------------------------------------------------------ */ - /** - * - * <p> - * Implements {@link javax.servlet.http.HttpSession} from the <code>javax.servlet</code> package. - * </p> - * - * - */ - public abstract class Session implements SessionIf, Serializable - { - protected final String _clusterId; // ID unique within cluster - protected final String _nodeId; // ID unique within node - protected final Map<String,Object> _attributes=new HashMap<String, Object>(); - protected boolean _idChanged; - protected final long _created; - protected long _cookieSet; - protected long _accessed; - protected long _lastAccessed; - protected boolean _invalid; - protected boolean _doInvalidate; - protected long _maxIdleMs=_dftMaxIdleSecs>0?_dftMaxIdleSecs*1000:-1; - protected boolean _newSession; - protected int _requests; - - /* ------------------------------------------------------------- */ - protected Session(HttpServletRequest request) - { - _newSession=true; - _created=System.currentTimeMillis(); - _clusterId=_sessionIdManager.newSessionId(request,_created); - _nodeId=_sessionIdManager.getNodeId(_clusterId,request); - _accessed=_created; - _lastAccessed=_created; - _requests=1; - Log.debug("new session & id "+_nodeId+" "+_clusterId); - } - - /* ------------------------------------------------------------- */ - protected Session(long created, long accessed, String clusterId) - { - _created=created; - _clusterId=clusterId; - _nodeId=_sessionIdManager.getNodeId(_clusterId,null); - _accessed=accessed; - _lastAccessed=accessed; - _requests=1; - Log.debug("new session "+_nodeId+" "+_clusterId); - } - - /* ------------------------------------------------------------- */ - /** - * @return True is the session is invalid or passivated. - */ - protected boolean isNotAvailable() - { - return _invalid; - } - - /* ------------------------------------------------------------- */ - public Session getSession() - { - return this; - } - - /* ------------------------------------------------------------ */ - public Object getAttribute(String name) - { - synchronized (Session.this) - { - if (isNotAvailable()) - throw new IllegalStateException(); - - return _attributes.get(name); - } - } - - /* ------------------------------------------------------------ */ - public Enumeration getAttributeNames() - { - synchronized (Session.this) - { - if (isNotAvailable()) - throw new IllegalStateException(); - List names=_attributes==null?Collections.EMPTY_LIST:new ArrayList(_attributes.keySet()); - return Collections.enumeration(names); - } - } - - /* ------------------------------------------------------------- */ - public long getCookieSetTime() - { - return _cookieSet; - } - - /* ------------------------------------------------------------- */ - public long getCreationTime() throws IllegalStateException - { - if (isNotAvailable()) - throw new IllegalStateException(); - return _created; - } - - /* ------------------------------------------------------------ */ - public String getId() throws IllegalStateException - { - return _nodeIdInSessionId?_nodeId:_clusterId; - } - - /* ------------------------------------------------------------- */ - protected String getNodeId() - { - return _nodeId; - } - - /* ------------------------------------------------------------- */ - protected String getClusterId() - { - return _clusterId; - } - - /* ------------------------------------------------------------- */ - public long getLastAccessedTime() throws IllegalStateException - { - if (isNotAvailable()) - throw new IllegalStateException(); - return _lastAccessed; - } - - /* ------------------------------------------------------------- */ - public int getMaxInactiveInterval() - { - if (isNotAvailable()) - throw new IllegalStateException(); - return (int)(_maxIdleMs/1000); - } - - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpSession#getServletContext() - */ - public ServletContext getServletContext() - { - return _context; - } - - /* ------------------------------------------------------------- */ - /** - * @deprecated - */ - @Deprecated - public HttpSessionContext getSessionContext() throws IllegalStateException - { - if (isNotAvailable()) - throw new IllegalStateException(); - return __nullSessionContext; - } - - /* ------------------------------------------------------------- */ - /** - * @deprecated As of Version 2.2, this method is replaced by - * {@link #getAttribute} - */ - @Deprecated - public Object getValue(String name) throws IllegalStateException - { - return getAttribute(name); - } - - /* ------------------------------------------------------------- */ - /** - * @deprecated As of Version 2.2, this method is replaced by - * {@link #getAttributeNames} - */ - @Deprecated - public String[] getValueNames() throws IllegalStateException - { - synchronized(Session.this) - { - if (isNotAvailable()) - throw new IllegalStateException(); - if (_attributes==null) - return new String[0]; - String[] a=new String[_attributes.size()]; - return (String[])_attributes.keySet().toArray(a); - } - } - - /* ------------------------------------------------------------ */ - protected void access(long time) - { - synchronized(Session.this) - { - if (!_invalid) - { - _newSession=false; - _lastAccessed=_accessed; - _accessed=time; - - if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < time) - { - invalidate(); - } - else - { - _requests++; - } - } - } - } - - /* ------------------------------------------------------------ */ - protected void complete() - { - synchronized(Session.this) - { - _requests--; - if (_doInvalidate && _requests<=0 ) - doInvalidate(); - } - } - - - /* ------------------------------------------------------------- */ - protected void timeout() throws IllegalStateException - { - // remove session from context and invalidate other sessions with same ID. - removeSession(this,true); - - // Notify listeners and unbind values - synchronized (Session.this) - { - if (!_invalid) - { - if (_requests<=0) - doInvalidate(); - else - _doInvalidate=true; - } - } - } - - /* ------------------------------------------------------------- */ - public void invalidate() throws IllegalStateException - { - // remove session from context and invalidate other sessions with same ID. - removeSession(this,true); - doInvalidate(); - } - - /* ------------------------------------------------------------- */ - protected void doInvalidate() throws IllegalStateException - { - try - { - Log.debug("invalidate ",_clusterId); - // Notify listeners and unbind values - if (isNotAvailable()) - throw new IllegalStateException(); - clearAttributes(); - } - finally - { - // mark as invalid - _invalid=true; - } - } - - /* ------------------------------------------------------------- */ - protected void clearAttributes() - { - while (_attributes!=null && _attributes.size()>0) - { - ArrayList keys; - synchronized (Session.this) - { - keys=new ArrayList(_attributes.keySet()); - } - - Iterator iter=keys.iterator(); - while (iter.hasNext()) - { - String key=(String)iter.next(); - - Object value; - synchronized (Session.this) - { - value=_attributes.remove(key); - } - unbindValue(key,value); - - if (_sessionAttributeListeners!=null) - { - HttpSessionBindingEvent event=new HttpSessionBindingEvent(this,key,value); - - for (int i=0; i<LazyList.size(_sessionAttributeListeners); i++) - ((HttpSessionAttributeListener)LazyList.get(_sessionAttributeListeners,i)).attributeRemoved(event); - } - } - } - if (_attributes!=null) - _attributes.clear(); - } - - /* ------------------------------------------------------------- */ - public boolean isIdChanged() - { - return _idChanged; - } - - /* ------------------------------------------------------------- */ - public boolean isNew() throws IllegalStateException - { - if (isNotAvailable()) - throw new IllegalStateException(); - return _newSession; - } - - /* ------------------------------------------------------------- */ - /** - * @deprecated As of Version 2.2, this method is replaced by - * {@link #setAttribute} - */ - @Deprecated - public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException - { - setAttribute(name,value); - } - - /* ------------------------------------------------------------ */ - public void removeAttribute(String name) - { - Object old; - synchronized(Session.this) - { - if (isNotAvailable()) - throw new IllegalStateException(); - if (_attributes==null) - return; - - old=_attributes.remove(name); - } - - if (old!=null) - { - unbindValue(name,old); - if (_sessionAttributeListeners!=null) - { - HttpSessionBindingEvent event=new HttpSessionBindingEvent(this,name,old); - - for (int i=0; i<LazyList.size(_sessionAttributeListeners); i++) - ((HttpSessionAttributeListener)LazyList.get(_sessionAttributeListeners,i)).attributeRemoved(event); - } - } - - } - - /* ------------------------------------------------------------- */ - /** - * @deprecated As of Version 2.2, this method is replaced by - * {@link #removeAttribute} - */ - @Deprecated - public void removeValue(java.lang.String name) throws IllegalStateException - { - removeAttribute(name); - } - - /* ------------------------------------------------------------ */ - public void setAttribute(String name, Object value) - { - Object old_value=null; - synchronized (Session.this) - { - if (value==null) - { - removeAttribute(name); - return; - } - - if (isNotAvailable()) - throw new IllegalStateException(); - old_value=_attributes.put(name,value); - } - - if (old_value==null || !value.equals(old_value)) - { - unbindValue(name,old_value); - bindValue(name,value); - - if (_sessionAttributeListeners!=null) - { - HttpSessionBindingEvent event=new HttpSessionBindingEvent(this,name,old_value==null?value:old_value); - - for (int i=0; i<LazyList.size(_sessionAttributeListeners); i++) - { - HttpSessionAttributeListener l=(HttpSessionAttributeListener)LazyList.get(_sessionAttributeListeners,i); - - if (old_value==null) - l.attributeAdded(event); - else - l.attributeReplaced(event); - } - } - } - } - - /* ------------------------------------------------------------- */ - public void setIdChanged(boolean changed) - { - _idChanged=changed; - } - - /* ------------------------------------------------------------- */ - public void setMaxInactiveInterval(int secs) - { - _maxIdleMs=(long)secs*1000; - } - - /* ------------------------------------------------------------- */ - @Override - public String toString() - { - return this.getClass().getName()+":"+getId()+"@"+hashCode(); - } - - /* ------------------------------------------------------------- */ - /** If value implements HttpSessionBindingListener, call valueBound() */ - protected void bindValue(java.lang.String name, Object value) - { - if (value!=null&&value instanceof HttpSessionBindingListener) - ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name)); - } - - /* ------------------------------------------------------------ */ - protected boolean isValid() - { - return !_invalid; - } - - /* ------------------------------------------------------------- */ - protected void cookieSet() - { - _cookieSet=_accessed; - } - - /* ------------------------------------------------------------- */ - /** If value implements HttpSessionBindingListener, call valueUnbound() */ - protected void unbindValue(java.lang.String name, Object value) + public void doSessionAttributeListeners(AbstractSession session, String name, Object old, Object value) + { + if (!_sessionAttributeListeners.isEmpty()) { - if (value!=null&&value instanceof HttpSessionBindingListener) - ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name)); - } + HttpSessionBindingEvent event=new HttpSessionBindingEvent(session,name,old==null?value:old); - /* ------------------------------------------------------------- */ - protected void willPassivate() - { - synchronized(Session.this) + for (HttpSessionAttributeListener l : _sessionAttributeListeners) { - HttpSessionEvent event = new HttpSessionEvent(this); - for (Iterator iter = _attributes.values().iterator(); iter.hasNext();) - { - Object value = iter.next(); - if (value instanceof HttpSessionActivationListener) - { - HttpSessionActivationListener listener = (HttpSessionActivationListener) value; - listener.sessionWillPassivate(event); - } - } - } - } - - /* ------------------------------------------------------------- */ - protected void didActivate() - { - synchronized(Session.this) - { - HttpSessionEvent event = new HttpSessionEvent(this); - for (Iterator iter = _attributes.values().iterator(); iter.hasNext();) - { - Object value = iter.next(); - if (value instanceof HttpSessionActivationListener) - { - HttpSessionActivationListener listener = (HttpSessionActivationListener) value; - listener.sessionDidActivate(event); - } - } + if (old==null) + l.attributeAdded(event); + else if (value==null) + l.attributeRemoved(event); + else + l.attributeReplaced(event); } } } 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 d9b9c8d8e3..cea2165073 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 @@ -31,7 +31,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.eclipse.jetty.server.SessionIdManager; -import org.eclipse.jetty.server.session.AbstractSessionManager.Session; import org.eclipse.jetty.util.MultiMap; /* ------------------------------------------------------------ */ @@ -183,7 +182,7 @@ public class HashSessionIdManager extends AbstractSessionIdManager { for (WeakReference<HttpSession> ref: sessions) { - Session session=(Session)ref.get(); + AbstractSession session=(AbstractSession)ref.get(); if (session!=null && session.isValid()) session.invalidate(); } 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 f2cf57fed1..3a7c49422d 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 @@ -14,16 +14,11 @@ package org.eclipse.jetty.server.session; import java.io.DataInputStream; -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.InputStream; import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -38,8 +33,8 @@ import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; /* ------------------------------------------------------------ */ @@ -54,16 +49,18 @@ import org.eclipse.jetty.util.log.Log; */ public class HashSessionManager extends AbstractSessionManager { + final static Logger __log = SessionHandler.__log; + protected final ConcurrentMap<String,HashedSession> _sessions=new ConcurrentHashMap<String,HashedSession>(); private static int __id; private Timer _timer; private boolean _timerStop=false; private TimerTask _task; - private int _scavengePeriodMs=30000; - private int _savePeriodMs=0; //don't do period saves by default - private int _idleSavePeriodMs = 0; // don't idle save sessions by default. + int _scavengePeriodMs=30000; + int _savePeriodMs=0; //don't do period saves by default + int _idleSavePeriodMs = 0; // don't idle save sessions by default. private TimerTask _saveTask; - private File _storeDir; + File _storeDir; private boolean _lazyLoad=false; private volatile boolean _sessionsLoaded=false; @@ -143,24 +140,16 @@ public class HashSessionManager extends AbstractSessionManager return _scavengePeriodMs/1000; } - - /* ------------------------------------------------------------ */ - @Override - public Map getSessionMap() - { - return Collections.unmodifiableMap(_sessions); - } - /* ------------------------------------------------------------ */ @Override public int getSessions() { int sessions=super.getSessions(); - if (Log.isDebugEnabled()) + if (__log.isDebugEnabled()) { if (_sessions.size()!=sessions) - Log.warn("sessions: "+_sessions.size()+"!="+sessions); + __log.warn("sessions: "+_sessions.size()+"!="+sessions); } return sessions; } @@ -230,7 +219,7 @@ public class HashSessionManager extends AbstractSessionManager } catch (Exception e) { - Log.warn(e); + __log.warn(e); } } }; @@ -311,13 +300,13 @@ public class HashSessionManager extends AbstractSessionManager for (Iterator<HashedSession> i=_sessions.values().iterator(); i.hasNext();) { HashedSession session=i.next(); - long idleTime=session._maxIdleMs; - if (idleTime>0&&session._accessed+idleTime<now) + long idleTime=session.getMaxInactiveInterval()*1000; + if (idleTime>0&&session.getAccessed()+idleTime<now) { // Found a stale session, add it to the list session.timeout(); } - else if (_idleSavePeriodMs>0&&session._accessed+_idleSavePeriodMs<now) + else if (_idleSavePeriodMs>0&&session.getAccessed()+_idleSavePeriodMs<now) { session.idle(); } @@ -328,7 +317,7 @@ public class HashSessionManager extends AbstractSessionManager if (t instanceof ThreadDeath) throw ((ThreadDeath)t); else - Log.warn("Problem scavenging sessions", t); + __log.warn("Problem scavenging sessions", t); } finally { @@ -338,7 +327,7 @@ public class HashSessionManager extends AbstractSessionManager /* ------------------------------------------------------------ */ @Override - protected void addSession(AbstractSessionManager.Session session) + protected void addSession(AbstractSession session) { if (isRunning()) _sessions.put(session.getClusterId(),(HashedSession)session); @@ -346,7 +335,7 @@ public class HashSessionManager extends AbstractSessionManager /* ------------------------------------------------------------ */ @Override - public AbstractSessionManager.Session getSession(String idInCluster) + public AbstractSession getSession(String idInCluster) { if ( _lazyLoad && !_sessionsLoaded) { @@ -356,7 +345,7 @@ public class HashSessionManager extends AbstractSessionManager } catch(Exception e) { - Log.warn(e); + __log.warn(e); } } @@ -409,15 +398,15 @@ public class HashSessionManager extends AbstractSessionManager /* ------------------------------------------------------------ */ @Override - protected AbstractSessionManager.Session newSession(HttpServletRequest request) + protected AbstractSession newSession(HttpServletRequest request) { - return new HashedSession(request); + return new HashedSession(this, request); } /* ------------------------------------------------------------ */ - protected AbstractSessionManager.Session newSession(long created, long accessed, String clusterId) + protected AbstractSession newSession(long created, long accessed, String clusterId) { - return new HashedSession(created,accessed, clusterId); + return new HashedSession(this, created,accessed, clusterId); } /* ------------------------------------------------------------ */ @@ -463,7 +452,7 @@ public class HashSessionManager extends AbstractSessionManager if (!_storeDir.canRead()) { - Log.warn ("Unable to restore Sessions: Cannot read from Session storage directory "+_storeDir.getAbsolutePath()); + __log.warn ("Unable to restore Sessions: Cannot read from Session storage directory "+_storeDir.getAbsolutePath()); return; } @@ -493,7 +482,7 @@ public class HashSessionManager extends AbstractSessionManager } catch (Exception e) { - Log.warn("Problem restoring session "+idInCuster, e); + __log.warn("Problem restoring session "+idInCuster, e); } return null; } @@ -508,7 +497,7 @@ public class HashSessionManager extends AbstractSessionManager if (!_storeDir.canWrite()) { - Log.warn ("Unable to save Sessions: Session persistence storage directory "+_storeDir.getAbsolutePath()+ " is not writeable"); + __log.warn ("Unable to save Sessions: Session persistence storage directory "+_storeDir.getAbsolutePath()+ " is not writeable"); return; } @@ -526,23 +515,13 @@ public class HashSessionManager extends AbstractSessionManager DataInputStream in = new DataInputStream(is); String clusterId = in.readUTF(); String nodeId = in.readUTF(); - boolean idChanged = in.readBoolean(); long created = in.readLong(); - long cookieSet = in.readLong(); long accessed = in.readLong(); - long lastAccessed = in.readLong(); - //boolean invalid = in.readBoolean(); - //boolean invalidate = in.readBoolean(); - //long maxIdle = in.readLong(); - //boolean isNew = in.readBoolean(); int requests = in.readInt(); if (session == null) - session = (HashedSession)newSession(created, System.currentTimeMillis(), clusterId); - - session._cookieSet = cookieSet; - session._lastAccessed = lastAccessed; - + session = (HashedSession)newSession(created, accessed, clusterId); + session.setRequests(requests); int size = in.readInt(); if (size>0) { @@ -563,228 +542,6 @@ public class HashSessionManager extends AbstractSessionManager /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - protected class HashedSession extends Session - { - /* ------------------------------------------------------------ */ - private static final long serialVersionUID=-2134521374206116367L; - - /** 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; - - /* ------------------------------------------------------------- */ - protected HashedSession(HttpServletRequest request) - { - super(request); - } - - /* ------------------------------------------------------------- */ - protected HashedSession(long created, long accessed, String clusterId) - { - super(created, accessed, clusterId); - } - - /* ------------------------------------------------------------- */ - protected boolean isNotAvailable() - { - if (_idleSavePeriodMs!=0) - deIdle(); - return _invalid; - } - - /* ------------------------------------------------------------- */ - @Override - public void setMaxInactiveInterval(int secs) - { - super.setMaxInactiveInterval(secs); - if (_maxIdleMs>0&&(_maxIdleMs/10)<_scavengePeriodMs) - HashSessionManager.this.setScavengePeriod((secs+9)/10); - } - - /* ------------------------------------------------------------ */ - @Override - protected void doInvalidate() - throws IllegalStateException - { - super.doInvalidate(); - - // Remove from the disk - if (_storeDir!=null && getId()!=null) - { - String id=getId(); - File f = new File(_storeDir, id); - f.delete(); - } - } - - /* ------------------------------------------------------------ */ - private synchronized void save(boolean reactivate) - { - // 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); - - File file = null; - FileOutputStream fos = null; - - try - { - file = new File(_storeDir, super.getId()); - - if (file.exists()) - file.delete(); - file.createNewFile(); - fos = new FileOutputStream(file); - willPassivate(); - save(fos); - if (reactivate) - didActivate(); - else - clearAttributes(); - } - catch (Exception e) - { - saveFailed(); // We won't try again for this session - - Log.warn("Problem saving session " + super.getId(), e); - - if (fos != null) - { - // Must not leave the file open if the saving failed - IO.close(fos); - // No point keeping the file if we didn't save the whole session - file.delete(); - _idled=false; // assume problem was before _values.clear(); - } - } - } - } - /* ------------------------------------------------------------ */ - public synchronized void save(OutputStream os) throws IOException - { - DataOutputStream out = new DataOutputStream(os); - out.writeUTF(_clusterId); - out.writeUTF(_nodeId); - out.writeBoolean(_idChanged); - out.writeLong( _created); - out.writeLong(_cookieSet); - out.writeLong(_accessed); - out.writeLong(_lastAccessed); - - /* 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.writeLong(_maxIdleMs); - //out.writeBoolean( _newSession); - out.writeInt(_requests); - if (_attributes != null) - { - out.writeInt(_attributes.size()); - ObjectOutputStream oos = new ObjectOutputStream(out); - for (Map.Entry<String,Object> entry: _attributes.entrySet()) - { - oos.writeUTF(entry.getKey()); - oos.writeObject(entry.getValue()); - } - oos.close(); - } - else - { - out.writeInt(0); - out.close(); - } - } - - /* ------------------------------------------------------------ */ - public synchronized void deIdle() - { - if (isIdled()) - { - // Access now to prevent race with idling period - access(System.currentTimeMillis()); - - - if (Log.isDebugEnabled()) - { - Log.debug("Deidling " + super.getId()); - } - - FileInputStream fis = null; - - try - { - File file = new File(_storeDir, super.getId()); - if (!file.exists() || !file.canRead()) - throw new FileNotFoundException(file.getName()); - - fis = new FileInputStream(file); - _idled = false; - restoreSession(fis, this); - - didActivate(); - - // If we are doing period saves, then there is no point deleting at this point - if (_savePeriodMs == 0) - file.delete(); - } - catch (Exception e) - { - Log.warn("Problem deidling session " + super.getId(), e); - IO.close(fis); - 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. - */ - public synchronized void idle() - { - save(false); - } - - /* ------------------------------------------------------------ */ - public boolean isIdled() - { - return _idled; - } - - /* ------------------------------------------------------------ */ - public boolean isSaveFailed() - { - return _saveFailed; - } - - /* ------------------------------------------------------------ */ - public void saveFailed() - { - _saveFailed = true; - } - - } - - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ protected class ClassLoadingObjectInputStream extends ObjectInputStream { /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java new file mode 100644 index 0000000000..98f0814bc8 --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java @@ -0,0 +1,227 @@ +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 java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.log.Log; + +class HashedSession extends AbstractSession +{ + 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; + + /* ------------------------------------------------------------- */ + 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 (_hashSessionManager._idleSavePeriodMs!=0) + deIdle(); + super.checkValid(); + } + + /* ------------------------------------------------------------- */ + @Override + public void setMaxInactiveInterval(int secs) + { + super.setMaxInactiveInterval(secs); + if (getMaxInactiveInterval()>0&&(getMaxInactiveInterval()*1000/10)<_hashSessionManager._scavengePeriodMs) + _hashSessionManager.setScavengePeriod((secs+9)/10); + } + + /* ------------------------------------------------------------ */ + @Override + protected void doInvalidate() + throws IllegalStateException + { + super.doInvalidate(); + + // Remove from the disk + if (_hashSessionManager._storeDir!=null && getId()!=null) + { + String id=getId(); + File f = new File(_hashSessionManager._storeDir, id); + f.delete(); + } + } + + /* ------------------------------------------------------------ */ + synchronized void save(boolean reactivate) + { + // 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); + + File file = null; + FileOutputStream fos = null; + + try + { + file = new File(_hashSessionManager._storeDir, super.getId()); + + if (file.exists()) + file.delete(); + file.createNewFile(); + fos = new FileOutputStream(file); + willPassivate(); + save(fos); + if (reactivate) + didActivate(); + else + clearAttributes(); + } + catch (Exception e) + { + saveFailed(); // We won't try again for this session + + Log.warn("Problem saving session " + super.getId(), e); + + if (fos != null) + { + // Must not leave the file open if the saving failed + IO.close(fos); + // No point keeping the file if we didn't save the whole session + file.delete(); + _idled=false; // assume problem was before _values.clear(); + } + } + } + } + /* ------------------------------------------------------------ */ + 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.writeLong(_maxIdleMs); + //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)); + } + oos.close(); + } + + /* ------------------------------------------------------------ */ + public synchronized void deIdle() + { + if (isIdled()) + { + // Access now to prevent race with idling period + access(System.currentTimeMillis()); + + + if (Log.isDebugEnabled()) + { + Log.debug("Deidling " + 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); + + 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) + { + Log.warn("Problem deidling session " + super.getId(), e); + IO.close(fis); + 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. + */ + public synchronized void idle() + { + save(false); + } + + /* ------------------------------------------------------------ */ + public synchronized boolean isIdled() + { + return _idled; + } + + /* ------------------------------------------------------------ */ + public synchronized boolean isSaveFailed() + { + return _saveFailed; + } + + /* ------------------------------------------------------------ */ + public synchronized void saveFailed() + { + _saveFailed = true; + } + +}
\ No newline at end of file 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 861a85977e..ea7da954f9 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 @@ -40,6 +40,7 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.SessionManager; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; @@ -52,7 +53,9 @@ import org.eclipse.jetty.util.log.Log; */ public class JDBCSessionIdManager extends AbstractSessionIdManager { - protected final HashSet<String> _sessionIds = new HashSet(); + final static Logger __log = SessionHandler.__log; + + protected final HashSet<String> _sessionIds = new HashSet<String>(); protected Server _server; protected String _driverClassName; protected String _connectionUrl; @@ -104,7 +107,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager throws SQLException { _dbName = dbMeta.getDatabaseProductName().toLowerCase(); - Log.debug ("Using database "+_dbName); + __log.debug ("Using database "+_dbName); _isLower = dbMeta.storesLowerCaseIdentifiers(); _isUpper = dbMeta.storesUpperCaseIdentifiers(); } @@ -228,7 +231,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager if ((System.currentTimeMillis()%2) == 0) _scavengeIntervalMs += tenPercent; - if (Log.isDebugEnabled()) Log.debug("Scavenging every "+_scavengeIntervalMs+" ms"); + if (__log.isDebugEnabled()) __log.debug("Scavenging every "+_scavengeIntervalMs+" ms"); if (_timer!=null && (period!=old_period || _task==null)) { synchronized (this) @@ -269,7 +272,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager } catch (Exception e) { - Log.warn("Problem storing session id="+id, e); + __log.warn("Problem storing session id="+id, e); } } } @@ -292,8 +295,8 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager synchronized (_sessionIds) { - if (Log.isDebugEnabled()) - Log.debug("Removing session id="+id); + if (__log.isDebugEnabled()) + __log.debug("Removing session id="+id); try { _sessionIds.remove(id); @@ -301,7 +304,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager } catch (Exception e) { - Log.warn("Problem removing session id="+id, e); + __log.warn("Problem removing session id="+id, e); } } @@ -356,7 +359,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager } catch (Exception e) { - Log.warn("Problem checking inUse for id="+clusterId, e); + __log.warn("Problem checking inUse for id="+clusterId, e); return false; } } @@ -407,13 +410,13 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager initializeDatabase(); prepareTables(); super.doStart(); - if (Log.isDebugEnabled()) Log.debug("Scavenging interval = "+getScavengeInterval()+" sec"); + if (__log.isDebugEnabled()) __log.debug("Scavenging interval = "+getScavengeInterval()+" sec"); _timer=new Timer("JDBCSessionScavenger", true); setScavengeInterval(getScavengeInterval()); } catch (Exception e) { - Log.warn("Problem initialising JettySessionIds table", e); + __log.warn("Problem initialising JettySessionIds table", e); } } @@ -650,7 +653,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager List expiredSessionIds = new ArrayList(); try { - if (Log.isDebugEnabled()) Log.debug("Scavenge sweep started at "+System.currentTimeMillis()); + if (__log.isDebugEnabled()) __log.debug("Scavenge sweep started at "+System.currentTimeMillis()); if (_lastScavengeTime > 0) { connection = getConnection(); @@ -659,7 +662,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager PreparedStatement statement = connection.prepareStatement(_selectExpiredSessions); long lowerBound = (_lastScavengeTime - _scavengeIntervalMs); long upperBound = _lastScavengeTime; - if (Log.isDebugEnabled()) Log.debug (" Searching for sessions expired between "+lowerBound + " and "+upperBound); + if (__log.isDebugEnabled()) __log.debug (" Searching for sessions expired between "+lowerBound + " and "+upperBound); statement.setLong(1, lowerBound); statement.setLong(2, upperBound); @@ -668,7 +671,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager { String sessionId = result.getString("sessionId"); expiredSessionIds.add(sessionId); - if (Log.isDebugEnabled()) Log.debug (" Found expired sessionId="+sessionId); + if (__log.isDebugEnabled()) __log.debug (" Found expired sessionId="+sessionId); } //tell the SessionManagers to expire any sessions with a matching sessionId in memory @@ -691,7 +694,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager upperBound = _lastScavengeTime - (2 * _scavengeIntervalMs); if (upperBound > 0) { - if (Log.isDebugEnabled()) Log.debug("Deleting old expired sessions expired before "+upperBound); + if (__log.isDebugEnabled()) __log.debug("Deleting old expired sessions expired before "+upperBound); statement = connection.prepareStatement(_deleteOldExpiredSessions); statement.setLong(1, upperBound); statement.executeUpdate(); @@ -700,12 +703,12 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager } catch (Exception e) { - Log.warn("Problem selecting expired sessions", e); + __log.warn("Problem selecting expired sessions", e); } finally { _lastScavengeTime=System.currentTimeMillis(); - if (Log.isDebugEnabled()) Log.debug("Scavenge sweep ended at "+_lastScavengeTime); + if (__log.isDebugEnabled()) __log.debug("Scavenge sweep ended at "+_lastScavengeTime); if (connection != null) { try @@ -714,7 +717,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager } catch (SQLException e) { - Log.warn(e); + __log.warn(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 2135947bb4..01f2cf6853 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 @@ -107,7 +107,7 @@ public class JDBCSessionManager extends AbstractSessionManager _created=System.currentTimeMillis(); _accessed = _created; _attributes = new HashMap<String,Object>(); - _lastNode = getIdManager().getWorkerName(); + _lastNode = getSessionIdManager().getWorkerName(); } public SessionData (String sessionId,Map<String,Object> attributes) @@ -116,7 +116,7 @@ public class JDBCSessionManager extends AbstractSessionManager _created=System.currentTimeMillis(); _accessed = _created; _attributes = attributes; - _lastNode = getIdManager().getWorkerName(); + _lastNode = getSessionIdManager().getWorkerName(); } public synchronized String getId () @@ -262,7 +262,7 @@ public class JDBCSessionManager extends AbstractSessionManager * * Session instance in memory of this node. */ - public class Session extends AbstractSessionManager.Session + public class Session extends AbstractSession { private static final long serialVersionUID = 5208464051134226143L; private final SessionData _data; @@ -275,13 +275,14 @@ public class JDBCSessionManager extends AbstractSessionManager */ protected Session (HttpServletRequest request) { - super(request); - _data = new SessionData(_clusterId,_attributes); + super(JDBCSessionManager.this,request); + _data = new SessionData(getClusterId(),_jdbcAttributes); if (_dftMaxIdleSecs>0) _data.setMaxIdleMs(_dftMaxIdleSecs*1000); _data.setCanonicalContext(canonicalize(_context.getContextPath())); _data.setVirtualHost(getVirtualHost(_context)); - _data.setExpiryTime(_maxIdleMs < 0 ? 0 : (System.currentTimeMillis() + _maxIdleMs)); + int maxInterval=getMaxInactiveInterval(); + _data.setExpiryTime(maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000)); } /** @@ -290,12 +291,12 @@ public class JDBCSessionManager extends AbstractSessionManager */ protected Session (long accessed, SessionData data) { - super(data.getCreated(), accessed, data.getId()); + super(JDBCSessionManager.this,data.getCreated(), accessed, data.getId()); _data=data; if (_dftMaxIdleSecs>0) _data.setMaxIdleMs(_dftMaxIdleSecs*1000); - _attributes.putAll(_data.getAttributeMap()); - _data.setAttributeMap(_attributes); + _jdbcAttributes.putAll(_data.getAttributeMap()); + _data.setAttributeMap(_jdbcAttributes); } @Override @@ -322,20 +323,26 @@ public class JDBCSessionManager extends AbstractSessionManager * Entry to session. * Called by SessionHandler on inbound request and the session already exists in this node's memory. * - * @see org.eclipse.jetty.server.session.AbstractSessionManager.Session#access(long) + * @see org.eclipse.jetty.server.session.AbstractSession#access(long) */ @Override - protected void access(long time) + protected boolean access(long time) { - super.access(time); - _data.setLastAccessed(_data.getAccessed()); - _data.setAccessed(time); - _data.setExpiryTime(_maxIdleMs < 0 ? 0 : (time + _maxIdleMs)); + if (super.access(time)) + { + _data.setLastAccessed(_data.getAccessed()); + _data.setAccessed(time); + + int maxInterval=getMaxInactiveInterval(); + _data.setExpiryTime(maxInterval <= 0 ? 0 : (time + maxInterval*1000)); + return true; + } + return false; } /** * Exit from session - * @see org.eclipse.jetty.server.session.AbstractSessionManager.Session#complete() + * @see org.eclipse.jetty.server.session.AbstractSession#complete() */ @Override protected void complete() @@ -506,7 +513,7 @@ public class JDBCSessionManager extends AbstractSessionManager " lastSaved="+(session==null?0:session._data._lastSaved)+ " interval="+(_saveIntervalSec * 1000)+ " lastNode="+session._data.getLastNode()+ - " thisNode="+getIdManager().getWorkerName()+ + " thisNode="+getSessionIdManager().getWorkerName()+ " difference="+(now - session._data._lastSaved)); } @@ -528,13 +535,13 @@ public class JDBCSessionManager extends AbstractSessionManager if (data != null) { - if (!data.getLastNode().equals(getIdManager().getWorkerName()) || session==null) + if (!data.getLastNode().equals(getSessionIdManager().getWorkerName()) || session==null) { //if the session has no expiry, or it is not already expired if (data._expiryTime <= 0 || data._expiryTime > now) { - Log.debug("getSession("+idInCluster+"): lastNode="+data.getLastNode()+" thisNode="+getIdManager().getWorkerName()); - data.setLastNode(getIdManager().getWorkerName()); + Log.debug("getSession("+idInCluster+"): lastNode="+data.getLastNode()+" thisNode="+getSessionIdManager().getWorkerName()); + data.setLastNode(getSessionIdManager().getWorkerName()); //session last used on a different node, or we don't have it in memory session = new Session(now,data); _sessions.put(idInCluster, session); @@ -567,17 +574,6 @@ public class JDBCSessionManager extends AbstractSessionManager } } } - - - /** - * Get all the sessions as a map of id to Session. - */ - @Override - public Map getSessionMap() - { - return Collections.unmodifiableMap(_sessions); - } - /** * Get the number of sessions. @@ -688,10 +684,10 @@ public class JDBCSessionManager extends AbstractSessionManager /** * Add a newly created session to our in-memory list for this node and persist it. * - * @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSessionManager.Session) + * @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSessionManager.AbstractSession) */ @Override - protected void addSession(AbstractSessionManager.Session session) + protected void addSession(AbstractSession session) { if (session==null) return; @@ -722,7 +718,7 @@ public class JDBCSessionManager extends AbstractSessionManager * @see org.eclipse.jetty.server.session.AbstractSessionManager#newSession(javax.servlet.http.HttpServletRequest) */ @Override - protected AbstractSessionManager.Session newSession(HttpServletRequest request) + protected AbstractSession newSession(HttpServletRequest request) { return new Session(request); } @@ -734,7 +730,7 @@ public class JDBCSessionManager extends AbstractSessionManager * {@link SessionIdManager#invalidateAll(String)} should be called. */ @Override - public void removeSession(AbstractSessionManager.Session session, boolean invalidate) + public void removeSession(AbstractSession session, boolean invalidate) { // Remove session from context and global maps boolean removed = false; @@ -757,11 +753,11 @@ public class JDBCSessionManager extends AbstractSessionManager if (invalidate) _sessionIdManager.invalidateAll(session.getClusterId()); - if (invalidate && _sessionListeners!=null) + if (invalidate && !_sessionListeners.isEmpty()) { HttpSessionEvent event=new HttpSessionEvent(session); - for (int i=LazyList.size(_sessionListeners); i-->0;) - ((HttpSessionListener)LazyList.get(_sessionListeners,i)).sessionDestroyed(event); + for (HttpSessionListener l : _sessionListeners) + l.sessionDestroyed(event); } if (!invalidate) { @@ -885,7 +881,7 @@ public class JDBCSessionManager extends AbstractSessionManager data.setCanonicalContext(result.getString("contextPath")); data.setVirtualHost(result.getString("virtualHost")); - InputStream is = ((JDBCSessionIdManager)getIdManager())._dbAdaptor.getBlobInputStream(result, "map"); + InputStream is = ((JDBCSessionIdManager)getSessionIdManager())._dbAdaptor.getBlobInputStream(result, "map"); ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream (is); Object o = ois.readObject(); data.setAttributeMap((Map<String,Object>)o); @@ -948,7 +944,7 @@ public class JDBCSessionManager extends AbstractSessionManager statement.setString(2, data.getId()); //session id statement.setString(3, data.getCanonicalContext()); //context path statement.setString(4, data.getVirtualHost()); //first vhost - statement.setString(5, getIdManager().getWorkerName());//my node id + statement.setString(5, getSessionIdManager().getWorkerName());//my node id statement.setLong(6, data.getAccessed());//accessTime statement.setLong(7, data.getLastAccessed()); //lastAccessTime statement.setLong(8, data.getCreated()); //time created @@ -999,7 +995,7 @@ public class JDBCSessionManager extends AbstractSessionManager long now = System.currentTimeMillis(); connection.setAutoCommit(true); statement = connection.prepareStatement(__updateSession); - statement.setString(1, getIdManager().getWorkerName());//my node id + statement.setString(1, getSessionIdManager().getWorkerName());//my node id statement.setLong(2, data.getAccessed());//accessTime statement.setLong(3, data.getLastAccessed()); //lastAccessTime statement.setLong(4, now); //last saved time @@ -1036,7 +1032,7 @@ public class JDBCSessionManager extends AbstractSessionManager protected void updateSessionNode (SessionData data) throws Exception { - String nodeId = getIdManager().getWorkerName(); + String nodeId = getSessionIdManager().getWorkerName(); Connection connection = getConnection(); PreparedStatement statement = null; try @@ -1073,7 +1069,7 @@ public class JDBCSessionManager extends AbstractSessionManager long now = System.currentTimeMillis(); connection.setAutoCommit(true); statement = connection.prepareStatement(__updateSessionAccessTime); - statement.setString(1, getIdManager().getWorkerName()); + statement.setString(1, getSessionIdManager().getWorkerName()); statement.setLong(2, data.getAccessed()); statement.setLong(3, data.getLastAccessed()); statement.setLong(4, now); @@ -1133,7 +1129,7 @@ public class JDBCSessionManager extends AbstractSessionManager private Connection getConnection () throws SQLException { - return ((JDBCSessionIdManager)getIdManager()).getConnection(); + return ((JDBCSessionIdManager)getSessionIdManager()).getConnection(); } /** diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java index f567c30256..01713ff275 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java @@ -31,13 +31,18 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.SessionManager; import org.eclipse.jetty.server.handler.ScopedHandler; import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; /* ------------------------------------------------------------ */ /** SessionHandler. */ public class SessionHandler extends ScopedHandler { + final static Logger __log = Log.getLogger("org.eclipse.jetty.server.session"); + public final static EnumSet<SessionTrackingMode> DEFAULT_TRACKING = EnumSet.of(SessionTrackingMode.COOKIE,SessionTrackingMode.URL); + + /* -------------------------------------------------------------- */ private SessionManager _sessionManager; @@ -137,11 +142,9 @@ public class SessionHandler extends ScopedHandler public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - setRequestedId(baseRequest,request); - SessionManager old_session_manager=null; HttpSession old_session=null; - + HttpSession access=null; try { old_session_manager = baseRequest.getSessionManager(); @@ -152,6 +155,7 @@ public class SessionHandler extends ScopedHandler // new session context baseRequest.setSessionManager(_sessionManager); baseRequest.setSession(null); + checkRequestedSessionId(baseRequest,request); } // access any existing session @@ -163,6 +167,7 @@ public class SessionHandler extends ScopedHandler { if(session!=old_session) { + access=session; HttpCookie cookie = _sessionManager.access(session,request.isSecure()); if (cookie!=null ) // Handle changed ID or max-age refresh baseRequest.getResponse().addCookie(cookie); @@ -176,10 +181,10 @@ public class SessionHandler extends ScopedHandler } } - if(Log.isDebugEnabled()) + if(__log.isDebugEnabled()) { - Log.debug("sessionManager="+_sessionManager); - Log.debug("session="+session); + __log.debug("sessionManager="+_sessionManager); + __log.debug("session="+session); } // start manual inline of nextScope(target,baseRequest,request,response); @@ -194,20 +199,19 @@ public class SessionHandler extends ScopedHandler } finally { - HttpSession session=request.getSession(false); - - if (old_session_manager != _sessionManager) + if (access!=null) + _sessionManager.complete(access); + else { - //leaving context, free up the session - if (session!=null) + HttpSession session = baseRequest.getSession(false); + if (session!=null && old_session==null) _sessionManager.complete(session); - - // Leave last session in place - if (old_session_manager!=null ) - { - baseRequest.setSessionManager(old_session_manager); - baseRequest.setSession(old_session); - } + } + + if (old_session_manager!=null && old_session_manager != _sessionManager) + { + baseRequest.setSessionManager(old_session_manager); + baseRequest.setSession(old_session); } } } @@ -235,13 +239,22 @@ public class SessionHandler extends ScopedHandler * @param baseRequest * @param request */ - protected void setRequestedId(Request baseRequest, HttpServletRequest request) + protected void checkRequestedSessionId(Request baseRequest, HttpServletRequest request) { String requested_session_id=request.getRequestedSessionId(); - if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()) || requested_session_id!=null) + + SessionManager sessionManager = getSessionManager(); + + if (requested_session_id!=null && sessionManager!=null) + { + HttpSession session=sessionManager.getHttpSession(requested_session_id); + if (session!=null && sessionManager.isValid(session)) + baseRequest.setSession(session); + return; + } + else if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType())) return; - SessionManager sessionManager = getSessionManager(); boolean requested_session_id_from_cookie=false; HttpSession session=null; @@ -256,22 +269,13 @@ public class SessionHandler extends ScopedHandler { if (sessionCookie.equalsIgnoreCase(cookies[i].getName())) { - if (requested_session_id!=null) - { - // Multiple jsessionid cookies. Probably due to - // multiple paths and/or domains. Pick the first - // known session or the last defined cookie. - if (sessionManager.getHttpSession(requested_session_id)!=null) - break; - } - requested_session_id=cookies[i].getValue(); requested_session_id_from_cookie = true; - if(Log.isDebugEnabled())Log.debug("Got Session ID "+requested_session_id+" from cookie"); + if(__log.isDebugEnabled())__log.debug("Got Session ID "+requested_session_id+" from cookie"); session=sessionManager.getHttpSession(requested_session_id); - if (session!=null) - baseRequest.setSession(session); + if (session!=null && sessionManager.isValid(session)) + break; } } } @@ -299,14 +303,17 @@ public class SessionHandler extends ScopedHandler requested_session_id = uri.substring(s,i); requested_session_id_from_cookie = false; - if(Log.isDebugEnabled()) - Log.debug("Got Session ID "+requested_session_id+" from URL"); + session=sessionManager.getHttpSession(requested_session_id); + if(__log.isDebugEnabled()) + __log.debug("Got Session ID "+requested_session_id+" from URL"); } } } baseRequest.setRequestedSessionId(requested_session_id); - baseRequest.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie); + baseRequest.setRequestedSessionIdFromCookie(requested_session_id!=null && requested_session_id_from_cookie); + if (session!=null && sessionManager.isValid(session)) + baseRequest.setSession(session); } /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java index d91b5c4cfc..d457296aca 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java @@ -41,6 +41,7 @@ import org.eclipse.jetty.io.ByteArrayEndPoint; import org.eclipse.jetty.server.bio.SocketConnector; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.session.AbstractSession; import org.eclipse.jetty.server.session.AbstractSessionManager; import org.eclipse.jetty.server.session.HashSessionIdManager; import org.eclipse.jetty.server.session.HashSessionManager; @@ -332,7 +333,7 @@ public class ResponseTest request.setRequestedSessionId("12345"); request.setRequestedSessionIdFromCookie(false); AbstractSessionManager manager=new HashSessionManager(); - manager.setIdManager(new HashSessionIdManager()); + manager.setSessionIdManager(new HashSessionIdManager()); request.setSessionManager(manager); request.setSession(new TestSession(manager,"12345")); @@ -380,7 +381,7 @@ public class ResponseTest request.setRequestedSessionId("12345"); request.setRequestedSessionIdFromCookie(false); AbstractSessionManager manager=new HashSessionManager(); - manager.setIdManager(new HashSessionIdManager()); + manager.setSessionIdManager(new HashSessionIdManager()); request.setSessionManager(manager); request.setSession(new TestSession(manager,"12345")); manager.setCheckingRemoteSessionIdEncoding(false); @@ -473,11 +474,11 @@ public class ResponseTest return response; } - private class TestSession extends AbstractSessionManager.Session + private class TestSession extends AbstractSession { public TestSession(AbstractSessionManager abstractSessionManager, String id) { - abstractSessionManager.super(System.currentTimeMillis(),System.currentTimeMillis(), id); + super(abstractSessionManager, System.currentTimeMillis(),System.currentTimeMillis(), id); } public Object getAttribute(String name) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java index 99081c499e..efb44bba5f 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java @@ -271,7 +271,7 @@ public class ContextHandlerTest ContextHandler handler = new ContextHandler(); assertTrue("Not a directory " + testDirectory,testDirectory.isDirectory()); - handler.setBaseResource(Resource.newResource(testDirectory.toURI().toURL())); + handler.setBaseResource(Resource.newResource(Resource.toURL(testDirectory))); List<String> paths = new ArrayList<String>(handler.getResourcePaths(root)); assertEquals(2,paths.size()); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionHandlerTest.java index 13bd96675e..c413a1a7be 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionHandlerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionHandlerTest.java @@ -161,7 +161,7 @@ public class SessionHandlerTest return cookieName; } }); - sessionHandler.setRequestedId(baseRequest,httpRequest); + sessionHandler.checkRequestedSessionId(baseRequest,httpRequest); assertEquals(sessionId,baseRequest.getRequestedSessionId()); assertTrue(baseRequest.isRequestedSessionIdFromCookie()); @@ -202,7 +202,7 @@ public class SessionHandlerTest } }); - sessionHandler.setRequestedId(baseRequest,httpRequest); + sessionHandler.checkRequestedSessionId(baseRequest,httpRequest); assertEquals(sessionId,baseRequest.getRequestedSessionId()); assertFalse(baseRequest.isRequestedSessionIdFromCookie()); @@ -627,7 +627,7 @@ public class SessionHandlerTest return null; } - public SessionIdManager getIdManager() + public SessionIdManager getSessionIdManager() { return null; } @@ -706,7 +706,7 @@ public class SessionHandlerTest { } - public void setIdManager(SessionIdManager idManager) + public void setSessionIdManager(SessionIdManager idManager) { } |