Issue #2282 - Simplifying BlockheadClient to drastically reduce CPU load during testing
This commit is contained in:
parent
e4ad88aaf1
commit
dd57cf0bf6
|
@ -37,7 +37,6 @@ import javax.websocket.OnClose;
|
||||||
import javax.websocket.OnMessage;
|
import javax.websocket.OnMessage;
|
||||||
import javax.websocket.WebSocketContainer;
|
import javax.websocket.WebSocketContainer;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
|
||||||
import org.eclipse.jetty.util.component.LifeCycle;
|
import org.eclipse.jetty.util.component.LifeCycle;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
@ -49,7 +48,6 @@ import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@Ignore("Not working atm")
|
@Ignore("Not working atm")
|
||||||
|
@ -165,9 +163,6 @@ public class DecoderReaderManySmallTest
|
||||||
|
|
||||||
private static final Logger LOG = Log.getLogger(DecoderReaderManySmallTest.class);
|
private static final Logger LOG = Log.getLogger(DecoderReaderManySmallTest.class);
|
||||||
|
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
private BlockheadServer server;
|
private BlockheadServer server;
|
||||||
private WebSocketContainer client;
|
private WebSocketContainer client;
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,6 @@ import javax.websocket.OnMessage;
|
||||||
import javax.websocket.WebSocketContainer;
|
import javax.websocket.WebSocketContainer;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
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.BufferUtil;
|
||||||
import org.eclipse.jetty.util.component.LifeCycle;
|
import org.eclipse.jetty.util.component.LifeCycle;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
@ -57,7 +56,6 @@ import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class DecoderReaderTest
|
public class DecoderReaderTest
|
||||||
|
@ -229,9 +227,6 @@ public class DecoderReaderTest
|
||||||
|
|
||||||
private static final Logger LOG = Log.getLogger(DecoderReaderTest.class);
|
private static final Logger LOG = Log.getLogger(DecoderReaderTest.class);
|
||||||
|
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
private BlockheadServer server;
|
private BlockheadServer server;
|
||||||
private WebSocketContainer client;
|
private WebSocketContainer client;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ import javax.websocket.Session;
|
||||||
import javax.websocket.WebSocketContainer;
|
import javax.websocket.WebSocketContainer;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
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.component.LifeCycle;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
@ -51,7 +50,6 @@ import org.eclipse.jetty.websocket.common.test.Timeouts;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class EncoderTest
|
public class EncoderTest
|
||||||
|
@ -186,8 +184,6 @@ public class EncoderTest
|
||||||
|
|
||||||
private static final Logger LOG = Log.getLogger(EncoderTest.class);
|
private static final Logger LOG = Log.getLogger(EncoderTest.class);
|
||||||
|
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
private BlockheadServer server;
|
private BlockheadServer server;
|
||||||
|
|
||||||
private WebSocketContainer client;
|
private WebSocketContainer client;
|
||||||
|
|
|
@ -35,7 +35,9 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -51,6 +53,9 @@ import javax.websocket.server.HandshakeRequest;
|
||||||
import javax.websocket.server.ServerEndpoint;
|
import javax.websocket.server.ServerEndpoint;
|
||||||
import javax.websocket.server.ServerEndpointConfig;
|
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.Server;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.IBlockheadClient;
|
import org.eclipse.jetty.websocket.common.test.BlockheadConnection;
|
||||||
import org.eclipse.jetty.websocket.common.test.Timeouts;
|
import org.eclipse.jetty.websocket.common.test.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
|
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -356,7 +361,8 @@ public class ConfiguratorTest
|
||||||
return dateFormat;
|
return dateFormat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static BlockheadClient client;
|
||||||
private static Server server;
|
private static Server server;
|
||||||
private static URI baseServerUri;
|
private static URI baseServerUri;
|
||||||
|
|
||||||
|
@ -408,18 +414,35 @@ public class ConfiguratorTest
|
||||||
server.stop();
|
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
|
@Test
|
||||||
public void testEmptyConfigurator() throws Exception
|
public void testEmptyConfigurator() throws Exception
|
||||||
{
|
{
|
||||||
URI uri = baseServerUri.resolve("/empty");
|
URI uri = baseServerUri.resolve("/empty");
|
||||||
|
|
||||||
try (IBlockheadClient client = new BlockheadClient(uri))
|
BlockheadClientRequest request = client.newWsRequest(uri);
|
||||||
|
request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "identity");
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
{
|
{
|
||||||
client.addExtensions("identity");
|
HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders();
|
||||||
client.connect();
|
HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS);
|
||||||
client.sendStandardRequest();
|
Assert.assertThat("response.extensions", extensionHeader.getValue(), is("identity"));
|
||||||
HttpResponse response = client.readResponseHeader();
|
|
||||||
Assert.assertThat("response.extensions", response.getExtensionsHeader(), is("identity"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,16 +451,19 @@ public class ConfiguratorTest
|
||||||
{
|
{
|
||||||
URI uri = baseServerUri.resolve("/no-extensions");
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
{
|
{
|
||||||
client.addExtensions("identity");
|
HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders();
|
||||||
client.connect();
|
HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS);
|
||||||
client.sendStandardRequest();
|
assertThat("response.extensions", extensionHeader, is(nullValue()));
|
||||||
HttpResponse response = client.expectUpgradeResponse();
|
|
||||||
assertThat("response.extensions", response.getExtensionsHeader(), nullValue());
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("NegoExts"));
|
clientConn.write(new TextFrame().setPayload("NegoExts"));
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
assertThat("Frame Response", frame.getPayloadAsUTF8(), is("negotiatedExtensions=[]"));
|
assertThat("Frame Response", frame.getPayloadAsUTF8(), is("negotiatedExtensions=[]"));
|
||||||
}
|
}
|
||||||
|
@ -448,15 +474,15 @@ public class ConfiguratorTest
|
||||||
{
|
{
|
||||||
URI uri = baseServerUri.resolve("/capture-request-headers");
|
URI uri = baseServerUri.resolve("/capture-request-headers");
|
||||||
|
|
||||||
try (IBlockheadClient client = new BlockheadClient(uri))
|
BlockheadClientRequest request = client.newWsRequest(uri);
|
||||||
{
|
request.header("X-Dummy", "Bogus");
|
||||||
client.addHeader("X-Dummy: Bogus\r\n");
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("X-Dummy"));
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
|
{
|
||||||
|
clientConn.write(new TextFrame().setPayload("X-Dummy"));
|
||||||
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Request Header [X-Dummy]: \"Bogus\""));
|
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");
|
URI uri = baseServerUri.resolve("/unique-user-props");
|
||||||
|
|
||||||
// First request
|
// First request
|
||||||
try (IBlockheadClient client = new BlockheadClient(uri))
|
BlockheadClientRequest request = client.newWsRequest(uri);
|
||||||
{
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("apple"));
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
{
|
||||||
|
clientConn.write(new TextFrame().setPayload("apple"));
|
||||||
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
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\""));
|
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [apple] = \"fruit from tree\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second request
|
// Second request
|
||||||
try (IBlockheadClient client = new BlockheadClient(uri))
|
|
||||||
{
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("apple"));
|
request = client.newWsRequest(uri);
|
||||||
client.write(new TextFrame().setPayload("blueberry"));
|
connFut = request.sendAsync();
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
|
{
|
||||||
|
clientConn.write(new TextFrame().setPayload("apple"));
|
||||||
|
clientConn.write(new TextFrame().setPayload("blueberry"));
|
||||||
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
// should have no value
|
// should have no value
|
||||||
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [apple] = <null>"));
|
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested User Property: [apple] = <null>"));
|
||||||
|
|
||||||
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\""));
|
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");
|
URI uri = baseServerUri.resolve("/addr");
|
||||||
|
|
||||||
// First request
|
BlockheadClientRequest request = client.newWsRequest(uri);
|
||||||
try (IBlockheadClient client = new BlockheadClient(uri))
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
{
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
InetSocketAddress expectedLocal = client.getLocalSocketAddress();
|
|
||||||
InetSocketAddress expectedRemote = client.getRemoteSocketAddress();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("addr"));
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
{
|
||||||
|
InetSocketAddress expectedLocal = clientConn.getLocalSocketAddress();
|
||||||
|
InetSocketAddress expectedRemote = clientConn.getRemoteSocketAddress();
|
||||||
|
|
||||||
|
clientConn.write(new TextFrame().setPayload("addr"));
|
||||||
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
|
|
||||||
StringWriter expected = new StringWriter();
|
StringWriter expected = new StringWriter();
|
||||||
|
@ -540,15 +563,14 @@ public class ConfiguratorTest
|
||||||
URI uri = baseServerUri.resolve("/protocols");
|
URI uri = baseServerUri.resolve("/protocols");
|
||||||
ProtocolsConfigurator.seenProtocols.set(null);
|
ProtocolsConfigurator.seenProtocols.set(null);
|
||||||
|
|
||||||
try (IBlockheadClient client = new BlockheadClient(uri))
|
BlockheadClientRequest request = client.newWsRequest(uri);
|
||||||
{
|
request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "echo");
|
||||||
client.addHeader("Sec-WebSocket-Protocol: echo\r\n");
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("getProtocols"));
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
{
|
||||||
|
clientConn.write(new TextFrame().setPayload("getProtocols"));
|
||||||
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\"]"));
|
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\"]"));
|
||||||
}
|
}
|
||||||
|
@ -564,15 +586,14 @@ public class ConfiguratorTest
|
||||||
URI uri = baseServerUri.resolve("/protocols");
|
URI uri = baseServerUri.resolve("/protocols");
|
||||||
ProtocolsConfigurator.seenProtocols.set(null);
|
ProtocolsConfigurator.seenProtocols.set(null);
|
||||||
|
|
||||||
try (IBlockheadClient client = new BlockheadClient(uri))
|
BlockheadClientRequest request = client.newWsRequest(uri);
|
||||||
{
|
request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "echo, chat, status");
|
||||||
client.addHeader("Sec-WebSocket-Protocol: echo, chat, status\r\n");
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("getProtocols"));
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
{
|
||||||
|
clientConn.write(new TextFrame().setPayload("getProtocols"));
|
||||||
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]"));
|
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]"));
|
||||||
}
|
}
|
||||||
|
@ -588,15 +609,14 @@ public class ConfiguratorTest
|
||||||
URI uri = baseServerUri.resolve("/protocols");
|
URI uri = baseServerUri.resolve("/protocols");
|
||||||
ProtocolsConfigurator.seenProtocols.set(null);
|
ProtocolsConfigurator.seenProtocols.set(null);
|
||||||
|
|
||||||
try (IBlockheadClient client = new BlockheadClient(uri))
|
BlockheadClientRequest request = client.newWsRequest(uri);
|
||||||
{
|
request.header("sec-websocket-protocol", "echo, chat, status");
|
||||||
client.addHeader("sec-websocket-protocol: echo, chat, status\r\n");
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("getProtocols"));
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
{
|
||||||
|
clientConn.write(new TextFrame().setPayload("getProtocols"));
|
||||||
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]"));
|
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]"));
|
||||||
}
|
}
|
||||||
|
@ -612,15 +632,15 @@ public class ConfiguratorTest
|
||||||
URI uri = baseServerUri.resolve("/protocols");
|
URI uri = baseServerUri.resolve("/protocols");
|
||||||
ProtocolsConfigurator.seenProtocols.set(null);
|
ProtocolsConfigurator.seenProtocols.set(null);
|
||||||
|
|
||||||
try (IBlockheadClient client = new BlockheadClient(uri))
|
BlockheadClientRequest request = client.newWsRequest(uri);
|
||||||
{
|
// We see "Websocket" (no capital "S" often)
|
||||||
client.addHeader("Sec-Websocket-Protocol: echo, chat, status\r\n");
|
request.header("Sec-Websocket-Protocol", "echo, chat, status");
|
||||||
client.connect();
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("getProtocols"));
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
{
|
||||||
|
clientConn.write(new TextFrame().setPayload("getProtocols"));
|
||||||
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]"));
|
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("Requested Protocols: [\"echo\",\"chat\",\"status\"]"));
|
||||||
}
|
}
|
||||||
|
@ -634,15 +654,15 @@ public class ConfiguratorTest
|
||||||
{
|
{
|
||||||
URI uri = baseServerUri.resolve("/timedecoder");
|
URI uri = baseServerUri.resolve("/timedecoder");
|
||||||
|
|
||||||
try (BlockheadClient client = new BlockheadClient(uri))
|
BlockheadClientRequest request = client.newWsRequest(uri);
|
||||||
{
|
// We see "Websocket" (no capital "S" often)
|
||||||
client.addHeader("Sec-Websocket-Protocol: gmt\r\n");
|
request.header("SeC-WeBsOcKeT-PrOtOcOl", "gmt");
|
||||||
client.connect();
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("2016-06-20T14:27:44"));
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
{
|
||||||
|
clientConn.write(new TextFrame().setPayload("2016-06-20T14:27:44"));
|
||||||
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
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"));
|
Assert.assertThat("Frame Response", frame.getPayloadAsUTF8(), is("cal=2016.06.20 AD at 14:27:44 +0000"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,7 +249,6 @@ public class EchoTest
|
||||||
public EchoTest(EchoCase testcase)
|
public EchoTest(EchoCase testcase)
|
||||||
{
|
{
|
||||||
this.testcase = testcase;
|
this.testcase = testcase;
|
||||||
System.err.println(testcase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=2000)
|
@Test(timeout=2000)
|
||||||
|
|
|
@ -179,7 +179,6 @@ public class ServerAnnotatedEndpointScanner_GoodSignaturesTest
|
||||||
public ServerAnnotatedEndpointScanner_GoodSignaturesTest(Case testcase)
|
public ServerAnnotatedEndpointScanner_GoodSignaturesTest(Case testcase)
|
||||||
{
|
{
|
||||||
this.testcase = testcase;
|
this.testcase = testcase;
|
||||||
System.err.printf("Testing signature of %s%n",testcase.pojo.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -24,14 +24,12 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
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.Session;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadServer;
|
import org.eclipse.jetty.websocket.common.test.BlockheadServer;
|
||||||
import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection;
|
import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,9 +37,6 @@ import org.junit.Test;
|
||||||
*/
|
*/
|
||||||
public class BadNetworkTest
|
public class BadNetworkTest
|
||||||
{
|
{
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
public ByteBufferPool bufferPool = new MappedByteBufferPool();
|
public ByteBufferPool bufferPool = new MappedByteBufferPool();
|
||||||
|
|
||||||
private BlockheadServer server;
|
private BlockheadServer server;
|
||||||
|
|
|
@ -51,7 +51,6 @@ import org.eclipse.jetty.io.EofException;
|
||||||
import org.eclipse.jetty.io.ManagedSelector;
|
import org.eclipse.jetty.io.ManagedSelector;
|
||||||
import org.eclipse.jetty.io.SelectorManager;
|
import org.eclipse.jetty.io.SelectorManager;
|
||||||
import org.eclipse.jetty.io.SocketChannelEndPoint;
|
import org.eclipse.jetty.io.SocketChannelEndPoint;
|
||||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
@ -76,7 +75,6 @@ import org.hamcrest.Matcher;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class ClientCloseTest
|
public class ClientCloseTest
|
||||||
|
@ -178,9 +176,6 @@ public class ClientCloseTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
private BlockheadServer server;
|
private BlockheadServer server;
|
||||||
private WebSocketClient client;
|
private WebSocketClient client;
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,6 @@ import java.util.concurrent.TimeoutException;
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
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.Session;
|
||||||
import org.eclipse.jetty.websocket.api.UpgradeException;
|
import org.eclipse.jetty.websocket.api.UpgradeException;
|
||||||
import org.eclipse.jetty.websocket.common.AcceptHash;
|
import org.eclipse.jetty.websocket.common.AcceptHash;
|
||||||
|
@ -49,7 +48,6 @@ import org.hamcrest.Matcher;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,9 +56,6 @@ import org.junit.Test;
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
public class ClientConnectTest
|
public class ClientConnectTest
|
||||||
{
|
{
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
public ByteBufferPool bufferPool = new MappedByteBufferPool();
|
public ByteBufferPool bufferPool = new MappedByteBufferPool();
|
||||||
|
|
||||||
private final int timeout = 500;
|
private final int timeout = 500;
|
||||||
|
|
|
@ -24,17 +24,12 @@ import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
|
||||||
import org.eclipse.jetty.websocket.client.io.ConnectionManager;
|
import org.eclipse.jetty.websocket.client.io.ConnectionManager;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class ConnectionManagerTest
|
public class ConnectionManagerTest
|
||||||
{
|
{
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
private void assertToSocketAddress(String uriStr, String expectedHost, int expectedPort) throws URISyntaxException
|
private void assertToSocketAddress(String uriStr, String expectedHost, int expectedPort) throws URISyntaxException
|
||||||
{
|
{
|
||||||
URI uri = new URI(uriStr);
|
URI uri = new URI(uriStr);
|
||||||
|
|
|
@ -18,14 +18,12 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.client;
|
package org.eclipse.jetty.websocket.client;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.Session;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadServer;
|
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.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class SlowClientTest
|
public class SlowClientTest
|
||||||
{
|
{
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
private BlockheadServer server;
|
private BlockheadServer server;
|
||||||
private WebSocketClient client;
|
private WebSocketClient client;
|
||||||
|
|
||||||
|
@ -72,7 +66,6 @@ public class SlowClientTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Slow
|
|
||||||
public void testClientSlowToSend() throws Exception
|
public void testClientSlowToSend() throws Exception
|
||||||
{
|
{
|
||||||
JettyTrackingSocket tsocket = new JettyTrackingSocket();
|
JettyTrackingSocket tsocket = new JettyTrackingSocket();
|
||||||
|
|
|
@ -24,8 +24,6 @@ import java.net.URI;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.Session;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.client.masks.ZeroMasker;
|
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.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@Ignore("TODO: Flappy Test")
|
|
||||||
public class SlowServerTest
|
public class SlowServerTest
|
||||||
{
|
{
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
private BlockheadServer server;
|
private BlockheadServer server;
|
||||||
private WebSocketClient client;
|
private WebSocketClient client;
|
||||||
|
|
||||||
|
@ -75,7 +67,6 @@ public class SlowServerTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Slow
|
|
||||||
public void testServerSlowToRead() throws Exception
|
public void testServerSlowToRead() throws Exception
|
||||||
{
|
{
|
||||||
JettyTrackingSocket tsocket = new JettyTrackingSocket();
|
JettyTrackingSocket tsocket = new JettyTrackingSocket();
|
||||||
|
@ -122,7 +113,6 @@ public class SlowServerTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Slow
|
|
||||||
public void testServerSlowToSend() throws Exception
|
public void testServerSlowToSend() throws Exception
|
||||||
{
|
{
|
||||||
JettyTrackingSocket clientSocket = new JettyTrackingSocket();
|
JettyTrackingSocket clientSocket = new JettyTrackingSocket();
|
||||||
|
|
|
@ -23,11 +23,9 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
@ -56,9 +54,6 @@ public class WebSocketClientBadUriTest
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
private WebSocketClient client;
|
private WebSocketClient client;
|
||||||
private final String uriStr;
|
private final String uriStr;
|
||||||
private final URI uri;
|
private final URI uri;
|
||||||
|
|
|
@ -34,7 +34,6 @@ import java.util.Map;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
||||||
|
@ -50,9 +49,7 @@ import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
@RunWith(AdvancedRunner.class)
|
|
||||||
public class WebSocketClientTest
|
public class WebSocketClientTest
|
||||||
{
|
{
|
||||||
private BlockheadServer server;
|
private BlockheadServer server;
|
||||||
|
|
|
@ -30,6 +30,12 @@
|
||||||
<artifactId>jetty-io</artifactId>
|
<artifactId>jetty-io</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-client</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||||
<artifactId>jetty-test-helper</artifactId>
|
<artifactId>jetty-test-helper</artifactId>
|
||||||
|
|
|
@ -22,14 +22,12 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
|
||||||
import org.eclipse.jetty.websocket.api.ProtocolException;
|
import org.eclipse.jetty.websocket.api.ProtocolException;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.PingFrame;
|
import org.eclipse.jetty.websocket.common.frames.PingFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.PongFrame;
|
import org.eclipse.jetty.websocket.common.frames.PongFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.UnitGenerator;
|
import org.eclipse.jetty.websocket.common.test.UnitGenerator;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
@ -74,9 +72,6 @@ public class TestABCase3
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
private WebSocketFrame invalidFrame;
|
private WebSocketFrame invalidFrame;
|
||||||
|
|
||||||
public TestABCase3(WebSocketFrame invalidFrame)
|
public TestABCase3(WebSocketFrame invalidFrame)
|
||||||
|
|
|
@ -28,18 +28,13 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class HttpResponseHeaderParserTest
|
public class HttpResponseHeaderParserTest
|
||||||
{
|
{
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
private void appendUtf8(ByteBuffer buf, String line)
|
private void appendUtf8(ByteBuffer buf, String line)
|
||||||
{
|
{
|
||||||
buf.put(ByteBuffer.wrap(StringUtil.getUtf8Bytes(line)));
|
buf.put(ByteBuffer.wrap(StringUtil.getUtf8Bytes(line)));
|
||||||
|
|
|
@ -26,7 +26,6 @@ import java.util.Arrays;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
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.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
|
@ -48,9 +47,6 @@ public class MessageOutputStreamTest
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(MessageOutputStreamTest.class);
|
private static final Logger LOG = Log.getLogger(MessageOutputStreamTest.class);
|
||||||
|
|
||||||
@Rule
|
|
||||||
public TestTracker testtracker = new TestTracker();
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public TestName testname = new TestName();
|
public TestName testname = new TestName();
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.util.Arrays;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
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.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
|
@ -46,9 +45,6 @@ public class MessageWriterTest
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(MessageWriterTest.class);
|
private static final Logger LOG = Log.getLogger(MessageWriterTest.class);
|
||||||
|
|
||||||
@Rule
|
|
||||||
public TestTracker testtracker = new TestTracker();
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public TestName testname = new TestName();
|
public TestName testname = new TestName();
|
||||||
|
|
||||||
|
|
|
@ -18,833 +18,67 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.common.test;
|
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.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.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
|
||||||
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.websocket.api.WebSocketPolicy;
|
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
import org.eclipse.jetty.websocket.api.extensions.ExtensionFactory;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||||
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.common.extensions.WebSocketExtensionFactory;
|
import org.eclipse.jetty.websocket.common.extensions.WebSocketExtensionFactory;
|
||||||
import org.eclipse.jetty.websocket.common.io.IOState;
|
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
public class BlockheadClient extends HttpClient implements WebSocketContainerScope
|
||||||
* A simple websocket client for performing unit tests with.
|
|
||||||
* <p>
|
|
||||||
* This client will use {@link HttpURLConnection} and {@link HttpsURLConnection} with standard blocking calls to perform websocket requests.
|
|
||||||
* <p>
|
|
||||||
* This client is <u>NOT</u> 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.
|
|
||||||
* <p>
|
|
||||||
* 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 <u>what</u> byte it sends or reads is not within its
|
|
||||||
* scope.
|
|
||||||
*/
|
|
||||||
public class BlockheadClient implements OutgoingFrames, ConnectionStateListener, AutoCloseable, IBlockheadClient
|
|
||||||
{
|
{
|
||||||
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;
|
super(null);
|
||||||
public long totalReadOps = 0;
|
setName("Blockhead-CLIENT");
|
||||||
public long totalParseOps = 0;
|
this.policy = new WebSocketPolicy(WebSocketBehavior.CLIENT);
|
||||||
|
this.bufferPool = new MappedByteBufferPool();
|
||||||
public LinkedBlockingQueue<WebSocketFrame> frames = new LinkedBlockingQueue<>();
|
this.extensionFactory = new WebSocketExtensionFactory(this);
|
||||||
public LinkedBlockingQueue<Throwable> errors = new LinkedBlockingQueue<>();
|
this.objectFactory = new DecoratedObjectFactory();
|
||||||
|
|
||||||
@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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String REQUEST_HASH_KEY = "dGhlIHNhbXBsZSBub25jZQ==";
|
public ByteBufferPool getBufferPool()
|
||||||
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<String> extensions = new ArrayList<>();
|
|
||||||
private List<String> 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
|
|
||||||
{
|
{
|
||||||
this(WebSocketPolicy.newClientPolicy(),destWebsocketURI);
|
return bufferPool;
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnect()
|
public DecoratedObjectFactory getObjectFactory()
|
||||||
{
|
{
|
||||||
LOG.debug("disconnect");
|
return objectFactory;
|
||||||
IO.close(in);
|
|
||||||
IO.close(out);
|
|
||||||
disconnectedLatch.countDown();
|
|
||||||
if (frameReader != null)
|
|
||||||
{
|
|
||||||
frameReader.interrupt();
|
|
||||||
}
|
|
||||||
if (socket != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
catch (IOException ignore)
|
|
||||||
{
|
|
||||||
/* ignore */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
public ExtensionFactory getExtensionFactory()
|
||||||
* @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#expectServerDisconnect()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void expectServerDisconnect()
|
|
||||||
{
|
{
|
||||||
if (eof)
|
return extensionFactory;
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
public WebSocketPolicy getPolicy()
|
||||||
* @see org.eclipse.jetty.websocket.common.test.IBlockheadClient#expectUpgradeResponse()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public HttpResponse expectUpgradeResponse() throws IOException
|
|
||||||
{
|
{
|
||||||
HttpResponse response = readResponseHeader();
|
return policy;
|
||||||
|
|
||||||
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<ExtensionConfig> 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush() throws IOException
|
public BlockheadClientRequest newWsRequest(URI destURI)
|
||||||
{
|
{
|
||||||
out.flush();
|
return new BlockheadClientRequest(this, destURI);
|
||||||
}
|
|
||||||
|
|
||||||
public String getConnectionValue()
|
|
||||||
{
|
|
||||||
return connectionValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExecutorService getExecutor()
|
|
||||||
{
|
|
||||||
if (executor == null)
|
|
||||||
{
|
|
||||||
executor = Executors.newCachedThreadPool();
|
|
||||||
}
|
|
||||||
return executor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ExtensionConfig> getExtensionConfigs(HttpResponse response)
|
|
||||||
{
|
|
||||||
List<ExtensionConfig> 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<String> getExtensions()
|
|
||||||
{
|
|
||||||
return extensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public URI getHttpURI()
|
|
||||||
{
|
|
||||||
return destHttpURI;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InetSocketAddress getLocalSocketAddress()
|
public void onSessionOpened(WebSocketSession session)
|
||||||
{
|
{ /* ignored */ }
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InetSocketAddress getRemoteSocketAddress()
|
public void onSessionClosed(WebSocketSession session)
|
||||||
{
|
{ /* ignored */ }
|
||||||
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<WebSocketFrame> 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<Object[]> data()
|
|
||||||
{
|
|
||||||
List<Object[]> 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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<BlockheadConnection> 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<BlockheadConnection> 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<ExtensionConfig> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<WebSocketFrame> 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<WebSocketFrame> incomingFrames = new LinkedBlockingQueue<>();
|
||||||
|
public final LinkedBlockingQueue<Throwable> 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.
|
||||||
|
* <p>
|
||||||
|
* if ExtensionStack is in play, this should be wired up to the output from
|
||||||
|
* the ExtensionStack.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -396,7 +396,7 @@ public class BlockheadServerConnection implements IncomingFrames, OutgoingFrames
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
LOG.debug("Entering echo thread");
|
LOG.debug("Entering read thread");
|
||||||
|
|
||||||
long totalReadBytes = 0;
|
long totalReadBytes = 0;
|
||||||
ByteBuffer buf = bufferPool.acquire(BUFFER_SIZE, false);
|
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!");
|
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);
|
LOG.debug("Starting Read Thread: {}", readThread);
|
||||||
reading.set(true);
|
reading.set(true);
|
||||||
readThread.start();
|
readThread.start();
|
||||||
|
|
|
@ -27,19 +27,20 @@ import java.nio.ByteBuffer;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||||
import org.eclipse.jetty.websocket.common.Generator;
|
import org.eclipse.jetty.websocket.common.Generator;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.io.IOState;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,28 +48,13 @@ import org.junit.Assert;
|
||||||
*/
|
*/
|
||||||
public class Fuzzer implements AutoCloseable
|
public class Fuzzer implements AutoCloseable
|
||||||
{
|
{
|
||||||
public static enum CloseState
|
public enum SendMode
|
||||||
{
|
|
||||||
OPEN,
|
|
||||||
REMOTE_INITIATED,
|
|
||||||
LOCAL_INITIATED
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum SendMode
|
|
||||||
{
|
{
|
||||||
BULK,
|
BULK,
|
||||||
PER_FRAME,
|
PER_FRAME,
|
||||||
SLOW
|
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 KBYTE = 1024;
|
||||||
private static final int MBYTE = KBYTE * KBYTE;
|
private static final int MBYTE = KBYTE * KBYTE;
|
||||||
|
|
||||||
|
@ -78,24 +64,26 @@ public class Fuzzer implements AutoCloseable
|
||||||
protected static final byte[] MASK =
|
protected static final byte[] MASK =
|
||||||
{ 0x11, 0x22, 0x33, 0x44 };
|
{ 0x11, 0x22, 0x33, 0x44 };
|
||||||
|
|
||||||
|
private final Fuzzed testcase;
|
||||||
private final BlockheadClient client;
|
private final BlockheadClient client;
|
||||||
private final Generator generator;
|
private final Generator generator;
|
||||||
private final String testname;
|
private final String testname;
|
||||||
|
private BlockheadConnection clientConnection;
|
||||||
private SendMode sendMode = SendMode.BULK;
|
private SendMode sendMode = SendMode.BULK;
|
||||||
private int slowSendSegmentSize = 5;
|
private int slowSendSegmentSize = 5;
|
||||||
|
|
||||||
public Fuzzer(Fuzzed testcase) throws Exception
|
public Fuzzer(Fuzzed testcase) throws Exception
|
||||||
{
|
{
|
||||||
WebSocketPolicy policy = WebSocketPolicy.newClientPolicy();
|
this.testcase = testcase;
|
||||||
|
this.client = new BlockheadClient();
|
||||||
int bigMessageSize = 20 * MBYTE;
|
int bigMessageSize = 20 * MBYTE;
|
||||||
|
|
||||||
policy.setMaxTextMessageSize(bigMessageSize);
|
client.getPolicy().setMaxTextMessageSize(bigMessageSize);
|
||||||
policy.setMaxBinaryMessageSize(bigMessageSize);
|
client.getPolicy().setMaxBinaryMessageSize(bigMessageSize);
|
||||||
policy.setIdleTimeout(5000);
|
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.generator = testcase.getLaxGenerator();
|
||||||
this.testname = testcase.getTestMethodName();
|
this.testname = testcase.getTestMethodName();
|
||||||
}
|
}
|
||||||
|
@ -120,30 +108,43 @@ public class Fuzzer implements AutoCloseable
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws Exception
|
public void close()
|
||||||
{
|
{
|
||||||
this.client.disconnect();
|
this.clientConnection.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect()
|
public void disconnect()
|
||||||
{
|
{
|
||||||
this.client.disconnect();
|
this.clientConnection.abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect() throws IOException
|
public void connect() throws IOException
|
||||||
{
|
{
|
||||||
if (!client.isConnected())
|
BlockheadClientRequest request = this.client.newWsRequest(testcase.getServerURI());
|
||||||
|
request.header("X-TestCase", testname);
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
client.connect();
|
this.clientConnection = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
client.addHeader("X-TestCase: " + testname + "\r\n");
|
}
|
||||||
client.sendStandardRequest();
|
catch (InterruptedException e)
|
||||||
client.expectUpgradeResponse();
|
{
|
||||||
|
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<WebSocketFrame> expect) throws Exception
|
public void expect(List<WebSocketFrame> 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
|
* @param unit the timeout unit to wait for each read frame
|
||||||
* @throws Exception if unable to validate expectations
|
* @throws Exception if unable to validate expectations
|
||||||
*/
|
*/
|
||||||
public void expect(List<WebSocketFrame> expect, int duration, TimeUnit unit) throws Exception
|
public void expect(List<WebSocketFrame> expect, long duration, TimeUnit unit) throws Exception
|
||||||
{
|
{
|
||||||
int expectedCount = expect.size();
|
int expectedCount = expect.size();
|
||||||
LOG.debug("expect() {} frame(s)",expect.size());
|
LOG.debug("expect() {} frame(s)",expect.size());
|
||||||
|
|
||||||
// Read frames
|
// Read frames
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConnection.getFrameQueue();
|
||||||
|
|
||||||
String prefix = "";
|
String prefix = "";
|
||||||
for (int i = 0; i < expectedCount; i++)
|
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.
|
// 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()
|
public SendMode getSendMode()
|
||||||
{
|
{
|
||||||
return sendMode;
|
return sendMode;
|
||||||
|
@ -228,27 +211,26 @@ public class Fuzzer implements AutoCloseable
|
||||||
|
|
||||||
public void send(ByteBuffer buf) throws IOException
|
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));
|
LOG.debug("Sending bytes {}",BufferUtil.toDetailString(buf));
|
||||||
if (sendMode == SendMode.SLOW)
|
if (sendMode == SendMode.SLOW)
|
||||||
{
|
{
|
||||||
client.writeRawSlowly(buf,slowSendSegmentSize);
|
clientConnection.writeRawSlowly(buf,slowSendSegmentSize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
client.writeRaw(buf);
|
clientConnection.writeRaw(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send(ByteBuffer buf, int numBytes) throws IOException
|
public void send(ByteBuffer buf, int numBytes) throws IOException
|
||||||
{
|
{
|
||||||
client.writeRaw(buf,numBytes);
|
clientConnection.writeRaw(buf, numBytes);
|
||||||
client.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send(List<WebSocketFrame> send) throws IOException
|
public void send(List<WebSocketFrame> 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);
|
LOG.debug("[{}] Sending {} frames (mode {})",testname,send.size(),sendMode);
|
||||||
if ((sendMode == SendMode.BULK) || (sendMode == SendMode.SLOW))
|
if ((sendMode == SendMode.BULK) || (sendMode == SendMode.SLOW))
|
||||||
{
|
{
|
||||||
|
@ -275,10 +257,10 @@ public class Fuzzer implements AutoCloseable
|
||||||
switch (sendMode)
|
switch (sendMode)
|
||||||
{
|
{
|
||||||
case BULK:
|
case BULK:
|
||||||
client.writeRaw(buf);
|
clientConnection.writeRaw(buf);
|
||||||
break;
|
break;
|
||||||
case SLOW:
|
case SLOW:
|
||||||
client.writeRawSlowly(buf,slowSendSegmentSize);
|
clientConnection.writeRawSlowly(buf,slowSendSegmentSize);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Whoops, unsupported sendMode: " + sendMode);
|
throw new RuntimeException("Whoops, unsupported sendMode: " + sendMode);
|
||||||
|
@ -294,8 +276,7 @@ public class Fuzzer implements AutoCloseable
|
||||||
BufferUtil.clearToFill(fullframe);
|
BufferUtil.clearToFill(fullframe);
|
||||||
generator.generateWholeFrame(f,fullframe);
|
generator.generateWholeFrame(f,fullframe);
|
||||||
BufferUtil.flipToFlush(fullframe,0);
|
BufferUtil.flipToFlush(fullframe,0);
|
||||||
client.writeRaw(fullframe);
|
clientConnection.writeRaw(fullframe);
|
||||||
client.flush();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.Parser;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public interface IBlockheadServerConnection
|
public interface IBlockheadServerConnection
|
||||||
{
|
{
|
||||||
public void close() throws IOException;
|
public void close() throws IOException;
|
||||||
|
|
|
@ -22,6 +22,9 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class Timeouts
|
public class Timeouts
|
||||||
{
|
{
|
||||||
public static long POLL_EVENT = 2;
|
public static final long CONNECT = 2;
|
||||||
public static TimeUnit POLL_EVENT_UNIT = TimeUnit.SECONDS;
|
public static final TimeUnit CONNECT_UNIT = TimeUnit.SECONDS;
|
||||||
|
|
||||||
|
public static final long POLL_EVENT = 2;
|
||||||
|
public static final TimeUnit POLL_EVENT_UNIT = TimeUnit.SECONDS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,15 +20,16 @@ package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
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.Server;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
|
||||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.server.examples.echo.BigEchoSocket;
|
import org.eclipse.jetty.websocket.server.examples.echo.BigEchoSocket;
|
||||||
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class AnnotatedMaxMessageSizeTest
|
public class AnnotatedMaxMessageSizeTest
|
||||||
{
|
{
|
||||||
@Rule
|
private static BlockheadClient client;
|
||||||
public TestTracker tracker = new TestTracker();
|
|
||||||
|
|
||||||
private static Server server;
|
private static Server server;
|
||||||
private static ServerConnector connector;
|
private static ServerConnector connector;
|
||||||
private static URI serverUri;
|
private static URI serverUri;
|
||||||
|
@ -89,59 +89,64 @@ public class AnnotatedMaxMessageSizeTest
|
||||||
server.stop();
|
server.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@BeforeClass
|
||||||
public void testEchoGood() throws IOException, Exception
|
public static void startClient() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(serverUri);
|
client = new BlockheadClient();
|
||||||
try
|
client.setIdleTimeout(TimeUnit.SECONDS.toMillis(2));
|
||||||
{
|
client.start();
|
||||||
client.setProtocols("echo");
|
}
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
|
@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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
|
{
|
||||||
// Generate text frame
|
// Generate text frame
|
||||||
String msg = "this is an echo ... cho ... ho ... o";
|
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)
|
// Read frame (hopefully text frame)
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
|
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout=8000)
|
@Test(timeout=8000)
|
||||||
public void testEchoTooBig() throws IOException, Exception
|
public void testEchoTooBig() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(serverUri);
|
BlockheadClientRequest request = client.newWsRequest(serverUri);
|
||||||
try(StacklessLogging logging = new StacklessLogging(Parser.class))
|
request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "echo");
|
||||||
{
|
|
||||||
client.setProtocols("echo");
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
|
StacklessLogging ignore = new StacklessLogging(Parser.class))
|
||||||
|
{
|
||||||
// Generate text frame
|
// Generate text frame
|
||||||
int size = 120 * 1024;
|
int size = 120 * 1024;
|
||||||
byte buf[] = new byte[size]; // buffer bigger than maxMessageSize
|
byte buf[] = new byte[size]; // buffer bigger than maxMessageSize
|
||||||
Arrays.fill(buf,(byte)'x');
|
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)
|
// Read frame (hopefully close frame saying its too large)
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Frame is close", tf.getOpCode(), is(OpCode.CLOSE));
|
Assert.assertThat("Frame is close", tf.getOpCode(), is(OpCode.CLOSE));
|
||||||
CloseInfo close = new CloseInfo(tf);
|
CloseInfo close = new CloseInfo(tf);
|
||||||
Assert.assertThat("Close Code", close.getStatusCode(), is(StatusCode.MESSAGE_TOO_LARGE));
|
Assert.assertThat("Close Code", close.getStatusCode(), is(StatusCode.MESSAGE_TOO_LARGE));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,12 +21,18 @@ package org.eclipse.jetty.websocket.server;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.common.test.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.server.examples.MyEchoServlet;
|
import org.eclipse.jetty.websocket.server.examples.MyEchoServlet;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -37,6 +43,7 @@ import org.junit.Test;
|
||||||
|
|
||||||
public class ChromeTest
|
public class ChromeTest
|
||||||
{
|
{
|
||||||
|
private static BlockheadClient client;
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
|
@ -52,34 +59,49 @@ public class ChromeTest
|
||||||
server.stop();
|
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
|
@Test
|
||||||
public void testUpgradeWithWebkitDeflateExtension() throws Exception
|
public void testUpgradeWithWebkitDeflateExtension() throws Exception
|
||||||
{
|
{
|
||||||
Assume.assumeTrue("Server has x-webkit-deflate-frame registered",
|
Assume.assumeTrue("Server has x-webkit-deflate-frame registered",
|
||||||
server.getWebSocketServletFactory().getExtensionFactory().isAvailable("x-webkit-deflate-frame"));
|
server.getWebSocketServletFactory().getExtensionFactory().isAvailable("x-webkit-deflate-frame"));
|
||||||
|
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
Assume.assumeTrue("Client has x-webkit-deflate-frame registered",
|
||||||
try
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
{
|
{
|
||||||
client.addExtensions("x-webkit-deflate-frame");
|
HttpFields responseFields = clientConn.getUpgradeResponseHeaders();
|
||||||
client.setProtocols("chat");
|
HttpField extensionField = responseFields.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS);
|
||||||
client.connect();
|
Assert.assertThat("Response", extensionField.getValue(),containsString("x-webkit-deflate-frame"));
|
||||||
client.sendStandardRequest();
|
|
||||||
HttpResponse response = client.expectUpgradeResponse();
|
|
||||||
Assert.assertThat("Response",response.getExtensionsHeader(),containsString("x-webkit-deflate-frame"));
|
|
||||||
|
|
||||||
// Generate text frame
|
// Generate text frame
|
||||||
String msg = "this is an echo ... cho ... ho ... o";
|
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)
|
// Read frame (hopefully text frame)
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
|
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import static org.junit.Assert.assertThat;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||||
|
@ -50,29 +53,30 @@ import org.junit.Test;
|
||||||
@Ignore("Unstable - see Issue #1815")
|
@Ignore("Unstable - see Issue #1815")
|
||||||
public class DecoratorsLegacyTest
|
public class DecoratorsLegacyTest
|
||||||
{
|
{
|
||||||
|
|
||||||
private static class DecoratorsSocket extends WebSocketAdapter
|
private static class DecoratorsSocket extends WebSocketAdapter
|
||||||
{
|
{
|
||||||
private final DecoratedObjectFactory objFactory;
|
private final DecoratedObjectFactory objFactory;
|
||||||
|
|
||||||
public DecoratorsSocket(DecoratedObjectFactory objFactory)
|
public DecoratorsSocket(DecoratedObjectFactory objFactory)
|
||||||
{
|
{
|
||||||
this.objFactory = objFactory;
|
this.objFactory = objFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWebSocketText(String message)
|
public void onWebSocketText(String message)
|
||||||
{
|
{
|
||||||
StringWriter str = new StringWriter();
|
StringWriter str = new StringWriter();
|
||||||
PrintWriter out = new PrintWriter(str);
|
PrintWriter out = new PrintWriter(str);
|
||||||
|
|
||||||
if (objFactory != null)
|
if (objFactory != null)
|
||||||
{
|
{
|
||||||
out.printf("Object is a DecoratedObjectFactory%n");
|
out.printf("Object is a DecoratedObjectFactory%n");
|
||||||
List<Decorator> decorators = objFactory.getDecorators();
|
List<Decorator> decorators = objFactory.getDecorators();
|
||||||
out.printf("Decorators.size = [%d]%n",decorators.size());
|
out.printf("Decorators.size = [%d]%n", decorators.size());
|
||||||
for (Decorator decorator : decorators)
|
for (Decorator decorator : decorators)
|
||||||
{
|
{
|
||||||
out.printf(" decorator[] = %s%n",decorator.getClass().getName());
|
out.printf(" decorator[] = %s%n", decorator.getClass().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -90,7 +94,7 @@ public class DecoratorsLegacyTest
|
||||||
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
|
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
|
||||||
{
|
{
|
||||||
ServletContext servletContext = req.getHttpServletRequest().getServletContext();
|
ServletContext servletContext = req.getHttpServletRequest().getServletContext();
|
||||||
DecoratedObjectFactory objFactory = (DecoratedObjectFactory)servletContext.getAttribute(DecoratedObjectFactory.ATTR);
|
DecoratedObjectFactory objFactory = (DecoratedObjectFactory) servletContext.getAttribute(DecoratedObjectFactory.ATTR);
|
||||||
return new DecoratorsSocket(objFactory);
|
return new DecoratorsSocket(objFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +115,7 @@ public class DecoratorsLegacyTest
|
||||||
factory.setCreator(this.creator);
|
factory.setCreator(this.creator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private static class DummyLegacyDecorator implements org.eclipse.jetty.servlet.ServletContextHandler.Decorator
|
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 SimpleServletServer server;
|
||||||
private static DecoratorsCreator decoratorsCreator;
|
private static DecoratorsCreator decoratorsCreator;
|
||||||
|
|
||||||
|
@ -154,31 +159,39 @@ public class DecoratorsLegacyTest
|
||||||
server.stop();
|
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
|
@Test
|
||||||
public void testAccessRequestCookies() throws Exception
|
public void testAccessRequestCookies() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
request.idleTimeout(1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
try
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
{
|
{
|
||||||
client.connect();
|
clientConn.write(new TextFrame().setPayload("info"));
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("info"));
|
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame resp = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame resp = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
String textMsg = resp.getPayloadAsUTF8();
|
String textMsg = resp.getPayloadAsUTF8();
|
||||||
|
|
||||||
assertThat("DecoratedObjectFactory", textMsg, containsString("Object is a DecoratedObjectFactory"));
|
assertThat("DecoratedObjectFactory", textMsg, containsString("Object is a DecoratedObjectFactory"));
|
||||||
assertThat("decorators.size", textMsg, containsString("Decorators.size = [1]"));
|
assertThat("decorators.size", textMsg, containsString("Decorators.size = [1]"));
|
||||||
assertThat("decorator type", textMsg, containsString("decorator[] = " + DummyLegacyDecorator.class.getName()));
|
assertThat("decorator type", textMsg, containsString("decorator[] = " + DummyLegacyDecorator.class.getName()));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import static org.junit.Assert.assertThat;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
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.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@Ignore
|
|
||||||
public class DecoratorsTest
|
public class DecoratorsTest
|
||||||
{
|
{
|
||||||
private static class DecoratorsSocket extends WebSocketAdapter
|
private static class DecoratorsSocket extends WebSocketAdapter
|
||||||
|
@ -126,6 +127,7 @@ public class DecoratorsTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static BlockheadClient client;
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
private static DecoratorsCreator decoratorsCreator;
|
private static DecoratorsCreator decoratorsCreator;
|
||||||
|
|
||||||
|
@ -152,21 +154,32 @@ public class DecoratorsTest
|
||||||
server.stop();
|
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
|
@Test
|
||||||
public void testAccessRequestCookies() throws Exception
|
public void testAccessRequestCookies() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
try
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
{
|
{
|
||||||
client.connect();
|
clientConn.write(new TextFrame().setPayload("info"));
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("info"));
|
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame resp = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame resp = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
String textMsg = resp.getPayloadAsUTF8();
|
String textMsg = resp.getPayloadAsUTF8();
|
||||||
|
|
||||||
|
@ -174,9 +187,5 @@ public class DecoratorsTest
|
||||||
assertThat("decorators.size", textMsg, containsString("Decorators.size = [1]"));
|
assertThat("decorators.size", textMsg, containsString("Decorators.size = [1]"));
|
||||||
assertThat("decorator type", textMsg, containsString("decorator[] = " + DummyUtilDecorator.class.getName()));
|
assertThat("decorator type", textMsg, containsString("decorator[] = " + DummyUtilDecorator.class.getName()));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,16 @@ package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.eclipse.jetty.websocket.server.examples.MyEchoServlet;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
@ -34,39 +38,45 @@ import org.junit.Test;
|
||||||
|
|
||||||
public class FirefoxTest
|
public class FirefoxTest
|
||||||
{
|
{
|
||||||
|
private static BlockheadClient client;
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void startServer() throws Exception
|
public static void startContainers() throws Exception
|
||||||
{
|
{
|
||||||
server = new SimpleServletServer(new MyEchoServlet());
|
server = new SimpleServletServer(new MyEchoServlet());
|
||||||
server.start();
|
server.start();
|
||||||
|
|
||||||
|
client = new BlockheadClient();
|
||||||
|
client.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void stopServer()
|
public static void stopContainers() throws Exception
|
||||||
{
|
{
|
||||||
|
client.stop();
|
||||||
server.stop();
|
server.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConnectionKeepAlive() throws Exception
|
public void testConnectionKeepAlive() throws Exception
|
||||||
{
|
{
|
||||||
try (IBlockheadClient client = new BlockheadClient(server.getServerUri()))
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
{
|
|
||||||
// Odd Connection Header value seen in Firefox
|
|
||||||
client.setConnectionValue("keep-alive, Upgrade");
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
|
// Odd Connection Header value seen in older Firefox versions
|
||||||
|
request.header(HttpHeader.CONNECTION, "keep-alive, Upgrade");
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try(BlockheadConnection conn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
|
{
|
||||||
// Generate text frame
|
// Generate text frame
|
||||||
String msg = "this is an echo ... cho ... ho ... o";
|
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)
|
// Read frame (hopefully text frame)
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = conn.getFrameQueue();
|
||||||
WebSocketFrame tf = frames.poll();
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Text Frame.status code", tf.getPayloadAsUTF8(), is(msg));
|
Assert.assertThat("Text Frame.status code", tf.getPayloadAsUTF8(), is(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,23 +21,30 @@ package org.eclipse.jetty.websocket.server;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.common.test.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.server.helper.EchoServlet;
|
import org.eclipse.jetty.websocket.server.helper.EchoServlet;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Assume;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class FragmentExtensionTest
|
public class FragmentExtensionTest
|
||||||
{
|
{
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
private static BlockheadClient client;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void startServer() throws Exception
|
public static void startServer() throws Exception
|
||||||
|
@ -52,6 +59,20 @@ public class FragmentExtensionTest
|
||||||
server.stop();
|
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)
|
private String[] split(String str, int partSize)
|
||||||
{
|
{
|
||||||
int strLength = str.length();
|
int strLength = str.length();
|
||||||
|
@ -69,37 +90,39 @@ public class FragmentExtensionTest
|
||||||
@Test
|
@Test
|
||||||
public void testFragmentExtension() throws Exception
|
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;
|
int fragSize = 4;
|
||||||
|
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
client.clearExtensions();
|
request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "fragment;maxLength=" + fragSize);
|
||||||
client.addExtensions("fragment;maxLength=" + fragSize);
|
request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "onConnect");
|
||||||
client.setProtocols("onConnect");
|
request.idleTimeout(1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
try
|
Future<BlockheadConnection> 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
|
// Make sure the read times out if there are problems with the implementation
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders();
|
||||||
client.connect();
|
HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS);
|
||||||
client.sendStandardRequest();
|
|
||||||
HttpResponse resp = client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
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";
|
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);
|
String parts[] = split(msg,fragSize);
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
for (int i = 0; i < parts.length; i++)
|
for (int i = 0; i < parts.length; i++)
|
||||||
{
|
{
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("text[" + i + "].payload",frame.getPayloadAsUTF8(),is(parts[i]));
|
Assert.assertThat("text[" + i + "].payload",frame.getPayloadAsUTF8(),is(parts[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,18 @@ package org.eclipse.jetty.websocket.server;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.common.test.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.server.helper.EchoServlet;
|
import org.eclipse.jetty.websocket.server.helper.EchoServlet;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -38,6 +43,7 @@ import org.junit.Test;
|
||||||
public class IdentityExtensionTest
|
public class IdentityExtensionTest
|
||||||
{
|
{
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
private static BlockheadClient client;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void startServer() throws Exception
|
public static void startServer() throws Exception
|
||||||
|
@ -52,34 +58,43 @@ public class IdentityExtensionTest
|
||||||
server.stop();
|
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
|
@Test
|
||||||
public void testIdentityExtension() throws Exception
|
public void testIdentityExtension() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
client.clearExtensions();
|
request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "identity;param=0");
|
||||||
client.addExtensions("identity;param=0");
|
request.header(HttpHeader.SEC_WEBSOCKET_EXTENSIONS, "identity;param=1, identity ; param = '2' ; other = ' some = value '");
|
||||||
client.addExtensions("identity;param=1, identity ; param = '2' ; other = ' some = value '");
|
request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "onConnect");
|
||||||
client.setProtocols("onConnect");
|
request.idleTimeout(1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
try
|
Future<BlockheadConnection> 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
|
HttpFields responseHeaders = clientConn.getUpgradeResponseHeaders();
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
HttpField extensionHeader = responseHeaders.getField(HttpHeader.SEC_WEBSOCKET_EXTENSIONS);
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
HttpResponse resp = client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
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<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is("Hello"));
|
Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is("Hello"));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,19 @@ package org.eclipse.jetty.websocket.server;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
|
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
|
||||||
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
|
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
|
||||||
|
@ -41,17 +45,23 @@ import org.junit.Test;
|
||||||
|
|
||||||
public class IdleTimeoutTest
|
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")
|
@SuppressWarnings("serial")
|
||||||
public static class TimeoutServlet extends WebSocketServlet
|
public static class TimeoutServlet extends WebSocketServlet
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void configure(WebSocketServletFactory factory)
|
public void configure(WebSocketServletFactory factory)
|
||||||
{
|
{
|
||||||
factory.getPolicy().setIdleTimeout(500);
|
factory.getPolicy().setIdleTimeout(IDLE_TIMEOUT_MS_WEBSOCKET_SERVER);
|
||||||
factory.register(RFCSocket.class);
|
factory.register(RFCSocket.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static BlockheadClient client;
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
|
@ -67,6 +77,20 @@ public class IdleTimeoutTest
|
||||||
server.stop();
|
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.
|
* Test IdleTimeout on server.
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
|
@ -74,37 +98,32 @@ public class IdleTimeoutTest
|
||||||
@Test
|
@Test
|
||||||
public void testIdleTimeout() throws Exception
|
public void testIdleTimeout() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
client.setProtocols("onConnect");
|
request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "onConnect");
|
||||||
client.setTimeout(2500,TimeUnit.MILLISECONDS);
|
request.idleTimeout(IDLE_TIMEOUT_MS_WEBSOCKET_CLIENT, TimeUnit.MILLISECONDS);
|
||||||
try
|
|
||||||
{
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
|
{
|
||||||
// This wait should be shorter than client timeout above, but
|
// This wait should be shorter than client timeout above, but
|
||||||
// longer than server timeout configured in TimeoutServlet
|
// longer than server timeout configured in TimeoutServlet
|
||||||
client.sleep(TimeUnit.MILLISECONDS,1000);
|
TimeUnit.MILLISECONDS.sleep(IDLE_TIMEOUT_ON_SERVER);
|
||||||
|
|
||||||
// Write to server
|
// Write to server
|
||||||
// This action is possible, but does nothing.
|
// This action is possible, but does nothing.
|
||||||
// Server could be in a half-closed state at this point.
|
// 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.
|
// 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
|
// 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
|
// Expect server to have closed due to its own timeout
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("frame opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
Assert.assertThat("frame opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||||
CloseInfo close = new CloseInfo(frame);
|
CloseInfo close = new CloseInfo(frame);
|
||||||
Assert.assertThat("close code",close.getStatusCode(),is(StatusCode.SHUTDOWN));
|
Assert.assertThat("close code",close.getStatusCode(),is(StatusCode.SHUTDOWN));
|
||||||
Assert.assertThat("close reason",close.getReason(),containsString("Timeout"));
|
Assert.assertThat("close reason",close.getReason(),containsString("Timeout"));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,21 +18,23 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.server;
|
package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.junit.Assert.*;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
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.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||||
import org.eclipse.jetty.util.log.StdErrLog;
|
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
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.WebSocketSession;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.common.test.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
|
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
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.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests various close scenarios that should result in Open Session cleanup
|
* Tests various close scenarios that should result in Open Session cleanup
|
||||||
*/
|
*/
|
||||||
@Ignore
|
|
||||||
public class ManyConnectionsCleanupTest
|
public class ManyConnectionsCleanupTest
|
||||||
{
|
{
|
||||||
static class AbstractCloseSocket extends WebSocketAdapter
|
static class AbstractCloseSocket extends WebSocketAdapter
|
||||||
|
@ -220,6 +221,7 @@ public class ManyConnectionsCleanupTest
|
||||||
|
|
||||||
private static final Logger LOG = Log.getLogger(ManyConnectionsCleanupTest.class);
|
private static final Logger LOG = Log.getLogger(ManyConnectionsCleanupTest.class);
|
||||||
|
|
||||||
|
private static BlockheadClient client;
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
private static AbstractCloseSocket closeSocket;
|
private static AbstractCloseSocket closeSocket;
|
||||||
|
|
||||||
|
@ -236,6 +238,20 @@ public class ManyConnectionsCleanupTest
|
||||||
server.stop();
|
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)
|
* Test session open session cleanup (bug #474936)
|
||||||
*
|
*
|
||||||
|
@ -245,35 +261,31 @@ public class ManyConnectionsCleanupTest
|
||||||
@Test
|
@Test
|
||||||
public void testOpenSessionCleanup() throws Exception
|
public void testOpenSessionCleanup() throws Exception
|
||||||
{
|
{
|
||||||
int iterationCount = 100;
|
int iterationCount = 20;
|
||||||
|
|
||||||
StdErrLog.getLogger(FastFailSocket.class).setLevel(StdErrLog.LEVEL_OFF);
|
// TODO: consider a SilentLogging alternative class
|
||||||
|
try(StacklessLogging ignore = new StacklessLogging(FastFailSocket.class, WebSocketSession.class))
|
||||||
StdErrLog sessLog = StdErrLog.getLogger(WebSocketSession.class);
|
|
||||||
int oldLevel = sessLog.getLevel();
|
|
||||||
sessLog.setLevel(StdErrLog.LEVEL_OFF);
|
|
||||||
|
|
||||||
for (int requests = 0; requests < iterationCount; requests++)
|
|
||||||
{
|
{
|
||||||
fastFail();
|
for (int requests = 0; requests < iterationCount; requests++)
|
||||||
fastClose();
|
{
|
||||||
dropConnection();
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
{
|
{
|
||||||
client.setProtocols("container");
|
clientConn.write(new TextFrame().setPayload("calls"));
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
clientConn.write(new TextFrame().setPayload("openSessions"));
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("calls"));
|
|
||||||
client.write(new TextFrame().setPayload("openSessions"));
|
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame;
|
WebSocketFrame frame;
|
||||||
String resp;
|
String resp;
|
||||||
|
|
||||||
|
@ -291,7 +303,7 @@ public class ManyConnectionsCleanupTest
|
||||||
assertThat("frames[2].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
assertThat("frames[2].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||||
CloseInfo close = new CloseInfo(frame);
|
CloseInfo close = new CloseInfo(frame);
|
||||||
assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL));
|
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
|
// ensure server socket got close event
|
||||||
assertThat("Open Sessions Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
assertThat("Open Sessions Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
||||||
|
@ -302,70 +314,63 @@ public class ManyConnectionsCleanupTest
|
||||||
|
|
||||||
private void fastClose() throws Exception
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
|
StacklessLogging ignore = new StacklessLogging(WebSocketSession.class))
|
||||||
{
|
{
|
||||||
client.setProtocols("fastclose");
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class))
|
|
||||||
{
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal");
|
||||||
frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL));
|
||||||
|
|
||||||
CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal");
|
// Notify server of close handshake
|
||||||
assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL));
|
clientConn.write(close.asFrame()); // respond with close
|
||||||
|
|
||||||
// Notify server of close handshake
|
// ensure server socket got close event
|
||||||
client.write(close.asFrame()); // respond with close
|
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
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
|
StacklessLogging ignore = new StacklessLogging(WebSocketSession.class))
|
||||||
{
|
{
|
||||||
client.setProtocols("fastfail");
|
CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal");
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
clientConn.write(close.asFrame()); // respond with close
|
||||||
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");
|
// ensure server socket got close event
|
||||||
client.write(close.asFrame()); // respond with close
|
assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
||||||
|
assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR));
|
||||||
// ensure server socket got close event
|
assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1));
|
||||||
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
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
|
StacklessLogging ignore = new StacklessLogging(WebSocketSession.class))
|
||||||
{
|
{
|
||||||
client.setProtocols("container");
|
clientConn.abort();
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
|
||||||
try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class))
|
|
||||||
{
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
client.disconnect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,16 @@ import static org.junit.Assert.assertThat;
|
||||||
import java.net.HttpCookie;
|
import java.net.HttpCookie;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.websocket.api.UpgradeRequest;
|
import org.eclipse.jetty.websocket.api.UpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.server.helper.EchoSocket;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||||
|
@ -43,6 +48,7 @@ import org.junit.Test;
|
||||||
|
|
||||||
public class RequestHeadersTest
|
public class RequestHeadersTest
|
||||||
{
|
{
|
||||||
|
|
||||||
private static class EchoCreator implements WebSocketCreator
|
private static class EchoCreator implements WebSocketCreator
|
||||||
{
|
{
|
||||||
private UpgradeRequest lastRequest;
|
private UpgradeRequest lastRequest;
|
||||||
|
@ -86,6 +92,7 @@ public class RequestHeadersTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static BlockheadClient client;
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
private static EchoCreator echoCreator;
|
private static EchoCreator echoCreator;
|
||||||
|
|
||||||
|
@ -103,19 +110,31 @@ public class RequestHeadersTest
|
||||||
server.stop();
|
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
|
@Test
|
||||||
public void testAccessRequestCookies() throws Exception
|
public void testAccessRequestCookies() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
request.idleTimeout(1, TimeUnit.SECONDS);
|
||||||
|
request.header(HttpHeader.COOKIE, "fruit=Pear; type=Anjou");
|
||||||
|
|
||||||
try
|
Future<BlockheadConnection> 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();
|
UpgradeRequest req = echoCreator.getLastRequest();
|
||||||
assertThat("Last Request",req,notNullValue());
|
assertThat("Last Request",req,notNullValue());
|
||||||
List<HttpCookie> cookies = req.getCookies();
|
List<HttpCookie> cookies = req.getCookies();
|
||||||
|
@ -127,25 +146,19 @@ public class RequestHeadersTest
|
||||||
assertThat("Cookie value",cookie.getValue(),anyOf(is("Pear"),is("Anjou")));
|
assertThat("Cookie value",cookie.getValue(),anyOf(is("Pear"),is("Anjou")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRequestURI() throws Exception
|
public void testRequestURI() throws Exception
|
||||||
{
|
{
|
||||||
URI destUri = server.getServerUri().resolve("/?abc=x%20z&breakfast=bacon%26eggs&2*2%3d5=false");
|
URI destUri = server.getServerUri().resolve("/?abc=x%20z&breakfast=bacon%26eggs&2*2%3d5=false");
|
||||||
BlockheadClient client = new BlockheadClient(destUri);
|
BlockheadClientRequest request = client.newWsRequest(destUri);
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
request.idleTimeout(1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
try
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection ignore = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
{
|
{
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
UpgradeRequest req = echoCreator.getLastRequest();
|
UpgradeRequest req = echoCreator.getLastRequest();
|
||||||
assertThat("Last Request",req,notNullValue());
|
assertThat("Last Request",req,notNullValue());
|
||||||
assertThat("Request.host", req.getHost(), is(server.getServerUri().getHost()));
|
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.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"));
|
assertThat("Request.uri.query", req.getRequestURI().getQuery(), is("abc=x z&breakfast=bacon&eggs&2*2=5=false"));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,11 @@ package org.eclipse.jetty.websocket.server;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
||||||
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||||
|
@ -90,7 +94,8 @@ public class SubProtocolTest
|
||||||
factory.setCreator(new ProtocolCreator());
|
factory.setCreator(new ProtocolCreator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static BlockheadClient client;
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
|
@ -105,6 +110,20 @@ public class SubProtocolTest
|
||||||
{
|
{
|
||||||
server.stop();
|
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
|
@Test
|
||||||
public void testSingleProtocol() throws Exception
|
public void testSingleProtocol() throws Exception
|
||||||
|
@ -120,17 +139,16 @@ public class SubProtocolTest
|
||||||
|
|
||||||
private void testSubProtocol(String requestProtocols, String acceptedSubProtocols) throws Exception
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
{
|
{
|
||||||
client.setTimeout(1, TimeUnit.SECONDS);
|
clientConn.write(new TextFrame().setPayload("showme"));
|
||||||
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
client.connect();
|
|
||||||
client.addHeader("Sec-WebSocket-Protocol: "+ requestProtocols + "\r\n");
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("showme"));
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
|
||||||
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
|
|
||||||
assertThat(ProtocolEchoSocket.class.getSimpleName() + ".onMessage()", tf.getPayloadAsUTF8(), is("acceptedSubprotocol=" + acceptedSubProtocols));
|
assertThat(ProtocolEchoSocket.class.getSimpleName() + ".onMessage()", tf.getPayloadAsUTF8(), is("acceptedSubprotocol=" + acceptedSubProtocols));
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.websocket.server;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||||
|
@ -101,6 +104,7 @@ public class SuspendResumeTest
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
private static BlockheadClient client;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void startServer() throws Exception
|
public static void startServer() throws Exception
|
||||||
|
@ -108,7 +112,21 @@ public class SuspendResumeTest
|
||||||
server = new SimpleServletServer(new EchoServlet());
|
server = new SimpleServletServer(new EchoServlet());
|
||||||
server.start();
|
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
|
@AfterClass
|
||||||
public static void stopServer()
|
public static void stopServer()
|
||||||
{
|
{
|
||||||
|
@ -118,18 +136,16 @@ public class SuspendResumeTest
|
||||||
@Test
|
@Test
|
||||||
public void testSuspendResume() throws Exception
|
public void testSuspendResume() throws Exception
|
||||||
{
|
{
|
||||||
try (BlockheadClient client = new BlockheadClient(server.getServerUri()))
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
|
|
||||||
|
Future<BlockheadConnection> 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();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("echo1"));
|
|
||||||
client.write(new TextFrame().setPayload("echo2"));
|
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
|
||||||
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
assertThat(EchoSocket.class.getSimpleName() + ".onMessage()", tf.getPayloadAsUTF8(), is("echo1"));
|
assertThat(EchoSocket.class.getSimpleName() + ".onMessage()", tf.getPayloadAsUTF8(), is("echo1"));
|
||||||
tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
|
|
|
@ -23,9 +23,10 @@ import static org.hamcrest.Matchers.is;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
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.io.MappedByteBufferPool;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.server.examples.MyEchoServlet;
|
import org.eclipse.jetty.websocket.server.examples.MyEchoServlet;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,6 +52,7 @@ import org.junit.Test;
|
||||||
public class TooFastClientTest
|
public class TooFastClientTest
|
||||||
{
|
{
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
private static BlockheadClient client;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void startServer() throws Exception
|
public static void startServer() throws Exception
|
||||||
|
@ -64,119 +67,93 @@ public class TooFastClientTest
|
||||||
server.stop();
|
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
|
@Test
|
||||||
@Ignore("RELEASE")
|
|
||||||
public void testUpgradeWithSmallFrames() throws Exception
|
public void testUpgradeWithSmallFrames() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
try
|
|
||||||
|
String msg1 = "Echo 1";
|
||||||
|
String msg2 = "This is also an echooooo!";
|
||||||
|
|
||||||
|
ByteBuffer initialPacket = createInitialPacket(msg1, msg2);
|
||||||
|
request.setInitialBytes(initialPacket);
|
||||||
|
|
||||||
|
Future<BlockheadConnection> 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)
|
// Read frames (hopefully text frames)
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Text Frame/msg1",tf.getPayloadAsUTF8(),is(msg1));
|
Assert.assertThat("Text Frame/msg1",tf.getPayloadAsUTF8(),is(msg1));
|
||||||
tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Text Frame/msg2",tf.getPayloadAsUTF8(),is(msg2));
|
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)
|
* 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 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.
|
* the normal input buffer sizes.
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Ignore("RELEASE")
|
|
||||||
public void testUpgradeWithLargeFrame() throws Exception
|
public void testUpgradeWithLargeFrame() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
try
|
|
||||||
|
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<BlockheadConnection> 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)
|
// Read frames (hopefully text frames)
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
|
|
||||||
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Text Frame/msg1",tf.getPayloadAsUTF8(),is(bigMsg));
|
Assert.assertThat("Text Frame/msg1",tf.getPayloadAsUTF8(),is(bigMsg));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,11 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
import org.eclipse.jetty.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.WebSocketSession;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.common.test.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
|
import org.eclipse.jetty.websocket.server.helper.RFCSocket;
|
||||||
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
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.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests various close scenarios
|
* Tests various close scenarios
|
||||||
*/
|
*/
|
||||||
@Ignore
|
|
||||||
public class WebSocketCloseTest
|
public class WebSocketCloseTest
|
||||||
{
|
{
|
||||||
static class AbstractCloseSocket extends WebSocketAdapter
|
static class AbstractCloseSocket extends WebSocketAdapter
|
||||||
|
@ -198,6 +199,7 @@ public class WebSocketCloseTest
|
||||||
|
|
||||||
private static final Logger LOG = Log.getLogger(WebSocketCloseTest.class);
|
private static final Logger LOG = Log.getLogger(WebSocketCloseTest.class);
|
||||||
|
|
||||||
|
private static BlockheadClient client;
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
private static AbstractCloseSocket closeSocket;
|
private static AbstractCloseSocket closeSocket;
|
||||||
|
|
||||||
|
@ -214,6 +216,20 @@ public class WebSocketCloseTest
|
||||||
server.stop();
|
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)
|
* Test fast close (bug #403817)
|
||||||
*
|
*
|
||||||
|
@ -223,23 +239,23 @@ public class WebSocketCloseTest
|
||||||
@Test
|
@Test
|
||||||
public void testFastClose() throws Exception
|
public void testFastClose() throws Exception
|
||||||
{
|
{
|
||||||
try (IBlockheadClient client = new BlockheadClient(server.getServerUri()))
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
{
|
request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "fastclose");
|
||||||
client.setProtocols("fastclose");
|
request.idleTimeout(5,TimeUnit.SECONDS);
|
||||||
client.setTimeout(5,TimeUnit.SECONDS);
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
|
{
|
||||||
// Verify that client got close frame
|
// Verify that client got close frame
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||||
CloseInfo close = new CloseInfo(frame);
|
CloseInfo close = new CloseInfo(frame);
|
||||||
assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL));
|
assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL));
|
||||||
|
|
||||||
// Notify server of close handshake
|
// 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
|
// ensure server socket got close event
|
||||||
assertThat("Fast Close Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true));
|
assertThat("Fast Close Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||||
|
@ -256,29 +272,27 @@ public class WebSocketCloseTest
|
||||||
@Test
|
@Test
|
||||||
public void testFastFail() throws Exception
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
|
StacklessLogging ignore = new StacklessLogging(FastFailSocket.class, WebSocketSession.class))
|
||||||
{
|
{
|
||||||
client.setProtocols("fastfail");
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
client.setTimeout(5,TimeUnit.SECONDS);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
try (StacklessLogging scope = new StacklessLogging(FastFailSocket.class, WebSocketSession.class))
|
assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||||
{
|
CloseInfo close = new CloseInfo(frame);
|
||||||
client.connect();
|
assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR));
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
clientConn.write(close.asFrame()); // respond with close
|
||||||
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
|
// ensure server socket got close event
|
||||||
|
assertThat("Fast Fail Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||||
// ensure server socket got close event
|
assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR));
|
||||||
assertThat("Fast Fail Latch",closeSocket.closeLatch.await(5,TimeUnit.SECONDS),is(true));
|
assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1));
|
||||||
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();
|
fastClose();
|
||||||
dropConnection();
|
dropConnection();
|
||||||
|
|
||||||
try (IBlockheadClient client = new BlockheadClient(server.getServerUri()))
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
{
|
request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "container");
|
||||||
client.setProtocols("container");
|
request.idleTimeout(1,TimeUnit.SECONDS);
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
|
{
|
||||||
TextFrame text = new TextFrame();
|
TextFrame text = new TextFrame();
|
||||||
text.setPayload("openSessions");
|
text.setPayload("openSessions");
|
||||||
client.write(text);
|
clientConn.write(text);
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.TEXT));
|
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));
|
assertThat("frames[1].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||||
CloseInfo close = new CloseInfo(frame);
|
CloseInfo close = new CloseInfo(frame);
|
||||||
assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL));
|
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
|
// ensure server socket got close event
|
||||||
assertThat("Open Sessions Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
assertThat("Open Sessions Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
||||||
|
@ -330,72 +344,67 @@ public class WebSocketCloseTest
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
private void fastClose() throws Exception
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
|
StacklessLogging ignore = new StacklessLogging(WebSocketSession.class))
|
||||||
{
|
{
|
||||||
client.setProtocols("fastclose");
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class))
|
|
||||||
{
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal");
|
||||||
WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL));
|
||||||
|
|
||||||
CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal");
|
// Notify server of close handshake
|
||||||
assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.NORMAL));
|
clientConn.write(close.asFrame()); // respond with close
|
||||||
|
|
||||||
// Notify server of close handshake
|
// ensure server socket got close event
|
||||||
client.write(close.asFrame()); // respond with close
|
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
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
|
StacklessLogging ignore = new StacklessLogging(WebSocketSession.class))
|
||||||
{
|
{
|
||||||
client.setProtocols("fastfail");
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class))
|
|
||||||
{
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal");
|
||||||
WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
clientConn.write(close.asFrame()); // respond with close
|
||||||
|
|
||||||
CloseInfo close = new CloseInfo(StatusCode.NORMAL,"Normal");
|
// ensure server socket got close event
|
||||||
client.write(close.asFrame()); // respond with close
|
assertThat("Fast Fail Latch",closeSocket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
||||||
|
assertThat("Fast Fail.statusCode",closeSocket.closeStatusCode,is(StatusCode.SERVER_ERROR));
|
||||||
// ensure server socket got close event
|
assertThat("Fast Fail.errors",closeSocket.errors.size(),is(1));
|
||||||
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")
|
@SuppressWarnings("Duplicates")
|
||||||
private void dropConnection() throws Exception
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
|
StacklessLogging ignore = new StacklessLogging(WebSocketSession.class))
|
||||||
{
|
{
|
||||||
client.setProtocols("container");
|
clientConn.abort();
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
|
||||||
try (StacklessLogging scope = new StacklessLogging(WebSocketSession.class))
|
|
||||||
{
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
client.disconnect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,18 +19,31 @@
|
||||||
package org.eclipse.jetty.websocket.server;
|
package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
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.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.eclipse.jetty.websocket.server.examples.MyEchoServlet;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
public class WebSocketInvalidVersionTest
|
public class WebSocketInvalidVersionTest
|
||||||
{
|
{
|
||||||
|
@Rule
|
||||||
|
public ExpectedException expectedException = ExpectedException.none();
|
||||||
|
|
||||||
|
private static BlockheadClient client;
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
|
@ -46,28 +59,40 @@ public class WebSocketInvalidVersionTest
|
||||||
server.stop();
|
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.
|
* Test the requirement of responding with an http 400 when using a Sec-WebSocket-Version that is unsupported.
|
||||||
|
*
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testRequestVersion29() throws Exception
|
public void testRequestVersion29() throws Exception
|
||||||
{
|
{
|
||||||
@SuppressWarnings("resource")
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
// intentionally bad version
|
||||||
client.setVersion(29); // intentionally bad version
|
request.header(HttpHeader.SEC_WEBSOCKET_VERSION, "29");
|
||||||
try
|
|
||||||
|
Future<BlockheadConnection> 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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
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.BatchMode;
|
||||||
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
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.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class WebSocketOverSSLTest
|
public class WebSocketOverSSLTest
|
||||||
{
|
{
|
||||||
public static final int CONNECT_TIMEOUT = 15000;
|
public static final int CONNECT_TIMEOUT = 15000;
|
||||||
public static final int FUTURE_TIMEOUT_SEC = 30;
|
public static final int FUTURE_TIMEOUT_SEC = 30;
|
||||||
@Rule
|
|
||||||
public TestTracker tracker = new TestTracker();
|
|
||||||
|
|
||||||
public ByteBufferPool bufferPool = new MappedByteBufferPool();
|
public ByteBufferPool bufferPool = new MappedByteBufferPool();
|
||||||
|
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
|
|
@ -21,29 +21,29 @@ package org.eclipse.jetty.websocket.server;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.common.test.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.server.helper.SessionServlet;
|
import org.eclipse.jetty.websocket.server.helper.SessionServlet;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
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}
|
* Testing various aspects of the server side support for WebSocket {@link org.eclipse.jetty.websocket.api.Session}
|
||||||
*/
|
*/
|
||||||
@RunWith(AdvancedRunner.class)
|
|
||||||
public class WebSocketServerSessionTest
|
public class WebSocketServerSessionTest
|
||||||
{
|
{
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
private static BlockheadClient client;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void startServer() throws Exception
|
public static void startServer() throws Exception
|
||||||
|
@ -58,19 +58,36 @@ public class WebSocketServerSessionTest
|
||||||
server.stop();
|
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
|
@Test
|
||||||
public void testDisconnect() throws Exception
|
public void testDisconnect() throws Exception
|
||||||
{
|
{
|
||||||
URI uri = server.getServerUri().resolve("/test/disconnect");
|
URI uri = server.getServerUri().resolve("/test/disconnect");
|
||||||
try (IBlockheadClient client = new BlockheadClient(uri))
|
|
||||||
|
BlockheadClientRequest request = client.newWsRequest(uri);
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
{
|
{
|
||||||
client.connect();
|
clientConn.write(new TextFrame().setPayload("harsh-disconnect"));
|
||||||
client.sendStandardRequest();
|
clientConn.write(new TextFrame().setPayload("this shouldn't be seen by server"));
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("harsh-disconnect"));
|
TimeUnit.SECONDS.sleep(10);
|
||||||
|
// clientConn.awaitDisconnect(1, TimeUnit.SECONDS);
|
||||||
client.awaitDisconnect(1, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,20 +95,20 @@ public class WebSocketServerSessionTest
|
||||||
public void testUpgradeRequestResponse() throws Exception
|
public void testUpgradeRequestResponse() throws Exception
|
||||||
{
|
{
|
||||||
URI uri = server.getServerUri().resolve("/test?snack=cashews&amount=handful&brand=off");
|
URI uri = server.getServerUri().resolve("/test?snack=cashews&amount=handful&brand=off");
|
||||||
try (IBlockheadClient client = new BlockheadClient(uri))
|
BlockheadClientRequest request = client.newWsRequest(uri);
|
||||||
{
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
|
{
|
||||||
// Ask the server socket for specific parameter map info
|
// Ask the server socket for specific parameter map info
|
||||||
client.write(new TextFrame().setPayload("getParameterMap|snack"));
|
clientConn.write(new TextFrame().setPayload("getParameterMap|snack"));
|
||||||
client.write(new TextFrame().setPayload("getParameterMap|amount"));
|
clientConn.write(new TextFrame().setPayload("getParameterMap|amount"));
|
||||||
client.write(new TextFrame().setPayload("getParameterMap|brand"));
|
clientConn.write(new TextFrame().setPayload("getParameterMap|brand"));
|
||||||
client.write(new TextFrame().setPayload("getParameterMap|cost")); // intentionally invalid
|
clientConn.write(new TextFrame().setPayload("getParameterMap|cost")); // intentionally invalid
|
||||||
|
|
||||||
// Read frame (hopefully text frame)
|
// Read frame (hopefully text frame)
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Parameter Map[snack]", tf.getPayloadAsUTF8(), is("[cashews]"));
|
Assert.assertThat("Parameter Map[snack]", tf.getPayloadAsUTF8(), is("[cashews]"));
|
||||||
tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
|
|
|
@ -22,13 +22,15 @@ import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
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.Utf8Appendable.NotUtf8Exception;
|
||||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
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.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
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.ContinuationFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.common.test.UnitGenerator;
|
import org.eclipse.jetty.websocket.common.test.UnitGenerator;
|
||||||
import org.eclipse.jetty.websocket.common.util.Hex;
|
import org.eclipse.jetty.websocket.common.util.Hex;
|
||||||
|
@ -50,16 +54,16 @@ import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test various <a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> specified requirements placed on {@link WebSocketServlet}
|
* Test various <a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> specified requirements placed on {@link WebSocketServlet}
|
||||||
*/
|
*/
|
||||||
@RunWith(AdvancedRunner.class)
|
|
||||||
public class WebSocketServletRFCTest
|
public class WebSocketServletRFCTest
|
||||||
{
|
{
|
||||||
|
private static final String REQUEST_HASH_KEY = "dGhlIHNhbXBsZSBub25jZQ==";
|
||||||
private static Generator generator = new UnitGenerator();
|
private static Generator generator = new UnitGenerator();
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
|
private static BlockheadClient client;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void startServer() throws Exception
|
public static void startServer() throws Exception
|
||||||
|
@ -74,16 +78,18 @@ public class WebSocketServletRFCTest
|
||||||
server.stop();
|
server.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@BeforeClass
|
||||||
* @param clazz the class to enable
|
public static void startClient() throws Exception
|
||||||
* @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)
|
|
||||||
{
|
{
|
||||||
StdErrLog log = StdErrLog.getLogger(clazz);
|
client = new BlockheadClient();
|
||||||
log.setHideStacks(!enabled);
|
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
|
@Test
|
||||||
public void testBinaryAggregate() throws Exception
|
public void testBinaryAggregate() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
try
|
|
||||||
{
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
|
{
|
||||||
// Generate binary frames
|
// Generate binary frames
|
||||||
byte buf1[] = new byte[128];
|
byte buf1[] = new byte[128];
|
||||||
byte buf2[] = new byte[128];
|
byte buf2[] = new byte[128];
|
||||||
|
@ -113,18 +118,18 @@ public class WebSocketServletRFCTest
|
||||||
|
|
||||||
bin = new BinaryFrame().setPayload(buf1).setFin(false);
|
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);
|
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);
|
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)
|
// Read frame echo'd back (hopefully a single binary frame)
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
Frame binmsg = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
Frame binmsg = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
int expectedSize = buf1.length + buf2.length + buf3.length;
|
int expectedSize = buf1.length + buf2.length + buf3.length;
|
||||||
Assert.assertThat("BinaryFrame.payloadLength",binmsg.getPayloadLength(),is(expectedSize));
|
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 0xBB",bbCount,is(buf2.length));
|
||||||
Assert.assertThat("Echoed data count for 0xCC",ccCount,is(buf3.length));
|
Assert.assertThat("Echoed data count for 0xCC",ccCount,is(buf3.length));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = NotUtf8Exception.class)
|
@Test(expected = NotUtf8Exception.class)
|
||||||
|
@ -179,26 +180,21 @@ public class WebSocketServletRFCTest
|
||||||
@Test
|
@Test
|
||||||
public void testEcho() throws Exception
|
public void testEcho() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
try
|
|
||||||
{
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
|
{
|
||||||
// Generate text frame
|
// Generate text frame
|
||||||
String msg = "this is an echo ... cho ... ho ... o";
|
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)
|
// Read frame (hopefully text frame)
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
|
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -209,24 +205,21 @@ public class WebSocketServletRFCTest
|
||||||
@Test
|
@Test
|
||||||
public void testInternalError() throws Exception
|
public void testInternalError() throws Exception
|
||||||
{
|
{
|
||||||
try (BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
StacklessLogging stackless=new StacklessLogging(EventDriver.class))
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
|
StacklessLogging ignore = new StacklessLogging(EventDriver.class))
|
||||||
{
|
{
|
||||||
client.connect();
|
// Generate text frame
|
||||||
client.sendStandardRequest();
|
clientConn.write(new TextFrame().setPayload("CRASH"));
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
try (StacklessLogging context = new StacklessLogging(EventDriver.class))
|
// Read frame (hopefully close frame)
|
||||||
{
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
// Generate text frame
|
Frame cf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
client.write(new TextFrame().setPayload("CRASH"));
|
CloseInfo close = new CloseInfo(cf);
|
||||||
|
Assert.assertThat("Close Frame.status code",close.getStatusCode(),is(StatusCode.SERVER_ERROR));
|
||||||
// Read frame (hopefully close frame)
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> 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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,61 +232,50 @@ public class WebSocketServletRFCTest
|
||||||
@Test
|
@Test
|
||||||
public void testLowercaseUpgrade() throws Exception
|
public void testLowercaseUpgrade() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
try
|
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<BlockheadConnection> 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
|
// Generate text frame
|
||||||
String msg = "this is an echo ... cho ... ho ... o";
|
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)
|
// Read frame (hopefully text frame)
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
|
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTextNotUTF8() throws Exception
|
public void testTextNotUTF8() throws Exception
|
||||||
{
|
{
|
||||||
try (StacklessLogging stackless=new StacklessLogging(Parser.class);
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri()))
|
request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "other");
|
||||||
{
|
|
||||||
client.setProtocols("other");
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
|
StacklessLogging ignore = new StacklessLogging(Parser.class))
|
||||||
|
{
|
||||||
byte buf[] = new byte[]
|
byte buf[] = new byte[]
|
||||||
{ (byte)0xC2, (byte)0xC3 };
|
{ (byte)0xC2, (byte)0xC3 };
|
||||||
|
|
||||||
WebSocketFrame txt = new TextFrame().setPayload(ByteBuffer.wrap(buf));
|
WebSocketFrame txt = new TextFrame().setPayload(ByteBuffer.wrap(buf));
|
||||||
txt.setMask(Hex.asByteArray("11223344"));
|
txt.setMask(Hex.asByteArray("11223344"));
|
||||||
ByteBuffer bbHeader = generator.generateHeaderBytes(txt);
|
ByteBuffer bbHeader = generator.generateHeaderBytes(txt);
|
||||||
client.writeRaw(bbHeader);
|
clientConn.writeRaw(bbHeader);
|
||||||
client.writeRaw(txt.getPayload());
|
clientConn.writeRaw(txt.getPayload());
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
Assert.assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||||
CloseInfo close = new CloseInfo(frame);
|
CloseInfo close = new CloseInfo(frame);
|
||||||
|
@ -310,37 +292,26 @@ public class WebSocketServletRFCTest
|
||||||
@Test
|
@Test
|
||||||
public void testUppercaseUpgrade() throws Exception
|
public void testUppercaseUpgrade() throws Exception
|
||||||
{
|
{
|
||||||
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
try
|
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<BlockheadConnection> 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
|
// Generate text frame
|
||||||
String msg = "this is an echo ... cho ... ho ... o";
|
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)
|
// Read frame (hopefully text frame)
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame tf = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
|
Assert.assertThat("Text Frame.status code",tf.getPayloadAsUTF8(),is(msg));
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,9 @@ import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import javax.servlet.DispatcherType;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
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.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@Ignore("Unstable - see Issue #1815")
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class WebSocketUpgradeFilterTest
|
public class WebSocketUpgradeFilterTest
|
||||||
{
|
{
|
||||||
|
@ -56,7 +60,23 @@ public class WebSocketUpgradeFilterTest
|
||||||
{
|
{
|
||||||
Server newServer() throws Exception;
|
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 AtomicInteger uniqTestDirId = new AtomicInteger(0);
|
||||||
|
|
||||||
private static File getNewTestDir()
|
private static File getNewTestDir()
|
||||||
|
@ -305,16 +325,16 @@ public class WebSocketUpgradeFilterTest
|
||||||
public void testNormalConfiguration() throws Exception
|
public void testNormalConfiguration() throws Exception
|
||||||
{
|
{
|
||||||
URI destUri = serverUri.resolve("/info/");
|
URI destUri = serverUri.resolve("/info/");
|
||||||
|
|
||||||
try (BlockheadClient client = new BlockheadClient(destUri))
|
BlockheadClientRequest request = client.newWsRequest(destUri);
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
{
|
{
|
||||||
client.connect();
|
clientConn.write(new TextFrame().setPayload("hello"));
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("hello"));
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
|
||||||
WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
String payload = received.getPayloadAsUTF8();
|
String payload = received.getPayloadAsUTF8();
|
||||||
|
|
||||||
|
@ -328,20 +348,19 @@ public class WebSocketUpgradeFilterTest
|
||||||
public void testStopStartOfHandler() throws Exception
|
public void testStopStartOfHandler() throws Exception
|
||||||
{
|
{
|
||||||
URI destUri = serverUri.resolve("/info/");
|
URI destUri = serverUri.resolve("/info/");
|
||||||
|
|
||||||
try (BlockheadClient client = new BlockheadClient(destUri))
|
BlockheadClientRequest request = client.newWsRequest(destUri);
|
||||||
|
|
||||||
|
Future<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT))
|
||||||
{
|
{
|
||||||
client.connect();
|
clientConn.write(new TextFrame().setPayload("hello 1"));
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("hello 1"));
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
|
||||||
WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
String payload = received.getPayloadAsUTF8();
|
String payload = received.getPayloadAsUTF8();
|
||||||
|
|
||||||
|
|
||||||
// If we can connect and send a text message, we know that the endpoint was
|
// 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
|
// added properly, and the response will help us verify the policy configuration too
|
||||||
assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024)));
|
assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024)));
|
||||||
|
@ -349,20 +368,19 @@ public class WebSocketUpgradeFilterTest
|
||||||
|
|
||||||
server.getHandler().stop();
|
server.getHandler().stop();
|
||||||
server.getHandler().start();
|
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();
|
clientConn.write(new TextFrame().setPayload("hello 2"));
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
client.write(new TextFrame().setPayload("hello 2"));
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
|
||||||
WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame received = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
String payload = received.getPayloadAsUTF8();
|
String payload = received.getPayloadAsUTF8();
|
||||||
|
|
||||||
|
|
||||||
// If we can connect and send a text message, we know that the endpoint was
|
// 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
|
// added properly, and the response will help us verify the policy configuration too
|
||||||
assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024)));
|
assertThat("payload", payload, containsString("session.maxTextMessageSize=" + (10 * 1024 * 1024)));
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
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.frames.PongFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.Fuzzer;
|
import org.eclipse.jetty.websocket.common.test.Fuzzer;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
@RunWith(AdvancedRunner.class)
|
|
||||||
public class TestABCase2 extends AbstractABCase
|
public class TestABCase2 extends AbstractABCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
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.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.Fuzzer;
|
import org.eclipse.jetty.websocket.common.test.Fuzzer;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test various bad / forbidden opcodes (per spec)
|
* Test various bad / forbidden opcodes (per spec)
|
||||||
*/
|
*/
|
||||||
@RunWith(AdvancedRunner.class)
|
|
||||||
public class TestABCase4 extends AbstractABCase
|
public class TestABCase4 extends AbstractABCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,8 +22,6 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.util.log.StacklessLogging;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
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.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.Fuzzer;
|
import org.eclipse.jetty.websocket.common.test.Fuzzer;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragmentation Tests
|
* Fragmentation Tests
|
||||||
*/
|
*/
|
||||||
@RunWith(AdvancedRunner.class)
|
|
||||||
public class TestABCase5 extends AbstractABCase
|
public class TestABCase5 extends AbstractABCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -65,7 +61,7 @@ public class TestABCase5 extends AbstractABCase
|
||||||
fuzzer.send(send);
|
fuzzer.send(send);
|
||||||
fuzzer.expect(expect);
|
fuzzer.expect(expect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send continuation+fin, then text+fin (framewise)
|
* Send continuation+fin, then text+fin (framewise)
|
||||||
|
@ -301,7 +297,6 @@ public class TestABCase5 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Slow
|
|
||||||
public void testCase5_19() throws Exception
|
public void testCase5_19() throws Exception
|
||||||
{
|
{
|
||||||
// phase 1
|
// phase 1
|
||||||
|
|
|
@ -23,8 +23,6 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.BufferUtil;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.TypeUtil;
|
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.test.Fuzzer;
|
||||||
import org.eclipse.jetty.websocket.common.util.Hex;
|
import org.eclipse.jetty.websocket.common.util.Hex;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UTF-8 Tests
|
* UTF-8 Tests
|
||||||
*/
|
*/
|
||||||
@RunWith(AdvancedRunner.class)
|
|
||||||
public class TestABCase6 extends AbstractABCase
|
public class TestABCase6 extends AbstractABCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -276,7 +272,6 @@ public class TestABCase6 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Slow
|
|
||||||
public void testCase6_4_1() throws Exception
|
public void testCase6_4_1() throws Exception
|
||||||
{
|
{
|
||||||
byte part1[] = StringUtil.getUtf8Bytes("\u03BA\u1F79\u03C3\u03BC\u03B5");
|
byte part1[] = StringUtil.getUtf8Bytes("\u03BA\u1F79\u03C3\u03BC\u03B5");
|
||||||
|
@ -312,7 +307,6 @@ public class TestABCase6 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Slow
|
|
||||||
public void testCase6_4_2() throws Exception
|
public void testCase6_4_2() throws Exception
|
||||||
{
|
{
|
||||||
byte part1[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5F4"); // split code point
|
byte part1[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5F4"); // split code point
|
||||||
|
@ -340,7 +334,6 @@ public class TestABCase6 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Slow
|
|
||||||
public void testCase6_4_3() throws Exception
|
public void testCase6_4_3() throws Exception
|
||||||
{
|
{
|
||||||
// Disable Long Stacks from Parser (we know this test will throw an 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
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Slow
|
|
||||||
public void testCase6_4_4() throws Exception
|
public void testCase6_4_4() throws Exception
|
||||||
{
|
{
|
||||||
byte invalid[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5F49080808080656469746564");
|
byte invalid[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5F49080808080656469746564");
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.TestTracker;
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
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.io.AbstractWebSocketConnection;
|
||||||
import org.eclipse.jetty.websocket.common.test.Fuzzer;
|
import org.eclipse.jetty.websocket.common.test.Fuzzer;
|
||||||
import org.eclipse.jetty.websocket.common.util.Hex;
|
import org.eclipse.jetty.websocket.common.util.Hex;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,9 +45,6 @@ import org.junit.Test;
|
||||||
*/
|
*/
|
||||||
public class TestABCase7 extends AbstractABCase
|
public class TestABCase7 extends AbstractABCase
|
||||||
{
|
{
|
||||||
@Rule
|
|
||||||
public TestTracker tt = new TestTracker();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic message then close frame, normal behavior
|
* Basic message then close frame, normal behavior
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
|
|
|
@ -24,8 +24,6 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.util.StringUtil;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
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.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.Fuzzer;
|
import org.eclipse.jetty.websocket.common.test.Fuzzer;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Big frame/message tests
|
* Big frame/message tests
|
||||||
*/
|
*/
|
||||||
@RunWith(AdvancedRunner.class)
|
|
||||||
public class TestABCase9 extends AbstractABCase
|
public class TestABCase9 extends AbstractABCase
|
||||||
{
|
{
|
||||||
private static final int KBYTE = 1024;
|
private static final int KBYTE = 1024;
|
||||||
|
@ -246,7 +242,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_1_5() throws Exception
|
public void testCase9_1_5() throws Exception
|
||||||
{
|
{
|
||||||
byte utf[] = new byte[8 * MBYTE];
|
byte utf[] = new byte[8 * MBYTE];
|
||||||
|
@ -275,7 +270,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_1_6() throws Exception
|
public void testCase9_1_6() throws Exception
|
||||||
{
|
{
|
||||||
byte utf[] = new byte[16 * MBYTE];
|
byte utf[] = new byte[16 * MBYTE];
|
||||||
|
@ -359,7 +353,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_2_3() throws Exception
|
public void testCase9_2_3() throws Exception
|
||||||
{
|
{
|
||||||
byte data[] = new byte[1 * MBYTE];
|
byte data[] = new byte[1 * MBYTE];
|
||||||
|
@ -388,7 +381,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_2_4() throws Exception
|
public void testCase9_2_4() throws Exception
|
||||||
{
|
{
|
||||||
byte data[] = new byte[4 * MBYTE];
|
byte data[] = new byte[4 * MBYTE];
|
||||||
|
@ -417,7 +409,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_2_5() throws Exception
|
public void testCase9_2_5() throws Exception
|
||||||
{
|
{
|
||||||
byte data[] = new byte[8 * MBYTE];
|
byte data[] = new byte[8 * MBYTE];
|
||||||
|
@ -446,7 +437,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_2_6() throws Exception
|
public void testCase9_2_6() throws Exception
|
||||||
{
|
{
|
||||||
byte data[] = new byte[16 * MBYTE];
|
byte data[] = new byte[16 * MBYTE];
|
||||||
|
@ -475,7 +465,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_3_1() throws Exception
|
public void testCase9_3_1() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,64);
|
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,64);
|
||||||
|
@ -486,7 +475,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_3_2() throws Exception
|
public void testCase9_3_2() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,256);
|
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,256);
|
||||||
|
@ -497,7 +485,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_3_3() throws Exception
|
public void testCase9_3_3() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,1 * KBYTE);
|
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,1 * KBYTE);
|
||||||
|
@ -508,7 +495,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_3_4() throws Exception
|
public void testCase9_3_4() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,4 * KBYTE);
|
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,4 * KBYTE);
|
||||||
|
@ -519,7 +505,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_3_5() throws Exception
|
public void testCase9_3_5() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,16 * KBYTE);
|
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,16 * KBYTE);
|
||||||
|
@ -530,7 +515,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_3_6() throws Exception
|
public void testCase9_3_6() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,64 * KBYTE);
|
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,64 * KBYTE);
|
||||||
|
@ -541,7 +525,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_3_7() throws Exception
|
public void testCase9_3_7() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,256 * KBYTE);
|
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,256 * KBYTE);
|
||||||
|
@ -552,7 +535,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_3_8() throws Exception
|
public void testCase9_3_8() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,1 * MBYTE);
|
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,1 * MBYTE);
|
||||||
|
@ -563,7 +545,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_3_9() throws Exception
|
public void testCase9_3_9() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,4 * MBYTE);
|
assertMultiFrameEcho(OpCode.TEXT,4 * MBYTE,4 * MBYTE);
|
||||||
|
@ -574,7 +555,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_4_1() throws Exception
|
public void testCase9_4_1() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,64);
|
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,64);
|
||||||
|
@ -585,7 +565,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_4_2() throws Exception
|
public void testCase9_4_2() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,256);
|
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,256);
|
||||||
|
@ -596,7 +575,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_4_3() throws Exception
|
public void testCase9_4_3() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,1 * KBYTE);
|
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,1 * KBYTE);
|
||||||
|
@ -607,7 +585,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_4_4() throws Exception
|
public void testCase9_4_4() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,4 * KBYTE);
|
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,4 * KBYTE);
|
||||||
|
@ -618,7 +595,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_4_5() throws Exception
|
public void testCase9_4_5() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,16 * KBYTE);
|
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,16 * KBYTE);
|
||||||
|
@ -629,7 +605,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_4_6() throws Exception
|
public void testCase9_4_6() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,64 * KBYTE);
|
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,64 * KBYTE);
|
||||||
|
@ -640,7 +615,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_4_7() throws Exception
|
public void testCase9_4_7() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,256 * KBYTE);
|
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,256 * KBYTE);
|
||||||
|
@ -651,7 +625,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_4_8() throws Exception
|
public void testCase9_4_8() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,1 * MBYTE);
|
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,1 * MBYTE);
|
||||||
|
@ -662,7 +635,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_4_9() throws Exception
|
public void testCase9_4_9() throws Exception
|
||||||
{
|
{
|
||||||
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,4 * MBYTE);
|
assertMultiFrameEcho(OpCode.BINARY,4 * MBYTE,4 * MBYTE);
|
||||||
|
@ -673,7 +645,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_5_1() throws Exception
|
public void testCase9_5_1() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,64);
|
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,64);
|
||||||
|
@ -684,7 +655,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_5_2() throws Exception
|
public void testCase9_5_2() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,128);
|
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,128);
|
||||||
|
@ -695,7 +665,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_5_3() throws Exception
|
public void testCase9_5_3() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,256);
|
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,256);
|
||||||
|
@ -706,7 +675,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_5_4() throws Exception
|
public void testCase9_5_4() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,512);
|
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,512);
|
||||||
|
@ -717,7 +685,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_5_5() throws Exception
|
public void testCase9_5_5() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,1024);
|
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,1024);
|
||||||
|
@ -728,7 +695,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_5_6() throws Exception
|
public void testCase9_5_6() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,2048);
|
assertSlowFrameEcho(OpCode.TEXT,1 * MBYTE,2048);
|
||||||
|
@ -739,7 +705,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_6_1() throws Exception
|
public void testCase9_6_1() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,64);
|
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,64);
|
||||||
|
@ -750,7 +715,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_6_2() throws Exception
|
public void testCase9_6_2() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,128);
|
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,128);
|
||||||
|
@ -761,7 +725,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_6_3() throws Exception
|
public void testCase9_6_3() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,256);
|
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,256);
|
||||||
|
@ -772,7 +735,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_6_4() throws Exception
|
public void testCase9_6_4() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,512);
|
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,512);
|
||||||
|
@ -783,7 +745,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_6_5() throws Exception
|
public void testCase9_6_5() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,1024);
|
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,1024);
|
||||||
|
@ -794,7 +755,6 @@ public class TestABCase9 extends AbstractABCase
|
||||||
* @throws Exception on test failure
|
* @throws Exception on test failure
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Stress("High I/O use")
|
|
||||||
public void testCase9_6_6() throws Exception
|
public void testCase9_6_6() throws Exception
|
||||||
{
|
{
|
||||||
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,2048);
|
assertSlowFrameEcho(OpCode.BINARY,1 * MBYTE,2048);
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.websocket.server.examples;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.RuntimeIOException;
|
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.RemoteEndpoint;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||||
|
|
||||||
|
@ -43,8 +42,6 @@ public class MyEchoSocket extends WebSocketAdapter
|
||||||
// echo the data back
|
// echo the data back
|
||||||
RemoteEndpoint remote = getRemote();
|
RemoteEndpoint remote = getRemote();
|
||||||
remote.sendString(message);
|
remote.sendString(message);
|
||||||
if (remote.getBatchMode() == BatchMode.ON)
|
|
||||||
remote.flush();
|
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,9 +22,11 @@ import static org.hamcrest.Matchers.instanceOf;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.common.CloseInfo;
|
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.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
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.common.test.Timeouts;
|
||||||
import org.eclipse.jetty.websocket.server.SimpleServletServer;
|
import org.eclipse.jetty.websocket.server.SimpleServletServer;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -47,6 +50,7 @@ public class MisbehavingClassTest
|
||||||
{
|
{
|
||||||
private static SimpleServletServer server;
|
private static SimpleServletServer server;
|
||||||
private static BadSocketsServlet badSocketsServlet;
|
private static BadSocketsServlet badSocketsServlet;
|
||||||
|
private static BlockheadClient client;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void startServer() throws Exception
|
public static void startServer() throws Exception
|
||||||
|
@ -62,29 +66,42 @@ public class MisbehavingClassTest
|
||||||
server.stop();
|
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
|
@Test
|
||||||
public void testListenerRuntimeOnConnect() throws Exception
|
public void testListenerRuntimeOnConnect() throws Exception
|
||||||
{
|
{
|
||||||
try (IBlockheadClient client = new BlockheadClient(server.getServerUri());
|
BlockheadClientRequest request = client.newWsRequest(server.getServerUri());
|
||||||
StacklessLogging scope = new StacklessLogging(ListenerRuntimeOnConnectSocket.class, WebSocketSession.class))
|
request.header(HttpHeader.SEC_WEBSOCKET_SUBPROTOCOL, "listener-runtime-connect");
|
||||||
|
request.idleTimeout(1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
ListenerRuntimeOnConnectSocket socket = badSocketsServlet.listenerRuntimeConnect;
|
||||||
|
socket.reset();
|
||||||
|
|
||||||
|
Future<BlockheadConnection> 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");
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
ListenerRuntimeOnConnectSocket socket = badSocketsServlet.listenerRuntimeConnect;
|
|
||||||
socket.reset();
|
|
||||||
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||||
CloseInfo close = new CloseInfo(frame);
|
CloseInfo close = new CloseInfo(frame);
|
||||||
assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR));
|
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
|
// ensure server socket got close event
|
||||||
assertThat("Close Latch",socket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
assertThat("Close Latch",socket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
||||||
|
@ -100,26 +117,25 @@ public class MisbehavingClassTest
|
||||||
@Test
|
@Test
|
||||||
public void testAnnotatedRuntimeOnConnect() throws Exception
|
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<BlockheadConnection> connFut = request.sendAsync();
|
||||||
|
|
||||||
|
try (BlockheadConnection clientConn = connFut.get(Timeouts.CONNECT, Timeouts.CONNECT_UNIT);
|
||||||
StacklessLogging scope = new StacklessLogging(AnnotatedRuntimeOnConnectSocket.class, WebSocketSession.class))
|
StacklessLogging scope = new StacklessLogging(AnnotatedRuntimeOnConnectSocket.class, WebSocketSession.class))
|
||||||
{
|
{
|
||||||
client.setProtocols("annotated-runtime-connect");
|
LinkedBlockingQueue<WebSocketFrame> frames = clientConn.getFrameQueue();
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
AnnotatedRuntimeOnConnectSocket socket = badSocketsServlet.annotatedRuntimeConnect;
|
|
||||||
socket.reset();
|
|
||||||
|
|
||||||
client.connect();
|
|
||||||
client.sendStandardRequest();
|
|
||||||
client.expectUpgradeResponse();
|
|
||||||
|
|
||||||
LinkedBlockingQueue<WebSocketFrame> frames = client.getFrameQueue();
|
|
||||||
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
WebSocketFrame frame = frames.poll(Timeouts.POLL_EVENT, Timeouts.POLL_EVENT_UNIT);
|
||||||
assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
assertThat("frames[0].opcode",frame.getOpCode(),is(OpCode.CLOSE));
|
||||||
CloseInfo close = new CloseInfo(frame);
|
CloseInfo close = new CloseInfo(frame);
|
||||||
assertThat("Close Status Code",close.getStatusCode(),is(StatusCode.SERVER_ERROR));
|
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
|
// ensure server socket got close event
|
||||||
assertThat("Close Latch",socket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
assertThat("Close Latch",socket.closeLatch.await(1,TimeUnit.SECONDS),is(true));
|
||||||
|
|
Loading…
Reference in New Issue