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:
Greg Wilkins 2019-01-22 13:25:29 +11:00
parent f9b9cc1313
commit 05dfbd18cd
12 changed files with 184 additions and 187 deletions

View File

@ -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

View File

@ -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();
} }
/** /**

View File

@ -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

View File

@ -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 &amp; reason) * Representation of a WebSocket Close (status code &amp; 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))
{ {

View File

@ -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;
} }

View File

@ -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;
} }
} }
}; };

View File

@ -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();

View File

@ -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);
} }
} }
} }

View File

@ -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();
} }
} }
} }

View File

@ -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();
} }
} }

View File

@ -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();
} }
} }
} }

View File

@ -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();
} }
} }
} }