diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java index 3402fb5b582..1500064c44b 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderManySmallTest.java @@ -37,7 +37,6 @@ import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.WebSocketContainer; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -49,7 +48,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; @Ignore("Not working atm") @@ -165,9 +163,6 @@ public class DecoderReaderManySmallTest private static final Logger LOG = Log.getLogger(DecoderReaderManySmallTest.class); - @Rule - public TestTracker tt = new TestTracker(); - private BlockheadServer server; private WebSocketContainer client; diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java index c3ffc6909ca..56792c47554 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/DecoderReaderTest.java @@ -42,7 +42,6 @@ import javax.websocket.OnMessage; import javax.websocket.WebSocketContainer; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; @@ -57,7 +56,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; public class DecoderReaderTest @@ -229,9 +227,6 @@ public class DecoderReaderTest private static final Logger LOG = Log.getLogger(DecoderReaderTest.class); - @Rule - public TestTracker tt = new TestTracker(); - private BlockheadServer server; private WebSocketContainer client; diff --git a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java index d8ac993af07..807ca8444e2 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java +++ b/jetty-websocket/javax-websocket-client-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/EncoderTest.java @@ -41,7 +41,6 @@ import javax.websocket.Session; import javax.websocket.WebSocketContainer; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -51,7 +50,6 @@ import org.eclipse.jetty.websocket.common.test.Timeouts; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; public class EncoderTest @@ -186,8 +184,6 @@ public class EncoderTest private static final Logger LOG = Log.getLogger(EncoderTest.class); - @Rule - public TestTracker tt = new TestTracker(); private BlockheadServer server; private WebSocketContainer client; diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java index 9042d4f4a4b..93ac72667c0 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ConfiguratorTest.java @@ -35,7 +35,9 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TimeZone; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -51,6 +53,9 @@ import javax.websocket.server.HandshakeRequest; import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpointConfig; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletContextHandler; @@ -60,8 +65,8 @@ import org.eclipse.jetty.websocket.api.util.QuoteUtil; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.HttpResponse; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer; import org.junit.AfterClass; @@ -356,7 +361,8 @@ public class ConfiguratorTest return dateFormat; } } - + + private static BlockheadClient client; private static Server server; private static URI baseServerUri; @@ -408,18 +414,35 @@ public class ConfiguratorTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testEmptyConfigurator() throws Exception { URI uri = baseServerUri.resolve("/empty"); - try (IBlockheadClient client = new BlockheadClient(uri)) + BlockheadClientRequest request = client.newWsRequest(uri); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "identity"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.addExtensions("identity"); - client.connect(); - client.sendStandardRequest(); - HttpResponse response = client.readResponseHeader(); - Assert.assertThat("response.extensions", response.getExtensionsHeader(), is("identity")); + HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders(); + HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); + Assert.assertThat("response.extensions", extensionHeader.getValue(), is("identity")); } } @@ -428,16 +451,19 @@ public class ConfiguratorTest { URI uri = baseServerUri.resolve("/no-extensions"); - try (IBlockheadClient client = new BlockheadClient(uri)) + BlockheadClientRequest request = client.newWsRequest(uri); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "identity"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.addExtensions("identity"); - client.connect(); - client.sendStandardRequest(); - HttpResponse response = client.expectUpgradeResponse(); - assertThat("response.extensions", response.getExtensionsHeader(), nullValue()); + HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders(); + HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); + assertThat("response.extensions", extensionHeader, is(nullValue())); - client.write(new TextFrame().setPayload("NegoExts")); - LinkedBlockingQueue frames = client.getFrameQueue(); + clientConn.write(new TextFrame().setPayload("NegoExts")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("Frame Response", frame.getPayloadAsUTF8(), is("negotiatedExtensions=[]")); } @@ -448,15 +474,15 @@ public class ConfiguratorTest { URI uri = baseServerUri.resolve("/capture-request-headers"); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("X-Dummy: Bogus\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + request.header("X-Dummy", "Bogus"); - client.write(new TextFrame().setPayload("X-Dummy")); - LinkedBlockingQueue frames = client.getFrameQueue(); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("X-Dummy")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Request Header [X-Dummy]: \"Bogus\"")); } @@ -468,33 +494,32 @@ public class ConfiguratorTest URI uri = baseServerUri.resolve("/unique-user-props"); // First request - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("apple")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("apple")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [apple] = \"fruit from tree\"")); } // Second request - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - client.write(new TextFrame().setPayload("apple")); - client.write(new TextFrame().setPayload("blueberry")); - LinkedBlockingQueue frames = client.getFrameQueue(); + request = client.newWsRequest(uri); + connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("apple")); + clientConn.write(new TextFrame().setPayload("blueberry")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); // should have no value Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [apple] = ")); - frame = frames.poll(); + frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [blueberry] = \"fruit from bush\"")); } } @@ -504,18 +529,16 @@ public class ConfiguratorTest { URI uri = baseServerUri.resolve("/addr"); - // First request - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - InetSocketAddress expectedLocal = client.getLocalSocketAddress(); - InetSocketAddress expectedRemote = client.getRemoteSocketAddress(); + BlockheadClientRequest request = client.newWsRequest(uri); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("addr")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + InetSocketAddress expectedLocal = clientConn.getLocalSocketAddress(); + InetSocketAddress expectedRemote = clientConn.getRemoteSocketAddress(); + + clientConn.write(new TextFrame().setPayload("addr")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); StringWriter expected = new StringWriter(); @@ -540,15 +563,14 @@ public class ConfiguratorTest URI uri = baseServerUri.resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("Sec-WebSocket-Protocol: echo\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "echo"); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("getProtocols")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("getProtocols")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\"]")); } @@ -564,15 +586,14 @@ public class ConfiguratorTest URI uri = baseServerUri.resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("Sec-WebSocket-Protocol: echo, chat, status\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "echo, chat, status"); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("getProtocols")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("getProtocols")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]")); } @@ -588,15 +609,14 @@ public class ConfiguratorTest URI uri = baseServerUri.resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("sec-websocket-protocol: echo, chat, status\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + request.header("sec-websocket-protocol", "echo, chat, status"); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("getProtocols")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("getProtocols")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]")); } @@ -612,15 +632,15 @@ public class ConfiguratorTest URI uri = baseServerUri.resolve("/protocols"); ProtocolsConfigurator.seenProtocols.set(null); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("Sec-Websocket-Protocol: echo, chat, status\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + // We see "Websocket" (no capital "S" often) + request.header("Sec-Websocket-Protocol", "echo, chat, status"); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("getProtocols")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("getProtocols")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]")); } @@ -634,15 +654,15 @@ public class ConfiguratorTest { URI uri = baseServerUri.resolve("/timedecoder"); - try (BlockheadClient client = new BlockheadClient(uri)) - { - client.addHeader("Sec-Websocket-Protocol: gmt\r\n"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + // We see "Websocket" (no capital "S" often) + request.header("SeC-WeBsOcKeT-PrOtOcOl", "gmt"); + Future connFut = request.sendAsync(); - client.write(new TextFrame().setPayload("2016-06-20T14:27:44")); - LinkedBlockingQueue frames = client.getFrameQueue(); + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { + clientConn.write(new TextFrame().setPayload("2016-06-20T14:27:44")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("cal=2016.06.20 AD at 14:27:44 +0000")); } diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java index b4b95d9c803..b836c4dcb8a 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/EchoTest.java @@ -249,7 +249,6 @@ public class EchoTest public EchoTest(EchoCase testcase) { this.testcase = testcase; - System.err.println(testcase); } @Test(timeout=2000) diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java index 0c168b60381..80a1a51bf72 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/ServerAnnotatedEndpointScanner_GoodSignaturesTest.java @@ -179,7 +179,6 @@ public class ServerAnnotatedEndpointScanner_GoodSignaturesTest public ServerAnnotatedEndpointScanner_GoodSignaturesTest(Case testcase) { this.testcase = testcase; - System.err.printf("Testing signature of %s%n",testcase.pojo.getName()); } @Test diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/BadNetworkTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/BadNetworkTest.java index 94cd12c0b6e..85a26b59156 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/BadNetworkTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/BadNetworkTest.java @@ -24,14 +24,12 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.test.BlockheadServer; import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.junit.After; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; /** @@ -39,9 +37,6 @@ import org.junit.Test; */ public class BadNetworkTest { - @Rule - public TestTracker tt = new TestTracker(); - public ByteBufferPool bufferPool = new MappedByteBufferPool(); private BlockheadServer server; diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java index 2b7ffe5e1e8..62da4dd5f7e 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientCloseTest.java @@ -51,7 +51,6 @@ import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.ManagedSelector; import org.eclipse.jetty.io.SelectorManager; import org.eclipse.jetty.io.SocketChannelEndPoint; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -76,7 +75,6 @@ import org.hamcrest.Matcher; import org.junit.After; import org.junit.Before; import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; public class ClientCloseTest @@ -178,9 +176,6 @@ public class ClientCloseTest } } - @Rule - public TestTracker tt = new TestTracker(); - private BlockheadServer server; private WebSocketClient client; diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientConnectTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientConnectTest.java index e1c842df49f..5b570fb4053 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientConnectTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ClientConnectTest.java @@ -39,7 +39,6 @@ import java.util.concurrent.TimeoutException; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.UpgradeException; import org.eclipse.jetty.websocket.common.AcceptHash; @@ -49,7 +48,6 @@ import org.hamcrest.Matcher; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; /** @@ -58,9 +56,6 @@ import org.junit.Test; @SuppressWarnings("Duplicates") public class ClientConnectTest { - @Rule - public TestTracker tt = new TestTracker(); - public ByteBufferPool bufferPool = new MappedByteBufferPool(); private final int timeout = 500; diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ConnectionManagerTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ConnectionManagerTest.java index 205c221855d..77511c95d31 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ConnectionManagerTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/ConnectionManagerTest.java @@ -24,17 +24,12 @@ import java.net.InetSocketAddress; import java.net.URI; import java.net.URISyntaxException; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.websocket.client.io.ConnectionManager; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; public class ConnectionManagerTest { - @Rule - public TestTracker tt = new TestTracker(); - private void assertToSocketAddress(String uriStr, String expectedHost, int expectedPort) throws URISyntaxException { URI uri = new URI(uriStr); diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowClientTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowClientTest.java index 7dde15b797f..d727c44b176 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowClientTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowClientTest.java @@ -18,14 +18,12 @@ package org.eclipse.jetty.websocket.client; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.is; import java.net.URI; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.TestTracker; -import org.eclipse.jetty.toolchain.test.annotation.Slow; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.test.BlockheadServer; @@ -33,14 +31,10 @@ import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; public class SlowClientTest { - @Rule - public TestTracker tt = new TestTracker(); - private BlockheadServer server; private WebSocketClient client; @@ -72,7 +66,6 @@ public class SlowClientTest } @Test - @Slow public void testClientSlowToSend() throws Exception { JettyTrackingSocket tsocket = new JettyTrackingSocket(); diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowServerTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowServerTest.java index 101d0eae04d..09050221515 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowServerTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/SlowServerTest.java @@ -24,8 +24,6 @@ import java.net.URI; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.TestTracker; -import org.eclipse.jetty.toolchain.test.annotation.Slow; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.client.masks.ZeroMasker; @@ -34,16 +32,10 @@ import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; import org.junit.Test; -@Ignore("TODO: Flappy Test") public class SlowServerTest { - @Rule - public TestTracker tt = new TestTracker(); - private BlockheadServer server; private WebSocketClient client; @@ -75,7 +67,6 @@ public class SlowServerTest } @Test - @Slow public void testServerSlowToRead() throws Exception { JettyTrackingSocket tsocket = new JettyTrackingSocket(); @@ -122,7 +113,6 @@ public class SlowServerTest } @Test - @Slow public void testServerSlowToSend() throws Exception { JettyTrackingSocket clientSocket = new JettyTrackingSocket(); diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java index 028083949a5..02e7c31317e 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientBadUriTest.java @@ -23,11 +23,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -56,9 +54,6 @@ public class WebSocketClientBadUriTest return data; } - @Rule - public TestTracker tt = new TestTracker(); - private WebSocketClient client; private final String uriStr; private final URI uri; diff --git a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientTest.java b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientTest.java index 90fe11e4da5..b22e3646d93 100644 --- a/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientTest.java +++ b/jetty-websocket/websocket-client/src/test/java/org/eclipse/jetty/websocket/client/WebSocketClientTest.java @@ -34,7 +34,6 @@ import java.util.Map; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.RemoteEndpoint; @@ -50,9 +49,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -@RunWith(AdvancedRunner.class) public class WebSocketClientTest { private BlockheadServer server; diff --git a/jetty-websocket/websocket-common/pom.xml b/jetty-websocket/websocket-common/pom.xml index a3bac53190d..2e7e2393291 100644 --- a/jetty-websocket/websocket-common/pom.xml +++ b/jetty-websocket/websocket-common/pom.xml @@ -30,6 +30,12 @@ jetty-io ${project.version} + + org.eclipse.jetty + jetty-client + ${project.version} + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase3.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase3.java index c8c2d6ee9cc..ab4dec13fe5 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase3.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/ab/TestABCase3.java @@ -22,14 +22,12 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.websocket.api.ProtocolException; import org.eclipse.jetty.websocket.common.CloseInfo; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.PingFrame; import org.eclipse.jetty.websocket.common.frames.PongFrame; import org.eclipse.jetty.websocket.common.test.UnitGenerator; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -74,9 +72,6 @@ public class TestABCase3 return data; } - @Rule - public TestTracker tt = new TestTracker(); - private WebSocketFrame invalidFrame; public TestABCase3(WebSocketFrame invalidFrame) diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/http/HttpResponseHeaderParserTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/http/HttpResponseHeaderParserTest.java index 96453c9b022..e9a4d36814e 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/http/HttpResponseHeaderParserTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/http/HttpResponseHeaderParserTest.java @@ -28,18 +28,13 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; public class HttpResponseHeaderParserTest { - @Rule - public TestTracker tt = new TestTracker(); - private void appendUtf8(ByteBuffer buf, String line) { buf.put(ByteBuffer.wrap(StringUtil.getUtf8Bytes(line))); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java index 0060f58c4b3..6e3aa82a3b3 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageOutputStreamTest.java @@ -26,7 +26,6 @@ import java.util.Arrays; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.WebSocketPolicy; @@ -48,9 +47,6 @@ public class MessageOutputStreamTest { private static final Logger LOG = Log.getLogger(MessageOutputStreamTest.class); - @Rule - public TestTracker testtracker = new TestTracker(); - @Rule public TestName testname = new TestName(); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java index ec77b8d176a..e4c6c99bced 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/message/MessageWriterTest.java @@ -24,7 +24,6 @@ import java.util.Arrays; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.WebSocketPolicy; @@ -46,9 +45,6 @@ public class MessageWriterTest { private static final Logger LOG = Log.getLogger(MessageWriterTest.class); - @Rule - public TestTracker testtracker = new TestTracker(); - @Rule public TestName testname = new TestName(); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java index e7bca7d02af..3dba1c72bb0 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java @@ -18,833 +18,67 @@ package org.eclipse.jetty.websocket.common.test; -import static org.hamcrest.Matchers.anyOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.SocketTimeoutException; import java.net.URI; -import java.net.URISyntaxException; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; - -import javax.net.ssl.HttpsURLConnection; +import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.util.BufferUtil; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.api.BatchMode; +import org.eclipse.jetty.util.DecoratedObjectFactory; +import org.eclipse.jetty.websocket.api.WebSocketBehavior; import org.eclipse.jetty.websocket.api.WebSocketPolicy; -import org.eclipse.jetty.websocket.api.WriteCallback; -import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; -import org.eclipse.jetty.websocket.api.extensions.Frame; -import org.eclipse.jetty.websocket.api.extensions.IncomingFrames; -import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames; -import org.eclipse.jetty.websocket.api.util.WSURI; -import org.eclipse.jetty.websocket.common.AcceptHash; -import org.eclipse.jetty.websocket.common.CloseInfo; -import org.eclipse.jetty.websocket.common.ConnectionState; -import org.eclipse.jetty.websocket.common.Generator; -import org.eclipse.jetty.websocket.common.OpCode; -import org.eclipse.jetty.websocket.common.Parser; -import org.eclipse.jetty.websocket.common.WebSocketFrame; -import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; +import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory; +import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.extensions.WebSocketExtensionFactory; -import org.eclipse.jetty.websocket.common.io.IOState; -import org.eclipse.jetty.websocket.common.io.IOState.ConnectionStateListener; -import org.eclipse.jetty.websocket.common.io.http.HttpResponseHeaderParser; -import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; -import org.junit.Assert; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; -/** - * A simple websocket client for performing unit tests with. - *

- * This client will use {@link HttpURLConnection} and {@link HttpsURLConnection} with standard blocking calls to perform websocket requests. - *

- * This client is NOT intended to be performant or follow the websocket spec religiously. In fact, being able to deviate from the websocket spec at will - * is desired for this client to operate properly for the unit testing within this module. - *

- * The BlockheadClient should never validate frames or bytes being sent for validity, against any sort of spec, or even sanity. It should, however be honest - * with regards to basic IO behavior, a write should work as expected, a read should work as expected, but what byte it sends or reads is not within its - * scope. - */ -public class BlockheadClient implements OutgoingFrames, ConnectionStateListener, AutoCloseable, IBlockheadClient +public class BlockheadClient extends HttpClient implements WebSocketContainerScope { - private class FrameReadingThread extends Thread implements Runnable, IncomingFrames + private WebSocketPolicy policy; + private ByteBufferPool bufferPool; + private ExtensionFactory extensionFactory; + private DecoratedObjectFactory objectFactory; + + public BlockheadClient() { - public long totalBytes = 0; - public long totalReadOps = 0; - public long totalParseOps = 0; - - public LinkedBlockingQueue frames = new LinkedBlockingQueue<>(); - public LinkedBlockingQueue errors = new LinkedBlockingQueue<>(); - - @Override - public void run() - { - LOG.debug("Reading frames from server"); - - byte buf[] = new byte[BUFFER_SIZE]; - try - { - if ((remainingBuffer != null) && (remainingBuffer.remaining() > 0)) - { - LOG.debug("Reading bytes received during response header parse: {}",BufferUtil.toDetailString(remainingBuffer)); - totalBytes += remainingBuffer.remaining(); - totalReadOps++; - parser.parse(remainingBuffer); - } - - int len = 0; - int available = 0; - while (!eof) - { - available = in.available(); - len = in.read(buf,0,Math.min(available,buf.length)); - totalReadOps++; - if (len < 0) - { - eof = true; - break; - } - else if (len > 0) - { - totalBytes += len; - ByteBuffer bbuf = ByteBuffer.wrap(buf,0,len); - if (LOG.isDebugEnabled()) - { - LOG.debug("Read {} bytes: {}",len,BufferUtil.toDetailString(bbuf)); - } - totalParseOps++; - parser.parse(bbuf); - } - } - } - catch (IOException e) - { - LOG.debug(e); - } - } - - @Override - public String toString() - { - StringBuilder str = new StringBuilder(); - str.append("FrameReadingThread["); - str.append(",frames=" + frames.size()); - str.append(",errors=" + errors.size()); - str.append(String.format(",totalBytes=%,d",totalBytes)); - str.append(String.format(",totalReadOps=%,d",totalReadOps)); - str.append(String.format(",totalParseOps=%,d",totalParseOps)); - str.append("]"); - return str.toString(); - } - - @Override - public synchronized void incomingError(Throwable t) - { - this.errors.add(t); - } - - @Override - public synchronized void incomingFrame(Frame frame) - { - this.frames.add(WebSocketFrame.copy(frame)); - } - - public synchronized void clear() - { - this.frames.clear(); - this.errors.clear(); - } + super(null); + setName("Blockhead-CLIENT"); + this.policy = new WebSocketPolicy(WebSocketBehavior.CLIENT); + this.bufferPool = new MappedByteBufferPool(); + this.extensionFactory = new WebSocketExtensionFactory(this); + this.objectFactory = new DecoratedObjectFactory(); } - private static final String REQUEST_HASH_KEY = "dGhlIHNhbXBsZSBub25jZQ=="; - private static final int BUFFER_SIZE = 64 * 1024; - private static final Logger LOG = Log.getLogger(BlockheadClient.class); - private final URI destHttpURI; - private final URI destWebsocketURI; - private final ByteBufferPool bufferPool; - private final Generator generator; - private final Parser parser; - - private final WebSocketExtensionFactory extensionFactory; - private FrameReadingThread frameReader; - - private ExecutorService executor; - private Socket socket; - private OutputStream out; - private InputStream in; - private int version = 13; // default to RFC-6455 - private String protocols; - private List extensions = new ArrayList<>(); - private List headers = new ArrayList<>(); - private byte[] clientmask = new byte[] { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF }; - private int timeout = 1000; - private OutgoingFrames outgoing = this; - private boolean eof = false; - private ExtensionStack extensionStack; - private IOState ioState; - private CountDownLatch disconnectedLatch = new CountDownLatch(1); - private ByteBuffer remainingBuffer; - - private String connectionValue = "Upgrade"; - - public BlockheadClient(URI destWebsocketURI) throws URISyntaxException + public ByteBufferPool getBufferPool() { - this(WebSocketPolicy.newClientPolicy(),destWebsocketURI); - } - - public BlockheadClient(WebSocketPolicy policy, URI destWebsocketURI) throws URISyntaxException - { - Assert.assertThat("Websocket URI scheme",destWebsocketURI.getScheme(),anyOf(is("ws"),is("wss"))); - this.destWebsocketURI = destWebsocketURI; - if (destWebsocketURI.getScheme().equals("wss")) - { - throw new RuntimeException("Sorry, BlockheadClient does not support SSL"); - } - this.destHttpURI = WSURI.toHttp(destWebsocketURI); - - LOG.debug("WebSocket URI: {}",destWebsocketURI); - LOG.debug(" HTTP URI: {}",destHttpURI); - - // This is a blockhead client, no point tracking leaks on this object. - this.bufferPool = new MappedByteBufferPool(8192); - this.generator = new Generator(policy,bufferPool); - this.parser = new Parser(policy,bufferPool); - - this.extensionFactory = new WebSocketExtensionFactory(new SimpleContainerScope(policy,bufferPool)); - this.ioState = new IOState(); - this.ioState.addListener(this); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#addExtensions(java.lang.String) - */ - @Override - public void addExtensions(String xtension) - { - this.extensions.add(xtension); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#addHeader(java.lang.String) - */ - @Override - public void addHeader(String header) - { - this.headers.add(header); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#awaitDisconnect(long, java.util.concurrent.TimeUnit) - */ - @Override - public boolean awaitDisconnect(long timeout, TimeUnit unit) throws InterruptedException - { - return disconnectedLatch.await(timeout,unit); - } - - public void clearCaptured() - { - frameReader.clear(); - } - - public void clearExtensions() - { - extensions.clear(); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#close() - */ - @Override - public void close() - { - LOG.debug("close()"); - close(-1,null); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#close(int, java.lang.String) - */ - @Override - public void close(int statusCode, String message) - { - LOG.debug("close({},{})",statusCode,message); - CloseInfo close = new CloseInfo(statusCode,message); - - if (!ioState.isClosed()) - { - ioState.onCloseLocal(close); - } - else - { - LOG.debug("Not issuing close. ioState = {}",ioState); - } - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#connect() - */ - @Override - public void connect() throws IOException - { - InetAddress destAddr = InetAddress.getByName(destHttpURI.getHost()); - int port = destHttpURI.getPort(); - - SocketAddress endpoint = new InetSocketAddress(destAddr,port); - - socket = new Socket(); - socket.setSoTimeout(timeout); - socket.connect(endpoint); - - out = socket.getOutputStream(); - in = socket.getInputStream(); + return bufferPool; } @Override - public void disconnect() + public DecoratedObjectFactory getObjectFactory() { - LOG.debug("disconnect"); - IO.close(in); - IO.close(out); - disconnectedLatch.countDown(); - if (frameReader != null) - { - frameReader.interrupt(); - } - if (socket != null) - { - try - { - socket.close(); - } - catch (IOException ignore) - { - /* ignore */ - } - } + return objectFactory; } - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#expectServerDisconnect() - */ - @Override - public void expectServerDisconnect() + public ExtensionFactory getExtensionFactory() { - if (eof) - { - return; - } - - try - { - int len = in.read(); - if (len == (-1)) - { - // we are disconnected - eof = true; - return; - } - - Assert.assertThat("Expecting no data and proper socket disconnect (issued from server)",len,is(-1)); - } - catch (SocketTimeoutException e) - { - LOG.warn(e); - Assert.fail("Expected a server initiated disconnect, instead the read timed out"); - } - catch (IOException e) - { - // acceptable path - } + return extensionFactory; } - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#expectUpgradeResponse() - */ - @Override - public HttpResponse expectUpgradeResponse() throws IOException + public WebSocketPolicy getPolicy() { - HttpResponse response = readResponseHeader(); - - if (LOG.isDebugEnabled()) - { - LOG.debug("Response Header: {}{}",'\n',response); - } - - Assert.assertThat("Response Status Code",response.getStatusCode(),is(101)); - Assert.assertThat("Response Status Reason",response.getStatusReason(),is("Switching Protocols")); - Assert.assertThat("Response Header[Upgrade]",response.getHeader("Upgrade"),is("WebSocket")); - Assert.assertThat("Response Header[Connection]",response.getHeader("Connection"),is("Upgrade")); - - // Validate the Sec-WebSocket-Accept - String acceptKey = response.getHeader("Sec-WebSocket-Accept"); - Assert.assertThat("Response Header[Sec-WebSocket-Accept Exists]",acceptKey,notNullValue()); - - String reqKey = REQUEST_HASH_KEY; - String expectedHash = AcceptHash.hashKey(reqKey); - - Assert.assertThat("Valid Sec-WebSocket-Accept Hash?",acceptKey,is(expectedHash)); - - // collect extensions configured in response header - List configs = getExtensionConfigs(response); - extensionStack = new ExtensionStack(this.extensionFactory); - extensionStack.negotiate(configs); - - // Setup Frame Reader - this.frameReader = new FrameReadingThread(); - this.frameReader.start(); - - // Start with default routing - extensionStack.setNextIncoming(frameReader); // the websocket layer - extensionStack.setNextOutgoing(outgoing); // the network layer - - // Configure Parser / Generator - extensionStack.configure(parser); - extensionStack.configure(generator); - - // Start Stack - try - { - extensionStack.start(); - } - catch (Exception e) - { - throw new IOException("Unable to start Extension Stack"); - } - - // configure parser - parser.setIncomingFramesHandler(extensionStack); - ioState.onOpened(); - - LOG.debug("outgoing = {}",outgoing); - LOG.debug("incoming = {}",extensionStack); - - return response; + return policy; } - public void flush() throws IOException + public BlockheadClientRequest newWsRequest(URI destURI) { - out.flush(); - } - - public String getConnectionValue() - { - return connectionValue; - } - - public ExecutorService getExecutor() - { - if (executor == null) - { - executor = Executors.newCachedThreadPool(); - } - return executor; - } - - private List getExtensionConfigs(HttpResponse response) - { - List configs = new ArrayList<>(); - - String econf = response.getHeader("Sec-WebSocket-Extensions"); - if (econf != null) - { - LOG.debug("Found Extension Response: {}",econf); - ExtensionConfig config = ExtensionConfig.parse(econf); - configs.add(config); - } - return configs; - } - - public List getExtensions() - { - return extensions; - } - - public URI getHttpURI() - { - return destHttpURI; + return new BlockheadClientRequest(this, destURI); } @Override - public InetSocketAddress getLocalSocketAddress() - { - return (InetSocketAddress)socket.getLocalSocketAddress(); - } - - public IOState getIOState() - { - return ioState; - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#getProtocols() - */ - @Override - public String getProtocols() - { - return protocols; - } - + public void onSessionOpened(WebSocketSession session) + { /* ignored */ } @Override - public InetSocketAddress getRemoteSocketAddress() - { - return (InetSocketAddress)socket.getRemoteSocketAddress(); - } - - public String getRequestHost() - { - if (destHttpURI.getPort() > 0) - { - return String.format("%s:%d",destHttpURI.getHost(),destHttpURI.getPort()); - } - else - { - return destHttpURI.getHost(); - } - } - - public String getRequestPath() - { - StringBuilder path = new StringBuilder(); - path.append(destHttpURI.getPath()); - if (StringUtil.isNotBlank(destHttpURI.getQuery())) - { - path.append('?').append(destHttpURI.getRawQuery()); - } - return path.toString(); - } - - public String getRequestWebSocketKey() - { - return REQUEST_HASH_KEY; - } - - public String getRequestWebSocketOrigin() - { - return destWebsocketURI.toASCIIString(); - } - - public int getVersion() - { - return version; - } - - public URI getWebsocketURI() - { - return destWebsocketURI; - } - - public boolean isConnected() - { - return (socket != null) && (socket.isConnected()); - } - - @Override - public void onConnectionStateChange(ConnectionState state) - { - LOG.debug("CLIENT onConnectionStateChange() - {}",state); - switch (state) - { - case CLOSED: - // Per Spec, client should not initiate disconnect on its own - // this.disconnect(); - break; - case CLOSING: - CloseInfo close = ioState.getCloseInfo(); - - WebSocketFrame frame = close.asFrame(); - LOG.debug("Issuing: {}",frame); - try - { - write(frame); - } - catch (IOException e) - { - LOG.debug(e); - } - break; - default: - /* do nothing */ - break; - } - } - - @Override - public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode) - { - ByteBuffer headerBuf = generator.generateHeaderBytes(frame); - if (LOG.isDebugEnabled()) - { - LOG.debug("writing out: {}",BufferUtil.toDetailString(headerBuf)); - } - try - { - BufferUtil.writeTo(headerBuf,out); - BufferUtil.writeTo(frame.getPayload(),out); - out.flush(); - if (callback != null) - { - callback.writeSuccess(); - } - } - catch (IOException e) - { - if (callback != null) - { - callback.writeFailed(e); - } - } - finally - { - bufferPool.release(headerBuf); - } - - if (frame.getOpCode() == OpCode.CLOSE) - { - disconnect(); - } - } - - @Override - public LinkedBlockingQueue getFrameQueue() - { - return frameReader.frames; - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#readResponseHeader() - */ - @Override - public HttpResponse readResponseHeader() throws IOException - { - HttpResponse response = new HttpResponse(); - HttpResponseHeaderParser respParser = new HttpResponseHeaderParser(response); - - byte buf[] = new byte[512]; - - while (!eof) - { - int available = in.available(); - int len = in.read(buf,0,Math.min(available,buf.length)); - if (len < 0) - { - eof = true; - break; - } - else if (len > 0) - { - ByteBuffer bbuf = ByteBuffer.wrap(buf,0,len); - if (LOG.isDebugEnabled()) - { - LOG.debug("Read {} bytes: {}",len,BufferUtil.toDetailString(bbuf)); - } - if (respParser.parse(bbuf) != null) - { - break; - } - } - } - - remainingBuffer = response.getRemainingBuffer(); - - return response; - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#sendStandardRequest() - */ - @Override - public void sendStandardRequest() throws IOException - { - StringBuilder req = generateUpgradeRequest(); - writeRaw(req.toString()); - } - - public StringBuilder generateUpgradeRequest() - { - StringBuilder req = new StringBuilder(); - req.append("GET ").append(getRequestPath()).append(" HTTP/1.1\r\n"); - req.append("Host: ").append(getRequestHost()).append("\r\n"); - req.append("Upgrade: websocket\r\n"); - req.append("User-Agent: BlockheadClient/JettyTests\r\n"); - req.append("Connection: ").append(connectionValue).append("\r\n"); - for (String header : headers) - { - req.append(header); - } - req.append("Sec-WebSocket-Key: ").append(getRequestWebSocketKey()).append("\r\n"); - req.append("Sec-WebSocket-Origin: ").append(getRequestWebSocketOrigin()).append("\r\n"); - if (StringUtil.isNotBlank(protocols)) - { - req.append("Sec-WebSocket-Protocol: ").append(protocols).append("\r\n"); - } - - for (String xtension : extensions) - { - req.append("Sec-WebSocket-Extensions: ").append(xtension).append("\r\n"); - } - req.append("Sec-WebSocket-Version: ").append(version).append("\r\n"); - req.append("\r\n"); - return req; - } - - @Override - public void setConnectionValue(String connectionValue) - { - this.connectionValue = connectionValue; - } - - public void setExecutor(ExecutorService executor) - { - this.executor = executor; - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#setProtocols(java.lang.String) - */ - @Override - public void setProtocols(String protocols) - { - this.protocols = protocols; - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#setTimeout(int, java.util.concurrent.TimeUnit) - */ - @Override - public void setTimeout(int duration, TimeUnit unit) - { - this.timeout = (int)TimeUnit.MILLISECONDS.convert(duration,unit); - } - - public void setVersion(int version) - { - this.version = version; - } - - public void skipTo(String string) throws IOException - { - int state = 0; - - while (true) - { - int b = in.read(); - if (b < 0) - { - throw new EOFException(); - } - - if (b == string.charAt(state)) - { - state++; - if (state == string.length()) - { - break; - } - } - else - { - state = 0; - } - } - } - - public void sleep(TimeUnit unit, int duration) throws InterruptedException - { - LOG.info("Sleeping for {} {}",duration,unit); - unit.sleep(duration); - LOG.info("Waking up from sleep"); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#write(org.eclipse.jetty.websocket.common.WebSocketFrame) - */ - @Override - public void write(WebSocketFrame frame) throws IOException - { - if (!ioState.isOpen()) - { - LOG.debug("IO Not Open / Not Writing: {}",frame); - return; - } - LOG.debug("write(Frame->{}) to {}",frame,outgoing); - if (LOG.isDebugEnabled()) - { - frame.setMask(new byte[] { 0x00, 0x00, 0x00, 0x00 }); - } - else - { - frame.setMask(clientmask); - } - extensionStack.outgoingFrame(frame,null,BatchMode.OFF); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#writeRaw(java.nio.ByteBuffer) - */ - @Override - public void writeRaw(ByteBuffer buf) throws IOException - { - LOG.debug("write(ByteBuffer) {}",BufferUtil.toDetailString(buf)); - BufferUtil.writeTo(buf,out); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#writeRaw(java.nio.ByteBuffer, int) - */ - @Override - public void writeRaw(ByteBuffer buf, int numBytes) throws IOException - { - int len = Math.min(numBytes,buf.remaining()); - byte arr[] = new byte[len]; - buf.get(arr,0,len); - out.write(arr); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#writeRaw(java.lang.String) - */ - @Override - public void writeRaw(String str) throws IOException - { - LOG.debug("write((String)[{}]){}{})",str.length(),'\n',str); - out.write(str.getBytes(StandardCharsets.ISO_8859_1)); - } - - /* (non-Javadoc) - * @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#writeRawSlowly(java.nio.ByteBuffer, int) - */ - @Override - public void writeRawSlowly(ByteBuffer buf, int segmentSize) throws IOException - { - while (buf.remaining() > 0) - { - writeRaw(buf,segmentSize); - flush(); - } - } + public void onSessionClosed(WebSocketSession session) + { /* ignored */ } } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConnection.java new file mode 100644 index 00000000000..72d7ff2c859 --- /dev/null +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConnection.java @@ -0,0 +1,48 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.common.test; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadLocalRandom; + +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.common.WebSocketFrame; +import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; + +public class BlockheadClientConnection extends BlockheadConnection +{ + public BlockheadClientConnection(WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack, EndPoint endp, Executor executor) + { + super(policy, bufferPool, extensionStack, endp, executor); + } + + @Override + public void write(WebSocketFrame frame) + { + if (frame.getMask() == null) + { + byte mask[] = new byte[4]; + ThreadLocalRandom.current().nextBytes(mask); + frame.setMask(mask); + } + super.write(frame); + } +} \ No newline at end of file diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConstructionTest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConstructionTest.java deleted file mode 100644 index 87ebe51ba0f..00000000000 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientConstructionTest.java +++ /dev/null @@ -1,72 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket.common.test; - -import static org.hamcrest.Matchers.is; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -/** - * Gotta test some basic constructors of the BlockheadClient. - */ -@RunWith(value = Parameterized.class) -public class BlockheadClientConstructionTest -{ - @Parameters - public static Collection data() - { - List data = new ArrayList<>(); - // @formatter:off - data.add(new Object[] { "ws://localhost/", "http://localhost/" }); - data.add(new Object[] { "ws://localhost:8080/", "http://localhost:8080/" }); - data.add(new Object[] { "ws://webtide.com/", "http://webtide.com/" }); - data.add(new Object[] { "ws://www.webtide.com/sockets/chat", "http://www.webtide.com/sockets/chat" }); - // @formatter:on - return data; - } - - private URI expectedWsUri; - private URI expectedHttpUri; - - public BlockheadClientConstructionTest(String wsuri, String httpuri) - { - this.expectedWsUri = URI.create(wsuri); - this.expectedHttpUri = URI.create(httpuri); - } - - @Test - public void testURIs() throws URISyntaxException - { - @SuppressWarnings("resource") - BlockheadClient client = new BlockheadClient(expectedWsUri); - Assert.assertThat("Websocket URI",client.getWebsocketURI(),is(expectedWsUri)); - Assert.assertThat("Websocket URI",client.getHttpURI(),is(expectedHttpUri)); - } - -} diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java new file mode 100644 index 00000000000..8dd9b2801f9 --- /dev/null +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClientRequest.java @@ -0,0 +1,252 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.common.test; + +import java.net.URI; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeoutException; + +import org.eclipse.jetty.client.HttpConversation; +import org.eclipse.jetty.client.HttpRequest; +import org.eclipse.jetty.client.HttpResponse; +import org.eclipse.jetty.client.HttpResponseException; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.client.api.Result; +import org.eclipse.jetty.client.http.HttpConnectionOverHTTP; +import org.eclipse.jetty.client.http.HttpConnectionUpgrader; +import org.eclipse.jetty.client.util.ByteBufferContentProvider; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.B64Code; +import org.eclipse.jetty.util.QuotedStringTokenizer; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.UpgradeException; +import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; +import org.eclipse.jetty.websocket.common.AcceptHash; +import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; + +public class BlockheadClientRequest extends HttpRequest implements Response.CompleteListener, HttpConnectionUpgrader +{ + private static final Logger LOG = Log.getLogger(BlockheadClientRequest.class); + private final BlockheadClient client; + private final CompletableFuture fut; + + protected BlockheadClientRequest(BlockheadClient client, URI uri) + { + super(client, new HttpConversation(), uri); + this.client = client; + this.fut = new CompletableFuture<>(); + } + + public void setInitialBytes(ByteBuffer initialBytes) + { + content(new RawBytesProvider(initialBytes)); + } + + private final String genRandomKey() + { + byte[] bytes = new byte[16]; + ThreadLocalRandom.current().nextBytes(bytes); + return new String(B64Code.encode(bytes)); + } + + private void initWebSocketHeaders() + { + method(HttpMethod.GET); + version(HttpVersion.HTTP_1_1); + + HttpFields fields = getHeaders(); + + // The Upgrade Headers + if (!fields.contains(HttpHeader.UPGRADE)) + header(HttpHeader.UPGRADE, "websocket"); + if (!fields.contains(HttpHeader.CONNECTION)) + header(HttpHeader.CONNECTION, "Upgrade"); + + // The WebSocket Headers + if (!fields.contains(HttpHeader.SEC_WEBSOCKET_KEY)) + header(HttpHeader.SEC_WEBSOCKET_KEY, genRandomKey()); + if (!fields.contains(HttpHeader.SEC_WEBSOCKET_VERSION)) + header(HttpHeader.SEC_WEBSOCKET_VERSION, "13"); + + // (Per the hybi list): Add no-cache headers to avoid compatibility issue. + // There are some proxies that rewrite "Connection: upgrade" + // to "Connection: close" in the response if a request doesn't contain + // these headers. + if (!fields.contains(HttpHeader.PRAGMA)) + header(HttpHeader.PRAGMA, "no-cache"); + if (!fields.contains(HttpHeader.CACHE_CONTROL)) + header(HttpHeader.CACHE_CONTROL, "no-cache"); + } + + @Override + public ContentResponse send() throws InterruptedException, TimeoutException, ExecutionException + { + throw new RuntimeException("Working with raw ContentResponse is invalid for WebSocket"); + } + + @Override + public void send(final Response.CompleteListener listener) + { + initWebSocketHeaders(); + super.send(listener); + } + + public CompletableFuture sendAsync() + { + send(this); + return fut; + } + + @Override + public void onComplete(Result result) + { + if (LOG.isDebugEnabled()) + { + LOG.debug("onComplete() - {}", result); + } + + URI requestURI = result.getRequest().getURI(); + Response response = result.getResponse(); + int responseStatusCode = response.getStatus(); + String responseLine = responseStatusCode + " " + response.getReason(); + + if (result.isFailed()) + { + if (LOG.isDebugEnabled()) + { + if (result.getFailure() != null) + LOG.debug("General Failure", result.getFailure()); + if (result.getRequestFailure() != null) + LOG.debug("Request Failure", result.getRequestFailure()); + if (result.getResponseFailure() != null) + LOG.debug("Response Failure", result.getResponseFailure()); + } + + Throwable failure = result.getFailure(); + if ((failure instanceof java.net.ConnectException) || (failure instanceof UpgradeException)) + { + // handle as-is + handleException(failure); + } + else + { + // wrap in UpgradeException + handleException(new UpgradeException(requestURI, responseStatusCode, responseLine, failure)); + } + } + + if (responseStatusCode != HttpStatus.SWITCHING_PROTOCOLS_101) + { + // Failed to upgrade (other reason) + handleException(new UpgradeException(requestURI, responseStatusCode, responseLine)); + } + } + + private void handleException(Throwable failure) + { + fut.completeExceptionally(failure); + } + + @Override + public void upgrade(HttpResponse response, HttpConnectionOverHTTP oldConn) + { + if (!this.getHeaders().get(HttpHeader.UPGRADE).equalsIgnoreCase("websocket")) + { + // Not my upgrade + throw new HttpResponseException("Not WebSocket Upgrade", response); + } + + // Check the Accept hash + String reqKey = this.getHeaders().get(HttpHeader.SEC_WEBSOCKET_KEY); + String expectedHash = AcceptHash.hashKey(reqKey); + String respHash = response.getHeaders().get(HttpHeader.SEC_WEBSOCKET_ACCEPT); + + if (expectedHash.equalsIgnoreCase(respHash) == false) + { + throw new HttpResponseException("Invalid Sec-WebSocket-Accept hash", response); + } + + // We can upgrade + EndPoint endp = oldConn.getEndPoint(); + + ExtensionStack extensionStack = new ExtensionStack(client.getExtensionFactory()); + List extensions = new ArrayList<>(); + HttpField extField = response.getHeaders().getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); + if (extField != null) + { + String[] extValues = extField.getValues(); + if (extValues != null) + { + for (String extVal : extValues) + { + QuotedStringTokenizer tok = new QuotedStringTokenizer(extVal, ","); + while (tok.hasMoreTokens()) + { + extensions.add(ExtensionConfig.parse(tok.nextToken())); + } + } + } + } + extensionStack.negotiate(extensions); + + BlockheadClientConnection connection = new BlockheadClientConnection( + client.getPolicy(), + client.getBufferPool(), + extensionStack, + endp, + client.getExecutor()); + + connection.setUpgradeResponseHeaders(response.getHeaders()); + + // Now swap out the connection + endp.upgrade(connection); + + fut.complete(connection); + } + + /** + * Raw Bytes Content Provider (intentionally without a Content-Type) + */ + public static class RawBytesProvider extends ByteBufferContentProvider + { + public RawBytesProvider(ByteBuffer buf) + { + super(buf); + } + + @Override + public String getContentType() + { + return null; + } + } +} diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java new file mode 100644 index 00000000000..2269e7f3f14 --- /dev/null +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadConnection.java @@ -0,0 +1,373 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.common.test; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.util.concurrent.Executor; +import java.util.concurrent.LinkedBlockingQueue; + +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.io.AbstractConnection; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.BatchMode; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.api.WriteCallback; +import org.eclipse.jetty.websocket.api.extensions.Frame; +import org.eclipse.jetty.websocket.api.extensions.IncomingFrames; +import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames; +import org.eclipse.jetty.websocket.common.Generator; +import org.eclipse.jetty.websocket.common.Parser; +import org.eclipse.jetty.websocket.common.WebSocketFrame; +import org.eclipse.jetty.websocket.common.extensions.ExtensionStack; + +public class BlockheadConnection extends AbstractConnection implements Connection.UpgradeTo +{ + private final static int BUFFER_SIZE = 4096; + public static final String STATIC_REQUEST_HASH_KEY = "dGhlIHNhbXBsZSBub25jZQ=="; + private final Logger LOG; + private final WebSocketPolicy policy; + private final ByteBufferPool bufferPool; + private final Parser parser; + private final Generator generator; + private final ExtensionStack extensionStack; + private final OutgoingNetwork networkOutgoing; + private final IncomingCapture incomingCapture; + private ByteBuffer networkBuffer; + private HttpFields upgradeResponseHeaders; + + public BlockheadConnection(WebSocketPolicy policy, ByteBufferPool bufferPool, ExtensionStack extensionStack, EndPoint endp, Executor executor) + { + super(endp, executor); + this.LOG = Log.getLogger(this.getClass()); + this.policy = policy; + this.bufferPool = bufferPool; + this.parser = new Parser(policy, bufferPool); + this.generator = new Generator(policy, bufferPool, false); + this.extensionStack = extensionStack; + + this.extensionStack.configure(this.parser); + this.extensionStack.configure(this.generator); + + // Wire up incoming frames (network -> extensionStack -> connection) + this.parser.setIncomingFramesHandler(extensionStack); + this.incomingCapture = new IncomingCapture(); + this.extensionStack.setNextIncoming(incomingCapture); + + // Wire up outgoing frames (connection -> extensionStack -> network) + this.networkOutgoing = new OutgoingNetwork(); + extensionStack.setNextOutgoing(networkOutgoing); + + try + { + extensionStack.start(); + } + catch (Exception e) + { + throw new RuntimeException("Unable to start ExtensionStack", e); + } + } + + public void abort() + { + EndPoint endPoint = getEndPoint(); + // We need to gently close first, to allow + // SSL close alerts to be sent by Jetty + endPoint.shutdownOutput(); + endPoint.close(); + } + + @Override + public void fillInterested() + { + // Handle situation where initial/prefill buffer (from upgrade) has created network buffer, + // but there is no actual read interest (yet) + if (BufferUtil.hasContent(networkBuffer)) + { + fillAndParse(); + } + else + { + super.fillInterested(); + } + } + + public LinkedBlockingQueue getFrameQueue() + { + return incomingCapture.incomingFrames; + } + + public Generator getGenerator() + { + return generator; + } + + public InetSocketAddress getLocalSocketAddress() + { + return getEndPoint().getLocalAddress(); + } + + public Parser getParser() + { + return parser; + } + + public InetSocketAddress getRemoteSocketAddress() + { + return getEndPoint().getRemoteAddress(); + } + + public HttpFields getUpgradeResponseHeaders() + { + return upgradeResponseHeaders; + } + + public boolean isOpen() + { + return getEndPoint().isOpen(); + } + + @Override + public void onFillable() + { + getNetworkBuffer(); + fillAndParse(); + } + + @Override + public void onUpgradeTo(ByteBuffer prefilled) + { + setInitialBuffer(prefilled); + } + + @Override + public void onOpen() + { + super.onOpen(); + fillInterested(); + } + + public void processConnectionError(Throwable cause) + { + LOG.warn("Connection Error", cause); + } + + public void setUpgradeResponseHeaders(HttpFields upgradeResponseHeaders) + { + this.upgradeResponseHeaders = upgradeResponseHeaders; + } + + public void write(WebSocketFrame frame) + { + networkOutgoing.outgoingFrame(frame, null, BatchMode.OFF); + } + + public void writeRaw(ByteBuffer buf) throws IOException + { + getEndPoint().flush(buf); + } + + public void writeRaw(ByteBuffer buf, int numBytes) throws IOException + { + int len = Math.min(numBytes, buf.remaining()); + ByteBuffer slice = buf.slice(); + buf.position(len); + try + { + getEndPoint().flush(slice); + } + catch (IOException e) + { + throw e; + } + finally + { + buf.position(buf.position() + len); + } + } + + public void writeRawSlowly(ByteBuffer buf, int segmentSize) throws IOException + { + while (buf.remaining() > 0) + { + writeRaw(buf, segmentSize); + } + } + + /** + * Extra bytes from the initial HTTP upgrade that need to + * be processed by the websocket parser before starting + * to read bytes from the connection + * + * @param prefilled the bytes of prefilled content encountered during upgrade + */ + protected void setInitialBuffer(ByteBuffer prefilled) + { + if (LOG.isDebugEnabled()) + { + LOG.debug("set Initial Buffer - {}", BufferUtil.toDetailString(prefilled)); + } + + if ((prefilled != null) && (prefilled.hasRemaining())) + { + networkBuffer = bufferPool.acquire(prefilled.remaining(), true); + BufferUtil.clearToFill(networkBuffer); + BufferUtil.put(prefilled, networkBuffer); + BufferUtil.flipToFlush(networkBuffer, 0); + } + } + + private void fillAndParse() + { + boolean interested = false; + + try + { + while (getEndPoint().isOpen()) + { + ByteBuffer nBuffer = getNetworkBuffer(); + + parser.parse(nBuffer); + + // Shouldn't reach this point if buffer has un-parsed bytes + assert (!nBuffer.hasRemaining()); + + int filled = getEndPoint().fill(nBuffer); + + if (LOG.isDebugEnabled()) + LOG.debug("endpointFill() filled={}: {}", filled, BufferUtil.toDetailString(nBuffer)); + + if (filled < 0) + { + releaseNetworkBuffer(nBuffer); + return; + } + + if (filled == 0) + { + releaseNetworkBuffer(nBuffer); + interested = true; + return; + } + } + } + catch (Throwable t) + { + processConnectionError(t); + } + finally + { + if (interested) + fillInterested(); + } + } + + private ByteBuffer getNetworkBuffer() + { + synchronized (this) + { + if (networkBuffer == null) + { + networkBuffer = bufferPool.acquire(BUFFER_SIZE, true); + } + return networkBuffer; + } + } + + private void releaseNetworkBuffer(ByteBuffer buffer) + { + synchronized (this) + { + assert (!buffer.hasRemaining()); + bufferPool.release(buffer); + networkBuffer = null; + } + } + + public class IncomingCapture implements IncomingFrames + { + public final LinkedBlockingQueue incomingFrames = new LinkedBlockingQueue<>(); + public final LinkedBlockingQueue incomingErrors = new LinkedBlockingQueue<>(); + + @Override + public void incomingError(Throwable cause) + { + incomingErrors.offer(cause); + } + + @Override + public void incomingFrame(Frame frame) + { + incomingFrames.offer(WebSocketFrame.copy(frame)); + } + } + + public class OutgoingNetwork implements OutgoingFrames + { + /** + * Last step for networkOutgoing frames before the network buffer. + *

+ * if ExtensionStack is in play, this should be wired up to the output from + * the ExtensionStack. + *

+ * + * @param frame the frame to eventually write to the network layer. + * @param callback the callback to notify when the frame is written. + * @param batchMode ignored by BlockheadConnections + */ + @Override + public void outgoingFrame(Frame frame, WriteCallback callback, BatchMode batchMode) + { + ByteBuffer header = generator.generateHeaderBytes(frame); + ByteBuffer payload = frame.getPayload(); + if (payload == null) + payload = BufferUtil.EMPTY_BUFFER; + + Callback jettyCallback = asJettyCallback(callback); + try + { + getEndPoint().flush(header, payload); + jettyCallback.succeeded(); + } + catch (IOException e) + { + jettyCallback.failed(e); + } + } + + private Callback asJettyCallback(final WriteCallback writeCallback) + { + if (writeCallback instanceof org.eclipse.jetty.util.Callback) + { + return (org.eclipse.jetty.util.Callback) writeCallback; + } + else + { + return new WriteCallbackDelegate(writeCallback); + } + } + } +} diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java index 6ab10df9091..b1a9d910198 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadServerConnection.java @@ -396,7 +396,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames @Override public void run() { - LOG.debug("Entering echo thread"); + LOG.debug("Entering read thread"); long totalReadBytes = 0; ByteBuffer buf = bufferPool.acquire(BUFFER_SIZE, false); @@ -450,7 +450,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames { throw new IllegalStateException("Read thread already declared/started!"); } - readThread = new Thread(this,"BlockheadServer/Read"); + readThread = new Thread(this,"Blockhead-Server-Read"); LOG.debug("Starting Read Thread: {}", readThread); reading.set(true); readThread.start(); diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java index 87c74d437e4..26910fcf0e4 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Fuzzer.java @@ -27,19 +27,20 @@ import java.nio.ByteBuffer; import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.eclipse.jetty.websocket.api.extensions.Frame; import org.eclipse.jetty.websocket.common.CloseInfo; import org.eclipse.jetty.websocket.common.Generator; import org.eclipse.jetty.websocket.common.OpCode; import org.eclipse.jetty.websocket.common.WebSocketFrame; -import org.eclipse.jetty.websocket.common.io.IOState; import org.junit.Assert; /** @@ -47,28 +48,13 @@ import org.junit.Assert; */ public class Fuzzer implements AutoCloseable { - public static enum CloseState - { - OPEN, - REMOTE_INITIATED, - LOCAL_INITIATED - } - - public static enum SendMode + public enum SendMode { BULK, PER_FRAME, SLOW } - public static enum DisconnectMode - { - /** Disconnect occurred after a proper close handshake */ - CLEAN, - /** Disconnect occurred in a harsh manner, without a close handshake */ - UNCLEAN - } - private static final int KBYTE = 1024; private static final int MBYTE = KBYTE * KBYTE; @@ -78,24 +64,26 @@ public class Fuzzer implements AutoCloseable protected static final byte[] MASK = { 0x11, 0x22, 0x33, 0x44 }; + private final Fuzzed testcase; private final BlockheadClient client; private final Generator generator; private final String testname; + private BlockheadConnection clientConnection; private SendMode sendMode = SendMode.BULK; private int slowSendSegmentSize = 5; public Fuzzer(Fuzzed testcase) throws Exception { - WebSocketPolicy policy = WebSocketPolicy.newClientPolicy(); - + this.testcase = testcase; + this.client = new BlockheadClient(); int bigMessageSize = 20 * MBYTE; - policy.setMaxTextMessageSize(bigMessageSize); - policy.setMaxBinaryMessageSize(bigMessageSize); - policy.setIdleTimeout(5000); + client.getPolicy().setMaxTextMessageSize(bigMessageSize); + client.getPolicy().setMaxBinaryMessageSize(bigMessageSize); + client.getPolicy().setIdleTimeout(5000); + + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); - this.client = new BlockheadClient(policy,testcase.getServerURI()); - this.client.setTimeout(2,TimeUnit.SECONDS); this.generator = testcase.getLaxGenerator(); this.testname = testcase.getTestMethodName(); } @@ -120,30 +108,43 @@ public class Fuzzer implements AutoCloseable } @Override - public void close() throws Exception + public void close() { - this.client.disconnect(); + this.clientConnection.close(); } public void disconnect() { - this.client.disconnect(); + this.clientConnection.abort(); } public void connect() throws IOException { - if (!client.isConnected()) + BlockheadClientRequest request = this.client.newWsRequest(testcase.getServerURI()); + request.header("X-TestCase", testname); + Future connFut = request.sendAsync(); + + try { - client.connect(); - client.addHeader("X-TestCase: " + testname + "\r\n"); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + this.clientConnection = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + } + catch (InterruptedException e) + { + throw new IOException("Connect interrupted", e); + } + catch (ExecutionException e) + { + throw new IOException("Connect execution failed", e); + } + catch (TimeoutException e) + { + throw new IOException("Connect timed out", e); } } public void expect(List expect) throws Exception { - expect(expect,10,TimeUnit.SECONDS); + expect(expect, Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); } /** @@ -154,13 +155,13 @@ public class Fuzzer implements AutoCloseable * @param unit the timeout unit to wait for each read frame * @throws Exception if unable to validate expectations */ - public void expect(List expect, int duration, TimeUnit unit) throws Exception + public void expect(List expect, long duration, TimeUnit unit) throws Exception { int expectedCount = expect.size(); LOG.debug("expect() {} frame(s)",expect.size()); // Read frames - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConnection.getFrameQueue(); String prefix = ""; for (int i = 0; i < expectedCount; i++) @@ -198,24 +199,6 @@ public class Fuzzer implements AutoCloseable // TODO Should test for no more frames. success if connection closed. } - public CloseState getCloseState() - { - IOState ios = client.getIOState(); - - if (ios.wasLocalCloseInitiated()) - { - return CloseState.LOCAL_INITIATED; - } - else if (ios.wasRemoteCloseInitiated()) - { - return CloseState.REMOTE_INITIATED; - } - else - { - return CloseState.OPEN; - } - } - public SendMode getSendMode() { return sendMode; @@ -228,27 +211,26 @@ public class Fuzzer implements AutoCloseable public void send(ByteBuffer buf) throws IOException { - Assert.assertThat("Client connected",client.isConnected(),is(true)); + Assert.assertThat("Client connected",clientConnection.isOpen(),is(true)); LOG.debug("Sending bytes {}",BufferUtil.toDetailString(buf)); if (sendMode == SendMode.SLOW) { - client.writeRawSlowly(buf,slowSendSegmentSize); + clientConnection.writeRawSlowly(buf,slowSendSegmentSize); } else { - client.writeRaw(buf); + clientConnection.writeRaw(buf); } } public void send(ByteBuffer buf, int numBytes) throws IOException { - client.writeRaw(buf,numBytes); - client.flush(); + clientConnection.writeRaw(buf, numBytes); } public void send(List send) throws IOException { - Assert.assertThat("Client connected",client.isConnected(),is(true)); + Assert.assertThat("Client connected",clientConnection.isOpen(),is(true)); LOG.debug("[{}] Sending {} frames (mode {})",testname,send.size(),sendMode); if ((sendMode == SendMode.BULK) || (sendMode == SendMode.SLOW)) { @@ -275,10 +257,10 @@ public class Fuzzer implements AutoCloseable switch (sendMode) { case BULK: - client.writeRaw(buf); + clientConnection.writeRaw(buf); break; case SLOW: - client.writeRawSlowly(buf,slowSendSegmentSize); + clientConnection.writeRawSlowly(buf,slowSendSegmentSize); break; default: throw new RuntimeException("Whoops, unsupported sendMode: " + sendMode); @@ -294,8 +276,7 @@ public class Fuzzer implements AutoCloseable BufferUtil.clearToFill(fullframe); generator.generateWholeFrame(f,fullframe); BufferUtil.flipToFlush(fullframe,0); - client.writeRaw(fullframe); - client.flush(); + clientConnection.writeRaw(fullframe); } } } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java index d5dceebd266..a44ec00e6dd 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/IBlockheadServerConnection.java @@ -29,6 +29,7 @@ import org.eclipse.jetty.websocket.api.extensions.Frame; import org.eclipse.jetty.websocket.common.Parser; import org.eclipse.jetty.websocket.common.WebSocketFrame; +@Deprecated public interface IBlockheadServerConnection { public void close() throws IOException; diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java index fa3321e2f18..b9092fbc6a5 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/Timeouts.java @@ -22,6 +22,9 @@ import java.util.concurrent.TimeUnit; public class Timeouts { - public static long POLL_EVENT = 2; - public static TimeUnit POLL_EVENT_UNIT = TimeUnit.SECONDS; + public static final long CONNECT = 2; + public static final TimeUnit CONNECT_UNIT = TimeUnit.SECONDS; + + public static final long POLL_EVENT = 2; + public static final TimeUnit POLL_EVENT_UNIT = TimeUnit.SECONDS; } diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/WriteCallbackDelegate.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/WriteCallbackDelegate.java new file mode 100644 index 00000000000..0d906c294d1 --- /dev/null +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/WriteCallbackDelegate.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.common.test; + +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.websocket.api.WriteCallback; + +public class WriteCallbackDelegate implements Callback +{ + private final WriteCallback delegate; + + public WriteCallbackDelegate(WriteCallback delegate) + { + this.delegate = delegate; + } + + @Override + public void succeeded() + { + if (this.delegate != null) + this.delegate.writeSuccess(); + } + + @Override + public void failed(Throwable x) + { + if (this.delegate != null) + this.delegate.writeFailed(x); + } +} diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java index f24fa3465db..eef290e3ab9 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/AnnotatedMaxMessageSizeTest.java @@ -20,15 +20,16 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; -import java.io.IOException; import java.net.URI; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.CloseInfo; @@ -37,20 +38,19 @@ import org.eclipse.jetty.websocket.common.Parser; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.echo.BigEchoSocket; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; public class AnnotatedMaxMessageSizeTest { - @Rule - public TestTracker tracker = new TestTracker(); - + private static BlockheadClient client; private static Server server; private static ServerConnector connector; private static URI serverUri; @@ -89,59 +89,64 @@ public class AnnotatedMaxMessageSizeTest server.stop(); } - @Test - public void testEchoGood() throws IOException, Exception + @BeforeClass + public static void startClient() throws Exception { - BlockheadClient client = new BlockheadClient(serverUri); - try - { - client.setProtocols("echo"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + + @Test + public void testEchoGood() throws Exception + { + BlockheadClientRequest request = client.newWsRequest(serverUri); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "echo"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } - finally - { - client.close(); - } } @Test(timeout=8000) - public void testEchoTooBig() throws IOException, Exception + public void testEchoTooBig() throws Exception { - BlockheadClient client = new BlockheadClient(serverUri); - try(StacklessLogging logging = new StacklessLogging(Parser.class)) - { - client.setProtocols("echo"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(serverUri); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "echo"); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(Parser.class)) + { // Generate text frame int size = 120 * 1024; byte buf[] = new byte[size]; // buffer bigger than maxMessageSize Arrays.fill(buf,(byte)'x'); - client.write(new TextFrame().setPayload(ByteBuffer.wrap(buf))); + clientConn.write(new TextFrame().setPayload(ByteBuffer.wrap(buf))); // Read frame (hopefully close frame saying its too large) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Frame is close", tf.getOpCode(), is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(tf); Assert.assertThat("Close Code", close.getStatusCode(), is(StatusCode.MESSAGE_TOO_LARGE)); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java index aa3437c9255..cb67178343e 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ChromeTest.java @@ -21,12 +21,18 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.HttpResponse; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.MyEchoServlet; import org.junit.AfterClass; @@ -37,6 +43,7 @@ import org.junit.Test; public class ChromeTest { + private static BlockheadClient client; private static SimpleServletServer server; @BeforeClass @@ -52,34 +59,49 @@ public class ChromeTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testUpgradeWithWebkitDeflateExtension() throws Exception { Assume.assumeTrue("Server has x-webkit-deflate-frame registered", server.getWebSocketServletFactory().getExtensionFactory().isAvailable("x-webkit-deflate-frame")); - - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try + + Assume.assumeTrue("Client has x-webkit-deflate-frame registered", + client.getExtensionFactory().isAvailable("x-webkit-deflate-frame")); + + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "x-webkit-deflate-frame"); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "chat"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.addExtensions("x-webkit-deflate-frame"); - client.setProtocols("chat"); - client.connect(); - client.sendStandardRequest(); - HttpResponse response = client.expectUpgradeResponse(); - Assert.assertThat("Response",response.getExtensionsHeader(),containsString("x-webkit-deflate-frame")); + HttpFields responseFields = clientConn.getUpgradeResponseHeaders(); + HttpField extensionField = responseFields.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); + Assert.assertThat("Response", extensionField.getValue(),containsString("x-webkit-deflate-frame")); // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java index 8dbf77587a3..45b37b1685d 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsLegacyTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertThat; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -36,6 +37,8 @@ import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -50,29 +53,30 @@ import org.junit.Test; @Ignore("Unstable - see Issue #1815") public class DecoratorsLegacyTest { + private static class DecoratorsSocket extends WebSocketAdapter { private final DecoratedObjectFactory objFactory; - + public DecoratorsSocket(DecoratedObjectFactory objFactory) { this.objFactory = objFactory; } - + @Override public void onWebSocketText(String message) { StringWriter str = new StringWriter(); PrintWriter out = new PrintWriter(str); - + if (objFactory != null) { out.printf("Object is a DecoratedObjectFactory%n"); List decorators = objFactory.getDecorators(); - out.printf("Decorators.size = [%d]%n",decorators.size()); + out.printf("Decorators.size = [%d]%n", decorators.size()); for (Decorator decorator : decorators) { - out.printf(" decorator[] = %s%n",decorator.getClass().getName()); + out.printf(" decorator[] = %s%n", decorator.getClass().getName()); } } else @@ -90,7 +94,7 @@ public class DecoratorsLegacyTest public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) { ServletContext servletContext = req.getHttpServletRequest().getServletContext(); - DecoratedObjectFactory objFactory = (DecoratedObjectFactory)servletContext.getAttribute(DecoratedObjectFactory.ATTR); + DecoratedObjectFactory objFactory = (DecoratedObjectFactory) servletContext.getAttribute(DecoratedObjectFactory.ATTR); return new DecoratorsSocket(objFactory); } } @@ -111,7 +115,7 @@ public class DecoratorsLegacyTest factory.setCreator(this.creator); } } - + @SuppressWarnings("deprecation") private static class DummyLegacyDecorator implements org.eclipse.jetty.servlet.ServletContextHandler.Decorator { @@ -127,6 +131,7 @@ public class DecoratorsLegacyTest } } + private static BlockheadClient client; private static SimpleServletServer server; private static DecoratorsCreator decoratorsCreator; @@ -154,31 +159,39 @@ public class DecoratorsLegacyTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testAccessRequestCookies() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.setTimeout(1,TimeUnit.SECONDS); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.idleTimeout(1, TimeUnit.SECONDS); - try + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - client.write(new TextFrame().setPayload("info")); + clientConn.write(new TextFrame().setPayload("info")); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame resp = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String textMsg = resp.getPayloadAsUTF8(); - + assertThat("DecoratedObjectFactory", textMsg, containsString("Object is a DecoratedObjectFactory")); assertThat("decorators.size", textMsg, containsString("Decorators.size = [1]")); assertThat("decorator type", textMsg, containsString("decorator[] = " + DummyLegacyDecorator.class.getName())); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java index 3753d360e56..1428aea3029 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DecoratorsTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertThat; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -36,6 +37,8 @@ import org.eclipse.jetty.websocket.api.WebSocketAdapter; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -44,10 +47,8 @@ import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; -@Ignore public class DecoratorsTest { private static class DecoratorsSocket extends WebSocketAdapter @@ -126,6 +127,7 @@ public class DecoratorsTest } } + private static BlockheadClient client; private static SimpleServletServer server; private static DecoratorsCreator decoratorsCreator; @@ -152,21 +154,32 @@ public class DecoratorsTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testAccessRequestCookies() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.setTimeout(1,TimeUnit.SECONDS); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); - try + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - client.write(new TextFrame().setPayload("info")); + clientConn.write(new TextFrame().setPayload("info")); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame resp = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String textMsg = resp.getPayloadAsUTF8(); @@ -174,9 +187,5 @@ public class DecoratorsTest assertThat("decorators.size", textMsg, containsString("Decorators.size = [1]")); assertThat("decorator type", textMsg, containsString("decorator[] = " + DummyUtilDecorator.class.getName())); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java index bebbf78aa14..e8b6661425d 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FirefoxTest.java @@ -20,12 +20,16 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.MyEchoServlet; import org.junit.AfterClass; import org.junit.Assert; @@ -34,39 +38,45 @@ import org.junit.Test; public class FirefoxTest { + private static BlockheadClient client; private static SimpleServletServer server; @BeforeClass - public static void startServer() throws Exception + public static void startContainers() throws Exception { server = new SimpleServletServer(new MyEchoServlet()); server.start(); + + client = new BlockheadClient(); + client.start(); } @AfterClass - public static void stopServer() + public static void stopContainers() throws Exception { + client.stop(); server.stop(); } @Test public void testConnectionKeepAlive() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) - { - // Odd Connection Header value seen in Firefox - client.setConnectionValue("keep-alive, Upgrade"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + // Odd Connection Header value seen in older Firefox versions + request.header(HttpHeader.CONNECTION, "keep-alive, Upgrade"); + + Future connFut = request.sendAsync(); + + try(BlockheadConnection conn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + conn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); - WebSocketFrame tf = frames.poll(); + LinkedBlockingQueue frames = conn.getFrameQueue(); + WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code", tf.getPayloadAsUTF8(), is(msg)); } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java index de089f26845..4bd4e9af557 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/FragmentExtensionTest.java @@ -21,23 +21,30 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.HttpResponse; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.EchoServlet; import org.junit.AfterClass; import org.junit.Assert; +import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; public class FragmentExtensionTest { private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -52,6 +59,20 @@ public class FragmentExtensionTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + private String[] split(String str, int partSize) { int strLength = str.length(); @@ -69,37 +90,39 @@ public class FragmentExtensionTest @Test public void testFragmentExtension() throws Exception { + Assume.assumeTrue("Server has fragment registered", + server.getWebSocketServletFactory().getExtensionFactory().isAvailable("fragment")); + + Assume.assumeTrue("Client has fragment registered", + client.getExtensionFactory().isAvailable("fragment")); + int fragSize = 4; - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.clearExtensions(); - client.addExtensions("fragment;maxLength=" + fragSize); - client.setProtocols("onConnect"); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "fragment;maxLength=" + fragSize); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "onConnect"); + request.idleTimeout(1, TimeUnit.SECONDS); - try + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { // Make sure the read times out if there are problems with the implementation - client.setTimeout(1,TimeUnit.SECONDS); - client.connect(); - client.sendStandardRequest(); - HttpResponse resp = client.expectUpgradeResponse(); + HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders(); + HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); - Assert.assertThat("Response",resp.getExtensionsHeader(),containsString("fragment")); + Assert.assertThat("Response",extensionHeader.getValue(),containsString("fragment")); String msg = "Sent as a long message that should be split"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); String parts[] = split(msg,fragSize); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); for (int i = 0; i < parts.length; i++) { WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("text[" + i + "].payload",frame.getPayloadAsUTF8(),is(parts[i])); } } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java index 49c4b268553..9ea5577186e 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdentityExtensionTest.java @@ -21,13 +21,18 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.HttpResponse; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.EchoServlet; import org.junit.AfterClass; @@ -38,6 +43,7 @@ import org.junit.Test; public class IdentityExtensionTest { private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -52,34 +58,43 @@ public class IdentityExtensionTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testIdentityExtension() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.clearExtensions(); - client.addExtensions("identity;param=0"); - client.addExtensions("identity;param=1, identity ; param = '2' ; other = ' some = value '"); - client.setProtocols("onConnect"); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "identity;param=0"); + request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "identity;param=1, identity ; param = '2' ; other = ' some = value '"); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "onConnect"); + request.idleTimeout(1, TimeUnit.SECONDS); - try + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - // Make sure the read times out if there are problems with the implementation - client.setTimeout(1,TimeUnit.SECONDS); - client.connect(); - client.sendStandardRequest(); - HttpResponse resp = client.expectUpgradeResponse(); + HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders(); + HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS); - Assert.assertThat("Response",resp.getExtensionsHeader(),containsString("identity")); + Assert.assertThat("Response", extensionHeader.getValue(), containsString("identity")); - client.write(new TextFrame().setPayload("Hello")); + clientConn.write(new TextFrame().setPayload("Hello")); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is("Hello")); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java index 9174d1e8ab0..704527f1b1f 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/IdleTimeoutTest.java @@ -21,15 +21,19 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.api.StatusCode; 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.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.RFCSocket; import org.eclipse.jetty.websocket.servlet.WebSocketServlet; @@ -41,17 +45,23 @@ import org.junit.Test; public class IdleTimeoutTest { + + public static final int IDLE_TIMEOUT_MS_WEBSOCKET_SERVER = 500; + public static final int IDLE_TIMEOUT_ON_SERVER = 1000; + public static final int IDLE_TIMEOUT_MS_WEBSOCKET_CLIENT = 2500; + @SuppressWarnings("serial") public static class TimeoutServlet extends WebSocketServlet { @Override public void configure(WebSocketServletFactory factory) { - factory.getPolicy().setIdleTimeout(500); + factory.getPolicy().setIdleTimeout(IDLE_TIMEOUT_MS_WEBSOCKET_SERVER); factory.register(RFCSocket.class); } } + private static BlockheadClient client; private static SimpleServletServer server; @BeforeClass @@ -67,6 +77,20 @@ public class IdleTimeoutTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + /** * Test IdleTimeout on server. * @throws Exception on test failure @@ -74,37 +98,32 @@ public class IdleTimeoutTest @Test public void testIdleTimeout() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.setProtocols("onConnect"); - client.setTimeout(2500,TimeUnit.MILLISECONDS); - try - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "onConnect"); + request.idleTimeout(IDLE_TIMEOUT_MS_WEBSOCKET_CLIENT, TimeUnit.MILLISECONDS); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // This wait should be shorter than client timeout above, but // longer than server timeout configured in TimeoutServlet - client.sleep(TimeUnit.MILLISECONDS,1000); + TimeUnit.MILLISECONDS.sleep(IDLE_TIMEOUT_ON_SERVER); // Write to server // This action is possible, but does nothing. // Server could be in a half-closed state at this point. // Where the server read is closed (due to timeout), but the server write is still open. // The server could not read this frame, if it is in this half closed state - client.write(new TextFrame().setPayload("Hello")); + clientConn.write(new TextFrame().setPayload("Hello")); // Expect server to have closed due to its own timeout - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("frame opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); Assert.assertThat("close code",close.getStatusCode(),is(StatusCode.SHUTDOWN)); Assert.assertThat("close reason",close.getReason(),containsString("Timeout")); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java index 0e819ec7d68..6b2b03231fd 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ManyConnectionsCleanupTest.java @@ -18,21 +18,23 @@ package org.eclipse.jetty.websocket.server; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.jetty.http.HttpHeader; 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.util.log.StdErrLog; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.WebSocketAdapter; @@ -42,7 +44,8 @@ import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.RFCSocket; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; @@ -52,13 +55,11 @@ import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; /** * Tests various close scenarios that should result in Open Session cleanup */ -@Ignore public class ManyConnectionsCleanupTest { static class AbstractCloseSocket extends WebSocketAdapter @@ -220,6 +221,7 @@ public class ManyConnectionsCleanupTest private static final Logger LOG = Log.getLogger(ManyConnectionsCleanupTest.class); + private static BlockheadClient client; private static SimpleServletServer server; private static AbstractCloseSocket closeSocket; @@ -236,6 +238,20 @@ public class ManyConnectionsCleanupTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + /** * Test session open session cleanup (bug #474936) * @@ -245,35 +261,31 @@ public class ManyConnectionsCleanupTest @Test public void testOpenSessionCleanup() throws Exception { - int iterationCount = 100; - - StdErrLog.getLogger(FastFailSocket.class).setLevel(StdErrLog.LEVEL_OFF); - - StdErrLog sessLog = StdErrLog.getLogger(WebSocketSession.class); - int oldLevel = sessLog.getLevel(); - sessLog.setLevel(StdErrLog.LEVEL_OFF); - - for (int requests = 0; requests < iterationCount; requests++) + int iterationCount = 20; + + // TODO: consider a SilentLogging alternative class + try(StacklessLogging ignore = new StacklessLogging(FastFailSocket.class, WebSocketSession.class)) { - fastFail(); - fastClose(); - dropConnection(); + for (int requests = 0; requests < iterationCount; requests++) + { + fastFail(); + fastClose(); + dropConnection(); + } } - sessLog.setLevel(oldLevel); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "container"); + request.idleTimeout(1, TimeUnit.SECONDS); - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.setProtocols("container"); - client.setTimeout(1,TimeUnit.SECONDS); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - client.write(new TextFrame().setPayload("calls")); - client.write(new TextFrame().setPayload("openSessions")); + clientConn.write(new TextFrame().setPayload("calls")); + clientConn.write(new TextFrame().setPayload("openSessions")); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame; String resp; @@ -291,7 +303,7 @@ public class ManyConnectionsCleanupTest assertThat("frames[2].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); - client.write(close.asFrame()); // respond with close + clientConn.write(close.asFrame()); // respond with close // ensure server socket got close event assertThat("Open Sessions Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); @@ -302,70 +314,63 @@ public class ManyConnectionsCleanupTest private void fastClose() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastclose"); + request.idleTimeout(1, TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("fastclose"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); + frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - LinkedBlockingQueue frames = client.getFrameQueue(); - frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); + assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); - CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); - assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); + // Notify server of close handshake + clientConn.write(close.asFrame()); // respond with close - // Notify server of close handshake - client.write(close.asFrame()); // respond with close - - // ensure server socket got close event - assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); - assertThat("Fast Close.statusCode",closeSocket.closeStatusCode,is(StatusCode.NORMAL)); - } + // ensure server socket got close event + assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); + assertThat("Fast Close.statusCode",closeSocket.closeStatusCode,is(StatusCode.NORMAL)); } } private void fastFail() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastfail"); + request.idleTimeout(1, TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("fastfail"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - // client.readFrames(1,2,TimeUnit.SECONDS); + CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); + clientConn.write(close.asFrame()); // respond with close - CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); - client.write(close.asFrame()); // respond with close - - // ensure server socket got close event - assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); - assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); - assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); - } + // ensure server socket got close event + assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); + assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); + assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); } } private void dropConnection() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "container"); + request.idleTimeout(1, TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("container"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - client.disconnect(); - } + clientConn.abort(); } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java index d8a5c24e311..292136afa81 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RequestHeadersTest.java @@ -26,11 +26,16 @@ import static org.junit.Assert.assertThat; import java.net.HttpCookie; import java.net.URI; import java.util.List; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.EchoSocket; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -43,6 +48,7 @@ import org.junit.Test; public class RequestHeadersTest { + private static class EchoCreator implements WebSocketCreator { private UpgradeRequest lastRequest; @@ -86,6 +92,7 @@ public class RequestHeadersTest } } + private static BlockheadClient client; private static SimpleServletServer server; private static EchoCreator echoCreator; @@ -103,19 +110,31 @@ public class RequestHeadersTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testAccessRequestCookies() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.setTimeout(1,TimeUnit.SECONDS); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.idleTimeout(1, TimeUnit.SECONDS); + request.header(HttpHeader.COOKIE, "fruit=Pear; type=Anjou"); - try + Future connFut = request.sendAsync(); + + try (BlockheadConnection ignore = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.addHeader("Cookie: fruit=Pear; type=Anjou\r\n"); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - UpgradeRequest req = echoCreator.getLastRequest(); assertThat("Last Request",req,notNullValue()); List cookies = req.getCookies(); @@ -127,25 +146,19 @@ public class RequestHeadersTest assertThat("Cookie value",cookie.getValue(),anyOf(is("Pear"),is("Anjou"))); } } - finally - { - client.close(); - } } @Test public void testRequestURI() throws Exception { URI destUri = server.getServerUri().resolve("/?abc=x%20z&breakfast=bacon%26eggs&2*2%3d5=false"); - BlockheadClient client = new BlockheadClient(destUri); - client.setTimeout(1,TimeUnit.SECONDS); - - try + BlockheadClientRequest request = client.newWsRequest(destUri); + request.idleTimeout(1, TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection ignore = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - UpgradeRequest req = echoCreator.getLastRequest(); assertThat("Last Request",req,notNullValue()); assertThat("Request.host", req.getHost(), is(server.getServerUri().getHost())); @@ -154,9 +167,5 @@ public class RequestHeadersTest assertThat("Request.uri.rawQuery", req.getRequestURI().getRawQuery(), is("abc=x%20z&breakfast=bacon%26eggs&2*2%3d5=false")); assertThat("Request.uri.query", req.getRequestURI().getQuery(), is("abc=x z&breakfast=bacon&eggs&2*2=5=false")); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java index 3beb3869427..277a3460e8c 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SubProtocolTest.java @@ -21,9 +21,11 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; @@ -31,6 +33,8 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -90,7 +94,8 @@ public class SubProtocolTest factory.setCreator(new ProtocolCreator()); } } - + + private static BlockheadClient client; private static SimpleServletServer server; @BeforeClass @@ -105,6 +110,20 @@ public class SubProtocolTest { server.stop(); } + + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } @Test public void testSingleProtocol() throws Exception @@ -120,17 +139,16 @@ public class SubProtocolTest private void testSubProtocol(String requestProtocols, String acceptedSubProtocols) throws Exception { - try (BlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, requestProtocols); + request.idleTimeout(1, TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.setTimeout(1, TimeUnit.SECONDS); - - client.connect(); - client.addHeader("Sec-WebSocket-Protocol: "+ requestProtocols + "\r\n"); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - client.write(new TextFrame().setPayload("showme")); - LinkedBlockingQueue frames = client.getFrameQueue(); + clientConn.write(new TextFrame().setPayload("showme")); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat(ProtocolEchoSocket.class.getSimpleName() + ".onMessage()", tf.getPayloadAsUTF8(), is("acceptedSubprotocol=" + acceptedSubProtocols)); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java index 09f2cd2c5a3..d8060ec7f5b 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SuspendResumeTest.java @@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -33,6 +34,8 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; @@ -101,6 +104,7 @@ public class SuspendResumeTest } private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -108,7 +112,21 @@ public class SuspendResumeTest server = new SimpleServletServer(new EchoServlet()); server.start(); } + + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @AfterClass public static void stopServer() { @@ -118,18 +136,16 @@ public class SuspendResumeTest @Test public void testSuspendResume() throws Exception { - try (BlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.setTimeout(1, TimeUnit.SECONDS); + clientConn.write(new TextFrame().setPayload("echo1")); + clientConn.write(new TextFrame().setPayload("echo2")); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - client.write(new TextFrame().setPayload("echo1")); - client.write(new TextFrame().setPayload("echo2")); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat(EchoSocket.class.getSimpleName() + ".onMessage()", tf.getPayloadAsUTF8(), is("echo1")); tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java index bf2de13101e..6b2aa39ff4a 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/TooFastClientTest.java @@ -23,9 +23,10 @@ import static org.hamcrest.Matchers.is; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.io.LeakTrackingByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.websocket.api.WebSocketPolicy; @@ -33,12 +34,13 @@ import org.eclipse.jetty.websocket.common.Generator; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.MyEchoServlet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; /** @@ -50,6 +52,7 @@ import org.junit.Test; public class TooFastClientTest { private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -64,119 +67,93 @@ public class TooFastClientTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + + private ByteBuffer createInitialPacket(String... msgs) + { + int len = Arrays.stream(msgs).mapToInt((str)->str.length() + Generator.MAX_HEADER_LENGTH).sum(); + ByteBuffer initialPacket = ByteBuffer.allocate(len); + + BufferUtil.clearToFill(initialPacket); + Generator generator = new Generator(WebSocketPolicy.newClientPolicy(), + new MappedByteBufferPool()); + + for (String msg : msgs) + { + TextFrame frame = new TextFrame().setPayload(msg); + byte mask[] = new byte[]{0x11, 0x22, 0x33, 0x44}; + frame.setMask(mask); + generator.generateWholeFrame(frame, initialPacket); + } + + BufferUtil.flipToFlush(initialPacket, 0); + return initialPacket; + } + @Test - @Ignore("RELEASE") public void testUpgradeWithSmallFrames() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + + String msg1 = "Echo 1"; + String msg2 = "This is also an echooooo!"; + + ByteBuffer initialPacket = createInitialPacket(msg1, msg2); + request.setInitialBytes(initialPacket); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - - // Create ByteBuffer representing the initial opening network packet from the client - ByteBuffer initialPacket = ByteBuffer.allocate(4096); - BufferUtil.clearToFill(initialPacket); - - // Add upgrade request to packet - StringBuilder upgradeRequest = client.generateUpgradeRequest(); - ByteBuffer upgradeBuffer = BufferUtil.toBuffer(upgradeRequest.toString(),StandardCharsets.UTF_8); - initialPacket.put(upgradeBuffer); - - // Add text frames - Generator generator = new Generator(WebSocketPolicy.newClientPolicy(), - new MappedByteBufferPool()); - - String msg1 = "Echo 1"; - String msg2 = "This is also an echooooo!"; - - TextFrame frame1 = new TextFrame().setPayload(msg1); - TextFrame frame2 = new TextFrame().setPayload(msg2); - - // Need to set frame mask (as these are client frames) - byte mask[] = new byte[] { 0x11, 0x22, 0x33, 0x44 }; - frame1.setMask(mask); - frame2.setMask(mask); - - generator.generateWholeFrame(frame1,initialPacket); - generator.generateWholeFrame(frame2,initialPacket); - - // Write packet to network - BufferUtil.flipToFlush(initialPacket,0); - client.writeRaw(initialPacket); - - // Expect upgrade - client.expectUpgradeResponse(); - // Read frames (hopefully text frames) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame/msg1",tf.getPayloadAsUTF8(),is(msg1)); tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame/msg2",tf.getPayloadAsUTF8(),is(msg2)); } - finally - { - client.close(); - } } - + /** * Test where were a client sends a HTTP Upgrade to websocket AND enough websocket frame(s) * to completely overfill the {@link org.eclipse.jetty.io.AbstractConnection#getInputBufferSize()} - * to test a situation where the WebSocket connection opens with prefill that exceeds + * to test a situation where the WebSocket connection opens with prefill that exceeds * the normal input buffer sizes. * @throws Exception on test failure */ @Test - @Ignore("RELEASE") public void testUpgradeWithLargeFrame() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + + byte bigMsgBytes[] = new byte[64*1024]; + Arrays.fill(bigMsgBytes,(byte)'x'); + String bigMsg = new String(bigMsgBytes, StandardCharsets.UTF_8); + + ByteBuffer initialPacket = createInitialPacket(bigMsg); + request.setInitialBytes(initialPacket); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - - // Create ByteBuffer representing the initial opening network packet from the client - ByteBuffer initialPacket = ByteBuffer.allocate(100 * 1024); - BufferUtil.clearToFill(initialPacket); - - // Add upgrade request to packet - StringBuilder upgradeRequest = client.generateUpgradeRequest(); - ByteBuffer upgradeBuffer = BufferUtil.toBuffer(upgradeRequest.toString(),StandardCharsets.UTF_8); - initialPacket.put(upgradeBuffer); - - // Add text frames - Generator generator = new Generator(WebSocketPolicy.newClientPolicy(), - new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged())); - - byte bigMsgBytes[] = new byte[64*1024]; - Arrays.fill(bigMsgBytes,(byte)'x'); - String bigMsg = new String(bigMsgBytes, StandardCharsets.UTF_8); - - // Need to set frame mask (as these are client frames) - byte mask[] = new byte[] { 0x11, 0x22, 0x33, 0x44 }; - TextFrame frame = new TextFrame().setPayload(bigMsg); - frame.setMask(mask); - generator.generateWholeFrame(frame,initialPacket); - - // Write packet to network - BufferUtil.flipToFlush(initialPacket,0); - client.writeRaw(initialPacket); - - // Expect upgrade - client.expectUpgradeResponse(); - // Read frames (hopefully text frames) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame/msg1",tf.getPayloadAsUTF8(),is(bigMsg)); } - finally - { - client.close(); - } } - - } 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 5ead761e174..75dbb333d09 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 @@ -26,9 +26,11 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.StacklessLogging; @@ -41,7 +43,8 @@ import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.RFCSocket; import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; @@ -51,13 +54,11 @@ import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; /** * Tests various close scenarios */ -@Ignore public class WebSocketCloseTest { static class AbstractCloseSocket extends WebSocketAdapter @@ -198,6 +199,7 @@ public class WebSocketCloseTest private static final Logger LOG = Log.getLogger(WebSocketCloseTest.class); + private static BlockheadClient client; private static SimpleServletServer server; private static AbstractCloseSocket closeSocket; @@ -214,6 +216,20 @@ public class WebSocketCloseTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + /** * Test fast close (bug #403817) * @@ -223,23 +239,23 @@ public class WebSocketCloseTest @Test public void testFastClose() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) - { - client.setProtocols("fastclose"); - client.setTimeout(5,TimeUnit.SECONDS); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastclose"); + request.idleTimeout(5,TimeUnit.SECONDS); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Verify that client got close frame - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); // Notify server of close handshake - client.write(close.asFrame()); // respond with close + clientConn.write(close.asFrame()); // respond with close // ensure server socket got close event assertThat("Fast Close Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true)); @@ -256,29 +272,27 @@ public class WebSocketCloseTest @Test public void testFastFail() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastfail"); + request.idleTimeout(5,TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(FastFailSocket.class, WebSocketSession.class)) { - client.setProtocols("fastfail"); - client.setTimeout(5,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(FastFailSocket.class, WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); + WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); + CloseInfo close = new CloseInfo(frame); + assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); - LinkedBlockingQueue frames = client.getFrameQueue(); - WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); - CloseInfo close = new CloseInfo(frame); - assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); + clientConn.write(close.asFrame()); // respond with close - client.write(close.asFrame()); // respond with close - - // ensure server socket got close event - assertThat("Fast Fail Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true)); - assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); - assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); - } + // ensure server socket got close event + assertThat("Fast Fail Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true)); + assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); + assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); } } @@ -295,19 +309,19 @@ public class WebSocketCloseTest fastClose(); dropConnection(); - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) - { - client.setProtocols("container"); - client.setTimeout(1,TimeUnit.SECONDS); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "container"); + request.idleTimeout(1,TimeUnit.SECONDS); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { TextFrame text = new TextFrame(); text.setPayload("openSessions"); - client.write(text); + clientConn.write(text); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.TEXT)); @@ -318,7 +332,7 @@ public class WebSocketCloseTest assertThat("frames[1].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); - client.write(close.asFrame()); // respond with close + clientConn.write(close.asFrame()); // respond with close // ensure server socket got close event assertThat("Open Sessions Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); @@ -330,72 +344,67 @@ public class WebSocketCloseTest @SuppressWarnings("Duplicates") private void fastClose() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastclose"); + request.idleTimeout(1,TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("fastclose"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); + WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - LinkedBlockingQueue frames = client.getFrameQueue(); - WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); + assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); - CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); - assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL)); + // Notify server of close handshake + clientConn.write(close.asFrame()); // respond with close - // Notify server of close handshake - client.write(close.asFrame()); // respond with close - - // ensure server socket got close event - assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); - assertThat("Fast Close.statusCode",closeSocket.closeStatusCode,is(StatusCode.NORMAL)); - } + // ensure server socket got close event + assertThat("Fast Close Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); + assertThat("Fast Close.statusCode",closeSocket.closeStatusCode,is(StatusCode.NORMAL)); } } private void fastFail() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastfail"); + request.idleTimeout(1,TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("fastfail"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); + WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - LinkedBlockingQueue frames = client.getFrameQueue(); - WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); + clientConn.write(close.asFrame()); // respond with close - CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal"); - client.write(close.asFrame()); // respond with close - - // ensure server socket got close event - assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); - assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); - assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); - } + // ensure server socket got close event + assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); + assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR)); + assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1)); } } @SuppressWarnings("Duplicates") private void dropConnection() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri())) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "container"); + request.idleTimeout(1,TimeUnit.SECONDS); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(WebSocketSession.class)) { - client.setProtocols("container"); - client.setTimeout(1,TimeUnit.SECONDS); - try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - client.disconnect(); - } + clientConn.abort(); } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketInvalidVersionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketInvalidVersionTest.java index b4c1ac14b07..31a4c2e91db 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketInvalidVersionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketInvalidVersionTest.java @@ -19,18 +19,31 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.instanceOf; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.websocket.api.UpgradeException; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.HttpResponse; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; +import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.examples.MyEchoServlet; import org.junit.AfterClass; -import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class WebSocketInvalidVersionTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private static BlockheadClient client; private static SimpleServletServer server; @BeforeClass @@ -46,28 +59,40 @@ public class WebSocketInvalidVersionTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + /** * Test the requirement of responding with an http 400 when using a Sec-WebSocket-Version that is unsupported. + * * @throws Exception on test failure */ @Test public void testRequestVersion29() throws Exception { - @SuppressWarnings("resource") - BlockheadClient client = new BlockheadClient(server.getServerUri()); - client.setVersion(29); // intentionally bad version - try + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + // intentionally bad version + request.header(HttpHeader.SEC_WEBSOCKET_VERSION, "29"); + + Future connFut = request.sendAsync(); + + expectedException.expect(ExecutionException.class); + expectedException.expectCause(instanceOf(UpgradeException.class)); + expectedException.expectMessage(containsString("400 Unsupported websocket version specification")); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - HttpResponse response = client.readResponseHeader(); - Assert.assertThat("Response Status Code",response.getStatusCode(),is(400)); - Assert.assertThat("Response Status Reason",response.getStatusReason(),containsString("Unsupported websocket version specification")); - Assert.assertThat("Response Versions",response.getHeader("Sec-WebSocket-Version"),is("13")); - } - finally - { - client.disconnect(); } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java index 623a14f78b0..f19736841ac 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketOverSSLTest.java @@ -27,7 +27,6 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.Session; @@ -38,16 +37,12 @@ import org.eclipse.jetty.websocket.server.helper.SessionServlet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; public class WebSocketOverSSLTest { public static final int CONNECT_TIMEOUT = 15000; public static final int FUTURE_TIMEOUT_SEC = 30; - @Rule - public TestTracker tracker = new TestTracker(); - public ByteBufferPool bufferPool = new MappedByteBufferPool(); private static SimpleServletServer server; diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java index ad5c2144fb5..6857f6b36a7 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServerSessionTest.java @@ -21,29 +21,29 @@ package org.eclipse.jetty.websocket.server; import static org.hamcrest.Matchers.is; import java.net.URI; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.helper.SessionServlet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.junit.runner.RunWith; /** * Testing various aspects of the server side support for WebSocket {@link org.eclipse.jetty.websocket.api.Session} */ -@RunWith(AdvancedRunner.class) public class WebSocketServerSessionTest { private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -58,19 +58,36 @@ public class WebSocketServerSessionTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testDisconnect() throws Exception { URI uri = server.getServerUri().resolve("/test/disconnect"); - try (IBlockheadClient client = new BlockheadClient(uri)) + + BlockheadClientRequest request = client.newWsRequest(uri); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + clientConn.write(new TextFrame().setPayload("harsh-disconnect")); + clientConn.write(new TextFrame().setPayload("this shouldn't be seen by server")); - client.write(new TextFrame().setPayload("harsh-disconnect")); - - client.awaitDisconnect(1, TimeUnit.SECONDS); + TimeUnit.SECONDS.sleep(10); + // clientConn.awaitDisconnect(1, TimeUnit.SECONDS); } } @@ -78,20 +95,20 @@ public class WebSocketServerSessionTest public void testUpgradeRequestResponse() throws Exception { URI uri = server.getServerUri().resolve("/test?snack=cashews&amount=handful&brand=off"); - try (IBlockheadClient client = new BlockheadClient(uri)) - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(uri); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Ask the server socket for specific parameter map info - client.write(new TextFrame().setPayload("getParameterMap|snack")); - client.write(new TextFrame().setPayload("getParameterMap|amount")); - client.write(new TextFrame().setPayload("getParameterMap|brand")); - client.write(new TextFrame().setPayload("getParameterMap|cost")); // intentionally invalid + clientConn.write(new TextFrame().setPayload("getParameterMap|snack")); + clientConn.write(new TextFrame().setPayload("getParameterMap|amount")); + clientConn.write(new TextFrame().setPayload("getParameterMap|brand")); + clientConn.write(new TextFrame().setPayload("getParameterMap|cost")); // intentionally invalid // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Parameter Map[snack]", tf.getPayloadAsUTF8(), is("[cashews]")); tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java index 994128476a2..31dec999088 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java @@ -22,13 +22,15 @@ import static org.hamcrest.Matchers.is; import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.Locale; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception; import org.eclipse.jetty.util.Utf8StringBuilder; import org.eclipse.jetty.util.log.StacklessLogging; -import org.eclipse.jetty.util.log.StdErrLog; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.extensions.Frame; import org.eclipse.jetty.websocket.common.CloseInfo; @@ -41,6 +43,8 @@ import org.eclipse.jetty.websocket.common.frames.BinaryFrame; import org.eclipse.jetty.websocket.common.frames.ContinuationFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.common.test.UnitGenerator; import org.eclipse.jetty.websocket.common.util.Hex; @@ -50,16 +54,16 @@ import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.junit.runner.RunWith; /** * Test various RFC 6455 specified requirements placed on {@link WebSocketServlet} */ -@RunWith(AdvancedRunner.class) public class WebSocketServletRFCTest { + private static final String REQUEST_HASH_KEY = "dGhlIHNhbXBsZSBub25jZQ=="; private static Generator generator = new UnitGenerator(); private static SimpleServletServer server; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -74,16 +78,18 @@ public class WebSocketServletRFCTest server.stop(); } - /** - * @param clazz the class to enable - * @param enabled true to enable the stack traces (or not) - * @deprecated use {@link StacklessLogging} in a try-with-resources block instead - */ - @Deprecated - private void enableStacks(Class clazz, boolean enabled) + @BeforeClass + public static void startClient() throws Exception { - StdErrLog log = StdErrLog.getLogger(clazz); - log.setHideStacks(!enabled); + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); } /** @@ -93,13 +99,12 @@ public class WebSocketServletRFCTest @Test public void testBinaryAggregate() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Generate binary frames byte buf1[] = new byte[128]; byte buf2[] = new byte[128]; @@ -113,18 +118,18 @@ public class WebSocketServletRFCTest bin = new BinaryFrame().setPayload(buf1).setFin(false); - client.write(bin); // write buf1 (fin=false) + clientConn.write(bin); // write buf1 (fin=false) bin = new ContinuationFrame().setPayload(buf2).setFin(false); - client.write(bin); // write buf2 (fin=false) + clientConn.write(bin); // write buf2 (fin=false) bin = new ContinuationFrame().setPayload(buf3).setFin(true); - client.write(bin); // write buf3 (fin=true) + clientConn.write(bin); // write buf3 (fin=true) // Read frame echo'd back (hopefully a single binary frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); Frame binmsg = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); int expectedSize = buf1.length + buf2.length + buf3.length; Assert.assertThat("BinaryFrame.payloadLength",binmsg.getPayloadLength(),is(expectedSize)); @@ -156,10 +161,6 @@ public class WebSocketServletRFCTest Assert.assertThat("Echoed data count for 0xBB",bbCount,is(buf2.length)); Assert.assertThat("Echoed data count for 0xCC",ccCount,is(buf3.length)); } - finally - { - client.close(); - } } @Test(expected = NotUtf8Exception.class) @@ -179,26 +180,21 @@ public class WebSocketServletRFCTest @Test public void testEcho() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try - { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) + { // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } - finally - { - client.close(); - } } /** @@ -209,24 +205,21 @@ public class WebSocketServletRFCTest @Test public void testInternalError() throws Exception { - try (BlockheadClient client = new BlockheadClient(server.getServerUri()); - StacklessLogging stackless=new StacklessLogging(EventDriver.class)) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(EventDriver.class)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + // Generate text frame + clientConn.write(new TextFrame().setPayload("CRASH")); - try (StacklessLogging context = new StacklessLogging(EventDriver.class)) - { - // Generate text frame - client.write(new TextFrame().setPayload("CRASH")); - - // Read frame (hopefully close frame) - LinkedBlockingQueue frames = client.getFrameQueue(); - Frame cf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); - CloseInfo close = new CloseInfo(cf); - Assert.assertThat("Close Frame.status code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); - } + // Read frame (hopefully close frame) + LinkedBlockingQueue frames = clientConn.getFrameQueue(); + Frame cf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); + CloseInfo close = new CloseInfo(cf); + Assert.assertThat("Close Frame.status code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); } } @@ -239,61 +232,50 @@ public class WebSocketServletRFCTest @Test public void testLowercaseUpgrade() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header("upgrade", "websocket"); + request.header("connection", "upgrade"); + request.header("sec-websocket-key", REQUEST_HASH_KEY); + request.header("sec-websocket-origin", server.getServerUri().toASCIIString()); + request.header("sec-websocket-protocol", "echo"); + request.header("sec-websocket-version", "13"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - - StringBuilder req = new StringBuilder(); - req.append("GET ").append(client.getRequestPath()).append(" HTTP/1.1\r\n"); - req.append("Host: ").append(client.getRequestHost()).append("\r\n"); - req.append("Upgrade: websocket\r\n"); - req.append("connection: upgrade\r\n"); - req.append("sec-websocket-key: ").append(client.getRequestWebSocketKey()).append("\r\n"); - req.append("sec-websocket-origin: ").append(client.getRequestWebSocketOrigin()).append("\r\n"); - req.append("sec-websocket-protocol: echo\r\n"); - req.append("sec-websocket-version: 13\r\n"); - req.append("\r\n"); - client.writeRaw(req.toString()); - - client.expectUpgradeResponse(); - // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } - finally - { - client.close(); - } } @Test public void testTextNotUTF8() throws Exception { - try (StacklessLogging stackless=new StacklessLogging(Parser.class); - BlockheadClient client = new BlockheadClient(server.getServerUri())) - { - client.setProtocols("other"); - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "other"); + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(Parser.class)) + { byte buf[] = new byte[] { (byte)0xC2, (byte)0xC3 }; WebSocketFrame txt = new TextFrame().setPayload(ByteBuffer.wrap(buf)); txt.setMask(Hex.asByteArray("11223344")); ByteBuffer bbHeader = generator.generateHeaderBytes(txt); - client.writeRaw(bbHeader); - client.writeRaw(txt.getPayload()); + clientConn.writeRaw(bbHeader); + clientConn.writeRaw(txt.getPayload()); - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); @@ -310,37 +292,26 @@ public class WebSocketServletRFCTest @Test public void testUppercaseUpgrade() throws Exception { - BlockheadClient client = new BlockheadClient(server.getServerUri()); - try + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header("UPGRADE", "WEBSOCKET"); + request.header("CONNECTION", "UPGRADE"); + request.header("SEC-WEBSOCKET-KEY", REQUEST_HASH_KEY.toUpperCase(Locale.US)); + request.header("SEC-WEBSOCKET-ORIGIN", server.getServerUri().toASCIIString()); + request.header("SEC-WEBSOCKET-PROTOCOL", "ECHO"); + request.header("SEC-WEBSOCKET-VERSION", "13"); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - - StringBuilder req = new StringBuilder(); - req.append("GET ").append(client.getRequestPath()).append(" HTTP/1.1\r\n"); - req.append("HOST: ").append(client.getRequestHost()).append("\r\n"); - req.append("UPGRADE: WEBSOCKET\r\n"); - req.append("CONNECTION: UPGRADE\r\n"); - req.append("SEC-WEBSOCKET-KEY: ").append(client.getRequestWebSocketKey()).append("\r\n"); - req.append("SEC-WEBSOCKET-ORIGIN: ").append(client.getRequestWebSocketOrigin()).append("\r\n"); - req.append("SEC-WEBSOCKET-PROTOCOL: ECHO\r\n"); - req.append("SEC-WEBSOCKET-VERSION: 13\r\n"); - req.append("\r\n"); - client.writeRaw(req.toString()); - - client.expectUpgradeResponse(); - // Generate text frame String msg = "this is an echo ... cho ... ho ... o"; - client.write(new TextFrame().setPayload(msg)); + clientConn.write(new TextFrame().setPayload(msg)); // Read frame (hopefully text frame) - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg)); } - finally - { - client.close(); - } } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java index 784aa8609ae..e0bb8fdae4a 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketUpgradeFilterTest.java @@ -27,7 +27,9 @@ import java.net.URI; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.DispatcherType; @@ -41,14 +43,16 @@ import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.BlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; -import org.junit.Ignore; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -@Ignore("Unstable - see Issue #1815") @RunWith(Parameterized.class) public class WebSocketUpgradeFilterTest { @@ -56,7 +60,23 @@ public class WebSocketUpgradeFilterTest { Server newServer() throws Exception; } - + + private static BlockheadClient client; + + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + private static AtomicInteger uniqTestDirId = new AtomicInteger(0); private static File getNewTestDir() @@ -305,16 +325,16 @@ public class WebSocketUpgradeFilterTest public void testNormalConfiguration() throws Exception { URI destUri = serverUri.resolve("/info/"); - - try (BlockheadClient client = new BlockheadClient(destUri)) + + BlockheadClientRequest request = client.newWsRequest(destUri); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + clientConn.write(new TextFrame().setPayload("hello")); - client.write(new TextFrame().setPayload("hello")); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String payload = received.getPayloadAsUTF8(); @@ -328,20 +348,19 @@ public class WebSocketUpgradeFilterTest public void testStopStartOfHandler() throws Exception { URI destUri = serverUri.resolve("/info/"); - - try (BlockheadClient client = new BlockheadClient(destUri)) + + BlockheadClientRequest request = client.newWsRequest(destUri); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + clientConn.write(new TextFrame().setPayload("hello 1")); - client.write(new TextFrame().setPayload("hello 1")); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String payload = received.getPayloadAsUTF8(); - // If we can connect and send a text message, we know that the endpoint was // added properly, and the response will help us verify the policy configuration too assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024))); @@ -349,20 +368,19 @@ public class WebSocketUpgradeFilterTest server.getHandler().stop(); server.getHandler().start(); - - try (BlockheadClient client = new BlockheadClient(destUri)) + + request = client.newWsRequest(destUri); + + connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT)) { - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); + clientConn.write(new TextFrame().setPayload("hello 2")); - client.write(new TextFrame().setPayload("hello 2")); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); String payload = received.getPayloadAsUTF8(); - // If we can connect and send a text message, we know that the endpoint was // added properly, and the response will help us verify the policy configuration too assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024))); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java index 5a61dfbcd41..2e75a6adb28 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase2.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; @@ -35,9 +34,7 @@ import org.eclipse.jetty.websocket.common.frames.PingFrame; import org.eclipse.jetty.websocket.common.frames.PongFrame; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.junit.Test; -import org.junit.runner.RunWith; -@RunWith(AdvancedRunner.class) public class TestABCase2 extends AbstractABCase { /** diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java index bafef7a354e..e3d565f595b 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase4.java @@ -22,7 +22,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; @@ -33,12 +32,10 @@ import org.eclipse.jetty.websocket.common.frames.PingFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.junit.Test; -import org.junit.runner.RunWith; /** * Test various bad / forbidden opcodes (per spec) */ -@RunWith(AdvancedRunner.class) public class TestABCase4 extends AbstractABCase { /** diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java index 0a7c1e74daf..780e2f90510 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java @@ -22,8 +22,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; -import org.eclipse.jetty.toolchain.test.annotation.Slow; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.CloseInfo; @@ -35,12 +33,10 @@ import org.eclipse.jetty.websocket.common.frames.PongFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.junit.Test; -import org.junit.runner.RunWith; /** * Fragmentation Tests */ -@RunWith(AdvancedRunner.class) public class TestABCase5 extends AbstractABCase { /** @@ -65,7 +61,7 @@ public class TestABCase5 extends AbstractABCase fuzzer.send(send); fuzzer.expect(expect); } - } + } /** * Send continuation+fin, then text+fin (framewise) @@ -301,7 +297,6 @@ public class TestABCase5 extends AbstractABCase * @throws Exception on test failure */ @Test - @Slow public void testCase5_19() throws Exception { // phase 1 diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java index 6e6084b2217..f8eef39cc37 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java @@ -23,8 +23,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; -import org.eclipse.jetty.toolchain.test.annotation.Slow; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; @@ -39,12 +37,10 @@ import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.eclipse.jetty.websocket.common.util.Hex; import org.junit.Test; -import org.junit.runner.RunWith; /** * UTF-8 Tests */ -@RunWith(AdvancedRunner.class) public class TestABCase6 extends AbstractABCase { /** @@ -276,7 +272,6 @@ public class TestABCase6 extends AbstractABCase * @throws Exception on test failure */ @Test - @Slow public void testCase6_4_1() throws Exception { byte part1[] = StringUtil.getUtf8Bytes("\u03BA\u1F79\u03C3\u03BC\u03B5"); @@ -312,7 +307,6 @@ public class TestABCase6 extends AbstractABCase * @throws Exception on test failure */ @Test - @Slow public void testCase6_4_2() throws Exception { byte part1[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5F4"); // split code point @@ -340,7 +334,6 @@ public class TestABCase6 extends AbstractABCase * @throws Exception on test failure */ @Test - @Slow public void testCase6_4_3() throws Exception { // Disable Long Stacks from Parser (we know this test will throw an exception) @@ -393,7 +386,6 @@ public class TestABCase6 extends AbstractABCase * @throws Exception on test failure */ @Test - @Slow public void testCase6_4_4() throws Exception { byte invalid[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5F49080808080656469746564"); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java index 18a20bc6d1b..eb5474e8c2f 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase7.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.eclipse.jetty.toolchain.test.TestTracker; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.StacklessLogging; @@ -39,7 +38,6 @@ import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.eclipse.jetty.websocket.common.util.Hex; -import org.junit.Rule; import org.junit.Test; /** @@ -47,9 +45,6 @@ import org.junit.Test; */ public class TestABCase7 extends AbstractABCase { - @Rule - public TestTracker tt = new TestTracker(); - /** * Basic message then close frame, normal behavior * @throws Exception on test failure diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java index 1756f634993..210783d547d 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase9.java @@ -24,8 +24,6 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; -import org.eclipse.jetty.toolchain.test.AdvancedRunner; -import org.eclipse.jetty.toolchain.test.annotation.Stress; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.CloseInfo; @@ -37,12 +35,10 @@ import org.eclipse.jetty.websocket.common.frames.DataFrame; import org.eclipse.jetty.websocket.common.frames.TextFrame; import org.eclipse.jetty.websocket.common.test.Fuzzer; import org.junit.Test; -import org.junit.runner.RunWith; /** * Big frame/message tests */ -@RunWith(AdvancedRunner.class) public class TestABCase9 extends AbstractABCase { private static final int KBYTE = 1024; @@ -246,7 +242,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_1_5() throws Exception { byte utf[] = new byte[8 * MBYTE]; @@ -275,7 +270,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_1_6() throws Exception { byte utf[] = new byte[16 * MBYTE]; @@ -359,7 +353,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_2_3() throws Exception { byte data[] = new byte[1 * MBYTE]; @@ -388,7 +381,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_2_4() throws Exception { byte data[] = new byte[4 * MBYTE]; @@ -417,7 +409,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_2_5() throws Exception { byte data[] = new byte[8 * MBYTE]; @@ -446,7 +437,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_2_6() throws Exception { byte data[] = new byte[16 * MBYTE]; @@ -475,7 +465,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_1() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,64); @@ -486,7 +475,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_2() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,256); @@ -497,7 +485,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_3() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,1 * KBYTE); @@ -508,7 +495,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_4() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,4 * KBYTE); @@ -519,7 +505,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_5() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,16 * KBYTE); @@ -530,7 +515,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_6() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,64 * KBYTE); @@ -541,7 +525,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_7() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,256 * KBYTE); @@ -552,7 +535,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_8() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,1 * MBYTE); @@ -563,7 +545,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_3_9() throws Exception { assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,4 * MBYTE); @@ -574,7 +555,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_1() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,64); @@ -585,7 +565,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_2() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,256); @@ -596,7 +575,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_3() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,1 * KBYTE); @@ -607,7 +585,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_4() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,4 * KBYTE); @@ -618,7 +595,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_5() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,16 * KBYTE); @@ -629,7 +605,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_6() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,64 * KBYTE); @@ -640,7 +615,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_7() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,256 * KBYTE); @@ -651,7 +625,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_8() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,1 * MBYTE); @@ -662,7 +635,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_4_9() throws Exception { assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,4 * MBYTE); @@ -673,7 +645,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_1() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,64); @@ -684,7 +655,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_2() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,128); @@ -695,7 +665,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_3() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,256); @@ -706,7 +675,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_4() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,512); @@ -717,7 +685,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_5() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,1024); @@ -728,7 +695,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_5_6() throws Exception { assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,2048); @@ -739,7 +705,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_1() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,64); @@ -750,7 +715,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_2() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,128); @@ -761,7 +725,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_3() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,256); @@ -772,7 +735,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_4() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,512); @@ -783,7 +745,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_5() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,1024); @@ -794,7 +755,6 @@ public class TestABCase9 extends AbstractABCase * @throws Exception on test failure */ @Test - @Stress("High I/O use") public void testCase9_6_6() throws Exception { assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,2048); diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java index b54266ef0a0..283ee8add7e 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/examples/MyEchoSocket.java @@ -21,7 +21,6 @@ package org.eclipse.jetty.websocket.server.examples; import java.io.IOException; import org.eclipse.jetty.io.RuntimeIOException; -import org.eclipse.jetty.websocket.api.BatchMode; import org.eclipse.jetty.websocket.api.RemoteEndpoint; import org.eclipse.jetty.websocket.api.WebSocketAdapter; @@ -43,8 +42,6 @@ public class MyEchoSocket extends WebSocketAdapter // echo the data back RemoteEndpoint remote = getRemote(); remote.sendString(message); - if (remote.getBatchMode() == BatchMode.ON) - remote.flush(); } catch (IOException e) { diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java index bc5db0c678c..4232727160a 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/misbehaving/MisbehavingClassTest.java @@ -22,9 +22,11 @@ import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.common.CloseInfo; @@ -32,7 +34,8 @@ import org.eclipse.jetty.websocket.common.OpCode; import org.eclipse.jetty.websocket.common.WebSocketFrame; import org.eclipse.jetty.websocket.common.WebSocketSession; import org.eclipse.jetty.websocket.common.test.BlockheadClient; -import org.eclipse.jetty.websocket.common.test.IBlockheadClient; +import org.eclipse.jetty.websocket.common.test.BlockheadClientRequest; +import org.eclipse.jetty.websocket.common.test.BlockheadConnection; import org.eclipse.jetty.websocket.common.test.Timeouts; import org.eclipse.jetty.websocket.server.SimpleServletServer; import org.junit.AfterClass; @@ -47,6 +50,7 @@ public class MisbehavingClassTest { private static SimpleServletServer server; private static BadSocketsServlet badSocketsServlet; + private static BlockheadClient client; @BeforeClass public static void startServer() throws Exception @@ -62,29 +66,42 @@ public class MisbehavingClassTest server.stop(); } + @BeforeClass + public static void startClient() throws Exception + { + client = new BlockheadClient(); + client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2)); + client.start(); + } + + @AfterClass + public static void stopClient() throws Exception + { + client.stop(); + } + @Test public void testListenerRuntimeOnConnect() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri()); - StacklessLogging scope = new StacklessLogging(ListenerRuntimeOnConnectSocket.class, WebSocketSession.class)) + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "listener-runtime-connect"); + request.idleTimeout(1, TimeUnit.SECONDS); + + ListenerRuntimeOnConnectSocket socket = badSocketsServlet.listenerRuntimeConnect; + socket.reset(); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); + StacklessLogging ignore = new StacklessLogging(ListenerRuntimeOnConnectSocket.class, WebSocketSession.class)) { - client.setProtocols("listener-runtime-connect"); - client.setTimeout(1,TimeUnit.SECONDS); - - ListenerRuntimeOnConnectSocket socket = badSocketsServlet.listenerRuntimeConnect; - socket.reset(); - - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); - client.write(close.asFrame()); // respond with close + clientConn.write(close.asFrame()); // respond with close // ensure server socket got close event assertThat("Close Latch",socket.closeLatch.await(1,TimeUnit.SECONDS),is(true)); @@ -100,26 +117,25 @@ public class MisbehavingClassTest @Test public void testAnnotatedRuntimeOnConnect() throws Exception { - try (IBlockheadClient client = new BlockheadClient(server.getServerUri()); + BlockheadClientRequest request = client.newWsRequest(server.getServerUri()); + request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "annotated-runtime-connect"); + request.idleTimeout(1, TimeUnit.SECONDS); + + AnnotatedRuntimeOnConnectSocket socket = badSocketsServlet.annotatedRuntimeConnect; + socket.reset(); + + Future connFut = request.sendAsync(); + + try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT); StacklessLogging scope = new StacklessLogging(AnnotatedRuntimeOnConnectSocket.class, WebSocketSession.class)) { - client.setProtocols("annotated-runtime-connect"); - client.setTimeout(1,TimeUnit.SECONDS); - - AnnotatedRuntimeOnConnectSocket socket = badSocketsServlet.annotatedRuntimeConnect; - socket.reset(); - - client.connect(); - client.sendStandardRequest(); - client.expectUpgradeResponse(); - - LinkedBlockingQueue frames = client.getFrameQueue(); + LinkedBlockingQueue frames = clientConn.getFrameQueue(); WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT); assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE)); CloseInfo close = new CloseInfo(frame); assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR)); - client.write(close.asFrame()); // respond with close + clientConn.write(close.asFrame()); // respond with close // ensure server socket got close event assertThat("Close Latch",socket.closeLatch.await(1,TimeUnit.SECONDS),is(true));