Issue #3964 * Avoid creating listener list for rarely used requestAttributeListener * AbstractConnector keeps a specific list of HttpChannel.Listeners to avoid Connection.Listeners and MBean listeners being added to the HttpChannel listener list. * Simplified listener handling by avoiding null connector, previously only needed for testing. * Fixed test that assumed HttpChannel listeners were not cleared by a recycle * Separated out durable vs cyclic HttpChannel.Listeners, so as to simplify handling. * Deprecated cyclic HttpChannel.Listeners, as I'm not sure the channel is the right place for them. * Added improved method to combine multiple HttpChannel Listeners into a single Listener. * Fixed MockConnector * Added benchmark * Improved benchmark * Updates from review * Removed benchmark and alternate implementations. * Updated javadoc * Updates from review Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
1f189d4618
commit
83463c2a23
|
@ -25,6 +25,7 @@ import org.eclipse.jetty.http.HttpFields;
|
|||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.http.MetaData;
|
||||
import org.eclipse.jetty.server.AbstractConnector;
|
||||
import org.eclipse.jetty.server.Authentication;
|
||||
import org.eclipse.jetty.server.HttpChannel;
|
||||
import org.eclipse.jetty.server.HttpChannelState;
|
||||
|
@ -58,7 +59,7 @@ public class SpnegoAuthenticatorTest
|
|||
@Test
|
||||
public void testChallengeSentWithNoAuthorization() throws Exception
|
||||
{
|
||||
HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null)
|
||||
HttpChannel channel = new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
|
||||
{
|
||||
@Override
|
||||
public Server getServer()
|
||||
|
@ -94,7 +95,7 @@ public class SpnegoAuthenticatorTest
|
|||
@Test
|
||||
public void testChallengeSentWithUnhandledAuthorization() throws Exception
|
||||
{
|
||||
HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null)
|
||||
HttpChannel channel = new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
|
||||
{
|
||||
@Override
|
||||
public Server getServer()
|
||||
|
@ -162,4 +163,29 @@ public class SpnegoAuthenticatorTest
|
|||
assertEquals("negotiate", _authenticator.getAuthSchemeFromHeader(" negotiate asdfasdf"));
|
||||
assertEquals("negotiated", _authenticator.getAuthSchemeFromHeader(" negotiated asdfasdf"));
|
||||
}
|
||||
|
||||
class MockConnector extends AbstractConnector
|
||||
{
|
||||
public MockConnector()
|
||||
{
|
||||
super(new Server() , null, null, null, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept(int acceptorID) throws IOException, InterruptedException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTransport()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dumpSelf()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.eclipse.jetty.util.ProcessorUtils;
|
|||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.Container;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.component.Graceful;
|
||||
|
@ -154,6 +155,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
|||
private final Set<EndPoint> _endpoints = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
private final Set<EndPoint> _immutableEndPoints = Collections.unmodifiableSet(_endpoints);
|
||||
private final Graceful.Shutdown _shutdown = new Graceful.Shutdown();
|
||||
private HttpChannel.Listener _httpChannelListeners = HttpChannel.NOOP_LISTENER;
|
||||
private CountDownLatch _stopping;
|
||||
private long _idleTimeout = 30000;
|
||||
private String _defaultProtocol;
|
||||
|
@ -188,6 +190,23 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
|||
pool = _server.getBean(ByteBufferPool.class);
|
||||
_byteBufferPool = pool != null ? pool : new ArrayByteBufferPool();
|
||||
|
||||
addEventListener(new Container.Listener()
|
||||
{
|
||||
@Override
|
||||
public void beanAdded(Container parent, Object bean)
|
||||
{
|
||||
if (bean instanceof HttpChannel.Listener)
|
||||
_httpChannelListeners = new HttpChannelListeners(getBeans(HttpChannel.Listener.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beanRemoved(Container parent, Object bean)
|
||||
{
|
||||
if (bean instanceof HttpChannel.Listener)
|
||||
_httpChannelListeners = new HttpChannelListeners(getBeans(HttpChannel.Listener.class));
|
||||
}
|
||||
});
|
||||
|
||||
addBean(_server, false);
|
||||
addBean(_executor);
|
||||
if (executor == null)
|
||||
|
@ -208,6 +227,24 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
|||
_acceptors = new Thread[acceptors];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link HttpChannel.Listener}s added to the connector
|
||||
* as a single combined Listener.
|
||||
* This is equivalent to a listener that iterates over the individual
|
||||
* listeners returned from <code>getBeans(HttpChannel.Listener.class);</code>,
|
||||
* except that: <ul>
|
||||
* <li>The result is precomputed, so it is more efficient</li>
|
||||
* <li>The result is ordered by the order added.</li>
|
||||
* <li>The result is immutable.</li>
|
||||
* </ul>
|
||||
* @see #getBeans(Class)
|
||||
* @return An unmodifiable list of EventListener beans
|
||||
*/
|
||||
public HttpChannel.Listener getHttpChannelListeners()
|
||||
{
|
||||
return _httpChannelListeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Server getServer()
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
@ -69,6 +70,7 @@ import org.eclipse.jetty.util.thread.Scheduler;
|
|||
*/
|
||||
public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
||||
{
|
||||
public static Listener NOOP_LISTENER = new Listener(){};
|
||||
private static final Logger LOG = Log.getLogger(HttpChannel.class);
|
||||
|
||||
private final AtomicLong _requests = new AtomicLong();
|
||||
|
@ -80,9 +82,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
private final HttpChannelState _state;
|
||||
private final Request _request;
|
||||
private final Response _response;
|
||||
private final HttpChannel.Listener _combinedListener;
|
||||
@Deprecated
|
||||
private final List<Listener> _transientListeners = new ArrayList<>();
|
||||
private HttpFields _trailers;
|
||||
private final Supplier<HttpFields> _trailerSupplier = () -> _trailers;
|
||||
private final List<Listener> _listeners;
|
||||
private MetaData.Response _committedMetaData;
|
||||
private RequestLog _requestLog;
|
||||
private long _oldIdleTimeout;
|
||||
|
@ -103,13 +107,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
_request = new Request(this, newHttpInput(_state));
|
||||
_response = new Response(this, newHttpOutput());
|
||||
|
||||
_executor = connector == null ? null : connector.getServer().getThreadPool();
|
||||
_requestLog = connector == null ? null : connector.getServer().getRequestLog();
|
||||
|
||||
List<Listener> listeners = new ArrayList<>();
|
||||
if (connector != null)
|
||||
listeners.addAll(connector.getBeans(Listener.class));
|
||||
_listeners = listeners;
|
||||
_executor = connector.getServer().getThreadPool();
|
||||
_requestLog = connector.getServer().getRequestLog();
|
||||
_combinedListener = (connector instanceof AbstractConnector)
|
||||
? ((AbstractConnector)connector).getHttpChannelListeners()
|
||||
: NOOP_LISTENER;
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("new {} -> {},{},{}",
|
||||
|
@ -139,14 +141,32 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
return _state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a transient Listener to the HttpChannel.
|
||||
* <p>Listeners added by this method will only be notified
|
||||
* if the HttpChannel has been constructed with an instance of
|
||||
* {@link TransientListeners} as an {@link AbstractConnector}
|
||||
* provided listener</p>
|
||||
* <p>Transient listeners are removed after every request cycle</p>
|
||||
* @param listener
|
||||
* @return true if the listener was added.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean addListener(Listener listener)
|
||||
{
|
||||
return _listeners.add(listener);
|
||||
return _transientListeners.add(listener);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean removeListener(Listener listener)
|
||||
{
|
||||
return _listeners.remove(listener);
|
||||
return _transientListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public List<Listener> getTransientListeners()
|
||||
{
|
||||
return _transientListeners;
|
||||
}
|
||||
|
||||
public long getBytesWritten()
|
||||
|
@ -294,6 +314,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
_written = 0;
|
||||
_trailers = null;
|
||||
_oldIdleTimeout = 0;
|
||||
_transientListeners.clear();
|
||||
}
|
||||
|
||||
public void onAsyncWaitForContent()
|
||||
|
@ -535,17 +556,17 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
try
|
||||
{
|
||||
_request.setDispatcherType(type);
|
||||
notifyBeforeDispatch(_request);
|
||||
_combinedListener.onBeforeDispatch(_request);
|
||||
dispatchable.dispatch();
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
notifyDispatchFailure(_request, x);
|
||||
_combinedListener.onDispatchFailure(_request, x);
|
||||
throw x;
|
||||
}
|
||||
finally
|
||||
{
|
||||
notifyAfterDispatch(_request);
|
||||
_combinedListener.onAfterDispatch(_request);
|
||||
_request.setDispatcherType(null);
|
||||
}
|
||||
}
|
||||
|
@ -668,7 +689,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
|
||||
_request.setSecure(HttpScheme.HTTPS.is(request.getURI().getScheme()));
|
||||
|
||||
notifyRequestBegin(_request);
|
||||
_combinedListener.onRequestBegin(_request);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("REQUEST for {} on {}{}{} {} {}{}{}", request.getURIString(), this, System.lineSeparator(),
|
||||
|
@ -680,7 +701,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("onContent {} {}", this, content);
|
||||
notifyRequestContent(_request, content.getByteBuffer());
|
||||
_combinedListener.onRequestContent(_request, content.getByteBuffer());
|
||||
return _request.getHttpInput().addContent(content);
|
||||
}
|
||||
|
||||
|
@ -688,7 +709,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("onContentComplete {}", this);
|
||||
notifyRequestContentEnd(_request);
|
||||
_combinedListener.onRequestContentEnd(_request);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -697,7 +718,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("onTrailers {} {}", this, trailers);
|
||||
_trailers = trailers;
|
||||
notifyRequestTrailers(_request);
|
||||
_combinedListener.onRequestTrailers(_request);
|
||||
}
|
||||
|
||||
public boolean onRequestComplete()
|
||||
|
@ -705,7 +726,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("onRequestComplete {}", this);
|
||||
boolean result = _request.getHttpInput().eof();
|
||||
notifyRequestEnd(_request);
|
||||
_combinedListener.onRequestEnd(_request);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -722,7 +743,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
setIdleTimeout(_oldIdleTimeout);
|
||||
|
||||
_request.onCompleted();
|
||||
notifyComplete(_request);
|
||||
_combinedListener.onComplete(_request);
|
||||
_transport.onCompleted();
|
||||
}
|
||||
|
||||
|
@ -738,7 +759,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
if (status < HttpStatus.BAD_REQUEST_400 || status > 599)
|
||||
failure = new BadMessageException(HttpStatus.BAD_REQUEST_400, reason, failure);
|
||||
|
||||
notifyRequestFailure(_request, failure);
|
||||
_combinedListener.onRequestFailure(_request, failure);
|
||||
|
||||
Action action;
|
||||
try
|
||||
|
@ -810,7 +831,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
? new Send100Callback(callback)
|
||||
: new SendCallback(callback, content, true, complete);
|
||||
|
||||
notifyResponseBegin(_request);
|
||||
_combinedListener.onResponseBegin(_request);
|
||||
|
||||
// committing write
|
||||
_transport.send(info, _request.isHead(), content, complete, committed);
|
||||
|
@ -936,89 +957,14 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
{
|
||||
if (_state.abortResponse())
|
||||
{
|
||||
notifyResponseFailure(_request, failure);
|
||||
_combinedListener.onResponseFailure(_request, failure);
|
||||
_transport.abort(failure);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyRequestBegin(Request request)
|
||||
{
|
||||
notifyEvent1(listener -> listener::onRequestBegin, request);
|
||||
}
|
||||
|
||||
private void notifyBeforeDispatch(Request request)
|
||||
{
|
||||
notifyEvent1(listener -> listener::onBeforeDispatch, request);
|
||||
}
|
||||
|
||||
private void notifyDispatchFailure(Request request, Throwable failure)
|
||||
{
|
||||
notifyEvent2(listener -> listener::onDispatchFailure, request, failure);
|
||||
}
|
||||
|
||||
private void notifyAfterDispatch(Request request)
|
||||
{
|
||||
notifyEvent1(listener -> listener::onAfterDispatch, request);
|
||||
}
|
||||
|
||||
private void notifyRequestContent(Request request, ByteBuffer content)
|
||||
{
|
||||
notifyEvent2(listener -> listener::onRequestContent, request, content);
|
||||
}
|
||||
|
||||
private void notifyRequestContentEnd(Request request)
|
||||
{
|
||||
notifyEvent1(listener -> listener::onRequestContentEnd, request);
|
||||
}
|
||||
|
||||
private void notifyRequestTrailers(Request request)
|
||||
{
|
||||
notifyEvent1(listener -> listener::onRequestTrailers, request);
|
||||
}
|
||||
|
||||
private void notifyRequestEnd(Request request)
|
||||
{
|
||||
notifyEvent1(listener -> listener::onRequestEnd, request);
|
||||
}
|
||||
|
||||
private void notifyRequestFailure(Request request, Throwable failure)
|
||||
{
|
||||
notifyEvent2(listener -> listener::onRequestFailure, request, failure);
|
||||
}
|
||||
|
||||
private void notifyResponseBegin(Request request)
|
||||
{
|
||||
notifyEvent1(listener -> listener::onResponseBegin, request);
|
||||
}
|
||||
|
||||
private void notifyResponseCommit(Request request)
|
||||
{
|
||||
notifyEvent1(listener -> listener::onResponseCommit, request);
|
||||
}
|
||||
|
||||
private void notifyResponseContent(Request request, ByteBuffer content)
|
||||
{
|
||||
notifyEvent2(listener -> listener::onResponseContent, request, content);
|
||||
}
|
||||
|
||||
private void notifyResponseEnd(Request request)
|
||||
{
|
||||
notifyEvent1(listener -> listener::onResponseEnd, request);
|
||||
}
|
||||
|
||||
private void notifyResponseFailure(Request request, Throwable failure)
|
||||
{
|
||||
notifyEvent2(listener -> listener::onResponseFailure, request, failure);
|
||||
}
|
||||
|
||||
private void notifyComplete(Request request)
|
||||
{
|
||||
notifyEvent1(listener -> listener::onComplete, request);
|
||||
}
|
||||
|
||||
private void notifyEvent1(Function<Listener, Consumer<Request>> function, Request request)
|
||||
{
|
||||
for (Listener listener : _listeners)
|
||||
for (Listener listener : _transientListeners)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -1033,7 +979,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
|
||||
private void notifyEvent2(Function<Listener, BiConsumer<Request, ByteBuffer>> function, Request request, ByteBuffer content)
|
||||
{
|
||||
for (Listener listener : _listeners)
|
||||
for (Listener listener : _transientListeners)
|
||||
{
|
||||
ByteBuffer view = content.slice();
|
||||
try
|
||||
|
@ -1049,7 +995,7 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
|
||||
private void notifyEvent2(Function<Listener, BiConsumer<Request, Throwable>> function, Request request, Throwable failure)
|
||||
{
|
||||
for (Listener listener : _listeners)
|
||||
for (Listener listener : _transientListeners)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -1085,8 +1031,13 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
* <p>Listener methods are invoked synchronously from the thread that is
|
||||
* performing the request processing, and they should not call blocking code
|
||||
* (otherwise the request processing will be blocked as well).</p>
|
||||
* <p>Listener instances that are set as a bean on the {@link Connector} are
|
||||
* efficiently added to {@link HttpChannel}. If additional listeners are added
|
||||
* using the deprecated {@link HttpChannel#addListener(Listener)}</p> method,
|
||||
* then an instance of {@link TransientListeners} must be added to the connector
|
||||
* in order for them to be invoked.
|
||||
*/
|
||||
public interface Listener
|
||||
public interface Listener extends EventListener
|
||||
{
|
||||
/**
|
||||
* Invoked just after the HTTP request line and headers have been parsed.
|
||||
|
@ -1256,11 +1207,11 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
_response.getHttpOutput().closed();
|
||||
super.succeeded();
|
||||
if (_commit)
|
||||
notifyResponseCommit(_request);
|
||||
_combinedListener.onResponseCommit(_request);
|
||||
if (_length > 0)
|
||||
notifyResponseContent(_request, _content);
|
||||
_combinedListener.onResponseContent(_request, _content);
|
||||
if (_complete && _state.completeResponse())
|
||||
notifyResponseEnd(_request);
|
||||
_combinedListener.onResponseEnd(_request);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1313,4 +1264,102 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
super.failed(new IllegalStateException());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Listener instance that can be added as a bean to {@link AbstractConnector} so that
|
||||
* the listeners obtained from HttpChannel{@link #getTransientListeners()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static class TransientListeners implements Listener
|
||||
{
|
||||
@Override
|
||||
public void onRequestBegin(Request request)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent1(listener -> listener::onRequestBegin, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeDispatch(Request request)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent1(listener -> listener::onBeforeDispatch, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDispatchFailure(Request request, Throwable failure)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent2(listener -> listener::onDispatchFailure, request, failure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAfterDispatch(Request request)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent1(listener -> listener::onAfterDispatch, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestContent(Request request, ByteBuffer content)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent2(listener -> listener::onRequestContent, request, content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestContentEnd(Request request)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent1(listener -> listener::onRequestContentEnd, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestTrailers(Request request)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent1(listener -> listener::onRequestTrailers, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestEnd(Request request)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent1(listener -> listener::onRequestEnd, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestFailure(Request request, Throwable failure)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent2(listener -> listener::onRequestFailure, request, failure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponseBegin(Request request)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent1(listener -> listener::onResponseBegin, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponseCommit(Request request)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent1(listener -> listener::onResponseCommit, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponseContent(Request request, ByteBuffer content)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent2(listener -> listener::onResponseContent, request, content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponseEnd(Request request)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent1(listener -> listener::onResponseEnd, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponseFailure(Request request, Throwable failure)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent2(listener -> listener::onResponseFailure, request, failure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(Request request)
|
||||
{
|
||||
request.getHttpChannel().notifyEvent1(listener -> listener::onComplete, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,286 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
* A {@link HttpChannel.Listener} that holds a collection of
|
||||
* other {@link HttpChannel.Listener} instances that are efficiently
|
||||
* invoked without iteration.
|
||||
* @see AbstractConnector
|
||||
*/
|
||||
public class HttpChannelListeners implements HttpChannel.Listener
|
||||
{
|
||||
static final Logger LOG = Log.getLogger(HttpChannel.class);
|
||||
public static HttpChannel.Listener NOOP = new HttpChannel.Listener() {};
|
||||
|
||||
private final NotifyRequest onRequestBegin;
|
||||
private final NotifyRequest onBeforeDispatch;
|
||||
private final NotifyFailure onDispatchFailure;
|
||||
private final NotifyRequest onAfterDispatch;
|
||||
private final NotifyContent onRequestContent;
|
||||
private final NotifyRequest onRequestContentEnd;
|
||||
private final NotifyRequest onRequestTrailers;
|
||||
private final NotifyRequest onRequestEnd;
|
||||
private final NotifyFailure onRequestFailure;
|
||||
private final NotifyRequest onResponseBegin;
|
||||
private final NotifyRequest onResponseCommit;
|
||||
private final NotifyContent onResponseContent;
|
||||
private final NotifyRequest onResponseEnd;
|
||||
private final NotifyFailure onResponseFailure;
|
||||
private final NotifyRequest onComplete;
|
||||
|
||||
public HttpChannelListeners(Collection<HttpChannel.Listener> listeners)
|
||||
{
|
||||
try
|
||||
{
|
||||
NotifyRequest onRequestBegin = NotifyRequest.NOOP;
|
||||
NotifyRequest onBeforeDispatch = NotifyRequest.NOOP;
|
||||
NotifyFailure onDispatchFailure = NotifyFailure.NOOP;
|
||||
NotifyRequest onAfterDispatch = NotifyRequest.NOOP;
|
||||
NotifyContent onRequestContent = NotifyContent.NOOP;
|
||||
NotifyRequest onRequestContentEnd = NotifyRequest.NOOP;
|
||||
NotifyRequest onRequestTrailers = NotifyRequest.NOOP;
|
||||
NotifyRequest onRequestEnd = NotifyRequest.NOOP;
|
||||
NotifyFailure onRequestFailure = NotifyFailure.NOOP;
|
||||
NotifyRequest onResponseBegin = NotifyRequest.NOOP;
|
||||
NotifyRequest onResponseCommit = NotifyRequest.NOOP;
|
||||
NotifyContent onResponseContent = NotifyContent.NOOP;
|
||||
NotifyRequest onResponseEnd = NotifyRequest.NOOP;
|
||||
NotifyFailure onResponseFailure = NotifyFailure.NOOP;
|
||||
NotifyRequest onComplete = NotifyRequest.NOOP;
|
||||
|
||||
for (HttpChannel.Listener listener : listeners)
|
||||
{
|
||||
if (!listener.getClass().getMethod("onRequestBegin", Request.class).isDefault())
|
||||
onRequestBegin = combine(onRequestBegin, listener::onRequestBegin);
|
||||
if (!listener.getClass().getMethod("onBeforeDispatch", Request.class).isDefault())
|
||||
onBeforeDispatch = combine(onBeforeDispatch, listener::onBeforeDispatch);
|
||||
if (!listener.getClass().getMethod("onDispatchFailure", Request.class, Throwable.class).isDefault())
|
||||
onDispatchFailure = combine(onDispatchFailure, listener::onDispatchFailure);
|
||||
if (!listener.getClass().getMethod("onAfterDispatch", Request.class).isDefault())
|
||||
onAfterDispatch = combine(onAfterDispatch, listener::onAfterDispatch);
|
||||
if (!listener.getClass().getMethod("onRequestContent", Request.class, ByteBuffer.class).isDefault())
|
||||
onRequestContent = combine(onRequestContent, listener::onRequestContent);
|
||||
if (!listener.getClass().getMethod("onRequestContentEnd", Request.class).isDefault())
|
||||
onRequestContentEnd = combine(onRequestContentEnd, listener::onRequestContentEnd);
|
||||
if (!listener.getClass().getMethod("onRequestTrailers", Request.class).isDefault())
|
||||
onRequestTrailers = combine(onRequestTrailers, listener::onRequestTrailers);
|
||||
if (!listener.getClass().getMethod("onRequestEnd", Request.class).isDefault())
|
||||
onRequestEnd = combine(onRequestEnd, listener::onRequestEnd);
|
||||
if (!listener.getClass().getMethod("onRequestFailure", Request.class, Throwable.class).isDefault())
|
||||
onRequestFailure = combine(onRequestFailure, listener::onRequestFailure);
|
||||
if (!listener.getClass().getMethod("onResponseBegin", Request.class).isDefault())
|
||||
onResponseBegin = combine(onResponseBegin, listener::onResponseBegin);
|
||||
if (!listener.getClass().getMethod("onResponseCommit", Request.class).isDefault())
|
||||
onResponseCommit = combine(onResponseCommit, listener::onResponseCommit);
|
||||
if (!listener.getClass().getMethod("onResponseContent", Request.class, ByteBuffer.class).isDefault())
|
||||
onResponseContent = combine(onResponseContent, listener::onResponseContent);
|
||||
if (!listener.getClass().getMethod("onResponseEnd", Request.class).isDefault())
|
||||
onResponseEnd = combine(onResponseEnd, listener::onResponseEnd);
|
||||
if (!listener.getClass().getMethod("onResponseFailure", Request.class, Throwable.class).isDefault())
|
||||
onResponseFailure = combine(onResponseFailure, listener::onResponseFailure);
|
||||
if (!listener.getClass().getMethod("onComplete", Request.class).isDefault())
|
||||
onComplete = combine(onComplete, listener::onComplete);
|
||||
}
|
||||
|
||||
this.onRequestBegin = onRequestBegin;
|
||||
this.onBeforeDispatch = onBeforeDispatch;
|
||||
this.onDispatchFailure = onDispatchFailure;
|
||||
this.onAfterDispatch = onAfterDispatch;
|
||||
this.onRequestContent = onRequestContent;
|
||||
this.onRequestContentEnd = onRequestContentEnd;
|
||||
this.onRequestTrailers = onRequestTrailers;
|
||||
this.onRequestEnd = onRequestEnd;
|
||||
this.onRequestFailure = onRequestFailure;
|
||||
this.onResponseBegin = onResponseBegin;
|
||||
this.onResponseCommit = onResponseCommit;
|
||||
this.onResponseContent = onResponseContent;
|
||||
this.onResponseEnd = onResponseEnd;
|
||||
this.onResponseFailure = onResponseFailure;
|
||||
this.onComplete = onComplete;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestBegin(Request request)
|
||||
{
|
||||
onRequestBegin.onRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeDispatch(Request request)
|
||||
{
|
||||
onBeforeDispatch.onRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDispatchFailure(Request request, Throwable failure)
|
||||
{
|
||||
onDispatchFailure.onFailure(request, failure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAfterDispatch(Request request)
|
||||
{
|
||||
onAfterDispatch.onRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestContent(Request request, ByteBuffer content)
|
||||
{
|
||||
onRequestContent.onContent(request, content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestContentEnd(Request request)
|
||||
{
|
||||
onRequestContentEnd.onRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestTrailers(Request request)
|
||||
{
|
||||
onRequestTrailers.onRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestEnd(Request request)
|
||||
{
|
||||
onRequestEnd.onRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestFailure(Request request, Throwable failure)
|
||||
{
|
||||
onRequestFailure.onFailure(request, failure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponseBegin(Request request)
|
||||
{
|
||||
onResponseBegin.onRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponseCommit(Request request)
|
||||
{
|
||||
onResponseCommit.onRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponseContent(Request request, ByteBuffer content)
|
||||
{
|
||||
onResponseContent.onContent(request, content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponseEnd(Request request)
|
||||
{
|
||||
onResponseEnd.onRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponseFailure(Request request, Throwable failure)
|
||||
{
|
||||
onResponseFailure.onFailure(request, failure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(Request request)
|
||||
{
|
||||
onComplete.onRequest(request);
|
||||
}
|
||||
|
||||
private interface NotifyRequest
|
||||
{
|
||||
void onRequest(Request request);
|
||||
|
||||
NotifyRequest NOOP = request ->
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
private interface NotifyFailure
|
||||
{
|
||||
void onFailure(Request request, Throwable failure);
|
||||
|
||||
NotifyFailure NOOP = (request, failure) ->
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
private interface NotifyContent
|
||||
{
|
||||
void onContent(Request request, ByteBuffer content);
|
||||
|
||||
NotifyContent NOOP = (request, content) ->
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
private static NotifyRequest combine(NotifyRequest first, NotifyRequest second)
|
||||
{
|
||||
if (first == NotifyRequest.NOOP)
|
||||
return second;
|
||||
if (second == NotifyRequest.NOOP)
|
||||
return first;
|
||||
return request ->
|
||||
{
|
||||
first.onRequest(request);
|
||||
second.onRequest(request);
|
||||
};
|
||||
}
|
||||
|
||||
private static NotifyFailure combine(NotifyFailure first, NotifyFailure second)
|
||||
{
|
||||
if (first == NotifyFailure.NOOP)
|
||||
return second;
|
||||
if (second == NotifyFailure.NOOP)
|
||||
return first;
|
||||
return (request, throwable) ->
|
||||
{
|
||||
first.onFailure(request, throwable);
|
||||
second.onFailure(request, throwable);
|
||||
};
|
||||
}
|
||||
|
||||
private static NotifyContent combine(NotifyContent first, NotifyContent second)
|
||||
{
|
||||
if (first == NotifyContent.NOOP)
|
||||
return (request, content) -> second.onContent(request, content.slice());
|
||||
if (second == NotifyContent.NOOP)
|
||||
return (request, content) -> first.onContent(request, content.slice());
|
||||
return (request, content) ->
|
||||
{
|
||||
content = content.slice();
|
||||
first.onContent(request, content);
|
||||
second.onContent(request, content);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1873,6 +1873,7 @@ public class Request implements HttpServletRequest
|
|||
_remote = null;
|
||||
_sessions = null;
|
||||
_input.recycle();
|
||||
_requestAttributeListeners.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -240,6 +240,37 @@ public class HttpChannelEventTest
|
|||
assertThat(elapsed.get(), Matchers.greaterThan(0L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransientListener() throws Exception
|
||||
{
|
||||
start(new TestHandler());
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
connector.addBean(new HttpChannel.TransientListeners());
|
||||
connector.addBean(new HttpChannel.Listener()
|
||||
{
|
||||
@Override
|
||||
public void onRequestBegin(Request request)
|
||||
{
|
||||
request.getHttpChannel().addListener(new HttpChannel.Listener()
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Request request)
|
||||
{
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
HttpTester.Request request = HttpTester.newRequest();
|
||||
request.setHeader("Host", "localhost");
|
||||
HttpTester.Response response = HttpTester.parseResponse(connector.getResponse(request.toString(), 5, TimeUnit.SECONDS));
|
||||
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
private static class TestHandler extends AbstractHandler.ErrorDispatchHandler
|
||||
{
|
||||
@Override
|
||||
|
|
|
@ -95,7 +95,7 @@ public class HttpInputAsyncStateTest
|
|||
public void before()
|
||||
{
|
||||
_noReadInDataAvailable = false;
|
||||
_in = new HttpInput(new HttpChannelState(new HttpChannel(null, new HttpConfiguration(), null, null)
|
||||
_in = new HttpInput(new HttpChannelState(new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
|
||||
{
|
||||
@Override
|
||||
public void onAsyncWaitForContent()
|
||||
|
|
|
@ -92,7 +92,7 @@ public class HttpInputTest
|
|||
@BeforeEach
|
||||
public void before()
|
||||
{
|
||||
_in = new HttpInput(new HttpChannelState(new HttpChannel(null, new HttpConfiguration(), null, null)
|
||||
_in = new HttpInput(new HttpChannelState(new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
|
||||
{
|
||||
@Override
|
||||
public void onAsyncWaitForContent()
|
||||
|
|
|
@ -45,7 +45,7 @@ public class HttpWriterTest
|
|||
|
||||
final ByteBufferPool pool = new ArrayByteBufferPool();
|
||||
|
||||
HttpChannel channel = new HttpChannel(null, new HttpConfiguration(), null, null)
|
||||
HttpChannel channel = new HttpChannel(new MockConnector(), new HttpConfiguration(), null, null)
|
||||
{
|
||||
@Override
|
||||
public ByteBufferPool getByteBufferPool()
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class MockConnector extends AbstractConnector
|
||||
{
|
||||
public MockConnector()
|
||||
{
|
||||
super(new Server() , null, null, null, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept(int acceptorID) throws IOException, InterruptedException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTransport()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dumpSelf()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -43,7 +43,7 @@ public interface Container
|
|||
/**
|
||||
* @param clazz the class of the beans
|
||||
* @param <T> the Bean type
|
||||
* @return the list of beans of the given class (or subclass)
|
||||
* @return a list of beans of the given class (or subclass)
|
||||
* @see #getBeans()
|
||||
* @see #getContainedBeans(Class)
|
||||
*/
|
||||
|
|
|
@ -65,8 +65,8 @@ public abstract class AbstractClusteredInvalidationSessionTest extends AbstractT
|
|||
TestServer server1 = new TestServer(0, maxInactiveInterval, scavengeInterval, cacheFactory1, storeFactory1);
|
||||
ServletContextHandler context = server1.addContext(contextPath);
|
||||
context.addServlet(TestServlet.class, servletMapping);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
context.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server1.getServerConnector().addBean(scopeListener);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -77,8 +77,8 @@ public abstract class AbstractClusteredSessionScavengingTest extends AbstractTes
|
|||
TestServlet servlet1 = new TestServlet();
|
||||
ServletHolder holder1 = new ServletHolder(servlet1);
|
||||
ServletContextHandler context = server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
context.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server1.getServerConnector().addBean(scopeListener);
|
||||
TestSessionListener listener1 = new TestSessionListener();
|
||||
context.getSessionHandler().addEventListener(listener1);
|
||||
context.addServlet(holder1, servletMapping);
|
||||
|
@ -96,8 +96,8 @@ public abstract class AbstractClusteredSessionScavengingTest extends AbstractTes
|
|||
((AbstractSessionDataStoreFactory)storeFactory2).setSavePeriodSec(0); //always save when the session exits
|
||||
TestServer server2 = new TestServer(0, maxInactivePeriod, scavengePeriod, cacheFactory2, storeFactory2);
|
||||
ServletContextHandler context2 = server2.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener2 = new TestContextScopeListener();
|
||||
context2.addEventListener(scopeListener2);
|
||||
TestHttpChannelCompleteListener scopeListener2 = new TestHttpChannelCompleteListener();
|
||||
server2.getServerConnector().addBean(scopeListener2);
|
||||
context2.addServlet(TestServlet.class, servletMapping);
|
||||
SessionHandler m2 = context2.getSessionHandler();
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.io.FileOutputStream;
|
|||
import java.io.FileWriter;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
|
@ -103,8 +102,8 @@ public abstract class AbstractWebAppObjectInSessionTest extends AbstractTestBase
|
|||
TestServer server1 = new TestServer(0, TestServer.DEFAULT_MAX_INACTIVE, TestServer.DEFAULT_SCAVENGE_SEC,
|
||||
cacheFactory, storeFactory);
|
||||
WebAppContext wac1 = server1.addWebAppContext(warDir.getCanonicalPath(), contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
wac1.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server1.getServerConnector().addBean(scopeListener);
|
||||
wac1.addServlet(WebAppObjectInSessionServlet.class.getName(), servletMapping);
|
||||
|
||||
try
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.server.HttpChannel.Listener;
|
||||
import org.eclipse.jetty.server.HttpChannelState;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler.ContextScopeListener;
|
||||
|
||||
public class TestContextScopeListener implements ContextScopeListener
|
||||
{
|
||||
AtomicReference<CountDownLatch> _exitSynchronizer = new AtomicReference<>();
|
||||
boolean listenerAdded = false;
|
||||
|
||||
/**
|
||||
* @return the exitSynchronizer
|
||||
*/
|
||||
public CountDownLatch getExitSynchronizer()
|
||||
{
|
||||
return _exitSynchronizer.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param exitSynchronizer the exitSynchronizer to set
|
||||
*/
|
||||
public void setExitSynchronizer(CountDownLatch exitSynchronizer)
|
||||
{
|
||||
_exitSynchronizer.set(exitSynchronizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterScope(Context context, org.eclipse.jetty.server.Request request, Object reason)
|
||||
{
|
||||
//noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitScope(final Context context, final org.eclipse.jetty.server.Request request)
|
||||
{
|
||||
if (request != null && !listenerAdded)
|
||||
{
|
||||
listenerAdded = true;
|
||||
request.getHttpChannel().addListener(new Listener()
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Request request)
|
||||
{
|
||||
Listener.super.onComplete(request);
|
||||
if (_exitSynchronizer.get() != null)
|
||||
_exitSynchronizer.get().countDown();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.server.HttpChannel.Listener;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
|
||||
public class TestHttpChannelCompleteListener implements Listener
|
||||
{
|
||||
private final AtomicReference<CountDownLatch> _exitSynchronizer = new AtomicReference<>();
|
||||
|
||||
/**
|
||||
* @param exitSynchronizer the exitSynchronizer to set
|
||||
*/
|
||||
public void setExitSynchronizer(CountDownLatch exitSynchronizer)
|
||||
{
|
||||
_exitSynchronizer.set(exitSynchronizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(Request request)
|
||||
{
|
||||
if (_exitSynchronizer.get() != null)
|
||||
_exitSynchronizer.get().countDown();
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.server.session;
|
|||
|
||||
import org.eclipse.jetty.server.NetworkConnector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.SessionIdManager;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
|
@ -93,6 +94,11 @@ public class TestServer
|
|||
return h;
|
||||
}
|
||||
|
||||
public ServerConnector getServerConnector()
|
||||
{
|
||||
return _server.getBean(ServerConnector.class);
|
||||
}
|
||||
|
||||
public void start() throws Exception
|
||||
{
|
||||
// server -> contexts collection -> context handler -> session handler -> servlet handler
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.io.IOException;
|
|||
import java.lang.reflect.Proxy;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
|
@ -65,8 +64,8 @@ public class AsyncTest
|
|||
String mapping = "/server";
|
||||
|
||||
ServletContextHandler contextHandler = server.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server.getServerConnector().addBean(scopeListener);
|
||||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
contextHandler.addServlet(holder, mapping);
|
||||
|
@ -117,8 +116,8 @@ public class AsyncTest
|
|||
String mapping = "/server";
|
||||
|
||||
ServletContextHandler contextHandler = server.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server.getServerConnector().addBean(scopeListener);
|
||||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
contextHandler.addServlet(holder, mapping);
|
||||
|
@ -167,8 +166,8 @@ public class AsyncTest
|
|||
TestServer server = new TestServer(0, -1, -1, cacheFactory, storeFactory);
|
||||
|
||||
ServletContextHandler contextA = server.addContext("/ctxA");
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextA.addEventListener(scopeListener); //just pick one of the contexts to register the listener
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server.getServerConnector().addBean(scopeListener); //just pick one of the contexts to register the listener
|
||||
CrossContextServlet ccServlet = new CrossContextServlet();
|
||||
ServletHolder ccHolder = new ServletHolder(ccServlet);
|
||||
contextA.addServlet(ccHolder, "/*");
|
||||
|
@ -224,8 +223,8 @@ public class AsyncTest
|
|||
String mapping = "/server";
|
||||
|
||||
ServletContextHandler contextHandler = server.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server.getServerConnector().addBean(scopeListener);
|
||||
|
||||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
|
@ -277,8 +276,8 @@ public class AsyncTest
|
|||
TestServer server = new TestServer(0, -1, -1, cacheFactory, storeFactory);
|
||||
|
||||
ServletContextHandler contextA = server.addContext("/ctxA");
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextA.addEventListener(scopeListener); //just pick a context
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server.getServerConnector().addBean(scopeListener);
|
||||
CrossContextServlet ccServlet = new CrossContextServlet();
|
||||
ServletHolder ccHolder = new ServletHolder(ccServlet);
|
||||
contextA.addServlet(ccHolder, "/*");
|
||||
|
|
|
@ -76,8 +76,8 @@ public class CreationTest
|
|||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
ServletContextHandler contextHandler = server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
|
||||
server1.start();
|
||||
|
@ -145,8 +145,8 @@ public class CreationTest
|
|||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
ServletContextHandler contextHandler = server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
|
||||
server1.start();
|
||||
|
@ -197,8 +197,8 @@ public class CreationTest
|
|||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
ServletContextHandler contextHandler = server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
|
||||
server1.start();
|
||||
|
@ -245,8 +245,8 @@ public class CreationTest
|
|||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
ServletContextHandler contextHandler = server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
|
||||
server1.start();
|
||||
|
@ -299,8 +299,8 @@ public class CreationTest
|
|||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
ServletContextHandler contextHandler = server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
ServletContextHandler ctxB = server1.addContext(contextB);
|
||||
ctxB.addServlet(TestServletB.class, servletMapping);
|
||||
|
@ -354,8 +354,8 @@ public class CreationTest
|
|||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
ServletContextHandler contextHandler = server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
ServletContextHandler ctxB = server1.addContext(contextB);
|
||||
ctxB.addServlet(TestServletB.class, servletMapping);
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.util.Collections;
|
|||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.http.HttpSessionActivationListener;
|
||||
import javax.servlet.http.HttpSessionEvent;
|
||||
|
@ -79,8 +78,8 @@ public class DefaultSessionCacheTest
|
|||
SessionDataStoreFactory storeFactory = new TestSessionDataStoreFactory();
|
||||
TestServer server = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
|
||||
ServletContextHandler contextHandler = server.addContext("/test");
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server.getServerConnector().addBean(scopeListener);
|
||||
|
||||
TestHttpSessionListener listener = new TestHttpSessionListener();
|
||||
contextHandler.getSessionHandler().addEventListener(listener);
|
||||
|
|
|
@ -151,8 +151,8 @@ public class DeleteUnloadableSessionTest
|
|||
TestServer server = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
|
||||
ServletContextHandler context = server.addContext(contextPath);
|
||||
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
context.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server.getServerConnector().addBean(scopeListener);
|
||||
|
||||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
|
|
|
@ -94,8 +94,8 @@ public class DirtyAttributeTest
|
|||
ServletContextHandler ctxA = server.addContext("/mod");
|
||||
ctxA.addServlet(TestDirtyServlet.class, "/test");
|
||||
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
ctxA.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server.getServerConnector().addBean(scopeListener);
|
||||
|
||||
server.start();
|
||||
int port = server.getPort();
|
||||
|
@ -125,15 +125,13 @@ public class DirtyAttributeTest
|
|||
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
|
||||
|
||||
//ensure request fully finished processing
|
||||
latch.await(5, TimeUnit.SECONDS);
|
||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
A_VALUE.assertPassivatesEquals(1);
|
||||
A_VALUE.assertActivatesEquals(1);
|
||||
A_VALUE.assertBindsEquals(1);
|
||||
A_VALUE.assertUnbindsEquals(0);
|
||||
|
||||
|
||||
|
||||
//do another request using the cookie to try changing the session attribute to the same value again
|
||||
latch = new CountDownLatch(1);
|
||||
scopeListener.setExitSynchronizer(latch);
|
||||
|
|
|
@ -76,8 +76,8 @@ public class IdleSessionTest
|
|||
_server1 = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
|
||||
ServletHolder holder = new ServletHolder(_servlet);
|
||||
ServletContextHandler contextHandler = _server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
_server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
_server1.start();
|
||||
int port1 = _server1.getPort();
|
||||
|
@ -202,8 +202,8 @@ public class IdleSessionTest
|
|||
_server1 = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
|
||||
ServletHolder holder = new ServletHolder(_servlet);
|
||||
ServletContextHandler contextHandler = _server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
_server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
_server1.start();
|
||||
int port1 = _server1.getPort();
|
||||
|
|
|
@ -75,8 +75,8 @@ public class NonClusteredSessionScavengingTest extends AbstractTestBase
|
|||
context1.addServlet(TestServlet.class, servletMapping);
|
||||
TestHttpSessionListener listener = new TestHttpSessionListener();
|
||||
context1.getSessionHandler().addEventListener(listener);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
context1.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server1.getServerConnector().addBean(scopeListener);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -144,8 +144,8 @@ public class NonClusteredSessionScavengingTest extends AbstractTestBase
|
|||
TestServer server = new TestServer(0, maxInactivePeriod, scavengePeriod,
|
||||
cacheFactory, storeFactory);
|
||||
ServletContextHandler context = server.addContext("/");
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
context.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server.getServerConnector().addBean(scopeListener);
|
||||
_dataStore = context.getSessionHandler().getSessionCache().getSessionDataStore();
|
||||
|
||||
context.addServlet(TestServlet.class, servletMapping);
|
||||
|
@ -208,8 +208,8 @@ public class NonClusteredSessionScavengingTest extends AbstractTestBase
|
|||
TestServer server = new TestServer(0, maxInactivePeriod, scavengePeriod,
|
||||
cacheFactory, storeFactory);
|
||||
ServletContextHandler context = server.addContext("/");
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
context.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server.getServerConnector().addBean(scopeListener);
|
||||
_dataStore = context.getSessionHandler().getSessionCache().getSessionDataStore();
|
||||
context.addServlet(TestServlet.class, servletMapping);
|
||||
String contextPath = "/";
|
||||
|
|
|
@ -59,8 +59,8 @@ public class ReentrantRequestSessionTest
|
|||
ServletContextHandler context = server.addContext(contextPath);
|
||||
context.addServlet(TestServlet.class, servletMapping);
|
||||
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
context.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
server.getServerConnector().addBean(scopeListener);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -58,8 +58,8 @@ public class SameContextForwardedSessionTest
|
|||
TestServer testServer = new TestServer(0, -1, -1, cacheFactory, storeFactory);
|
||||
|
||||
ServletContextHandler testServletContextHandler = testServer.addContext("/context");
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
testServletContextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
testServer.getServerConnector().addBean(scopeListener);
|
||||
ServletHolder holder = new ServletHolder(new Servlet1());
|
||||
testServletContextHandler.addServlet(holder, "/one");
|
||||
testServletContextHandler.addServlet(Servlet2.class, "/two");
|
||||
|
|
|
@ -124,8 +124,8 @@ public class SaveOptimizeTest
|
|||
_servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(_servlet);
|
||||
ServletContextHandler contextHandler = _server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
_server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
_servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
|
||||
_server1.start();
|
||||
|
@ -207,8 +207,8 @@ public class SaveOptimizeTest
|
|||
_servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(_servlet);
|
||||
ServletContextHandler contextHandler = _server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
_server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
_servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
|
||||
_server1.start();
|
||||
|
@ -297,8 +297,8 @@ public class SaveOptimizeTest
|
|||
_servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(_servlet);
|
||||
ServletContextHandler contextHandler = _server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
_server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
_servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
|
||||
_server1.start();
|
||||
|
@ -392,8 +392,8 @@ public class SaveOptimizeTest
|
|||
_servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(_servlet);
|
||||
ServletContextHandler contextHandler = _server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
_server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
_servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
|
||||
_server1.start();
|
||||
|
@ -471,8 +471,8 @@ public class SaveOptimizeTest
|
|||
_servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(_servlet);
|
||||
ServletContextHandler contextHandler = _server1.addContext(contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextHandler.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
_server1.getServerConnector().addBean(scopeListener);
|
||||
contextHandler.addServlet(holder, servletMapping);
|
||||
_servlet.setStore(contextHandler.getSessionHandler().getSessionCache().getSessionDataStore());
|
||||
_server1.start();
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.io.IOException;
|
|||
import java.net.HttpCookie;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -41,7 +40,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
|
@ -118,8 +116,8 @@ public class SessionRenewTest
|
|||
String contextPathA = "";
|
||||
String servletMapping = "/server";
|
||||
WebAppContext contextA = _server.addWebAppContext(".", contextPathA);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
contextA.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
_server.getServerConnector().addBean(scopeListener);
|
||||
contextA.setParentLoaderPriority(true);
|
||||
contextA.addServlet(TestServlet.class, servletMapping);
|
||||
|
||||
|
@ -185,8 +183,8 @@ public class SessionRenewTest
|
|||
String contextPath = "";
|
||||
String servletMapping = "/server";
|
||||
WebAppContext context = _server.addWebAppContext(".", contextPath);
|
||||
TestContextScopeListener scopeListener = new TestContextScopeListener();
|
||||
context.addEventListener(scopeListener);
|
||||
TestHttpChannelCompleteListener scopeListener = new TestHttpChannelCompleteListener();
|
||||
_server.getServerConnector().addBean(scopeListener);
|
||||
context.setParentLoaderPriority(true);
|
||||
context.addServlet(TestServlet.class, servletMapping);
|
||||
TestHttpSessionIdListener testListener = new TestHttpSessionIdListener();
|
||||
|
|
Loading…
Reference in New Issue