410537 - Exceptions during @OnWebSocketConnect not reported to @OnWebSocketError
+ Fixed EventDriver behavior with regards to unhandled throwables during calls to the various onMethod() calls + Adding testcase to verify intended behavior
This commit is contained in:
parent
9d89bc564e
commit
a535381b53
|
@ -163,7 +163,14 @@ public abstract class EventDriver implements IncomingFrames
|
||||||
{
|
{
|
||||||
LOG.debug("openSession({})",session);
|
LOG.debug("openSession({})",session);
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.onConnect();
|
try
|
||||||
|
{
|
||||||
|
this.onConnect();
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
unhandled(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void terminateConnection(int statusCode, String rawreason)
|
protected void terminateConnection(int statusCode, String rawreason)
|
||||||
|
@ -177,6 +184,7 @@ public abstract class EventDriver implements IncomingFrames
|
||||||
private void unhandled(Throwable t)
|
private void unhandled(Throwable t)
|
||||||
{
|
{
|
||||||
LOG.warn("Unhandled Error (closing connection)",t);
|
LOG.warn("Unhandled Error (closing connection)",t);
|
||||||
|
onError(t);
|
||||||
|
|
||||||
// Unhandled Error, close the connection.
|
// Unhandled Error, close the connection.
|
||||||
switch (policy.getBehavior())
|
switch (policy.getBehavior())
|
||||||
|
|
|
@ -237,17 +237,15 @@ public class ServletWebSocketRequest extends UpgradeRequest
|
||||||
{
|
{
|
||||||
if (protocol == null)
|
if (protocol == null)
|
||||||
{
|
{
|
||||||
return new String[]
|
return new String[] {};
|
||||||
{ null };
|
|
||||||
}
|
}
|
||||||
protocol = protocol.trim();
|
protocol = protocol.trim();
|
||||||
if ((protocol == null) || (protocol.length() == 0))
|
if ((protocol == null) || (protocol.length() == 0))
|
||||||
{
|
{
|
||||||
return new String[]
|
return new String[] {};
|
||||||
{ null };
|
|
||||||
}
|
}
|
||||||
String[] passed = protocol.split("\\s*,\\s*");
|
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);
|
System.arraycopy(passed,0,protocols,0,passed.length);
|
||||||
return protocols;
|
return protocols;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
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.Session;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.api.UpgradeRequest;
|
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.CloseInfo;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
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.blockhead.BlockheadClient;
|
||||||
import org.eclipse.jetty.websocket.server.helper.IncomingFramesCapture;
|
import org.eclipse.jetty.websocket.server.helper.IncomingFramesCapture;
|
||||||
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
|
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
|
||||||
|
@ -52,28 +54,7 @@ import org.junit.Test;
|
||||||
*/
|
*/
|
||||||
public class WebSocketCloseTest
|
public class WebSocketCloseTest
|
||||||
{
|
{
|
||||||
@SuppressWarnings("serial")
|
static class AbstractCloseSocket extends WebSocketAdapter
|
||||||
public static class CloseServlet extends WebSocketServlet implements WebSocketCreator
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void configure(WebSocketServletFactory factory)
|
|
||||||
{
|
|
||||||
factory.setCreator(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object createWebSocket(UpgradeRequest req, UpgradeResponse resp)
|
|
||||||
{
|
|
||||||
if (req.hasSubProtocol("fastclose"))
|
|
||||||
{
|
|
||||||
fastcloseSocket = new FastCloseSocket();
|
|
||||||
return fastcloseSocket;
|
|
||||||
}
|
|
||||||
return new RFCSocket();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class FastCloseSocket extends WebSocketAdapter
|
|
||||||
{
|
{
|
||||||
public CountDownLatch closeLatch = new CountDownLatch(1);
|
public CountDownLatch closeLatch = new CountDownLatch(1);
|
||||||
public String closeReason = null;
|
public String closeReason = null;
|
||||||
|
@ -89,6 +70,48 @@ public class WebSocketCloseTest
|
||||||
closeLatch.countDown();
|
closeLatch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWebSocketError(Throwable cause)
|
||||||
|
{
|
||||||
|
errors.add(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public static class CloseServlet extends WebSocketServlet implements WebSocketCreator
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void configure(WebSocketServletFactory factory)
|
||||||
|
{
|
||||||
|
factory.setCreator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createWebSocket(UpgradeRequest req, UpgradeResponse resp)
|
||||||
|
{
|
||||||
|
if (req.hasSubProtocol("fastclose"))
|
||||||
|
{
|
||||||
|
closeSocket = new FastCloseSocket();
|
||||||
|
return closeSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.hasSubProtocol("fastfail"))
|
||||||
|
{
|
||||||
|
closeSocket = new FastFailSocket();
|
||||||
|
return closeSocket;
|
||||||
|
}
|
||||||
|
return new RFCSocket();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On Connect, close socket
|
||||||
|
*/
|
||||||
|
public static class FastCloseSocket extends AbstractCloseSocket
|
||||||
|
{
|
||||||
|
private static final Logger LOG = Log.getLogger(WebSocketCloseTest.FastCloseSocket.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWebSocketConnect(Session sess)
|
public void onWebSocketConnect(Session sess)
|
||||||
{
|
{
|
||||||
|
@ -102,6 +125,21 @@ public class WebSocketCloseTest
|
||||||
e.printStackTrace(System.err);
|
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
|
@Override
|
||||||
public void onWebSocketError(Throwable cause)
|
public void onWebSocketError(Throwable cause)
|
||||||
|
@ -111,8 +149,9 @@ public class WebSocketCloseTest
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Logger LOG = Log.getLogger(WebSocketCloseTest.class);
|
private static final Logger LOG = Log.getLogger(WebSocketCloseTest.class);
|
||||||
|
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
private static FastCloseSocket fastcloseSocket;
|
private static AbstractCloseSocket closeSocket;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void startServer() throws Exception
|
public static void startServer() throws Exception
|
||||||
|
@ -150,8 +189,44 @@ public class WebSocketCloseTest
|
||||||
|
|
||||||
client.write(close.asFrame()); // respond with close
|
client.write(close.asFrame()); // respond with close
|
||||||
|
|
||||||
Assert.assertThat("Fast Close Latch",fastcloseSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
Assert.assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
||||||
Assert.assertThat("Fast Close.statusCode",fastcloseSocket.closeStatusCode,is(StatusCode.NORMAL));
|
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
|
finally
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue