Unverified Commit 6bbcebf8 authored by Raphael's avatar Raphael Committed by GitHub

Merge pull request #1403

Fix flow setup for WebSocket servers
parents 73c3ad38 a928b44b
......@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file. The format
is based on [Keep a Changelog](https://keepachangelog.com).
## [Unreleased]
### Fixed
- Fix flow setup for servers that use `web_socket::with`. This bug caused
servers to immediately abort incoming connection (#1402).
- Make sure that a protocol stack ships pending data before closing a socket.
This bug prevented clients from receiving error messages from servers if the
server shuts down immediately after writing the message.
## [0.19.0] - 2023-04-17
### Added
......
......@@ -93,6 +93,13 @@ int caf_main(caf::actor_system& sys, const config& cfg) {
// ... that simply pushes data back to the sender.
auto [pull, push] = ev.data();
pull.observe_on(self)
.do_on_error([](const caf::error& what) { //
std::cout << "*** connection closed: " << to_string(what)
<< "\n";
})
.do_on_complete([] { //
std::cout << "*** connection closed\n";
})
.do_on_next([](const ws::frame& x) {
if (x.is_binary()) {
std::cout
......@@ -115,7 +122,7 @@ int caf_main(caf::actor_system& sys, const config& cfg) {
return EXIT_FAILURE;
}
// Note: the actor system will keep the application running for as long as the
// workers are still alive.
// worker from .start() is still alive.
return EXIT_SUCCESS;
}
// --(rst-main-end)--
......
......@@ -78,6 +78,7 @@ public:
(*on_request_)(acc);
if (acc.accepted()) {
app_event = std::move(acc.app_event);
ws_resources = std::move(acc.ws_resources);
return {};
}
return std::move(acc) //
......
......@@ -214,16 +214,16 @@ void transport::handle_buffered_data() {
auto delta = bytes.subspan(delta_offset_);
auto consumed = up_->consume(bytes, delta);
if (consumed < 0) {
// Negative values indicate that the application encountered an
// unrecoverable error.
// Negative values indicate that the application wants to close the
// socket. We still make sure to send any pending data before closing.
up_->abort(make_error(caf::sec::runtime_error, "consumed < 0"));
parent_->deregister();
parent_->deregister_reading();
return;
} else if (static_cast<size_t>(consumed) > n) {
// Must not happen. An application cannot handle more data then we pass
// to it.
up_->abort(make_error(sec::logic_error, "consumed > buffer.size"));
parent_->deregister();
parent_->deregister_reading();
return;
} else if (consumed == 0) {
if (next_) {
......
......@@ -17,3 +17,12 @@ add_test(
--variable BINARY_PATH:$<TARGET_FILE:quote-server>
--variable SSL_PATH:${CMAKE_CURRENT_SOURCE_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/web_socket/quote-server.robot")
add_test(
NAME "robot-web-socket-echo"
COMMAND
${Python_EXECUTABLE}
-m robot
--variable BINARY_PATH:$<TARGET_FILE:echo>
--variable SSL_PATH:${CMAKE_CURRENT_SOURCE_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/web_socket/echo.robot")
*** Settings ***
Documentation A test suite for examples/web_socket/echo-server
Library Collections
Library Process
Library RequestsLibrary
Library WebSocketClient
Suite Setup Start Servers
Suite Teardown Stop Servers
*** Variables ***
${HTTP_URL} http://localhost:55501
${HTTPS_URL} https://localhost:55502
${WS_URL} ws://localhost:55501
${WSS_URL} wss://localhost:55502
${FRAME_COUNT} ${10}
${BINARY_PATH} /path/to/the/server
${SSL_PATH} /path/to/the/pem/files
*** Test Cases ***
Test WebSocket Server
[Tags] WebSocket
${fd}= WebSocketClient.Connect ${WS_URL}
WebSocketClient.Send ${fd} Hello
${result}= WebSocketClient.Recv ${fd}
WebSocketClient.Close ${fd}
Should Be Equal ${result} Hello
Test WebSocket Over SSL Server
[Tags] WebSocket
${ssl_arg}= Evaluate {"cert_reqs": ssl.CERT_NONE}
${fd}= WebSocketClient.Connect ${WSS_URL} sslopt=${ssl_arg}
WebSocketClient.Send ${fd} Hello
${result}= WebSocketClient.Recv ${fd}
WebSocketClient.Close ${fd}
Should Be Equal ${result} Hello
*** Keywords ***
Start Servers
${res1}= Start Process ${BINARY_PATH} -p 55501
Set Suite Variable ${ws_server_process} ${res1}
${res2}= Start Process ${BINARY_PATH} -p 55502 -k ${SSL_PATH}/key.pem -c ${SSL_PATH}/cert.pem
Set Suite Variable ${wss_server_process} ${res2}
Wait Until Keyword Succeeds 5s 125ms Check If HTTP Server Is Reachable
Wait Until Keyword Succeeds 5s 125ms Check If HTTPS Server Is Reachable
Stop Servers
Terminate Process ${ws_server_process}
Terminate Process ${wss_server_process}
Check If HTTP Server Is Reachable
# The server sends a "400 Bad Request" if we try HTTP on the WebSocket port.
# This is because the server is configured to only accept WebSocket
# connections. However, we can still use this behavior to check if the
# server is up and running.
Log Try reaching ${HTTP_URL}.
${resp}= GET ${HTTP_URL} expected_status=400
Check If HTTPS Server Is Reachable
Log Try reaching ${HTTPS_URL}.
${resp}= GET ${HTTPS_URL} expected_status=400 verify=${False}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment