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 993e411b334..7e720679a2c 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 @@ -5,6 +5,8 @@ import static org.hamcrest.Matchers.*; import java.nio.ByteBuffer; import java.util.Arrays; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.junit.Assert; import org.junit.Test; @@ -43,4 +45,71 @@ public class GeneratorTest Assert.assertThat("Created Parts",totalParts,is(expectedParts)); Assert.assertThat("Created Bytes",totalBytes,is(payload.length + expectedHeaderSize)); } + + @Test + public void testWindowedGenerateWithMasking() + { + byte payload[] = new byte[10240]; + Arrays.fill(payload,(byte)0x55); + + byte mask[] = new byte[] + { 0x2A, (byte)0xF0, 0x0F, 0x00 }; + + WebSocketFrame frame = WebSocketFrame.binary(payload); + frame.setMask(mask); + + int totalParts = 0; + int totalBytes = 0; + int windowSize = 2929; // important, use an odd # window size to test masking across window barriers + int expectedHeaderSize = 8; + int expectedParts = (int)Math.ceil((double)(payload.length + expectedHeaderSize) / windowSize); + + // Buffer to capture generated bytes + ByteBuffer completeBuf = ByteBuffer.allocate(payload.length + expectedHeaderSize); + BufferUtil.clearToFill(completeBuf); + + // Generate and capture generator output + Generator generator = new UnitGenerator(); + + boolean done = false; + while (!done) + { + Assert.assertThat("Too many parts",totalParts,lessThan(20)); + + ByteBuffer buf = generator.generate(windowSize,frame); + // System.out.printf("Generated buf.limit() = %,d%n",buf.limit()); + + totalBytes += buf.remaining(); + totalParts++; + + BufferUtil.put(buf,completeBuf); + + done = (frame.remaining() <= 0); + } + + Assert.assertThat("Created Parts",totalParts,is(expectedParts)); + Assert.assertThat("Created Bytes",totalBytes,is(payload.length + expectedHeaderSize)); + + // Parse complete buffer. + WebSocketPolicy policy = WebSocketPolicy.newServerPolicy(); + Parser parser = new Parser(policy); + FrameParseCapture capture = new FrameParseCapture(); + parser.setIncomingFramesHandler(capture); + + BufferUtil.flipToFlush(completeBuf,0); + parser.parse(completeBuf); + + // Assert validity of frame + WebSocketFrame actual = capture.getFrames().get(0); + Assert.assertThat("Frame.opcode",actual.getOpCode(),is(OpCode.BINARY)); + Assert.assertThat("Frame.payloadLength",actual.getPayloadLength(),is(payload.length)); + + // Validate payload content for proper masking + ByteBuffer actualData = actual.getPayload().slice(); + Assert.assertThat("Frame.payload.remaining",actualData.remaining(),is(payload.length)); + while (actualData.remaining() > 0) + { + Assert.assertThat("Actual.payload[" + actualData.position() + "]",actualData.get(),is((byte)0x55)); + } + } }