1
0

websocket_parser.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #ifndef WEBSOCKET_PARSER_H
  2. #define WEBSOCKET_PARSER_H
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. #include <sys/types.h>
  7. #if defined(_WIN32) && !defined(__MINGW32__) && \
  8. (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)
  9. #include <BaseTsd.h>
  10. #include <stddef.h>
  11. typedef __int8 int8_t;
  12. typedef unsigned __int8 uint8_t;
  13. typedef __int16 int16_t;
  14. typedef unsigned __int16 uint16_t;
  15. typedef __int32 int32_t;
  16. typedef unsigned __int32 uint32_t;
  17. typedef __int64 int64_t;
  18. typedef unsigned __int64 uint64_t;
  19. #else
  20. #include <stdint.h>
  21. #endif
  22. #define WEBSOCKET_UUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
  23. typedef struct websocket_parser websocket_parser;
  24. typedef struct websocket_parser_settings websocket_parser_settings;
  25. typedef enum websocket_flags {
  26. // opcodes
  27. WS_OP_CONTINUE = 0x0,
  28. WS_OP_TEXT = 0x1,
  29. WS_OP_BINARY = 0x2,
  30. WS_OP_CLOSE = 0x8,
  31. WS_OP_PING = 0x9,
  32. WS_OP_PONG = 0xA,
  33. // marks
  34. WS_FINAL_FRAME = 0x10,
  35. WS_HAS_MASK = 0x20,
  36. } websocket_flags;
  37. #define WS_OP_MASK 0xF
  38. #define WS_FIN WS_FINAL_FRAME
  39. typedef int (*websocket_data_cb) (websocket_parser*, const char * at, size_t length);
  40. typedef int (*websocket_cb) (websocket_parser*);
  41. struct websocket_parser {
  42. uint32_t state;
  43. websocket_flags flags;
  44. char mask[4];
  45. uint8_t mask_offset;
  46. size_t length;
  47. size_t require;
  48. size_t offset;
  49. void * data;
  50. };
  51. struct websocket_parser_settings {
  52. websocket_cb on_frame_header;
  53. websocket_data_cb on_frame_body;
  54. websocket_cb on_frame_end;
  55. };
  56. void websocket_parser_init(websocket_parser *parser);
  57. void websocket_parser_settings_init(websocket_parser_settings *settings);
  58. size_t websocket_parser_execute(
  59. websocket_parser * parser,
  60. const websocket_parser_settings *settings,
  61. const char * data,
  62. size_t len
  63. );
  64. // Apply XOR mask (see https://tools.ietf.org/html/rfc6455#section-5.3) and store mask's offset
  65. void websocket_parser_decode(char * dst, const char * src, size_t len, websocket_parser * parser);
  66. // Apply XOR mask (see https://tools.ietf.org/html/rfc6455#section-5.3) and return mask's offset
  67. uint8_t websocket_decode(char * dst, const char * src, size_t len, const char mask[4], uint8_t mask_offset);
  68. #define websocket_encode(dst, src, len, mask, mask_offset) websocket_decode(dst, src, len, mask, mask_offset)
  69. // Calculate frame size using flags and data length
  70. size_t websocket_calc_frame_size(websocket_flags flags, size_t data_len);
  71. // Create string representation of frame
  72. size_t websocket_build_frame(char * frame, websocket_flags flags, const char mask[4], const char * data, size_t data_len);
  73. #define websocket_parser_get_opcode(p) (p->flags & WS_OP_MASK)
  74. #define websocket_parser_has_mask(p) (p->flags & WS_HAS_MASK)
  75. #define websocket_parser_has_final(p) (p->flags & WS_FIN)
  76. #ifdef __cplusplus
  77. }
  78. #endif
  79. #endif //WEBSOCKET_PARSER_H