Merged branch 'jetty-10.0.x' into 'jetty-10.0.x-3951-http2_demand'.
This commit is contained in:
commit
6577a8b9dc
|
@ -27,7 +27,6 @@ import java.security.CodeSource;
|
|||
import java.security.PermissionCollection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.EventListener;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -615,9 +614,9 @@ public class AntWebAppContext extends WebAppContext
|
|||
TaskLog.logWithTimestamp("Stopping web application " + this);
|
||||
Thread.currentThread().sleep(500L);
|
||||
super.doStop();
|
||||
//remove all filters, servlets and listeners. They will be recreated
|
||||
//either via application of a context xml file or web.xml or annotation or servlet api
|
||||
setEventListeners(new EventListener[0]);
|
||||
// remove all filters and servlets. They will be recreated
|
||||
// either via application of a context xml file or web.xml or annotation or servlet api.
|
||||
// Event listeners are reset in ContextHandler.doStop()
|
||||
getServletHandler().setFilters(new FilterHolder[0]);
|
||||
getServletHandler().setFilterMappings(new FilterMapping[0]);
|
||||
getServletHandler().setServlets(new ServletHolder[0]);
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.io.EOFException;
|
|||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpClientTransport;
|
||||
import org.eclipse.jetty.client.HttpExchange;
|
||||
import org.eclipse.jetty.client.HttpReceiver;
|
||||
import org.eclipse.jetty.client.HttpResponse;
|
||||
|
@ -50,8 +51,13 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
|
|||
super(channel);
|
||||
HttpClient httpClient = channel.getHttpDestination().getHttpClient();
|
||||
parser = new HttpParser(this, -1, httpClient.getHttpCompliance());
|
||||
parser.setHeaderCacheSize(((HttpClientTransportOverHTTP)httpClient.getTransport()).getHeaderCacheSize());
|
||||
parser.setHeaderCacheCaseSensitive(((HttpClientTransportOverHTTP)httpClient.getTransport()).isHeaderCacheCaseSensitive());
|
||||
HttpClientTransport transport = httpClient.getTransport();
|
||||
if (transport instanceof HttpClientTransportOverHTTP)
|
||||
{
|
||||
HttpClientTransportOverHTTP httpTransport = (HttpClientTransportOverHTTP)transport;
|
||||
parser.setHeaderCacheSize(httpTransport.getHeaderCacheSize());
|
||||
parser.setHeaderCacheCaseSensitive(httpTransport.isHeaderCacheCaseSensitive());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,7 +39,6 @@ public class HttpClientJMXTest
|
|||
String name = "foo";
|
||||
HttpClient httpClient = new HttpClient();
|
||||
httpClient.setName(name);
|
||||
httpClient.start();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -47,6 +46,7 @@ public class HttpClientJMXTest
|
|||
MBeanContainer mbeanContainer = new MBeanContainer(mbeanServer);
|
||||
// Adding MBeanContainer as a bean will trigger the registration of MBeans.
|
||||
httpClient.addBean(mbeanContainer);
|
||||
httpClient.start();
|
||||
|
||||
String domain = HttpClient.class.getPackage().getName();
|
||||
ObjectName pattern = new ObjectName(domain + ":type=" + HttpClient.class.getSimpleName().toLowerCase(Locale.ENGLISH) + ",*");
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<!-- ================================================================ -->
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.setuid.SetUIDListener">
|
||||
<Set name="startServerAsPrivileged"><Property name="jetty.setuid.startServerAsPrivileged" default="false"/></Set>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<!-- Mixin the Start FileNoticeLifeCycleListener -->
|
||||
<!-- =============================================================== -->
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.util.component.FileNoticeLifeCycleListener">
|
||||
<Arg><Property name="jetty.state" default="./jetty.state"/></Arg>
|
||||
|
|
|
@ -73,7 +73,7 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory
|
|||
|
||||
final HTTP2ClientConnection connection = new HTTP2ClientConnection(client, byteBufferPool, executor, endPoint,
|
||||
parser, session, client.getInputBufferSize(), promise, listener);
|
||||
connection.addListener(connectionListener);
|
||||
connection.addEventListener(connectionListener);
|
||||
return customize(connection, context);
|
||||
}
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
|||
endPoint, httpConfiguration, parser, session, getInputBufferSize(), listener);
|
||||
connection.setUseInputDirectByteBuffers(isUseInputDirectByteBuffers());
|
||||
connection.setUseOutputDirectByteBuffers(isUseOutputDirectByteBuffers());
|
||||
connection.addListener(sessionContainer);
|
||||
connection.addEventListener(sessionContainer);
|
||||
return configure(connection, connector, endPoint);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.eclipse.jetty.io;
|
||||
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Executor;
|
||||
|
@ -57,13 +58,14 @@ public abstract class AbstractConnection implements Connection
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener)
|
||||
public void addEventListener(EventListener listener)
|
||||
{
|
||||
_listeners.add(listener);
|
||||
if (listener instanceof Listener)
|
||||
_listeners.add((Listener)listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener)
|
||||
public void removeEventListener(EventListener listener)
|
||||
{
|
||||
_listeners.remove(listener);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -43,7 +44,7 @@ public interface ClientConnectionFactory
|
|||
{
|
||||
ContainerLifeCycle client = (ContainerLifeCycle)context.get(CLIENT_CONTEXT_KEY);
|
||||
if (client != null)
|
||||
client.getBeans(Connection.Listener.class).forEach(connection::addListener);
|
||||
client.getBeans(EventListener.class).forEach(connection::addEventListener);
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.io;
|
|||
|
||||
import java.io.Closeable;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.EventListener;
|
||||
|
||||
import org.eclipse.jetty.util.component.Container;
|
||||
|
||||
|
@ -38,14 +39,14 @@ public interface Connection extends Closeable
|
|||
*
|
||||
* @param listener the listener to add
|
||||
*/
|
||||
public void addListener(Listener listener);
|
||||
public void addEventListener(EventListener listener);
|
||||
|
||||
/**
|
||||
* <p>Removes a listener of connection events.</p>
|
||||
*
|
||||
* @param listener the listener to remove
|
||||
*/
|
||||
public void removeListener(Listener listener);
|
||||
public void removeEventListener(EventListener listener);
|
||||
|
||||
/**
|
||||
* <p>Callback method invoked when this connection is opened.</p>
|
||||
|
@ -133,7 +134,7 @@ public interface Connection extends Closeable
|
|||
* the Connector or ConnectionFactory are added as listeners to all new connections
|
||||
* </p>
|
||||
*/
|
||||
public interface Listener
|
||||
public interface Listener extends EventListener
|
||||
{
|
||||
public void onOpened(Connection connection);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ import java.util.function.IntUnaryOperator;
|
|||
import org.eclipse.jetty.util.ProcessorUtils;
|
||||
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.log.Log;
|
||||
|
@ -389,31 +390,37 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump
|
|||
*/
|
||||
public abstract Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException;
|
||||
|
||||
public void addEventListener(EventListener listener)
|
||||
/**
|
||||
* @param listener An EventListener
|
||||
* @see AcceptListener
|
||||
* @see Container#addEventListener(EventListener)
|
||||
*/
|
||||
@Override
|
||||
public boolean addEventListener(EventListener listener)
|
||||
{
|
||||
if (isRunning())
|
||||
throw new IllegalStateException(this.toString());
|
||||
if (super.addEventListener(listener))
|
||||
{
|
||||
if (listener instanceof AcceptListener)
|
||||
addAcceptListener(AcceptListener.class.cast(listener));
|
||||
_acceptListeners.add((AcceptListener)listener);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeEventListener(EventListener listener)
|
||||
@Override
|
||||
public boolean removeEventListener(EventListener listener)
|
||||
{
|
||||
if (isRunning())
|
||||
throw new IllegalStateException(this.toString());
|
||||
if (super.removeEventListener(listener))
|
||||
{
|
||||
if (listener instanceof AcceptListener)
|
||||
removeAcceptListener(AcceptListener.class.cast(listener));
|
||||
}
|
||||
|
||||
public void addAcceptListener(AcceptListener listener)
|
||||
{
|
||||
if (!_acceptListeners.contains(listener))
|
||||
_acceptListeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeAcceptListener(AcceptListener listener)
|
||||
{
|
||||
_acceptListeners.remove(listener);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void onAccepting(SelectableChannel channel)
|
||||
|
@ -461,12 +468,16 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump
|
|||
}
|
||||
}
|
||||
|
||||
public interface SelectorManagerListener extends EventListener
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>A listener for accept events.</p>
|
||||
* <p>This listener is called from either the selector or acceptor thread
|
||||
* and implementations must be non blocking and fast.</p>
|
||||
*/
|
||||
public interface AcceptListener extends EventListener
|
||||
public interface AcceptListener extends SelectorManagerListener
|
||||
{
|
||||
/**
|
||||
* Called immediately after a new SelectableChannel is accepted, but
|
||||
|
|
|
@ -571,7 +571,8 @@ public abstract class WriteFlusher
|
|||
}
|
||||
|
||||
/**
|
||||
* <p>A listener of {@link WriteFlusher} events.</p>
|
||||
* <p>A listener of {@link WriteFlusher} events.
|
||||
* If implemented by a Connection class, the {@link #onFlushed(long)} event will be delivered to it.</p>
|
||||
*/
|
||||
public interface Listener
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
</New>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
<Ref id="httpConnector">
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerConnectorListener">
|
||||
<Set name="fileName"><Property name="jetty.port.file" default="port.txt"/></Set>
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.io.IOException;
|
|||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EventListener;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -356,11 +355,9 @@ public class JettyWebAppContext extends WebAppContext
|
|||
|
||||
super.doStop();
|
||||
|
||||
// remove all listeners, servlets and filters. This is because we will
|
||||
// re-apply
|
||||
// any context xml file, which means they would potentially be added
|
||||
// multiple times.
|
||||
setEventListeners(new EventListener[0]);
|
||||
// remove all servlets and filters. This is because we will
|
||||
// re-appy any context xml file, which means they would potentially be
|
||||
// added multiple times.
|
||||
getServletHandler().setFilters(new FilterHolder[0]);
|
||||
getServletHandler().setFilterMappings(new FilterMapping[0]);
|
||||
getServletHandler().setServlets(new ServletHolder[0]);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.maven.plugin.ServerListener">
|
||||
<Set name="tokenFile"><Property name="jetty.token.file"/></Set>
|
||||
|
|
|
@ -46,7 +46,7 @@ public class Activator implements BundleActivator
|
|||
{
|
||||
//For test purposes, use a random port
|
||||
Server server = new Server(0);
|
||||
server.getConnectors()[0].addLifeCycleListener(new AbstractLifeCycleListener()
|
||||
server.getConnectors()[0].addEventListener(new AbstractLifeCycleListener()
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.osgi.boot.utils.ServerConnectorListener">
|
||||
<Set name="sysPropertyName">boot.context.service.port</Set>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.osgi.boot.utils.ServerConnectorListener">
|
||||
<Set name="sysPropertyName">boot.webapp.service.port</Set>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.osgi.boot.utils.ServerConnectorListener">
|
||||
<Set name="sysPropertyName">boot.annotations.port</Set>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.osgi.boot.utils.ServerConnectorListener">
|
||||
<Set name="sysPropertyName">boot.bundle.port</Set>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.osgi.boot.utils.ServerConnectorListener">
|
||||
<Set name="sysPropertyName">boot.javax.websocket.port</Set>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.osgi.boot.utils.ServerConnectorListener">
|
||||
<Set name="sysPropertyName">boot.jsp.port</Set>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.osgi.boot.utils.ServerConnectorListener">
|
||||
<Set name="sysPropertyName">boot.websocket.port</Set>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.osgi.boot.utils.ServerConnectorListener">
|
||||
<Set name="sysPropertyName">foo.foo</Set>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call name="addLifeCycleListener">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.osgi.boot.utils.ServerConnectorListener">
|
||||
<Set name="sysPropertyName">boot.https.port</Set>
|
||||
|
|
|
@ -125,6 +125,31 @@ public class SpnegoAuthenticatorTest
|
|||
assertEquals(HttpHeader.NEGOTIATE.asString(), res.getHeader(HttpHeader.WWW_AUTHENTICATE.asString()));
|
||||
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, res.getStatus());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MockConnector extends AbstractConnector
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.io.AbstractConnection;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.ArrayUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
|
@ -32,17 +31,7 @@ import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
|||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
||||
/**
|
||||
* <p>Provides the common handling for {@link ConnectionFactory} implementations including:</p>
|
||||
* <ul>
|
||||
* <li>Protocol identification</li>
|
||||
* <li>Configuration of new Connections:
|
||||
* <ul>
|
||||
* <li>Setting inputbuffer size</li>
|
||||
* <li>Calling {@link Connection#addListener(Connection.Listener)} for all
|
||||
* Connection.Listener instances found as beans on the {@link Connector}
|
||||
* and this {@link ConnectionFactory}</li>
|
||||
* </ul>
|
||||
* </ul>
|
||||
* <p>Provides the common handling for {@link ConnectionFactory} implementations.</p>
|
||||
*/
|
||||
@ManagedObject
|
||||
public abstract class AbstractConnectionFactory extends ContainerLifeCycle implements ConnectionFactory
|
||||
|
@ -92,19 +81,10 @@ public abstract class AbstractConnectionFactory extends ContainerLifeCycle imple
|
|||
connection.setInputBufferSize(getInputBufferSize());
|
||||
|
||||
// Add Connection.Listeners from Connector
|
||||
if (connector instanceof ContainerLifeCycle)
|
||||
{
|
||||
ContainerLifeCycle aggregate = (ContainerLifeCycle)connector;
|
||||
for (Connection.Listener listener : aggregate.getBeans(Connection.Listener.class))
|
||||
{
|
||||
connection.addListener(listener);
|
||||
}
|
||||
}
|
||||
connector.getEventListeners().forEach(connection::addEventListener);
|
||||
|
||||
// Add Connection.Listeners from this factory
|
||||
for (Connection.Listener listener : getBeans(Connection.Listener.class))
|
||||
{
|
||||
connection.addListener(listener);
|
||||
}
|
||||
getEventListeners().forEach(connection::addEventListener);
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
|
|
@ -104,7 +104,6 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
_state = new HttpChannelState(this);
|
||||
_request = new Request(this, newHttpInput(_state));
|
||||
_response = new Response(this, newHttpOutput());
|
||||
|
||||
_executor = connector.getServer().getThreadPool();
|
||||
_requestLog = connector.getServer().getRequestLog();
|
||||
_combinedListener = (connector instanceof AbstractConnector)
|
||||
|
@ -1224,16 +1223,17 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
public void succeeded()
|
||||
{
|
||||
_written += _length;
|
||||
if (_complete)
|
||||
_response.getHttpOutput().closed();
|
||||
super.succeeded();
|
||||
if (_commit)
|
||||
_combinedListener.onResponseCommit(_request);
|
||||
if (_length > 0)
|
||||
_combinedListener.onResponseContent(_request, _content);
|
||||
if (_complete && _state.completeResponse())
|
||||
{
|
||||
_response.getHttpOutput().closed();
|
||||
_combinedListener.onResponseEnd(_request);
|
||||
}
|
||||
super.succeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(final Throwable x)
|
||||
|
|
|
@ -386,22 +386,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
|
|||
if (!_state.compareAndSet(state, State.CLOSED))
|
||||
break;
|
||||
|
||||
// Just make sure write and output stream really are closed
|
||||
try
|
||||
{
|
||||
_channel.getResponse().closeOutput();
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
abort(x);
|
||||
}
|
||||
finally
|
||||
{
|
||||
releaseBuffer();
|
||||
}
|
||||
// Return even if an exception is thrown by closeOutput().
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,10 +223,8 @@ public class ServerConnector extends AbstractNetworkConnector
|
|||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
for (EventListener l : getBeans(EventListener.class))
|
||||
{
|
||||
for (EventListener l : getBeans(SelectorManager.SelectorManagerListener.class))
|
||||
_manager.addEventListener(l);
|
||||
}
|
||||
|
||||
super.doStart();
|
||||
|
||||
|
|
|
@ -198,7 +198,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
private boolean _compactPath = false;
|
||||
private boolean _usingSecurityManager = System.getSecurityManager() != null;
|
||||
|
||||
private final List<EventListener> _eventListeners = new CopyOnWriteArrayList<>();
|
||||
private final List<EventListener> _programmaticListeners = new CopyOnWriteArrayList<>();
|
||||
private final List<ServletContextListener> _servletContextListeners = new CopyOnWriteArrayList<>();
|
||||
private final List<ServletContextListener> _destroySerletContextListeners = new ArrayList<>();
|
||||
|
@ -206,7 +205,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
private final List<ServletRequestListener> _servletRequestListeners = new CopyOnWriteArrayList<>();
|
||||
private final List<ServletRequestAttributeListener> _servletRequestAttributeListeners = new CopyOnWriteArrayList<>();
|
||||
private final List<ContextScopeListener> _contextListeners = new CopyOnWriteArrayList<>();
|
||||
private final List<EventListener> _durableListeners = new CopyOnWriteArrayList<>();
|
||||
private final Set<EventListener> _durableListeners = new HashSet<>();
|
||||
private String[] _protectedTargets;
|
||||
private final CopyOnWriteArrayList<AliasCheck> _aliasChecks = new CopyOnWriteArrayList<ContextHandler.AliasCheck>();
|
||||
|
||||
|
@ -260,7 +259,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
{
|
||||
dumpObjects(out, indent,
|
||||
new ClassLoaderDump(getClassLoader()),
|
||||
new DumpableCollection("eventListeners " + this, _eventListeners),
|
||||
new DumpableCollection("handler attributes " + this, ((AttributesMap)getAttributes()).getAttributeEntrySet()),
|
||||
new DumpableCollection("context attributes " + this, ((Context)getServletContext()).getAttributeEntrySet()),
|
||||
new DumpableCollection("initparams " + this, getInitParams().entrySet()));
|
||||
|
@ -606,54 +604,22 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
return _displayName;
|
||||
}
|
||||
|
||||
public EventListener[] getEventListeners()
|
||||
{
|
||||
return _eventListeners.toArray(new EventListener[_eventListeners.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the context event listeners.
|
||||
*
|
||||
* @param eventListeners the event listeners
|
||||
* @see ServletContextListener
|
||||
* @see ServletContextAttributeListener
|
||||
* @see ServletRequestListener
|
||||
* @see ServletRequestAttributeListener
|
||||
*/
|
||||
public void setEventListeners(EventListener[] eventListeners)
|
||||
{
|
||||
_contextListeners.clear();
|
||||
_servletContextListeners.clear();
|
||||
_servletContextAttributeListeners.clear();
|
||||
_servletRequestListeners.clear();
|
||||
_servletRequestAttributeListeners.clear();
|
||||
_eventListeners.clear();
|
||||
|
||||
if (eventListeners != null)
|
||||
for (EventListener listener : eventListeners)
|
||||
{
|
||||
addEventListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a context event listeners.
|
||||
*
|
||||
* @param listener the event listener to add
|
||||
* @return true if the listener was added
|
||||
* @see ContextScopeListener
|
||||
* @see ServletContextListener
|
||||
* @see ServletContextAttributeListener
|
||||
* @see ServletRequestListener
|
||||
* @see ServletRequestAttributeListener
|
||||
*/
|
||||
public void addEventListener(EventListener listener)
|
||||
@Override
|
||||
public boolean addEventListener(EventListener listener)
|
||||
{
|
||||
_eventListeners.add(listener);
|
||||
|
||||
if (!(isStarted() || isStarting()))
|
||||
if (super.addEventListener(listener))
|
||||
{
|
||||
_durableListeners.add(listener);
|
||||
}
|
||||
|
||||
if (listener instanceof ContextScopeListener)
|
||||
{
|
||||
_contextListeners.add((ContextScopeListener)listener);
|
||||
|
@ -672,21 +638,17 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
|
||||
if (listener instanceof ServletRequestAttributeListener)
|
||||
_servletRequestAttributeListeners.add((ServletRequestAttributeListener)listener);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a context event listeners.
|
||||
*
|
||||
* @param listener the event listener to remove
|
||||
* @see ServletContextListener
|
||||
* @see ServletContextAttributeListener
|
||||
* @see ServletRequestListener
|
||||
* @see ServletRequestAttributeListener
|
||||
*/
|
||||
public void removeEventListener(EventListener listener)
|
||||
@Override
|
||||
public boolean removeEventListener(EventListener listener)
|
||||
{
|
||||
if (super.removeEventListener(listener))
|
||||
{
|
||||
_eventListeners.remove(listener);
|
||||
|
||||
if (listener instanceof ContextScopeListener)
|
||||
_contextListeners.remove(listener);
|
||||
|
||||
|
@ -701,6 +663,9 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
|
||||
if (listener instanceof ServletRequestAttributeListener)
|
||||
_servletRequestAttributeListeners.remove(listener);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -720,7 +685,11 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
|
||||
public boolean isDurableListener(EventListener listener)
|
||||
{
|
||||
// The durable listeners are those set when the context is started
|
||||
if (isStarted())
|
||||
return _durableListeners.contains(listener);
|
||||
// If we are not yet started then all set listeners are durable
|
||||
return getEventListeners().contains(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -800,6 +769,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
if (_mimeTypes == null)
|
||||
_mimeTypes = new MimeTypes();
|
||||
|
||||
_durableListeners.addAll(getEventListeners());
|
||||
|
||||
try
|
||||
{
|
||||
// Set the classloader, context and enter scope
|
||||
|
@ -975,7 +946,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
stopContext();
|
||||
|
||||
// retain only durable listeners
|
||||
setEventListeners(_durableListeners.toArray(new EventListener[_durableListeners.size()]));
|
||||
setEventListeners(_durableListeners);
|
||||
_durableListeners.clear();
|
||||
|
||||
if (_errorHandler != null)
|
||||
|
|
|
@ -261,9 +261,16 @@ public class SessionHandler extends ScopedHandler
|
|||
* Individual SessionManagers implementations may accept arbitrary listener types,
|
||||
* but they are expected to at least handle HttpSessionActivationListener,
|
||||
* HttpSessionAttributeListener, HttpSessionBindingListener and HttpSessionListener.
|
||||
* @return true if the listener was added
|
||||
* @see #removeEventListener(EventListener)
|
||||
* @see HttpSessionAttributeListener
|
||||
* @see HttpSessionListener
|
||||
* @see HttpSessionIdListener
|
||||
*/
|
||||
public void addEventListener(EventListener listener)
|
||||
@Override
|
||||
public boolean addEventListener(EventListener listener)
|
||||
{
|
||||
if (super.addEventListener(listener))
|
||||
{
|
||||
if (listener instanceof HttpSessionAttributeListener)
|
||||
_sessionAttributeListeners.add((HttpSessionAttributeListener)listener);
|
||||
|
@ -271,23 +278,9 @@ public class SessionHandler extends ScopedHandler
|
|||
_sessionListeners.add((HttpSessionListener)listener);
|
||||
if (listener instanceof HttpSessionIdListener)
|
||||
_sessionIdListeners.add((HttpSessionIdListener)listener);
|
||||
addBean(listener, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all event listeners for session-related events.
|
||||
*
|
||||
* @see #removeEventListener(EventListener)
|
||||
*/
|
||||
public void clearEventListeners()
|
||||
{
|
||||
for (EventListener e : getBeans(EventListener.class))
|
||||
{
|
||||
removeBean(e);
|
||||
}
|
||||
_sessionAttributeListeners.clear();
|
||||
_sessionListeners.clear();
|
||||
_sessionIdListeners.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -785,13 +778,10 @@ public class SessionHandler extends ScopedHandler
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an event listener for for session-related events.
|
||||
*
|
||||
* @param listener the session event listener to remove
|
||||
* @see #addEventListener(EventListener)
|
||||
*/
|
||||
public void removeEventListener(EventListener listener)
|
||||
@Override
|
||||
public boolean removeEventListener(EventListener listener)
|
||||
{
|
||||
if (super.removeEventListener(listener))
|
||||
{
|
||||
if (listener instanceof HttpSessionAttributeListener)
|
||||
_sessionAttributeListeners.remove(listener);
|
||||
|
@ -799,7 +789,9 @@ public class SessionHandler extends ScopedHandler
|
|||
_sessionListeners.remove(listener);
|
||||
if (listener instanceof HttpSessionIdListener)
|
||||
_sessionIdListeners.remove(listener);
|
||||
removeBean(listener);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// 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 org.eclipse.jetty.http.HttpCompliance;
|
||||
import org.eclipse.jetty.http.MetaData;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
||||
/**
|
||||
* Extended Server Tester.
|
||||
*/
|
||||
public class DelayedServerTest extends HttpServerTestBase
|
||||
{
|
||||
@BeforeEach
|
||||
public void init() throws Exception
|
||||
{
|
||||
startServer(new ServerConnector(_server, new HttpConnectionFactory()
|
||||
{
|
||||
@Override
|
||||
public Connection newConnection(Connector connector, EndPoint endPoint)
|
||||
{
|
||||
return configure(new DelayedHttpConnection(getHttpConfiguration(), connector, endPoint), connector, endPoint);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private static class DelayedHttpConnection extends HttpConnection
|
||||
{
|
||||
public DelayedHttpConnection(HttpConfiguration config, Connector connector, EndPoint endPoint)
|
||||
{
|
||||
super(config, connector, endPoint, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(MetaData.Request request, MetaData.Response response, ByteBuffer content, boolean lastContent, Callback callback)
|
||||
{
|
||||
DelayedCallback delay = new DelayedCallback(callback, getServer().getThreadPool());
|
||||
super.send(request, response, content, lastContent, delay);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DelayedCallback extends Callback.Nested
|
||||
{
|
||||
final ThreadPool pool;
|
||||
|
||||
public DelayedCallback(Callback callback, ThreadPool threadPool)
|
||||
{
|
||||
super(callback);
|
||||
pool = threadPool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
pool.execute(()->
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(10);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
super.succeeded();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
pool.execute(()->
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(20);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
super.failed(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.server;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -73,11 +72,6 @@ public class ExtendedServerTest extends HttpServerTestBase
|
|||
{
|
||||
private volatile long _lastSelected;
|
||||
|
||||
public ExtendedEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key, Scheduler scheduler)
|
||||
{
|
||||
super(channel, selector, key, scheduler);
|
||||
}
|
||||
|
||||
public ExtendedEndPoint(SocketChannel channel, ManagedSelector selector, SelectionKey key, Scheduler scheduler)
|
||||
{
|
||||
super(channel, selector, key, scheduler);
|
||||
|
|
|
@ -28,10 +28,12 @@ import java.io.LineNumberReader;
|
|||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Exchanger;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
|
@ -42,6 +44,8 @@ import org.eclipse.jetty.http.tools.HttpTester;
|
|||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.EofException;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.log.AbstractLogger;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -1816,4 +1820,53 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
|||
assertThat(client.getInputStream().read(), is(-1));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendAsyncContent() throws Exception
|
||||
{
|
||||
int size = 64 * 1024;
|
||||
configureServer(new SendAsyncContentHandler(size));
|
||||
|
||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||
{
|
||||
OutputStream os = client.getOutputStream();
|
||||
os.write(("GET / HTTP/1.1\r\nHost: localhost\r\n\r\n").getBytes(StandardCharsets.ISO_8859_1));
|
||||
os.flush();
|
||||
|
||||
HttpTester.Response response = HttpTester.parseResponse(client.getInputStream());
|
||||
assertThat(response.getStatus(), is(200));
|
||||
assertThat(response.getContentBytes().length, is(size));
|
||||
|
||||
// Try again to check previous request completed OK
|
||||
os.write(("GET / HTTP/1.1\r\nHost: localhost\r\n\r\n").getBytes(StandardCharsets.ISO_8859_1));
|
||||
os.flush();
|
||||
response = HttpTester.parseResponse(client.getInputStream());
|
||||
assertThat(response.getStatus(), is(200));
|
||||
assertThat(response.getContentBytes().length, is(size));
|
||||
}
|
||||
}
|
||||
|
||||
private class SendAsyncContentHandler extends AbstractHandler
|
||||
{
|
||||
final ByteBuffer content;
|
||||
|
||||
public SendAsyncContentHandler(int size)
|
||||
{
|
||||
content = BufferUtil.allocate(size);
|
||||
Arrays.fill(content.array(),0,size,(byte)'X');
|
||||
content.position(0);
|
||||
content.limit(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setStatus(200);
|
||||
response.setContentType("application/unknown");
|
||||
response.setContentLength(content.remaining());
|
||||
AsyncContext async = request.startAsync();
|
||||
((HttpOutput)response.getOutputStream()).sendContent(content.slice(), Callback.from(async::complete));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ public class ShutdownHandlerTest
|
|||
start(null);
|
||||
|
||||
CountDownLatch stopLatch = new CountDownLatch(1);
|
||||
server.addLifeCycleListener(new AbstractLifeCycle.AbstractLifeCycleListener()
|
||||
server.addEventListener(new AbstractLifeCycle.AbstractLifeCycleListener()
|
||||
{
|
||||
@Override
|
||||
public void lifeCycleStopped(LifeCycle event)
|
||||
|
|
|
@ -61,6 +61,7 @@ public class ListenerHolder extends BaseHolder<EventListener>
|
|||
* just like ServletHolder and FilterHolder,
|
||||
* the listener will not be introspected for
|
||||
* annotations like Resource etc.
|
||||
* @param listener The listener instance
|
||||
*/
|
||||
public void setListener(EventListener listener)
|
||||
{
|
||||
|
|
|
@ -196,15 +196,21 @@ public class ServletContextHandler extends ContextHandler
|
|||
|
||||
/**
|
||||
* Add EventListener
|
||||
* Adds an EventListener to the list. @see org.eclipse.jetty.server.handler.ContextHandler#addEventListener().
|
||||
* Also adds any listeners that are session related to the SessionHandler.
|
||||
*
|
||||
* @param listener the listener to add
|
||||
* @return true if the listener was added
|
||||
* @see HttpSessionAttributeListener
|
||||
* @see HttpSessionActivationListener
|
||||
* @see HttpSessionBindingListener
|
||||
* @see HttpSessionListener
|
||||
* @see HttpSessionIdListener
|
||||
* @see ContextHandler#addEventListener(EventListener)
|
||||
*/
|
||||
@Override
|
||||
public void addEventListener(EventListener listener)
|
||||
public boolean addEventListener(EventListener listener)
|
||||
{
|
||||
if (super.addEventListener(listener))
|
||||
{
|
||||
super.addEventListener(listener);
|
||||
if ((listener instanceof HttpSessionActivationListener) ||
|
||||
(listener instanceof HttpSessionAttributeListener) ||
|
||||
(listener instanceof HttpSessionBindingListener) ||
|
||||
|
@ -214,6 +220,9 @@ public class ServletContextHandler extends ContextHandler
|
|||
if (_sessionHandler != null)
|
||||
_sessionHandler.addEventListener(listener);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -670,7 +670,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
|||
//Register a listener to delete tmp files that are created as a result of this
|
||||
//servlet calling Request.getPart() or Request.getParts()
|
||||
ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext());
|
||||
if (!Arrays.asList(ch.getEventListeners()).contains(MultiPartCleanerListener.INSTANCE))
|
||||
if (!ch.getEventListeners().contains(MultiPartCleanerListener.INSTANCE))
|
||||
ch.addEventListener(MultiPartCleanerListener.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
|
@ -463,10 +462,8 @@ public class ServletContextHandlerTest
|
|||
}
|
||||
}
|
||||
|
||||
EventListener[] listeners = root.getEventListeners();
|
||||
assertNotNull(listeners);
|
||||
List<String> listenerClassNames = new ArrayList<>();
|
||||
for (EventListener l : listeners)
|
||||
for (EventListener l : root.getEventListeners())
|
||||
listenerClassNames.add(l.getClass().getName());
|
||||
|
||||
assertTrue(listenerClassNames.contains("org.eclipse.jetty.servlet.ServletContextHandlerTest$MySCAListener"));
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.servlet;
|
|||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import javax.servlet.DispatcherType;
|
||||
|
@ -120,9 +121,19 @@ public class ServletLifeCycleTest
|
|||
"Destroy class org.eclipse.jetty.servlet.ServletLifeCycleTest$TestListener"));
|
||||
|
||||
// Listener added before start is not destroyed
|
||||
EventListener[] listeners = context.getEventListeners();
|
||||
assertThat(listeners.length, is(1));
|
||||
assertThat(listeners[0].getClass(), is(TestListener2.class));
|
||||
List<EventListener> listeners = context.getEventListeners();
|
||||
assertThat(listeners.size(), is(1));
|
||||
assertThat(listeners.get(0).getClass(), is(TestListener2.class));
|
||||
|
||||
server.start();
|
||||
context.addEventListener(new EventListener() {});listeners = context.getEventListeners();
|
||||
listeners = context.getEventListeners();
|
||||
assertThat(listeners.size(), is(3));
|
||||
|
||||
server.stop();
|
||||
listeners = context.getEventListeners();
|
||||
assertThat(listeners.size(), is(1));
|
||||
assertThat(listeners.get(0).getClass(), is(TestListener2.class));
|
||||
}
|
||||
|
||||
public static class TestDecorator implements Decorator
|
||||
|
|
|
@ -19,10 +19,7 @@
|
|||
package org.eclipse.jetty.util;
|
||||
|
||||
/**
|
||||
* Interface for 3rd party libraries to decorate recently created objects in Jetty.
|
||||
* <p>
|
||||
* Most common use is weld/CDI.
|
||||
* <p>
|
||||
* Interface to decorate objects created by the {@link DecoratedObjectFactory}
|
||||
*/
|
||||
public interface Decorator
|
||||
{
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
package org.eclipse.jetty.util.component;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.eclipse.jetty.util.Uptime;
|
||||
|
@ -49,7 +52,7 @@ public abstract class AbstractLifeCycle implements LifeCycle
|
|||
public static final String STARTED = State.STARTED.toString();
|
||||
public static final String STOPPING = State.STOPPING.toString();
|
||||
|
||||
private final CopyOnWriteArrayList<LifeCycle.Listener> _listeners = new CopyOnWriteArrayList<LifeCycle.Listener>();
|
||||
private final List<EventListener> _eventListener = new CopyOnWriteArrayList<>();
|
||||
private final Object _lock = new Object();
|
||||
private volatile State _state = State.STOPPED;
|
||||
private long _stopTimeout = 30000;
|
||||
|
@ -186,16 +189,39 @@ public abstract class AbstractLifeCycle implements LifeCycle
|
|||
return _state == State.FAILED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLifeCycleListener(LifeCycle.Listener listener)
|
||||
public List<EventListener> getEventListeners()
|
||||
{
|
||||
_listeners.add(listener);
|
||||
return _eventListener;
|
||||
}
|
||||
|
||||
public void setEventListeners(Collection<EventListener> eventListeners)
|
||||
{
|
||||
for (EventListener l : _eventListener)
|
||||
{
|
||||
if (!eventListeners.contains(l))
|
||||
removeEventListener(l);
|
||||
}
|
||||
|
||||
for (EventListener l : eventListeners)
|
||||
{
|
||||
if (!_eventListener.contains(l))
|
||||
addEventListener(l);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLifeCycleListener(LifeCycle.Listener listener)
|
||||
public boolean addEventListener(EventListener listener)
|
||||
{
|
||||
_listeners.remove(listener);
|
||||
if (_eventListener.contains(listener))
|
||||
return false;
|
||||
_eventListener.add(listener);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeEventListener(EventListener listener)
|
||||
{
|
||||
return _eventListener.remove(listener);
|
||||
}
|
||||
|
||||
@ManagedAttribute(value = "Lifecycle State for this instance", readonly = true)
|
||||
|
@ -226,8 +252,9 @@ public abstract class AbstractLifeCycle implements LifeCycle
|
|||
_state = State.STARTED;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("STARTED @{}ms {}", Uptime.getUptime(), this);
|
||||
for (Listener listener : _listeners)
|
||||
listener.lifeCycleStarted(this);
|
||||
for (EventListener listener : _eventListener)
|
||||
if (listener instanceof Listener)
|
||||
((Listener)listener).lifeCycleStarted(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,8 +263,9 @@ public abstract class AbstractLifeCycle implements LifeCycle
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("STARTING {}", this);
|
||||
_state = State.STARTING;
|
||||
for (Listener listener : _listeners)
|
||||
listener.lifeCycleStarting(this);
|
||||
for (EventListener listener : _eventListener)
|
||||
if (listener instanceof Listener)
|
||||
((Listener)listener).lifeCycleStarting(this);
|
||||
}
|
||||
|
||||
private void setStopping()
|
||||
|
@ -245,8 +273,9 @@ public abstract class AbstractLifeCycle implements LifeCycle
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("STOPPING {}", this);
|
||||
_state = State.STOPPING;
|
||||
for (Listener listener : _listeners)
|
||||
listener.lifeCycleStopping(this);
|
||||
for (EventListener listener : _eventListener)
|
||||
if (listener instanceof Listener)
|
||||
((Listener)listener).lifeCycleStopping(this);
|
||||
}
|
||||
|
||||
private void setStopped()
|
||||
|
@ -256,10 +285,9 @@ public abstract class AbstractLifeCycle implements LifeCycle
|
|||
_state = State.STOPPED;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("STOPPED {}", this);
|
||||
for (Listener listener : _listeners)
|
||||
{
|
||||
listener.lifeCycleStopped(this);
|
||||
}
|
||||
for (EventListener listener : _eventListener)
|
||||
if (listener instanceof Listener)
|
||||
((Listener)listener).lifeCycleStopped(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,9 +296,10 @@ public abstract class AbstractLifeCycle implements LifeCycle
|
|||
_state = State.FAILED;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.warn("FAILED " + this + ": " + th, th);
|
||||
for (Listener listener : _listeners)
|
||||
for (EventListener listener : _eventListener)
|
||||
{
|
||||
listener.lifeCycleFailure(this, th);
|
||||
if (listener instanceof Listener)
|
||||
((Listener)listener).lifeCycleFailure(this, th);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,25 +18,28 @@
|
|||
|
||||
package org.eclipse.jetty.util.component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A Container
|
||||
*/
|
||||
public interface Container
|
||||
{
|
||||
|
||||
/**
|
||||
* Add a bean. If the bean is-a {@link Listener}, then also do an implicit {@link #addEventListener(Listener)}.
|
||||
* Add a bean. If the bean is-a {@link EventListener}, then also do an implicit {@link #addEventListener(EventListener)}.
|
||||
*
|
||||
* @param o the bean object to add
|
||||
* @return true if the bean was added, false if it was already present
|
||||
*/
|
||||
public boolean addBean(Object o);
|
||||
boolean addBean(Object o);
|
||||
|
||||
/**
|
||||
* Adds the given bean, explicitly managing it or not.
|
||||
*
|
||||
* If the bean is-a {@link EventListener}, then also do an implicit {@link #addEventListener(EventListener)}.
|
||||
* @param o The bean object to add
|
||||
* @param managed whether to managed the lifecycle of the bean
|
||||
* @return true if the bean was added, false if it was already present
|
||||
|
@ -47,7 +50,7 @@ public interface Container
|
|||
* @return the list of beans known to this aggregate
|
||||
* @see #getBean(Class)
|
||||
*/
|
||||
public Collection<Object> getBeans();
|
||||
Collection<Object> getBeans();
|
||||
|
||||
/**
|
||||
* @param clazz the class of the beans
|
||||
|
@ -56,39 +59,56 @@ public interface Container
|
|||
* @see #getBeans()
|
||||
* @see #getContainedBeans(Class)
|
||||
*/
|
||||
public <T> Collection<T> getBeans(Class<T> clazz);
|
||||
<T> Collection<T> getBeans(Class<T> clazz);
|
||||
|
||||
/**
|
||||
* @param clazz the class of the beans
|
||||
* @param <T> the Bean type
|
||||
* @return a list of beans of the given class (or subclass), which may be cached/shared.
|
||||
* @see #getBeans()
|
||||
* @see #getContainedBeans(Class)
|
||||
*/
|
||||
default <T> Collection<T> getCachedBeans(Class<T> clazz)
|
||||
{
|
||||
return getBeans(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clazz the class of the bean
|
||||
* @param <T> the Bean type
|
||||
* @return the first bean of a specific class (or subclass), or null if no such bean exist
|
||||
*/
|
||||
public <T> T getBean(Class<T> clazz);
|
||||
<T> T getBean(Class<T> clazz);
|
||||
|
||||
|
||||
/**
|
||||
* Removes the given bean.
|
||||
* If the bean is-a {@link Listener}, then also do an implicit {@link #removeEventListener(Listener)}.
|
||||
* If the bean is-a {@link EventListener}, then also do an implicit {@link #removeEventListener(EventListener)}.
|
||||
*
|
||||
* @param o the bean to remove
|
||||
* @return whether the bean was removed
|
||||
*/
|
||||
public boolean removeBean(Object o);
|
||||
boolean removeBean(Object o);
|
||||
|
||||
/**
|
||||
* Add an event listener.
|
||||
*
|
||||
* EventListeners added by this method are also added as beans.
|
||||
* @param listener the listener to add
|
||||
* @return true if the listener was added
|
||||
* @see Container.Listener
|
||||
* @see LifeCycle.Listener
|
||||
* @see Container#addBean(Object)
|
||||
*/
|
||||
public void addEventListener(Listener listener);
|
||||
boolean addEventListener(EventListener listener);
|
||||
|
||||
/**
|
||||
* Remove an event listener.
|
||||
*
|
||||
* @param listener the listener to remove
|
||||
* @return true if the listener was removed
|
||||
* @see Container#removeBean(Object)
|
||||
*/
|
||||
public void removeEventListener(Listener listener);
|
||||
boolean removeEventListener(EventListener listener);
|
||||
|
||||
/**
|
||||
* Unmanages a bean already contained by this aggregate, so that it is not started/stopped/destroyed with this
|
||||
|
@ -114,12 +134,35 @@ public interface Container
|
|||
*/
|
||||
boolean isManaged(Object bean);
|
||||
|
||||
/**
|
||||
* @param clazz the class of the beans
|
||||
* @param <T> the Bean type
|
||||
* @return the list of beans of the given class from the entire Container hierarchy
|
||||
*/
|
||||
<T> Collection<T> getContainedBeans(Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Get the beans added to the container that are EventListeners.
|
||||
* This is essentially equivalent to <code>getBeans(EventListener.class);</code>,
|
||||
* except that: <ul>
|
||||
* <li>The result may be precomputed, so it can be 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
|
||||
*/
|
||||
default List<EventListener> getEventListeners()
|
||||
{
|
||||
return Collections.unmodifiableList(new ArrayList<>(getBeans(EventListener.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* A listener for Container events.
|
||||
* If an added bean implements this interface it will receive the events
|
||||
* for this container.
|
||||
*/
|
||||
public interface Listener
|
||||
interface Listener extends EventListener
|
||||
{
|
||||
void beanAdded(Container parent, Object child);
|
||||
|
||||
|
@ -131,14 +174,7 @@ public interface Container
|
|||
* If an added bean implements this interface, then it will
|
||||
* be added to all contained beans that are themselves Containers
|
||||
*/
|
||||
public interface InheritedListener extends Listener
|
||||
interface InheritedListener extends Listener
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clazz the class of the beans
|
||||
* @param <T> the Bean type
|
||||
* @return the list of beans of the given class from the entire Container hierarchy
|
||||
*/
|
||||
public <T> Collection<T> getContainedBeans(Class<T> clazz);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EventListener;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -64,6 +65,10 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* If adding a bean that is shared between multiple {@link ContainerLifeCycle} instances, then it should be started
|
||||
* before being added, so it is unmanaged, or the API must be used to explicitly set it as unmanaged.
|
||||
* <p>
|
||||
* All {@link EventListener}s added via {@link #addEventListener(EventListener)} are also added as beans and all beans
|
||||
* added via an {@link #addBean(Object)} method that are also {@link EventListener}s are added as listeners via a
|
||||
* call to {@link #addEventListener(EventListener)}.
|
||||
* <p>
|
||||
* This class also provides utility methods to dump deep structures of objects.
|
||||
* In the dump, the following symbols are used to indicate the type of contained object:
|
||||
* <pre>
|
||||
|
@ -340,18 +345,17 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
|
||||
Bean newBean = new Bean(o);
|
||||
|
||||
// if the bean is a Listener
|
||||
if (o instanceof Container.Listener)
|
||||
addEventListener((Container.Listener)o);
|
||||
|
||||
// Add the bean
|
||||
_beans.add(newBean);
|
||||
|
||||
// Tell existing listeners about the new bean
|
||||
// Tell any existing listeners about the new bean
|
||||
for (Container.Listener l : _listeners)
|
||||
{
|
||||
l.beanAdded(this, o);
|
||||
}
|
||||
|
||||
// if the bean is an EventListener, then add it. Because we have already added it as a bean above, then
|
||||
// addBean will not be called back.
|
||||
if (o instanceof EventListener)
|
||||
addEventListener((EventListener)o);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -448,17 +452,26 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addEventListener(Container.Listener listener)
|
||||
public boolean addEventListener(EventListener listener)
|
||||
{
|
||||
if (_listeners.contains(listener))
|
||||
return;
|
||||
// Has it already been added as a listener?
|
||||
if (super.addEventListener(listener))
|
||||
{
|
||||
// If it is not yet a bean,
|
||||
if (!contains(listener))
|
||||
// add it as a bean, we will be called back to add it as an event listener, but it will have
|
||||
// already been added, so we will not enter this branch.
|
||||
addBean(listener);
|
||||
|
||||
_listeners.add(listener);
|
||||
if (listener instanceof Container.Listener)
|
||||
{
|
||||
Container.Listener cl = (Container.Listener)listener;
|
||||
_listeners.add(cl);
|
||||
|
||||
// tell it about existing beans
|
||||
for (Bean b : _beans)
|
||||
{
|
||||
listener.beanAdded(this, b._bean);
|
||||
cl.beanAdded(this, b._bean);
|
||||
|
||||
// handle inheritance
|
||||
if (listener instanceof InheritedListener && b.isManaged() && b._bean instanceof Container)
|
||||
|
@ -470,6 +483,32 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeEventListener(EventListener listener)
|
||||
{
|
||||
if (super.removeEventListener(listener))
|
||||
{
|
||||
removeBean(listener);
|
||||
if (_listeners.remove(listener))
|
||||
{
|
||||
// remove existing beans
|
||||
for (Bean b : _beans)
|
||||
{
|
||||
((Container.Listener)listener).beanRemoved(this, b._bean);
|
||||
|
||||
if (listener instanceof InheritedListener && b.isManaged() && b._bean instanceof Container)
|
||||
((Container)b._bean).removeBean(listener);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages a bean already contained by this aggregate, so that it is started/stopped/destroyed with this
|
||||
|
@ -637,8 +676,9 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
l.beanRemoved(this, bean._bean);
|
||||
}
|
||||
|
||||
if (bean._bean instanceof Container.Listener)
|
||||
removeEventListener((Container.Listener)bean._bean);
|
||||
// Remove event listeners, checking list here to avoid calling extended removeEventListener if already removed.
|
||||
if (bean._bean instanceof EventListener && getEventListeners().contains(bean._bean))
|
||||
removeEventListener((EventListener)bean._bean);
|
||||
|
||||
// stop managed beans
|
||||
if (wasManaged && bean._bean instanceof LifeCycle)
|
||||
|
@ -661,22 +701,6 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEventListener(Container.Listener listener)
|
||||
{
|
||||
if (_listeners.remove(listener))
|
||||
{
|
||||
// remove existing beans
|
||||
for (Bean b : _beans)
|
||||
{
|
||||
listener.beanRemoved(this, b._bean);
|
||||
|
||||
if (listener instanceof InheritedListener && b.isManaged() && b._bean instanceof Container)
|
||||
((Container)b._bean).removeBean(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStopTimeout(long stopTimeout)
|
||||
{
|
||||
|
|
|
@ -138,9 +138,9 @@ public interface LifeCycle
|
|||
*/
|
||||
boolean isFailed();
|
||||
|
||||
void addLifeCycleListener(LifeCycle.Listener listener);
|
||||
boolean addEventListener(EventListener listener);
|
||||
|
||||
void removeLifeCycleListener(LifeCycle.Listener listener);
|
||||
boolean removeEventListener(EventListener listener);
|
||||
|
||||
/**
|
||||
* Listener.
|
||||
|
|
|
@ -33,7 +33,7 @@ public class StopLifeCycle extends AbstractLifeCycle implements LifeCycle.Listen
|
|||
public StopLifeCycle(LifeCycle lifecycle)
|
||||
{
|
||||
_lifecycle = lifecycle;
|
||||
addLifeCycleListener(this);
|
||||
addEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -482,6 +482,7 @@ public abstract class Resource implements ResourceFactory, Closeable
|
|||
* @param parent True if the parent directory should be included
|
||||
* @param query query params
|
||||
* @return String of HTML
|
||||
* @throws IOException on failure to generate a list.
|
||||
*/
|
||||
public String getListHTML(String base, boolean parent, String query) throws IOException
|
||||
{
|
||||
|
|
|
@ -443,6 +443,11 @@ public class ContainerLifeCycleTest
|
|||
|
||||
c0.addBean(inherited);
|
||||
|
||||
assertEquals("listener", handled.poll());
|
||||
assertEquals("added", operation.poll());
|
||||
assertEquals(c0, parent.poll());
|
||||
assertEquals(inherited, child.poll());
|
||||
|
||||
assertEquals("inherited", handled.poll());
|
||||
assertEquals("added", operation.poll());
|
||||
assertEquals(c0, parent.poll());
|
||||
|
@ -453,11 +458,6 @@ public class ContainerLifeCycleTest
|
|||
assertEquals(c0, parent.poll());
|
||||
assertEquals(listener, child.poll());
|
||||
|
||||
assertEquals("listener", handled.poll());
|
||||
assertEquals("added", operation.poll());
|
||||
assertEquals(c0, parent.poll());
|
||||
assertEquals(inherited, child.poll());
|
||||
|
||||
assertEquals("inherited", handled.poll());
|
||||
assertEquals("added", operation.poll());
|
||||
assertEquals(c0, parent.poll());
|
||||
|
|
|
@ -161,7 +161,7 @@ public class LifeCycleListenerNestedTest
|
|||
{
|
||||
if (child instanceof LifeCycle)
|
||||
{
|
||||
((LifeCycle)child).addLifeCycleListener(this);
|
||||
((LifeCycle)child).addEventListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ public class LifeCycleListenerNestedTest
|
|||
{
|
||||
if (child instanceof LifeCycle)
|
||||
{
|
||||
((LifeCycle)child).removeLifeCycleListener(this);
|
||||
((LifeCycle)child).removeEventListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ public class LifeCycleListenerNestedTest
|
|||
foo.addBean(barb);
|
||||
|
||||
CapturingListener listener = new CapturingListener();
|
||||
foo.addLifeCycleListener(listener);
|
||||
foo.addEventListener(listener);
|
||||
if (workaround)
|
||||
foo.addEventListener(listener);
|
||||
|
||||
|
@ -216,7 +216,7 @@ public class LifeCycleListenerNestedTest
|
|||
Foo foo = new Foo();
|
||||
|
||||
CapturingListener listener = new CapturingListener();
|
||||
foo.addLifeCycleListener(listener);
|
||||
foo.addEventListener(listener);
|
||||
if (workaround)
|
||||
foo.addEventListener(listener);
|
||||
|
||||
|
@ -254,7 +254,7 @@ public class LifeCycleListenerNestedTest
|
|||
Bar barb = new Bar("b");
|
||||
|
||||
CapturingListener listener = new CapturingListener();
|
||||
foo.addLifeCycleListener(listener);
|
||||
foo.addEventListener(listener);
|
||||
if (workaround)
|
||||
foo.addEventListener(listener);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public class LifeCycleListenerTest
|
|||
{
|
||||
TestLifeCycle lifecycle = new TestLifeCycle();
|
||||
TestListener listener = new TestListener();
|
||||
lifecycle.addLifeCycleListener(listener);
|
||||
lifecycle.addEventListener(listener);
|
||||
|
||||
lifecycle.setCause(cause);
|
||||
|
||||
|
@ -72,7 +72,7 @@ public class LifeCycleListenerTest
|
|||
{
|
||||
TestLifeCycle lifecycle = new TestLifeCycle();
|
||||
TestListener listener = new TestListener();
|
||||
lifecycle.addLifeCycleListener(listener);
|
||||
lifecycle.addEventListener(listener);
|
||||
|
||||
// need to set the state to something other than stopped or stopping or
|
||||
// else
|
||||
|
@ -116,11 +116,11 @@ public class LifeCycleListenerTest
|
|||
{
|
||||
TestLifeCycle lifecycle = new TestLifeCycle();
|
||||
TestListener listener = new TestListener();
|
||||
lifecycle.addLifeCycleListener(listener);
|
||||
lifecycle.addEventListener(listener);
|
||||
|
||||
lifecycle.start();
|
||||
assertTrue(listener.starting, "The starting event didn't occur");
|
||||
lifecycle.removeLifeCycleListener(listener);
|
||||
lifecycle.removeEventListener(listener);
|
||||
lifecycle.stop();
|
||||
assertFalse(listener.stopping, "The stopping event occurred");
|
||||
}
|
||||
|
|
|
@ -556,15 +556,6 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.thread.AbstractLifeCycle#doStop()
|
||||
*/
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
|
@ -957,7 +948,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
new DumpableCollection("Configurations " + name, _configurations),
|
||||
new DumpableCollection("Handler attributes " + name, ((AttributesMap)getAttributes()).getAttributeEntrySet()),
|
||||
new DumpableCollection("Context attributes " + name, getServletContext().getAttributeEntrySet()),
|
||||
new DumpableCollection("EventListeners " + this, Arrays.asList(getEventListeners())),
|
||||
new DumpableCollection("EventListeners " + this, getEventListeners()),
|
||||
new DumpableCollection("Initparams " + name, getInitParams().entrySet())
|
||||
);
|
||||
}
|
||||
|
@ -1080,18 +1071,10 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setEventListeners(EventListener[] eventListeners)
|
||||
public boolean removeEventListener(EventListener listener)
|
||||
{
|
||||
if (_sessionHandler != null)
|
||||
_sessionHandler.clearEventListeners();
|
||||
|
||||
super.setEventListeners(eventListeners);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEventListener(EventListener listener)
|
||||
if (super.removeEventListener(listener))
|
||||
{
|
||||
super.removeEventListener(listener);
|
||||
if ((listener instanceof HttpSessionActivationListener) ||
|
||||
(listener instanceof HttpSessionAttributeListener) ||
|
||||
(listener instanceof HttpSessionBindingListener) ||
|
||||
|
@ -1101,6 +1084,9 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
if (_sessionHandler != null)
|
||||
_sessionHandler.removeEventListener(listener);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -90,7 +90,7 @@ public class WebAppContextTest
|
|||
server.setHandler(wac);
|
||||
wac.addEventListener(new MySessionListener());
|
||||
|
||||
Collection<MySessionListener> listeners = wac.getSessionHandler().getBeans(org.eclipse.jetty.webapp.WebAppContextTest.MySessionListener.class);
|
||||
Collection<MySessionListener> listeners = wac.getSessionHandler().getBeans(MySessionListener.class);
|
||||
assertNotNull(listeners);
|
||||
assertEquals(1, listeners.size());
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ public class JavaxWebSocketServerContainer extends JavaxWebSocketClientContainer
|
|||
WebSocketComponents.ensureWebSocketComponents(servletContext),
|
||||
coreClientSupplier);
|
||||
contextHandler.addManaged(container);
|
||||
contextHandler.addLifeCycleListener(container);
|
||||
contextHandler.addEventListener(container);
|
||||
}
|
||||
// Store a reference to the ServerContainer per - javax.websocket spec 1.0 final - section 6.4: Programmatic Server Deployment
|
||||
servletContext.setAttribute(JAVAX_WEBSOCKET_CONTAINER_ATTRIBUTE, container);
|
||||
|
|
|
@ -76,7 +76,7 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
|
|||
WebSocketComponents.ensureWebSocketComponents(servletContext), executor);
|
||||
servletContext.setAttribute(JETTY_WEBSOCKET_CONTAINER_ATTRIBUTE, container);
|
||||
contextHandler.addManaged(container);
|
||||
contextHandler.addLifeCycleListener(container);
|
||||
contextHandler.addEventListener(container);
|
||||
}
|
||||
|
||||
return container;
|
||||
|
@ -112,7 +112,7 @@ public class JettyWebSocketServerContainer extends ContainerLifeCycle implements
|
|||
{
|
||||
factory = new JettyServerFrameHandlerFactory(this);
|
||||
contextHandler.addManaged(factory);
|
||||
contextHandler.addLifeCycleListener(factory);
|
||||
contextHandler.addEventListener(factory);
|
||||
}
|
||||
frameHandlerFactory = factory;
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ import org.eclipse.jetty.http.HttpScheme;
|
|||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
|
@ -371,14 +370,8 @@ public abstract class ClientUpgradeRequest extends HttpRequest implements Respon
|
|||
|
||||
HttpClient httpClient = wsClient.getHttpClient();
|
||||
WebSocketConnection wsConnection = newWebSocketConnection(endp, httpClient.getExecutor(), httpClient.getScheduler(), httpClient.getByteBufferPool(), coreSession);
|
||||
|
||||
for (Connection.Listener listener : wsClient.getBeans(Connection.Listener.class))
|
||||
{
|
||||
wsConnection.addListener(listener);
|
||||
}
|
||||
|
||||
wsClient.getEventListeners().forEach(wsConnection::addEventListener);
|
||||
coreSession.setWebSocketConnection(wsConnection);
|
||||
|
||||
notifyUpgradeListeners((listener) -> listener.onHandshakeResponse(this, response));
|
||||
|
||||
// Now swap out the connection
|
||||
|
|
|
@ -30,7 +30,6 @@ import org.eclipse.jetty.http.HttpMethod;
|
|||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.http.PreEncodedHttpField;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.server.ConnectionFactory;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
|
@ -211,10 +210,7 @@ public final class RFC6455Handshaker implements Handshaker
|
|||
if (connection == null)
|
||||
throw new WebSocketException("not upgraded: no connection");
|
||||
|
||||
for (Connection.Listener listener : connector.getBeans(Connection.Listener.class))
|
||||
{
|
||||
connection.addListener(listener);
|
||||
}
|
||||
connector.getEventListeners().forEach(connection::addEventListener);
|
||||
|
||||
coreSession.setWebSocketConnection(connection);
|
||||
|
||||
|
|
|
@ -170,5 +170,10 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||
org.eclipse.jetty.LEVEL=INFO
|
||||
#org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog
|
||||
org.eclipse.jetty.LEVEL=WARN
|
||||
#org.eclipse.jetty.LEVEL=DEBUG
|
||||
#org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<configuration>
|
||||
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||
<file>target/logs/jetty.txt</file>
|
||||
<append>false</append>
|
||||
<encoder>
|
||||
<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="debug">
|
||||
<appender-ref ref="FILE" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -26,7 +26,7 @@ import org.eclipse.jetty.server.Request;
|
|||
|
||||
public class TestHttpChannelCompleteListener implements Listener
|
||||
{
|
||||
private final AtomicReference<CountDownLatch> _exitSynchronizer = new AtomicReference<>();
|
||||
AtomicReference<CountDownLatch> _exitSynchronizer = new AtomicReference<>();
|
||||
|
||||
/**
|
||||
* @param exitSynchronizer the exitSynchronizer to set
|
||||
|
|
Loading…
Reference in New Issue