Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Wilkins2012-08-02 18:48:34 -0400
committerGreg Wilkins2012-08-02 18:48:34 -0400
commit5e6cd1b27f8a67ecdd5b745cb2f162bd5670e5c7 (patch)
treebf44767c0c802c868fbac42bdaf1283a73e8fa0d /jetty-websocket
parent962a0d08895274d2701c5ffd8a4776706064d8d2 (diff)
parent57f16d750d0120d02d9d60828c71daaaf4d83a3f (diff)
downloadorg.eclipse.jetty.project-5e6cd1b27f8a67ecdd5b745cb2f162bd5670e5c7.tar.gz
org.eclipse.jetty.project-5e6cd1b27f8a67ecdd5b745cb2f162bd5670e5c7.tar.xz
org.eclipse.jetty.project-5e6cd1b27f8a67ecdd5b745cb2f162bd5670e5c7.zip
Merge branch 'jetty-9' into jetty-9-oneconnector
Conflicts: jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java
Diffstat (limited to 'jetty-websocket')
-rw-r--r--jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/extensions/fragment/FragmentExtension.java2
-rw-r--r--jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/AbstractWebSocketConnection.java9
-rw-r--r--jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/ControlFrameBytes.java6
-rw-r--r--jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/FrameBytes.java2
-rw-r--r--jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/Parser.java51
-rw-r--r--jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/WebSocketFrame.java3
-rw-r--r--jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/extensions/DeflateFrameExtensionTest.java2
-rw-r--r--jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/extensions/FragmentExtensionTest.java2
-rw-r--r--jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/GeneratorTest.java39
-rw-r--r--jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/ParserTest.java138
-rw-r--r--jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/UnitGenerator.java35
-rw-r--r--jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/UnitParser.java29
-rw-r--r--jetty-websocket/websocket-core/src/test/resources/jetty-logging.properties3
-rw-r--r--jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DeflateExtensionTest.java2
-rw-r--r--jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java2
-rw-r--r--jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase1.java7
-rw-r--r--jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java5
-rw-r--r--jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java60
-rw-r--r--jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties3
19 files changed, 291 insertions, 109 deletions
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/extensions/fragment/FragmentExtension.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/extensions/fragment/FragmentExtension.java
index b4210a1799..325841baac 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/extensions/fragment/FragmentExtension.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/extensions/fragment/FragmentExtension.java
@@ -29,7 +29,7 @@ public class FragmentExtension extends Extension
private int maxLength = -1;
@Override
- public <C> void output(C context, Callback<C> callback, WebSocketFrame frame) throws IOException
+ public <C> void output(C context, Callback<C> callback, final WebSocketFrame frame) throws IOException
{
if (frame.isControlFrame())
{
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/AbstractWebSocketConnection.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/AbstractWebSocketConnection.java
index 5fe68ec9ba..9a0f970d63 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/AbstractWebSocketConnection.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/AbstractWebSocketConnection.java
@@ -106,6 +106,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
}
flushing = false;
}
+ flush();
}
@Override
@@ -288,7 +289,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
else if (filled < 0)
{
LOG.debug("read - EOF Reached");
- disconnect(false);
+ // disconnect(false); // FIXME Simone says this is bad
return -1;
}
else
@@ -376,15 +377,9 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
try
{
endpoint.write(frameBytes.context,frameBytes,buffer);
- long count = writes.incrementAndGet();
- if ((count % 10) == 0)
- {
- LOG.info("Server wrote {} ByteBuffers",count);
- }
}
catch (Throwable t)
{
- LOG.debug(t);
frameBytes.failed(frameBytes.context,t);
}
}
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/ControlFrameBytes.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/ControlFrameBytes.java
index 2bb7715302..0aebfd7a0b 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/ControlFrameBytes.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/ControlFrameBytes.java
@@ -18,11 +18,14 @@ package org.eclipse.jetty.websocket.io;
import java.nio.ByteBuffer;
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.protocol.OpCode;
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
public class ControlFrameBytes<C> extends FrameBytes<C>
{
+ private static final Logger LOG = Log.getLogger(ControlFrameBytes.class);
private ByteBuffer buffer;
public ControlFrameBytes(AbstractWebSocketConnection connection, Callback<C> callback, C context, WebSocketFrame frame)
@@ -32,6 +35,7 @@ public class ControlFrameBytes<C> extends FrameBytes<C>
@Override
public void completed(C context) {
+ LOG.debug("completed() - frame: {}",frame);
connection.getBufferPool().release(buffer);
super.completed(context);
@@ -39,7 +43,7 @@ public class ControlFrameBytes<C> extends FrameBytes<C>
if (frame.getOpCode() == OpCode.CLOSE)
{
// Disconnect the connection (no more packets/frames)
- connection.disconnect(false);
+ connection.disconnect(true); // FIXME (should only shutdown output here)
}
}
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/FrameBytes.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/FrameBytes.java
index a1260f5f44..c52e8a50cf 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/FrameBytes.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/io/FrameBytes.java
@@ -57,7 +57,7 @@ public abstract class FrameBytes<C> implements Callback<C>, Runnable
{
if (LOG.isDebugEnabled())
{
- LOG.debug("completed({})",context);
+ LOG.debug("completed({}) - {}",context,this.getClass().getName());
}
cancelTask();
connection.complete(this);
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/Parser.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/Parser.java
index fa49a5e705..eead9e9154 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/Parser.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/Parser.java
@@ -49,6 +49,7 @@ public class Parser
private int cursor = 0;
// Frame
private WebSocketFrame frame;
+ private WebSocketFrame priorDataFrame;
private byte lastDataOpcode;
// payload specific
private ByteBuffer payload;
@@ -177,8 +178,15 @@ public class Parser
{
LOG.debug("{} Parsed Frame: {}",policy.getBehavior(),frame);
notifyFrame(frame);
+ if (frame.isDataFrame() && frame.isFin())
+ {
+ priorDataFrame = null;
+ }
+ else
+ {
+ priorDataFrame = frame;
+ }
}
-
}
catch (WebSocketException e)
{
@@ -267,20 +275,35 @@ public class Parser
throw new ProtocolException("RSV3 not allowed to be set");
}
- if (OpCode.isControlFrame(opcode) && !fin)
+ boolean isContinuation = false;
+
+ if (OpCode.isControlFrame(opcode))
{
- throw new ProtocolException("Fragmented Control Frame [" + OpCode.name(opcode) + "]");
+ // control frame validation
+ if (!fin)
+ {
+ throw new ProtocolException("Fragmented Control Frame [" + OpCode.name(opcode) + "]");
+ }
}
-
- if (opcode == OpCode.CONTINUATION)
+ else if (opcode == OpCode.CONTINUATION)
{
- if (frame == null)
+ isContinuation = true;
+ // continuation validation
+ if (priorDataFrame == null)
{
- throw new ProtocolException("Fragment continuation frame without prior !FIN");
+ throw new ProtocolException("CONTINUATION frame without prior !FIN");
}
// Be careful to use the original opcode
opcode = lastDataOpcode;
}
+ else if (OpCode.isDataFrame(opcode))
+ {
+ // data validation
+ if ((priorDataFrame != null) && (!priorDataFrame.isFin()))
+ {
+ throw new ProtocolException("Unexpected " + OpCode.name(opcode) + " frame, was expecting CONTINUATION");
+ }
+ }
// base framing flags
frame = new WebSocketFrame();
@@ -289,6 +312,7 @@ public class Parser
frame.setRsv2(rsv2);
frame.setRsv3(rsv3);
frame.setOpCode(opcode);
+ frame.setContinuation(isContinuation);
if (frame.isDataFrame())
{
@@ -392,8 +416,8 @@ public class Parser
case MASK_BYTES:
{
byte b = buffer.get();
+ frame.getMask()[4 - cursor] = b;
--cursor;
- frame.getMask()[cursor] = b;
if (cursor == 0)
{
// special case for empty payloads (no more bytes left in buffer)
@@ -435,7 +459,7 @@ public class Parser
* the payload buffer
* @return true if payload is done reading, false if incomplete
*/
- public boolean parsePayload(ByteBuffer buffer)
+ private boolean parsePayload(ByteBuffer buffer)
{
if (payloadLength == 0)
{
@@ -449,6 +473,7 @@ public class Parser
getPolicy().assertValidPayloadLength(payloadLength);
frame.assertValid();
payload = ByteBuffer.allocate(payloadLength);
+ BufferUtil.clearToFill(payload);
}
BufferUtil.put(buffer,payload);
@@ -457,14 +482,18 @@ public class Parser
{
BufferUtil.flipToFlush(payload,0);
+ LOG.debug("PreMask: {}",BufferUtil.toDetailString(payload));
// demask (if needed)
if (frame.isMasked())
{
byte mask[] = frame.getMask();
+ int offset;
+ int start = payload.position();
int end = payload.limit();
- for (int i = payload.position(); i < end; i++)
+ for (int i = start; i < end; i++)
{
- payload.put(i,(byte)(payload.get(i) ^ mask[i % 4]));
+ offset = (i - start);
+ payload.put(i,(byte)(payload.get(i) ^ mask[offset % 4]));
}
}
diff --git a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/WebSocketFrame.java b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/WebSocketFrame.java
index 78459b17c3..b4f7b035ea 100644
--- a/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/WebSocketFrame.java
+++ b/jetty-websocket/websocket-core/src/main/java/org/eclipse/jetty/websocket/protocol/WebSocketFrame.java
@@ -113,6 +113,7 @@ public class WebSocketFrame implements Frame
*/
public WebSocketFrame(byte opcode)
{
+ reset();
this.opcode = opcode;
}
@@ -126,7 +127,7 @@ public class WebSocketFrame implements Frame
*/
public WebSocketFrame(WebSocketFrame copy)
{
- fin = copy.rsv1;
+ fin = copy.fin;
rsv1 = copy.rsv2;
rsv2 = copy.rsv2;
rsv3 = copy.rsv3;
diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/extensions/DeflateFrameExtensionTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/extensions/DeflateFrameExtensionTest.java
index 90ba98fe30..2136f6d863 100644
--- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/extensions/DeflateFrameExtensionTest.java
+++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/extensions/DeflateFrameExtensionTest.java
@@ -232,7 +232,7 @@ public class DeflateFrameExtensionTest
Assert.assertThat(prefix + ".opcode",actual.getOpCode(),is(OpCode.TEXT));
Assert.assertThat(prefix + ".fin",actual.isFin(),is(true));
- Assert.assertThat(prefix + ".rsv1",actual.isRsv1(),is(true));
+ Assert.assertThat(prefix + ".rsv1",actual.isRsv1(),is(false)); // RSV1 should be unset at this point
Assert.assertThat(prefix + ".rsv2",actual.isRsv2(),is(false));
Assert.assertThat(prefix + ".rsv3",actual.isRsv3(),is(false));
diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/extensions/FragmentExtensionTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/extensions/FragmentExtensionTest.java
index d22c966b1f..0fc69b6e0e 100644
--- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/extensions/FragmentExtensionTest.java
+++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/extensions/FragmentExtensionTest.java
@@ -88,7 +88,7 @@ public class FragmentExtensionTest
quote.add("a single experiment can prove me wrong.");
quote.add("-- Albert Einstein");
- // Manually compress frame and pass into extension
+ // Manually create frame and pass into extension
for (String q : quote)
{
WebSocketFrame frame = WebSocketFrame.text(q);
diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/GeneratorTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/GeneratorTest.java
index 3b1b0e60c8..c184dab666 100644
--- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/GeneratorTest.java
+++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/GeneratorTest.java
@@ -16,19 +16,13 @@ import org.junit.Test;
public class GeneratorTest
{
-
/**
* Prevent regression of masking of many packets.
*/
@Test
public void testManyMasked()
{
- byte[] MASK =
- { 0x11, 0x22, 0x33, 0x44 };
- int pingCount = 1000;
-
- // the generator
- Generator generator = new UnitGenerator();
+ int pingCount = 10;
// Prepare frames
List<WebSocketFrame> send = new ArrayList<>();
@@ -39,40 +33,15 @@ public class GeneratorTest
}
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
- // Generate into single bytebuffer
- int buflen = 0;
- for (WebSocketFrame f : send)
- {
- buflen += f.getPayloadLength() + Generator.OVERHEAD;
- }
- ByteBuffer completeBuf = ByteBuffer.allocate(buflen);
- BufferUtil.clearToFill(completeBuf);
-
- // Generate frames
- for (WebSocketFrame f : send)
- {
- f.setMask(MASK); // make sure we have mask set
- ByteBuffer slice = f.getPayload().slice();
- BufferUtil.put(generator.generate(f),completeBuf);
- f.setPayload(slice);
- }
- BufferUtil.flipToFlush(completeBuf,0);
+ ByteBuffer completeBuf = UnitGenerator.generate(send);
// Parse complete buffer (5 bytes at a time)
- WebSocketPolicy policy = WebSocketPolicy.newServerPolicy();
- Parser parser = new Parser(policy);
+ UnitParser parser = new UnitParser();
IncomingFramesCapture capture = new IncomingFramesCapture();
parser.setIncomingFramesHandler(capture);
int segmentSize = 5;
- while (completeBuf.remaining() > 0)
- {
- ByteBuffer part = completeBuf.slice();
- int len = Math.min(segmentSize,part.remaining());
- part.limit(part.position() + len);
- parser.parse(part);
- completeBuf.position(completeBuf.position() + len);
- }
+ parser.parseSlowly(completeBuf,segmentSize);
// Assert validity of frame
int frameCount = send.size();
diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/ParserTest.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/ParserTest.java
index 3fc300d2a8..34f78fd183 100644
--- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/ParserTest.java
+++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/ParserTest.java
@@ -18,15 +18,151 @@ package org.eclipse.jetty.websocket.protocol;
import static org.hamcrest.Matchers.*;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.api.WebSocketBehavior;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
-import org.eclipse.jetty.websocket.protocol.Parser;
import org.junit.Assert;
import org.junit.Test;
public class ParserTest
{
+ /**
+ * Similar to the server side 5.15 testcase. A normal 2 fragment text text message, followed by another continuation.
+ */
+ @Test
+ public void testParseCase5_15()
+ {
+ List<WebSocketFrame> send = new ArrayList<>();
+ send.add(new WebSocketFrame(OpCode.TEXT).setPayload("fragment1").setFin(false));
+ send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("fragment2").setFin(true));
+ send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload("fragment3").setFin(false)); // bad frame
+ send.add(new WebSocketFrame(OpCode.TEXT).setPayload("fragment4").setFin(true));
+ send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
+
+ ByteBuffer completeBuf = UnitGenerator.generate(send);
+ UnitParser parser = new UnitParser();
+ IncomingFramesCapture capture = new IncomingFramesCapture();
+ parser.setIncomingFramesHandler(capture);
+ parser.parse(completeBuf);
+
+ capture.assertErrorCount(1);
+ capture.assertHasFrame(OpCode.TEXT,2);
+ }
+
+ /**
+ * Similar to the server side 5.18 testcase. Text message fragmented as 2 frames, both as opcode=TEXT
+ */
+ @Test
+ public void testParseCase5_18()
+ {
+ List<WebSocketFrame> send = new ArrayList<>();
+ send.add(new WebSocketFrame(OpCode.TEXT).setPayload("fragment1").setFin(false));
+ send.add(new WebSocketFrame(OpCode.TEXT).setPayload("fragment2").setFin(true)); // bad frame, must be continuation
+ send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
+
+ ByteBuffer completeBuf = UnitGenerator.generate(send);
+ UnitParser parser = new UnitParser();
+ IncomingFramesCapture capture = new IncomingFramesCapture();
+ parser.setIncomingFramesHandler(capture);
+ parser.parse(completeBuf);
+
+ capture.assertErrorCount(1);
+ capture.assertHasFrame(OpCode.TEXT,1); // fragment 1
+ }
+
+ /**
+ * Similar to the server side 5.19 testcase.
+ * text message, send in 5 frames/fragments, with 2 pings in the mix.
+ */
+ @Test
+ public void testParseCase5_19()
+ {
+ List<WebSocketFrame> send = new ArrayList<>();
+ send.add(new WebSocketFrame(OpCode.TEXT).setPayload("f1").setFin(false));
+ send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload(",f2").setFin(false));
+ send.add(new WebSocketFrame(OpCode.PING).setPayload("pong-1"));
+ send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload(",f3").setFin(false));
+ send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload(",f4").setFin(false));
+ send.add(new WebSocketFrame(OpCode.PING).setPayload("pong-2"));
+ send.add(new WebSocketFrame(OpCode.CONTINUATION).setPayload(",f5").setFin(true));
+ send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
+
+ ByteBuffer completeBuf = UnitGenerator.generate(send);
+ UnitParser parser = new UnitParser();
+ IncomingFramesCapture capture = new IncomingFramesCapture();
+ parser.setIncomingFramesHandler(capture);
+ parser.parse(completeBuf);
+
+ capture.assertErrorCount(0);
+ capture.assertHasFrame(OpCode.TEXT,5);
+ capture.assertHasFrame(OpCode.CLOSE,1);
+ capture.assertHasFrame(OpCode.PING,2);
+ }
+
+ /**
+ * Similar to the server side 5.6 testcase. pong, then text, then close frames.
+ */
+ @Test
+ public void testParseCase5_6()
+ {
+ List<WebSocketFrame> send = new ArrayList<>();
+ send.add(WebSocketFrame.pong().setPayload("ping"));
+ send.add(WebSocketFrame.text("hello, world"));
+ send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
+
+ ByteBuffer completeBuf = UnitGenerator.generate(send);
+ UnitParser parser = new UnitParser();
+ IncomingFramesCapture capture = new IncomingFramesCapture();
+ parser.setIncomingFramesHandler(capture);
+ parser.parse(completeBuf);
+
+ capture.assertErrorCount(0);
+ capture.assertHasFrame(OpCode.TEXT,1);
+ capture.assertHasFrame(OpCode.CLOSE,1);
+ capture.assertHasFrame(OpCode.PONG,1);
+ }
+
+ /**
+ * Similar to the server side 6.2.3 testcase. Lots of small 1 byte UTF8 Text frames, representing 1 overall text message.
+ */
+ @Test
+ public void testParseCase6_2_3()
+ {
+ String utf8 = "Hello-\uC2B5@\uC39F\uC3A4\uC3BC\uC3A0\uC3A1-UTF-8!!";
+ byte msg[] = StringUtil.getUtf8Bytes(utf8);
+
+ List<WebSocketFrame> send = new ArrayList<>();
+ int len = msg.length;
+ byte opcode = OpCode.TEXT;
+ byte mini[];
+ for (int i = 0; i < len; i++)
+ {
+ WebSocketFrame frame = new WebSocketFrame(opcode);
+ mini = new byte[1];
+ mini[0] = msg[i];
+ frame.setPayload(mini);
+ boolean isLast = (i >= (len - 1));
+ frame.setFin(isLast);
+ send.add(frame);
+ opcode = OpCode.CONTINUATION;
+ }
+ send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
+
+ ByteBuffer completeBuf = UnitGenerator.generate(send);
+ UnitParser parser = new UnitParser();
+ IncomingFramesCapture capture = new IncomingFramesCapture();
+ parser.setIncomingFramesHandler(capture);
+ parser.parse(completeBuf);
+
+ capture.assertErrorCount(0);
+ capture.assertHasFrame(OpCode.TEXT,len);
+ capture.assertHasFrame(OpCode.CLOSE,1);
+ }
+
@Test
public void testParseNothing()
{
diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/UnitGenerator.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/UnitGenerator.java
index 9493da489f..7b0b6087a0 100644
--- a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/UnitGenerator.java
+++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/UnitGenerator.java
@@ -15,7 +15,11 @@
//========================================================================
package org.eclipse.jetty.websocket.protocol;
+import java.nio.ByteBuffer;
+import java.util.List;
+
import org.eclipse.jetty.io.StandardByteBufferPool;
+import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
/**
@@ -23,6 +27,37 @@ import org.eclipse.jetty.websocket.api.WebSocketPolicy;
*/
public class UnitGenerator extends Generator
{
+ public static ByteBuffer generate(List<WebSocketFrame> frames)
+ {
+ // Create non-symmetrical mask (shows mask bytes order issues)
+ byte[] MASK =
+ { 0x11, 0x22, 0x33, 0x44 };
+
+ // the generator
+ Generator generator = new UnitGenerator();
+
+ // Generate into single bytebuffer
+ int buflen = 0;
+ for (WebSocketFrame f : frames)
+ {
+ buflen += f.getPayloadLength() + Generator.OVERHEAD;
+ }
+ ByteBuffer completeBuf = ByteBuffer.allocate(buflen);
+ BufferUtil.clearToFill(completeBuf);
+
+ // Generate frames
+ for (WebSocketFrame f : frames)
+ {
+ f.setMask(MASK); // make sure we have mask set
+ ByteBuffer slice = f.getPayload().slice();
+ BufferUtil.put(generator.generate(f),completeBuf);
+ f.setPayload(slice);
+ }
+
+ BufferUtil.flipToFlush(completeBuf,0);
+ return completeBuf;
+ }
+
public UnitGenerator()
{
super(WebSocketPolicy.newServerPolicy(),new StandardByteBufferPool());
diff --git a/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/UnitParser.java b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/UnitParser.java
new file mode 100644
index 0000000000..860f02da43
--- /dev/null
+++ b/jetty-websocket/websocket-core/src/test/java/org/eclipse/jetty/websocket/protocol/UnitParser.java
@@ -0,0 +1,29 @@
+package org.eclipse.jetty.websocket.protocol;
+
+import java.nio.ByteBuffer;
+
+import org.eclipse.jetty.websocket.api.WebSocketPolicy;
+
+public class UnitParser extends Parser
+{
+ public UnitParser()
+ {
+ super(WebSocketPolicy.newServerPolicy());
+ }
+
+ private void parsePartial(ByteBuffer buf, int numBytes)
+ {
+ int len = Math.min(numBytes,buf.remaining());
+ byte arr[] = new byte[len];
+ buf.get(arr,0,len);
+ this.parse(ByteBuffer.wrap(arr));
+ }
+
+ public void parseSlowly(ByteBuffer buf, int segmentSize)
+ {
+ while (buf.remaining() > 0)
+ {
+ parsePartial(buf,segmentSize);
+ }
+ }
+}
diff --git a/jetty-websocket/websocket-core/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-core/src/test/resources/jetty-logging.properties
index fbf6944551..c100df43af 100644
--- a/jetty-websocket/websocket-core/src/test/resources/jetty-logging.properties
+++ b/jetty-websocket/websocket-core/src/test/resources/jetty-logging.properties
@@ -1,2 +1,3 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
-org.eclipse.jetty.websocket.LEVEL=WARN \ No newline at end of file
+org.eclipse.jetty.websocket.LEVEL=WARN
+# org.eclipse.jetty.websocket.protocol.Parser.LEVEL=DEBUG \ No newline at end of file
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DeflateExtensionTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DeflateExtensionTest.java
index 03ef8bcc21..3f854d4ecd 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DeflateExtensionTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/DeflateExtensionTest.java
@@ -47,7 +47,7 @@ public class DeflateExtensionTest
}
@Test
- @Ignore /* FIXME */
+ @Ignore("Not yet working")
public void testDeflateFrameExtension() throws Exception
{
BlockheadClient client = new BlockheadClient(server.getServerUri());
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java
index 2044fe97a0..25cb7cba13 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/WebSocketServletRFCTest.java
@@ -233,6 +233,7 @@ public class WebSocketServletRFCTest
}
@Test
+ @Ignore("Should be moved to Fuzzer")
public void testMaxBinarySize() throws Exception
{
BlockheadClient client = new BlockheadClient(server.getServerUri());
@@ -274,6 +275,7 @@ public class WebSocketServletRFCTest
}
@Test
+ @Ignore("Should be moved to Fuzzer")
public void testMaxTextSize() throws Exception
{
BlockheadClient client = new BlockheadClient(server.getServerUri());
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase1.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase1.java
index 2bcc408ea1..90ed4497ff 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase1.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase1.java
@@ -23,7 +23,6 @@ import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.protocol.CloseInfo;
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
import org.eclipse.jetty.websocket.server.ab.Fuzzer.SendMode;
-import org.junit.Ignore;
import org.junit.Test;
public class TestABCase1 extends AbstractABCase
@@ -184,7 +183,6 @@ public class TestABCase1 extends AbstractABCase
* Echo 65535 byte TEXT message (uses medium 2 byte payload length)
*/
@Test
- @Ignore /* FIXME */
public void testCase1_1_6() throws Exception
{
byte payload[] = new byte[65535];
@@ -216,7 +214,6 @@ public class TestABCase1 extends AbstractABCase
* Echo 65536 byte TEXT message (uses large 8 byte payload length)
*/
@Test
- @Ignore /* FIXME */
public void testCase1_1_7() throws Exception
{
byte payload[] = new byte[65536];
@@ -252,7 +249,6 @@ public class TestABCase1 extends AbstractABCase
* This is done to test the parsing together of the frame on the server side.
*/
@Test
- @Ignore /* FIXME */
public void testCase1_1_8() throws Exception
{
byte payload[] = new byte[65536];
@@ -438,7 +434,6 @@ public class TestABCase1 extends AbstractABCase
* Echo 65535 byte BINARY message (uses medium 2 byte payload length)
*/
@Test
- @Ignore /* FIXME */
public void testCase1_2_6() throws Exception
{
byte payload[] = new byte[65535];
@@ -470,7 +465,6 @@ public class TestABCase1 extends AbstractABCase
* Echo 65536 byte BINARY message (uses large 8 byte payload length)
*/
@Test
- @Ignore /* FIXME */
public void testCase1_2_7() throws Exception
{
byte payload[] = new byte[65536];
@@ -506,7 +500,6 @@ public class TestABCase1 extends AbstractABCase
* This is done to test the parsing together of the frame on the server side.
*/
@Test
- @Ignore /* FIXME */
public void testCase1_2_8() throws Exception
{
byte payload[] = new byte[65536];
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java
index 5d9f12eec0..bf66c78cac 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase5.java
@@ -26,7 +26,6 @@ import org.eclipse.jetty.websocket.api.StatusCode;
import org.eclipse.jetty.websocket.protocol.CloseInfo;
import org.eclipse.jetty.websocket.protocol.OpCode;
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -242,7 +241,6 @@ public class TestABCase5 extends AbstractABCase
* Send text fragmented properly in 2 frames, then continuation!fin, then text unfragmented.
*/
@Test
- @Ignore /* FIXME */
public void testCase5_15() throws Exception
{
List<WebSocketFrame> send = new ArrayList<>();
@@ -253,7 +251,7 @@ public class TestABCase5 extends AbstractABCase
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
List<WebSocketFrame> expect = new ArrayList<>();
- send.add(WebSocketFrame.text("fragment1fragment2"));
+ expect.add(WebSocketFrame.text("fragment1fragment2"));
expect.add(new CloseInfo(StatusCode.PROTOCOL).asFrame());
Fuzzer fuzzer = new Fuzzer(this);
@@ -338,7 +336,6 @@ public class TestABCase5 extends AbstractABCase
* text message fragmented in 2 frames, both frames as opcode=TEXT
*/
@Test
- @Ignore /* FIXME */
public void testCase5_18() throws Exception
{
List<WebSocketFrame> send = new ArrayList<>();
diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java
index 08d60fc373..2719cbc19c 100644
--- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java
+++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/ab/TestABCase6.java
@@ -38,6 +38,27 @@ import org.junit.runner.RunWith;
public class TestABCase6 extends AbstractABCase
{
/**
+ * Split a message byte array into a series of fragments (frames + continuations) of 1 byte message contents each.
+ */
+ protected void fragmentText(List<WebSocketFrame> frames, byte msg[])
+ {
+ int len = msg.length;
+ byte opcode = OpCode.TEXT;
+ byte mini[];
+ for (int i = 0; i < len; i++)
+ {
+ WebSocketFrame frame = new WebSocketFrame(opcode);
+ mini = new byte[1];
+ mini[0] = msg[i];
+ frame.setPayload(mini);
+ boolean isLast = (i >= (len - 1));
+ frame.setFin(isLast);
+ frames.add(frame);
+ opcode = OpCode.CONTINUATION;
+ }
+ }
+
+ /**
* text message, 1 frame, 0 length
*/
@Test
@@ -198,18 +219,7 @@ public class TestABCase6 extends AbstractABCase
byte msg[] = StringUtil.getUtf8Bytes(utf8);
List<WebSocketFrame> send = new ArrayList<>();
- int len = msg.length;
- byte opcode = OpCode.TEXT;
- byte mini[];
- for (int i = 0; i < len; i++)
- {
- WebSocketFrame frame = new WebSocketFrame(opcode);
- mini = new byte[1];
- mini[0] = msg[i];
- frame.setPayload(mini);
- frame.setFin(!(i < (len - 1)));
- send.add(frame);
- }
+ fragmentText(send,msg);
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
List<WebSocketFrame> expect = new ArrayList<>();
@@ -239,18 +249,7 @@ public class TestABCase6 extends AbstractABCase
byte msg[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5");
List<WebSocketFrame> send = new ArrayList<>();
- int len = msg.length;
- byte opcode = OpCode.TEXT;
- byte mini[];
- for (int i = 0; i < len; i++)
- {
- WebSocketFrame frame = new WebSocketFrame(opcode);
- mini = new byte[1];
- mini[0] = msg[i];
- frame.setPayload(mini);
- frame.setFin(!(i < (len - 1)));
- send.add(frame);
- }
+ fragmentText(send,msg);
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
List<WebSocketFrame> expect = new ArrayList<>();
@@ -309,18 +308,7 @@ public class TestABCase6 extends AbstractABCase
byte invalid[] = Hex.asByteArray("CEBAE1BDB9CF83CEBCCEB5EDA080656469746564");
List<WebSocketFrame> send = new ArrayList<>();
- int len = invalid.length;
- byte opcode = OpCode.TEXT;
- byte mini[];
- for (int i = 0; i < len; i++)
- {
- WebSocketFrame frame = new WebSocketFrame(opcode);
- mini = new byte[1];
- mini[0] = invalid[i];
- frame.setPayload(mini);
- frame.setFin(!(i < (len - 1)));
- send.add(frame);
- }
+ fragmentText(send,invalid);
send.add(new CloseInfo(StatusCode.NORMAL).asFrame());
List<WebSocketFrame> expect = new ArrayList<>();
diff --git a/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties b/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties
index 1610750775..880ca590b8 100644
--- a/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties
+++ b/jetty-websocket/websocket-server/src/test/resources/jetty-logging.properties
@@ -1,5 +1,6 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
org.eclipse.jetty.LEVEL=WARN
+# org.eclipse.jetty.io.ChannelEndPoint.LEVEL=INFO
org.eclipse.jetty.server.LEVEL=WARN
# org.eclipse.jetty.websocket.LEVEL=WARN
org.eclipse.jetty.websocket.server.helper.RFCSocket.LEVEL=OFF
@@ -10,6 +11,8 @@ org.eclipse.jetty.websocket.server.helper.RFCSocket.LEVEL=OFF
# org.eclipse.jetty.util.thread.QueuedThreadPool.LEVEL=DEBUG
# org.eclipse.jetty.io.SelectorManager.LEVEL=INFO
# org.eclipse.jetty.websocket.LEVEL=DEBUG
+# org.eclipse.jetty.websocket.io.FrameBytes.LEVEL=DEBUG
+# org.eclipse.jetty.websocket.io.ControlFrameBytes.LEVEL=DEBUG
# org.eclipse.jetty.websocket.driver.WebSocketEventDriver.LEVEL=DEBUG
# org.eclipse.jetty.websocket.extensions.LEVEL=DEBUG
# org.eclipse.jetty.websocket.protocol.Generator.LEVEL=INFO

Back to the top