mirror of
https://github.com/jetty/jetty.project.git
synced 2025-03-03 12:29:31 +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
@ -128,7 +128,18 @@ public interface Callback extends Invocable
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
static Callback from(Runnable completed)
|
||||
{
|
||||
return new Completing()
|
||||
{
|
||||
public void completed()
|
||||
{
|
||||
completed.run();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class Completing implements Callback
|
||||
{
|
||||
@Override
|
||||
|
@ -18,24 +18,6 @@
|
||||
|
||||
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.net.URI;
|
||||
import java.security.Principal;
|
||||
@ -48,6 +30,25 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
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.
|
||||
*/
|
||||
@ -535,7 +536,7 @@ public class JavaxWebSocketSession extends AbstractLifeCycle implements javax.we
|
||||
@Override
|
||||
public boolean isOpen()
|
||||
{
|
||||
return coreSession.isOpen();
|
||||
return coreSession.isOutputOpen();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,11 @@
|
||||
|
||||
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.websocket.api.CloseStatus;
|
||||
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.core.FrameHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
import java.time.Duration;
|
||||
import java.util.Objects;
|
||||
|
||||
public class WebSocketSessionImpl implements Session, Dumpable
|
||||
{
|
||||
private final FrameHandler.CoreSession coreSession;
|
||||
@ -160,7 +160,7 @@ public class WebSocketSessionImpl implements Session, Dumpable
|
||||
@Override
|
||||
public boolean isOpen()
|
||||
{
|
||||
return remoteEndpoint.getCoreSession().isOpen();
|
||||
return remoteEndpoint.getCoreSession().isOutputOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,14 +18,13 @@
|
||||
|
||||
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.charset.StandardCharsets;
|
||||
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)
|
||||
@ -194,7 +193,7 @@ public class CloseStatus
|
||||
|
||||
int len = 2; // status code
|
||||
|
||||
byte reasonBytes[] = null;
|
||||
byte[] reasonBytes = null;
|
||||
|
||||
if (reason != null)
|
||||
{
|
||||
@ -208,7 +207,7 @@ public class CloseStatus
|
||||
ByteBuffer buf = BufferUtil.allocate(len);
|
||||
BufferUtil.flipToFill(buf);
|
||||
buf.put((byte)((statusCode >>> 8) & 0xFF));
|
||||
buf.put((byte)((statusCode >>> 0) & 0xFF));
|
||||
buf.put((byte)(statusCode & 0xFF));
|
||||
|
||||
if ((reasonBytes != null) && (reasonBytes.length > 0))
|
||||
{
|
||||
|
@ -270,7 +270,7 @@ public interface FrameHandler extends IncomingFrames
|
||||
/**
|
||||
* @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.
|
||||
@ -374,7 +374,7 @@ public interface FrameHandler extends IncomingFrames
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen()
|
||||
public boolean isOutputOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -20,13 +20,13 @@ package org.eclipse.jetty.websocket.core.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
@ -235,11 +235,16 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen()
|
||||
public boolean isOutputOpen()
|
||||
{
|
||||
return channelState.isOutputOpen();
|
||||
}
|
||||
|
||||
public boolean isClosed()
|
||||
{
|
||||
return channelState.isClosed();
|
||||
}
|
||||
|
||||
public void setWebSocketConnection(WebSocketConnection connection)
|
||||
{
|
||||
this.connection = connection;
|
||||
@ -306,75 +311,56 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
||||
{
|
||||
handler.onClosed(closeStatus);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Throwable 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
|
||||
*/
|
||||
public void processError(Throwable cause)
|
||||
public void processConnectionError(Throwable cause)
|
||||
{
|
||||
CloseStatus closeStatus;
|
||||
CloseStatus closeStatus = closeStatusFor(cause);
|
||||
|
||||
if (cause instanceof Utf8Appendable.NotUtf8Exception)
|
||||
{
|
||||
closeStatus = new CloseStatus(CloseStatus.BAD_PAYLOAD, cause.getMessage());
|
||||
}
|
||||
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());
|
||||
}
|
||||
Callback callback = Callback.from(()->{onClosed(cause, closeStatus);connection.close();});
|
||||
|
||||
if (closeStatus.getCode() == CloseStatus.PROTOCOL)
|
||||
close(closeStatus, callback, false);
|
||||
else
|
||||
{
|
||||
LOG.warn("Unhandled Error (closing connection)", cause);
|
||||
callback.succeeded();
|
||||
}
|
||||
|
||||
// Exception on end-user WS-Endpoint.
|
||||
// Fast-fail & close connection with reason.
|
||||
int statusCode = CloseStatus.SERVER_ERROR;
|
||||
if (behavior == Behavior.CLIENT)
|
||||
statusCode = CloseStatus.POLICY_VIOLATION;
|
||||
|
||||
closeStatus = new CloseStatus(statusCode, cause.getMessage());
|
||||
}
|
||||
|
||||
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);
|
||||
/**
|
||||
* Process an Error that originated from the handler.
|
||||
*
|
||||
* @param cause the cause
|
||||
*/
|
||||
public void processHandlerError(Throwable cause)
|
||||
{
|
||||
CloseStatus closeStatus = closeStatusFor(cause);
|
||||
close(closeStatus, Callback.from(()->onClosed(cause, closeStatus)), false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -393,27 +379,19 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("ConnectionState: Transition to CONNECTED");
|
||||
|
||||
try
|
||||
{
|
||||
// Open connection and handler
|
||||
channelState.onOpen();
|
||||
handler.onOpen(this);
|
||||
if (!demanding)
|
||||
connection.demand(1);
|
||||
// Open connection and handler
|
||||
channelState.onOpen();
|
||||
handler.onOpen(this);
|
||||
if (!demanding)
|
||||
connection.demand(1);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
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));
|
||||
}
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("ConnectionState: Transition to OPEN");
|
||||
}
|
||||
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())
|
||||
LOG.debug("sendFrame({}, {}, {})", frame, callback, batch);
|
||||
|
||||
boolean closed;
|
||||
boolean closeConnection;
|
||||
try
|
||||
{
|
||||
assertValidOutgoing(frame);
|
||||
closed = channelState.checkOutgoing(frame);
|
||||
closeConnection = channelState.onOutgoingFrame(frame);
|
||||
}
|
||||
catch (Throwable ex)
|
||||
{
|
||||
@ -476,7 +454,7 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("close({}, {}, {})", CloseStatus.getCloseStatus(frame), callback, batch);
|
||||
|
||||
if (closed)
|
||||
if (closeConnection)
|
||||
{
|
||||
callback = new Callback.Nested(callback)
|
||||
{
|
||||
@ -613,14 +591,13 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
||||
LOG.debug("receiveFrame({}, {}) - connectionState={}, handler={}",
|
||||
frame, callback, channelState, handler);
|
||||
|
||||
|
||||
boolean closed = channelState.checkIncoming(frame);
|
||||
boolean closeConnection = channelState.onIncomingFrame(frame);
|
||||
|
||||
// Handle inbound close
|
||||
if (frame.getOpCode() == OpCode.CLOSE)
|
||||
{
|
||||
connection.cancelDemand();
|
||||
if (closed)
|
||||
if (closeConnection)
|
||||
{
|
||||
callback = new Callback.Nested(callback)
|
||||
{
|
||||
@ -648,8 +625,9 @@ public class WebSocketChannel implements IncomingFrames, FrameHandler.CoreSessio
|
||||
LOG.debug("ConnectionState: sending close response {}", closeStatus);
|
||||
|
||||
// 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);
|
||||
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();
|
||||
boolean fin = frame.isFin();
|
||||
@ -153,7 +153,7 @@ public class WebSocketChannelState
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean checkIncoming(Frame frame) throws ProtocolException
|
||||
public boolean onIncomingFrame(Frame frame) throws ProtocolException
|
||||
{
|
||||
byte opcode = frame.getOpCode();
|
||||
boolean fin = frame.isFin();
|
||||
|
@ -18,6 +18,13 @@
|
||||
|
||||
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.ByteBufferPool;
|
||||
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.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
|
||||
*/
|
||||
@ -167,9 +167,12 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("onClose() of physical connection");
|
||||
|
||||
// TODO review all close paths
|
||||
IOException e = new IOException("Closed");
|
||||
channel.onClosed(e);
|
||||
if (!channel.isClosed())
|
||||
{
|
||||
IOException e = new IOException("Closed");
|
||||
channel.onClosed(e);
|
||||
}
|
||||
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
@ -179,10 +182,27 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
||||
if (LOG.isDebugEnabled())
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
@ -219,7 +239,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
||||
referenced.release();
|
||||
|
||||
// notify session & endpoint
|
||||
channel.processError(cause);
|
||||
channel.processHandlerError(cause);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -431,7 +451,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
||||
LOG.warn(t.toString());
|
||||
BufferUtil.clear(networkBuffer.getBuffer());
|
||||
releaseNetworkBuffer();
|
||||
channel.processError(t);
|
||||
channel.processConnectionError(t);
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,18 +496,6 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
||||
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
|
||||
public void setInputBufferSize(int inputBufferSize)
|
||||
{
|
||||
@ -610,7 +618,7 @@ public class WebSocketConnection extends AbstractConnection implements Connectio
|
||||
public void onCompleteFailure(Throwable x)
|
||||
{
|
||||
super.onCompleteFailure(x);
|
||||
channel.processError(x);
|
||||
channel.processConnectionError(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,11 @@
|
||||
|
||||
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.NetworkConnector;
|
||||
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.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.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
@ -65,7 +65,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
|
||||
enum State
|
||||
{
|
||||
OPEN, ICLOSED, OCLOSED
|
||||
OPEN, ISHUT, OSHUT
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
@ -93,7 +93,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
|
||||
break;
|
||||
}
|
||||
case ICLOSED:
|
||||
case ISHUT:
|
||||
{
|
||||
TestFrameHandler serverHandler = new TestFrameHandler();
|
||||
|
||||
@ -109,12 +109,12 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
assertNotNull(frame);
|
||||
assertThat(new CloseStatus(frame.getPayload()).getCode(), is(CloseStatus.NORMAL));
|
||||
|
||||
assertThat(server.handler.getCoreSession().toString(), containsString("ICLOSED"));
|
||||
LOG.info("Server: ICLOSED");
|
||||
assertThat(server.handler.getCoreSession().toString(), containsString("ISHUT"));
|
||||
LOG.info("Server: ISHUT");
|
||||
|
||||
break;
|
||||
}
|
||||
case OCLOSED:
|
||||
case OSHUT:
|
||||
{
|
||||
TestFrameHandler serverHandler = new TestFrameHandler();
|
||||
|
||||
@ -129,8 +129,8 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
assertNotNull(frame);
|
||||
assertThat(new CloseStatus(frame.getPayload()).getCode(), is(CloseStatus.NORMAL));
|
||||
|
||||
assertThat(server.handler.getCoreSession().toString(), containsString("OCLOSED"));
|
||||
LOG.info("Server: OCLOSED");
|
||||
assertThat(server.handler.getCoreSession().toString(), containsString("OSHUT"));
|
||||
LOG.info("Server: OSHUT");
|
||||
|
||||
break;
|
||||
}
|
||||
@ -140,7 +140,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
@Test
|
||||
public void serverClose_ICLOSED() throws Exception
|
||||
{
|
||||
setup(State.ICLOSED);
|
||||
setup(State.ISHUT);
|
||||
|
||||
server.handler.receivedCallback.poll().succeeded();
|
||||
Frame frame = receiveFrame(client.getInputStream());
|
||||
@ -154,7 +154,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
@Test
|
||||
public void serverDifferentClose_ICLOSED() throws Exception
|
||||
{
|
||||
setup(State.ICLOSED);
|
||||
setup(State.ISHUT);
|
||||
|
||||
server.sendFrame(CloseStatus.toFrame(CloseStatus.SHUTDOWN));
|
||||
server.handler.receivedCallback.poll().succeeded();
|
||||
@ -171,7 +171,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
{
|
||||
try (StacklessLogging stackless = new StacklessLogging(WebSocketChannel.class))
|
||||
{
|
||||
setup(State.ICLOSED);
|
||||
setup(State.ISHUT);
|
||||
server.handler.receivedCallback.poll().failed(new Exception("test failure"));
|
||||
|
||||
Frame frame = receiveFrame(client.getInputStream());
|
||||
@ -186,7 +186,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
@Test
|
||||
public void clientClose_OCLOSED() throws Exception
|
||||
{
|
||||
setup(State.OCLOSED);
|
||||
setup(State.OSHUT);
|
||||
server.handler.getCoreSession().demand(1);
|
||||
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true));
|
||||
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
|
||||
@ -201,7 +201,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
@Test
|
||||
public void clientDifferentClose_OCLOSED() throws Exception
|
||||
{
|
||||
setup(State.OCLOSED);
|
||||
setup(State.OSHUT);
|
||||
server.handler.getCoreSession().demand(1);
|
||||
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.BAD_PAYLOAD), true));
|
||||
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
|
||||
@ -218,7 +218,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
{
|
||||
try (StacklessLogging stackless = new StacklessLogging(WebSocketChannel.class))
|
||||
{
|
||||
setup(State.OCLOSED);
|
||||
setup(State.OSHUT);
|
||||
server.handler.getCoreSession().demand(1);
|
||||
client.getOutputStream().write(RawFrameBuilder.buildClose(new CloseStatus(CloseStatus.NORMAL), true));
|
||||
assertNotNull(server.handler.receivedFrames.poll(10, TimeUnit.SECONDS));
|
||||
@ -246,7 +246,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
@Test
|
||||
public void clientSendsBadFrame_OCLOSED() throws Exception
|
||||
{
|
||||
setup(State.OCLOSED);
|
||||
setup(State.OSHUT);
|
||||
|
||||
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.PONG, "pong frame not masked", false));
|
||||
server.handler.getCoreSession().demand(1);
|
||||
@ -258,7 +258,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
@Test
|
||||
public void clientSendsBadFrame_ICLOSED() throws Exception
|
||||
{
|
||||
setup(State.ICLOSED);
|
||||
setup(State.ISHUT);
|
||||
|
||||
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.PONG, "pong frame not masked", false));
|
||||
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
|
||||
@ -286,7 +286,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
@Test
|
||||
public void clientAborts_OCLOSED() throws Exception
|
||||
{
|
||||
setup(State.OCLOSED);
|
||||
setup(State.OSHUT);
|
||||
|
||||
client.close();
|
||||
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
|
||||
@ -299,7 +299,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
@Test
|
||||
public void clientAborts_ICLOSED() throws Exception
|
||||
{
|
||||
setup(State.ICLOSED);
|
||||
setup(State.ISHUT);
|
||||
|
||||
client.close();
|
||||
assertFalse(server.handler.closed.await(250, TimeUnit.MILLISECONDS));
|
||||
@ -330,7 +330,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
@Test
|
||||
public void onFrameThrows_OCLOSED() throws Exception
|
||||
{
|
||||
setup(State.OCLOSED);
|
||||
setup(State.OSHUT);
|
||||
|
||||
client.getOutputStream().write(RawFrameBuilder.buildFrame(OpCode.BINARY, "binary", true));
|
||||
|
||||
@ -478,7 +478,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
||||
|
||||
public boolean isOpen()
|
||||
{
|
||||
return handler.getCoreSession().isOpen();
|
||||
return handler.getCoreSession().isOutputOpen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,11 @@
|
||||
|
||||
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.NetworkConnector;
|
||||
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.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.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
@ -208,7 +208,7 @@ public class WebSocketClientServerTest
|
||||
|
||||
public boolean isOpen()
|
||||
{
|
||||
return handler.getCoreSession().isOpen();
|
||||
return handler.getCoreSession().isOutputOpen();
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,7 +272,7 @@ public class WebSocketClientServerTest
|
||||
|
||||
public boolean isOpen()
|
||||
{
|
||||
return handler.getCoreSession().isOpen();
|
||||
return handler.getCoreSession().isOutputOpen();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,10 @@
|
||||
|
||||
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.NetworkConnector;
|
||||
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.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.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
@ -218,7 +218,7 @@ public class ValidationExtensionTest extends WebSocketTester
|
||||
|
||||
public boolean isOpen()
|
||||
{
|
||||
return handler.getCoreSession().isOpen();
|
||||
return handler.getCoreSession().isOutputOpen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,12 @@
|
||||
|
||||
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.server.HttpConnectionFactory;
|
||||
import org.eclipse.jetty.server.NetworkConnector;
|
||||
@ -46,12 +52,6 @@ import org.hamcrest.MatcherAssert;
|
||||
import org.hamcrest.Matchers;
|
||||
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.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
@ -547,7 +547,7 @@ public class WebSocketServerTest extends WebSocketTester
|
||||
|
||||
public boolean isOpen()
|
||||
{
|
||||
return handler.getCoreSession().isOpen();
|
||||
return handler.getCoreSession().isOutputOpen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user