|
@@ -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);
|
|
|
+}
|