Merge branch 'jetty-9' of ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project into jetty-9
This commit is contained in:
commit
3bebb2e0a4
|
@ -20,9 +20,9 @@ import org.eclipse.jetty.websocket.io.MessageInputStream;
|
|||
import org.eclipse.jetty.websocket.io.MessageReader;
|
||||
import org.eclipse.jetty.websocket.io.StreamAppender;
|
||||
import org.eclipse.jetty.websocket.parser.Parser;
|
||||
import org.eclipse.jetty.websocket.protocol.CloseInfo;
|
||||
import org.eclipse.jetty.websocket.protocol.Frame;
|
||||
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||
import org.eclipse.jetty.websocket.util.CloseUtil;
|
||||
|
||||
/**
|
||||
* Responsible for routing the internally generated events destined for a specific WebSocket instance to whatever choice of development style the developer has
|
||||
|
@ -134,10 +134,8 @@ public class WebSocketEventDriver implements Parser.Listener
|
|||
// not interested in close events
|
||||
return;
|
||||
}
|
||||
byte payload[] = frame.getPayloadData();
|
||||
int statusCode = CloseUtil.getStatusCode(payload);
|
||||
String reason = CloseUtil.getReason(payload);
|
||||
events.onClose.call(websocket,connection,statusCode,reason);
|
||||
CloseInfo close = new CloseInfo(frame);
|
||||
events.onClose.call(websocket,connection,close.getStatusCode(),close.getReason());
|
||||
return;
|
||||
}
|
||||
case BINARY:
|
||||
|
|
|
@ -77,13 +77,22 @@ public class FrameParser
|
|||
}
|
||||
policy.assertValidPayloadLength((int)len);
|
||||
|
||||
if (frame.getOpCode().isControlFrame())
|
||||
switch (frame.getOpCode())
|
||||
{
|
||||
if (payloadLength > WebSocketFrame.MAX_CONTROL_PAYLOAD)
|
||||
{
|
||||
throw new ProtocolException("Invalid Control Frame payload length, [" + payloadLength + "] cannot exceed ["
|
||||
+ WebSocketFrame.MAX_CONTROL_PAYLOAD + "]");
|
||||
}
|
||||
case CLOSE:
|
||||
if (payloadLength == 1)
|
||||
{
|
||||
throw new ProtocolException("Invalid close frame payload length, [" + payloadLength + "]");
|
||||
}
|
||||
// fall thru
|
||||
case PING:
|
||||
case PONG:
|
||||
if (payloadLength > WebSocketFrame.MAX_CONTROL_PAYLOAD)
|
||||
{
|
||||
throw new ProtocolException("Invalid control frame payload length, [" + payloadLength + "] cannot exceed ["
|
||||
+ WebSocketFrame.MAX_CONTROL_PAYLOAD + "]");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
package org.eclipse.jetty.websocket.util;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.websocket.api.ProtocolException;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.protocol.WebSocketFrame;
|
||||
|
||||
public class CloseUtil
|
||||
{
|
||||
public static void assertValidPayload(WebSocketFrame frame)
|
||||
{
|
||||
byte payload[] = frame.getPayloadData();
|
||||
|
||||
if (payload.length < 2)
|
||||
{
|
||||
return; // no status code
|
||||
}
|
||||
|
||||
int statusCode = getStatusCode(payload);
|
||||
|
||||
// Validate value
|
||||
if ((statusCode < StatusCode.NORMAL) || (statusCode == StatusCode.UNDEFINED) || (statusCode == StatusCode.NO_CLOSE)
|
||||
|| (statusCode == StatusCode.NO_CODE) || ((statusCode > 1011) && (statusCode <= 2999)) || (statusCode >= 5000))
|
||||
{
|
||||
throw new ProtocolException("Invalid close code: " + statusCode);
|
||||
}
|
||||
|
||||
// validate reason
|
||||
getReason(payload);
|
||||
}
|
||||
|
||||
public static String getReason(byte[] payload)
|
||||
{
|
||||
if (payload.length <= 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ByteBuffer bb = ByteBuffer.wrap(payload);
|
||||
int len = payload.length - 2;
|
||||
byte utf[] = new byte[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
utf[i] = bb.get(i + 2);
|
||||
}
|
||||
return StringUtil.toUTF8String(utf,0,utf.length);
|
||||
}
|
||||
|
||||
public static int getStatusCode(byte[] payload)
|
||||
{
|
||||
|
||||
int statusCode = 0;
|
||||
ByteBuffer bb = ByteBuffer.wrap(payload);
|
||||
statusCode |= (bb.get(0) & 0xFF) << 8;
|
||||
statusCode |= (bb.get(1) & 0xFF);
|
||||
return statusCode;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
package org.eclipse.jetty.websocket.ab;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.websocket.ByteBufferAssert;
|
||||
|
@ -93,11 +94,11 @@ public class TestABCase7_3
|
|||
parser.addListener(capture);
|
||||
parser.parse(expected);
|
||||
|
||||
Assert.assertEquals( "error on invalid close payload", 1, capture.getErrorCount(WebSocketException.class)) ;
|
||||
Assert.assertEquals("error on invalid close payload",1,capture.getErrorCount(ProtocolException.class));
|
||||
|
||||
WebSocketException known = capture.getErrors().get(0);
|
||||
ProtocolException known = (ProtocolException)capture.getErrors().get(0);
|
||||
|
||||
Assert.assertTrue("invalid payload should be in message",known.getMessage().contains("invalid payload length"));
|
||||
Assert.assertThat("Payload.message",known.getMessage(),containsString("Invalid close frame payload length"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -307,25 +308,32 @@ public class TestABCase7_3
|
|||
@Test
|
||||
public void testCase7_3_6ParseCloseWithInvalidStatusReason()
|
||||
{
|
||||
StringBuilder message = new StringBuilder();
|
||||
for ( int i = 0 ; i < 124 ; ++i )
|
||||
{
|
||||
message.append("*");
|
||||
}
|
||||
byte[] messageBytes = new byte[124];
|
||||
Arrays.fill(messageBytes,(byte)'*');
|
||||
|
||||
byte[] messageBytes = message.toString().getBytes();
|
||||
ByteBuffer expected = ByteBuffer.allocate(256);
|
||||
|
||||
ByteBuffer expected = ByteBuffer.allocate(132);
|
||||
byte b;
|
||||
|
||||
expected.put(new byte[]
|
||||
{ (byte)0x88 });
|
||||
byte b = 0x00; // no masking
|
||||
|
||||
b |= (messageBytes.length + 2) & 0x7F;
|
||||
// fin + op
|
||||
b = 0x00;
|
||||
b |= 0x80; // fin on
|
||||
b |= 0x08; // close
|
||||
expected.put(b);
|
||||
expected.putShort((short)1000);
|
||||
|
||||
expected.put(messageBytes);
|
||||
// mask + len
|
||||
b = 0x00;
|
||||
b |= 0x00; // no masking
|
||||
b |= 0x7E; // 2 byte len
|
||||
expected.put(b);
|
||||
|
||||
// 2 byte len
|
||||
expected.putChar((char)(messageBytes.length + 2));
|
||||
|
||||
// payload
|
||||
expected.putShort((short)1000); // status code
|
||||
expected.put(messageBytes); // reason
|
||||
|
||||
expected.flip();
|
||||
|
||||
Parser parser = new Parser(policy);
|
||||
|
@ -333,10 +341,10 @@ public class TestABCase7_3
|
|||
parser.addListener(capture);
|
||||
parser.parse(expected);
|
||||
|
||||
Assert.assertEquals( "error on invalid close payload", 1, capture.getErrorCount(WebSocketException.class)) ;
|
||||
Assert.assertEquals("error on invalid close payload",1,capture.getErrorCount(ProtocolException.class));
|
||||
|
||||
WebSocketException known = capture.getErrors().get(0);
|
||||
ProtocolException known = (ProtocolException)capture.getErrors().get(0);
|
||||
|
||||
Assert.assertTrue("invalid payload should be in message",known.getMessage().contains("invalid payload length"));
|
||||
Assert.assertThat("Payload.message",known.getMessage(),containsString("Invalid control frame payload length"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue