Moving more tests cases over

This commit is contained in:
Joakim Erdfelt 2012-07-06 15:53:41 -07:00
parent 5d9eab45b4
commit 7a35ea9c75
7 changed files with 303 additions and 708 deletions

View File

@ -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="));
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -27,9 +27,6 @@ import java.net.SocketException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
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.Server;
@ -37,7 +34,6 @@ import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.Utf8StringBuilder;
import org.eclipse.jetty.websocket.annotations.OnWebSocketClose;
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.api.StatusCode;
import org.eclipse.jetty.websocket.api.WebSocketConnection;
import org.eclipse.jetty.websocket.protocol.AcceptHash;
import org.eclipse.jetty.websocket.protocol.OpCode;
import org.junit.AfterClass;
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
public void testMaxBinarySize2() throws Exception
{

View File

@ -3,10 +3,12 @@ package org.eclipse.jetty.websocket.server;
import static org.hamcrest.Matchers.*;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.log.Log;
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.api.StatusCode;
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.FrameBuilder;
import org.eclipse.jetty.websocket.protocol.OpCode;
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.server.blockhead.BlockheadClient;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
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
* 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();
}
}
}

View File

@ -15,6 +15,8 @@ import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
@ -63,9 +65,10 @@ public class BlockheadClient implements Parser.Listener
private InputStream in;
private int version = 13; // default to RFC-6455
private String protocols;
private String extensions;
private List<String> extensions = new ArrayList<>();
private byte[] clientmask = new byte[]
{ (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF };
private int timeout = 1000;
public BlockheadClient(URI destWebsocketURI) throws URISyntaxException
{
@ -87,6 +90,16 @@ public class BlockheadClient implements Parser.Listener
incomingFrameQueue = new LinkedBlockingDeque<>();
}
public void addExtensions(String xtension)
{
this.extensions.add(xtension);
}
public void clearExtensions()
{
extensions.clear();
}
public void close()
{
IO.close(in);
@ -108,7 +121,7 @@ public class BlockheadClient implements Parser.Listener
socket = new Socket(destAddr,port);
out = socket.getOutputStream();
// socket.setSoTimeout(1000);
socket.setSoTimeout(timeout);
in = socket.getInputStream();
}
@ -121,7 +134,7 @@ public class BlockheadClient implements Parser.Listener
return respHeader;
}
public String getExtensions()
public List<String> getExtensions()
{
return extensions;
}
@ -285,25 +298,26 @@ public class BlockheadClient implements Parser.Listener
{
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("\r\n");
writeRaw(req.toString());
}
public void setExtensions(String extensions)
{
this.extensions = extensions;
}
public void setProtocols(String protocols)
{
this.protocols = protocols;
}
public void setTimeout(TimeUnit unit, int duration)
{
this.timeout = (int)TimeUnit.MILLISECONDS.convert(duration,unit);
}
public void setVersion(int version)
{
this.version = version;