| 837 | } |
| 838 | } |
| 839 | |
| 840 | void HttpWebSocketFrameReader::reset(HttpWebSocketEndpointRole role) |
| 841 | { |
| 842 | endpointRole = role; |
| 843 | currentFrame = {}; |
| 844 | |
| 845 | state = State::HeaderByte0; |
| 846 | |
| 847 | fragmentedMessageInProgress = false; |
| 848 | |
| 849 | headerByte0 = 0; |
| 850 | |
| 851 | extendedLengthBytesExpected = 0; |
| 852 | extendedLengthBytesRead = 0; |
| 853 | maskBytesRead = 0; |
| 854 | |
| 855 | extendedLengthAccumulator = 0; |
| 856 | payloadBytesRemaining = 0; |
| 857 | payloadBytesConsumed = 0; |
| 858 | } |
| 859 | |
| 860 | Result HttpWebSocketFrameReader::parse(Span<char> data, size_t& consumedBytes) |
| 861 | { |
| 862 | consumedBytes = 0; |
| 863 | while (consumedBytes < data.sizeInBytes()) |
| 864 | { |
| 865 | const uint8_t current = static_cast<uint8_t>(data[consumedBytes]); |
| 866 | switch (state) |
| 867 | { |
| 868 | case State::HeaderByte0: |
| 869 | headerByte0 = current; |
| 870 | consumedBytes++; |
| 871 | state = State::HeaderByte1; |
| 872 | break; |
| 873 | |
| 874 | case State::HeaderByte1: { |
| 875 | const uint8_t opcodeValue = headerByte0 & 0x0F; |
| 876 | SC_TRY_MSG((headerByte0 & 0x70) == 0, "HttpWebSocketFrameReader RSV bits are not supported"); |
| 877 | currentFrame = {}; |
| 878 | currentFrame.fin = (headerByte0 & 0x80) != 0; |
| 879 | currentFrame.opcode = static_cast<HttpWebSocketOpcode>(opcodeValue); |
| 880 | SC_TRY_MSG(scHttpWebSocketIsSupportedOpcode(currentFrame.opcode), |
| 881 | "HttpWebSocketFrameReader unsupported opcode"); |
| 882 | |
| 883 | currentFrame.masked = (current & 0x80) != 0; |
| 884 | const uint8_t payloadLengthField = current & 0x7F; |
| 885 | |
| 886 | extendedLengthAccumulator = 0; |
| 887 | extendedLengthBytesRead = 0; |
| 888 | maskBytesRead = 0; |
| 889 | |
| 890 | consumedBytes++; |
| 891 | |
| 892 | if (payloadLengthField < 126) |
| 893 | { |
| 894 | currentFrame.payloadLength = payloadLengthField; |
| 895 | if (currentFrame.masked) |
| 896 | { |