include/ylt/standalone/cinatra/ws_define.h (122 lines of code) (raw):

#pragma once #include <cstdint> #include <string_view> namespace cinatra { using namespace std::string_view_literals; #if defined(_WIN32) #define __SWAP_LONGLONG(l) \ ((((l) >> 56) & 0x00000000000000FFLL) | \ (((l) >> 40) & 0x000000000000FF00LL) | \ (((l) >> 24) & 0x0000000000FF0000LL) | \ (((l) >> 8) & 0x00000000FF000000LL) | (((l) << 8) & 0x000000FF00000000LL) | \ (((l) << 24) & 0x0000FF0000000000LL) | \ (((l) << 40) & 0x00FF000000000000LL) | \ (((l) << 56) & 0xFF00000000000000LL)) inline uint64_t htobe64(uint64_t val) { const uint64_t ret = __SWAP_LONGLONG(val); return ret; } inline uint64_t be64toh(uint64_t val) { const uint64_t ret = __SWAP_LONGLONG(val); return ret; } #elif defined(__APPLE__) #include <libkern/OSByteOrder.h> #define be64toh(x) OSSwapBigToHostInt64(x) #define htobe64(x) OSSwapHostToBigInt64(x) #endif //_WIN32 enum opcode : std::uint8_t { cont = 0, text = 1, binary = 2, rsv3 = 3, rsv4 = 4, rsv5 = 5, rsv6 = 6, rsv7 = 7, close = 8, ping = 9, pong = 10, crsvb = 11, crsvc = 12, crsvd = 13, crsve = 14, crsvf = 15 }; /** Close status codes. These codes accompany close frames. @see <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1">RFC 6455 7.4.1 Defined Status Codes</a> */ enum close_code : std::uint16_t { /// Normal closure; the connection successfully completed whatever purpose for /// which it was created. normal = 1000, /// The endpoint is going away, either because of a server failure or because /// the browser is navigating away from the page that opened the connection. going_away = 1001, /// The endpoint is terminating the connection due to a protocol error. protocol_error = 1002, /// The connection is being terminated because the endpoint received data of a /// type it cannot accept (for example, a text-only endpoint received binary /// data). unknown_data = 1003, /// The endpoint is terminating the connection because a message was received /// that contained inconsistent data (e.g., non-UTF-8 data within a text /// message). bad_payload = 1007, /// The endpoint is terminating the connection because it received a message /// that violates its policy. This is a generic status code, used when codes /// 1003 and 1009 are not suitable. policy_error = 1008, /// The endpoint is terminating the connection because a data frame was /// received that is too large. too_big = 1009, /// The client is terminating the connection because it expected the server to /// negotiate one or more extension, but the server didn't. needs_extension = 1010, /// The server is terminating the connection because it encountered an /// unexpected condition that prevented it from fulfilling the request. internal_error = 1011, /// The server is terminating the connection because it is restarting. service_restart = 1012, /// The server is terminating the connection due to a temporary condition, /// e.g. it is overloaded and is casting off some of its clients. try_again_later = 1013, //---- // // The following are illegal on the wire // /** Used internally to mean "no error" This code is reserved and may not be sent. */ none = 0, /** Reserved for future use by the WebSocket standard. This code is reserved and may not be sent. */ reserved1 = 1004, /** No status code was provided even though one was expected. This code is reserved and may not be sent. */ no_status = 1005, /** Connection was closed without receiving a close frame This code is reserved and may not be sent. */ abnormal = 1006, /** Reserved for future use by the WebSocket standard. This code is reserved and may not be sent. */ reserved2 = 1014, /** Reserved for future use by the WebSocket standard. This code is reserved and may not be sent. */ reserved3 = 1015 // //---- // last = 5000 // satisfy warnings }; enum class ws_frame_type { WS_ERROR_FRAME = 0xFF00, WS_INCOMPLETE_FRAME = 0xFE00, WS_OPENING_FRAME = 0x3300, WS_CLOSING_FRAME = 0x3400, WS_INCOMPLETE_TEXT_FRAME = 0x01, WS_INCOMPLETE_BINARY_FRAME = 0x02, WS_TEXT_FRAME = 0x81, // 128 + 1 == WS_FRAGMENT_FIN | WS_OPCODE_TEXT WS_BINARY_FRAME = 0x82, // 128 + 2 WS_RSV3_FRAME = 0x83, // 128 + 3 WS_RSV4_FRAME = 0x84, WS_RSV5_FRAME = 0x85, WS_RSV6_FRAME = 0x86, WS_RSV7_FRAME = 0x87, WS_CLOSE_FRAME = 0x88, WS_PING_FRAME = 0x89, WS_PONG_FRAME = 0x8A, }; struct close_frame { uint16_t code; char *message; size_t length; }; enum ws_head_len { SHORT_HEADER = 6, MEDIUM_HEADER = 8, LONG_HEADER = 14, INVALID_HEADER }; enum client_ws_head_len { CLIENT_SHORT_HEADER = 2, CLIENT_MEDIUM_HEADER = 4, CLIENT_LONG_HEADER = 10, CLIENT_INVALID_HEADER }; enum ws_send_state { SND_CONTINUATION = 1, SND_NO_FIN = 2, SND_COMPRESSED = 64 }; struct frame_header { uint8_t opcode : 4; uint8_t rsv3 : 1; uint8_t rsv2 : 1; uint8_t rsv1 : 1; uint8_t fin : 1; uint8_t len : 7; uint8_t mask : 1; }; #define WEBSOCKET_FRAME_MAXLEN 16384 #define WEBSOCKET_PAYLOAD_SINGLE 125 #define WEBSOCKET_PAYLOAD_EXTEND_1 126 #define WEBSOCKET_PAYLOAD_EXTEND_2 127 inline constexpr const size_t MAX_CLOSE_PAYLOAD = 123; inline constexpr const std::string_view WEBSOCKET = "websocket"sv; inline constexpr const std::string_view UPGRADE = "Upgrade"sv; inline constexpr const char ws_guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; } // namespace cinatra