fix: Fix bugs in new webserver (#1780)

Fixes #919.

Fixes bugs for new webserver:
- Unhandled exception when closing already closed websocket
- No pings for plain websocket connection
- Server drops websocket connection when client responds to pings but
doesn't send anything

Also changing API of ng connections. Now timeout is set by a separate
method instead of providing it for each call.
This commit is contained in:
Sergey Kuznetsov
2024-12-19 15:14:04 +00:00
committed by GitHub
parent c4b87d2a0a
commit 7d4e3619b0
13 changed files with 238 additions and 204 deletions

View File

@@ -159,7 +159,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_NoHandler_Send)
.WillOnce(Return(makeRequest("some_request", headers_)))
.WillOnce(Return(makeError(websocket::error::closed)));
EXPECT_CALL(*mockHttpConnection_, send).WillOnce([](Response response, auto&&, auto&&) {
EXPECT_CALL(*mockHttpConnection_, send).WillOnce([](Response response, auto&&) {
EXPECT_EQ(response.message(), "WebSocket is not supported by this server");
return std::nullopt;
});
@@ -183,7 +183,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_BadTarget_Send)
.WillOnce(Return(makeRequest(http::request<http::string_body>{http::verb::get, target, 11, requestMessage})))
.WillOnce(Return(makeError(http::error::end_of_stream)));
EXPECT_CALL(*mockHttpConnection_, send).WillOnce([](Response response, auto&&, auto&&) {
EXPECT_CALL(*mockHttpConnection_, send).WillOnce([](Response response, auto&&) {
EXPECT_EQ(response.message(), "Bad target");
auto const httpResponse = std::move(response).intoHttpResponse();
EXPECT_EQ(httpResponse.result(), http::status::bad_request);
@@ -207,7 +207,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_BadMethod_Send)
.WillOnce(Return(makeRequest(http::request<http::string_body>{http::verb::acl, "/", 11})))
.WillOnce(Return(makeError(http::error::end_of_stream)));
EXPECT_CALL(*mockHttpConnection_, send).WillOnce([](Response response, auto&&, auto&&) {
EXPECT_CALL(*mockHttpConnection_, send).WillOnce([](Response response, auto&&) {
EXPECT_EQ(response.message(), "Unsupported http method");
return std::nullopt;
});
@@ -241,7 +241,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_Send)
return Response(http::status::ok, responseMessage, request);
});
EXPECT_CALL(*mockWsConnection_, send).WillOnce([&responseMessage](Response response, auto&&, auto&&) {
EXPECT_CALL(*mockWsConnection_, send).WillOnce([&responseMessage](Response response, auto&&) {
EXPECT_EQ(response.message(), responseMessage);
return std::nullopt;
});
@@ -279,7 +279,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, SendSubscriptionMessage)
EXPECT_CALL(*mockWsConnection_, send).WillOnce(Return(std::nullopt));
EXPECT_CALL(*mockWsConnection_, sendBuffer)
.WillOnce([&subscriptionMessage](boost::asio::const_buffer buffer, auto&&, auto&&) {
.WillOnce([&subscriptionMessage](boost::asio::const_buffer buffer, auto&&) {
EXPECT_EQ(boost::beast::buffers_to_string(buffer), subscriptionMessage);
return std::nullopt;
});
@@ -353,7 +353,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, SubscriptionContextIsNullForHt
return Response(http::status::ok, responseMessage, request);
});
EXPECT_CALL(*mockHttpConnection_, send).WillOnce([&responseMessage](Response response, auto&&, auto&&) {
EXPECT_CALL(*mockHttpConnection_, send).WillOnce([&responseMessage](Response response, auto&&) {
EXPECT_EQ(response.message(), responseMessage);
return std::nullopt;
});
@@ -395,12 +395,10 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_Send_Loop)
return Response(http::status::ok, responseMessage, request);
});
EXPECT_CALL(*mockHttpConnection_, send)
.Times(3)
.WillRepeatedly([&responseMessage](Response response, auto&&, auto&&) {
EXPECT_EQ(response.message(), responseMessage);
return std::nullopt;
});
EXPECT_CALL(*mockHttpConnection_, send).Times(3).WillRepeatedly([&responseMessage](Response response, auto&&) {
EXPECT_EQ(response.message(), responseMessage);
return std::nullopt;
});
EXPECT_CALL(*mockHttpConnection_, close);
@@ -434,7 +432,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Receive_Handle_SendError)
return Response(http::status::ok, responseMessage, request);
});
EXPECT_CALL(*mockHttpConnection_, send).WillOnce([&responseMessage](Response response, auto&&, auto&&) {
EXPECT_CALL(*mockHttpConnection_, send).WillOnce([&responseMessage](Response response, auto&&) {
EXPECT_EQ(response.message(), responseMessage);
return makeError(http::error::end_of_stream).error();
});
@@ -460,14 +458,12 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Stop)
bool connectionClosed = false;
EXPECT_CALL(*mockWsConnection_, wasUpgraded).WillOnce(Return(true));
EXPECT_CALL(*mockWsConnection_, receive)
.Times(4)
.WillRepeatedly([&](auto&&, auto&&) -> std::expected<Request, Error> {
if (connectionClosed) {
return makeError(websocket::error::closed);
}
return makeRequest(requestMessage, headers_);
});
EXPECT_CALL(*mockWsConnection_, receive).Times(4).WillRepeatedly([&](auto&&) -> std::expected<Request, Error> {
if (connectionClosed) {
return makeError(websocket::error::closed);
}
return makeRequest(requestMessage, headers_);
});
EXPECT_CALL(wsHandlerMock, Call).Times(3).WillRepeatedly([&](Request const& request, auto&&, auto&&, auto&&) {
EXPECT_EQ(request.message(), requestMessage);
@@ -475,7 +471,7 @@ TEST_F(ConnectionHandlerSequentialProcessingTest, Stop)
});
size_t numCalls = 0;
EXPECT_CALL(*mockWsConnection_, send).Times(3).WillRepeatedly([&](Response response, auto&&, auto&&) {
EXPECT_CALL(*mockWsConnection_, send).Times(3).WillRepeatedly([&](Response response, auto&&) {
EXPECT_EQ(response.message(), responseMessage);
++numCalls;
@@ -550,7 +546,7 @@ TEST_F(ConnectionHandlerParallelProcessingTest, Receive_Handle_Send)
return Response(http::status::ok, responseMessage, request);
});
EXPECT_CALL(*mockWsConnection_, send).WillOnce([&responseMessage](Response response, auto&&, auto&&) {
EXPECT_CALL(*mockWsConnection_, send).WillOnce([&responseMessage](Response response, auto&&) {
EXPECT_EQ(response.message(), responseMessage);
return std::nullopt;
});
@@ -574,7 +570,7 @@ TEST_F(ConnectionHandlerParallelProcessingTest, Receive_Handle_Send_Loop)
std::string const requestMessage = "some message";
std::string const responseMessage = "some response";
auto const returnRequest = [&](auto&&, auto&&) { return makeRequest(requestMessage, headers_); };
auto const returnRequest = [&](auto&&) { return makeRequest(requestMessage, headers_); };
EXPECT_CALL(*mockWsConnection_, wasUpgraded).WillOnce(Return(true));
EXPECT_CALL(*mockWsConnection_, receive)
@@ -587,12 +583,10 @@ TEST_F(ConnectionHandlerParallelProcessingTest, Receive_Handle_Send_Loop)
return Response(http::status::ok, responseMessage, request);
});
EXPECT_CALL(*mockWsConnection_, send)
.Times(2)
.WillRepeatedly([&responseMessage](Response response, auto&&, auto&&) {
EXPECT_EQ(response.message(), responseMessage);
return std::nullopt;
});
EXPECT_CALL(*mockWsConnection_, send).Times(2).WillRepeatedly([&responseMessage](Response response, auto&&) {
EXPECT_EQ(response.message(), responseMessage);
return std::nullopt;
});
EXPECT_CALL(onDisconnectMock_, Call).WillOnce([connectionPtr = mockWsConnection_.get()](Connection const& c) {
EXPECT_EQ(&c, connectionPtr);
@@ -613,7 +607,7 @@ TEST_F(ConnectionHandlerParallelProcessingTest, Receive_Handle_Send_Loop_TooMany
std::string const requestMessage = "some message";
std::string const responseMessage = "some response";
auto const returnRequest = [&](auto&&, auto&&) { return makeRequest(requestMessage, headers_); };
auto const returnRequest = [&](auto&&) { return makeRequest(requestMessage, headers_); };
testing::Sequence const sequence;
EXPECT_CALL(*mockWsConnection_, wasUpgraded).WillOnce(Return(true));
@@ -635,11 +629,7 @@ TEST_F(ConnectionHandlerParallelProcessingTest, Receive_Handle_Send_Loop_TooMany
EXPECT_CALL(
*mockWsConnection_,
send(
testing::ResultOf([](Response response) { return response.message(); }, responseMessage),
testing::_,
testing::_
)
send(testing::ResultOf([](Response response) { return response.message(); }, responseMessage), testing::_)
)
.Times(3)
.WillRepeatedly(Return(std::nullopt));
@@ -650,7 +640,6 @@ TEST_F(ConnectionHandlerParallelProcessingTest, Receive_Handle_Send_Loop_TooMany
testing::ResultOf(
[](Response response) { return response.message(); }, "Too many requests for one connection"
),
testing::_,
testing::_
)
)