QString andrq::getString(QDataStream &in, int key) { qint32 len; in >> len; char *data = (char *)qMalloc(len); in.readRawData(data, len); int dh = 0, dl = 0; int temp = key; dl |= temp & 0x000000FF; temp >>= 20; dh |= temp & 0x000000FF; /* if (!ans) return false;*/ int ah = 184; //10111000b; for (int i = 0; i < len; ++i) { int al = uchar(data[i]); al ^= ah; al=(al%32)*8+al/32; //циклический сдвиг al на 3 бита влево al ^= dh; al -= dl; data[i] = char(al); ah=(ah%8)*32+ah/8; //циклический сдвиг ah вправо на 3 бита } static QTextCodec *ansii_codec = QTextCodec::codecForName("cp1251"); static QTextCodec *utf8_codec = QTextCodec::codecForName("utf-8"); QTextCodec *codec = isValidUtf8(QByteArray::fromRawData(data, len)) ? utf8_codec : ansii_codec; QString result = codec->toUnicode(data, len); qFree(data); return result; }
bool isValidUtf8(const char *s, int maxLen, bool zeroInvalid) { return isValidUtf8(reinterpret_cast<const uchar *>(s), maxLen, zeroInvalid); }
void WebSocket::handleFragment(const char *fragment, size_t length, OpCode opCode, bool fin, size_t remainingBytes, bool compressed) { SocketData *socketData = (SocketData *) p->data; // Text or binary if (opCode < 3) { // permessage-deflate if (compressed) { socketData->pmd->setInput((char *) fragment, length); size_t bufferSpace; try { while (!(bufferSpace = socketData->pmd->inflate(socketData->server->inflateBuffer, Server::LARGE_BUFFER_SIZE))) { socketData->buffer.append(socketData->server->inflateBuffer, Server::LARGE_BUFFER_SIZE); } if (!remainingBytes && fin) { unsigned char tail[4] = {0, 0, 255, 255}; socketData->pmd->setInput((char *) tail, 4); if (!socketData->pmd->inflate(socketData->server->inflateBuffer + Server::LARGE_BUFFER_SIZE - bufferSpace, bufferSpace)) { socketData->buffer.append(socketData->server->inflateBuffer + Server::LARGE_BUFFER_SIZE - bufferSpace, bufferSpace); while (!(bufferSpace = socketData->pmd->inflate(socketData->server->inflateBuffer, Server::LARGE_BUFFER_SIZE))) { socketData->buffer.append(socketData->server->inflateBuffer, Server::LARGE_BUFFER_SIZE); } } } } catch (...) { close(true, 1006); return; } fragment = socketData->server->inflateBuffer; length = Server::LARGE_BUFFER_SIZE - bufferSpace; } if (!remainingBytes && fin && !socketData->buffer.length()) { if (opCode == 1 && !isValidUtf8((unsigned char *) fragment, length)) { close(true, 1006); return; } socketData->server->messageCallback(p, (char *) fragment, length, opCode); } else { socketData->buffer.append(fragment, socketData->server->maxPayload ? std::min(length, socketData->server->maxPayload - socketData->buffer.length()) : length); if (!remainingBytes && fin) { // Chapter 6 if (opCode == 1 && !isValidUtf8((unsigned char *) socketData->buffer.c_str(), socketData->buffer.length())) { close(true, 1006); return; } socketData->server->messageCallback(p, (char *) socketData->buffer.c_str(), socketData->buffer.length(), opCode); socketData->buffer.clear(); } } } else { socketData->controlBuffer.append(fragment, length); if (!remainingBytes && fin) { if (opCode == CLOSE) { std::tuple<unsigned short, char *, size_t> closeFrame = Parser::parseCloseFrame(socketData->controlBuffer); close(false, std::get<0>(closeFrame), std::get<1>(closeFrame), std::get<2>(closeFrame)); // leave the controlBuffer with the close frame intact return; } else { if (opCode == PING) { send((char *) socketData->controlBuffer.c_str(), socketData->controlBuffer.length(), OpCode::PONG); } else if (opCode == PONG) { socketData->server->pongCallback(p, (char *) socketData->controlBuffer.c_str(), socketData->controlBuffer.length()); } } socketData->controlBuffer.clear(); } } }