Making WebSocketFrame use builder pattern
This commit is contained in:
parent
20876011e0
commit
c2f1d23f2b
|
@ -199,4 +199,5 @@ public class WebSocketPolicy
|
|||
{
|
||||
this.maxTextMessageSize = maxTextMessageSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,26 +46,57 @@ public class Generator
|
|||
public static final int OVERHEAD = 28;
|
||||
|
||||
private final WebSocketPolicy policy;
|
||||
private static ByteBufferPool bufferPool;
|
||||
private final ByteBufferPool bufferPool;
|
||||
private boolean validating;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param policy
|
||||
* @deprecated discouraged usage form
|
||||
*/
|
||||
@Deprecated
|
||||
public Generator(WebSocketPolicy policy)
|
||||
{
|
||||
this.policy = policy;
|
||||
|
||||
if (this.bufferPool == null)
|
||||
{
|
||||
this.bufferPool = new StandardByteBufferPool();
|
||||
}
|
||||
this(policy,new StandardByteBufferPool());
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct Generator with provided policy and bufferPool
|
||||
*
|
||||
* @param policy
|
||||
* the policy to use
|
||||
* @param bufferPool
|
||||
* the buffer pool to use
|
||||
*/
|
||||
public Generator(WebSocketPolicy policy, ByteBufferPool bufferPool)
|
||||
{
|
||||
this(policy,bufferPool,true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct Generator with provided policy and bufferPool
|
||||
*
|
||||
* @param policy
|
||||
* the policy to use
|
||||
* @param bufferPool
|
||||
* the buffer pool to use
|
||||
* @param validating
|
||||
* true to enable RFC frame validation
|
||||
*/
|
||||
public Generator(WebSocketPolicy policy, ByteBufferPool bufferPool, boolean validating)
|
||||
{
|
||||
this.policy = policy;
|
||||
this.bufferPool = bufferPool;
|
||||
this.validating = validating;
|
||||
}
|
||||
|
||||
public void assertFrameValid(WebSocketFrame frame)
|
||||
{
|
||||
if (!validating)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 6455 Section 5.2
|
||||
*
|
||||
|
@ -262,11 +293,6 @@ public class Generator
|
|||
return generate(bufferSize,frame);
|
||||
}
|
||||
|
||||
public void init(ByteBufferPool pool)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.eclipse.jetty.websocket.protocol;
|
|||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.ProtocolException;
|
||||
|
@ -66,11 +67,42 @@ public class CloseInfo
|
|||
}
|
||||
}
|
||||
|
||||
public CloseInfo(int statusCode, String reason)
|
||||
{
|
||||
this.statusCode = statusCode;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public CloseInfo(WebSocketFrame frame)
|
||||
{
|
||||
this(frame.getPayload(),false);
|
||||
}
|
||||
|
||||
public ByteBuffer asByteBuffer()
|
||||
{
|
||||
if (statusCode != (-1))
|
||||
{
|
||||
ByteBuffer buf = ByteBuffer.allocate(WebSocketFrame.MAX_CONTROL_PAYLOAD);
|
||||
buf.putChar((char)statusCode);
|
||||
if (StringUtil.isNotBlank(reason))
|
||||
{
|
||||
byte utf[] = StringUtil.getUtf8Bytes(reason);
|
||||
buf.put(utf,0,utf.length);
|
||||
}
|
||||
BufferUtil.flipToFlush(buf,0);
|
||||
return buf;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public WebSocketFrame asFrame()
|
||||
{
|
||||
WebSocketFrame frame = new WebSocketFrame(OpCode.CLOSE);
|
||||
frame.setFin(true);
|
||||
frame.setPayload(asByteBuffer());
|
||||
return frame;
|
||||
}
|
||||
|
||||
public String getReason()
|
||||
{
|
||||
return reason;
|
||||
|
|
|
@ -18,9 +18,11 @@ import org.eclipse.jetty.websocket.generator.Generator;
|
|||
*/
|
||||
public class FrameBuilder
|
||||
{
|
||||
/**
|
||||
* A Generator that doesn't
|
||||
*/
|
||||
public class DirtyGenerator extends Generator
|
||||
{
|
||||
|
||||
public DirtyGenerator()
|
||||
{
|
||||
super(WebSocketPolicy.newServerPolicy(),bufferPool);
|
||||
|
@ -30,10 +32,9 @@ public class FrameBuilder
|
|||
public void assertFrameValid(WebSocketFrame frame)
|
||||
{
|
||||
/*
|
||||
* we desire the ability to craft bad frames so ignore frame validation
|
||||
* Do no validation of the frame validity. <p> we desire the ability to craft bad frames so we'll ignore frame validation
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static ByteBufferPool bufferPool = new StandardByteBufferPool();
|
||||
|
|
|
@ -34,7 +34,7 @@ public class WebSocketFrame implements Frame
|
|||
/** Maximum size of Control frame, per RFC 6455 */
|
||||
public static final int MAX_CONTROL_PAYLOAD = 125;
|
||||
|
||||
private boolean fin = false;
|
||||
private boolean fin = true;
|
||||
private boolean rsv1 = false;
|
||||
private boolean rsv2 = false;
|
||||
private boolean rsv3 = false;
|
||||
|
@ -215,7 +215,7 @@ public class WebSocketFrame implements Frame
|
|||
|
||||
public void reset()
|
||||
{
|
||||
fin = false;
|
||||
fin = true;
|
||||
rsv1 = false;
|
||||
rsv2 = false;
|
||||
rsv3 = false;
|
||||
|
@ -227,35 +227,41 @@ public class WebSocketFrame implements Frame
|
|||
continuation = false;
|
||||
}
|
||||
|
||||
public void setContinuation(boolean continuation)
|
||||
public WebSocketFrame setContinuation(boolean continuation)
|
||||
{
|
||||
this.continuation = continuation;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setContinuationIndex(int continuationIndex)
|
||||
public WebSocketFrame setContinuationIndex(int continuationIndex)
|
||||
{
|
||||
this.continuationIndex = continuationIndex;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setFin(boolean fin)
|
||||
public WebSocketFrame setFin(boolean fin)
|
||||
{
|
||||
this.fin = fin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setMask(byte[] maskingKey)
|
||||
public WebSocketFrame setMask(byte[] maskingKey)
|
||||
{
|
||||
this.mask = maskingKey;
|
||||
this.masked = (mask != null);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setMasked(boolean mask)
|
||||
public WebSocketFrame setMasked(boolean mask)
|
||||
{
|
||||
this.masked = mask;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setOpCode(OpCode opCode)
|
||||
public WebSocketFrame setOpCode(OpCode opCode)
|
||||
{
|
||||
this.opcode = opCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -264,12 +270,12 @@ public class WebSocketFrame implements Frame
|
|||
* @param buf
|
||||
* the bytebuffer to set
|
||||
*/
|
||||
public void setPayload(byte buf[])
|
||||
public WebSocketFrame setPayload(byte buf[])
|
||||
{
|
||||
if (buf == null)
|
||||
{
|
||||
data = null;
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (opcode.isControlFrame())
|
||||
|
@ -284,6 +290,7 @@ public class WebSocketFrame implements Frame
|
|||
data = ByteBuffer.allocate(len);
|
||||
BufferUtil.clearToFill(data);
|
||||
data.put(buf,0,len);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -292,12 +299,12 @@ public class WebSocketFrame implements Frame
|
|||
* @param buf
|
||||
* the bytebuffer to set
|
||||
*/
|
||||
public void setPayload(byte buf[], int offset, int len)
|
||||
public WebSocketFrame setPayload(byte buf[], int offset, int len)
|
||||
{
|
||||
if (buf == null)
|
||||
{
|
||||
data = null;
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (opcode.isControlFrame())
|
||||
|
@ -311,6 +318,7 @@ public class WebSocketFrame implements Frame
|
|||
data = ByteBuffer.allocate(len);
|
||||
BufferUtil.clearToFill(data);
|
||||
data.put(buf,0,len);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,12 +331,12 @@ public class WebSocketFrame implements Frame
|
|||
* @param buf
|
||||
* the bytebuffer to set
|
||||
*/
|
||||
public void setPayload(ByteBuffer buf)
|
||||
public WebSocketFrame setPayload(ByteBuffer buf)
|
||||
{
|
||||
if (buf == null)
|
||||
{
|
||||
data = null;
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (opcode.isControlFrame())
|
||||
|
@ -340,21 +348,25 @@ public class WebSocketFrame implements Frame
|
|||
}
|
||||
|
||||
data = buf.slice();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setRsv1(boolean rsv1)
|
||||
public WebSocketFrame setRsv1(boolean rsv1)
|
||||
{
|
||||
this.rsv1 = rsv1;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setRsv2(boolean rsv2)
|
||||
public WebSocketFrame setRsv2(boolean rsv2)
|
||||
{
|
||||
this.rsv2 = rsv2;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setRsv3(boolean rsv3)
|
||||
public WebSocketFrame setRsv3(boolean rsv3)
|
||||
{
|
||||
this.rsv3 = rsv3;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package org.eclipse.jetty.websocket.protocol;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.StandardByteBufferPool;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.websocket.ByteBufferAssert;
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.generator.Generator;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class WebSocketFrameTest
|
||||
{
|
||||
private static Generator strictGenerator;
|
||||
private static Generator laxGenerator;
|
||||
|
||||
@BeforeClass
|
||||
public static void initGenerator()
|
||||
{
|
||||
WebSocketPolicy policy = WebSocketPolicy.newServerPolicy();
|
||||
ByteBufferPool bufferPool = new StandardByteBufferPool();
|
||||
strictGenerator = new Generator(policy,bufferPool);
|
||||
laxGenerator = new Generator(policy,bufferPool,false);
|
||||
}
|
||||
|
||||
private void assertEqual(String message, ByteBuffer expected, ByteBuffer actual)
|
||||
{
|
||||
|
||||
BufferUtil.flipToFlush(actual,0);
|
||||
BufferUtil.flipToFlush(expected,0);
|
||||
|
||||
ByteBufferAssert.assertEquals(message,expected,actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaxInvalidClose()
|
||||
{
|
||||
WebSocketFrame frame = new WebSocketFrame(OpCode.CLOSE).setFin(false);
|
||||
ByteBuffer actual = laxGenerator.generate(frame);
|
||||
ByteBuffer expected = ByteBuffer.allocate(2);
|
||||
expected.put((byte)0x08);
|
||||
expected.put((byte)0x00);
|
||||
|
||||
assertEqual("Lax Invalid Close Frame",expected,actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaxInvalidPing()
|
||||
{
|
||||
WebSocketFrame frame = new WebSocketFrame(OpCode.PING).setFin(false);
|
||||
ByteBuffer actual = laxGenerator.generate(frame);
|
||||
ByteBuffer expected = ByteBuffer.allocate(2);
|
||||
expected.put((byte)0x09);
|
||||
expected.put((byte)0x00);
|
||||
|
||||
assertEqual("Lax Invalid Ping Frame",expected,actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStrictValidClose()
|
||||
{
|
||||
CloseInfo close = new CloseInfo(StatusCode.NORMAL,null);
|
||||
ByteBuffer actual = strictGenerator.generate(close.asFrame());
|
||||
ByteBuffer expected = ByteBuffer.allocate(4);
|
||||
expected.put((byte)0x88);
|
||||
expected.put((byte)0x02);
|
||||
expected.put((byte)0x03);
|
||||
expected.put((byte)0xE8);
|
||||
|
||||
assertEqual("Strict Valid Close Frame",expected,actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStrictValidPing()
|
||||
{
|
||||
WebSocketFrame frame = new WebSocketFrame(OpCode.PING);
|
||||
ByteBuffer actual = strictGenerator.generate(frame);
|
||||
ByteBuffer expected = ByteBuffer.allocate(2);
|
||||
expected.put((byte)0x89);
|
||||
expected.put((byte)0x00);
|
||||
|
||||
assertEqual("Strict Valid Ping Frame",expected,actual);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue