in GaiaXAndroidClientToStudio/src/main/java/com/alibaba/gaiax/studio/third/socket/java_websocket/WebSocketImpl.java [242:379]
private boolean decodeHandshake(ByteBuffer socketBufferNew) {
ByteBuffer socketBuffer;
if (tmpHandshakeBytes.capacity() == 0) {
socketBuffer = socketBufferNew;
} else {
if (tmpHandshakeBytes.remaining() < socketBufferNew.remaining()) {
ByteBuffer buf = ByteBuffer.allocate(tmpHandshakeBytes.capacity() + socketBufferNew.remaining());
tmpHandshakeBytes.flip();
buf.put(tmpHandshakeBytes);
tmpHandshakeBytes = buf;
}
tmpHandshakeBytes.put(socketBufferNew);
tmpHandshakeBytes.flip();
socketBuffer = tmpHandshakeBytes;
}
socketBuffer.mark();
try {
HandshakeState handshakestate;
try {
if (role == Role.SERVER) {
if (draft == null) {
for (Draft d : knownDrafts) {
d = d.copyInstance();
try {
d.setParseMode(role);
socketBuffer.reset();
Handshakedata tmphandshake = d.translateHandshake(socketBuffer);
if (!(tmphandshake instanceof ClientHandshake)) {
Log.e("GaiaX.Socket", "Closing due to wrong handshake");
closeConnectionDueToWrongHandshake(new InvalidDataException(CloseFrame.PROTOCOL_ERROR, "wrong http function"));
return false;
}
ClientHandshake handshake = (ClientHandshake) tmphandshake;
handshakestate = d.acceptHandshakeAsServer(handshake);
if (handshakestate == HandshakeState.MATCHED) {
resourceDescriptor = handshake.getResourceDescriptor();
ServerHandshakeBuilder response;
try {
response = wsl.onWebsocketHandshakeReceivedAsServer(this, d, handshake);
} catch (InvalidDataException e) {
Log.e("GaiaX.Socket", "Closing due to wrong handshake. Possible handshake rejection", e);
closeConnectionDueToWrongHandshake(e);
return false;
} catch (RuntimeException e) {
Log.e("GaiaX.Socket", "Closing due to internal server error", e);
wsl.onWebsocketError(this, e);
closeConnectionDueToInternalServerError(e);
return false;
}
write(d.createHandshake(d.postProcessHandshakeResponseAsServer(handshake, response)));
draft = d;
open(handshake);
return true;
}
} catch (InvalidHandshakeException e) {
// go on with an other draft
}
}
if (draft == null) {
Log.e("GaiaX.Socket", "Closing due to protocol error: no draft matches");
closeConnectionDueToWrongHandshake(new InvalidDataException(CloseFrame.PROTOCOL_ERROR, "no draft matches"));
}
return false;
} else {
// special case for multiple step handshakes
Handshakedata tmphandshake = draft.translateHandshake(socketBuffer);
if (!(tmphandshake instanceof ClientHandshake)) {
Log.e("GaiaX.Socket", "Closing due to protocol error: wrong http function");
flushAndClose(CloseFrame.PROTOCOL_ERROR, "wrong http function", false);
return false;
}
ClientHandshake handshake = (ClientHandshake) tmphandshake;
handshakestate = draft.acceptHandshakeAsServer(handshake);
if (handshakestate == HandshakeState.MATCHED) {
open(handshake);
return true;
} else {
Log.e("GaiaX.Socket", "Closing due to protocol error: the handshake did finally not match");
close(CloseFrame.PROTOCOL_ERROR, "the handshake did finally not match");
}
return false;
}
} else if (role == Role.CLIENT) {
draft.setParseMode(role);
Handshakedata tmphandshake = draft.translateHandshake(socketBuffer);
if (!(tmphandshake instanceof ServerHandshake)) {
Log.e("GaiaX.Socket", "Closing due to protocol error: wrong http function");
flushAndClose(CloseFrame.PROTOCOL_ERROR, "wrong http function", false);
return false;
}
ServerHandshake handshake = (ServerHandshake) tmphandshake;
handshakestate = draft.acceptHandshakeAsClient(handshakerequest, handshake);
if (handshakestate == HandshakeState.MATCHED) {
try {
wsl.onWebsocketHandshakeReceivedAsClient(this, handshakerequest, handshake);
} catch (InvalidDataException e) {
Log.e("GaiaX.Socket", "Closing due to invalid data exception. Possible handshake rejection", e);
flushAndClose(e.getCloseCode(), e.getMessage(), false);
return false;
} catch (RuntimeException e) {
Log.e("GaiaX.Socket", "Closing since client was never connected", e);
wsl.onWebsocketError(this, e);
flushAndClose(CloseFrame.NEVER_CONNECTED, e.getMessage(), false);
return false;
}
open(handshake);
return true;
} else {
Log.e("GaiaX.Socket", "Closing due to protocol error: draft {} refuses handshake");
close(CloseFrame.PROTOCOL_ERROR, "draft " + draft + " refuses handshake");
}
}
} catch (InvalidHandshakeException e) {
Log.e("GaiaX.Socket", "Closing due to invalid handshake", e);
close(e);
}
} catch (IncompleteHandshakeException e) {
if (tmpHandshakeBytes.capacity() == 0) {
socketBuffer.reset();
int newsize = e.getPreferredSize();
if (newsize == 0) {
newsize = socketBuffer.capacity() + 16;
} else {
assert (e.getPreferredSize() >= socketBuffer.remaining());
}
tmpHandshakeBytes = ByteBuffer.allocate(newsize);
tmpHandshakeBytes.put(socketBufferNew);
// tmpHandshakeBytes.flip();
} else {
tmpHandshakeBytes.position(tmpHandshakeBytes.limit());
tmpHandshakeBytes.limit(tmpHandshakeBytes.capacity());
}
}
return false;
}