wslay.h 26 KB

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