mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-19 11:15:50 +00:00
feat: Dosguard API weights (#2082)
Experimental support for Dosguard API weights.
This commit is contained in:
@@ -165,75 +165,13 @@ struct RequestHandlerTest : SyncAsioContextTest, WebHandlersTest {
|
||||
|
||||
testing::StrictMock<RpcHandlerMock> rpcHandler;
|
||||
StrictMockConnection connectionMock{ip, boost::beast::flat_buffer{}, tagFactory};
|
||||
RequestHandler<RpcHandlerMock> requestHandler{adminVerifier, rpcHandler, dosGuardMock};
|
||||
RequestHandler<RpcHandlerMock> requestHandler{adminVerifier, rpcHandler};
|
||||
};
|
||||
|
||||
TEST_F(RequestHandlerTest, DosguardRateLimited_Http)
|
||||
{
|
||||
web::ng::Request const request{http::request<http::string_body>{http::verb::get, "/", 11}};
|
||||
|
||||
EXPECT_CALL(dosGuardMock, request(ip)).WillOnce(testing::Return(false));
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto response = requestHandler(request, connectionMock, nullptr, yield);
|
||||
auto const httpResponse = std::move(response).intoHttpResponse();
|
||||
|
||||
EXPECT_EQ(httpResponse.result(), boost::beast::http::status::service_unavailable);
|
||||
|
||||
auto const body = boost::json::parse(httpResponse.body()).as_object();
|
||||
EXPECT_EQ(body.at("error").as_string(), "slowDown");
|
||||
EXPECT_EQ(body.at("error_code").as_int64(), rpc::RippledError::rpcSLOW_DOWN);
|
||||
EXPECT_EQ(body.at("status").as_string(), "error");
|
||||
EXPECT_FALSE(body.contains("id"));
|
||||
EXPECT_FALSE(body.contains("request"));
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RequestHandlerTest, DosguardRateLimited_Ws)
|
||||
{
|
||||
auto const requestMessage = R"json({"some": "request", "id": "some id"})json";
|
||||
web::ng::Request::HttpHeaders const headers{};
|
||||
web::ng::Request const request{requestMessage, headers};
|
||||
|
||||
EXPECT_CALL(dosGuardMock, request(ip)).WillOnce(testing::Return(false));
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto const response = requestHandler(request, connectionMock, nullptr, yield);
|
||||
auto const message = boost::json::parse(response.message()).as_object();
|
||||
|
||||
EXPECT_EQ(message.at("error").as_string(), "slowDown");
|
||||
EXPECT_EQ(message.at("error_code").as_int64(), rpc::RippledError::rpcSLOW_DOWN);
|
||||
EXPECT_EQ(message.at("status").as_string(), "error");
|
||||
EXPECT_EQ(message.at("id").as_string(), "some id");
|
||||
EXPECT_EQ(message.at("request").as_string(), requestMessage);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RequestHandlerTest, DosguardRateLimited_Ws_ErrorParsing)
|
||||
{
|
||||
auto const requestMessage = R"json(some request "id": "some id")json";
|
||||
web::ng::Request::HttpHeaders const headers{};
|
||||
web::ng::Request const request{requestMessage, headers};
|
||||
|
||||
EXPECT_CALL(dosGuardMock, request(ip)).WillOnce(testing::Return(false));
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto const response = requestHandler(request, connectionMock, nullptr, yield);
|
||||
auto const message = boost::json::parse(response.message()).as_object();
|
||||
|
||||
EXPECT_EQ(message.at("error").as_string(), "slowDown");
|
||||
EXPECT_EQ(message.at("error_code").as_int64(), rpc::RippledError::rpcSLOW_DOWN);
|
||||
EXPECT_EQ(message.at("status").as_string(), "error");
|
||||
EXPECT_FALSE(message.contains("id"));
|
||||
EXPECT_EQ(message.at("request").as_string(), requestMessage);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RequestHandlerTest, RpcHandlerThrows)
|
||||
{
|
||||
web::ng::Request const request{http::request<http::string_body>{http::verb::get, "/", 11}};
|
||||
|
||||
EXPECT_CALL(dosGuardMock, request(ip)).WillOnce(testing::Return(true));
|
||||
EXPECT_CALL(*adminVerifier, isAdmin).WillOnce(testing::Return(true));
|
||||
EXPECT_CALL(rpcHandler, call).WillOnce(testing::Throw(std::runtime_error{"some error"}));
|
||||
|
||||
@@ -257,10 +195,8 @@ TEST_F(RequestHandlerTest, NoErrors)
|
||||
web::ng::Response const response{http::status::ok, "some response", request};
|
||||
auto const httpResponse = web::ng::Response{response}.intoHttpResponse();
|
||||
|
||||
EXPECT_CALL(dosGuardMock, request(ip)).WillOnce(testing::Return(true));
|
||||
EXPECT_CALL(*adminVerifier, isAdmin).WillOnce(testing::Return(true));
|
||||
EXPECT_CALL(rpcHandler, call).WillOnce(testing::Return(response));
|
||||
EXPECT_CALL(dosGuardMock, add(ip, testing::_)).WillOnce(testing::Return(true));
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto actualResponse = requestHandler(request, connectionMock, nullptr, yield);
|
||||
@@ -272,55 +208,3 @@ TEST_F(RequestHandlerTest, NoErrors)
|
||||
EXPECT_EQ(actualHttpResponse.version(), 11);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RequestHandlerTest, ResponseDosGuardWarning_ResponseHasWarnings)
|
||||
{
|
||||
web::ng::Request const request{http::request<http::string_body>{http::verb::get, "/", 11}};
|
||||
web::ng::Response const response{
|
||||
http::status::ok, R"json({"some":"response", "warnings":["some warning"]})json", request
|
||||
};
|
||||
auto const httpResponse = web::ng::Response{response}.intoHttpResponse();
|
||||
|
||||
EXPECT_CALL(dosGuardMock, request(ip)).WillOnce(testing::Return(true));
|
||||
EXPECT_CALL(*adminVerifier, isAdmin).WillOnce(testing::Return(true));
|
||||
EXPECT_CALL(rpcHandler, call).WillOnce(testing::Return(response));
|
||||
EXPECT_CALL(dosGuardMock, add(ip, testing::_)).WillOnce(testing::Return(false));
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto actualResponse = requestHandler(request, connectionMock, nullptr, yield);
|
||||
|
||||
auto const actualHttpResponse = std::move(actualResponse).intoHttpResponse();
|
||||
|
||||
EXPECT_EQ(actualHttpResponse.result(), httpResponse.result());
|
||||
EXPECT_EQ(actualHttpResponse.version(), 11);
|
||||
|
||||
auto actualBody = boost::json::parse(actualHttpResponse.body()).as_object();
|
||||
EXPECT_EQ(actualBody.at("some").as_string(), "response");
|
||||
EXPECT_EQ(actualBody.at("warnings").as_array().size(), 2);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RequestHandlerTest, ResponseDosGuardWarning_ResponseDoesntHaveWarnings)
|
||||
{
|
||||
web::ng::Request const request{http::request<http::string_body>{http::verb::get, "/", 11}};
|
||||
web::ng::Response const response{http::status::ok, R"json({"some":"response"})json", request};
|
||||
auto const httpResponse = web::ng::Response{response}.intoHttpResponse();
|
||||
|
||||
EXPECT_CALL(dosGuardMock, request(ip)).WillOnce(testing::Return(true));
|
||||
EXPECT_CALL(*adminVerifier, isAdmin).WillOnce(testing::Return(true));
|
||||
EXPECT_CALL(rpcHandler, call).WillOnce(testing::Return(response));
|
||||
EXPECT_CALL(dosGuardMock, add(ip, testing::_)).WillOnce(testing::Return(false));
|
||||
|
||||
runSpawn([&](boost::asio::yield_context yield) {
|
||||
auto actualResponse = requestHandler(request, connectionMock, nullptr, yield);
|
||||
|
||||
auto const actualHttpResponse = std::move(actualResponse).intoHttpResponse();
|
||||
|
||||
EXPECT_EQ(actualHttpResponse.result(), httpResponse.result());
|
||||
EXPECT_EQ(actualHttpResponse.version(), 11);
|
||||
|
||||
auto actualBody = boost::json::parse(actualHttpResponse.body()).as_object();
|
||||
EXPECT_EQ(actualBody.at("some").as_string(), "response");
|
||||
EXPECT_EQ(actualBody.at("warnings").as_array().size(), 1);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user