mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-18 10:45:51 +00:00
@@ -58,8 +58,21 @@ public:
|
||||
* @param connection The connection
|
||||
*/
|
||||
void
|
||||
operator()(boost::json::object&& req, std::shared_ptr<Server::ConnectionBase> const& connection)
|
||||
operator()(std::string const& reqStr, std::shared_ptr<Server::ConnectionBase> const& connection)
|
||||
{
|
||||
auto req = boost::json::object{};
|
||||
try
|
||||
{
|
||||
req = boost::json::parse(reqStr).as_object();
|
||||
}
|
||||
catch (boost::exception const& _)
|
||||
{
|
||||
connection->send(
|
||||
boost::json::serialize(RPC::makeError(RPC::RippledError::rpcBAD_SYNTAX)),
|
||||
boost::beast::http::status::ok);
|
||||
return;
|
||||
}
|
||||
|
||||
perfLog_.debug() << connection->tag() << "Adding to work queue";
|
||||
// specially handle for http connections
|
||||
if (!connection->upgraded)
|
||||
|
||||
@@ -207,21 +207,9 @@ public:
|
||||
|
||||
log_.info() << tag() << "Received request from ip = " << clientIp << " - posting to WorkQueue";
|
||||
|
||||
auto request = boost::json::object{};
|
||||
try
|
||||
{
|
||||
request = boost::json::parse(req_.body()).as_object();
|
||||
}
|
||||
catch (boost::exception const& e)
|
||||
{
|
||||
return sender_(httpResponse(
|
||||
http::status::ok,
|
||||
"application/json",
|
||||
boost::json::serialize(RPC::makeError(RPC::RippledError::rpcBAD_SYNTAX))));
|
||||
}
|
||||
try
|
||||
{
|
||||
(*handler_)(std::move(request), derived().shared_from_this());
|
||||
(*handler_)(req_.body(), derived().shared_from_this());
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
|
||||
@@ -221,12 +221,19 @@ public:
|
||||
|
||||
perfLog_.info() << tag() << "Received request from ip = " << this->clientIp;
|
||||
|
||||
auto sendError = [this](auto error, boost::json::value const& request) {
|
||||
auto sendError = [this](auto error, std::string&& requestStr) {
|
||||
auto e = RPC::makeError(error);
|
||||
|
||||
if (request.is_object() && request.as_object().contains("id"))
|
||||
e["id"] = request.as_object().at("id");
|
||||
e["request"] = request;
|
||||
try
|
||||
{
|
||||
auto request = boost::json::parse(requestStr);
|
||||
if (request.is_object() && request.as_object().contains("id"))
|
||||
e["id"] = request.as_object().at("id");
|
||||
e["request"] = std::move(request);
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
e["request"] = std::move(requestStr);
|
||||
}
|
||||
|
||||
auto responseStr = boost::json::serialize(e);
|
||||
log_.trace() << responseStr;
|
||||
@@ -236,37 +243,21 @@ public:
|
||||
|
||||
std::string msg{static_cast<char const*>(buffer_.data().data()), buffer_.size()};
|
||||
|
||||
boost::json::value raw = [](std::string&& msg) {
|
||||
try
|
||||
{
|
||||
return boost::json::parse(msg);
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
return boost::json::value{msg};
|
||||
}
|
||||
}(std::move(msg));
|
||||
|
||||
// dosGuard served request++ and check ip address
|
||||
if (!dosGuard_.get().request(clientIp))
|
||||
{
|
||||
sendError(RPC::RippledError::rpcSLOW_DOWN, raw);
|
||||
}
|
||||
else if (!raw.is_object())
|
||||
{
|
||||
sendError(RPC::RippledError::rpcBAD_SYNTAX, raw);
|
||||
sendError(RPC::RippledError::rpcSLOW_DOWN, std::move(msg));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto request = raw.as_object();
|
||||
try
|
||||
{
|
||||
(*handler_)(std::move(request), shared_from_this());
|
||||
(*handler_)(msg, shared_from_this());
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
perfLog_.error() << tag() << "Caught exception : " << e.what();
|
||||
sendError(RPC::RippledError::rpcINTERNAL, raw);
|
||||
sendError(RPC::RippledError::rpcINTERNAL, std::move(msg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <webserver/interface/ConnectionBase.h>
|
||||
|
||||
#include <boost/beast.hpp>
|
||||
#include <boost/json.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -33,9 +32,9 @@ namespace Server {
|
||||
*/
|
||||
// clang-format off
|
||||
template <typename T>
|
||||
concept ServerHandler = requires(T handler, boost::json::object&& req, std::shared_ptr<ConnectionBase> const& ws, boost::beast::error_code ec) {
|
||||
concept ServerHandler = requires(T handler, std::string const& req, std::shared_ptr<ConnectionBase> const& ws, boost::beast::error_code ec) {
|
||||
// the callback when server receives a request
|
||||
{ handler(std::move(req), ws) };
|
||||
{ handler(req, ws) };
|
||||
// the callback when there is an error
|
||||
{ handler(ec, ws) };
|
||||
};
|
||||
|
||||
@@ -84,11 +84,10 @@ protected:
|
||||
|
||||
TEST_F(WebRPCExecutorTest, HTTPDefaultPath)
|
||||
{
|
||||
auto request = boost::json::parse(R"({
|
||||
"method": "server_info",
|
||||
"params": [{}]
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({
|
||||
"method": "server_info",
|
||||
"params": [{}]
|
||||
})";
|
||||
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
@@ -119,11 +118,10 @@ TEST_F(WebRPCExecutorTest, HTTPDefaultPath)
|
||||
TEST_F(WebRPCExecutorTest, WsNormalPath)
|
||||
{
|
||||
session->upgraded = true;
|
||||
auto request = boost::json::parse(R"({
|
||||
"command": "server_info",
|
||||
"id": 99
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({
|
||||
"command": "server_info",
|
||||
"id": 99
|
||||
})";
|
||||
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
@@ -155,11 +153,10 @@ TEST_F(WebRPCExecutorTest, WsNormalPath)
|
||||
|
||||
TEST_F(WebRPCExecutorTest, HTTPForwardedPath)
|
||||
{
|
||||
auto request = boost::json::parse(R"({
|
||||
"method": "server_info",
|
||||
"params": [{}]
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({
|
||||
"method": "server_info",
|
||||
"params": [{}]
|
||||
})";
|
||||
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
@@ -197,11 +194,10 @@ TEST_F(WebRPCExecutorTest, HTTPForwardedPath)
|
||||
TEST_F(WebRPCExecutorTest, WsForwardedPath)
|
||||
{
|
||||
session->upgraded = true;
|
||||
auto request = boost::json::parse(R"({
|
||||
"command": "server_info",
|
||||
"id": 99
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({
|
||||
"command": "server_info",
|
||||
"id": 99
|
||||
})";
|
||||
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
@@ -275,14 +271,13 @@ TEST_F(WebRPCExecutorTest, HTTPErrorPath)
|
||||
}
|
||||
]
|
||||
})";
|
||||
auto request = boost::json::parse(requestJSON).as_object();
|
||||
EXPECT_CALL(*rpcEngine, buildResponse(testing::_))
|
||||
.WillOnce(testing::Return(RPC::Status{RPC::RippledError::rpcINVALID_PARAMS, "ledgerIndexMalformed"}));
|
||||
EXPECT_CALL(*rpcEngine, notifyErrored("ledger")).Times(1);
|
||||
|
||||
EXPECT_CALL(*etl, lastCloseAgeSeconds()).WillOnce(testing::Return(45));
|
||||
|
||||
(*rpcExecutor)(std::move(request), session);
|
||||
(*rpcExecutor)(std::move(requestJSON), session);
|
||||
std::this_thread::sleep_for(200ms);
|
||||
EXPECT_EQ(boost::json::parse(session->message), boost::json::parse(response));
|
||||
}
|
||||
@@ -318,25 +313,23 @@ TEST_F(WebRPCExecutorTest, WsErrorPath)
|
||||
"ledger_index": "xx",
|
||||
"id": "123"
|
||||
})";
|
||||
auto request = boost::json::parse(requestJSON).as_object();
|
||||
EXPECT_CALL(*rpcEngine, buildResponse(testing::_))
|
||||
.WillOnce(testing::Return(RPC::Status{RPC::RippledError::rpcINVALID_PARAMS, "ledgerIndexMalformed"}));
|
||||
EXPECT_CALL(*rpcEngine, notifyErrored("ledger")).Times(1);
|
||||
|
||||
EXPECT_CALL(*etl, lastCloseAgeSeconds()).WillOnce(testing::Return(45));
|
||||
|
||||
(*rpcExecutor)(std::move(request), session);
|
||||
(*rpcExecutor)(std::move(requestJSON), session);
|
||||
std::this_thread::sleep_for(200ms);
|
||||
EXPECT_EQ(boost::json::parse(session->message), boost::json::parse(response));
|
||||
}
|
||||
|
||||
TEST_F(WebRPCExecutorTest, HTTPNotReady)
|
||||
{
|
||||
auto request = boost::json::parse(R"({
|
||||
"method": "server_info",
|
||||
"params": [{}]
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({
|
||||
"method": "server_info",
|
||||
"params": [{}]
|
||||
})";
|
||||
|
||||
static auto constexpr response = R"({
|
||||
"result":{
|
||||
@@ -365,11 +358,10 @@ TEST_F(WebRPCExecutorTest, WsNotReady)
|
||||
{
|
||||
session->upgraded = true;
|
||||
|
||||
auto request = boost::json::parse(R"({
|
||||
"command": "server_info",
|
||||
"id": 99
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({
|
||||
"command": "server_info",
|
||||
"id": 99
|
||||
})";
|
||||
|
||||
static auto constexpr response = R"({
|
||||
"error":"notReady",
|
||||
@@ -391,10 +383,7 @@ TEST_F(WebRPCExecutorTest, WsNotReady)
|
||||
|
||||
TEST_F(WebRPCExecutorTest, HTTPBadSyntax)
|
||||
{
|
||||
auto request = boost::json::parse(R"({
|
||||
"method2": "server_info"
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({"method2": "server_info"})";
|
||||
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
@@ -420,10 +409,7 @@ TEST_F(WebRPCExecutorTest, HTTPBadSyntax)
|
||||
|
||||
TEST_F(WebRPCExecutorTest, HTTPBadSyntaxWhenRequestSubscribe)
|
||||
{
|
||||
auto request = boost::json::parse(R"({
|
||||
"method": "subscribe"
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({"method": "subscribe"})";
|
||||
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
@@ -450,12 +436,10 @@ TEST_F(WebRPCExecutorTest, HTTPBadSyntaxWhenRequestSubscribe)
|
||||
TEST_F(WebRPCExecutorTest, WsBadSyntax)
|
||||
{
|
||||
session->upgraded = true;
|
||||
auto request = boost::json::parse(R"(
|
||||
{
|
||||
"command2": "server_info",
|
||||
"id": 99
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({
|
||||
"command2": "server_info",
|
||||
"id": 99
|
||||
})";
|
||||
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
@@ -509,10 +493,9 @@ TEST_F(WebRPCExecutorTest, HTTPInternalError)
|
||||
}
|
||||
]
|
||||
})";
|
||||
auto request = boost::json::parse(requestJSON).as_object();
|
||||
EXPECT_CALL(*rpcEngine, buildResponse(testing::_)).Times(1).WillOnce(testing::Throw(std::runtime_error("MyError")));
|
||||
|
||||
(*rpcExecutor)(std::move(request), session);
|
||||
(*rpcExecutor)(std::move(requestJSON), session);
|
||||
std::this_thread::sleep_for(200ms);
|
||||
EXPECT_EQ(boost::json::parse(session->message), boost::json::parse(response));
|
||||
}
|
||||
@@ -541,21 +524,19 @@ TEST_F(WebRPCExecutorTest, WsInternalError)
|
||||
"command": "ledger",
|
||||
"id": "123"
|
||||
})";
|
||||
auto request = boost::json::parse(requestJSON).as_object();
|
||||
EXPECT_CALL(*rpcEngine, buildResponse(testing::_)).Times(1).WillOnce(testing::Throw(std::runtime_error("MyError")));
|
||||
|
||||
(*rpcExecutor)(std::move(request), session);
|
||||
(*rpcExecutor)(std::move(requestJSON), session);
|
||||
std::this_thread::sleep_for(200ms);
|
||||
EXPECT_EQ(boost::json::parse(session->message), boost::json::parse(response));
|
||||
}
|
||||
|
||||
TEST_F(WebRPCExecutorTest, HTTPOutDated)
|
||||
{
|
||||
auto request = boost::json::parse(R"({
|
||||
"method": "server_info",
|
||||
"params": [{}]
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({
|
||||
"method": "server_info",
|
||||
"params": [{}]
|
||||
})";
|
||||
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
@@ -591,11 +572,10 @@ TEST_F(WebRPCExecutorTest, WsOutdated)
|
||||
{
|
||||
session->upgraded = true;
|
||||
|
||||
auto request = boost::json::parse(R"({
|
||||
"command": "server_info",
|
||||
"id": 99
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({
|
||||
"command": "server_info",
|
||||
"id": 99
|
||||
})";
|
||||
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
@@ -636,17 +616,22 @@ TEST_F(WebRPCExecutorTest, WsTooBusy)
|
||||
auto rpcEngine2 = std::make_shared<MockRPCEngine>();
|
||||
auto rpcExecutor2 =
|
||||
std::make_shared<RPCExecutor<MockRPCEngine, MockETLService>>(cfg, mockBackendPtr, rpcEngine2, etl, subManager);
|
||||
auto request = boost::json::parse(R"({
|
||||
"command": "server_info",
|
||||
"id": 99
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({
|
||||
"command": "server_info",
|
||||
"id": 99
|
||||
})";
|
||||
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
|
||||
static auto constexpr response =
|
||||
R"({"error":"tooBusy","error_code":9,"error_message":"The server is too busy to help you now.","status":"error","type":"response"})";
|
||||
R"({
|
||||
"error":"tooBusy",
|
||||
"error_code":9,
|
||||
"error_message":"The server is too busy to help you now.",
|
||||
"status":"error",
|
||||
"type":"response"
|
||||
})";
|
||||
EXPECT_CALL(*rpcEngine2, post).WillOnce(testing::Return(false));
|
||||
(*rpcExecutor2)(std::move(request), session);
|
||||
EXPECT_EQ(boost::json::parse(session->message), boost::json::parse(response));
|
||||
@@ -657,19 +642,57 @@ TEST_F(WebRPCExecutorTest, HTTPTooBusy)
|
||||
auto rpcEngine2 = std::make_shared<MockRPCEngine>();
|
||||
auto rpcExecutor2 =
|
||||
std::make_shared<RPCExecutor<MockRPCEngine, MockETLService>>(cfg, mockBackendPtr, rpcEngine2, etl, subManager);
|
||||
auto request = boost::json::parse(R"({
|
||||
"method": "server_info",
|
||||
"params": [{}]
|
||||
})")
|
||||
.as_object();
|
||||
static auto constexpr request = R"({
|
||||
"method": "server_info",
|
||||
"params": [{}]
|
||||
})";
|
||||
|
||||
mockBackendPtr->updateRange(MINSEQ); // min
|
||||
mockBackendPtr->updateRange(MAXSEQ); // max
|
||||
|
||||
static auto constexpr response =
|
||||
R"({"error":"tooBusy","error_code":9,"error_message":"The server is too busy to help you now.","status":"error","type":"response"})";
|
||||
R"({
|
||||
"error":"tooBusy",
|
||||
"error_code":9,
|
||||
"error_message":"The server is too busy to help you now.",
|
||||
"status":"error",
|
||||
"type":"response"
|
||||
})";
|
||||
|
||||
EXPECT_CALL(*rpcEngine2, post).WillOnce(testing::Return(false));
|
||||
(*rpcExecutor2)(std::move(request), session);
|
||||
EXPECT_EQ(boost::json::parse(session->message), boost::json::parse(response));
|
||||
}
|
||||
|
||||
TEST_F(WebRPCExecutorTest, HTTPRequestNotJson)
|
||||
{
|
||||
static auto constexpr request = "not json";
|
||||
static auto constexpr response =
|
||||
R"({
|
||||
"error":"badSyntax",
|
||||
"error_code":1,
|
||||
"error_message":"Syntax error.",
|
||||
"status":"error",
|
||||
"type":"response"
|
||||
})";
|
||||
|
||||
(*rpcExecutor)(std::move(request), session);
|
||||
EXPECT_EQ(boost::json::parse(session->message), boost::json::parse(response));
|
||||
}
|
||||
|
||||
TEST_F(WebRPCExecutorTest, WsRequestNotJson)
|
||||
{
|
||||
session->upgraded = true;
|
||||
static auto constexpr request = "not json";
|
||||
static auto constexpr response =
|
||||
R"({
|
||||
"error":"badSyntax",
|
||||
"error_code":1,
|
||||
"error_message":"Syntax error.",
|
||||
"status":"error",
|
||||
"type":"response"
|
||||
})";
|
||||
|
||||
(*rpcExecutor)(std::move(request), session);
|
||||
EXPECT_EQ(boost::json::parse(session->message), boost::json::parse(response));
|
||||
}
|
||||
|
||||
@@ -162,9 +162,9 @@ class EchoExecutor
|
||||
{
|
||||
public:
|
||||
void
|
||||
operator()(boost::json::object&& req, std::shared_ptr<Server::ConnectionBase> const& ws)
|
||||
operator()(std::string const& reqStr, std::shared_ptr<Server::ConnectionBase> const& ws)
|
||||
{
|
||||
ws->send(boost::json::serialize(req), http::status::ok);
|
||||
ws->send(std::string(reqStr), http::status::ok);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -177,7 +177,7 @@ class ExceptionExecutor
|
||||
{
|
||||
public:
|
||||
void
|
||||
operator()(boost::json::object&& req, std::shared_ptr<Server::ConnectionBase> const& ws)
|
||||
operator()(std::string const& req, std::shared_ptr<Server::ConnectionBase> const& ws)
|
||||
{
|
||||
throw std::runtime_error("MyError");
|
||||
}
|
||||
@@ -207,52 +207,6 @@ TEST_F(WebServerTest, Ws)
|
||||
wsClient.disconnect();
|
||||
}
|
||||
|
||||
TEST_F(WebServerTest, HttpBodyNotJsonValue)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const server = Server::make_HttpServer(cfg, ctx, std::nullopt, dosGuard, e);
|
||||
auto const res = HttpSyncClient::syncPost("localhost", "8888", R"({)");
|
||||
EXPECT_EQ(
|
||||
res,
|
||||
R"({"error":"badSyntax","error_code":1,"error_message":"Syntax error.","status":"error","type":"response"})");
|
||||
}
|
||||
|
||||
TEST_F(WebServerTest, HttpBodyNotJsonObject)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const server = Server::make_HttpServer(cfg, ctx, std::nullopt, dosGuard, e);
|
||||
auto const res = HttpSyncClient::syncPost("localhost", "8888", R"("123")");
|
||||
EXPECT_EQ(
|
||||
res,
|
||||
R"({"error":"badSyntax","error_code":1,"error_message":"Syntax error.","status":"error","type":"response"})");
|
||||
}
|
||||
|
||||
TEST_F(WebServerTest, WsBodyNotJsonValue)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
WebSocketSyncClient wsClient;
|
||||
auto const server = Server::make_HttpServer(cfg, ctx, std::nullopt, dosGuard, e);
|
||||
wsClient.connect("localhost", "8888");
|
||||
auto const res = wsClient.syncPost(R"({)");
|
||||
wsClient.disconnect();
|
||||
EXPECT_EQ(
|
||||
res,
|
||||
R"({"error":"badSyntax","error_code":1,"error_message":"Syntax error.","status":"error","type":"response","request":["{"]})");
|
||||
}
|
||||
|
||||
TEST_F(WebServerTest, WsBodyNotJsonObject)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const server = Server::make_HttpServer(cfg, ctx, std::nullopt, dosGuard, e);
|
||||
WebSocketSyncClient wsClient;
|
||||
wsClient.connect("localhost", "8888");
|
||||
auto const res = wsClient.syncPost(R"("Hello")");
|
||||
wsClient.disconnect();
|
||||
EXPECT_EQ(
|
||||
res,
|
||||
R"({"error":"badSyntax","error_code":1,"error_message":"Syntax error.","status":"error","type":"response","request":"Hello"})");
|
||||
}
|
||||
|
||||
TEST_F(WebServerTest, HttpInternalError)
|
||||
{
|
||||
auto e = std::make_shared<ExceptionExecutor>();
|
||||
@@ -269,11 +223,24 @@ TEST_F(WebServerTest, WsInternalError)
|
||||
auto const server = Server::make_HttpServer(cfg, ctx, std::nullopt, dosGuard, e);
|
||||
WebSocketSyncClient wsClient;
|
||||
wsClient.connect("localhost", "8888");
|
||||
auto const res = wsClient.syncPost(R"({})");
|
||||
auto const res = wsClient.syncPost(R"({"id":"id1"})");
|
||||
wsClient.disconnect();
|
||||
EXPECT_EQ(
|
||||
res,
|
||||
R"({"error":"internal","error_code":73,"error_message":"Internal error.","status":"error","type":"response","request":{}})");
|
||||
R"({"error":"internal","error_code":73,"error_message":"Internal error.","status":"error","type":"response","id":"id1","request":{"id":"id1"}})");
|
||||
}
|
||||
|
||||
TEST_F(WebServerTest, WsInternalErrorNotJson)
|
||||
{
|
||||
auto e = std::make_shared<ExceptionExecutor>();
|
||||
auto const server = Server::make_HttpServer(cfg, ctx, std::nullopt, dosGuard, e);
|
||||
WebSocketSyncClient wsClient;
|
||||
wsClient.connect("localhost", "8888");
|
||||
auto const res = wsClient.syncPost("not json");
|
||||
wsClient.disconnect();
|
||||
EXPECT_EQ(
|
||||
res,
|
||||
R"({"error":"internal","error_code":73,"error_message":"Internal error.","status":"error","type":"response","request":"not json"})");
|
||||
}
|
||||
|
||||
TEST_F(WebServerTest, Https)
|
||||
|
||||
Reference in New Issue
Block a user