com.alipay.api.java_websocket.drafts.Draft_6455 Maven / Gradle / Ivy
/*
* Copyright (c) 2010-2018 Nathan Rajlich
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package com.alipay.api.java_websocket.drafts;
import com.alipay.api.java_websocket.WebSocketImpl;
import com.alipay.api.java_websocket.enums.*;
import com.alipay.api.java_websocket.exceptions.*;
import com.alipay.api.java_websocket.extensions.DefaultExtension;
import com.alipay.api.java_websocket.extensions.IExtension;
import com.alipay.api.java_websocket.framing.*;
import com.alipay.api.java_websocket.handshake.*;
import com.alipay.api.java_websocket.protocols.IProtocol;
import com.alipay.api.java_websocket.protocols.Protocol;
import com.alipay.api.java_websocket.util.Base64;
import com.alipay.api.java_websocket.util.Charsetfunctions;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Implementation for the RFC 6455 websocket protocol This is the recommended class for your websocket connection
*/
public class Draft_6455 extends Draft {
/**
* Attribute for the used extension in this draft
*/
private IExtension extension = new DefaultExtension();
/**
* Attribute for all available extension in this draft
*/
private List knownExtensions;
/**
* Attribute for the used protocol in this draft
*/
private IProtocol protocol;
/**
* Attribute for all available protocols in this draft
*/
private List knownProtocols;
/**
* Attribute for the current continuous frame
*/
private Framedata current_continuous_frame;
/**
* Attribute for the payload of the current continuous frame
*/
private List byteBufferList;
/**
* Attribute for the current incomplete frame
*/
private ByteBuffer incompleteframe;
/**
* Attribute for the reusable random instance
*/
private final Random reuseableRandom = new Random();
/**
* Constructor for the websocket protocol specified by RFC 6455 with default extensions
*
* @since 1.3.5
*/
public Draft_6455() {
this(Collections.emptyList());
}
/**
* Constructor for the websocket protocol specified by RFC 6455 with custom extensions
*
* @param inputExtension the extension which should be used for this draft
* @since 1.3.5
*/
public Draft_6455(IExtension inputExtension) {
this(Collections.singletonList(inputExtension));
}
/**
* Constructor for the websocket protocol specified by RFC 6455 with custom extensions
*
* @param inputExtensions the extensions which should be used for this draft
* @since 1.3.5
*/
public Draft_6455(List inputExtensions) {
this(inputExtensions, Collections.singletonList(new Protocol("")));
}
/**
* Constructor for the websocket protocol specified by RFC 6455 with custom extensions and protocols
*
* @param inputExtensions the extensions which should be used for this draft
* @param inputProtocols the protocols which should be used for this draft
* @since 1.3.7
*/
public Draft_6455(List inputExtensions, List inputProtocols) {
if (inputExtensions == null || inputProtocols == null) {
throw new IllegalArgumentException();
}
knownExtensions = new ArrayList(inputExtensions.size());
knownProtocols = new ArrayList(inputProtocols.size());
boolean hasDefault = false;
byteBufferList = new ArrayList();
for (IExtension inputExtension : inputExtensions) {
if (inputExtension.getClass().equals(DefaultExtension.class)) {
hasDefault = true;
}
}
knownExtensions.addAll(inputExtensions);
//We always add the DefaultExtension to implement the normal RFC 6455 specification
if (!hasDefault) {
knownExtensions.add(this.knownExtensions.size(), extension);
}
knownProtocols.addAll(inputProtocols);
}
public HandshakeState acceptHandshakeAsServer(ClientHandshake handshakedata) throws InvalidHandshakeException {
int v = readVersion(handshakedata);
if (v != 13) {
return HandshakeState.NOT_MATCHED;
}
HandshakeState extensionState = HandshakeState.NOT_MATCHED;
String requestedExtension = handshakedata.getFieldValue("Sec-WebSocket-Extensions");
for (IExtension knownExtension : knownExtensions) {
if (knownExtension.acceptProvidedExtensionAsServer(requestedExtension)) {
extension = knownExtension;
extensionState = HandshakeState.MATCHED;
break;
}
}
HandshakeState protocolState = HandshakeState.NOT_MATCHED;
String requestedProtocol = handshakedata.getFieldValue("Sec-WebSocket-Protocol");
for (IProtocol knownProtocol : knownProtocols) {
if (knownProtocol.acceptProvidedProtocol(requestedProtocol)) {
protocol = knownProtocol;
protocolState = HandshakeState.MATCHED;
break;
}
}
if (protocolState == HandshakeState.MATCHED && extensionState == HandshakeState.MATCHED) {
return HandshakeState.MATCHED;
}
return HandshakeState.NOT_MATCHED;
}
public HandshakeState acceptHandshakeAsClient(ClientHandshake request, ServerHandshake response) throws InvalidHandshakeException {
if (!basicAccept(response)) {
return HandshakeState.NOT_MATCHED;
}
if (!request.hasFieldValue("Sec-WebSocket-Key") || !response.hasFieldValue("Sec-WebSocket-Accept")) {
return HandshakeState.NOT_MATCHED;
}
String seckey_answere = response.getFieldValue("Sec-WebSocket-Accept");
String seckey_challenge = request.getFieldValue("Sec-WebSocket-Key");
seckey_challenge = generateFinalKey(seckey_challenge);
if (!seckey_challenge.equals(seckey_answere)) {
return HandshakeState.NOT_MATCHED;
}
HandshakeState extensionState = HandshakeState.NOT_MATCHED;
String requestedExtension = response.getFieldValue("Sec-WebSocket-Extensions");
for (IExtension knownExtension : knownExtensions) {
if (knownExtension.acceptProvidedExtensionAsClient(requestedExtension)) {
extension = knownExtension;
extensionState = HandshakeState.MATCHED;
break;
}
}
HandshakeState protocolState = HandshakeState.NOT_MATCHED;
String requestedProtocol = response.getFieldValue("Sec-WebSocket-Protocol");
for (IProtocol knownProtocol : knownProtocols) {
if (knownProtocol.acceptProvidedProtocol(requestedProtocol)) {
protocol = knownProtocol;
protocolState = HandshakeState.MATCHED;
break;
}
}
if (protocolState == HandshakeState.MATCHED && extensionState == HandshakeState.MATCHED) {
return HandshakeState.MATCHED;
}
return HandshakeState.NOT_MATCHED;
}
/**
* Getter for the extension which is used by this draft
*
* @return the extension which is used or null, if handshake is not yet done
*/
public IExtension getExtension() {
return extension;
}
/**
* Getter for all available extensions for this draft
*
* @return the extensions which are enabled for this draft
*/
public List getKnownExtensions() {
return knownExtensions;
}
/**
* Getter for the protocol which is used by this draft
*
* @return the protocol which is used or null, if handshake is not yet done or no valid protocols
* @since 1.3.7
*/
public IProtocol getProtocol() {
return protocol;
}
/**
* Getter for all available protocols for this draft
*
* @return the protocols which are enabled for this draft
* @since 1.3.7
*/
public List getKnownProtocols() {
return knownProtocols;
}
public ClientHandshakeBuilder postProcessHandshakeRequestAsClient(ClientHandshakeBuilder request) {
request.put("Upgrade", "websocket");
request.put("Connection", "Upgrade"); // to respond to a Connection keep alives
byte[] random = new byte[16];
reuseableRandom.nextBytes(random);
request.put("Sec-WebSocket-Key", Base64.encodeBytes(random));
request.put("Sec-WebSocket-Version", "13");// overwriting the previous
StringBuilder requestedExtensions = new StringBuilder();
for (IExtension knownExtension : knownExtensions) {
if (knownExtension.getProvidedExtensionAsClient() != null && knownExtension.getProvidedExtensionAsClient().length() != 0) {
if (requestedExtensions.length() > 0) {
requestedExtensions.append(", ");
}
requestedExtensions.append(knownExtension.getProvidedExtensionAsClient());
}
}
if (requestedExtensions.length() != 0) {
request.put("Sec-WebSocket-Extensions", requestedExtensions.toString());
}
StringBuilder requestedProtocols = new StringBuilder();
for (IProtocol knownProtocol : knownProtocols) {
if (knownProtocol.getProvidedProtocol().length() != 0) {
if (requestedProtocols.length() > 0) {
requestedProtocols.append(", ");
}
requestedProtocols.append(knownProtocol.getProvidedProtocol());
}
}
if (requestedProtocols.length() != 0) {
request.put("Sec-WebSocket-Protocol", requestedProtocols.toString());
}
return request;
}
public HandshakeBuilder postProcessHandshakeResponseAsServer(ClientHandshake request, ServerHandshakeBuilder response) throws
InvalidHandshakeException {
response.put("Upgrade", "websocket");
response.put("Connection", request.getFieldValue("Connection")); // to respond to a Connection keep alives
String seckey = request.getFieldValue("Sec-WebSocket-Key");
if (seckey == null) { throw new InvalidHandshakeException("missing Sec-WebSocket-Key"); }
response.put("Sec-WebSocket-Accept", generateFinalKey(seckey));
if (getExtension().getProvidedExtensionAsServer().length() != 0) {
response.put("Sec-WebSocket-Extensions", getExtension().getProvidedExtensionAsServer());
}
if (getProtocol() != null && getProtocol().getProvidedProtocol().length() != 0) {
response.put("Sec-WebSocket-Protocol", getProtocol().getProvidedProtocol());
}
response.setHttpStatusMessage("Web Socket Protocol Handshake");
response.put("Server", "TooTallNate Java-WebSocket");
response.put("Date", getServerTime());
return response;
}
public Draft copyInstance() {
ArrayList newExtensions = new ArrayList();
for (IExtension extension : getKnownExtensions()) {
newExtensions.add(extension.copyInstance());
}
ArrayList newProtocols = new ArrayList();
for (IProtocol protocol : getKnownProtocols()) {
newProtocols.add(protocol.copyInstance());
}
Draft_6455 draft = new Draft_6455(newExtensions, newProtocols);
draft.setCharset(getCharset());
return draft;
}
public ByteBuffer createBinaryFrame(Framedata framedata) {
getExtension().encodeFrame(framedata);
return createByteBufferFromFramedata(framedata);
}
private ByteBuffer createByteBufferFromFramedata(Framedata framedata) {
ByteBuffer mes = framedata.getPayloadData();
boolean mask = role == Role.CLIENT; // framedata.getTransfereMasked();
int sizebytes = mes.remaining() <= 125 ? 1 : mes.remaining() <= 65535 ? 2 : 8;
ByteBuffer buf = ByteBuffer.allocate(1 + (sizebytes > 1 ? sizebytes + 1 : sizebytes) + (mask ? 4 : 0) + mes.remaining());
byte optcode = fromOpcode(framedata.getOpcode());
byte one = (byte) (framedata.isFin() ? -128 : 0);
one |= optcode;
buf.put(one);
byte[] payloadlengthbytes = toByteArray(mes.remaining(), sizebytes);
assert (payloadlengthbytes.length == sizebytes);
if (sizebytes == 1) {
buf.put((byte) (payloadlengthbytes[0] | (mask ? (byte) -128 : 0)));
} else if (sizebytes == 2) {
buf.put((byte) ((byte) 126 | (mask ? (byte) -128 : 0)));
buf.put(payloadlengthbytes);
} else if (sizebytes == 8) {
buf.put((byte) ((byte) 127 | (mask ? (byte) -128 : 0)));
buf.put(payloadlengthbytes);
} else { throw new RuntimeException("Size representation not supported/specified"); }
if (mask) {
ByteBuffer maskkey = ByteBuffer.allocate(4);
maskkey.putInt(reuseableRandom.nextInt());
buf.put(maskkey.array());
for (int i = 0; mes.hasRemaining(); i++) {
buf.put((byte) (mes.get() ^ maskkey.get(i % 4)));
}
} else {
buf.put(mes);
//Reset the position of the bytebuffer e.g. for additional use
mes.flip();
}
assert (buf.remaining() == 0) : buf.remaining();
buf.flip();
return buf;
}
public Framedata translateSingleFrame(ByteBuffer buffer) throws IncompleteException, InvalidDataException {
int maxpacketsize = buffer.remaining();
int realpacketsize = 2;
if (maxpacketsize < realpacketsize) {
throw new IncompleteException(realpacketsize);
}
byte b1 = buffer.get( /*0*/);
boolean FIN = b1 >> 8 != 0;
boolean rsv1 = false;
boolean rsv2 = false;
boolean rsv3 = false;
if ((b1 & 0x40) != 0) {
rsv1 = true;
}
if ((b1 & 0x20) != 0) {
rsv2 = true;
}
if ((b1 & 0x10) != 0) {
rsv3 = true;
}
byte b2 = buffer.get( /*1*/);
boolean MASK = (b2 & -128) != 0;
int payloadlength = (byte) (b2 & ~(byte) 128);
Opcode optcode = toOpcode((byte) (b1 & 15));
if (!(payloadlength >= 0 && payloadlength <= 125)) {
if (optcode == Opcode.PING || optcode == Opcode.PONG || optcode == Opcode.CLOSING) {
throw new InvalidFrameException("more than 125 octets");
}
if (payloadlength == 126) {
realpacketsize += 2; // additional length bytes
if (maxpacketsize < realpacketsize) {
throw new IncompleteException(realpacketsize);
}
byte[] sizebytes = new byte[3];
sizebytes[1] = buffer.get( /*1 + 1*/);
sizebytes[2] = buffer.get( /*1 + 2*/);
payloadlength = new BigInteger(sizebytes).intValue();
} else {
realpacketsize += 8; // additional length bytes
if (maxpacketsize < realpacketsize) {
throw new IncompleteException(realpacketsize);
}
byte[] bytes = new byte[8];
for (int i = 0; i < 8; i++) {
bytes[i] = buffer.get( /*1 + i*/);
}
long length = new BigInteger(bytes).longValue();
if (length > Integer.MAX_VALUE) {
throw new LimitExedeedException("Payloadsize is to big...");
} else {
payloadlength = (int) length;
}
}
}
// int maskskeystart = foff + realpacketsize;
realpacketsize += (MASK ? 4 : 0);
// int payloadstart = foff + realpacketsize;
realpacketsize += payloadlength;
if (maxpacketsize < realpacketsize) { throw new IncompleteException(realpacketsize); }
ByteBuffer payload = ByteBuffer.allocate(checkAlloc(payloadlength));
if (MASK) {
byte[] maskskey = new byte[4];
buffer.get(maskskey);
for (int i = 0; i < payloadlength; i++) {
payload.put((byte) (buffer.get( /*payloadstart + i*/) ^ maskskey[i % 4]));
}
} else {
payload.put(buffer.array(), buffer.position(), payload.limit());
buffer.position(buffer.position() + payload.limit());
}
FramedataImpl1 frame = FramedataImpl1.get(optcode);
frame.setFin(FIN);
frame.setRSV1(rsv1);
frame.setRSV2(rsv2);
frame.setRSV3(rsv3);
payload.flip();
frame.setPayload(payload);
getExtension().isFrameValid(frame);
getExtension().decodeFrame(frame);
frame.isValid();
return frame;
}
public List translateFrame(ByteBuffer buffer) throws InvalidDataException {
while (true) {
List frames = new LinkedList();
Framedata cur;
if (incompleteframe != null) {
// complete an incomplete frame
try {
buffer.mark();
int available_next_byte_count = buffer.remaining();// The number of bytes received
int expected_next_byte_count = incompleteframe.remaining();// The number of bytes to complete the incomplete frame
if (expected_next_byte_count > available_next_byte_count) {
// did not receive enough bytes to complete the frame
incompleteframe.put(buffer.array(), buffer.position(), available_next_byte_count);
buffer.position(buffer.position() + available_next_byte_count);
return Collections.emptyList();
}
incompleteframe.put(buffer.array(), buffer.position(), expected_next_byte_count);
buffer.position(buffer.position() + expected_next_byte_count);
cur = translateSingleFrame((ByteBuffer) incompleteframe.duplicate().position(0));
frames.add(cur);
incompleteframe = null;
} catch (IncompleteException e) {
// extending as much as suggested
ByteBuffer extendedframe = ByteBuffer.allocate(checkAlloc(e.getPreferredSize()));
assert (extendedframe.limit() > incompleteframe.limit());
incompleteframe.rewind();
extendedframe.put(incompleteframe);
incompleteframe = extendedframe;
continue;
}
}
while (buffer.hasRemaining()) {// Read as much as possible full frames
buffer.mark();
try {
cur = translateSingleFrame(buffer);
frames.add(cur);
} catch (IncompleteException e) {
// remember the incomplete data
buffer.reset();
int pref = e.getPreferredSize();
incompleteframe = ByteBuffer.allocate(checkAlloc(pref));
incompleteframe.put(buffer);
break;
}
}
return frames;
}
}
public List createFrames(ByteBuffer binary, boolean mask) {
BinaryFrame curframe = new BinaryFrame();
curframe.setPayload(binary);
curframe.setTransferemasked(mask);
try {
curframe.isValid();
} catch (InvalidDataException e) {
throw new NotSendableException(e);
}
return Collections.singletonList((Framedata) curframe);
}
public List createFrames(String text, boolean mask) {
TextFrame curframe = new TextFrame();
curframe.setPayload(ByteBuffer.wrap(Charsetfunctions.charsetBytes(text, getCharset())));
curframe.setTransferemasked(mask);
try {
curframe.isValid();
} catch (InvalidDataException e) {
throw new NotSendableException(e);
}
return Collections.singletonList((Framedata) curframe);
}
public void reset() {
incompleteframe = null;
if (extension != null) {
extension.reset();
}
extension = new DefaultExtension();
protocol = null;
}
/**
* Generate a date for for the date-header
*
* @return the server time
*/
private String getServerTime() {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat(
"EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
return dateFormat.format(calendar.getTime());
}
/**
* Generate a final key from a input string
*
* @param in the input string
* @return a final key
*/
private String generateFinalKey(String in) {
String seckey = in.trim();
String acc = seckey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
MessageDigest sh1;
try {
sh1 = MessageDigest.getInstance("SHA1");
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException(e);
}
return Base64.encodeBytes(sh1.digest(acc.getBytes()));
}
private byte[] toByteArray(long val, int bytecount) {
byte[] buffer = new byte[bytecount];
int highest = 8 * bytecount - 8;
for (int i = 0; i < bytecount; i++) {
buffer[i] = (byte) (val >>> (highest - 8 * i));
}
return buffer;
}
private byte fromOpcode(Opcode opcode) {
if (opcode == Opcode.CONTINUOUS) { return 0; } else if (opcode == Opcode.TEXT) { return 1; } else if (opcode == Opcode.BINARY) {
return 2;
} else if (opcode == Opcode.CLOSING) {
return 8;
} else if (opcode == Opcode.PING) {
return 9;
} else if (opcode == Opcode.PONG) {
return 10;
}
throw new IllegalArgumentException("Don't know how to handle " + opcode.toString());
}
private Opcode toOpcode(byte opcode) throws InvalidFrameException {
switch (opcode) {
case 0:
return Opcode.CONTINUOUS;
case 1:
return Opcode.TEXT;
case 2:
return Opcode.BINARY;
// 3-7 are not yet defined
case 8:
return Opcode.CLOSING;
case 9:
return Opcode.PING;
case 10:
return Opcode.PONG;
// 11-15 are not yet defined
default:
throw new InvalidFrameException("Unknown opcode " + (short) opcode);
}
}
public void processFrame(WebSocketImpl webSocketImpl, Framedata frame) throws InvalidDataException {
Opcode curop = frame.getOpcode();
if (curop == Opcode.CLOSING) {
int code = CloseFrame.NOCODE;
String reason = "";
if (frame instanceof CloseFrame) {
CloseFrame cf = (CloseFrame) frame;
code = cf.getCloseCode();
reason = cf.getMessage();
}
if (webSocketImpl.getReadyState() == ReadyState.CLOSING) {
// complete the close handshake by disconnecting
webSocketImpl.closeConnection(code, reason, true);
} else {
// echo close handshake
if (getCloseHandshakeType() == CloseHandshakeType.TWOWAY) { webSocketImpl.close(code, reason, true); } else {
webSocketImpl.flushAndClose(code, reason, false);
}
}
} else if (curop == Opcode.PING) {
webSocketImpl.getWebSocketListener().onWebsocketPing(webSocketImpl, frame);
} else if (curop == Opcode.PONG) {
webSocketImpl.updateLastPong();
webSocketImpl.getWebSocketListener().onWebsocketPong(webSocketImpl, frame);
} else if (!frame.isFin() || curop == Opcode.CONTINUOUS) {
if (curop != Opcode.CONTINUOUS) {
if (current_continuous_frame != null) {
throw new InvalidDataException(CloseFrame.PROTOCOL_ERROR, "Previous continuous frame sequence not completed.");
}
current_continuous_frame = frame;
byteBufferList.add(frame.getPayloadData());
} else if (frame.isFin()) {
if (current_continuous_frame == null) {
throw new InvalidDataException(CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started.");
}
byteBufferList.add(frame.getPayloadData());
if (current_continuous_frame.getOpcode() == Opcode.TEXT) {
((FramedataImpl1) current_continuous_frame).setPayload(getPayloadFromByteBufferList());
((FramedataImpl1) current_continuous_frame).isValid();
try {
webSocketImpl.getWebSocketListener().onWebsocketMessage(webSocketImpl, Charsetfunctions
.stringCharset(current_continuous_frame.getPayloadData(), getCharset()));
} catch (RuntimeException e) {
webSocketImpl.getWebSocketListener().onWebsocketError(webSocketImpl, e);
}
} else if (current_continuous_frame.getOpcode() == Opcode.BINARY) {
((FramedataImpl1) current_continuous_frame).setPayload(getPayloadFromByteBufferList());
((FramedataImpl1) current_continuous_frame).isValid();
try {
webSocketImpl.getWebSocketListener().onWebsocketMessage(webSocketImpl, current_continuous_frame.getPayloadData());
} catch (RuntimeException e) {
webSocketImpl.getWebSocketListener().onWebsocketError(webSocketImpl, e);
}
}
current_continuous_frame = null;
byteBufferList.clear();
} else if (current_continuous_frame == null) {
throw new InvalidDataException(CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started.");
}
//Check if the whole payload is valid utf8, when the opcode indicates a text
if (curop == Opcode.TEXT) {
if (!Charsetfunctions.isValidUTF8(frame.getPayloadData())) {
throw new InvalidDataException(CloseFrame.NO_UTF8);
}
}
//Checking if the current continuous frame contains a correct payload with the other frames combined
if (curop == Opcode.CONTINUOUS && current_continuous_frame != null) {
byteBufferList.add(frame.getPayloadData());
}
} else if (current_continuous_frame != null) {
throw new InvalidDataException(CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence not completed.");
} else if (curop == Opcode.TEXT) {
try {
webSocketImpl.getWebSocketListener().onWebsocketMessage(webSocketImpl, Charsetfunctions
.stringCharset(frame.getPayloadData(), getCharset()));
} catch (RuntimeException e) {
webSocketImpl.getWebSocketListener().onWebsocketError(webSocketImpl, e);
}
} else if (curop == Opcode.BINARY) {
try {
webSocketImpl.getWebSocketListener().onWebsocketMessage(webSocketImpl, frame.getPayloadData());
} catch (RuntimeException e) {
webSocketImpl.getWebSocketListener().onWebsocketError(webSocketImpl, e);
}
} else {
throw new InvalidDataException(CloseFrame.PROTOCOL_ERROR, "non control or continious frame expected");
}
}
public CloseHandshakeType getCloseHandshakeType() {
return CloseHandshakeType.TWOWAY;
}
public String toString() {
String result = super.toString();
if (getExtension() != null) { result += " extension: " + getExtension().toString(); }
if (getProtocol() != null) { result += " protocol: " + getProtocol().toString(); }
return result;
}
public boolean equals(Object o) {
if (this == o) { return true; }
if (o == null || getClass() != o.getClass()) { return false; }
Draft_6455 that = (Draft_6455) o;
if (extension != null ? !extension.equals(that.extension) : that.extension != null) { return false; }
return protocol != null ? protocol.equals(that.protocol) : that.protocol == null;
}
public int hashCode() {
int result = extension != null ? extension.hashCode() : 0;
result = 31 * result + (protocol != null ? protocol.hashCode() : 0);
return result;
}
/**
* Method to generate a full bytebuffer out of all the fragmented frame payload
*
* @return a bytebuffer containing all the data
* @throws LimitExedeedException will be thrown when the totalSize is bigger then Integer.MAX_VALUE due to not being able to allocate
* more
*/
private ByteBuffer getPayloadFromByteBufferList() throws LimitExedeedException {
long totalSize = 0;
for (ByteBuffer buffer : byteBufferList) {
totalSize += buffer.limit();
}
if (totalSize > Integer.MAX_VALUE) {
throw new LimitExedeedException("Payloadsize is to big...");
}
ByteBuffer resultingByteBuffer = ByteBuffer.allocate((int) totalSize);
for (ByteBuffer buffer : byteBufferList) {
resultingByteBuffer.put(buffer);
}
resultingByteBuffer.flip();
return resultingByteBuffer;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy