public void close(InvalidDataException e) { close(e.getCloseCode(), e.getMessage(), false); }
/** * Returns whether the handshake phase has is completed. In case of a broken handshake this will * be never the case. */ 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 { if (draft == null) { HandshakeState isflashedgecase = isFlashEdgeCase(socketBuffer); if (isflashedgecase == HandshakeState.MATCHED) { try { write(ByteBuffer.wrap(Charsetfunctions.utf8Bytes(wsl.getFlashPolicy(this)))); close(CloseFrame.FLASHPOLICY, ""); } catch (InvalidDataException e) { close( CloseFrame.ABNORMAL_CLOSE, "remote peer closed connection before flashpolicy could be transmitted", true); } return false; } } HandshakeState handshakestate = null; 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 == false) { flushAndClose(CloseFrame.PROTOCOL_ERROR, "wrong http function", false); 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) { flushAndClose(e.getCloseCode(), e.getMessage(), false); return false; } catch (RuntimeException e) { wsl.onWebsocketError(this, e); flushAndClose(CloseFrame.NEVER_CONNECTED, e.getMessage(), false); return false; } write( d.createHandshake( d.postProcessHandshakeResponseAsServer(handshake, response), role)); draft = d; open(handshake); return true; } } catch (InvalidHandshakeException e) { // go on with an other draft } } if (draft == null) { close(CloseFrame.PROTOCOL_ERROR, "no draft matches"); } return false; } else { // special case for multiple step handshakes Handshakedata tmphandshake = draft.translateHandshake(socketBuffer); if (tmphandshake instanceof ClientHandshake == false) { 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 { close(CloseFrame.PROTOCOL_ERROR, "the handshake did finaly not match"); } return false; } } else if (role == Role.CLIENT) { draft.setParseMode(role); Handshakedata tmphandshake = draft.translateHandshake(socketBuffer); if (tmphandshake instanceof ServerHandshake == false) { 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) { flushAndClose(e.getCloseCode(), e.getMessage(), false); return false; } catch (RuntimeException e) { wsl.onWebsocketError(this, e); flushAndClose(CloseFrame.NEVER_CONNECTED, e.getMessage(), false); return false; } open(handshake); return true; } else { close(CloseFrame.PROTOCOL_ERROR, "draft " + draft + " refuses handshake"); } } } catch (InvalidHandshakeException e) { close(e); } } catch (IncompleteHandshakeException e) { if (tmpHandshakeBytes.capacity() == 0) { socketBuffer.reset(); int newsize = e.getPreferedSize(); if (newsize == 0) { newsize = socketBuffer.capacity() + 16; } else { assert (e.getPreferedSize() >= socketBuffer.remaining()); } tmpHandshakeBytes = ByteBuffer.allocate(newsize); tmpHandshakeBytes.put(socketBufferNew); // tmpHandshakeBytes.flip(); } else { tmpHandshakeBytes.position(tmpHandshakeBytes.limit()); tmpHandshakeBytes.limit(tmpHandshakeBytes.capacity()); } } return false; }