mirror of
https://github.com/XRPLF/clio.git
synced 2025-12-06 17:27:58 +00:00
refactor: Coroutine based webserver (#1699)
Code of new coroutine-based web server. The new server is not connected to Clio and not ready to use yet. For #919.
This commit is contained in:
committed by
Alex Kremer
parent
5c77e59374
commit
b8f1deb90f
@@ -20,7 +20,9 @@
|
||||
#include "util/AssignRandomPort.hpp"
|
||||
#include "util/LoggerFixtures.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/TestHttpSyncClient.hpp"
|
||||
#include "util/TestHttpClient.hpp"
|
||||
#include "util/TestWebSocketClient.hpp"
|
||||
#include "util/TmpFile.hpp"
|
||||
#include "util/config/Config.hpp"
|
||||
#include "util/prometheus/Gauge.hpp"
|
||||
#include "util/prometheus/Label.hpp"
|
||||
@@ -45,6 +47,7 @@
|
||||
#include <fmt/core.h>
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <test_data/SslCert.hpp>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
@@ -103,14 +106,6 @@ generateJSONDataOverload(std::string_view port)
|
||||
));
|
||||
}
|
||||
|
||||
boost::json::value
|
||||
addSslConfig(boost::json::value config)
|
||||
{
|
||||
config.as_object()["ssl_key_file"] = TEST_DATA_SSL_KEY_PATH;
|
||||
config.as_object()["ssl_cert_file"] = TEST_DATA_SSL_CERT_PATH;
|
||||
return config;
|
||||
}
|
||||
|
||||
struct WebServerTest : NoLoggerFixture {
|
||||
~WebServerTest() override
|
||||
{
|
||||
@@ -126,6 +121,14 @@ struct WebServerTest : NoLoggerFixture {
|
||||
runner.emplace([this] { ctx.run(); });
|
||||
}
|
||||
|
||||
boost::json::value
|
||||
addSslConfig(boost::json::value config) const
|
||||
{
|
||||
config.as_object()["ssl_key_file"] = sslKeyFile.path;
|
||||
config.as_object()["ssl_cert_file"] = sslCertFile.path;
|
||||
return config;
|
||||
}
|
||||
|
||||
// this ctx is for dos timer
|
||||
boost::asio::io_context ctxSync;
|
||||
std::string const port = std::to_string(tests::util::generateFreePort());
|
||||
@@ -141,6 +144,9 @@ struct WebServerTest : NoLoggerFixture {
|
||||
// this ctx is for http server
|
||||
boost::asio::io_context ctx;
|
||||
|
||||
TmpFile sslCertFile{tests::sslCertFile()};
|
||||
TmpFile sslKeyFile{tests::sslKeyFile()};
|
||||
|
||||
private:
|
||||
std::optional<boost::asio::io_service::work> work;
|
||||
std::optional<std::thread> runner;
|
||||
@@ -212,7 +218,7 @@ TEST_F(WebServerTestsWithMockPrometheus, Http)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
|
||||
auto const res = HttpSyncClient::syncPost("localhost", port, R"({"Hello":1})");
|
||||
auto const res = HttpSyncClient::post("localhost", port, R"({"Hello":1})");
|
||||
EXPECT_EQ(res, R"({"Hello":1})");
|
||||
}
|
||||
|
||||
@@ -236,7 +242,7 @@ TEST_F(WebServerTestsWithMockPrometheus, HttpInternalError)
|
||||
{
|
||||
auto e = std::make_shared<ExceptionExecutor>();
|
||||
auto const server = makeServerSync(cfg, ctx, dosGuard, e);
|
||||
auto const res = HttpSyncClient::syncPost("localhost", port, R"({})");
|
||||
auto const res = HttpSyncClient::post("localhost", port, R"({})");
|
||||
EXPECT_EQ(
|
||||
res,
|
||||
R"({"error":"internal","error_code":73,"error_message":"Internal error.","status":"error","type":"response"})"
|
||||
@@ -286,7 +292,7 @@ TEST_F(WebServerTestsWithMockPrometheus, IncompleteSslConfig)
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
|
||||
auto jsonConfig = generateJSONWithDynamicPort(port);
|
||||
jsonConfig.as_object()["ssl_key_file"] = TEST_DATA_SSL_KEY_PATH;
|
||||
jsonConfig.as_object()["ssl_key_file"] = sslKeyFile.path;
|
||||
|
||||
auto const server = makeServerSync(Config{jsonConfig}, ctx, dosGuard, e);
|
||||
EXPECT_EQ(server, nullptr);
|
||||
@@ -297,7 +303,7 @@ TEST_F(WebServerTestsWithMockPrometheus, WrongSslConfig)
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
|
||||
auto jsonConfig = generateJSONWithDynamicPort(port);
|
||||
jsonConfig.as_object()["ssl_key_file"] = TEST_DATA_SSL_KEY_PATH;
|
||||
jsonConfig.as_object()["ssl_key_file"] = sslKeyFile.path;
|
||||
jsonConfig.as_object()["ssl_cert_file"] = "wrong_path";
|
||||
|
||||
auto const server = makeServerSync(Config{jsonConfig}, ctx, dosGuard, e);
|
||||
@@ -334,9 +340,9 @@ TEST_F(WebServerTestsWithMockPrometheus, HttpRequestOverload)
|
||||
{
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto const server = makeServerSync(cfg, ctx, dosGuardOverload, e);
|
||||
auto res = HttpSyncClient::syncPost("localhost", port, R"({})");
|
||||
auto res = HttpSyncClient::post("localhost", port, R"({})");
|
||||
EXPECT_EQ(res, "{}");
|
||||
res = HttpSyncClient::syncPost("localhost", port, R"({})");
|
||||
res = HttpSyncClient::post("localhost", port, R"({})");
|
||||
EXPECT_EQ(
|
||||
res,
|
||||
R"({"error":"slowDown","error_code":10,"error_message":"You are placing too much load on the server.","status":"error","type":"response"})"
|
||||
@@ -372,7 +378,7 @@ TEST_F(WebServerTestsWithMockPrometheus, HttpPayloadOverload)
|
||||
std::string const s100(100, 'a');
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
auto server = makeServerSync(cfg, ctx, dosGuardOverload, e);
|
||||
auto const res = HttpSyncClient::syncPost("localhost", port, fmt::format(R"({{"payload":"{}"}})", s100));
|
||||
auto const res = HttpSyncClient::post("localhost", port, fmt::format(R"({{"payload":"{}"}})", s100));
|
||||
EXPECT_EQ(
|
||||
res,
|
||||
R"({"payload":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","warning":"load","warnings":[{"id":2003,"message":"You are about to be rate limited"}]})"
|
||||
@@ -535,7 +541,7 @@ TEST_P(WebServerAdminTest, HttpAdminCheck)
|
||||
auto server = makeServerSync(serverConfig, ctx, dosGuardOverload, e);
|
||||
std::string const request = "Why hello";
|
||||
uint32_t const webServerPort = serverConfig.value<uint32_t>("server.port");
|
||||
auto const res = HttpSyncClient::syncPost("localhost", std::to_string(webServerPort), request, GetParam().headers);
|
||||
auto const res = HttpSyncClient::post("localhost", std::to_string(webServerPort), request, GetParam().headers);
|
||||
EXPECT_EQ(res, fmt::format("{} {}", request, GetParam().expectedResponse));
|
||||
}
|
||||
|
||||
@@ -653,7 +659,7 @@ TEST_F(WebServerPrometheusTest, rejectedWithoutAdminPassword)
|
||||
uint32_t const webServerPort = tests::util::generateFreePort();
|
||||
Config const serverConfig{boost::json::parse(JSONServerConfigWithAdminPassword(webServerPort))};
|
||||
auto server = makeServerSync(serverConfig, ctx, dosGuard, e);
|
||||
auto const res = HttpSyncClient::syncGet("localhost", std::to_string(webServerPort), "", "/metrics");
|
||||
auto const res = HttpSyncClient::get("localhost", std::to_string(webServerPort), "", "/metrics");
|
||||
EXPECT_EQ(res, "Only admin is allowed to collect metrics");
|
||||
}
|
||||
|
||||
@@ -676,7 +682,7 @@ TEST_F(WebServerPrometheusTest, rejectedIfPrometheusIsDisabled)
|
||||
Config const serverConfig{boost::json::parse(JSONServerConfigWithDisabledPrometheus)};
|
||||
PrometheusService::init(serverConfig);
|
||||
auto server = makeServerSync(serverConfig, ctx, dosGuard, e);
|
||||
auto const res = HttpSyncClient::syncGet(
|
||||
auto const res = HttpSyncClient::get(
|
||||
"localhost",
|
||||
std::to_string(webServerPort),
|
||||
"",
|
||||
@@ -697,7 +703,7 @@ TEST_F(WebServerPrometheusTest, validResponse)
|
||||
auto e = std::make_shared<EchoExecutor>();
|
||||
Config const serverConfig{boost::json::parse(JSONServerConfigWithAdminPassword(webServerPort))};
|
||||
auto server = makeServerSync(serverConfig, ctx, dosGuard, e);
|
||||
auto const res = HttpSyncClient::syncGet(
|
||||
auto const res = HttpSyncClient::get(
|
||||
"localhost",
|
||||
std::to_string(webServerPort),
|
||||
"",
|
||||
|
||||
Reference in New Issue
Block a user