Moving more tests cases over
This commit is contained in:
parent
5d9eab45b4
commit
7a35ea9c75
|
@ -0,0 +1,15 @@
|
||||||
|
package org.eclipse.jetty.websocket.protocol;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class AcceptHashTest
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
public void testHash()
|
||||||
|
{
|
||||||
|
Assert.assertThat(AcceptHash.hashKey("dGhlIHNhbXBsZSBub25jZQ=="),is("s3pPLMBiTxaQ9kYGzzhZRbK+xOo="));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.websocket.protocol.FrameBuilder;
|
||||||
|
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||||
|
import org.eclipse.jetty.websocket.server.WebSocketServletRFCTest.RFCServlet;
|
||||||
|
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class DeflateExtensionTest
|
||||||
|
{
|
||||||
|
private static SimpleServletServer server;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void startServer() throws Exception
|
||||||
|
{
|
||||||
|
server = new SimpleServletServer(new RFCServlet());
|
||||||
|
server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void stopServer()
|
||||||
|
{
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeflateFrameExtension() throws Exception
|
||||||
|
{
|
||||||
|
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||||
|
client.clearExtensions();
|
||||||
|
client.addExtensions("x-deflate-frame;minLength=64");
|
||||||
|
// client.addExtensions("fragment;minFragments=2");
|
||||||
|
client.setProtocols("echo");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Make sure the read times out if there are problems with the implementation
|
||||||
|
client.setTimeout(TimeUnit.SECONDS,1);
|
||||||
|
client.connect();
|
||||||
|
client.sendStandardRequest();
|
||||||
|
String resp = client.expectUpgradeResponse();
|
||||||
|
|
||||||
|
Assert.assertThat("Response",resp,containsString("x-deflate"));
|
||||||
|
|
||||||
|
// Server sends a big message
|
||||||
|
String text = "0123456789ABCDEF ";
|
||||||
|
text = text + text + text + text;
|
||||||
|
text = text + text + text + text;
|
||||||
|
text = text + text + text + text + 'X';
|
||||||
|
|
||||||
|
client.write(FrameBuilder.text(text).asFrame());
|
||||||
|
|
||||||
|
// TODO: use socket that captures frame payloads to verify fragmentation
|
||||||
|
|
||||||
|
Queue<WebSocketFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,1000);
|
||||||
|
WebSocketFrame frame = frames.remove();
|
||||||
|
Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is(text));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.websocket.protocol.FrameBuilder;
|
||||||
|
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||||
|
import org.eclipse.jetty.websocket.server.WebSocketServletRFCTest.RFCServlet;
|
||||||
|
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class FragmentExtensionTest
|
||||||
|
{
|
||||||
|
private static SimpleServletServer server;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void startServer() throws Exception
|
||||||
|
{
|
||||||
|
server = new SimpleServletServer(new RFCServlet());
|
||||||
|
server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void stopServer()
|
||||||
|
{
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFragmentExtension() throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||||
|
client.clearExtensions();
|
||||||
|
client.addExtensions("fragment;maxLength=4;minFragments=7");
|
||||||
|
client.setProtocols("onConnect");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Make sure the read times out if there are problems with the implementation
|
||||||
|
client.setTimeout(TimeUnit.SECONDS,1);
|
||||||
|
client.connect();
|
||||||
|
client.sendStandardRequest();
|
||||||
|
String resp = client.expectUpgradeResponse();
|
||||||
|
|
||||||
|
Assert.assertThat("Response",resp,containsString("fragment"));
|
||||||
|
|
||||||
|
String msg = "Sent as a long message that should be split";
|
||||||
|
client.write(FrameBuilder.text(msg).asFrame());
|
||||||
|
|
||||||
|
// TODO: use socket that captures frame counts to verify fragmentation
|
||||||
|
|
||||||
|
Queue<WebSocketFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,1000);
|
||||||
|
WebSocketFrame frame = frames.remove();
|
||||||
|
Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is(msg));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.websocket.protocol.FrameBuilder;
|
||||||
|
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||||
|
import org.eclipse.jetty.websocket.server.WebSocketServletRFCTest.RFCServlet;
|
||||||
|
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class IdentityExtensionTest
|
||||||
|
{
|
||||||
|
private static SimpleServletServer server;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void startServer() throws Exception
|
||||||
|
{
|
||||||
|
server = new SimpleServletServer(new RFCServlet());
|
||||||
|
server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void stopServer()
|
||||||
|
{
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIdentityExtension() throws Exception
|
||||||
|
{
|
||||||
|
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||||
|
client.clearExtensions();
|
||||||
|
client.addExtensions("identity;param=0");
|
||||||
|
client.addExtensions("identity;param=1, identity ; param = '2' ; other = ' some = value '");
|
||||||
|
client.setProtocols("onConnect");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Make sure the read times out if there are problems with the implementation
|
||||||
|
client.setTimeout(TimeUnit.SECONDS,1);
|
||||||
|
client.connect();
|
||||||
|
client.sendStandardRequest();
|
||||||
|
String resp = client.expectUpgradeResponse();
|
||||||
|
|
||||||
|
Assert.assertThat("Response",resp,containsString("identity"));
|
||||||
|
|
||||||
|
client.write(FrameBuilder.text("Hello").asFrame());
|
||||||
|
|
||||||
|
Queue<WebSocketFrame> frames = client.readFrames(1,TimeUnit.MILLISECONDS,1000);
|
||||||
|
WebSocketFrame frame = frames.remove();
|
||||||
|
Assert.assertThat("TEXT.payload",frame.getPayloadAsUTF8(),is("Hello"));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,9 +27,6 @@ import java.net.SocketException;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
import java.util.zip.Deflater;
|
|
||||||
import java.util.zip.Inflater;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.server.SelectChannelConnector;
|
import org.eclipse.jetty.server.SelectChannelConnector;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
@ -37,7 +34,6 @@ import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
import org.eclipse.jetty.util.FutureCallback;
|
import org.eclipse.jetty.util.FutureCallback;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.TypeUtil;
|
|
||||||
import org.eclipse.jetty.util.Utf8StringBuilder;
|
import org.eclipse.jetty.util.Utf8StringBuilder;
|
||||||
import org.eclipse.jetty.websocket.annotations.OnWebSocketClose;
|
import org.eclipse.jetty.websocket.annotations.OnWebSocketClose;
|
||||||
import org.eclipse.jetty.websocket.annotations.OnWebSocketConnect;
|
import org.eclipse.jetty.websocket.annotations.OnWebSocketConnect;
|
||||||
|
@ -45,7 +41,6 @@ import org.eclipse.jetty.websocket.annotations.OnWebSocketMessage;
|
||||||
import org.eclipse.jetty.websocket.annotations.WebSocket;
|
import org.eclipse.jetty.websocket.annotations.WebSocket;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketConnection;
|
import org.eclipse.jetty.websocket.api.WebSocketConnection;
|
||||||
import org.eclipse.jetty.websocket.protocol.AcceptHash;
|
|
||||||
import org.eclipse.jetty.websocket.protocol.OpCode;
|
import org.eclipse.jetty.websocket.protocol.OpCode;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
@ -263,699 +258,6 @@ public class WebSocketMessageRFC6455Test
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBinaryAggregate() throws Exception
|
|
||||||
{
|
|
||||||
Socket socket = new Socket("localhost",__connector.getLocalPort());
|
|
||||||
OutputStream output = socket.getOutputStream();
|
|
||||||
output.write(("GET /chat HTTP/1.1\r\n" + "Host: server.example.com\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n"
|
|
||||||
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Origin: http://example.com\r\n" + "Sec-WebSocket-Protocol: aggregate\r\n"
|
|
||||||
+ "Sec-WebSocket-Version: " + WSVERSION + "\r\n" + "\r\n").getBytes("ISO-8859-1"));
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
socket.setSoTimeout(1000);
|
|
||||||
InputStream input = socket.getInputStream();
|
|
||||||
|
|
||||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
|
||||||
skipTo("Sec-WebSocket-Accept: ",input);
|
|
||||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
|
||||||
skipTo("\r\n\r\n",input);
|
|
||||||
|
|
||||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
|
||||||
assertNotNull(__serverWebSocket.connection);
|
|
||||||
|
|
||||||
output.write(OpCode.BINARY.getCode());
|
|
||||||
output.write(0x8a);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
byte[] bytes = "0123456789".getBytes(StringUtil.__ISO_8859_1);
|
|
||||||
for (byte b : bytes)
|
|
||||||
{
|
|
||||||
output.write(b ^ 0xff);
|
|
||||||
}
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
output.write(0x80);
|
|
||||||
output.write(0x8a);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
for (byte b : bytes)
|
|
||||||
{
|
|
||||||
output.write(b ^ 0xff);
|
|
||||||
}
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
assertEquals(0x80 + OpCode.BINARY.getCode(),input.read());
|
|
||||||
assertEquals(20,input.read());
|
|
||||||
lookFor("01234567890123456789",input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBlockedConsumer() throws Exception
|
|
||||||
{
|
|
||||||
Socket socket = new Socket("localhost",__connector.getLocalPort());
|
|
||||||
OutputStream output = socket.getOutputStream();
|
|
||||||
|
|
||||||
byte[] bytes = "This is a long message of text that we will send again and again".getBytes(StringUtil.__ISO_8859_1);
|
|
||||||
byte[] mesg = new byte[bytes.length + 6];
|
|
||||||
mesg[0] = (byte)(0x80 + OpCode.TEXT.getCode());
|
|
||||||
mesg[1] = (byte)(0x80 + bytes.length);
|
|
||||||
mesg[2] = (byte)0xff;
|
|
||||||
mesg[3] = (byte)0xff;
|
|
||||||
mesg[4] = (byte)0xff;
|
|
||||||
mesg[5] = (byte)0xff;
|
|
||||||
for (int i = 0; i < bytes.length; i++)
|
|
||||||
{
|
|
||||||
mesg[6 + i] = (byte)(bytes[i] ^ 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int count = 100000;
|
|
||||||
|
|
||||||
output.write(("GET /chat HTTP/1.1\r\n" + "Host: server.example.com\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n"
|
|
||||||
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Origin: http://example.com\r\n" + "Sec-WebSocket-Protocol: latch\r\n"
|
|
||||||
+ "Sec-WebSocket-Version: " + WSVERSION + "\r\n" + "\r\n").getBytes("ISO-8859-1"));
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Make sure the read times out if there are problems with the implementation
|
|
||||||
socket.setSoTimeout(60000);
|
|
||||||
|
|
||||||
InputStream input = socket.getInputStream();
|
|
||||||
|
|
||||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
|
||||||
skipTo("Sec-WebSocket-Accept: ",input);
|
|
||||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
|
||||||
skipTo("\r\n\r\n",input);
|
|
||||||
|
|
||||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
|
||||||
assertNotNull(__serverWebSocket.connection);
|
|
||||||
|
|
||||||
// Send and receive 1 message
|
|
||||||
output.write(mesg);
|
|
||||||
output.flush();
|
|
||||||
while (__textCount.get() == 0)
|
|
||||||
{
|
|
||||||
Thread.sleep(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
// unblock the latch in 4s
|
|
||||||
new Thread()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Thread.sleep(4000);
|
|
||||||
__latch.countDown();
|
|
||||||
// System.err.println("latched");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start();
|
|
||||||
|
|
||||||
// Send enough messages to fill receive buffer
|
|
||||||
long max = 0;
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
output.write(mesg);
|
|
||||||
if ((i % 100) == 0)
|
|
||||||
{
|
|
||||||
// System.err.println(">>> "+i);
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
long duration = now - start;
|
|
||||||
start = now;
|
|
||||||
if (max < duration)
|
|
||||||
{
|
|
||||||
max = duration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread.sleep(50);
|
|
||||||
while (__textCount.get() < (count + 1))
|
|
||||||
{
|
|
||||||
System.err.println(__textCount.get() + "<" + (count + 1));
|
|
||||||
Thread.sleep(10);
|
|
||||||
}
|
|
||||||
assertEquals(count + 1,__textCount.get()); // all messages
|
|
||||||
assertTrue(max > 2000); // was blocked
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBlockedProducer() throws Exception
|
|
||||||
{
|
|
||||||
final Socket socket = new Socket("localhost",__connector.getLocalPort());
|
|
||||||
OutputStream output = socket.getOutputStream();
|
|
||||||
|
|
||||||
final int count = 100000;
|
|
||||||
|
|
||||||
output.write(("GET /chat HTTP/1.1\r\n" + "Host: server.example.com\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n"
|
|
||||||
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Origin: http://example.com\r\n" + "Sec-WebSocket-Protocol: latch\r\n"
|
|
||||||
+ "Sec-WebSocket-Version: " + WSVERSION + "\r\n" + "\r\n").getBytes("ISO-8859-1"));
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Make sure the read times out if there are problems with the implementation
|
|
||||||
socket.setSoTimeout(60000);
|
|
||||||
|
|
||||||
InputStream input = socket.getInputStream();
|
|
||||||
|
|
||||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
|
||||||
skipTo("Sec-WebSocket-Accept: ",input);
|
|
||||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
|
||||||
skipTo("\r\n\r\n",input);
|
|
||||||
|
|
||||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
|
||||||
assertNotNull(__serverWebSocket.connection);
|
|
||||||
__latch.countDown();
|
|
||||||
|
|
||||||
// wait 2s and then consume messages
|
|
||||||
final AtomicLong totalB = new AtomicLong();
|
|
||||||
new Thread()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Thread.sleep(2000);
|
|
||||||
|
|
||||||
byte[] recv = new byte[32 * 1024];
|
|
||||||
|
|
||||||
int len = 0;
|
|
||||||
while (len >= 0)
|
|
||||||
{
|
|
||||||
totalB.addAndGet(len);
|
|
||||||
len = socket.getInputStream().read(recv,0,recv.length);
|
|
||||||
Thread.sleep(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start();
|
|
||||||
|
|
||||||
// Send enough messages to fill receive buffer
|
|
||||||
long max = 0;
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
String mesg = "How Now Brown Cow";
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
__serverWebSocket.connection.write(null,fnf(),mesg);
|
|
||||||
if ((i % 100) == 0)
|
|
||||||
{
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
long duration = now - start;
|
|
||||||
start = now;
|
|
||||||
if (max < duration)
|
|
||||||
{
|
|
||||||
max = duration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (totalB.get() < (count * (mesg.length() + 2)))
|
|
||||||
{
|
|
||||||
Thread.sleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
assertEquals(count * (mesg.length() + 2),totalB.get()); // all messages
|
|
||||||
Assert.assertThat("Was blocked (max time)",max,greaterThan(1000L)); // was blocked
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCloseIn() throws Exception
|
|
||||||
{
|
|
||||||
int[][] tests =
|
|
||||||
{
|
|
||||||
{ -1, 0, -1 },
|
|
||||||
{ -1, 0, -1 },
|
|
||||||
{ 1000, 2, 1000 },
|
|
||||||
{ 1000, 2 + 4, 1000 },
|
|
||||||
{ 1005, 2 + 23, 1002 },
|
|
||||||
{ 1005, 2 + 23, 1002 },
|
|
||||||
{ 1006, 2 + 23, 1002 },
|
|
||||||
{ 1006, 2 + 23, 1002 },
|
|
||||||
{ 4000, 2, 4000 },
|
|
||||||
{ 4000, 2 + 4, 4000 },
|
|
||||||
{ 9000, 2 + 23, 1002 },
|
|
||||||
{ 9000, 2 + 23, 1002 } };
|
|
||||||
|
|
||||||
String[] mesg =
|
|
||||||
{ "", "", "", "mesg", "", "mesg", "", "mesg", "", "mesg", "", "mesg" };
|
|
||||||
|
|
||||||
String[] resp =
|
|
||||||
{ "", "", "", "mesg", "Invalid close code 1005", "Invalid close code 1005", "Invalid close code 1006", "Invalid close code 1006", "", "mesg",
|
|
||||||
"Invalid close code 9000", "Invalid close code 9000" };
|
|
||||||
|
|
||||||
for (int t = 0; t < tests.length; t++)
|
|
||||||
{
|
|
||||||
String tst = "" + t;
|
|
||||||
Socket socket = new Socket("localhost",__connector.getLocalPort());
|
|
||||||
OutputStream output = socket.getOutputStream();
|
|
||||||
output.write(("GET /chat HTTP/1.1\r\n" + "Host: server.example.com\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n"
|
|
||||||
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Origin: http://example.com\r\n" + "Sec-WebSocket-Protocol: chat\r\n"
|
|
||||||
+ "Sec-WebSocket-Version: " + WSVERSION + "\r\n" + "\r\n").getBytes("ISO-8859-1"));
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
socket.setSoTimeout(100000);
|
|
||||||
InputStream input = socket.getInputStream();
|
|
||||||
|
|
||||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
|
||||||
skipTo("Sec-WebSocket-Accept: ",input);
|
|
||||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
|
||||||
skipTo("\r\n\r\n",input);
|
|
||||||
|
|
||||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
|
||||||
assertNotNull(__serverWebSocket.connection);
|
|
||||||
|
|
||||||
int code = tests[t][0];
|
|
||||||
String m = mesg[t];
|
|
||||||
|
|
||||||
output.write(0x88);
|
|
||||||
output.write(0x80 + (code <= 0?0:(2 + m.length())));
|
|
||||||
output.write(0x00);
|
|
||||||
output.write(0x00);
|
|
||||||
output.write(0x00);
|
|
||||||
output.write(0x00);
|
|
||||||
|
|
||||||
if (code > 0)
|
|
||||||
{
|
|
||||||
output.write(code / 0x100);
|
|
||||||
output.write(code % 0x100);
|
|
||||||
output.write(m.getBytes());
|
|
||||||
}
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
__serverWebSocket.awaitDisconnected(1000);
|
|
||||||
|
|
||||||
byte[] buf = new byte[128];
|
|
||||||
int len = input.read(buf);
|
|
||||||
|
|
||||||
assertEquals(tst,2 + tests[t][1],len);
|
|
||||||
assertEquals(tst,(byte)0x88,buf[0]);
|
|
||||||
|
|
||||||
if (len >= 4)
|
|
||||||
{
|
|
||||||
code = ((0xff & buf[2]) * 0x100) + (0xff & buf[3]);
|
|
||||||
assertEquals(tst,tests[t][2],code);
|
|
||||||
|
|
||||||
if (len > 4)
|
|
||||||
{
|
|
||||||
m = new String(buf,4,len - 4,"UTF-8");
|
|
||||||
assertEquals(tst,resp[t],m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assertEquals(tst,tests[t][2],-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = input.read(buf);
|
|
||||||
assertEquals(tst,-1,len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCloseOut() throws Exception
|
|
||||||
{
|
|
||||||
int[][] tests =
|
|
||||||
{
|
|
||||||
{ -1, 0, -1 },
|
|
||||||
{ -1, 0, -1 },
|
|
||||||
{ 0, 2, 1000 },
|
|
||||||
{ 0, 2 + 4, 1000 },
|
|
||||||
{ 1000, 2, 1000 },
|
|
||||||
{ 1000, 2 + 4, 1000 },
|
|
||||||
{ 1005, 0, -1 },
|
|
||||||
{ 1005, 0, -1 },
|
|
||||||
{ 1006, 0, -1 },
|
|
||||||
{ 1006, 0, -1 },
|
|
||||||
{ 9000, 2, 9000 },
|
|
||||||
{ 9000, 2 + 4, 9000 } };
|
|
||||||
|
|
||||||
String[] mesg =
|
|
||||||
{ null, "Not Sent", null, "mesg", null, "mesg", null, "mesg", null, "mesg", null, "mesg" };
|
|
||||||
|
|
||||||
for (int t = 0; t < tests.length; t++)
|
|
||||||
{
|
|
||||||
String tst = "" + t;
|
|
||||||
Socket socket = new Socket("localhost",__connector.getLocalPort());
|
|
||||||
OutputStream output = socket.getOutputStream();
|
|
||||||
output.write(("GET /chat HTTP/1.1\r\n" + "Host: server.example.com\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n"
|
|
||||||
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Origin: http://example.com\r\n" + "Sec-WebSocket-Protocol: chat\r\n"
|
|
||||||
+ "Sec-WebSocket-Version: " + WSVERSION + "\r\n" + "\r\n").getBytes("ISO-8859-1"));
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
socket.setSoTimeout(100000);
|
|
||||||
InputStream input = socket.getInputStream();
|
|
||||||
|
|
||||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
|
||||||
skipTo("Sec-WebSocket-Accept: ",input);
|
|
||||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
|
||||||
skipTo("\r\n\r\n",input);
|
|
||||||
|
|
||||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
|
||||||
assertNotNull(__serverWebSocket.connection);
|
|
||||||
|
|
||||||
__serverWebSocket.connection.close(tests[t][0],mesg[t]);
|
|
||||||
|
|
||||||
byte[] buf = new byte[128];
|
|
||||||
int len = input.read(buf);
|
|
||||||
assertEquals(tst,2 + tests[t][1],len);
|
|
||||||
assertEquals(tst,(byte)0x88,buf[0]);
|
|
||||||
|
|
||||||
if (len >= 4)
|
|
||||||
{
|
|
||||||
int code = ((0xff & buf[2]) * 0x100) + (0xff & buf[3]);
|
|
||||||
assertEquals(tst,tests[t][2],code);
|
|
||||||
|
|
||||||
if (len > 4)
|
|
||||||
{
|
|
||||||
String m = new String(buf,4,len - 4,"UTF-8");
|
|
||||||
assertEquals(tst,mesg[t],m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assertEquals(tst,tests[t][2],-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
output.write(0x88);
|
|
||||||
output.write(0x80);
|
|
||||||
output.write(0x00);
|
|
||||||
output.write(0x00);
|
|
||||||
output.write(0x00);
|
|
||||||
output.write(0x00);
|
|
||||||
output.flush();
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
System.err.println("socket " + socket);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = input.read(buf);
|
|
||||||
assertEquals(tst,-1,len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeflateFrameExtension() throws Exception
|
|
||||||
{
|
|
||||||
Socket socket = new Socket("localhost",__connector.getLocalPort());
|
|
||||||
OutputStream output = socket.getOutputStream();
|
|
||||||
output.write(("GET /chat HTTP/1.1\r\n" + "Host: server.example.com\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n"
|
|
||||||
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Origin: http://example.com\r\n" + "Sec-WebSocket-Protocol: echo\r\n"
|
|
||||||
+ "Sec-WebSocket-Version: " + WSVERSION + "\r\n" + "Sec-WebSocket-Extensions: x-deflate-frame;minLength=64\r\n"
|
|
||||||
+ "Sec-WebSocket-Extensions: fragment;minFragments=2\r\n" + "\r\n").getBytes("ISO-8859-1"));
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Make sure the read times out if there are problems with the implementation
|
|
||||||
socket.setSoTimeout(1000);
|
|
||||||
|
|
||||||
InputStream input = socket.getInputStream();
|
|
||||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
|
||||||
skipTo("Sec-WebSocket-Accept: ",input);
|
|
||||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
|
||||||
skipTo("Sec-WebSocket-Extensions: ",input);
|
|
||||||
lookFor("x-deflate-frame;minLength=64",input);
|
|
||||||
skipTo("Sec-WebSocket-Extensions: ",input);
|
|
||||||
lookFor("fragment;",input);
|
|
||||||
skipTo("\r\n\r\n",input);
|
|
||||||
|
|
||||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
|
||||||
assertNotNull(__serverWebSocket.connection);
|
|
||||||
|
|
||||||
// Server sends a big message
|
|
||||||
String text = "0123456789ABCDEF ";
|
|
||||||
text = text + text + text + text;
|
|
||||||
text = text + text + text + text;
|
|
||||||
text = text + text + text + text + 'X';
|
|
||||||
byte[] data = text.getBytes("utf-8");
|
|
||||||
Deflater deflater = new Deflater();
|
|
||||||
deflater.setInput(data);
|
|
||||||
deflater.finish();
|
|
||||||
byte[] buf = new byte[data.length];
|
|
||||||
|
|
||||||
buf[0] = ((byte)0x7e);
|
|
||||||
buf[1] = (byte)(data.length >> 8);
|
|
||||||
buf[2] = (byte)(data.length & 0xff);
|
|
||||||
|
|
||||||
int l = deflater.deflate(buf,3,buf.length - 3);
|
|
||||||
|
|
||||||
assertTrue(deflater.finished());
|
|
||||||
|
|
||||||
output.write(0xC1);
|
|
||||||
output.write((byte)(0x80 | (0xff & (l + 3))));
|
|
||||||
output.write(0x00);
|
|
||||||
output.write(0x00);
|
|
||||||
output.write(0x00);
|
|
||||||
output.write(0x00);
|
|
||||||
output.write(buf,0,l + 3);
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
assertEquals(0x40 + OpCode.TEXT.getCode(),input.read());
|
|
||||||
assertEquals(0x20 + 3,input.read());
|
|
||||||
assertEquals(0x7e,input.read());
|
|
||||||
assertEquals(0x02,input.read());
|
|
||||||
assertEquals(0x20,input.read());
|
|
||||||
|
|
||||||
byte[] raw = new byte[32];
|
|
||||||
assertEquals(32,input.read(raw));
|
|
||||||
|
|
||||||
Inflater inflater = new Inflater();
|
|
||||||
inflater.setInput(raw);
|
|
||||||
|
|
||||||
byte[] result = new byte[544];
|
|
||||||
assertEquals(544,inflater.inflate(result));
|
|
||||||
assertEquals(TypeUtil.toHexString(data,0,544),TypeUtil.toHexString(result));
|
|
||||||
|
|
||||||
assertEquals((byte)0xC0,(byte)input.read());
|
|
||||||
assertEquals(0x21 + 3,input.read());
|
|
||||||
assertEquals(0x7e,input.read());
|
|
||||||
assertEquals(0x02,input.read());
|
|
||||||
assertEquals(0x21,input.read());
|
|
||||||
|
|
||||||
assertEquals(32,input.read(raw));
|
|
||||||
|
|
||||||
inflater.reset();
|
|
||||||
inflater.setInput(raw);
|
|
||||||
result = new byte[545];
|
|
||||||
assertEquals(545,inflater.inflate(result));
|
|
||||||
assertEquals(TypeUtil.toHexString(data,544,545),TypeUtil.toHexString(result));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFragmentExtension() throws Exception
|
|
||||||
{
|
|
||||||
Socket socket = new Socket("localhost",__connector.getLocalPort());
|
|
||||||
OutputStream output = socket.getOutputStream();
|
|
||||||
output.write(("GET /chat HTTP/1.1\r\n" + "Host: server.example.com\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n"
|
|
||||||
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Origin: http://example.com\r\n" + "Sec-WebSocket-Protocol: onConnect\r\n"
|
|
||||||
+ "Sec-WebSocket-Version: " + WSVERSION + "\r\n" + "Sec-WebSocket-Extensions: fragment;maxLength=4;minFragments=7\r\n" + "\r\n")
|
|
||||||
.getBytes("ISO-8859-1"));
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Make sure the read times out if there are problems with the implementation
|
|
||||||
socket.setSoTimeout(1000);
|
|
||||||
|
|
||||||
InputStream input = socket.getInputStream();
|
|
||||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
|
||||||
skipTo("Sec-WebSocket-Accept: ",input);
|
|
||||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
|
||||||
skipTo("Sec-WebSocket-Extensions: ",input);
|
|
||||||
lookFor("fragment;",input);
|
|
||||||
skipTo("\r\n\r\n",input);
|
|
||||||
|
|
||||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
|
||||||
assertNotNull(__serverWebSocket.connection);
|
|
||||||
|
|
||||||
assertEquals(0x01,input.read());
|
|
||||||
assertEquals(0x04,input.read());
|
|
||||||
lookFor("sent",input);
|
|
||||||
assertEquals(0x00,input.read());
|
|
||||||
assertEquals(0x04,input.read());
|
|
||||||
lookFor(" on ",input);
|
|
||||||
assertEquals(0x00,input.read());
|
|
||||||
assertEquals(0x04,input.read());
|
|
||||||
lookFor("conn",input);
|
|
||||||
assertEquals(0x00,input.read());
|
|
||||||
assertEquals(0x01,input.read());
|
|
||||||
lookFor("e",input);
|
|
||||||
assertEquals(0x00,input.read());
|
|
||||||
assertEquals(0x01,input.read());
|
|
||||||
lookFor("c",input);
|
|
||||||
assertEquals(0x00,input.read());
|
|
||||||
assertEquals(0x00,input.read());
|
|
||||||
assertEquals(0x80,input.read());
|
|
||||||
assertEquals(0x01,input.read());
|
|
||||||
lookFor("t",input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHash()
|
|
||||||
{
|
|
||||||
assertEquals("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",AcceptHash.hashKey("dGhlIHNhbXBsZSBub25jZQ=="));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIdentityExtension() throws Exception
|
|
||||||
{
|
|
||||||
Socket socket = new Socket("localhost",__connector.getLocalPort());
|
|
||||||
OutputStream output = socket.getOutputStream();
|
|
||||||
output.write(("GET /chat HTTP/1.1\r\n" + "Host: server.example.com\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n"
|
|
||||||
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Origin: http://example.com\r\n" + "Sec-WebSocket-Protocol: onConnect\r\n"
|
|
||||||
+ "Sec-WebSocket-Version: " + WSVERSION + "\r\n" + "Sec-WebSocket-Extensions: identity;param=0\r\n"
|
|
||||||
+ "Sec-WebSocket-Extensions: identity;param=1, identity ; param = '2' ; other = ' some = value ' \r\n" + "\r\n").getBytes("ISO-8859-1"));
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Make sure the read times out if there are problems with the implementation
|
|
||||||
socket.setSoTimeout(1000);
|
|
||||||
|
|
||||||
InputStream input = socket.getInputStream();
|
|
||||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
|
||||||
skipTo("Sec-WebSocket-Accept: ",input);
|
|
||||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
|
||||||
skipTo("Sec-WebSocket-Extensions: ",input);
|
|
||||||
lookFor("identity;param=0",input);
|
|
||||||
skipTo("Sec-WebSocket-Extensions: ",input);
|
|
||||||
lookFor("identity;param=1",input);
|
|
||||||
skipTo("Sec-WebSocket-Extensions: ",input);
|
|
||||||
lookFor("identity;",input);
|
|
||||||
skipTo("\r\n\r\n",input);
|
|
||||||
|
|
||||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
|
||||||
assertNotNull(__serverWebSocket.connection);
|
|
||||||
|
|
||||||
assertEquals(0x81,input.read());
|
|
||||||
assertEquals(0x0f,input.read());
|
|
||||||
lookFor("sent on connect",input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIdle() throws Exception
|
|
||||||
{
|
|
||||||
Socket socket = new Socket("localhost",__connector.getLocalPort());
|
|
||||||
OutputStream output = socket.getOutputStream();
|
|
||||||
output.write(("GET /chat HTTP/1.1\r\n" + "Host: server.example.com\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n"
|
|
||||||
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Origin: http://example.com\r\n" + "Sec-WebSocket-Protocol: onConnect\r\n"
|
|
||||||
+ "Sec-WebSocket-Version: " + WSVERSION + "\r\n" + "\r\n").getBytes("ISO-8859-1"));
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Make sure the read times out if there are problems with the implementation
|
|
||||||
socket.setSoTimeout(10000);
|
|
||||||
|
|
||||||
InputStream input = socket.getInputStream();
|
|
||||||
|
|
||||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
|
||||||
skipTo("Sec-WebSocket-Accept: ",input);
|
|
||||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
|
||||||
skipTo("\r\n\r\n",input);
|
|
||||||
|
|
||||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
|
||||||
assertNotNull(__serverWebSocket.connection);
|
|
||||||
|
|
||||||
assertEquals(0x81,input.read());
|
|
||||||
assertEquals(0x0f,input.read());
|
|
||||||
lookFor("sent on connect",input);
|
|
||||||
|
|
||||||
assertEquals((byte)0x88,(byte)input.read());
|
|
||||||
assertEquals(26,input.read());
|
|
||||||
assertEquals(1000 / 0x100,input.read());
|
|
||||||
assertEquals(1000 % 0x100,input.read());
|
|
||||||
lookFor("Idle",input);
|
|
||||||
|
|
||||||
// respond to close
|
|
||||||
output.write(0x88 ^ 0xff);
|
|
||||||
output.write(0x80 ^ 0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
assertTrue(__serverWebSocket.awaitDisconnected(5000));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
__serverWebSocket.connection.write(null,fnf(),"Don't send");
|
|
||||||
Assert.fail("Should have thrown IOException");
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
Assert.assertThat("IOException",e.getMessage(),containsString("TODO"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMaxBinarySize() throws Exception
|
|
||||||
{
|
|
||||||
Socket socket = new Socket("localhost",__connector.getLocalPort());
|
|
||||||
OutputStream output = socket.getOutputStream();
|
|
||||||
output.write(("GET /chat HTTP/1.1\r\n" + "Host: server.example.com\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n"
|
|
||||||
+ "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Origin: http://example.com\r\n" + "Sec-WebSocket-Protocol: other\r\n"
|
|
||||||
+ "Sec-WebSocket-Version: " + WSVERSION + "\r\n" + "\r\n").getBytes("ISO-8859-1"));
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
socket.setSoTimeout(100000);
|
|
||||||
InputStream input = socket.getInputStream();
|
|
||||||
|
|
||||||
lookFor("HTTP/1.1 101 Switching Protocols\r\n",input);
|
|
||||||
skipTo("Sec-WebSocket-Accept: ",input);
|
|
||||||
lookFor("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",input);
|
|
||||||
skipTo("\r\n\r\n",input);
|
|
||||||
|
|
||||||
assertTrue(__serverWebSocket.awaitConnected(1000));
|
|
||||||
assertNotNull(__serverWebSocket.connection);
|
|
||||||
|
|
||||||
output.write(0x02);
|
|
||||||
output.write(0x8a);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
byte[] bytes = "0123456789".getBytes(StringUtil.__ISO_8859_1);
|
|
||||||
for (byte b : bytes)
|
|
||||||
{
|
|
||||||
output.write(b ^ 0xff);
|
|
||||||
}
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
output.write(0x80);
|
|
||||||
output.write(0x8a);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
output.write(0xff);
|
|
||||||
for (byte b : bytes)
|
|
||||||
{
|
|
||||||
output.write(b ^ 0xff);
|
|
||||||
}
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
assertEquals(0x80 | OpCode.CLOSE.getCode(),input.read());
|
|
||||||
assertEquals(19,input.read());
|
|
||||||
int code = ((0xff & input.read()) * 0x100) + (0xff & input.read());
|
|
||||||
assertEquals(StatusCode.MESSAGE_TOO_LARGE,code);
|
|
||||||
lookFor("Message size > 15",input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMaxBinarySize2() throws Exception
|
public void testMaxBinarySize2() throws Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,10 +3,12 @@ package org.eclipse.jetty.websocket.server;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.FutureCallback;
|
import org.eclipse.jetty.util.FutureCallback;
|
||||||
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;
|
||||||
|
@ -15,13 +17,16 @@ import org.eclipse.jetty.websocket.annotations.OnWebSocketMessage;
|
||||||
import org.eclipse.jetty.websocket.annotations.WebSocket;
|
import org.eclipse.jetty.websocket.annotations.WebSocket;
|
||||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketConnection;
|
import org.eclipse.jetty.websocket.api.WebSocketConnection;
|
||||||
|
import org.eclipse.jetty.websocket.generator.FrameGenerator;
|
||||||
import org.eclipse.jetty.websocket.protocol.CloseInfo;
|
import org.eclipse.jetty.websocket.protocol.CloseInfo;
|
||||||
import org.eclipse.jetty.websocket.protocol.FrameBuilder;
|
import org.eclipse.jetty.websocket.protocol.FrameBuilder;
|
||||||
|
import org.eclipse.jetty.websocket.protocol.OpCode;
|
||||||
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
|
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
|
||||||
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -208,6 +213,32 @@ public class WebSocketServletRFCTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore("Idle Timeouts not working (yet)")
|
||||||
|
public void testIdle() throws Exception
|
||||||
|
{
|
||||||
|
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||||
|
client.setProtocols("onConnect");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
client.connect();
|
||||||
|
client.sendStandardRequest();
|
||||||
|
client.expectUpgradeResponse();
|
||||||
|
|
||||||
|
client.write(FrameBuilder.text("Hello").asFrame());
|
||||||
|
|
||||||
|
// now wait for the server to time out
|
||||||
|
// should be 2 frames, the TextFrame echo, and then the Close on disconnect
|
||||||
|
Queue<WebSocketFrame> frames = client.readFrames(2,TimeUnit.SECONDS,5);
|
||||||
|
Assert.assertThat("frames[0].opcode",frames.remove().getOpCode(),is(OpCode.TEXT));
|
||||||
|
Assert.assertThat("frames[1].opcode",frames.remove().getOpCode(),is(OpCode.CLOSE));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the requirement of responding with server terminated close code 1011 when there is an unhandled (internal server error) being produced by the
|
* Test the requirement of responding with server terminated close code 1011 when there is an unhandled (internal server error) being produced by the
|
||||||
* WebSocket POJO.
|
* WebSocket POJO.
|
||||||
|
@ -237,4 +268,34 @@ public class WebSocketServletRFCTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMaxBinarySize() throws Exception
|
||||||
|
{
|
||||||
|
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||||
|
client.setProtocols("other");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
client.connect();
|
||||||
|
client.sendStandardRequest();
|
||||||
|
client.expectUpgradeResponse();
|
||||||
|
|
||||||
|
int dataSize = 1024 * 100;
|
||||||
|
byte buf[] = new byte[dataSize];
|
||||||
|
Arrays.fill(buf,(byte)0x44);
|
||||||
|
ByteBuffer bb = ByteBuffer.allocate(dataSize + FrameGenerator.OVERHEAD);
|
||||||
|
BufferUtil.clearToFill(bb);
|
||||||
|
FrameBuilder.binary(buf).fill(bb);
|
||||||
|
BufferUtil.flipToFlush(bb,0);
|
||||||
|
client.writeRaw(bb);
|
||||||
|
|
||||||
|
Queue<WebSocketFrame> frames = client.readFrames(2,TimeUnit.SECONDS,1);
|
||||||
|
Assert.assertThat("frames[0].opcode",frames.remove().getOpCode(),is(OpCode.BINARY));
|
||||||
|
Assert.assertThat("frames[1].opcode",frames.remove().getOpCode(),is(OpCode.CLOSE));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ import java.net.Socket;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -63,9 +65,10 @@ public class BlockheadClient implements Parser.Listener
|
||||||
private InputStream in;
|
private InputStream in;
|
||||||
private int version = 13; // default to RFC-6455
|
private int version = 13; // default to RFC-6455
|
||||||
private String protocols;
|
private String protocols;
|
||||||
private String extensions;
|
private List<String> extensions = new ArrayList<>();
|
||||||
private byte[] clientmask = new byte[]
|
private byte[] clientmask = new byte[]
|
||||||
{ (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF };
|
{ (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF };
|
||||||
|
private int timeout = 1000;
|
||||||
|
|
||||||
public BlockheadClient(URI destWebsocketURI) throws URISyntaxException
|
public BlockheadClient(URI destWebsocketURI) throws URISyntaxException
|
||||||
{
|
{
|
||||||
|
@ -87,6 +90,16 @@ public class BlockheadClient implements Parser.Listener
|
||||||
incomingFrameQueue = new LinkedBlockingDeque<>();
|
incomingFrameQueue = new LinkedBlockingDeque<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addExtensions(String xtension)
|
||||||
|
{
|
||||||
|
this.extensions.add(xtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearExtensions()
|
||||||
|
{
|
||||||
|
extensions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
public void close()
|
public void close()
|
||||||
{
|
{
|
||||||
IO.close(in);
|
IO.close(in);
|
||||||
|
@ -108,7 +121,7 @@ public class BlockheadClient implements Parser.Listener
|
||||||
socket = new Socket(destAddr,port);
|
socket = new Socket(destAddr,port);
|
||||||
|
|
||||||
out = socket.getOutputStream();
|
out = socket.getOutputStream();
|
||||||
// socket.setSoTimeout(1000);
|
socket.setSoTimeout(timeout);
|
||||||
in = socket.getInputStream();
|
in = socket.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +134,7 @@ public class BlockheadClient implements Parser.Listener
|
||||||
return respHeader;
|
return respHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getExtensions()
|
public List<String> getExtensions()
|
||||||
{
|
{
|
||||||
return extensions;
|
return extensions;
|
||||||
}
|
}
|
||||||
|
@ -285,25 +298,26 @@ public class BlockheadClient implements Parser.Listener
|
||||||
{
|
{
|
||||||
req.append("Sec-WebSocket-Protocol: ").append(protocols).append("\r\n");
|
req.append("Sec-WebSocket-Protocol: ").append(protocols).append("\r\n");
|
||||||
}
|
}
|
||||||
if (StringUtil.isNotBlank(extensions))
|
|
||||||
|
for (String xtension : extensions)
|
||||||
{
|
{
|
||||||
req.append("Sec-WebSocket-Extensions: ").append(extensions).append("\r\n");
|
req.append("Sec-WebSocket-Extensions: ").append(xtension).append("\r\n");
|
||||||
}
|
}
|
||||||
req.append("Sec-WebSocket-Version: ").append(version).append("\r\n");
|
req.append("Sec-WebSocket-Version: ").append(version).append("\r\n");
|
||||||
req.append("\r\n");
|
req.append("\r\n");
|
||||||
writeRaw(req.toString());
|
writeRaw(req.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExtensions(String extensions)
|
|
||||||
{
|
|
||||||
this.extensions = extensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProtocols(String protocols)
|
public void setProtocols(String protocols)
|
||||||
{
|
{
|
||||||
this.protocols = protocols;
|
this.protocols = protocols;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTimeout(TimeUnit unit, int duration)
|
||||||
|
{
|
||||||
|
this.timeout = (int)TimeUnit.MILLISECONDS.convert(duration,unit);
|
||||||
|
}
|
||||||
|
|
||||||
public void setVersion(int version)
|
public void setVersion(int version)
|
||||||
{
|
{
|
||||||
this.version = version;
|
this.version = version;
|
||||||
|
|
Loading…
Reference in New Issue