wslay.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. /*
  2. * Wslay - The WebSocket Library
  3. *
  4. * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sublicense, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  21. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. */
  25. #ifndef WSLAY_H
  26. #define WSLAY_H
  27. #ifdef __cplusplus
  28. extern "C" {
  29. #endif
  30. #include <stdint.h>
  31. #include <stdlib.h>
  32. #include <sys/types.h>
  33. /*
  34. * wslay/wslayver.h is generated from wslay/wslayver.h.in by
  35. * configure. The projects which do not use autotools can set
  36. * WSLAY_VERSION macro from outside to avoid to generating wslayver.h
  37. */
  38. #ifndef WSLAY_VERSION
  39. # include <wslay/wslayver.h>
  40. #endif /* WSLAY_VERSION */
  41. enum wslay_error {
  42. WSLAY_ERR_WANT_READ = -100,
  43. WSLAY_ERR_WANT_WRITE = -101,
  44. WSLAY_ERR_PROTO = -200,
  45. WSLAY_ERR_INVALID_ARGUMENT = -300,
  46. WSLAY_ERR_INVALID_CALLBACK = -301,
  47. WSLAY_ERR_NO_MORE_MSG = -302,
  48. WSLAY_ERR_CALLBACK_FAILURE = -400,
  49. WSLAY_ERR_WOULDBLOCK = -401,
  50. WSLAY_ERR_NOMEM = -500
  51. };
  52. /*
  53. * Status codes defined in RFC6455
  54. */
  55. enum wslay_status_code {
  56. WSLAY_CODE_NORMAL_CLOSURE = 1000,
  57. WSLAY_CODE_GOING_AWAY = 1001,
  58. WSLAY_CODE_PROTOCOL_ERROR = 1002,
  59. WSLAY_CODE_UNSUPPORTED_DATA = 1003,
  60. WSLAY_CODE_NO_STATUS_RCVD = 1005,
  61. WSLAY_CODE_ABNORMAL_CLOSURE = 1006,
  62. WSLAY_CODE_INVALID_FRAME_PAYLOAD_DATA = 1007,
  63. WSLAY_CODE_POLICY_VIOLATION = 1008,
  64. WSLAY_CODE_MESSAGE_TOO_BIG = 1009,
  65. WSLAY_CODE_MANDATORY_EXT = 1010,
  66. WSLAY_CODE_INTERNAL_SERVER_ERROR = 1011,
  67. WSLAY_CODE_TLS_HANDSHAKE = 1015
  68. };
  69. enum wslay_io_flags {
  70. /*
  71. * There is more data to send.
  72. */
  73. WSLAY_MSG_MORE = 1
  74. };
  75. /*
  76. * Callback function used by wslay_frame_send() function when it needs
  77. * to send data. The implementation of this function must send at most
  78. * len bytes of data in data. flags is the bitwise OR of zero or more
  79. * of the following flag:
  80. *
  81. * WSLAY_MSG_MORE
  82. * There is more data to send
  83. *
  84. * It provides some hints to tune performance and behaviour. user_data
  85. * is one given in wslay_frame_context_init() function. The
  86. * implementation of this function must return the number of bytes
  87. * sent. If there is an error, return -1. The return value 0 is also
  88. * treated an error by the library.
  89. */
  90. typedef ssize_t (*wslay_frame_send_callback)(const uint8_t *data, size_t len,
  91. int flags, void *user_data);
  92. /*
  93. * Callback function used by wslay_frame_recv() function when it needs
  94. * more data. The implementation of this function must fill at most
  95. * len bytes of data into buf. The memory area of buf is allocated by
  96. * library and not be freed by the application code. flags is always 0
  97. * in this version. user_data is one given in
  98. * wslay_frame_context_init() function. The implementation of this
  99. * function must return the number of bytes filled. If there is an
  100. * error, return -1. The return value 0 is also treated an error by
  101. * the library.
  102. */
  103. typedef ssize_t (*wslay_frame_recv_callback)(uint8_t *buf, size_t len,
  104. int flags, void *user_data);
  105. /*
  106. * Callback function used by wslay_frame_send() function when it needs
  107. * new mask key. The implementation of this function must write
  108. * exactly len bytes of mask key to buf. user_data is one given in
  109. * wslay_frame_context_init() function. The implementation of this
  110. * function return 0 on success. If there is an error, return -1.
  111. */
  112. typedef int (*wslay_frame_genmask_callback)(uint8_t *buf, size_t len,
  113. void *user_data);
  114. struct wslay_frame_callbacks {
  115. wslay_frame_send_callback send_callback;
  116. wslay_frame_recv_callback recv_callback;
  117. wslay_frame_genmask_callback genmask_callback;
  118. };
  119. /*
  120. * The opcode defined in RFC6455.
  121. */
  122. enum wslay_opcode {
  123. WSLAY_CONTINUATION_FRAME = 0x0u,
  124. WSLAY_TEXT_FRAME = 0x1u,
  125. WSLAY_BINARY_FRAME = 0x2u,
  126. WSLAY_CONNECTION_CLOSE = 0x8u,
  127. WSLAY_PING = 0x9u,
  128. WSLAY_PONG = 0xau
  129. };
  130. /*
  131. * Macro that returns 1 if opcode is control frame opcode, otherwise
  132. * returns 0.
  133. */
  134. #define wslay_is_ctrl_frame(opcode) ((opcode >> 3) & 1)
  135. /*
  136. * Macros that represent and return reserved bits: RSV1, RSV2, RSV3.
  137. * These macros assume that rsv is constructed by ((RSV1 << 2) |
  138. * (RSV2 << 1) | RSV3)
  139. */
  140. #define WSLAY_RSV_NONE ((uint8_t)0)
  141. #define WSLAY_RSV1_BIT (((uint8_t)1) << 2)
  142. #define WSLAY_RSV2_BIT (((uint8_t)1) << 1)
  143. #define WSLAY_RSV3_BIT (((uint8_t)1) << 0)
  144. #define wslay_get_rsv1(rsv) ((rsv >> 2) & 1)
  145. #define wslay_get_rsv2(rsv) ((rsv >> 1) & 1)
  146. #define wslay_get_rsv3(rsv) (rsv & 1)
  147. struct wslay_frame_iocb {
  148. /* 1 for fragmented final frame, 0 for otherwise */
  149. uint8_t fin;
  150. /*
  151. * reserved 3 bits. rsv = ((RSV1 << 2) | (RSV << 1) | RSV3).
  152. * RFC6455 requires 0 unless extensions are negotiated.
  153. */
  154. uint8_t rsv;
  155. /* 4 bit opcode */
  156. uint8_t opcode;
  157. /* payload length [0, 2**63-1] */
  158. uint64_t payload_length;
  159. /* 1 for masked frame, 0 for unmasked */
  160. uint8_t mask;
  161. /* part of payload data */
  162. const uint8_t *data;
  163. /* bytes of data defined above */
  164. size_t data_length;
  165. };
  166. struct wslay_frame_context;
  167. typedef struct wslay_frame_context *wslay_frame_context_ptr;
  168. /*
  169. * Initializes ctx using given callbacks and user_data. This function
  170. * allocates memory for struct wslay_frame_context and stores the
  171. * result to *ctx. The callback functions specified in callbacks are
  172. * copied to ctx. user_data is stored in ctx and it will be passed to
  173. * callback functions. When the user code finished using ctx, it must
  174. * call wslay_frame_context_free to deallocate memory.
  175. */
  176. int wslay_frame_context_init(wslay_frame_context_ptr *ctx,
  177. const struct wslay_frame_callbacks *callbacks,
  178. void *user_data);
  179. /*
  180. * Deallocates memory pointed by ctx.
  181. */
  182. void wslay_frame_context_free(wslay_frame_context_ptr ctx);
  183. /*
  184. * Send WebSocket frame specified in iocb. ctx must be initialized
  185. * using wslay_frame_context_init() function. iocb->fin must be 1 if
  186. * this is a fin frame, otherwise 0. iocb->rsv is reserved bits.
  187. * iocb->opcode must be the opcode of this frame. iocb->mask must be
  188. * 1 if this is masked frame, otherwise 0. iocb->payload_length is
  189. * the payload_length of this frame. iocb->data must point to the
  190. * payload data to be sent. iocb->data_length must be the length of
  191. * the data. This function calls send_callback function if it needs
  192. * to send bytes. This function calls gen_mask_callback function if
  193. * it needs new mask key. This function returns the number of payload
  194. * bytes sent. Please note that it does not include any number of
  195. * header bytes. If it cannot send any single bytes of payload, it
  196. * returns WSLAY_ERR_WANT_WRITE. If the library detects error in iocb,
  197. * this function returns WSLAY_ERR_INVALID_ARGUMENT. If callback
  198. * functions report a failure, this function returns
  199. * WSLAY_ERR_INVALID_CALLBACK. This function does not always send all
  200. * given data in iocb. If there are remaining data to be sent, adjust
  201. * data and data_length in iocb accordingly and call this function
  202. * again.
  203. */
  204. ssize_t wslay_frame_send(wslay_frame_context_ptr ctx,
  205. struct wslay_frame_iocb *iocb);
  206. /*
  207. * Write WebSocket frame specified in iocb to buf of length
  208. * buflen. ctx must be initialized using wslay_frame_context_init()
  209. * function. iocb->fin must be 1 if this is a fin frame, otherwise 0.
  210. * iocb->rsv is reserved bits. iocb->opcode must be the opcode of
  211. * this frame. iocb->mask must be 1 if this is masked frame,
  212. * otherwise 0. iocb->payload_length is the payload_length of this
  213. * frame. iocb->data must point to the payload data to be
  214. * sent. iocb->data_length must be the length of the data. Unlike
  215. * wslay_frame_send, this function does not call send_callback
  216. * function. This function calls gen_mask_callback function if it
  217. * needs new mask key. This function returns the number of bytes
  218. * written to a buffer. Unlike wslay_frame_send, it includes the
  219. * number of header bytes. Instead, the number of payload bytes
  220. * written is assigned to *pwpayloadlen if this function succeeds. If
  221. * there is not enough space left in a buffer, it returns 0. If the
  222. * library detects error in iocb, this function returns
  223. * WSLAY_ERR_INVALID_ARGUMENT. If callback functions report a
  224. * failure, this function returns WSLAY_ERR_INVALID_CALLBACK. This
  225. * function does not always send all given data in iocb. If there are
  226. * remaining data to be sent, adjust data and data_length in iocb
  227. * accordingly and call this function again.
  228. */
  229. ssize_t wslay_frame_write(wslay_frame_context_ptr ctx,
  230. struct wslay_frame_iocb *iocb, uint8_t *buf,
  231. size_t buflen, size_t *pwpayloadlen);
  232. /*
  233. * Receives WebSocket frame and stores it in iocb. This function
  234. * returns the number of payload bytes received. This does not
  235. * include header bytes. In this case, iocb will be populated as
  236. * follows: iocb->fin is 1 if received frame is fin frame, otherwise
  237. * 0. iocb->rsv is reserved bits of received frame. iocb->opcode is
  238. * opcode of received frame. iocb->mask is 1 if received frame is
  239. * masked, otherwise 0. iocb->payload_length is the payload length of
  240. * received frame. iocb->data is pointed to the buffer containing
  241. * received payload data. This buffer is allocated by the library and
  242. * must be read-only. iocb->data_length is the number of payload
  243. * bytes recieved. This function calls recv_callback if it needs to
  244. * receive additional bytes. If it cannot receive any single bytes of
  245. * payload, it returns WSLAY_ERR_WANT_READ. If the library detects
  246. * protocol violation in a received frame, this function returns
  247. * WSLAY_ERR_PROTO. If callback functions report a failure, this
  248. * function returns WSLAY_ERR_INVALID_CALLBACK. This function does
  249. * not always receive whole frame in a single call. If there are
  250. * remaining data to be received, call this function again. This
  251. * function ensures frame alignment.
  252. */
  253. ssize_t wslay_frame_recv(wslay_frame_context_ptr ctx,
  254. struct wslay_frame_iocb *iocb);
  255. struct wslay_event_context;
  256. /* Pointer to the event-based API context */
  257. typedef struct wslay_event_context *wslay_event_context_ptr;
  258. struct wslay_event_on_msg_recv_arg {
  259. /* reserved bits: rsv = (RSV1 << 2) | (RSV2 << 1) | RSV3 */
  260. uint8_t rsv;
  261. /* opcode */
  262. uint8_t opcode;
  263. /* received message */
  264. const uint8_t *msg;
  265. /* message length */
  266. size_t msg_length;
  267. /*
  268. * Status code iff opcode == WSLAY_CONNECTION_CLOSE. If no status
  269. * code is included in the close control frame, it is set to 0.
  270. */
  271. uint16_t status_code;
  272. };
  273. /*
  274. * Callback function invoked by wslay_event_recv() when a message is
  275. * completely received.
  276. */
  277. typedef void (*wslay_event_on_msg_recv_callback)(
  278. wslay_event_context_ptr ctx, const struct wslay_event_on_msg_recv_arg *arg,
  279. void *user_data);
  280. struct wslay_event_on_frame_recv_start_arg {
  281. /* fin bit; 1 for final frame, or 0. */
  282. uint8_t fin;
  283. /* reserved bits: rsv = (RSV1 << 2) | (RSV2 << 1) | RSV3 */
  284. uint8_t rsv;
  285. /* opcode of the frame */
  286. uint8_t opcode;
  287. /* payload length of ths frame */
  288. uint64_t payload_length;
  289. };
  290. /*
  291. * Callback function invoked by wslay_event_recv() when a new frame
  292. * starts to be received. This callback function is only invoked once
  293. * for each frame.
  294. */
  295. typedef void (*wslay_event_on_frame_recv_start_callback)(
  296. wslay_event_context_ptr ctx,
  297. const struct wslay_event_on_frame_recv_start_arg *arg, void *user_data);
  298. struct wslay_event_on_frame_recv_chunk_arg {
  299. /* chunk of payload data */
  300. const uint8_t *data;
  301. /* length of data */
  302. size_t data_length;
  303. };
  304. /*
  305. * Callback function invoked by wslay_event_recv() when a chunk of
  306. * frame payload is received.
  307. */
  308. typedef void (*wslay_event_on_frame_recv_chunk_callback)(
  309. wslay_event_context_ptr ctx,
  310. const struct wslay_event_on_frame_recv_chunk_arg *arg, void *user_data);
  311. /*
  312. * Callback function invoked by wslay_event_recv() when a frame is
  313. * completely received.
  314. */
  315. typedef void (*wslay_event_on_frame_recv_end_callback)(
  316. wslay_event_context_ptr ctx, void *user_data);
  317. /*
  318. * Callback function invoked by wslay_event_recv() when it wants to
  319. * receive more data from peer. The implementation of this callback
  320. * function must read data at most len bytes from peer and store them
  321. * in buf and return the number of bytes read. flags is always 0 in
  322. * this version.
  323. *
  324. * If there is an error, return -1 and set error code
  325. * WSLAY_ERR_CALLBACK_FAILURE using wslay_event_set_error(). Wslay
  326. * event-based API on the whole assumes non-blocking I/O. If the cause
  327. * of error is EAGAIN or EWOULDBLOCK, set WSLAY_ERR_WOULDBLOCK
  328. * instead. This is important because it tells wslay_event_recv() to
  329. * stop receiving further data and return.
  330. */
  331. typedef ssize_t (*wslay_event_recv_callback)(wslay_event_context_ptr ctx,
  332. uint8_t *buf, size_t len,
  333. int flags, void *user_data);
  334. /*
  335. * Callback function invoked by wslay_event_send() when it wants to
  336. * send more data to peer. The implementation of this callback
  337. * function must send data at most len bytes to peer and return the
  338. * number of bytes sent. flags is the bitwise OR of zero or more of
  339. * the following flag:
  340. *
  341. * WSLAY_MSG_MORE
  342. * There is more data to send
  343. *
  344. * It provides some hints to tune performance and behaviour.
  345. *
  346. * If there is an error, return -1 and set error code
  347. * WSLAY_ERR_CALLBACK_FAILURE using wslay_event_set_error(). Wslay
  348. * event-based API on the whole assumes non-blocking I/O. If the cause
  349. * of error is EAGAIN or EWOULDBLOCK, set WSLAY_ERR_WOULDBLOCK
  350. * instead. This is important because it tells wslay_event_send() to
  351. * stop sending data and return.
  352. */
  353. typedef ssize_t (*wslay_event_send_callback)(wslay_event_context_ptr ctx,
  354. const uint8_t *data, size_t len,
  355. int flags, void *user_data);
  356. /*
  357. * Callback function invoked by wslay_event_send() when it wants new
  358. * mask key. As described in RFC6455, only the traffic from WebSocket
  359. * client is masked, so this callback function is only needed if an
  360. * event-based API is initialized for WebSocket client use.
  361. */
  362. typedef int (*wslay_event_genmask_callback)(wslay_event_context_ptr ctx,
  363. uint8_t *buf, size_t len,
  364. void *user_data);
  365. struct wslay_event_callbacks {
  366. wslay_event_recv_callback recv_callback;
  367. wslay_event_send_callback send_callback;
  368. wslay_event_genmask_callback genmask_callback;
  369. wslay_event_on_frame_recv_start_callback on_frame_recv_start_callback;
  370. wslay_event_on_frame_recv_chunk_callback on_frame_recv_chunk_callback;
  371. wslay_event_on_frame_recv_end_callback on_frame_recv_end_callback;
  372. wslay_event_on_msg_recv_callback on_msg_recv_callback;
  373. };
  374. /*
  375. * Initializes ctx as WebSocket Server. user_data is an arbitrary
  376. * pointer, which is directly passed to each callback functions as
  377. * user_data argument.
  378. *
  379. * On success, returns 0. On error, returns one of following negative
  380. * values:
  381. *
  382. * WSLAY_ERR_NOMEM
  383. * Out of memory.
  384. */
  385. int wslay_event_context_server_init(
  386. wslay_event_context_ptr *ctx, const struct wslay_event_callbacks *callbacks,
  387. void *user_data);
  388. /*
  389. * Initializes ctx as WebSocket client. user_data is an arbitrary
  390. * pointer, which is directly passed to each callback functions as
  391. * user_data argument.
  392. *
  393. * On success, returns 0. On error, returns one of following negative
  394. * values:
  395. *
  396. * WSLAY_ERR_NOMEM
  397. * Out of memory.
  398. */
  399. int wslay_event_context_client_init(
  400. wslay_event_context_ptr *ctx, const struct wslay_event_callbacks *callbacks,
  401. void *user_data);
  402. /*
  403. * Releases allocated resources for ctx.
  404. */
  405. void wslay_event_context_free(wslay_event_context_ptr ctx);
  406. /*
  407. * Sets a bit mask of allowed reserved bits.
  408. * Currently only permitted values are WSLAY_RSV1_BIT to allow PMCE
  409. * extension (see RFC-7692) or WSLAY_RSV_NONE to disable.
  410. *
  411. * Default: WSLAY_RSV_NONE
  412. */
  413. void wslay_event_config_set_allowed_rsv_bits(wslay_event_context_ptr ctx,
  414. uint8_t rsv);
  415. /*
  416. * Enables or disables buffering of an entire message for non-control
  417. * frames. If val is 0, buffering is enabled. Otherwise, buffering is
  418. * disabled. If wslay_event_on_msg_recv_callback is invoked when
  419. * buffering is disabled, the msg_length member of struct
  420. * wslay_event_on_msg_recv_arg is set to 0.
  421. *
  422. * The control frames are always buffered regardless of this function call.
  423. *
  424. * This function must not be used after the first invocation of
  425. * wslay_event_recv() function.
  426. */
  427. void wslay_event_config_set_no_buffering(wslay_event_context_ptr ctx, int val);
  428. /*
  429. * Sets maximum length of a message that can be received. The length
  430. * of message is checked by wslay_event_recv() function. If the length
  431. * of a message is larger than this value, reading operation is
  432. * disabled (same effect with wslay_event_shutdown_read() call) and
  433. * close control frame with WSLAY_CODE_MESSAGE_TOO_BIG is queued. If
  434. * buffering for non-control frames is disabled, the library checks
  435. * each frame payload length and does not check length of entire
  436. * message.
  437. *
  438. * The default value is (1u << 31)-1.
  439. */
  440. void wslay_event_config_set_max_recv_msg_length(wslay_event_context_ptr ctx,
  441. uint64_t val);
  442. /*
  443. * Sets callbacks to ctx. The callbacks previouly set by this function
  444. * or wslay_event_context_server_init() or
  445. * wslay_event_context_client_init() are replaced with callbacks.
  446. */
  447. void wslay_event_config_set_callbacks(
  448. wslay_event_context_ptr ctx, const struct wslay_event_callbacks *callbacks);
  449. /*
  450. * Receives messages from peer. When receiving
  451. * messages, it uses wslay_event_recv_callback function. Single call
  452. * of this function receives multiple messages until
  453. * wslay_event_recv_callback function sets error code
  454. * WSLAY_ERR_WOULDBLOCK.
  455. *
  456. * When close control frame is received, this function automatically
  457. * queues close control frame. Also this function calls
  458. * wslay_event_set_read_enabled() with second argument 0 to disable
  459. * further read from peer.
  460. *
  461. * When ping control frame is received, this function automatically
  462. * queues pong control frame.
  463. *
  464. * In case of a fatal errror which leads to negative return code, this
  465. * function calls wslay_event_set_read_enabled() with second argument
  466. * 0 to disable further read from peer.
  467. *
  468. * wslay_event_recv() returns 0 if it succeeds, or one of the
  469. * following negative error codes:
  470. *
  471. * WSLAY_ERR_CALLBACK_FAILURE
  472. * User defined callback function is failed.
  473. *
  474. * WSLAY_ERR_NOMEM
  475. * Out of memory.
  476. *
  477. * When negative error code is returned, application must not make any
  478. * further call of wslay_event_recv() and must close WebSocket
  479. * connection.
  480. */
  481. int wslay_event_recv(wslay_event_context_ptr ctx);
  482. /*
  483. * Sends queued messages to peer. When sending a
  484. * message, it uses wslay_event_send_callback function. Single call of
  485. * wslay_event_send() sends multiple messages until
  486. * wslay_event_send_callback sets error code WSLAY_ERR_WOULDBLOCK.
  487. *
  488. * If ctx is initialized for WebSocket client use, wslay_event_send()
  489. * uses wslay_event_genmask_callback to get new mask key.
  490. *
  491. * When a message queued using wslay_event_queue_fragmented_msg() is
  492. * sent, wslay_event_send() invokes
  493. * wslay_event_fragmented_msg_callback for that message.
  494. *
  495. * After close control frame is sent, this function calls
  496. * wslay_event_set_write_enabled() with second argument 0 to disable
  497. * further transmission to peer.
  498. *
  499. * If there are any pending messages, wslay_event_want_write() returns
  500. * 1, otherwise returns 0.
  501. *
  502. * In case of a fatal errror which leads to negative return code, this
  503. * function calls wslay_event_set_write_enabled() with second argument
  504. * 0 to disable further transmission to peer.
  505. *
  506. * wslay_event_send() returns 0 if it succeeds, or one of the
  507. * following negative error codes:
  508. *
  509. * WSLAY_ERR_CALLBACK_FAILURE
  510. * User defined callback function is failed.
  511. *
  512. * WSLAY_ERR_NOMEM
  513. * Out of memory.
  514. *
  515. * When negative error code is returned, application must not make any
  516. * further call of wslay_event_send() and must close WebSocket
  517. * connection.
  518. */
  519. int wslay_event_send(wslay_event_context_ptr ctx);
  520. /*
  521. * Writes queued messages to a buffer. Unlike wslay_event_send(), this
  522. * function writes messages into the given buffer. It does not use
  523. * wslay_event_send_callback function. Single call of
  524. * wslay_event_write() writes multiple messages until there is not
  525. * enough space left in a buffer.
  526. *
  527. * If ctx is initialized for WebSocket client use, wslay_event_write()
  528. * uses wslay_event_genmask_callback to get new mask key.
  529. *
  530. * buf is a pointer to buffer and its capacity is given in buflen. It
  531. * should have at least 14 bytes.
  532. *
  533. * When a message queued using wslay_event_queue_fragmented_msg() is
  534. * sent, wslay_event_write() invokes
  535. * wslay_event_fragmented_msg_callback for that message.
  536. *
  537. * After close control frame is sent, this function calls
  538. * wslay_event_set_write_enabled() with second argument 0 to disable
  539. * further transmission to peer.
  540. *
  541. * If there are any pending messages, wslay_event_want_write() returns
  542. * 1, otherwise returns 0.
  543. *
  544. * In case of a fatal errror which leads to negative return code, this
  545. * function calls wslay_event_set_write_enabled() with second argument
  546. * 0 to disable further transmission to peer.
  547. *
  548. * wslay_event_write() returns the number of bytes written to a buffer
  549. * if it succeeds, or one of the following negative error codes:
  550. *
  551. * WSLAY_ERR_CALLBACK_FAILURE
  552. * User defined callback function is failed.
  553. *
  554. * WSLAY_ERR_NOMEM
  555. * Out of memory.
  556. *
  557. * When negative error code is returned, application must not make any
  558. * further call of wslay_event_write() and must close WebSocket
  559. * connection.
  560. */
  561. ssize_t wslay_event_write(wslay_event_context_ptr ctx, uint8_t *buf,
  562. size_t buflen);
  563. struct wslay_event_msg {
  564. uint8_t opcode;
  565. const uint8_t *msg;
  566. size_t msg_length;
  567. };
  568. /*
  569. * Queues message specified in arg.
  570. *
  571. * This function supports both control and non-control messages and
  572. * the given message is sent without fragmentation. If fragmentation
  573. * is needed, use wslay_event_queue_fragmented_msg() function instead.
  574. *
  575. * This function just queues a message and does not send
  576. * it. wslay_event_send() function call sends these queued messages.
  577. *
  578. * wslay_event_queue_msg() returns 0 if it succeeds, or returns the
  579. * following negative error codes:
  580. *
  581. * WSLAY_ERR_NO_MORE_MSG
  582. * Could not queue given message. The one of possible reason is that
  583. * close control frame has been queued/sent and no further queueing
  584. * message is not allowed.
  585. *
  586. * WSLAY_ERR_INVALID_ARGUMENT
  587. * The given message is invalid.
  588. *
  589. * WSLAY_ERR_NOMEM
  590. * Out of memory.
  591. */
  592. int wslay_event_queue_msg(wslay_event_context_ptr ctx,
  593. const struct wslay_event_msg *arg);
  594. /*
  595. * Extended version of wslay_event_queue_msg which allows to set reserved bits.
  596. */
  597. int wslay_event_queue_msg_ex(wslay_event_context_ptr ctx,
  598. const struct wslay_event_msg *arg, uint8_t rsv);
  599. /*
  600. * Specify "source" to generate message.
  601. */
  602. union wslay_event_msg_source {
  603. int fd;
  604. void *data;
  605. };
  606. /*
  607. * Callback function called by wslay_event_send() to read message data
  608. * from source. The implementation of
  609. * wslay_event_fragmented_msg_callback must store at most len bytes of
  610. * data to buf and return the number of stored bytes. If all data is
  611. * read (i.e., EOF), set *eof to 1. If no data can be generated at the
  612. * moment, return 0. If there is an error, return -1 and set error
  613. * code WSLAY_ERR_CALLBACK_FAILURE using wslay_event_set_error().
  614. */
  615. typedef ssize_t (*wslay_event_fragmented_msg_callback)(
  616. wslay_event_context_ptr ctx, uint8_t *buf, size_t len,
  617. const union wslay_event_msg_source *source, int *eof, void *user_data);
  618. struct wslay_event_fragmented_msg {
  619. /* opcode */
  620. uint8_t opcode;
  621. /* "source" to generate message data */
  622. union wslay_event_msg_source source;
  623. /* Callback function to read message data from source. */
  624. wslay_event_fragmented_msg_callback read_callback;
  625. };
  626. /*
  627. * Queues a fragmented message specified in arg.
  628. *
  629. * This function supports non-control messages only. For control frames,
  630. * use wslay_event_queue_msg() or wslay_event_queue_close().
  631. *
  632. * This function just queues a message and does not send
  633. * it. wslay_event_send() function call sends these queued messages.
  634. *
  635. * wslay_event_queue_fragmented_msg() returns 0 if it succeeds, or
  636. * returns the following negative error codes:
  637. *
  638. * WSLAY_ERR_NO_MORE_MSG
  639. * Could not queue given message. The one of possible reason is that
  640. * close control frame has been queued/sent and no further queueing
  641. * message is not allowed.
  642. *
  643. * WSLAY_ERR_INVALID_ARGUMENT
  644. * The given message is invalid.
  645. *
  646. * WSLAY_ERR_NOMEM
  647. * Out of memory.
  648. */
  649. int wslay_event_queue_fragmented_msg(
  650. wslay_event_context_ptr ctx, const struct wslay_event_fragmented_msg *arg);
  651. /*
  652. * Extended version of wslay_event_queue_fragmented_msg which allows to set
  653. * reserved bits.
  654. */
  655. int wslay_event_queue_fragmented_msg_ex(
  656. wslay_event_context_ptr ctx, const struct wslay_event_fragmented_msg *arg,
  657. uint8_t rsv);
  658. /*
  659. * Queues close control frame. This function is provided just for
  660. * convenience. wslay_event_queue_msg() can queue a close control
  661. * frame as well. status_code is the status code of close control
  662. * frame. reason is the close reason encoded in UTF-8. reason_length
  663. * is the length of reason in bytes. reason_length must be less than
  664. * 123 bytes.
  665. *
  666. * If status_code is 0, reason and reason_length is not used and close
  667. * control frame with zero-length payload will be queued.
  668. *
  669. * This function just queues a message and does not send
  670. * it. wslay_event_send() function call sends these queued messages.
  671. *
  672. * wslay_event_queue_close() returns 0 if it succeeds, or returns the
  673. * following negative error codes:
  674. *
  675. * WSLAY_ERR_NO_MORE_MSG
  676. * Could not queue given message. The one of possible reason is that
  677. * close control frame has been queued/sent and no further queueing
  678. * message is not allowed.
  679. *
  680. * WSLAY_ERR_INVALID_ARGUMENT
  681. * The given message is invalid.
  682. *
  683. * WSLAY_ERR_NOMEM
  684. * Out of memory.
  685. */
  686. int wslay_event_queue_close(wslay_event_context_ptr ctx, uint16_t status_code,
  687. const uint8_t *reason, size_t reason_length);
  688. /*
  689. * Sets error code to tell the library there is an error. This
  690. * function is typically used in user defined callback functions. See
  691. * the description of callback function to know which error code
  692. * should be used.
  693. */
  694. void wslay_event_set_error(wslay_event_context_ptr ctx, int val);
  695. /*
  696. * Query whehter the library want to read more data from peer.
  697. *
  698. * wslay_event_want_read() returns 1 if the library want to read more
  699. * data from peer, or returns 0.
  700. */
  701. int wslay_event_want_read(wslay_event_context_ptr ctx);
  702. /*
  703. * Query whehter the library want to send more data to peer.
  704. *
  705. * wslay_event_want_write() returns 1 if the library want to send more
  706. * data to peer, or returns 0.
  707. */
  708. int wslay_event_want_write(wslay_event_context_ptr ctx);
  709. /*
  710. * Prevents the event-based API context from reading any further data
  711. * from peer.
  712. *
  713. * This function may be used with wslay_event_queue_close() if the
  714. * application detects error in the data received and wants to fail
  715. * WebSocket connection.
  716. */
  717. void wslay_event_shutdown_read(wslay_event_context_ptr ctx);
  718. /*
  719. * Prevents the event-based API context from sending any further data
  720. * to peer.
  721. */
  722. void wslay_event_shutdown_write(wslay_event_context_ptr ctx);
  723. /*
  724. * Returns 1 if the event-based API context allows read operation, or
  725. * return 0.
  726. *
  727. * After wslay_event_shutdown_read() is called,
  728. * wslay_event_get_read_enabled() returns 0.
  729. */
  730. int wslay_event_get_read_enabled(wslay_event_context_ptr ctx);
  731. /*
  732. * Returns 1 if the event-based API context allows write operation, or
  733. * return 0.
  734. *
  735. * After wslay_event_shutdown_write() is called,
  736. * wslay_event_get_write_enabled() returns 0.
  737. */
  738. int wslay_event_get_write_enabled(wslay_event_context_ptr ctx);
  739. /*
  740. * Returns 1 if a close control frame has been received from peer, or
  741. * returns 0.
  742. */
  743. int wslay_event_get_close_received(wslay_event_context_ptr ctx);
  744. /*
  745. * Returns 1 if a close control frame has been sent to peer, or
  746. * returns 0.
  747. */
  748. int wslay_event_get_close_sent(wslay_event_context_ptr ctx);
  749. /*
  750. * Returns status code received in close control frame. If no close
  751. * control frame has not been received, returns
  752. * WSLAY_CODE_ABNORMAL_CLOSURE. If received close control frame has no
  753. * status code, returns WSLAY_CODE_NO_STATUS_RCVD.
  754. */
  755. uint16_t wslay_event_get_status_code_received(wslay_event_context_ptr ctx);
  756. /*
  757. * Returns status code sent in close control frame. If no close
  758. * control frame has not been sent, returns
  759. * WSLAY_CODE_ABNORMAL_CLOSURE. If sent close control frame has no
  760. * status code, returns WSLAY_CODE_NO_STATUS_RCVD.
  761. */
  762. uint16_t wslay_event_get_status_code_sent(wslay_event_context_ptr ctx);
  763. /*
  764. * Returns the number of queued messages.
  765. */
  766. size_t wslay_event_get_queued_msg_count(wslay_event_context_ptr ctx);
  767. /*
  768. * Returns the sum of queued message length. It only counts the
  769. * message length queued using wslay_event_queue_msg() or
  770. * wslay_event_queue_close().
  771. */
  772. size_t wslay_event_get_queued_msg_length(wslay_event_context_ptr ctx);
  773. #ifdef __cplusplus
  774. }
  775. #endif
  776. #endif /* WSLAY_H */