Update wslay

pull/765/head
Tatsuhiro Tsujikawa 2016-11-02 22:41:36 +09:00
parent 90452ae11b
commit fb380d4016
8 changed files with 320 additions and 19 deletions

14
deps/wslay/.gitignore vendored
View File

@ -27,3 +27,17 @@ stamp-h1
INSTALL
.DS_STORE
tests/main
tests/main.log
tests/main.trs
tests/test-suite.log
/compile
/test-driver
/build.*
doc/man
doc/sphinx/_build
/CMakeFiles/
/cmake_install.cmake
/lib/cmake_install.cmake
/lib/libwslay.a
/wslay-config.cmake
/wslay.cmake

View File

@ -1,7 +1,7 @@
Wslay - The WebSocket library
=============================
Project Web: http://wslay.sourceforge.net/
Project Web: https://github.com/tatsuhiro-t/wslay
Wslay is a WebSocket library written in C.
It implements the protocol version 13 described in
@ -34,7 +34,8 @@ and
Requirements
------------
`Sphinx <http://sphinx.pocoo.org/>`_ is used to generate man pages.
`Sphinx <http://www.sphinx-doc.org/en/stable/>`_ is used to generate
man pages.
To build and run the unit test programs, the following packages are
needed:

View File

@ -145,10 +145,15 @@ enum wslay_opcode {
#define wslay_is_ctrl_frame(opcode) ((opcode >> 3) & 1)
/*
* Macros that returns reserved bits: RSV1, RSV2, RSV3. These macros
* assumes that rsv is constructed by ((RSV1 << 2) | (RSV2 << 1) |
* RSV3)
* Macros that represent and return reserved bits: RSV1, RSV2, RSV3.
* These macros assume that rsv is constructed by ((RSV1 << 2) |
* (RSV2 << 1) | RSV3)
*/
#define WSLAY_RSV_NONE ((uint8_t) 0)
#define WSLAY_RSV1_BIT (((uint8_t) 1) << 2)
#define WSLAY_RSV2_BIT (((uint8_t) 1) << 1)
#define WSLAY_RSV3_BIT (((uint8_t) 1) << 0)
#define wslay_get_rsv1(rsv) ((rsv >> 2) & 1)
#define wslay_get_rsv2(rsv) ((rsv >> 1) & 1)
#define wslay_get_rsv3(rsv) (rsv & 1)
@ -201,7 +206,7 @@ void wslay_frame_context_free(wslay_frame_context_ptr ctx);
* 1 if this is masked frame, otherwise 0. iocb->payload_length is
* the payload_length of this frame. iocb->data must point to the
* payload data to be sent. iocb->data_length must be the length of
* the data. This function calls recv_callback function if it needs
* the data. This function calls send_callback function if it needs
* to send bytes. This function calls gen_mask_callback function if
* it needs new mask key. This function returns the number of payload
* bytes sent. Please note that it does not include any number of
@ -407,6 +412,16 @@ int wslay_event_context_client_init
*/
void wslay_event_context_free(wslay_event_context_ptr ctx);
/*
* Sets a bit mask of allowed reserved bits.
* Currently only permitted values are WSLAY_RSV1_BIT to allow PMCE
* extension (see RFC-7692) or WSLAY_RSV_NONE to disable.
*
* Default: WSLAY_RSV_NONE
*/
void wslay_event_config_set_allowed_rsv_bits(wslay_event_context_ptr ctx,
uint8_t rsv);
/*
* Enables or disables buffering of an entire message for non-control
* frames. If val is 0, buffering is enabled. Otherwise, buffering is
@ -550,6 +565,12 @@ struct wslay_event_msg {
int wslay_event_queue_msg(wslay_event_context_ptr ctx,
const struct wslay_event_msg *arg);
/*
* Extended version of wslay_event_queue_msg which allows to set reserved bits.
*/
int wslay_event_queue_msg_ex(wslay_event_context_ptr ctx,
const struct wslay_event_msg *arg, uint8_t rsv);
/*
* Specify "source" to generate message.
*/
@ -607,6 +628,13 @@ struct wslay_event_fragmented_msg {
int wslay_event_queue_fragmented_msg
(wslay_event_context_ptr ctx, const struct wslay_event_fragmented_msg *arg);
/*
* Extended version of wslay_event_queue_fragmented_msg which allows to set
* reserved bits.
*/
int wslay_event_queue_fragmented_msg_ex(wslay_event_context_ptr ctx,
const struct wslay_event_fragmented_msg *arg, uint8_t rsv);
/*
* Queues close control frame. This function is provided just for
* convenience. wslay_event_queue_msg() can queue a close control

View File

@ -206,7 +206,7 @@ static int wslay_event_imsg_append_chunk(struct wslay_event_imsg *m, size_t len)
}
static int wslay_event_omsg_non_fragmented_init
(struct wslay_event_omsg **m, uint8_t opcode,
(struct wslay_event_omsg **m, uint8_t opcode, uint8_t rsv,
const uint8_t *msg, size_t msg_length)
{
*m = (struct wslay_event_omsg*)malloc(sizeof(struct wslay_event_omsg));
@ -216,6 +216,7 @@ static int wslay_event_omsg_non_fragmented_init
memset(*m, 0, sizeof(struct wslay_event_omsg));
(*m)->fin = 1;
(*m)->opcode = opcode;
(*m)->rsv = rsv;
(*m)->type = WSLAY_NON_FRAGMENTED;
if(msg_length) {
(*m)->data = (uint8_t*)malloc(msg_length);
@ -230,7 +231,7 @@ static int wslay_event_omsg_non_fragmented_init
}
static int wslay_event_omsg_fragmented_init
(struct wslay_event_omsg **m, uint8_t opcode,
(struct wslay_event_omsg **m, uint8_t opcode, uint8_t rsv,
const union wslay_event_msg_source source,
wslay_event_fragmented_msg_callback read_callback)
{
@ -240,6 +241,7 @@ static int wslay_event_omsg_fragmented_init
}
memset(*m, 0, sizeof(struct wslay_event_omsg));
(*m)->opcode = opcode;
(*m)->rsv = rsv;
(*m)->type = WSLAY_FRAGMENTED;
(*m)->source = source;
(*m)->read_callback = read_callback;
@ -301,7 +303,9 @@ int wslay_event_queue_close(wslay_event_context_ptr ctx, uint16_t status_code,
} else {
ncode = htons(status_code);
memcpy(msg, &ncode, 2);
memcpy(msg+2, reason, reason_length);
if(reason_length) {
memcpy(msg+2, reason, reason_length);
}
msg_length = reason_length+2;
}
arg.opcode = WSLAY_CONNECTION_CLOSE;
@ -328,19 +332,33 @@ static int wslay_event_queue_close_wrapper
return 0;
}
static int wslay_event_verify_rsv_bits(wslay_event_context_ptr ctx, uint8_t rsv)
{
return ((rsv & ~ctx->allowed_rsv_bits) == 0);
}
int wslay_event_queue_msg(wslay_event_context_ptr ctx,
const struct wslay_event_msg *arg)
{
return wslay_event_queue_msg_ex(ctx, arg, WSLAY_RSV_NONE);
}
int wslay_event_queue_msg_ex(wslay_event_context_ptr ctx,
const struct wslay_event_msg *arg, uint8_t rsv)
{
int r;
struct wslay_event_omsg *omsg;
if(!wslay_event_is_msg_queueable(ctx)) {
return WSLAY_ERR_NO_MORE_MSG;
}
if(wslay_is_ctrl_frame(arg->opcode) && arg->msg_length > 125) {
/* RSV1 is not allowed for control frames */
if((wslay_is_ctrl_frame(arg->opcode) &&
(arg->msg_length > 125 || wslay_get_rsv1(rsv)))
|| !wslay_event_verify_rsv_bits(ctx, rsv)) {
return WSLAY_ERR_INVALID_ARGUMENT;
}
if((r = wslay_event_omsg_non_fragmented_init
(&omsg, arg->opcode, arg->msg, arg->msg_length)) != 0) {
(&omsg, arg->opcode, rsv, arg->msg, arg->msg_length)) != 0) {
return r;
}
if(wslay_is_ctrl_frame(arg->opcode)) {
@ -359,17 +377,24 @@ int wslay_event_queue_msg(wslay_event_context_ptr ctx,
int wslay_event_queue_fragmented_msg
(wslay_event_context_ptr ctx, const struct wslay_event_fragmented_msg *arg)
{
return wslay_event_queue_fragmented_msg_ex(ctx, arg, WSLAY_RSV_NONE);
}
int wslay_event_queue_fragmented_msg_ex(wslay_event_context_ptr ctx,
const struct wslay_event_fragmented_msg *arg, uint8_t rsv)
{
int r;
struct wslay_event_omsg *omsg;
if(!wslay_event_is_msg_queueable(ctx)) {
return WSLAY_ERR_NO_MORE_MSG;
}
if(wslay_is_ctrl_frame(arg->opcode)) {
if(wslay_is_ctrl_frame(arg->opcode) ||
!wslay_event_verify_rsv_bits(ctx, rsv)) {
return WSLAY_ERR_INVALID_ARGUMENT;
}
if((r = wslay_event_omsg_fragmented_init
(&omsg, arg->opcode, arg->source, arg->read_callback)) != 0) {
(&omsg, arg->opcode, rsv, arg->source, arg->read_callback)) != 0) {
return r;
}
if((r = wslay_queue_push(ctx->send_queue, omsg)) != 0) {
@ -547,9 +572,11 @@ int wslay_event_recv(wslay_event_context_ptr ctx)
r = wslay_frame_recv(ctx->frame_ctx, &iocb);
if(r >= 0) {
int new_frame = 0;
/* We only allow rsv == 0 ATM. */
if(iocb.rsv != 0 ||
((ctx->server && !iocb.mask) || (!ctx->server && iocb.mask))) {
/* RSV1 is not allowed on control and continuation frames */
if((!wslay_event_verify_rsv_bits(ctx, iocb.rsv)) ||
(wslay_get_rsv1(iocb.rsv) && (wslay_is_ctrl_frame(iocb.opcode) ||
iocb.opcode == WSLAY_CONTINUATION_FRAME)) ||
(ctx->server && !iocb.mask) || (!ctx->server && iocb.mask)) {
if((r = wslay_event_queue_close_wrapper
(ctx, WSLAY_CODE_PROTOCOL_ERROR, NULL, 0)) != 0) {
return r;
@ -608,8 +635,10 @@ int wslay_event_recv(wslay_event_context_ptr ctx)
}
}
}
if(ctx->imsg->opcode == WSLAY_TEXT_FRAME ||
ctx->imsg->opcode == WSLAY_CONNECTION_CLOSE) {
/* If RSV1 bit is set then it is too early for utf-8 validation */
if((!wslay_get_rsv1(ctx->imsg->rsv) &&
ctx->imsg->opcode == WSLAY_TEXT_FRAME) ||
ctx->imsg->opcode == WSLAY_CONNECTION_CLOSE) {
size_t i;
if(ctx->imsg->opcode == WSLAY_CONNECTION_CLOSE) {
i = 2;
@ -815,6 +844,7 @@ int wslay_event_send(wslay_event_context_ptr ctx)
memset(&iocb, 0, sizeof(iocb));
iocb.fin = 1;
iocb.opcode = ctx->omsg->opcode;
iocb.rsv = ctx->omsg->rsv;
iocb.mask = ctx->server^1;
iocb.data = ctx->omsg->data+ctx->opayloadoff;
iocb.data_length = ctx->opayloadlen-ctx->opayloadoff;
@ -871,6 +901,7 @@ int wslay_event_send(wslay_event_context_ptr ctx)
memset(&iocb, 0, sizeof(iocb));
iocb.fin = ctx->omsg->fin;
iocb.opcode = ctx->omsg->opcode;
iocb.rsv = ctx->omsg->rsv;
iocb.mask = ctx->server ? 0 : 1;
iocb.data = ctx->obufmark;
iocb.data_length = ctx->obuflimit-ctx->obufmark;
@ -886,6 +917,8 @@ int wslay_event_send(wslay_event_context_ptr ctx)
ctx->omsg = NULL;
} else {
ctx->omsg->opcode = WSLAY_CONTINUATION_FRAME;
/* RSV1 is not set on continuation frames */
ctx->omsg->rsv = ctx->omsg->rsv & ~WSLAY_RSV1_BIT;
}
} else {
break;
@ -951,6 +984,13 @@ int wslay_event_get_close_sent(wslay_event_context_ptr ctx)
return (ctx->close_status & WSLAY_CLOSE_SENT) > 0;
}
void wslay_event_config_set_allowed_rsv_bits(wslay_event_context_ptr ctx,
uint8_t rsv)
{
/* We currently only allow WSLAY_RSV1_BIT or WSLAY_RSV_NONE */
ctx->allowed_rsv_bits = rsv & WSLAY_RSV1_BIT;
}
void wslay_event_config_set_no_buffering(wslay_event_context_ptr ctx, int val)
{
if(val) {

View File

@ -56,6 +56,7 @@ enum wslay_event_msg_type {
struct wslay_event_omsg {
uint8_t fin;
uint8_t opcode;
uint8_t rsv;
enum wslay_event_msg_type type;
uint8_t *data;
@ -135,6 +136,7 @@ struct wslay_event_context {
struct wslay_event_callbacks callbacks;
struct wslay_event_frame_user_data frame_user_data;
void *user_data;
uint8_t allowed_rsv_bits;
};
#endif /* WSLAY_EVENT_H */

View File

@ -44,6 +44,7 @@ static int clean_suite1(void)
int main(void)
{
CU_pSuite pSuite = NULL;
unsigned int num_tests_failed;
/* initialize the CUnit test registry */
if (CUE_SUCCESS != CU_initialize_registry())
@ -93,8 +94,14 @@ int main(void)
test_wslay_event_send_fragmented_msg) ||
!CU_add_test(pSuite, "wslay_event_send_fragmented_msg_with_ctrl",
test_wslay_event_send_fragmented_msg_with_ctrl) ||
!CU_add_test(pSuite, "wslay_event_send_fragmented_msg_with_rsv1",
test_wslay_event_send_fragmented_msg_with_rsv1) ||
!CU_add_test(pSuite, "wslay_event_send_msg_with_rsv1",
test_wslay_event_send_msg_with_rsv1) ||
!CU_add_test(pSuite, "wslay_event_send_ctrl_msg_first",
test_wslay_event_send_ctrl_msg_first) ||
!CU_add_test(pSuite, "wslay_event_send_ctrl_msg_with_rsv1",
test_wslay_event_send_ctrl_msg_with_rsv1) ||
!CU_add_test(pSuite, "wslay_event_queue_close",
test_wslay_event_queue_close) ||
!CU_add_test(pSuite, "wslay_event_queue_close_without_code",
@ -109,10 +116,14 @@ int main(void)
test_wslay_event_callback_failure) ||
!CU_add_test(pSuite, "wslay_event_no_buffering",
test_wslay_event_no_buffering) ||
!CU_add_test(pSuite, "wslay_event_recv_text_frame_with_rsv1",
test_wslay_event_recv_text_frame_with_rsv1) ||
!CU_add_test(pSuite, "wslay_event_frame_too_big",
test_wslay_event_frame_too_big) ||
!CU_add_test(pSuite, "wslay_event_message_too_big",
test_wslay_event_message_too_big) ||
!CU_add_test(pSuite, "wslay_event_config_set_allowed_rsv_bits",
test_wslay_event_config_set_allowed_rsv_bits) ||
!CU_add_test(pSuite, "wslay_queue", test_wslay_queue)) {
CU_cleanup_registry();
return CU_get_error();
@ -121,6 +132,12 @@ int main(void)
/* Run all tests using the CUnit Basic interface */
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
num_tests_failed = CU_get_number_of_tests_failed();
CU_cleanup_registry();
return CU_get_error();
if (CU_get_error() == CUE_SUCCESS) {
return (int)num_tests_failed;
} else {
printf("CUnit Error: %s\n", CU_get_error_msg());
return CU_get_error();
}
}

View File

@ -214,6 +214,71 @@ void test_wslay_event_send_fragmented_msg_with_ctrl(void)
wslay_event_context_free(ctx);
}
void test_wslay_event_send_fragmented_msg_with_rsv1(void)
{
wslay_event_context_ptr ctx;
struct wslay_event_callbacks callbacks;
struct my_user_data ud;
struct accumulator acc;
const char msg[] = "Hello";
struct scripted_data_feed df;
struct wslay_event_fragmented_msg arg;
const uint8_t ans[] = {
0x41, 0x03, 0x48, 0x65, 0x6c,
0x80, 0x02, 0x6c, 0x6f
};
scripted_data_feed_init(&df, (const uint8_t*)msg, sizeof(msg)-1);
df.feedseq[0] = 3;
df.feedseq[1] = 2;
memset(&callbacks, 0, sizeof(callbacks));
callbacks.send_callback = accumulator_send_callback;
memset(&acc, 0, sizeof(acc));
ud.acc = &acc;
wslay_event_context_server_init(&ctx, &callbacks, &ud);
wslay_event_config_set_allowed_rsv_bits(ctx, WSLAY_RSV1_BIT);
memset(&arg, 0, sizeof(arg));
arg.opcode = WSLAY_TEXT_FRAME;
arg.source.data = &df;
arg.read_callback = scripted_read_callback;
CU_ASSERT(0 ==
wslay_event_queue_fragmented_msg_ex(ctx, &arg, WSLAY_RSV1_BIT));
CU_ASSERT(0 == wslay_event_send(ctx));
CU_ASSERT_EQUAL(9, acc.length);
CU_ASSERT(0 == memcmp(ans, acc.buf, acc.length));
wslay_event_context_free(ctx);
}
void test_wslay_event_send_msg_with_rsv1(void)
{
wslay_event_context_ptr ctx;
struct wslay_event_callbacks callbacks;
struct my_user_data ud;
struct accumulator acc;
const char msg[] = "Hello";
struct wslay_event_msg arg;
const uint8_t ans[] = {
0xc1, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f /* "Hello" */
};
memset(&callbacks, 0, sizeof(callbacks));
callbacks.send_callback = accumulator_send_callback;
memset(&acc, 0, sizeof(acc));
ud.acc = &acc;
wslay_event_context_server_init(&ctx, &callbacks, &ud);
wslay_event_config_set_allowed_rsv_bits(ctx, WSLAY_RSV1_BIT);
memset(&arg, 0, sizeof(arg));
arg.opcode = WSLAY_TEXT_FRAME;
arg.msg = (const uint8_t*)msg;
arg.msg_length = 5;
CU_ASSERT(0 == wslay_event_queue_msg_ex(ctx, &arg, WSLAY_RSV1_BIT));
CU_ASSERT(0 == wslay_event_send(ctx));
CU_ASSERT(7 == acc.length);
CU_ASSERT(0 == memcmp(ans, acc.buf, acc.length));
wslay_event_context_free(ctx);
}
void test_wslay_event_send_ctrl_msg_first(void)
{
wslay_event_context_ptr ctx;
@ -246,6 +311,26 @@ void test_wslay_event_send_ctrl_msg_first(void)
wslay_event_context_free(ctx);
}
void test_wslay_event_send_ctrl_msg_with_rsv1(void)
{
wslay_event_context_ptr ctx;
struct wslay_event_callbacks callbacks;
struct wslay_event_msg arg;
memset(&callbacks, 0, sizeof(callbacks));
wslay_event_context_server_init(&ctx, &callbacks, NULL);
wslay_event_config_set_allowed_rsv_bits(ctx, WSLAY_RSV1_BIT);
memset(&arg, 0, sizeof(arg));
arg.opcode = WSLAY_PING;
arg.msg_length = 0;
CU_ASSERT(WSLAY_ERR_INVALID_ARGUMENT ==
wslay_event_queue_msg_ex(ctx, &arg, WSLAY_RSV1_BIT));
wslay_event_context_free(ctx);
}
void test_wslay_event_queue_close(void)
{
wslay_event_context_ptr ctx;
@ -422,6 +507,89 @@ void test_wslay_event_no_buffering(void)
wslay_event_context_free(ctx);
}
static void
text_rsv1_on_msg_recv_callback(wslay_event_context_ptr ctx,
const struct wslay_event_on_msg_recv_arg *arg,
void *user_data)
{
CU_ASSERT(WSLAY_TEXT_FRAME == arg->opcode);
CU_ASSERT(WSLAY_RSV1_BIT == arg->rsv);
}
void test_wslay_event_recv_text_frame_with_rsv1(void)
{
wslay_event_context_ptr ctx;
struct wslay_event_callbacks callbacks;
struct my_user_data ud;
const uint8_t msg[] = {
0xc1, 0x07, 0xf2, 0x48, 0xcd, 0xc9, 0xc9, 0x07, 0x00 // "Hello" pm-deflate
};
const uint8_t fragmented[] = {
0x41, 0x03, 0xf2, 0x48, 0xcd, // First fragment
0x80, 0x04, 0xc9, 0xc9, 0x07, 0x00 // Second fragment, RSV1 bit off
};
const uint8_t bad_fragment[] = {
0x41, 0x03, 0xf2, 0x48, 0xcd,
0xc0, 0x04, 0xc9, 0xc9, 0x07, 0x00 // RSV1 bit on
};
const uint8_t pingmsg[] = {
0xc9, 0x03, 0x46, 0x6f, 0x6f /* ping with "Foo" */
};
struct scripted_data_feed df;
/* Message marked with RSV1 should skip UTF-8 validation */
scripted_data_feed_init(&df, (const uint8_t*)msg, sizeof(msg));
memset(&callbacks, 0, sizeof(callbacks));
ud.df = &df;
callbacks.recv_callback = scripted_recv_callback;
callbacks.on_msg_recv_callback = text_rsv1_on_msg_recv_callback;
wslay_event_context_client_init(&ctx, &callbacks, &ud);
wslay_event_config_set_allowed_rsv_bits(ctx, WSLAY_RSV1_BIT);
CU_ASSERT(0 == wslay_event_recv(ctx));
CU_ASSERT(0 == wslay_event_want_write(ctx));
wslay_event_context_free(ctx);
/* UTF-8 validation is skipped for continuation frames if the
* initial frame was marked with RSV1 bit */
scripted_data_feed_init(&df, (const uint8_t*)fragmented, sizeof(fragmented));
memset(&callbacks, 0, sizeof(callbacks));
ud.df = &df;
callbacks.recv_callback = scripted_recv_callback;
callbacks.on_msg_recv_callback = text_rsv1_on_msg_recv_callback;
wslay_event_context_client_init(&ctx, &callbacks, &ud);
wslay_event_config_set_allowed_rsv_bits(ctx, WSLAY_RSV1_BIT);
CU_ASSERT(0 == wslay_event_recv(ctx));
CU_ASSERT(0 == wslay_event_want_write(ctx));
wslay_event_context_free(ctx);
/* disallow RSV1 */
scripted_data_feed_init(&df, (const uint8_t*)msg, sizeof(msg));
wslay_event_context_client_init(&ctx, &callbacks, &ud);
CU_ASSERT(0 == wslay_event_recv(ctx));
/* Close frame must be queued */
CU_ASSERT(wslay_event_want_write(ctx));
wslay_event_context_free(ctx);
/* RSV1 is not allowed in continuation frame */
scripted_data_feed_init(&df, (const uint8_t*)bad_fragment,
sizeof(bad_fragment));
wslay_event_context_client_init(&ctx, &callbacks, &ud);
wslay_event_config_set_allowed_rsv_bits(ctx, WSLAY_RSV1_BIT);
CU_ASSERT(0 == wslay_event_recv(ctx));
/* Close frame must be queued */
CU_ASSERT(wslay_event_want_write(ctx));
wslay_event_context_free(ctx);
/* RSV1 is not allowed in ping frame */
scripted_data_feed_init(&df, (const uint8_t*)pingmsg, sizeof(pingmsg));
wslay_event_context_client_init(&ctx, &callbacks, &ud);
wslay_event_config_set_allowed_rsv_bits(ctx, WSLAY_RSV1_BIT);
CU_ASSERT(0 == wslay_event_recv(ctx));
/* Close frame must be queued */
CU_ASSERT(wslay_event_want_write(ctx));
wslay_event_context_free(ctx);
}
void test_wslay_event_frame_too_big(void)
{
wslay_event_context_ptr ctx;
@ -489,3 +657,29 @@ void test_wslay_event_message_too_big(void)
wslay_event_get_status_code_sent(ctx));
wslay_event_context_free(ctx);
}
void test_wslay_event_config_set_allowed_rsv_bits(void)
{
wslay_event_context_ptr ctx;
struct wslay_event_callbacks callbacks;
memset(&callbacks, 0, sizeof(callbacks));
CU_ASSERT(0 == wslay_event_context_server_init(&ctx, &callbacks, NULL));
CU_ASSERT(WSLAY_RSV_NONE == ctx->allowed_rsv_bits);
wslay_event_config_set_allowed_rsv_bits(ctx, WSLAY_RSV1_BIT);
CU_ASSERT(WSLAY_RSV1_BIT == ctx->allowed_rsv_bits);
wslay_event_config_set_allowed_rsv_bits(ctx, WSLAY_RSV1_BIT | WSLAY_RSV2_BIT |
WSLAY_RSV3_BIT);
CU_ASSERT(WSLAY_RSV1_BIT == ctx->allowed_rsv_bits);
wslay_event_config_set_allowed_rsv_bits(ctx, WSLAY_RSV2_BIT | WSLAY_RSV3_BIT);
CU_ASSERT(WSLAY_RSV_NONE == ctx->allowed_rsv_bits);
wslay_event_context_free(ctx);
}

View File

@ -27,7 +27,10 @@
void test_wslay_event_send_fragmented_msg(void);
void test_wslay_event_send_fragmented_msg_with_ctrl(void);
void test_wslay_event_send_fragmented_msg_with_rsv1(void);
void test_wslay_event_send_msg_with_rsv1(void);
void test_wslay_event_send_ctrl_msg_first(void);
void test_wslay_event_send_ctrl_msg_with_rsv1(void);
void test_wslay_event_queue_close(void);
void test_wslay_event_queue_close_without_code(void);
void test_wslay_event_recv_close_without_code(void);
@ -35,7 +38,9 @@ void test_wslay_event_reply_close(void);
void test_wslay_event_no_more_msg(void);
void test_wslay_event_callback_failure(void);
void test_wslay_event_no_buffering(void);
void test_wslay_event_recv_text_frame_with_rsv1(void);
void test_wslay_event_frame_too_big(void);
void test_wslay_event_message_too_big(void);
void test_wslay_event_config_set_allowed_rsv_bits(void);
#endif /* WSLAY_EVENT_TEST_H */