Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/EventDriver.java10
-rw-r--r--jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/ServletWebSocketRequest.java8
-rw-r--r--jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java113
3 files changed, 106 insertions, 25 deletions
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/EventDriver.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/EventDriver.java
index d217937d47..5461df4188 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/EventDriver.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/events/EventDriver.java
@@ -163,7 +163,14 @@ public abstract class EventDriver implements IncomingFrames
{
LOG.debug("openSession({})",session);
this.session = session;
- this.onConnect();
+ try
+ {
+ this.onConnect();
+ }
+ catch (Throwable t)
+ {
+ unhandled(t);
+ }
}
protected void terminateConnection(int statusCode, String rawreason)
@@ -177,6 +184,7 @@ public abstract class EventDriver implements IncomingFrames
private void unhandled(Throwable t)
{
LOG.warn("Unhandled Error (closing connection)",t);
+ onError(t);
// Unhandled Error, close the connection.
switch (policy.getBehavior())
diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/ServletWebSocketRequest.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/ServletWebSocketRequest.java
index e274c963ee..66140c8073 100644
--- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/ServletWebSocketRequest.java
+++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/ServletWebSocketRequest.java
@@ -237,17 +237,15 @@ public class ServletWebSocketRequest extends UpgradeRequest
{
if (protocol == null)
{
- return new String[]
- { null };
+ return new String[] {};
}
protocol = protocol.trim();
if ((protocol == null) || (protocol.length() == 0))
{
- return new String[]
- { null };
+ return new String[] {};
}
String[] passed = protocol.split("\\s*,\\s*");
- String[] protocols = new String[passed.length + 1];
+ String[] protocols = new String[passed.length];
System.arraycopy(passed,0,protocols,0,passed.length);
return protocols;
}
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java
index 00c001bcd2..aafdea8946 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketCloseTest.java
@@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.log.StacklessLogging;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.UpgradeRequest;
@@ -36,6 +37,7 @@ import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.eclipse.jetty.websocket.common.CloseInfo;
import org.eclipse.jetty.websocket.common.OpCode;
import org.eclipse.jetty.websocket.common.WebSocketFrame;
+import org.eclipse.jetty.websocket.common.events.EventDriver;
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
import org.eclipse.jetty.websocket.server.helper.IncomingFramesCapture;
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
@@ -52,6 +54,30 @@ import org.junit.Test;
*/
public class WebSocketCloseTest
{
+ static class AbstractCloseSocket extends WebSocketAdapter
+ {
+ public CountDownLatch closeLatch = new CountDownLatch(1);
+ public String closeReason = null;
+ public int closeStatusCode = -1;
+ public List<Throwable> errors = new ArrayList<>();
+
+ @Override
+ public void onWebSocketClose(int statusCode, String reason)
+ {
+ LOG.debug("onWebSocketClose({}, {})",statusCode,reason);
+ this.closeStatusCode = statusCode;
+ this.closeReason = reason;
+ closeLatch.countDown();
+ }
+
+ @Override
+ public void onWebSocketError(Throwable cause)
+ {
+ errors.add(cause);
+ }
+
+ }
+
@SuppressWarnings("serial")
public static class CloseServlet extends WebSocketServlet implements WebSocketCreator
{
@@ -66,28 +92,25 @@ public class WebSocketCloseTest
{
if (req.hasSubProtocol("fastclose"))
{
- fastcloseSocket = new FastCloseSocket();
- return fastcloseSocket;
+ closeSocket = new FastCloseSocket();
+ return closeSocket;
+ }
+
+ if (req.hasSubProtocol("fastfail"))
+ {
+ closeSocket = new FastFailSocket();
+ return closeSocket;
}
return new RFCSocket();
}
}
- public static class FastCloseSocket extends WebSocketAdapter
+ /**
+ * On Connect, close socket
+ */
+ public static class FastCloseSocket extends AbstractCloseSocket
{
- public CountDownLatch closeLatch = new CountDownLatch(1);
- public String closeReason = null;
- public int closeStatusCode = -1;
- public List<Throwable> errors = new ArrayList<>();
-
- @Override
- public void onWebSocketClose(int statusCode, String reason)
- {
- LOG.debug("onWebSocketClose({}, {})",statusCode,reason);
- this.closeStatusCode = statusCode;
- this.closeReason = reason;
- closeLatch.countDown();
- }
+ private static final Logger LOG = Log.getLogger(WebSocketCloseTest.FastCloseSocket.class);
@Override
public void onWebSocketConnect(Session sess)
@@ -102,6 +125,21 @@ public class WebSocketCloseTest
e.printStackTrace(System.err);
}
}
+ }
+
+ /**
+ * On Connect, throw unhandled exception
+ */
+ public static class FastFailSocket extends AbstractCloseSocket
+ {
+ private static final Logger LOG = Log.getLogger(WebSocketCloseTest.FastFailSocket.class);
+
+ @Override
+ public void onWebSocketConnect(Session sess)
+ {
+ LOG.debug("onWebSocketConnect({})",sess);
+ throw new RuntimeException("Intentional FastFail");
+ }
@Override
public void onWebSocketError(Throwable cause)
@@ -111,8 +149,9 @@ public class WebSocketCloseTest
}
private static final Logger LOG = Log.getLogger(WebSocketCloseTest.class);
+
private static SimpleServletServer server;
- private static FastCloseSocket fastcloseSocket;
+ private static AbstractCloseSocket closeSocket;
@BeforeClass
public static void startServer() throws Exception
@@ -150,8 +189,44 @@ public class WebSocketCloseTest
client.write(close.asFrame()); // respond with close
- Assert.assertThat("Fast Close Latch",fastcloseSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
- Assert.assertThat("Fast Close.statusCode",fastcloseSocket.closeStatusCode,is(StatusCode.NORMAL));
+ Assert.assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
+ Assert.assertThat("Fast Close.statusCode",closeSocket.closeStatusCode,is(StatusCode.NORMAL));
+ }
+ finally
+ {
+ client.close();
+ }
+ }
+
+ /**
+ * Test fast fail (bug #410537)
+ */
+ @Test
+ public void testFastFail() throws Exception
+ {
+ BlockheadClient client = new BlockheadClient(server.getServerUri());
+ client.setProtocols("fastfail");
+ client.setTimeout(TimeUnit.SECONDS,1);
+ try
+ {
+ try (StacklessLogging scope = new StacklessLogging(EventDriver.class))
+ {
+ client.connect();
+ client.sendStandardRequest();
+ client.expectUpgradeResponse();
+
+ IncomingFramesCapture capture = client.readFrames(1,TimeUnit.SECONDS,1);
+ WebSocketFrame frame = capture.getFrames().poll();
+ Assert.assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
+ CloseInfo close = new CloseInfo(frame);
+ Assert.assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR));
+
+ client.write(close.asFrame()); // respond with close
+
+ Assert.assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
+ Assert.assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR));
+ Assert.assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1));
+ }
}
finally
{

Back to the top