| 1123 | } |
| 1124 | |
| 1125 | Result HttpWebSocketEndpoint::sendClose(uint16_t statusCode, Span<const char> reason, const uint8_t* maskKey, |
| 1126 | Span<char> storage, Span<const char>& encodedFrame) |
| 1127 | { |
| 1128 | SC_TRY_MSG(statusCode != 0 or reason.empty(), "HttpWebSocketEndpoint close reason requires a status code"); |
| 1129 | SC_TRY_MSG(reason.sizeInBytes() + (statusCode == 0 ? 0 : 2) <= sizeof(controlPayload), |
| 1130 | "HttpWebSocketEndpoint close payload too large"); |
| 1131 | |
| 1132 | char closePayload[125] = {0}; |
| 1133 | size_t closePayloadSize = 0; |
| 1134 | if (statusCode != 0) |
| 1135 | { |
| 1136 | closePayload[closePayloadSize++] = static_cast<char>((statusCode >> 8) & 0xFF); |
| 1137 | closePayload[closePayloadSize++] = static_cast<char>(statusCode & 0xFF); |
| 1138 | } |
| 1139 | if (reason.sizeInBytes() > 0) |
| 1140 | { |
| 1141 | ::memcpy(closePayload + closePayloadSize, reason.data(), reason.sizeInBytes()); |
| 1142 | closePayloadSize += reason.sizeInBytes(); |
| 1143 | } |
| 1144 | |
| 1145 | HttpWebSocketFrameHeaderView header; |
| 1146 | header.opcode = HttpWebSocketOpcode::Close; |
| 1147 | header.fin = true; |
| 1148 | header.payloadLength = closePayloadSize; |
| 1149 | SC_TRY(applyOutgoingMask(header, maskKey)); |
| 1150 | SC_TRY(sendFrame(header, {closePayload, closePayloadSize}, storage, encodedFrame)); |
| 1151 | closeSent = true; |
| 1152 | return Result(true); |
| 1153 | } |
| 1154 | |
| 1155 | Result HttpWebSocketEndpoint::getPendingControlFrame(Span<const char>& frame) const |
| 1156 | { |