Working TextFrame parsing (with masking)

This commit is contained in:
Joakim Erdfelt 2012-06-19 15:03:43 -07:00
parent 763b0b500d
commit dcfa524211
4 changed files with 93 additions and 6 deletions

View File

@ -57,9 +57,20 @@ public abstract class FrameParser<T extends BaseFrame>
protected int copyBuffer(ByteBuffer src, ByteBuffer dest, int length)
{
int amt = Math.min(length,src.remaining());
byte b[] = new byte[amt];
src.get(b,0,amt);
dest.put(b,0,amt);
if (getFrame().isMasked())
{
byte mask[] = getFrame().getMask();
for (int i = 0; i < amt; i++)
{
dest.put((byte)(src.get() ^ mask[i % 4]));
}
}
else
{
byte b[] = new byte[amt];
src.get(b,0,amt);
dest.put(b,0,amt);
}
return amt;
}

View File

@ -2,12 +2,15 @@ package org.eclipse.jetty.websocket.parser;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.websocket.api.WebSocketSettings;
import org.eclipse.jetty.websocket.frames.TextFrame;
public class TextPayloadParser extends FrameParser<TextFrame>
{
private TextFrame frame;
private ByteBuffer payload;
private int payloadLength;
public TextPayloadParser(WebSocketSettings settings)
{
@ -22,9 +25,25 @@ public class TextPayloadParser extends FrameParser<TextFrame>
}
@Override
public boolean parsePayload(ByteBuffer buf)
public boolean parsePayload(ByteBuffer buffer)
{
// TODO Auto-generated method stub
payloadLength = getFrame().getPayloadLength();
while (buffer.hasRemaining())
{
if (payload == null)
{
payload = ByteBuffer.allocate(payloadLength);
}
copyBuffer(buffer,payload,payloadLength);
if (payload.position() >= payloadLength)
{
payload.flip();
frame.setData(BufferUtil.toString(payload));
return true;
}
}
return false;
}
@ -32,5 +51,6 @@ public class TextPayloadParser extends FrameParser<TextFrame>
public void reset()
{
super.reset();
payloadLength = 0;
}
}

View File

@ -6,7 +6,7 @@ import org.eclipse.jetty.websocket.ByteBufferAssert;
import org.eclipse.jetty.websocket.frames.PingFrame;
import org.junit.Test;
public class PingParserTest
public class PingPayloadParserTest
{
@Test
public void testBasicPingParsing()

View File

@ -0,0 +1,56 @@
package org.eclipse.jetty.websocket.parser;
import static org.hamcrest.Matchers.*;
import java.nio.ByteBuffer;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.Debug;
import org.eclipse.jetty.websocket.frames.TextFrame;
import org.junit.Assert;
import org.junit.Test;
public class TextPayloadParserTest
{
private final byte[] mask = new byte[]
{ 0x00, (byte)0xF0, 0x0F, (byte)0xFF };
@Test
public void testShortMaskedText() throws Exception
{
Debug.enableDebugLogging(Parser.class);
Debug.enableDebugLogging(TextPayloadParser.class);
String expectedText = "Hello World";
ByteBuffer buf = ByteBuffer.allocate(24);
buf.put((byte)0x81);
buf.put((byte)(0x80 | expectedText.length()));
writeMask(buf);
writeMasked(buf,expectedText.getBytes(StringUtil.__UTF8));
buf.flip();
Parser parser = new Parser();
FrameParseCapture capture = new FrameParseCapture();
parser.addListener(capture);
parser.parse(buf);
capture.assertNoErrors();
capture.assertHasFrame(TextFrame.class,1);
TextFrame txt = (TextFrame)capture.getFrames().get(0);
Assert.assertThat("TextFrame.data",txt.getData().toString(),is("Hello World"));
}
private void writeMask(ByteBuffer buf)
{
buf.put(mask,0,mask.length);
}
private void writeMasked(ByteBuffer buf, byte[] bytes)
{
int len = bytes.length;
for (int i = 0; i < len; i++)
{
buf.put((byte)(bytes[i] ^ mask[i % 4]));
}
}
}