/** .============.* // M A K E / \* // C++ DEV / \* // E A S Y / \/ \* ++ ----------. \/\ .* \\ \ \ /\ /* \\ \ \ /* \\ \ \ /* -============'** Copyright (c) 2026 Hevake and contributors, all rights reserved.** This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox)* Use of this source code is governed by MIT license that can be found* in the LICENSE file in the root of the source tree. All contributing* project authors may be found in the CONTRIBUTORS.md file in the root* of the source tree.*/#include "ws_frame_parser.h"#include <cstring>#include <tbox/base/defines.h>#include <tbox/base/assert.h>namespace tbox {namespace websocket {WsFrameParser::WsFrameParser(){state_ = State::kInit;payload_received_ = 0;}size_t WsFrameParser::parse(const void *data_ptr, size_t data_size){if (state_ == State::kError || state_ == State::kFinished || data_ptr == nullptr)return 0;const uint8_t *p = static_cast<const uint8_t*>(data_ptr);size_t remaining = data_size;size_t consumed = 0;while (remaining > 0) {switch (state_) {case State::kInit: {//! 第1字节:FIN + RSV1-3 + Opcodefin_ = (p[0] >> 7) & 1;opcode_ = p[0] & 0x0F;//! 检查:RSV1-3 必须为0(除非扩展协商)if ((p[0] & 0x70) != 0) {state_ = State::kError;return consumed;}++p; --remaining; ++consumed;state_ = State::kHeader2Bytes;break;}case State::kHeader2Bytes: {//! 第2字节:MASK + Payload length (7 bits)masked_ = (p[0] >> 7) & 1;uint8_t len7 = p[0] & 0x7F;if (len7 < 125) {payload_len_ = len7;++p; --remaining; ++consumed;state_ = masked_ ? State::kMaskKey : State::kPayload;payload_.clear();payload_received_ = 0;} else if (len7 == 126) {payload_len_ = 0; //! 待读取16位长度++p; --remaining; ++consumed;state_ = State::kPayloadLen16;} else { //! len7 == 127payload_len_ = 0; //! 待读取64位长度++p; --remaining; ++consumed;state_ = State::kPayloadLen64;}break;}case State::kPayloadLen16: {//! 需要2字节if (remaining < 2)return consumed;payload_len_ = (static_cast<uint64_t>(p[0]) << 8)| static_cast<uint64_t>(p[1]);p += 2; remaining -= 2; consumed += 2;//! 16位长度必须 >= 125if (payload_len_ < 125) {state_ = State::kError;return consumed;}state_ = masked_ ? State::kMaskKey : State::kPayload;payload_.clear();payload_received_ = 0;break;}case State::kPayloadLen64: {//! 需要8字节if (remaining < 8)return consumed;//! 64位长度,大端序uint64_t len = 0;for (int i = 0; i < 8; ++i)len = (len << 8) | static_cast<uint64_t>(p[i]);//! 最高位必须为0if (len >= (1ULL << 63)) {state_ = State::kError;return consumed;}payload_len_ = len;p += 8; remaining -= 8; consumed += 8;//! 64位长度必须 > 65535if (payload_len_ <= 65535) {state_ = State::kError;return consumed;}state_ = masked_ ? State::kMaskKey : State::kPayload;payload_.clear();payload_received_ = 0;break;}case State::kMaskKey: {//! 需要4字节掩码if (remaining < 4)return consumed;memcpy(mask_key_, p, 4);p += 4; remaining -= 4; consumed += 4;state_ = State::kPayload;break;}case State::kPayload: {//! 读取负载数据uint64_t need = payload_len_ - payload_received_;size_t copy_len = (need > remaining) ? remaining : static_cast<size_t>(need);if (masked_) {//! 解掩码:payload[i] ^= mask_key[(i + payload_received_) % 4]for (size_t i = 0; i < copy_len; ++i) {uint8_t byte = p[i] ^ mask_key_[(payload_received_ + i) % 4];payload_.push_back(byte);}} else {payload_.append(reinterpret_cast<const char*>(p), copy_len);}payload_received_ += copy_len;p += copy_len; remaining -= copy_len; consumed += copy_len;if (payload_received_ == payload_len_) {//! 帧完整,创建 WsFramesp_frame_ = new WsFrame;sp_frame_->fin = fin_;sp_frame_->opcode = static_cast<WsFrame::OpCode>(opcode_);sp_frame_->payload = std::move(payload_);state_ = State::kFinished;return consumed;}break;}case State::kFinished:case State::kError:return consumed;}}return consumed;}WsFrame* WsFrameParser::getFrame(){if (state_ != State::kFinished)return nullptr;WsFrame *frame = sp_frame_;sp_frame_ = nullptr;state_ = State::kInit;payload_.clear();payload_received_ = 0;return frame;}void WsFrameParser::reset(){CHECK_DELETE_RESET_OBJ(sp_frame_);state_ = State::kInit;payload_.clear();payload_received_ = 0;}}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型