| 651 | } |
| 652 | |
| 653 | Result HttpWebSocketFrameReader::parse(Span<char> data, size_t& consumedBytes) |
| 654 | { |
| 655 | consumedBytes = 0; |
| 656 | while (consumedBytes < data.sizeInBytes()) |
| 657 | { |
| 658 | const uint8_t current = static_cast<uint8_t>(data[consumedBytes]); |
| 659 | switch (state) |
| 660 | { |
| 661 | case State::HeaderByte0: |
| 662 | headerByte0 = current; |
| 663 | consumedBytes++; |
| 664 | state = State::HeaderByte1; |
| 665 | break; |
| 666 | |
| 667 | case State::HeaderByte1: { |
| 668 | const uint8_t opcodeValue = headerByte0 & 0x0F; |
| 669 | SC_TRY_MSG((headerByte0 & 0x70) == 0, "HttpWebSocketFrameReader RSV bits are not supported"); |
| 670 | currentFrame = {}; |
| 671 | currentFrame.fin = (headerByte0 & 0x80) != 0; |
| 672 | currentFrame.opcode = static_cast<HttpWebSocketOpcode>(opcodeValue); |
| 673 | SC_TRY_MSG(scHttpWebSocketIsSupportedOpcode(currentFrame.opcode), |
| 674 | "HttpWebSocketFrameReader unsupported opcode"); |
| 675 | |
| 676 | currentFrame.masked = (current & 0x80) != 0; |
| 677 | const uint8_t payloadLengthField = current & 0x7F; |
| 678 | |
| 679 | extendedLengthAccumulator = 0; |
| 680 | extendedLengthBytesRead = 0; |
| 681 | maskBytesRead = 0; |
| 682 | |
| 683 | consumedBytes++; |
| 684 | |
| 685 | if (payloadLengthField < 126) |
| 686 | { |
| 687 | currentFrame.payloadLength = payloadLengthField; |
| 688 | if (currentFrame.masked) |
| 689 | { |
| 690 | state = State::MaskKey; |
| 691 | } |
| 692 | else |
| 693 | { |
| 694 | SC_TRY(onHeaderReady()); |
| 695 | } |
| 696 | } |
| 697 | else |
| 698 | { |
| 699 | extendedLengthBytesExpected = payloadLengthField == 126 ? 2 : 8; |
| 700 | state = State::ExtendedLength; |
| 701 | } |
| 702 | break; |
| 703 | } |
| 704 | |
| 705 | case State::ExtendedLength: |
| 706 | SC_TRY_MSG(not(extendedLengthBytesExpected == 8 and extendedLengthBytesRead == 0 and (current & 0x80) != 0), |
| 707 | "HttpWebSocketFrameReader invalid 64-bit payload length"); |
| 708 | extendedLengthAccumulator = (extendedLengthAccumulator << 8) | current; |
| 709 | extendedLengthBytesRead++; |
| 710 | consumedBytes++; |
no test coverage detected