Cleaning up 'frames' package
This commit is contained in:
parent
b696915b29
commit
b9ca387d53
|
@ -86,7 +86,7 @@ public class WebSocketGeneratorRFC6455 implements WebSocketGenerator
|
||||||
boolean mask=_maskGen!=null;
|
boolean mask=_maskGen!=null;
|
||||||
|
|
||||||
if (_buffer==null)
|
if (_buffer==null)
|
||||||
_buffer=mask?_buffers.getBuffer():_buffers.getDirectBuffer();
|
_buffer=mask?_buffers.getData():_buffers.getDirectBuffer();
|
||||||
|
|
||||||
boolean last=WebSocketConnectionRFC6455.isLastFrame(flags);
|
boolean last=WebSocketConnectionRFC6455.isLastFrame(flags);
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class WebSocketParserRFC6455 implements WebSocketParser
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* @param buffers The buffers to use for parsing. Only the {@link Buffers#getBuffer()} is used.
|
* @param buffers The buffers to use for parsing. Only the {@link Buffers#getData()} is used.
|
||||||
* This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
|
* This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data
|
||||||
* is mostly used.
|
* is mostly used.
|
||||||
* @param endp the endpoint
|
* @param endp the endpoint
|
||||||
|
@ -139,7 +139,7 @@ public class WebSocketParserRFC6455 implements WebSocketParser
|
||||||
public int parseNext()
|
public int parseNext()
|
||||||
{
|
{
|
||||||
if (_buffer==null)
|
if (_buffer==null)
|
||||||
_buffer=_buffers.getBuffer();
|
_buffer=_buffers.getData();
|
||||||
|
|
||||||
boolean progress=false;
|
boolean progress=false;
|
||||||
int filled=-1;
|
int filled=-1;
|
||||||
|
@ -374,7 +374,7 @@ public class WebSocketParserRFC6455 implements WebSocketParser
|
||||||
if (buffer!=null && buffer.length()>0)
|
if (buffer!=null && buffer.length()>0)
|
||||||
{
|
{
|
||||||
if (_buffer==null)
|
if (_buffer==null)
|
||||||
_buffer=_buffers.getBuffer();
|
_buffer=_buffers.getData();
|
||||||
|
|
||||||
_buffer.put(buffer);
|
_buffer.put(buffer);
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
|
|
|
@ -23,19 +23,19 @@ public class WebSocket
|
||||||
*/
|
*/
|
||||||
private final static byte[] MAGIC;
|
private final static byte[] MAGIC;
|
||||||
|
|
||||||
public final static int CLOSE_NORMAL = 1000;
|
public final static short CLOSE_NORMAL = 1000;
|
||||||
public final static int CLOSE_SHUTDOWN = 1001;
|
public final static short CLOSE_SHUTDOWN = 1001;
|
||||||
public final static int CLOSE_PROTOCOL = 1002;
|
public final static short CLOSE_PROTOCOL = 1002;
|
||||||
public final static int CLOSE_BAD_DATA = 1003;
|
public final static short CLOSE_BAD_DATA = 1003;
|
||||||
public final static int CLOSE_UNDEFINED = 1004;
|
public final static short CLOSE_UNDEFINED = 1004;
|
||||||
public final static int CLOSE_NO_CODE = 1005;
|
public final static short CLOSE_NO_CODE = 1005;
|
||||||
public final static int CLOSE_NO_CLOSE = 1006;
|
public final static short CLOSE_NO_CLOSE = 1006;
|
||||||
public final static int CLOSE_BAD_PAYLOAD = 1007;
|
public final static short CLOSE_BAD_PAYLOAD = 1007;
|
||||||
public final static int CLOSE_POLICY_VIOLATION = 1008;
|
public final static short CLOSE_POLICY_VIOLATION = 1008;
|
||||||
public final static int CLOSE_MESSAGE_TOO_LARGE = 1009;
|
public final static short CLOSE_MESSAGE_TOO_LARGE = 1009;
|
||||||
public final static int CLOSE_REQUIRED_EXTENSION = 1010;
|
public final static short CLOSE_REQUIRED_EXTENSION = 1010;
|
||||||
public final static int CLOSE_SERVER_ERROR = 1011;
|
public final static short CLOSE_SERVER_ERROR = 1011;
|
||||||
public final static int CLOSE_FAILED_TLS_HANDSHAKE = 1015;
|
public final static short CLOSE_FAILED_TLS_HANDSHAKE = 1015;
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,16 +26,42 @@ package org.eclipse.jetty.websocket.frames;
|
||||||
*/
|
*/
|
||||||
public class BaseFrame
|
public class BaseFrame
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* OpCode for a {@link ContinuationFrame}
|
||||||
|
*
|
||||||
|
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
|
||||||
|
*/
|
||||||
public final static byte OP_CONTINUATION = 0x00;
|
public final static byte OP_CONTINUATION = 0x00;
|
||||||
|
/**
|
||||||
|
* OpCode for a {@link TextFrame}
|
||||||
|
*
|
||||||
|
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
|
||||||
|
*/
|
||||||
public final static byte OP_TEXT = 0x01;
|
public final static byte OP_TEXT = 0x01;
|
||||||
|
/**
|
||||||
|
* OpCode for a {@link BinaryFrame}
|
||||||
|
*
|
||||||
|
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
|
||||||
|
*/
|
||||||
public final static byte OP_BINARY = 0x02;
|
public final static byte OP_BINARY = 0x02;
|
||||||
public final static byte OP_EXT_DATA = 0x03;
|
/**
|
||||||
|
* OpCode for a {@link CloseFrame}
|
||||||
public final static byte OP_CONTROL = 0x08;
|
*
|
||||||
|
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
|
||||||
|
*/
|
||||||
public final static byte OP_CLOSE = 0x08;
|
public final static byte OP_CLOSE = 0x08;
|
||||||
|
/**
|
||||||
|
* OpCode for a {@link PingFrame}
|
||||||
|
*
|
||||||
|
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
|
||||||
|
*/
|
||||||
public final static byte OP_PING = 0x09;
|
public final static byte OP_PING = 0x09;
|
||||||
|
/**
|
||||||
|
* OpCode for a {@link PongFrame}
|
||||||
|
*
|
||||||
|
* @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
|
||||||
|
*/
|
||||||
public final static byte OP_PONG = 0x0A;
|
public final static byte OP_PONG = 0x0A;
|
||||||
public final static byte OP_EXT_CTRL = 0x0B;
|
|
||||||
|
|
||||||
private boolean fin;
|
private boolean fin;
|
||||||
private boolean rsv1;
|
private boolean rsv1;
|
||||||
|
@ -43,30 +69,35 @@ public class BaseFrame
|
||||||
private boolean rsv3;
|
private boolean rsv3;
|
||||||
private byte opcode = -1;
|
private byte opcode = -1;
|
||||||
private boolean masked = false;
|
private boolean masked = false;
|
||||||
|
|
||||||
private long payloadLength;
|
private long payloadLength;
|
||||||
private byte mask[];
|
private byte mask[];
|
||||||
|
|
||||||
public final static int FLAG_FIN = 0x8;
|
public final static int FLAG_FIN = 0x8;
|
||||||
public final static int FLAG_RSV1 = 0x4;
|
public final static int FLAG_RSV1 = 0x4;
|
||||||
public final static int FLAG_RSV2 = 0x2;
|
public final static int FLAG_RSV2 = 0x2;
|
||||||
public final static int FLAG_RSV3 = 0x1;
|
public final static int FLAG_RSV3 = 0x1;
|
||||||
|
|
||||||
/**
|
public BaseFrame() {
|
||||||
* @deprecated use {@link #isControlFrame()} instead
|
/* default */
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public static boolean isControlFrame(byte opcode)
|
|
||||||
{
|
|
||||||
return (opcode & OP_CONTROL) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated use {@link #isLastFrame()} instead
|
* Copy Constructor
|
||||||
|
* @param copy the copy
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
public BaseFrame(BaseFrame copy) {
|
||||||
public static boolean isLastFrame(byte flags)
|
this.fin = copy.fin;
|
||||||
{
|
this.rsv1 = copy.rsv1;
|
||||||
return (flags & FLAG_FIN) != 0;
|
this.rsv2 = copy.rsv2;
|
||||||
|
this.rsv3 = copy.rsv3;
|
||||||
|
this.opcode = copy.opcode;
|
||||||
|
this.masked = copy.masked;
|
||||||
|
this.payloadLength = copy.payloadLength;
|
||||||
|
if(copy.mask != null) {
|
||||||
|
int mlen = copy.mask.length;
|
||||||
|
this.mask = new byte[mlen];
|
||||||
|
System.arraycopy(copy.mask,0,this.mask,0,mlen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getMask()
|
public byte[] getMask()
|
||||||
|
@ -90,7 +121,7 @@ public class BaseFrame
|
||||||
|
|
||||||
public boolean isControlFrame()
|
public boolean isControlFrame()
|
||||||
{
|
{
|
||||||
return (opcode & OP_CONTROL) != 0;
|
return (opcode >= OP_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFin()
|
public boolean isFin()
|
||||||
|
|
|
@ -1,5 +1,69 @@
|
||||||
package org.eclipse.jetty.websocket.frames;
|
package org.eclipse.jetty.websocket.frames;
|
||||||
|
|
||||||
public class BinaryFrame {
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of a <a href="https://tools.ietf.org/html/rfc6455#section-5.6">Binary Data Frame (0x02)</a>.
|
||||||
|
*/
|
||||||
|
public class BinaryFrame extends BaseFrame
|
||||||
|
{
|
||||||
|
private ByteBuffer data; // TODO: make this a standard byte buffer?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default unspecified data
|
||||||
|
*/
|
||||||
|
public BinaryFrame()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
super.setOpcode(OP_BINARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy Constructor
|
||||||
|
*
|
||||||
|
* @param base
|
||||||
|
* the base frame to work off of.
|
||||||
|
*/
|
||||||
|
public BinaryFrame(BaseFrame base)
|
||||||
|
{
|
||||||
|
super(base);
|
||||||
|
// TODO: limit this somehow?
|
||||||
|
// TODO: create a streaming binary frame?
|
||||||
|
data = ByteBuffer.allocate((int)base.getPayloadLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data
|
||||||
|
*
|
||||||
|
* @return the raw bytebuffer data (can be null)
|
||||||
|
*/
|
||||||
|
public ByteBuffer getData()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data and payload length.
|
||||||
|
*
|
||||||
|
* @param buf
|
||||||
|
* the bytebuffer to set
|
||||||
|
*/
|
||||||
|
public void setData(byte buf[])
|
||||||
|
{
|
||||||
|
int len = buf.length;
|
||||||
|
this.data = ByteBuffer.allocate(len);
|
||||||
|
this.setPayloadLength(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data and payload length.
|
||||||
|
*
|
||||||
|
* @param buf
|
||||||
|
* the byte array to set
|
||||||
|
*/
|
||||||
|
public void setData(ByteBuffer buffer)
|
||||||
|
{
|
||||||
|
this.data = buffer;
|
||||||
|
this.setPayloadLength(buffer.capacity());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,52 @@
|
||||||
package org.eclipse.jetty.websocket.frames;
|
package org.eclipse.jetty.websocket.frames;
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.frames.ControlFrameType;
|
import org.eclipse.jetty.websocket.api.WebSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of a <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">Close Frame (0x08)</a>.
|
||||||
|
*/
|
||||||
public class CloseFrame extends ControlFrame
|
public class CloseFrame extends ControlFrame
|
||||||
{
|
{
|
||||||
private final int pingId;
|
private final short statusCode;
|
||||||
|
private String reason;
|
||||||
|
|
||||||
public CloseFrame(short version, int pingId)
|
public CloseFrame()
|
||||||
{
|
{
|
||||||
super(version, ControlFrameType.CLOSE_FRAME, (byte)0);
|
this(WebSocket.CLOSE_NORMAL); // TODO: evaluate default (or unspecified status code)
|
||||||
this.pingId = pingId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPingId()
|
public CloseFrame(short statusCode)
|
||||||
{
|
{
|
||||||
return pingId;
|
super(ControlFrameType.CLOSE_FRAME);
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason()
|
||||||
|
{
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getStatusCode()
|
||||||
|
{
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReason(String reason)
|
||||||
|
{
|
||||||
|
this.reason = reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return String.format("%s ping=%d", super.toString(), getPingId());
|
StringBuilder msg = new StringBuilder();
|
||||||
}
|
msg.append(super.toString());
|
||||||
|
msg.append(" statusCode=").append(statusCode);
|
||||||
|
if (reason != null)
|
||||||
|
{
|
||||||
|
msg.append(" reason=\"").append(reason).append("\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,27 @@
|
||||||
package org.eclipse.jetty.websocket.frames;
|
package org.eclipse.jetty.websocket.frames;
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.frames.ControlFrameType;
|
/**
|
||||||
|
* Base class for all <a href="https://tools.ietf.org/html/rfc6455#section-5.5">control frames</a>.
|
||||||
public class ControlFrame extends BaseFrame
|
* <p>
|
||||||
|
* TODO: investigate as candidate for removal.
|
||||||
|
*/
|
||||||
|
public abstract class ControlFrame extends BaseFrame
|
||||||
{
|
{
|
||||||
private final short _version;
|
private final ControlFrameType type;
|
||||||
private final ControlFrameType _type;
|
|
||||||
private final byte _flags; // check if needed
|
|
||||||
|
|
||||||
|
public ControlFrame(ControlFrameType type)
|
||||||
public ControlFrame( short version, ControlFrameType type, byte flags )
|
|
||||||
{
|
{
|
||||||
_version = version;
|
this.type = type;
|
||||||
_type = type;
|
|
||||||
_flags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getVersion()
|
|
||||||
{
|
|
||||||
return _version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControlFrameType getType()
|
public ControlFrameType getType()
|
||||||
{
|
{
|
||||||
return _type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return String.format("%s frame v%s", getType(), getVersion());
|
return String.format("%s frame v%s",getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package org.eclipse.jetty.websocket.frames;
|
package org.eclipse.jetty.websocket.frames;
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.frames.ControlFrameType;
|
/**
|
||||||
|
* Representation of a <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">Ping Frame (0x09)</a>.
|
||||||
|
*/
|
||||||
public class PingFrame extends ControlFrame
|
public class PingFrame extends ControlFrame
|
||||||
{
|
{
|
||||||
private final int pingId;
|
private final int pingId;
|
||||||
|
|
||||||
public PingFrame(short version, int pingId)
|
public PingFrame(int pingId)
|
||||||
{
|
{
|
||||||
super(version, ControlFrameType.PING_FRAME, (byte)0);
|
super(ControlFrameType.PING_FRAME);
|
||||||
this.pingId = pingId;
|
this.pingId = pingId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package org.eclipse.jetty.websocket.frames;
|
package org.eclipse.jetty.websocket.frames;
|
||||||
|
|
||||||
import org.eclipse.jetty.websocket.frames.ControlFrameType;
|
/**
|
||||||
|
* Representation of a <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">Pong Frame (0x0A)</a>.
|
||||||
|
*/
|
||||||
public class PongFrame extends ControlFrame
|
public class PongFrame extends ControlFrame
|
||||||
{
|
{
|
||||||
private final int pingId;
|
private final int pingId;
|
||||||
|
|
||||||
public PongFrame(short version, int pingId)
|
public PongFrame(int pingId)
|
||||||
{
|
{
|
||||||
super(version, ControlFrameType.PONG_FRAME, (byte)0);
|
super(ControlFrameType.PONG_FRAME);
|
||||||
this.pingId = pingId;
|
this.pingId = pingId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +21,6 @@ public class PongFrame extends ControlFrame
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return String.format("%s ping=%d", super.toString(), getPingId());
|
return String.format("%s pong=%d",super.toString(),getPingId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,65 @@
|
||||||
package org.eclipse.jetty.websocket.frames;
|
package org.eclipse.jetty.websocket.frames;
|
||||||
|
|
||||||
public class TextFrame {
|
/**
|
||||||
|
* Representation of a <a href="https://tools.ietf.org/html/rfc6455#section-5.6">Text Data Frame (0x01)</a>.
|
||||||
|
*/
|
||||||
|
public class TextFrame extends BaseFrame
|
||||||
|
{
|
||||||
|
private StringBuilder data = new StringBuilder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor (unspecified data)
|
||||||
|
*/
|
||||||
|
public TextFrame()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
super.setOpcode(OP_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy Constructor
|
||||||
|
*
|
||||||
|
* @param base
|
||||||
|
* the base frame to work off of.
|
||||||
|
*/
|
||||||
|
public TextFrame(BaseFrame copy)
|
||||||
|
{
|
||||||
|
super(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data
|
||||||
|
*
|
||||||
|
* @return the raw StringBuilder data (can be null)
|
||||||
|
*/
|
||||||
|
public StringBuilder getData()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data and payload length.
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* the String to set
|
||||||
|
*/
|
||||||
|
public void setData(String str)
|
||||||
|
{
|
||||||
|
int len = str.length();
|
||||||
|
this.data = new StringBuilder(str);
|
||||||
|
this.setPayloadLength(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data and payload length.
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* the StringBuilder to set
|
||||||
|
*/
|
||||||
|
public void setData(StringBuilder str)
|
||||||
|
{
|
||||||
|
int len = str.length();
|
||||||
|
this.data = str;
|
||||||
|
this.setPayloadLength(len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue