Merge remote-tracking branch 'origin/jetty-9.4.x'

This commit is contained in:
Jan Bartel 2016-05-19 16:32:11 +10:00
commit 6551d2c9a9
6 changed files with 49 additions and 43 deletions

View File

@ -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.
*/

View File

@ -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();

View File

@ -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
{

View File

@ -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);
}
/**

View File

@ -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);

View File

@ -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
{