diff --git a/wish/cpp/CMakeLists.txt b/wish/cpp/CMakeLists.txt index a1989c4..583536f 100644 --- a/wish/cpp/CMakeLists.txt +++ b/wish/cpp/CMakeLists.txt @@ -152,6 +152,7 @@ include_directories(src) # Build as a static library: libevent is also static and was not compiled with # -fPIC, so it cannot be linked into a shared object. add_library(buffer_event_web_stream STATIC + src/web_stream.h src/buffer_event_web_stream.cc src/buffer_event_web_stream.h ${libevent_SOURCE_DIR}/bufferevent_openssl.c diff --git a/wish/cpp/patches/wslay-disable-mask.patch b/wish/cpp/patches/wslay-disable-mask.patch index 874e319..416c4cd 100644 --- a/wish/cpp/patches/wslay-disable-mask.patch +++ b/wish/cpp/patches/wslay-disable-mask.patch @@ -1,3 +1,15 @@ +diff --git a/lib/includes/wslay/wslay.h b/lib/includes/wslay/wslay.h +index b73e6d8..80a5f78 100644 +--- a/lib/includes/wslay/wslay.h ++++ b/lib/includes/wslay/wslay.h +@@ -132,6 +132,7 @@ enum wslay_opcode { + WSLAY_CONTINUATION_FRAME = 0x0u, + WSLAY_TEXT_FRAME = 0x1u, + WSLAY_BINARY_FRAME = 0x2u, ++ WSLAY_METADATA_FRAME = 0x3u, + WSLAY_CONNECTION_CLOSE = 0x8u, + WSLAY_PING = 0x9u, + WSLAY_PONG = 0xau diff --git a/lib/wslay_event.c b/lib/wslay_event.c index 4c29fe4..93e9255 100644 --- a/lib/wslay_event.c @@ -11,6 +23,14 @@ index 4c29fe4..93e9255 100644 if ((r = wslay_event_queue_close_wrapper(ctx, WSLAY_CODE_PROTOCOL_ERROR, NULL, 0)) != 0) { return (int)r; +@@ -519,6 +519,7 @@ int wslay_event_recv(wslay_event_context_ptr ctx) { + if (ctx->imsg->opcode == 0xffu) { + if (iocb.opcode == WSLAY_TEXT_FRAME || + iocb.opcode == WSLAY_BINARY_FRAME || ++ iocb.opcode == WSLAY_METADATA_FRAME || + iocb.opcode == WSLAY_CONNECTION_CLOSE || + iocb.opcode == WSLAY_PING || iocb.opcode == WSLAY_PONG) { + wslay_event_imsg_set(ctx->imsg, iocb.fin, iocb.rsv, iocb.opcode); @@ -775,7 +775,7 @@ int wslay_event_send(wslay_event_context_ptr ctx) { iocb.fin = 1; iocb.opcode = ctx->omsg->opcode; diff --git a/wish/cpp/src/buffer_event_web_stream_test.cc b/wish/cpp/src/buffer_event_web_stream_test.cc index 5191d85..5d14e4a 100644 --- a/wish/cpp/src/buffer_event_web_stream_test.cc +++ b/wish/cpp/src/buffer_event_web_stream_test.cc @@ -234,3 +234,64 @@ TEST_F(BufferEventWebStreamTest, CloseSignalsEOF) { // Only delete server. delete server; } + +// Verify that metadata frames (opcode = 3) can be sent and received correctly by both client and server. +TEST_F(BufferEventWebStreamTest, HandshakeAndMetadataExchange) { + bufferevent* pair[2]; + int rv = bufferevent_pair_new(base_, + BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS, + pair); + ASSERT_EQ(rv, 0); + + BufferEventWebStream* server = new BufferEventWebStream(pair[0], true /* is_server */); + BufferEventWebStream* client = new BufferEventWebStream(pair[1], false /* is_server */); + + bool server_opened = false; + bool client_opened = false; + std::string metadata_from_client; + std::string metadata_from_server; + + server->SetOnOpen([&]() { + server_opened = true; + server->SendMetadata("Server Metadata"); + }); + + client->SetOnOpen([&]() { + client_opened = true; + client->SendMetadata("Client Metadata"); + }); + + auto check_done = [&]() { + if (!metadata_from_client.empty() && !metadata_from_server.empty()) { + event_base_loopbreak(base_); + } + }; + + server->SetOnMessage([&](uint8_t opcode, const std::string& msg) { + if (opcode == WEB_STREAM_OPCODE_METADATA) { + metadata_from_client = msg; + } + check_done(); + }); + + client->SetOnMessage([&](uint8_t opcode, const std::string& msg) { + if (opcode == WEB_STREAM_OPCODE_METADATA) { + metadata_from_server = msg; + } + check_done(); + }); + + server->Start(); + client->Start(); + + event_base_dispatch(base_); + + EXPECT_TRUE(client_opened); + EXPECT_TRUE(server_opened); + EXPECT_EQ(metadata_from_client, "Client Metadata"); + EXPECT_EQ(metadata_from_server, "Server Metadata"); + + delete server; + delete client; +} +