Fixed encoding of the length in case of binary messages.

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1438 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Simone Bordet 2010-04-02 08:03:42 +00:00
parent 529e04295f
commit f1c3f3e42c
3 changed files with 17 additions and 20 deletions

View File

@ -39,35 +39,25 @@ public class WebSocketGenerator
if (_buffer.space() == 0)
expelBuffer(blockFor);
bufferPut(frame, blockFor);
if (isLengthFrame(frame))
{
// Send a length delimited frame
_buffer.put(frame);
if (_buffer.space() == 0)
expelBuffer(blockFor);
// How many bytes we need for the length ?
// We have 7 bits available, so log2(length) / 7 + 1
// For example, 50000 bytes is 2 8-bytes: 11000011 01010000
// but we need to write it in 3 7-bytes 0000011 0000110 1010000
// 65536 == 1 00000000 00000000 => 100 0000000 0000000
int lengthBytes = new BigInteger(String.valueOf(length)).bitLength() / 7 + 1;
for (int i = lengthBytes - 1; i >= 0; --i)
for (int i = lengthBytes - 1; i > 0; --i)
{
byte lengthByte = (byte)(0x80 | (0x7F & (length >> 7 * i)));
_buffer.put(lengthByte);
if (_buffer.space() == 0)
expelBuffer(blockFor);
bufferPut(lengthByte, blockFor);
}
bufferPut((byte)(0x7F & length), blockFor);
}
else
{
_buffer.put(frame);
}
if (_buffer.space() == 0)
expelBuffer(blockFor);
int remaining = length;
while (remaining > 0)
@ -97,11 +87,18 @@ public class WebSocketGenerator
}
}
private boolean isLengthFrame(byte frame)
private synchronized boolean isLengthFrame(byte frame)
{
return (frame & WebSocket.LENGTH_FRAME) == WebSocket.LENGTH_FRAME;
}
private synchronized void bufferPut(byte datum, long blockFor) throws IOException
{
_buffer.put(datum);
if (_buffer.space() == 0)
expelBuffer(blockFor);
}
public synchronized void addFrame(byte frame, String content, int blockFor) throws IOException
{
byte[] bytes = content.getBytes("UTF-8");

View File

@ -57,7 +57,7 @@ public class WebSocketGeneratorTest extends TestCase
_generator.addFrame((byte)0x84,"Hell\uFF4F W\uFF4Frld".getBytes(StringUtil.__UTF8),0);
_generator.flush();
assertEquals(0x84,0xff&_out.get());
assertEquals(0x80|15,0xff&_out.get());
assertEquals(15,0xff&_out.get());
assertEquals('H',_out.get());
assertEquals('e',_out.get());
assertEquals('l',_out.get());
@ -86,7 +86,7 @@ public class WebSocketGeneratorTest extends TestCase
_generator.flush();
assertEquals(0x85,0xff&_out.get());
assertEquals(0x80|(b.length>>7),0xff&_out.get());
assertEquals(0x80|(0x7f&b.length),0xff&_out.get());
assertEquals(0x7f&b.length,0xff&_out.get());
for (int i=0;i<b.length;i++)
assertEquals('0'+(i%10),0xff&_out.get());
}

View File

@ -134,7 +134,7 @@ public class WebSocketMessageTest extends TestCase
byte[] data = message.toString().getBytes("UTF-8");
_serverWebSocket.outbound.sendMessage(WebSocket.LENGTH_FRAME, data);
// I know the format of the message will be: 0x80 0x84 0x80 0x80 ...
// Length of the message is 65536, so the length will be encoded as 0x84 0x80 0x00
int frame = input.read();
assertEquals(0x80, frame);
int length1 = input.read();
@ -142,7 +142,7 @@ public class WebSocketMessageTest extends TestCase
int length2 = input.read();
assertEquals(0x80, length2);
int length3 = input.read();
assertEquals(0x80, length3);
assertEquals(0x00, length3);
int read = 0;
while (read < data.length)
{