| 87 | } |
| 88 | |
| 89 | void ProtocolWebSocket::parse(Socket *sock, QIODevice *io) const |
| 90 | { |
| 91 | qint64 bytesAvailable = io->bytesAvailable(); |
| 92 | const auto *request = static_cast<ProtoRequestHttp *>(sock->protoData); |
| 93 | |
| 94 | Q_FOREVER |
| 95 | { |
| 96 | if (!bytesAvailable || !request->websocket_need || |
| 97 | (bytesAvailable < request->websocket_need && |
| 98 | request->websocket_phase != ProtoRequestHttp::WebSocketPhase::WebSocketPhasePayload)) { |
| 99 | // Need more data |
| 100 | return; |
| 101 | } |
| 102 | |
| 103 | quint32 maxlen = qMin(request->websocket_need, static_cast<quint32>(m_postBufferSize)); |
| 104 | qint64 len = io->read(m_postBuffer, maxlen); |
| 105 | if (len == -1) { |
| 106 | qCWarning(C_SERVER_WS) << "Failed to read from socket" << io->errorString(); |
| 107 | sock->connectionClose(); |
| 108 | return; |
| 109 | } |
| 110 | bytesAvailable -= len; |
| 111 | |
| 112 | switch (request->websocket_phase) { |
| 113 | case ProtoRequestHttp::WebSocketPhase::WebSocketPhaseHeaders: |
| 114 | if (!websocket_parse_header(sock, m_postBuffer, io)) { |
| 115 | return; |
| 116 | } |
| 117 | break; |
| 118 | case ProtoRequestHttp::WebSocketPhase::WebSocketPhaseSize: |
| 119 | if (!websocket_parse_size(sock, m_postBuffer, m_websockets_max_size)) { |
| 120 | return; |
| 121 | } |
| 122 | break; |
| 123 | case ProtoRequestHttp::WebSocketPhase::WebSocketPhaseMask: |
| 124 | websocket_parse_mask(sock, m_postBuffer, io); |
| 125 | break; |
| 126 | case ProtoRequestHttp::WebSocketPhase::WebSocketPhasePayload: |
| 127 | if (!websocket_parse_payload(sock, m_postBuffer, int(len), io)) { |
| 128 | return; |
| 129 | } |
| 130 | break; |
| 131 | default: |
| 132 | Q_UNREACHABLE(); |
| 133 | break; |
| 134 | } |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | ProtocolData *ProtocolWebSocket::createData(Socket *sock) const |
nothing calls this directly
no test coverage detected