mirror of
https://github.com/jetty/jetty.project.git
synced 2025-03-03 20:39:18 +00:00
Issue #2175 cleanups after review
Improve ws error handling by splitting processError into handling for errors from the network and errors from the application. Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
f9b9cc1313
commit
05dfbd18cd
@ -129,6 +129,17 @@ public interface Callback extends Invocable
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Callback from(Runnable completed)
|
||||||
|
{
|
||||||
|
return new Completing()
|
||||||
|
{
|
||||||
|
public void completed()
|
||||||
|
{
|
||||||
|
completed.run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class Completing implements Callback
|
class Completing implements Callback
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,24 +18,6 @@
|
|||||||
|
|
||||||
package org.eclipse.jetty.websocket.javax.common;
|
package org.eclipse.jetty.websocket.javax.common;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.SharedBlockingCallback;
|
|
||||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
|
||||||
import org.eclipse.jetty.websocket.core.ExtensionConfig;
|
|
||||||
import org.eclipse.jetty.websocket.core.FrameHandler;
|
|
||||||
import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders;
|
|
||||||
import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders;
|
|
||||||
import org.eclipse.jetty.websocket.javax.common.util.ReflectUtils;
|
|
||||||
|
|
||||||
import javax.websocket.CloseReason;
|
|
||||||
import javax.websocket.EndpointConfig;
|
|
||||||
import javax.websocket.Extension;
|
|
||||||
import javax.websocket.MessageHandler;
|
|
||||||
import javax.websocket.RemoteEndpoint.Async;
|
|
||||||
import javax.websocket.RemoteEndpoint.Basic;
|
|
||||||
import javax.websocket.Session;
|
|
||||||
import javax.websocket.WebSocketContainer;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
@ -48,6 +30,25 @@ import java.util.Objects;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.websocket.CloseReason;
|
||||||
|
import javax.websocket.EndpointConfig;
|
||||||
|
import javax.websocket.Extension;
|
||||||
|
import javax.websocket.MessageHandler;
|
||||||
|
import javax.websocket.RemoteEndpoint.Async;
|
||||||
|
import javax.websocket.RemoteEndpoint.Basic;
|
||||||
|
import javax.websocket.Session;
|
||||||
|
import javax.websocket.WebSocketContainer;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.SharedBlockingCallback;
|
||||||
|
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||||
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.websocket.core.ExtensionConfig;
|
||||||
|
import org.eclipse.jetty.websocket.core.FrameHandler;
|
||||||
|
import org.eclipse.jetty.websocket.javax.common.decoders.AvailableDecoders;
|
||||||
|
import org.eclipse.jetty.websocket.javax.common.encoders.AvailableEncoders;
|
||||||
|
import org.eclipse.jetty.websocket.javax.common.util.ReflectUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client Session for the JSR.
|
* Client Session for the JSR.
|
||||||
*/
|
*/
|
||||||
@ -535,7 +536,7 @@ public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.we
|
|||||||
@Override
|
@Override
|
||||||
public boolean isOpen()
|
public boolean isOpen()
|
||||||
{
|
{
|
||||||
return coreSession.isOpen();
|
return coreSession.isOutputOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,6 +18,11 @@
|
|||||||
|
|
||||||
package org.eclipse.jetty.websocket.common;
|
package org.eclipse.jetty.websocket.common;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.component.Dumpable;
|
import org.eclipse.jetty.util.component.Dumpable;
|
||||||
import org.eclipse.jetty.websocket.api.CloseStatus;
|
import org.eclipse.jetty.websocket.api.CloseStatus;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
@ -27,11 +32,6 @@ import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
|||||||
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
||||||
import org.eclipse.jetty.websocket.core.FrameHandler;
|
import org.eclipse.jetty.websocket.core.FrameHandler;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class WebSocketSessionImpl implements Session, Dumpable
|
public class WebSocketSessionImpl implements Session, Dumpable
|
||||||
{
|
{
|
||||||
private final FrameHandler.CoreSession coreSession;
|
private final FrameHandler.CoreSession coreSession;
|
||||||
@ -160,7 +160,7 @@ public class WebSocketSessionImpl implements Session, Dumpable
|
|||||||
@Override
|
@Override
|
||||||
public boolean isOpen()
|
public boolean isOpen()
|
||||||
{
|
{
|
||||||
return remoteEndpoint.getCoreSession().isOpen();
|
return remoteEndpoint.getCoreSession().isOutputOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,14 +18,13 @@
|
|||||||
|
|
||||||
package org.eclipse.jetty.websocket.core;
|
package org.eclipse.jetty.websocket.core;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
|
||||||
import org.eclipse.jetty.util.Utf8Appendable;
|
|
||||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
|
import org.eclipse.jetty.util.Utf8Appendable;
|
||||||
|
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Representation of a WebSocket Close (status code & reason)
|
* Representation of a WebSocket Close (status code & reason)
|
||||||
@ -194,7 +193,7 @@ public class CloseStatus
|
|||||||
|
|
||||||
int len = 2; // status code
|
int len = 2; // status code
|
||||||
|
|
||||||
byte reasonBytes[] = null;
|
byte[] reasonBytes = null;
|
||||||
|
|
||||||
if (reason != null)
|
if (reason != null)
|
||||||
{
|
{
|
||||||
@ -208,7 +207,7 @@ public class CloseStatus
|
|||||||
ByteBuffer buf = BufferUtil.allocate(len);
|
ByteBuffer buf = BufferUtil.allocate(len);
|
||||||
BufferUtil.flipToFill(buf);
|
BufferUtil.flipToFill(buf);
|
||||||
buf.put((byte)((statusCode >>> 8) & 0xFF));
|
buf.put((byte)((statusCode >>> 8) & 0xFF));
|
||||||
buf.put((byte)((statusCode >>> 0) & 0xFF));
|
buf.put((byte)(statusCode & 0xFF));
|
||||||
|
|
||||||
if ((reasonBytes != null) && (reasonBytes.length > 0))
|
if ((reasonBytes != null) && (reasonBytes.length > 0))
|
||||||
{
|
{
|
||||||
|
@ -270,7 +270,7 @@ public interface FrameHandler extends IncomingFrames
|
|||||||
/**
|
/**
|
||||||
* @return True if the websocket is open outbound
|
* @return True if the websocket is open outbound
|
||||||
*/
|
*/
|
||||||
boolean isOpen();
|
boolean isOutputOpen();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If using BatchMode.ON or BatchMode.AUTO, trigger a flush of enqueued / batched frames.
|
* If using BatchMode.ON or BatchMode.AUTO, trigger a flush of enqueued / batched frames.
|
||||||
@ -374,7 +374,7 @@ public interface FrameHandler extends IncomingFrames
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpen()
|
public boolean isOutputOpen()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -20,13 +20,13 @@ package org.eclipse.jetty.websocket.core.internal;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.SocketException;
|
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
@ -235,11 +235,16 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpen()
|
public boolean isOutputOpen()
|
||||||
{
|
{
|
||||||
return channelState.isOutputOpen();
|
return channelState.isOutputOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isClosed()
|
||||||
|
{
|
||||||
|
return channelState.isClosed();
|
||||||
|
}
|
||||||
|
|
||||||
public void setWebSocketConnection(WebSocketConnection connection)
|
public void setWebSocketConnection(WebSocketConnection connection)
|
||||||
{
|
{
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
@ -306,75 +311,56 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
|||||||
{
|
{
|
||||||
handler.onClosed(closeStatus);
|
handler.onClosed(closeStatus);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
LOG.warn(e);
|
LOG.warn(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CloseStatus closeStatusFor(Throwable cause)
|
||||||
|
{
|
||||||
|
int code;
|
||||||
|
if (cause instanceof ProtocolException)
|
||||||
|
code = CloseStatus.PROTOCOL;
|
||||||
|
else if (cause instanceof Utf8Appendable.NotUtf8Exception)
|
||||||
|
code = CloseStatus.BAD_PAYLOAD;
|
||||||
|
else if (cause instanceof WebSocketTimeoutException || cause instanceof TimeoutException || cause instanceof SocketTimeoutException)
|
||||||
|
code = CloseStatus.SHUTDOWN;
|
||||||
|
else if (behavior == Behavior.CLIENT)
|
||||||
|
code = CloseStatus.POLICY_VIOLATION;
|
||||||
|
else
|
||||||
|
code = CloseStatus.SERVER_ERROR;
|
||||||
|
|
||||||
|
return new CloseStatus(code, cause.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process an Error event seen by the Session and/or Connection
|
* Process an Error that originated from the connection.
|
||||||
*
|
*
|
||||||
* @param cause the cause
|
* @param cause the cause
|
||||||
*/
|
*/
|
||||||
public void processError(Throwable cause)
|
public void processConnectionError(Throwable cause)
|
||||||
{
|
{
|
||||||
CloseStatus closeStatus;
|
CloseStatus closeStatus = closeStatusFor(cause);
|
||||||
|
|
||||||
if (cause instanceof Utf8Appendable.NotUtf8Exception)
|
Callback callback = Callback.from(()->{onClosed(cause, closeStatus);connection.close();});
|
||||||
{
|
|
||||||
closeStatus = new CloseStatus(CloseStatus.BAD_PAYLOAD, cause.getMessage());
|
if (closeStatus.getCode() == CloseStatus.PROTOCOL)
|
||||||
}
|
close(closeStatus, callback, false);
|
||||||
else if (cause instanceof SocketTimeoutException)
|
|
||||||
{
|
|
||||||
// A path often seen in Windows
|
|
||||||
closeStatus = new CloseStatus(CloseStatus.SHUTDOWN, cause.getMessage());
|
|
||||||
}
|
|
||||||
else if (cause instanceof IOException)
|
|
||||||
{
|
|
||||||
closeStatus = new CloseStatus(CloseStatus.PROTOCOL, cause.getMessage());
|
|
||||||
}
|
|
||||||
else if (cause instanceof SocketException)
|
|
||||||
{
|
|
||||||
// A path unique to Unix
|
|
||||||
closeStatus = new CloseStatus(CloseStatus.SHUTDOWN, cause.getMessage());
|
|
||||||
}
|
|
||||||
else if (cause instanceof CloseException)
|
|
||||||
{
|
|
||||||
CloseException ce = (CloseException)cause;
|
|
||||||
closeStatus = new CloseStatus(ce.getStatusCode(), ce.getMessage());
|
|
||||||
}
|
|
||||||
else if (cause instanceof WebSocketTimeoutException)
|
|
||||||
{
|
|
||||||
closeStatus = new CloseStatus(CloseStatus.SHUTDOWN, cause.getMessage());
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
callback.succeeded();
|
||||||
LOG.warn("Unhandled Error (closing connection)", cause);
|
}
|
||||||
|
|
||||||
// Exception on end-user WS-Endpoint.
|
/**
|
||||||
// Fast-fail & close connection with reason.
|
* Process an Error that originated from the handler.
|
||||||
int statusCode = CloseStatus.SERVER_ERROR;
|
*
|
||||||
if (behavior == Behavior.CLIENT)
|
* @param cause the cause
|
||||||
statusCode = CloseStatus.POLICY_VIOLATION;
|
*/
|
||||||
|
public void processHandlerError(Throwable cause)
|
||||||
closeStatus = new CloseStatus(statusCode, cause.getMessage());
|
{
|
||||||
}
|
CloseStatus closeStatus = closeStatusFor(cause);
|
||||||
|
close(closeStatus, Callback.from(()->onClosed(cause, closeStatus)), false);
|
||||||
try
|
|
||||||
{
|
|
||||||
// TODO can we avoid the illegal state exception in outClosed
|
|
||||||
close(closeStatus, Callback.NOOP, false);
|
|
||||||
}
|
|
||||||
catch (IllegalStateException e)
|
|
||||||
{
|
|
||||||
if (cause == null)
|
|
||||||
cause = e;
|
|
||||||
else
|
|
||||||
cause.addSuppressed(e);
|
|
||||||
}
|
|
||||||
onClosed(cause, closeStatus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -393,27 +379,19 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
|||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("ConnectionState: Transition to CONNECTED");
|
LOG.debug("ConnectionState: Transition to CONNECTED");
|
||||||
|
|
||||||
try
|
// Open connection and handler
|
||||||
{
|
channelState.onOpen();
|
||||||
// Open connection and handler
|
handler.onOpen(this);
|
||||||
channelState.onOpen();
|
if (!demanding)
|
||||||
handler.onOpen(this);
|
connection.demand(1);
|
||||||
if (!demanding)
|
|
||||||
connection.demand(1);
|
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("ConnectionState: Transition to OPEN");
|
LOG.debug("ConnectionState: Transition to OPEN");
|
||||||
}
|
|
||||||
catch (Throwable t)
|
|
||||||
{
|
|
||||||
LOG.warn("Error during OPEN", t);
|
|
||||||
// TODO: this must trigger onError AND onClose
|
|
||||||
processError(new CloseException(CloseStatus.SERVER_ERROR, t));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Throwable t)
|
catch (Throwable t)
|
||||||
{
|
{
|
||||||
processError(t); // Handle error
|
LOG.warn("Error during OPEN", t);
|
||||||
|
processHandlerError(new CloseException(CloseStatus.SERVER_ERROR, t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,11 +437,11 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
|||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("sendFrame({}, {}, {})", frame, callback, batch);
|
LOG.debug("sendFrame({}, {}, {})", frame, callback, batch);
|
||||||
|
|
||||||
boolean closed;
|
boolean closeConnection;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
assertValidOutgoing(frame);
|
assertValidOutgoing(frame);
|
||||||
closed = channelState.checkOutgoing(frame);
|
closeConnection = channelState.onOutgoingFrame(frame);
|
||||||
}
|
}
|
||||||
catch (Throwable ex)
|
catch (Throwable ex)
|
||||||
{
|
{
|
||||||
@ -476,7 +454,7 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
|||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("close({}, {}, {})", CloseStatus.getCloseStatus(frame), callback, batch);
|
LOG.debug("close({}, {}, {})", CloseStatus.getCloseStatus(frame), callback, batch);
|
||||||
|
|
||||||
if (closed)
|
if (closeConnection)
|
||||||
{
|
{
|
||||||
callback = new Callback.Nested(callback)
|
callback = new Callback.Nested(callback)
|
||||||
{
|
{
|
||||||
@ -613,14 +591,13 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
|||||||
LOG.debug("receiveFrame({}, {}) - connectionState={}, handler={}",
|
LOG.debug("receiveFrame({}, {}) - connectionState={}, handler={}",
|
||||||
frame, callback, channelState, handler);
|
frame, callback, channelState, handler);
|
||||||
|
|
||||||
|
boolean closeConnection = channelState.onIncomingFrame(frame);
|
||||||
boolean closed = channelState.checkIncoming(frame);
|
|
||||||
|
|
||||||
// Handle inbound close
|
// Handle inbound close
|
||||||
if (frame.getOpCode() == OpCode.CLOSE)
|
if (frame.getOpCode() == OpCode.CLOSE)
|
||||||
{
|
{
|
||||||
connection.cancelDemand();
|
connection.cancelDemand();
|
||||||
if (closed)
|
if (closeConnection)
|
||||||
{
|
{
|
||||||
callback = new Callback.Nested(callback)
|
callback = new Callback.Nested(callback)
|
||||||
{
|
{
|
||||||
@ -648,8 +625,9 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
|||||||
LOG.debug("ConnectionState: sending close response {}", closeStatus);
|
LOG.debug("ConnectionState: sending close response {}", closeStatus);
|
||||||
|
|
||||||
// this may race with a rare application close but errors are ignored
|
// this may race with a rare application close but errors are ignored
|
||||||
|
if (closeStatus==null)
|
||||||
|
closeStatus = CloseStatus.NO_CODE_STATUS;
|
||||||
close(closeStatus.getCode(), closeStatus.getReason(), Callback.NOOP);
|
close(closeStatus.getCode(), closeStatus.getReason(), Callback.NOOP);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -118,7 +118,7 @@ public class WebSocketChannelState
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkOutgoing(Frame frame) throws ProtocolException
|
public boolean onOutgoingFrame(Frame frame) throws ProtocolException
|
||||||
{
|
{
|
||||||
byte opcode = frame.getOpCode();
|
byte opcode = frame.getOpCode();
|
||||||
boolean fin = frame.isFin();
|
boolean fin = frame.isFin();
|
||||||
@ -153,7 +153,7 @@ public class WebSocketChannelState
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkIncoming(Frame frame) throws ProtocolException
|
public boolean onIncomingFrame(Frame frame) throws ProtocolException
|
||||||
{
|
{
|
||||||
byte opcode = frame.getOpCode();
|
byte opcode = frame.getOpCode();
|
||||||
boolean fin = frame.isFin();
|
boolean fin = frame.isFin();
|
||||||
|
@ -18,6 +18,13 @@
|
|||||||
|
|
||||||
package org.eclipse.jetty.websocket.core.internal;
|
package org.eclipse.jetty.websocket.core.internal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.AbstractConnection;
|
import org.eclipse.jetty.io.AbstractConnection;
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.Connection;
|
import org.eclipse.jetty.io.Connection;
|
||||||
@ -34,13 +41,6 @@ import org.eclipse.jetty.websocket.core.MessageTooLargeException;
|
|||||||
import org.eclipse.jetty.websocket.core.ProtocolException;
|
import org.eclipse.jetty.websocket.core.ProtocolException;
|
||||||
import org.eclipse.jetty.websocket.core.WebSocketTimeoutException;
|
import org.eclipse.jetty.websocket.core.WebSocketTimeoutException;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the implementation of {@link org.eclipse.jetty.io.Connection} that is suitable for WebSocket
|
* Provides the implementation of {@link org.eclipse.jetty.io.Connection} that is suitable for WebSocket
|
||||||
*/
|
*/
|
||||||
@ -167,9 +167,12 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
|||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("onClose() of physical connection");
|
LOG.debug("onClose() of physical connection");
|
||||||
|
|
||||||
// TODO review all close paths
|
if (!channel.isClosed())
|
||||||
IOException e = new IOException("Closed");
|
{
|
||||||
channel.onClosed(e);
|
IOException e = new IOException("Closed");
|
||||||
|
channel.onClosed(e);
|
||||||
|
}
|
||||||
|
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,10 +182,27 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
|||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("onIdleExpired()");
|
LOG.debug("onIdleExpired()");
|
||||||
|
|
||||||
channel.processError(new WebSocketTimeoutException("Connection Idle Timeout"));
|
// treat as a handler error because socket is still open
|
||||||
|
channel.processHandlerError(new WebSocketTimeoutException("Connection Idle Timeout"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event for no activity on connection (read or write)
|
||||||
|
*
|
||||||
|
* @return true to signal that the endpoint must be closed, false to keep the endpoint open
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean onReadTimeout(Throwable timeout)
|
||||||
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("onReadTimeout()");
|
||||||
|
|
||||||
|
// treat as a handler error because socket is still open
|
||||||
|
channel.processHandlerError(new WebSocketTimeoutException("Timeout on Read", timeout));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected void onFrame(Parser.ParsedFrame frame)
|
protected void onFrame(Parser.ParsedFrame frame)
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
@ -219,7 +239,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
|||||||
referenced.release();
|
referenced.release();
|
||||||
|
|
||||||
// notify session & endpoint
|
// notify session & endpoint
|
||||||
channel.processError(cause);
|
channel.processHandlerError(cause);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -431,7 +451,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
|||||||
LOG.warn(t.toString());
|
LOG.warn(t.toString());
|
||||||
BufferUtil.clear(networkBuffer.getBuffer());
|
BufferUtil.clear(networkBuffer.getBuffer());
|
||||||
releaseNetworkBuffer();
|
releaseNetworkBuffer();
|
||||||
channel.processError(t);
|
channel.processConnectionError(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,18 +496,6 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
|||||||
super.onOpen();
|
super.onOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Event for no activity on connection (read or write)
|
|
||||||
*
|
|
||||||
* @return true to signal that the endpoint must be closed, false to keep the endpoint open
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected boolean onReadTimeout(Throwable timeout)
|
|
||||||
{
|
|
||||||
channel.processError(new WebSocketTimeoutException("Timeout on Read", timeout));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setInputBufferSize(int inputBufferSize)
|
public void setInputBufferSize(int inputBufferSize)
|
||||||
{
|
{
|
||||||
@ -610,7 +618,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
|||||||
public void onCompleteFailure(Throwable x)
|
public void onCompleteFailure(Throwable x)
|
||||||
{
|
{
|
||||||
super.onCompleteFailure(x);
|
super.onCompleteFailure(x);
|
||||||
channel.processError(x);
|
channel.processConnectionError(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,11 @@
|
|||||||
|
|
||||||
package org.eclipse.jetty.websocket.core;
|
package org.eclipse.jetty.websocket.core;
|
||||||
|
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||||
import org.eclipse.jetty.server.NetworkConnector;
|
import org.eclipse.jetty.server.NetworkConnector;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
@ -39,11 +44,6 @@ import org.eclipse.jetty.websocket.core.server.internal.RFC6455Handshaker;
|
|||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import static org.eclipse.jetty.util.Callback.NOOP;
|
import static org.eclipse.jetty.util.Callback.NOOP;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
@ -65,7 +65,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
|
|
||||||
enum State
|
enum State
|
||||||
{
|
{
|
||||||
OPEN, ICLOSED, OCLOSED
|
OPEN, ISHUT, OSHUT
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
@ -93,7 +93,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ICLOSED:
|
case ISHUT:
|
||||||
{
|
{
|
||||||
TestFrameHandler serverHandler = new TestFrameHandler();
|
TestFrameHandler serverHandler = new TestFrameHandler();
|
||||||
|
|
||||||
@ -109,12 +109,12 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
assertNotNull(frame);
|
assertNotNull(frame);
|
||||||
assertThat(new CloseStatus(frame.getPayload()).getCode(), is(CloseStatus.NORMAL));
|
assertThat(new CloseStatus(frame.getPayload()).getCode(), is(CloseStatus.NORMAL));
|
||||||
|
|
||||||
assertThat(server.handler.getCoreSession().toString(), containsString("ICLOSED"));
|
assertThat(server.handler.getCoreSession().toString(), containsString("ISHUT"));
|
||||||
LOG.info("Server: ICLOSED");
|
LOG.info("Server: ISHUT");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OCLOSED:
|
case OSHUT:
|
||||||
{
|
{
|
||||||
TestFrameHandler serverHandler = new TestFrameHandler();
|
TestFrameHandler serverHandler = new TestFrameHandler();
|
||||||
|
|
||||||
@ -129,8 +129,8 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
assertNotNull(frame);
|
assertNotNull(frame);
|
||||||
assertThat(new CloseStatus(frame.getPayload()).getCode(), is(CloseStatus.NORMAL));
|
assertThat(new CloseStatus(frame.getPayload()).getCode(), is(CloseStatus.NORMAL));
|
||||||
|
|
||||||
assertThat(server.handler.getCoreSession().toString(), containsString("OCLOSED"));
|
assertThat(server.handler.getCoreSession().toString(), containsString("OSHUT"));
|
||||||
LOG.info("Server: OCLOSED");
|
LOG.info("Server: OSHUT");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
@Test
|
@Test
|
||||||
public void serverClose_ICLOSED() throws Exception
|
public void serverClose_ICLOSED() throws Exception
|
||||||
{
|
{
|
||||||
setup(State.ICLOSED);
|
setup(State.ISHUT);
|
||||||
|
|
||||||
server.handler.receivedCallback.poll().succeeded();
|
server.handler.receivedCallback.poll().succeeded();
|
||||||
Frame frame = receiveFrame(client.getInputStream());
|
Frame frame = receiveFrame(client.getInputStream());
|
||||||
@ -154,7 +154,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
@Test
|
@Test
|
||||||
public void serverDifferentClose_ICLOSED() throws Exception
|
public void serverDifferentClose_ICLOSED() throws Exception
|
||||||
{
|
{
|
||||||
setup(State.ICLOSED);
|
setup(State.ISHUT);
|
||||||
|
|
||||||
server.sendFrame(CloseStatus.toFrame(CloseStatus.SHUTDOWN));
|
server.sendFrame(CloseStatus.toFrame(CloseStatus.SHUTDOWN));
|
||||||
server.handler.receivedCallback.poll().succeeded();
|
server.handler.receivedCallback.poll().succeeded();
|
||||||
@ -171,7 +171,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
{
|
{
|
||||||
try (StacklessLogging stackless = new StacklessLogging(WebSocketChannel.class))
|
try (StacklessLogging stackless = new StacklessLogging(WebSocketChannel.class))
|
||||||
{
|
{
|
||||||
setup(State.ICLOSED);
|
setup(State.ISHUT);
|
||||||
server.handler.receivedCallback.poll().failed(new Exception("test failure"));
|
server.handler.receivedCallback.poll().failed(new Exception("test failure"));
|
||||||
|
|
||||||
Frame frame = receiveFrame(client.getInputStream());
|
Frame frame = receiveFrame(client.getInputStream());
|
||||||
@ -186,7 +186,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
@Test
|
@Test
|
||||||
public void clientClose_OCLOSED() throws Exception
|
public void clientClose_OCLOSED() throws Exception
|
||||||
{
|
{
|
||||||
setup(State.OCLOSED);
|
setup(State.OSHUT);
|
||||||
server.handler.getCoreSession().demand(1);
|
server.handler.getCoreSession().demand(1);
|
||||||
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true));
|
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true));
|
||||||
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
|
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
|
||||||
@ -201,7 +201,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
@Test
|
@Test
|
||||||
public void clientDifferentClose_OCLOSED() throws Exception
|
public void clientDifferentClose_OCLOSED() throws Exception
|
||||||
{
|
{
|
||||||
setup(State.OCLOSED);
|
setup(State.OSHUT);
|
||||||
server.handler.getCoreSession().demand(1);
|
server.handler.getCoreSession().demand(1);
|
||||||
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.BAD_PAYLOAD), true));
|
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.BAD_PAYLOAD), true));
|
||||||
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
|
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
|
||||||
@ -218,7 +218,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
{
|
{
|
||||||
try (StacklessLogging stackless = new StacklessLogging(WebSocketChannel.class))
|
try (StacklessLogging stackless = new StacklessLogging(WebSocketChannel.class))
|
||||||
{
|
{
|
||||||
setup(State.OCLOSED);
|
setup(State.OSHUT);
|
||||||
server.handler.getCoreSession().demand(1);
|
server.handler.getCoreSession().demand(1);
|
||||||
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true));
|
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true));
|
||||||
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
|
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
|
||||||
@ -246,7 +246,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
@Test
|
@Test
|
||||||
public void clientSendsBadFrame_OCLOSED() throws Exception
|
public void clientSendsBadFrame_OCLOSED() throws Exception
|
||||||
{
|
{
|
||||||
setup(State.OCLOSED);
|
setup(State.OSHUT);
|
||||||
|
|
||||||
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.PONG, "pong frame not masked", false));
|
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.PONG, "pong frame not masked", false));
|
||||||
server.handler.getCoreSession().demand(1);
|
server.handler.getCoreSession().demand(1);
|
||||||
@ -258,7 +258,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
@Test
|
@Test
|
||||||
public void clientSendsBadFrame_ICLOSED() throws Exception
|
public void clientSendsBadFrame_ICLOSED() throws Exception
|
||||||
{
|
{
|
||||||
setup(State.ICLOSED);
|
setup(State.ISHUT);
|
||||||
|
|
||||||
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.PONG, "pong frame not masked", false));
|
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.PONG, "pong frame not masked", false));
|
||||||
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
|
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
|
||||||
@ -286,7 +286,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
@Test
|
@Test
|
||||||
public void clientAborts_OCLOSED() throws Exception
|
public void clientAborts_OCLOSED() throws Exception
|
||||||
{
|
{
|
||||||
setup(State.OCLOSED);
|
setup(State.OSHUT);
|
||||||
|
|
||||||
client.close();
|
client.close();
|
||||||
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
|
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
|
||||||
@ -299,7 +299,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
@Test
|
@Test
|
||||||
public void clientAborts_ICLOSED() throws Exception
|
public void clientAborts_ICLOSED() throws Exception
|
||||||
{
|
{
|
||||||
setup(State.ICLOSED);
|
setup(State.ISHUT);
|
||||||
|
|
||||||
client.close();
|
client.close();
|
||||||
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
|
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
|
||||||
@ -330,7 +330,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
@Test
|
@Test
|
||||||
public void onFrameThrows_OCLOSED() throws Exception
|
public void onFrameThrows_OCLOSED() throws Exception
|
||||||
{
|
{
|
||||||
setup(State.OCLOSED);
|
setup(State.OSHUT);
|
||||||
|
|
||||||
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.BINARY, "binary", true));
|
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.BINARY, "binary", true));
|
||||||
|
|
||||||
@ -478,7 +478,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||||||
|
|
||||||
public boolean isOpen()
|
public boolean isOpen()
|
||||||
{
|
{
|
||||||
return handler.getCoreSession().isOpen();
|
return handler.getCoreSession().isOutputOpen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,11 @@
|
|||||||
|
|
||||||
package org.eclipse.jetty.websocket.core.client;
|
package org.eclipse.jetty.websocket.core.client;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||||
import org.eclipse.jetty.server.NetworkConnector;
|
import org.eclipse.jetty.server.NetworkConnector;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
@ -45,11 +50,6 @@ import org.hamcrest.Matchers;
|
|||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
@ -208,7 +208,7 @@ public class WebSocketClientServerTest
|
|||||||
|
|
||||||
public boolean isOpen()
|
public boolean isOpen()
|
||||||
{
|
{
|
||||||
return handler.getCoreSession().isOpen();
|
return handler.getCoreSession().isOutputOpen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ public class WebSocketClientServerTest
|
|||||||
|
|
||||||
public boolean isOpen()
|
public boolean isOpen()
|
||||||
{
|
{
|
||||||
return handler.getCoreSession().isOpen();
|
return handler.getCoreSession().isOutputOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
|
|
||||||
package org.eclipse.jetty.websocket.core.extensions;
|
package org.eclipse.jetty.websocket.core.extensions;
|
||||||
|
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||||
import org.eclipse.jetty.server.NetworkConnector;
|
import org.eclipse.jetty.server.NetworkConnector;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
@ -44,10 +48,6 @@ import org.eclipse.jetty.websocket.core.server.WebSocketUpgradeHandler;
|
|||||||
import org.eclipse.jetty.websocket.core.server.internal.RFC6455Handshaker;
|
import org.eclipse.jetty.websocket.core.server.internal.RFC6455Handshaker;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import static org.eclipse.jetty.util.Callback.NOOP;
|
import static org.eclipse.jetty.util.Callback.NOOP;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
@ -218,7 +218,7 @@ public class ValidationExtensionTest extends WebSocketTester
|
|||||||
|
|
||||||
public boolean isOpen()
|
public boolean isOpen()
|
||||||
{
|
{
|
||||||
return handler.getCoreSession().isOpen();
|
return handler.getCoreSession().isOutputOpen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,12 @@
|
|||||||
|
|
||||||
package org.eclipse.jetty.websocket.core.server;
|
package org.eclipse.jetty.websocket.core.server;
|
||||||
|
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||||
import org.eclipse.jetty.server.NetworkConnector;
|
import org.eclipse.jetty.server.NetworkConnector;
|
||||||
@ -46,12 +52,6 @@ import org.hamcrest.MatcherAssert;
|
|||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
@ -547,7 +547,7 @@ public class WebSocketServerTest extends WebSocketTester
|
|||||||
|
|
||||||
public boolean isOpen()
|
public boolean isOpen()
|
||||||
{
|
{
|
||||||
return handler.getCoreSession().isOpen();
|
return handler.getCoreSession().isOutputOpen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user