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:
parent
529e04295f
commit
f1c3f3e42c
|
@ -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");
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue