Merged branch 'jetty-9.4.x' into 'master'.

This commit is contained in:
Simone Bordet 2016-11-23 12:19:31 +01:00
commit 23753759bb
14 changed files with 178 additions and 73 deletions

View File

@ -182,15 +182,15 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements Connec
}
@Override
public String toString()
public String toConnectionString()
{
return String.format("%s@%h(l:%s <-> r:%s,closed=%b)[%s]",
getClass().getSimpleName(),
this,
getEndPoint().getLocalAddress(),
getEndPoint().getRemoteAddress(),
closed.get(),
channel);
return String.format("%s@%x(l:%s <-> r:%s,closed=%b)=>%s",
getClass().getSimpleName(),
hashCode(),
getEndPoint().getLocalAddress(),
getEndPoint().getRemoteAddress(),
closed.get(),
channel);
}
private class Delegate extends HttpConnection

View File

@ -292,15 +292,15 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec
}
@Override
public String toString()
public String toConnectionString()
{
return String.format("%s@%h(l:%s <-> r:%s)",
getClass().getSimpleName(),
this,
getEndPoint().getLocalAddress(),
getEndPoint().getRemoteAddress());
return String.format("%s@%x[l:%s<->r:%s]",
getClass().getSimpleName(),
hashCode(),
getEndPoint().getLocalAddress(),
getEndPoint().getRemoteAddress());
}
private class Delegate extends HttpConnection
{
private Delegate(HttpDestination destination)

View File

@ -249,12 +249,16 @@ public abstract class AbstractConnection implements Connection
}
@Override
public String toString()
public final String toString()
{
return String.format("%s@%x[%s]",
getClass().getSimpleName(),
hashCode(),
_endPoint);
return String.format("%s<-%s",toConnectionString(),getEndPoint());
}
public String toConnectionString()
{
return String.format("%s@%h",
getClass().getSimpleName(),
this);
}
private class ReadCallback implements Callback
@ -274,7 +278,8 @@ public abstract class AbstractConnection implements Connection
@Override
public String toString()
{
return String.format("AC.ReadCB@%x{%s}", AbstractConnection.this.hashCode(),AbstractConnection.this);
return String.format("AC.ReadCB@%h{%s}", AbstractConnection.this,AbstractConnection.this);
}
}
}

View File

@ -427,6 +427,11 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
@Override
public String toString()
{
return String.format("%s->%s",toEndPointString(),toConnectionString());
}
public String toEndPointString()
{
Class<?> c=getClass();
String name=c.getSimpleName();
@ -436,20 +441,26 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
name=c.getSimpleName();
}
Connection connection = getConnection();
return String.format("%s@%x{%s<->%s,%s,%s|%s,%d/%d,%s@%x}",
return String.format("%s@%h{%s<->%s,%s,fill=%s,flush=%s,to=%d/%d}",
name,
hashCode(),
this,
getRemoteAddress(),
getLocalAddress(),
_state.get(),
_fillInterest.toStateString(),
_writeFlusher.toStateString(),
getIdleFor(),
getIdleTimeout(),
connection == null ? null : connection.getClass().getSimpleName(),
connection == null ? 0 : connection.hashCode());
getIdleTimeout());
}
public String toConnectionString()
{
Connection connection = getConnection();
if (connection instanceof AbstractConnection)
return ((AbstractConnection)connection).toConnectionString();
return String.format("%s@%x",connection.getClass().getSimpleName(),connection.hashCode());
}
private enum State
{

View File

@ -60,7 +60,7 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage
private abstract class RunnableTask implements Runnable, Invocable
{
private final String _operation;
final String _operation;
protected RunnableTask(String op)
{
@ -70,7 +70,7 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage
@Override
public String toString()
{
return ChannelEndPoint.this.toString()+":"+_operation;
return String.format("CEP:%s:%s:%s",ChannelEndPoint.this,_operation,getInvocationType());
}
}
@ -138,6 +138,13 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage
{
getWriteFlusher().completeWrite();
}
@Override
public String toString()
{
return String.format("CEP:%s:%s:%s->%s",ChannelEndPoint.this,_operation,getInvocationType(),getWriteFlusher());
}
};
private final Runnable _runCompleteWriteFillable = new RunnableCloseable("runCompleteWriteFillable")
@ -424,7 +431,7 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage
@Override
public String toString()
public String toEndPointString()
{
// We do a best effort to print the right toString() and that's it.
try
@ -433,7 +440,7 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage
int keyInterests = valid ? _key.interestOps() : -1;
int keyReadiness = valid ? _key.readyOps() : -1;
return String.format("%s{io=%d/%d,kio=%d,kro=%d}",
super.toString(),
super.toEndPointString(),
_currentInterestOps,
_desiredInterestOps,
keyInterests,

View File

@ -838,4 +838,9 @@ public class ManagedSelector extends AbstractLifeCycle implements Dumpable
}
}
}
public Selector getSelector()
{
return _selector;
}
}

View File

@ -275,6 +275,11 @@ abstract public class WriteFlusher
{
return Invocable.getInvocationType(_callback);
}
public Object getCallback()
{
return _callback;
}
}
public InvocationType getCallbackInvocationType()
@ -523,7 +528,8 @@ abstract public class WriteFlusher
@Override
public String toString()
{
return String.format("WriteFlusher@%x{%s}", hashCode(), _state.get());
State s = _state.get();
return String.format("WriteFlusher@%x{%s}->%s", hashCode(), s,s instanceof PendingState?((PendingState)s).getCallback():null);
}
public String toStateString()

View File

@ -44,6 +44,7 @@ import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Invocable;
/**
* A Connection that acts as an interceptor between an EndPoint providing SSL encrypted data
@ -93,21 +94,52 @@ public class SslConnection extends AbstractConnection
private final boolean _decryptedDirectBuffers = false;
private boolean _renegotiationAllowed;
private boolean _closedOutbound;
private final Runnable _runCompletWrite = new Runnable()
private abstract class RunnableTask implements Runnable, Invocable
{
private final String _operation;
protected RunnableTask(String op)
{
_operation=op;
}
@Override
public String toString()
{
return String.format("SSL:%s:%s:%s",SslConnection.this,_operation,getInvocationType());
}
}
private final Runnable _runCompleteWrite = new RunnableTask("runCompleteWrite")
{
@Override
public void run()
{
_decryptedEndPoint.getWriteFlusher().completeWrite();
}
@Override
public InvocationType getInvocationType()
{
return getDecryptedEndPoint().getWriteFlusher().getCallbackInvocationType();
}
};
private final Runnable _runFillable = new Runnable()
private final Runnable _runFillable = new RunnableTask("runFillable")
{
@Override
public void run()
{
_decryptedEndPoint.getFillInterest().fillable();
}
@Override
public InvocationType getInvocationType()
{
return getDecryptedEndPoint().getFillInterest().getCallbackInvocationType();
}
};
Callback _sslReadCallback = new Callback()
@ -234,7 +266,7 @@ public class SslConnection extends AbstractConnection
if (_decryptedEndPoint._flushRequiresFillToProgress)
{
_decryptedEndPoint._flushRequiresFillToProgress = false;
_runCompletWrite.run();
_runCompleteWrite.run();
}
}
@ -266,7 +298,7 @@ public class SslConnection extends AbstractConnection
}
@Override
public String toString()
public String toConnectionString()
{
ByteBuffer b = _encryptedInput;
int ei=b==null?-1:b.remaining();
@ -275,22 +307,17 @@ public class SslConnection extends AbstractConnection
b = _decryptedInput;
int di=b==null?-1:b.remaining();
return String.format("SslConnection@%x{%s,eio=%d/%d,di=%d} -> %s",
return String.format("%s@%x{%s,eio=%d/%d,di=%d}=>%s",
getClass().getSimpleName(),
hashCode(),
_sslEngine.getHandshakeStatus(),
ei,eo,di,
_decryptedEndPoint.getConnection());
}
((AbstractConnection)_decryptedEndPoint.getConnection()).toConnectionString());
}
public class DecryptedEndPoint extends AbstractEndPoint
{
private boolean _fillRequiresFlushToProgress;
private boolean _flushRequiresFillToProgress;
private boolean _cannotAcceptMoreAppDataToFlush;
private boolean _handshaken;
private boolean _underFlown;
private final Callback _writeCallback = new Callback()
private final class WriteCallBack implements Callback, Invocable
{
@Override
public void succeeded()
@ -316,7 +343,7 @@ public class SslConnection extends AbstractConnection
}
if (fillable)
getFillInterest().fillable();
_runCompletWrite.run();
_runCompleteWrite.run();
}
@Override
@ -355,7 +382,27 @@ public class SslConnection extends AbstractConnection
}
},x);
}
};
@Override
public InvocationType getInvocationType()
{
return getWriteFlusher().getCallbackInvocationType();
}
@Override
public String toString()
{
return String.format("SSL@%h.DEP.writeCallback",SslConnection.this);
}
}
private boolean _fillRequiresFlushToProgress;
private boolean _flushRequiresFillToProgress;
private boolean _cannotAcceptMoreAppDataToFlush;
private boolean _handshaken;
private boolean _underFlown;
private final Callback _writeCallback = new WriteCallBack();
public DecryptedEndPoint()
{
@ -452,7 +499,7 @@ public class SslConnection extends AbstractConnection
{
// try to flush what is pending
// execute to avoid recursion
getExecutor().execute(_runCompletWrite);
getExecutor().execute(_runCompleteWrite);
}
}
}
@ -738,7 +785,7 @@ public class SslConnection extends AbstractConnection
if (_flushRequiresFillToProgress)
{
_flushRequiresFillToProgress = false;
getExecutor().execute(_runCompletWrite);
getExecutor().execute(_runCompleteWrite);
}
if (_encryptedInput != null && !_encryptedInput.hasRemaining())

View File

@ -77,12 +77,13 @@ public abstract class ProxyConnection extends AbstractConnection
protected abstract void write(EndPoint endPoint, ByteBuffer buffer, Callback callback);
@Override
public String toString()
public String toConnectionString()
{
return String.format("%s[l:%d<=>r:%d]",
super.toString(),
getEndPoint().getLocalAddress().getPort(),
getEndPoint().getRemoteAddress().getPort());
return String.format("%s@%x[l:%d<=>r:%d]",
getClass().getSimpleName(),
hashCode(),
getEndPoint().getLocalAddress().getPort(),
getEndPoint().getRemoteAddress().getPort());
}
private class ProxyIteratingCallback extends IteratingCallback

View File

@ -559,10 +559,11 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
}
@Override
public String toString()
public String toConnectionString()
{
return String.format("%s[p=%s,g=%s,c=%s]",
super.toString(),
return String.format("%s@%x[p=%s,g=%s]=>%s",
getClass().getSimpleName(),
hashCode(),
_parser,
_generator,
_channel);

View File

@ -27,6 +27,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.channels.SelectionKey;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
@ -49,6 +50,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.LeakTrackingByteBufferPool;
import org.eclipse.jetty.io.ManagedSelector;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
@ -69,7 +71,7 @@ public class ThreadStarvationTest
final static int BUFFER_SIZE=1024*1024;
final static int BUFFERS=64;
final static int THREADS=5;
final static int CLIENTS=THREADS*2;
final static int CLIENTS=THREADS+2;
@Rule
public TestTracker tracker = new TestTracker();

View File

@ -154,6 +154,13 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
}
}
@Override
protected void doStop() throws Exception
{
mappedCreator.getMappings().reset();
super.doStop();
}
public ServerEndpointMetadata getServerEndpointMetadata(final Class<?> endpoint, final ServerEndpointConfig config) throws DeploymentException
{
ServerEndpointMetadata metadata = null;

View File

@ -758,11 +758,14 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
}
@Override
public String toString()
public String toConnectionString()
{
return String.format("%s@%X{endp=%s,ios=%s,f=%s,g=%s,p=%s}",getClass().getSimpleName(),hashCode(),getEndPoint(),ioState,flusher,generator,parser);
return String.format("%s@%x[ios=%s,f=%s,g=%s,p=%s]",
getClass().getSimpleName(),
hashCode(),
ioState,flusher,generator,parser);
}
@Override
public int hashCode()
{

View File

@ -44,6 +44,7 @@ import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
@ -55,11 +56,13 @@ import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
* Inline Servlet Filter to capture WebSocket upgrade requests and perform path mappings to {@link WebSocketCreator} objects.
*/
@ManagedObject("WebSocket Upgrade Filter")
public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter, MappedWebSocketCreator, Dumpable
public class WebSocketUpgradeFilter extends AbstractLifeCycle implements Filter, MappedWebSocketCreator, Dumpable
{
public static final String CONTEXT_ATTRIBUTE_KEY = "contextAttributeKey";
private static final Logger LOG = Log.getLogger(WebSocketUpgradeFilter.class);
private boolean localMapper;
private boolean localFactory;
public static WebSocketUpgradeFilter configureContext(ServletContextHandler context) throws ServletException
{
// Prevent double configure
@ -162,8 +165,14 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
@Override
public void destroy()
{
factory.cleanup();
super.destroy();
if (localFactory)
{
factory.cleanup();
}
if (localMapper)
{
mappedWebSocketCreator.getMappings().reset();
}
}
@Override
@ -281,21 +290,22 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
try
{
mappedWebSocketCreator = (MappedWebSocketCreator) config.getServletContext().getAttribute(CREATOR_KEY);
ServletContext context = config.getServletContext();
mappedWebSocketCreator = (MappedWebSocketCreator) context.getAttribute(CREATOR_KEY);
if (mappedWebSocketCreator == null)
{
mappedWebSocketCreator = new DefaultMappedWebSocketCreator();
localMapper = true;
}
factory = (WebSocketServerFactory) config.getServletContext().getAttribute(FACTORY_KEY);
factory = (WebSocketServerFactory) context.getAttribute(FACTORY_KEY);
if (factory == null)
{
factory = new WebSocketServerFactory(policy, bufferPool);
localFactory = true;
}
factory.init(config.getServletContext());
addBean(factory, true);
// TODO: Policy isn't from attributes
factory.init(context);
String max = config.getInitParameter("maxIdleTime");
if (max != null)
@ -328,7 +338,7 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
key = WebSocketUpgradeFilter.class.getName();
}
setToAttribute(config.getServletContext(), key);
setToAttribute(context, key);
factory.start();
}