Merge remote-tracking branch 'origin/jetty-9.4.x'
This commit is contained in:
commit
6551d2c9a9
|
@ -28,13 +28,31 @@ import org.eclipse.jetty.util.Callback;
|
|||
/** Abstraction of the outbound HTTP transport.
|
||||
*/
|
||||
public interface HttpTransport
|
||||
{
|
||||
{
|
||||
/** Asynchronous call to send a response (or part) over the transport
|
||||
* @param info The header info to send, or null if just sending more data.
|
||||
* The first call to send for a response must have a non null info.
|
||||
* @param head True if the response if for a HEAD request (and the data should not be sent).
|
||||
* @param content A buffer of content to be sent.
|
||||
* @param lastContent True if the content is the last content for the current response.
|
||||
* @param callback The Callback instance that success or failure of the send is notified on
|
||||
*/
|
||||
void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback);
|
||||
|
||||
/**
|
||||
* @return true if responses can be pushed over this transport
|
||||
*/
|
||||
boolean isPushSupported();
|
||||
|
||||
|
||||
/**
|
||||
* @param request A request to use as the basis for generating a pushed response.
|
||||
*/
|
||||
void push(MetaData.Request request);
|
||||
|
||||
|
||||
/**
|
||||
* Called to indicated the end of the current request/response cycle (which may be
|
||||
* some time after the last content is sent).
|
||||
*/
|
||||
void onCompleted();
|
||||
|
||||
/**
|
||||
|
@ -46,7 +64,8 @@ public interface HttpTransport
|
|||
* <p>
|
||||
* This method is called when an error response needs to be sent,
|
||||
* but the response is already committed, or when a write failure
|
||||
* is detected.
|
||||
* is detected. If abort is called, {@link #onCompleted()} is not
|
||||
* called
|
||||
*
|
||||
* @param failure the failure that caused the abort.
|
||||
*/
|
||||
|
|
|
@ -25,7 +25,7 @@ import java.util.Set;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.Locker.Lock;
|
||||
|
@ -51,7 +51,7 @@ import org.eclipse.jetty.util.thread.Locker.Lock;
|
|||
* passivated before eviction from the cache.
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSessionCache extends AbstractLifeCycle implements SessionCache
|
||||
public abstract class AbstractSessionCache extends ContainerLifeCycle implements SessionCache
|
||||
{
|
||||
final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
|
@ -74,7 +74,7 @@ public abstract class AbstractSessionCache extends AbstractLifeCycle implements
|
|||
/**
|
||||
* When, if ever, to evict sessions: never; only when the last request for them finishes; after inactivity time (expressed as secs)
|
||||
*/
|
||||
protected int _evictionPolicy;
|
||||
protected int _evictionPolicy = SessionCache.NEVER_EVICT;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -204,10 +204,7 @@ public abstract class AbstractSessionCache extends AbstractLifeCycle implements
|
|||
if (_context == null)
|
||||
throw new IllegalStateException ("No ContextId");
|
||||
|
||||
_sessionDataStore.initialize(_context);
|
||||
_sessionDataStore.start();
|
||||
|
||||
|
||||
_sessionDataStore.initialize(_context);
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
@ -234,6 +231,7 @@ public abstract class AbstractSessionCache extends AbstractLifeCycle implements
|
|||
*/
|
||||
public void setSessionDataStore(SessionDataStore sessionStore)
|
||||
{
|
||||
updateBean(_sessionDataStore, sessionStore);
|
||||
_sessionDataStore = sessionStore;
|
||||
}
|
||||
|
||||
|
@ -447,6 +445,7 @@ public abstract class AbstractSessionCache extends AbstractLifeCycle implements
|
|||
|
||||
if (_sessionDataStore == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("No SessionDataStore, putting into SessionCache only id={}", id);
|
||||
session.setResident(true);
|
||||
if (doPutIfAbsent(id, session) == null) //ensure it is in our map
|
||||
session.updateInactivityTimer();
|
||||
|
@ -464,6 +463,7 @@ public abstract class AbstractSessionCache extends AbstractLifeCycle implements
|
|||
//if we evict on session exit, boot it from the cache
|
||||
if (getEvictionPolicy() == EVICT_ON_SESSION_EXIT)
|
||||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Eviction on request exit id={}", id);
|
||||
doDelete(session.getId());
|
||||
session.setResident(false);
|
||||
}
|
||||
|
@ -472,12 +472,14 @@ public abstract class AbstractSessionCache extends AbstractLifeCycle implements
|
|||
session.setResident(true);
|
||||
if (doPutIfAbsent(id,session) == null) //ensure it is in our map
|
||||
session.updateInactivityTimer();
|
||||
if (LOG.isDebugEnabled())LOG.debug("Non passivating SessionDataStore, session in SessionCache only id={}",id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//backing store supports passivation, call the listeners
|
||||
session.willPassivate();
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Session passivating id={}", id);
|
||||
_sessionDataStore.store(id, session.getSessionData());
|
||||
|
||||
if (getEvictionPolicy() == EVICT_ON_SESSION_EXIT)
|
||||
|
@ -485,6 +487,7 @@ public abstract class AbstractSessionCache extends AbstractLifeCycle implements
|
|||
//throw out the passivated session object from the map
|
||||
doDelete(id);
|
||||
session.setResident(false);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Evicted on request exit id={}", id);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -493,11 +496,13 @@ public abstract class AbstractSessionCache extends AbstractLifeCycle implements
|
|||
session.setResident(true);
|
||||
if (doPutIfAbsent(id,session) == null) //ensure it is in our map
|
||||
session.updateInactivityTimer();
|
||||
if (LOG.isDebugEnabled())LOG.debug("Session reactivated id={}",id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Req count={} for id={}",session.getRequests(),id);
|
||||
session.setResident(true);
|
||||
if (doPutIfAbsent(id, session) == null) //ensure it is the map, but don't save it to the backing store until the last request exists
|
||||
session.updateInactivityTimer();
|
||||
|
|
|
@ -485,7 +485,7 @@ public class Session implements SessionHandler.SessionIf
|
|||
{
|
||||
//we do not want to evict inactive sessions
|
||||
setInactivityTimer(-1L);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Session is immortal && never evict: timer cancelled");
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Session is immortal && bo inactivity eviction: timer cancelled");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -354,8 +354,7 @@ public class SessionData implements Serializable
|
|||
LOG.debug("Testing expiry on session {}: Never expires? {} Is expired?{}", _id, (getExpiry()<= 0), (getExpiry() < time));
|
||||
if (getExpiry() <= 0)
|
||||
return false; //never expires
|
||||
|
||||
return (getExpiry() < time);
|
||||
return (getExpiry() <= time);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -402,7 +402,6 @@ public class SessionHandler extends ScopedHandler
|
|||
//check if session management is set up, if not set up HashSessions
|
||||
final Server server=getServer();
|
||||
|
||||
|
||||
_context=ContextHandler.getCurrentContext();
|
||||
_loader=Thread.currentThread().getContextClassLoader();
|
||||
|
||||
|
@ -413,11 +412,7 @@ public class SessionHandler extends ScopedHandler
|
|||
if (_sessionCache == null)
|
||||
{
|
||||
SessionCacheFactory ssFactory = server.getBean(SessionCacheFactory.class);
|
||||
if (ssFactory != null)
|
||||
_sessionCache = ssFactory.getSessionCache(this);
|
||||
else
|
||||
_sessionCache = new DefaultSessionCache(this);
|
||||
|
||||
setSessionCache(ssFactory != null?ssFactory.getSessionCache(this):new DefaultSessionCache(this));
|
||||
SessionDataStore sds = null;
|
||||
SessionDataStoreFactory sdsFactory = server.getBean(SessionDataStoreFactory.class);
|
||||
if (sdsFactory != null)
|
||||
|
@ -500,10 +495,8 @@ public class SessionHandler extends ScopedHandler
|
|||
_checkingRemoteSessionIdEncoding=Boolean.parseBoolean(tmp);
|
||||
}
|
||||
|
||||
_sessionContext = new SessionContext(_sessionIdManager.getWorkerName(), _context);
|
||||
|
||||
_sessionContext = new SessionContext(_sessionIdManager.getWorkerName(), _context);
|
||||
_sessionCache.initialize(_sessionContext);
|
||||
_sessionCache.start();
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
@ -1009,8 +1002,12 @@ public class SessionHandler extends ScopedHandler
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param cache
|
||||
*/
|
||||
public void setSessionCache (SessionCache cache)
|
||||
{
|
||||
updateBean(_sessionCache, cache);
|
||||
_sessionCache = cache;
|
||||
}
|
||||
|
||||
|
@ -1361,18 +1358,6 @@ public class SessionHandler extends ScopedHandler
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return (_context==null?super.toString():_context.toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -1574,12 +1559,12 @@ public class SessionHandler extends ScopedHandler
|
|||
{
|
||||
//if there is a session that was created during handling this context, then complete it
|
||||
HttpSession finalSession = baseRequest.getSession(false);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("FinalSession="+finalSession+" old_session_manager="+old_session_manager+" this="+this);
|
||||
if ((finalSession != null) && (old_session_manager != this))
|
||||
{
|
||||
complete((Session)finalSession, baseRequest);
|
||||
}
|
||||
|
||||
|
||||
if (old_session_manager != null && old_session_manager != this)
|
||||
{
|
||||
baseRequest.setSessionHandler(old_session_manager);
|
||||
|
|
|
@ -57,7 +57,7 @@ public abstract class AbstractSessionInvalidateAndCreateTest
|
|||
{
|
||||
public class MySessionListener implements HttpSessionListener
|
||||
{
|
||||
List<Integer> destroys;
|
||||
List<Integer> destroys = new ArrayList<>();
|
||||
|
||||
public void sessionCreated(HttpSessionEvent e)
|
||||
{
|
||||
|
@ -66,9 +66,6 @@ public abstract class AbstractSessionInvalidateAndCreateTest
|
|||
|
||||
public void sessionDestroyed(HttpSessionEvent e)
|
||||
{
|
||||
if (destroys == null)
|
||||
destroys = new ArrayList<>();
|
||||
|
||||
destroys.add(e.getSession().hashCode());
|
||||
}
|
||||
}
|
||||
|
@ -129,9 +126,9 @@ public abstract class AbstractSessionInvalidateAndCreateTest
|
|||
request2.header("Cookie", sessionCookie);
|
||||
ContentResponse response2 = request2.send();
|
||||
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
|
||||
|
||||
|
||||
// Wait for the scavenger to run
|
||||
pause(inactivePeriod+scavengePeriod);
|
||||
pause(inactivePeriod+(2*scavengePeriod));
|
||||
|
||||
//test that the session created in the last test is scavenged:
|
||||
//the HttpSessionListener should have been called when session1 was invalidated and session2 was scavenged
|
||||
|
@ -186,6 +183,7 @@ public abstract class AbstractSessionInvalidateAndCreateTest
|
|||
{
|
||||
HttpSession session = request.getSession(true);
|
||||
session.setAttribute("identity", "session1");
|
||||
session.setMaxInactiveInterval(-1); //don't let this session expire, we want to explicitly invalidate it
|
||||
}
|
||||
else if ("test".equals(action))
|
||||
{
|
||||
|
@ -196,7 +194,7 @@ public abstract class AbstractSessionInvalidateAndCreateTest
|
|||
|
||||
//invalidate existing session
|
||||
session.invalidate();
|
||||
|
||||
|
||||
//now try to access the invalid session
|
||||
try
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue