mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-23 13:45:04 +02:00
(WIP) Add unit-tests for HttpServerConnection (and later others)
This commit is contained in:
parent
fcad7f77cc
commit
42cee50cc0
@ -88,6 +88,8 @@ set(base_test_SOURCES
|
||||
icinga-perfdata.cpp
|
||||
methods-pluginnotificationtask.cpp
|
||||
remote-configpackageutility.cpp
|
||||
remote-httpserverconnection.cpp
|
||||
remote-httpmessage.cpp
|
||||
remote-url.cpp
|
||||
${base_OBJS}
|
||||
$<TARGET_OBJECTS:config>
|
||||
@ -271,6 +273,20 @@ add_boost_test(base
|
||||
icinga_perfdata/parse_edgecases
|
||||
icinga_perfdata/empty_warn_crit_min_max
|
||||
methods_pluginnotificationtask/truncate_long_output
|
||||
remote_httpmessage/request_parse
|
||||
# remote_httpmessage/request_params
|
||||
remote_httpserverconnection/setup_certs
|
||||
remote_httpserverconnection/expect_100_continue
|
||||
remote_httpserverconnection/bad_request
|
||||
remote_httpserverconnection/error_access_control
|
||||
remote_httpserverconnection/error_accept_header
|
||||
remote_httpserverconnection/error_authenticate_cn
|
||||
remote_httpserverconnection/error_authenticate_passwd
|
||||
remote_httpserverconnection/error_authenticate_wronguser
|
||||
remote_httpserverconnection/error_authenticate_wrongpasswd
|
||||
remote_httpserverconnection/reuse_connection_and_wg_abort
|
||||
remote_httpserverconnection/liveness_disconnect
|
||||
remote_httpserverconnection/cleanup_certs
|
||||
remote_configpackageutility/ValidateName
|
||||
remote_url/id_and_path
|
||||
remote_url/parameters
|
||||
@ -279,6 +295,32 @@ add_boost_test(base
|
||||
remote_url/illegal_legal_strings
|
||||
)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
set_tests_properties(
|
||||
base-remote_httpmessage/request_parse
|
||||
base-remote_httpserverconnection/expect_100_continue
|
||||
base-remote_httpserverconnection/bad_request
|
||||
base-remote_httpserverconnection/error_access_control
|
||||
base-remote_httpserverconnection/error_accept_header
|
||||
base-remote_httpserverconnection/error_authenticate_cn
|
||||
base-remote_httpserverconnection/error_authenticate_passwd
|
||||
base-remote_httpserverconnection/error_authenticate_wronguser
|
||||
base-remote_httpserverconnection/error_authenticate_wrongpasswd
|
||||
base-remote_httpserverconnection/reuse_connection_and_wg_abort
|
||||
base-remote_httpserverconnection/liveness_disconnect
|
||||
PROPERTIES FIXTURES_REQUIRED ssl_certs)
|
||||
|
||||
set_tests_properties(
|
||||
base-remote_httpserverconnection/setup_certs
|
||||
PROPERTIES FIXTURES_SETUP ssl_certs
|
||||
)
|
||||
|
||||
set_tests_properties(
|
||||
base-remote_httpserverconnection/cleanup_certs
|
||||
PROPERTIES FIXTURES_CLEANUP ssl_certs
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ICINGA2_WITH_LIVESTATUS)
|
||||
set(livestatus_test_SOURCES
|
||||
icingaapplication-fixture.cpp
|
||||
|
53
test/base-configuration-fixture.hpp
Normal file
53
test/base-configuration-fixture.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#ifndef CONFIGURATION_FIXTURE_H
|
||||
#define CONFIGURATION_FIXTURE_H
|
||||
|
||||
#include "base/configuration.hpp"
|
||||
#include "base/utility.hpp"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <BoostTestTargetConfig.h>
|
||||
|
||||
namespace icinga {
|
||||
|
||||
struct ConfigurationDataDirFixture
|
||||
{
|
||||
ConfigurationDataDirFixture()
|
||||
{
|
||||
Utility::MkDir(tmpDir, 0700);
|
||||
}
|
||||
|
||||
String tmpDir = boost::filesystem::temp_directory_path().append("icinga2").string();
|
||||
String previousDataDir = std::exchange(Configuration::DataDir, tmpDir);
|
||||
};
|
||||
|
||||
struct ConfigurationDataDirCleanupFixture: ConfigurationDataDirFixture
|
||||
{
|
||||
~ConfigurationDataDirCleanupFixture()
|
||||
{
|
||||
Utility::RemoveDirRecursive(std::exchange(Configuration::DataDir, previousDataDir));
|
||||
}
|
||||
};
|
||||
|
||||
struct ConfigurationCacheDirFixture
|
||||
{
|
||||
ConfigurationCacheDirFixture()
|
||||
{
|
||||
Utility::MkDir(tmpCacheDir, 0700);
|
||||
}
|
||||
|
||||
String tmpCacheDir = boost::filesystem::temp_directory_path().append("icinga2").append("cache").string();
|
||||
String previousCacheDir = std::exchange(Configuration::CacheDir, tmpCacheDir);
|
||||
};
|
||||
|
||||
struct ConfigurationCacheDirCleanupFixture: ConfigurationCacheDirFixture
|
||||
{
|
||||
~ConfigurationCacheDirCleanupFixture()
|
||||
{
|
||||
Utility::RemoveDirRecursive(std::exchange(Configuration::CacheDir, previousCacheDir));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace icinga
|
||||
|
||||
#endif // CONFIGURATION_FIXTURE_H
|
47
test/base-sslcert-fixture.hpp
Normal file
47
test/base-sslcert-fixture.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#ifndef SSLCERT_FIXTURE_H
|
||||
#define SSLCERT_FIXTURE_H
|
||||
|
||||
#include "remote/apilistener.hpp"
|
||||
#include "remote/pkiutility.hpp"
|
||||
#include "test/base-configuration-fixture.hpp"
|
||||
#include <BoostTestTargetConfig.h>
|
||||
|
||||
namespace icinga{
|
||||
|
||||
struct SslCertificateFixture: ConfigurationDataDirFixture
|
||||
{
|
||||
SslCertificateFixture()
|
||||
{
|
||||
caDir = ApiListener::GetCaDir();
|
||||
Utility::MkDir(caDir, 0700);
|
||||
certsDir = ApiListener::GetCertsDir();
|
||||
Utility::MkDir(certsDir, 0700);
|
||||
|
||||
PkiUtility::NewCa();
|
||||
if (!Utility::PathExists(certsDir+"ca.crt")) {
|
||||
Utility::CopyFile(caDir + "ca.crt", certsDir + "ca.crt");
|
||||
}
|
||||
}
|
||||
|
||||
~SslCertificateFixture() {}
|
||||
|
||||
void EnsureCertFor(const String& name)
|
||||
{
|
||||
auto certKeyFileName = certsDir + name + ".crt";
|
||||
|
||||
if (!Utility::PathExists(certKeyFileName)) {
|
||||
PkiUtility::NewCert(name, certsDir + name + ".key", certsDir + name + ".csr",
|
||||
certsDir + name + ".crt");
|
||||
PkiUtility::SignCsr(certsDir + name + ".csr", certsDir + name + ".crt");
|
||||
}
|
||||
}
|
||||
|
||||
String caDir;
|
||||
String certsDir;
|
||||
};
|
||||
|
||||
} // namespace icinga
|
||||
|
||||
#endif // SSLCERT_FIXTURE_H
|
91
test/base-tlsstream-fixture.hpp
Normal file
91
test/base-tlsstream-fixture.hpp
Normal file
@ -0,0 +1,91 @@
|
||||
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#ifndef TLSSTREAM_FIXTURE_H
|
||||
#define TLSSTREAM_FIXTURE_H
|
||||
|
||||
#include "test/base-sslcert-fixture.hpp"
|
||||
#include "base/tlsstream.hpp"
|
||||
#include "base/io-engine.hpp"
|
||||
#include <BoostTestTargetConfig.h>
|
||||
|
||||
namespace icinga {
|
||||
|
||||
/**
|
||||
* Creates a pair of TLS Streams on a random unused port.
|
||||
*/
|
||||
struct TlsStreamFixture: SslCertificateFixture
|
||||
{
|
||||
TlsStreamFixture()
|
||||
{
|
||||
using namespace boost::asio::ip;
|
||||
using handshake_type = boost::asio::ssl::stream_base::handshake_type;
|
||||
|
||||
EnsureCertFor("remote");
|
||||
EnsureCertFor("local");
|
||||
|
||||
auto& localContext = IoEngine::Get().GetIoContext();
|
||||
|
||||
remoteSslCtx = SetupSslContext(certsDir + "remote.crt", certsDir + "remote.key", caDir+"ca.crt", "", DEFAULT_TLS_CIPHERS,
|
||||
DEFAULT_TLS_PROTOCOLMIN, DebugInfo());
|
||||
client = Shared<AsioTlsStream>::Make(IoEngine::Get().GetIoContext(), *remoteSslCtx);
|
||||
|
||||
localSslCtx = SetupSslContext(certsDir + "local.crt", certsDir + "local.key", caDir+"ca.crt",
|
||||
"", DEFAULT_TLS_CIPHERS, DEFAULT_TLS_PROTOCOLMIN, DebugInfo());
|
||||
server = Shared<AsioTlsStream>::Make(localContext, *localSslCtx);
|
||||
|
||||
std::mutex handshakeMutex;
|
||||
std::condition_variable handshakeCv;
|
||||
bool handshakeDone = false;
|
||||
|
||||
tcp::acceptor acceptor{localContext, tcp::endpoint{make_address_v4("127.0.0.1"), 0}};
|
||||
acceptor.listen();
|
||||
acceptor.async_accept(server->lowest_layer(), [&, this](const boost::system::error_code& ec) {
|
||||
if (ec) {
|
||||
std::cout << "Local Accept Error: " << ec.message() << std::endl;
|
||||
return;
|
||||
}
|
||||
server->next_layer().async_handshake(handshake_type::server, [&, this](const boost::system::error_code& ec) {
|
||||
if (ec) {
|
||||
std::cout << "Local Handshake Error: " << ec.message() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
handshakeMutex.lock();
|
||||
handshakeDone = true;
|
||||
handshakeMutex.unlock();
|
||||
handshakeCv.notify_all();
|
||||
});
|
||||
});
|
||||
|
||||
boost::system::error_code ec;
|
||||
if (client->lowest_layer().connect(acceptor.local_endpoint(), ec)) {
|
||||
std::cout << "Client Connect error: " << ec.message() << std::endl;
|
||||
}
|
||||
|
||||
if (client->next_layer().handshake(handshake_type::client, ec)) {
|
||||
std::cout << "Client Handshake error: " << ec.message() << std::endl;
|
||||
}
|
||||
if (!client->next_layer().IsVerifyOK()) {
|
||||
std::cout << "Verify failed for connection" << std::endl;
|
||||
throw;
|
||||
}
|
||||
|
||||
std::unique_lock lock{handshakeMutex};
|
||||
handshakeCv.wait(lock, [&](){return handshakeDone;});
|
||||
}
|
||||
|
||||
~TlsStreamFixture()
|
||||
{
|
||||
std::cout << "TlsStreamFixture done" << std::endl;
|
||||
}
|
||||
|
||||
Shared<boost::asio::ssl::context>::Ptr remoteSslCtx;
|
||||
Shared<AsioTlsStream>::Ptr client;
|
||||
|
||||
Shared<boost::asio::ssl::context>::Ptr localSslCtx;
|
||||
Shared<AsioTlsStream>::Ptr server;
|
||||
};
|
||||
|
||||
} // namespace icinga
|
||||
|
||||
#endif // HTTPSERVERCONNECTION_FIXTURE_H
|
103
test/remote-httpmessage.cpp
Normal file
103
test/remote-httpmessage.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include "test/base-tlsstream-fixture.hpp"
|
||||
#include "test/icingaapplication-fixture.hpp"
|
||||
#include "base/base64.hpp"
|
||||
#include "base/json.hpp"
|
||||
#include "config/configitem.hpp"
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "remote/httphandler.hpp"
|
||||
#include <boost/beast/http.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <set>
|
||||
#include <BoostTestTargetConfig.h>
|
||||
|
||||
using namespace icinga;
|
||||
using namespace boost::beast;
|
||||
|
||||
struct HttpMessageFixture: TlsStreamFixture
|
||||
{
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(remote_httpmessage, HttpMessageFixture)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(request_parse)
|
||||
{
|
||||
std::atomic<bool> done = false;
|
||||
|
||||
http::request<boost::beast::http::string_body> requestOut;
|
||||
requestOut.method(http::verb::get);
|
||||
requestOut.target("https://localhost:5665/v1/test");
|
||||
requestOut.set(http::field::authorization, "Basic " + Base64::Encode("invalid:invalid"));
|
||||
requestOut.set(http::field::accept, "application/json");
|
||||
requestOut.set(http::field::connection, "close");
|
||||
requestOut.content_length(0);
|
||||
|
||||
auto & io = IoEngine::Get();
|
||||
io.SpawnCoroutine(io.GetIoContext(), [&, this](boost::asio::yield_context yc) {
|
||||
boost::beast::flat_buffer buf;
|
||||
HttpRequest request(server);
|
||||
server->async_fill(yc);
|
||||
BOOST_REQUIRE_NO_THROW(request.ParseHeader(buf, yc));
|
||||
|
||||
for (auto & field : requestOut.base()) {
|
||||
BOOST_REQUIRE(request.count(field.name()));
|
||||
}
|
||||
|
||||
request.ParseBody(buf, yc);
|
||||
|
||||
server->next_layer().async_shutdown(yc);
|
||||
});
|
||||
|
||||
http::write(*client, requestOut);
|
||||
client->flush();
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(client->next_layer().shutdown());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(request_params)
|
||||
{
|
||||
HttpRequest request(client);
|
||||
request.body() = JsonEncode(new Dictionary{{"test1", false}, {"test2", true}});
|
||||
std::cout << request.body();
|
||||
request.target("https://localhost:1234/v1/test?test1&test3&test3");
|
||||
request.DecodeParams();
|
||||
|
||||
BOOST_REQUIRE_EQUAL(request.Params()->Get("test2"), "true");
|
||||
BOOST_REQUIRE(request.Params()->Get("test1").IsObjectType<Array>());
|
||||
BOOST_REQUIRE_EQUAL(request.GetLastParameter("test1"), "true");
|
||||
BOOST_REQUIRE(request.Params()->Get("test3").IsObjectType<Array>());
|
||||
BOOST_REQUIRE_EQUAL(request.GetLastParameter("test3"), "true");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(response_stream_operator)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(response_body_reader)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(response_body_writer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(response_write_fixed)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(response_write_chunked)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(response_sendjsonbody)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
380
test/remote-httpserverconnection.cpp
Normal file
380
test/remote-httpserverconnection.cpp
Normal file
@ -0,0 +1,380 @@
|
||||
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include "test/base-tlsstream-fixture.hpp"
|
||||
#include "test/icingaapplication-fixture.hpp"
|
||||
#include "base/base64.hpp"
|
||||
#include "base/json.hpp"
|
||||
#include "config/configitem.hpp"
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "remote/httphandler.hpp"
|
||||
#include <boost/beast/http.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <set>
|
||||
#include <BoostTestTargetConfig.h>
|
||||
|
||||
using namespace icinga;
|
||||
using namespace boost::beast;
|
||||
using namespace boost::unit_test_framework;
|
||||
|
||||
struct HttpServerConnectionFixture :
|
||||
TlsStreamFixture, IcingaApplicationFixture, ConfigurationCacheDirCleanupFixture
|
||||
{
|
||||
HttpServerConnectionFixture()
|
||||
: wg(new StoppableWaitGroup)
|
||||
{
|
||||
Logger::SetConsoleLogSeverity(icinga::LogDebug);
|
||||
}
|
||||
|
||||
~HttpServerConnectionFixture() {};
|
||||
|
||||
static void CreateApiListener(){
|
||||
ConfigItem::RunWithActivationContext(new Function("CreateTestUser", []() {
|
||||
String config = R"CONFIG(
|
||||
const NodeName = "local"
|
||||
object Endpoint "local" {}
|
||||
object Zone "local" {
|
||||
endpoints = [ "local" ]
|
||||
}
|
||||
object ApiListener "api" {
|
||||
accept_config = false
|
||||
accept_commands = false
|
||||
|
||||
bind_host = "localhost"
|
||||
bind_port = 123456
|
||||
ticket_salt = "test"
|
||||
access_control_allow_origin = ["127.0.0.1"]
|
||||
}
|
||||
)CONFIG";
|
||||
std::unique_ptr<Expression> expr = ConfigCompiler::CompileText("<test>", config);
|
||||
expr->Evaluate(*ScriptFrame::GetCurrentFrame());
|
||||
}));
|
||||
}
|
||||
|
||||
static void CreateTestUsers()
|
||||
{
|
||||
ApiUser::Ptr user = new ApiUser;
|
||||
user->SetName("remote");
|
||||
user->SetClientCN("remote");
|
||||
user->SetPermissions(new Array{"*"});
|
||||
user->Register();
|
||||
|
||||
user = new ApiUser;
|
||||
user->SetName("test");
|
||||
user->SetPassword("test");
|
||||
user->SetPermissions(new Array{"*"});
|
||||
user->Register();
|
||||
}
|
||||
|
||||
void SetupHttpServerConnection(bool authenticated)
|
||||
{
|
||||
String identity = authenticated ? "remote" : "invalid";
|
||||
conn = new HttpServerConnection(wg, identity, authenticated, server);
|
||||
conn->Start();
|
||||
}
|
||||
|
||||
void ShutdownTlsConn()
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
if (client->next_layer().shutdown(ec)) {
|
||||
BOOST_TEST_MESSAGE(ec.message());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
boost::asio::deadline_timer timeout{IoEngine::Get().GetIoContext()};
|
||||
HttpServerConnection::Ptr conn;
|
||||
StoppableWaitGroup::Ptr wg;
|
||||
};
|
||||
|
||||
class UnitTestHandler final: public HttpHandler
|
||||
{
|
||||
bool HandleRequest(const WaitGroup::Ptr& waitGroup, HttpRequest& request, HttpResponse& response,
|
||||
boost::asio::yield_context& yc) override
|
||||
{
|
||||
response.result(boost::beast::http::status::ok);
|
||||
response.body() << "test";
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_URLHANDLER("/v1/test", UnitTestHandler);
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(remote_httpserverconnection, HttpServerConnectionFixture)
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(setup_certs, SslCertificateFixture)
|
||||
{
|
||||
EnsureCertFor("local");
|
||||
EnsureCertFor("remote");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(expect_100_continue)
|
||||
{
|
||||
CreateTestUsers();
|
||||
SetupHttpServerConnection(true);
|
||||
|
||||
http::request<boost::beast::http::string_body> request;
|
||||
request.method(http::verb::get);
|
||||
request.version(11);
|
||||
request.target("https://localhost:5665/v1/test");
|
||||
request.set(http::field::expect, "100-continue");
|
||||
request.set(http::field::accept, "application/json");
|
||||
request.set(http::field::connection, "close");
|
||||
request.content_length(0);
|
||||
http::request_serializer<http::string_body> sr(request);
|
||||
http::write_header(*client, sr);
|
||||
client->flush();
|
||||
|
||||
flat_buffer buf;
|
||||
http::response<http::string_body> response;
|
||||
http::read(*client, buf, response);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(response.version(), 11);
|
||||
BOOST_REQUIRE_EQUAL(response.result(), http::status::continue_);
|
||||
|
||||
http::write(*client, sr);
|
||||
client->flush();
|
||||
|
||||
http::read(*client, buf, response);
|
||||
BOOST_REQUIRE_EQUAL(response.version(), 11);
|
||||
BOOST_REQUIRE_EQUAL(response.result(), http::status::ok);
|
||||
BOOST_REQUIRE_EQUAL(response.body(), "test");
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(ShutdownTlsConn());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bad_request)
|
||||
{
|
||||
CreateTestUsers();
|
||||
SetupHttpServerConnection(true);
|
||||
|
||||
http::request<boost::beast::http::string_body> request;
|
||||
request.method(http::verb::get);
|
||||
request.version(12);
|
||||
request.target("https://localhost:5665/v1/test");
|
||||
request.set(http::field::accept, "application/json");
|
||||
request.set(http::field::connection, "close");
|
||||
request.content_length(0);
|
||||
http::write(*client, request);
|
||||
client->flush();
|
||||
|
||||
flat_buffer buf;
|
||||
http::response<http::string_body> response;
|
||||
http::read(*client, buf, response);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(response.result(), http::status::bad_request);
|
||||
BOOST_REQUIRE_NE(response.body().find("<h1>Bad Request</h1>"), std::string::npos);
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(ShutdownTlsConn());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(error_access_control)
|
||||
{
|
||||
CreateTestUsers();
|
||||
CreateApiListener();
|
||||
SetupHttpServerConnection(true);
|
||||
|
||||
http::request<boost::beast::http::string_body> request;
|
||||
request.method(http::verb::options);
|
||||
request.target("https://localhost:5665/v1/test");
|
||||
request.set(http::field::origin, "127.0.0.1");
|
||||
request.set(http::field::access_control_request_method, "GET");
|
||||
request.set(http::field::connection, "close");
|
||||
request.content_length(0);
|
||||
http::write(*client, request);
|
||||
client->flush();
|
||||
|
||||
flat_buffer buf;
|
||||
http::response<http::string_body> response;
|
||||
http::read(*client, buf, response);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(response.version(), 11);
|
||||
BOOST_REQUIRE_EQUAL(response.result(), http::status::ok);
|
||||
BOOST_REQUIRE_EQUAL(response.body(), "Preflight OK");
|
||||
|
||||
boost::container::flat_set<std::string> sv;
|
||||
boost::container::flat_set options{"GET", "POST", "PUT", "DELETE", "PUSH"};
|
||||
|
||||
BOOST_REQUIRE_NE(response[http::field::access_control_allow_methods], "");
|
||||
BOOST_REQUIRE_NE(response[http::field::access_control_allow_headers], "");
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(ShutdownTlsConn());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(error_accept_header)
|
||||
{
|
||||
CreateTestUsers();
|
||||
SetupHttpServerConnection(true);
|
||||
|
||||
http::request<boost::beast::http::string_body> request;
|
||||
request.method(http::verb::post);
|
||||
request.target("https://localhost:5665/v1/test");
|
||||
request.set(http::field::accept, "text/html");
|
||||
request.set(http::field::connection, "close");
|
||||
request.content_length(0);
|
||||
http::write(*client, request);
|
||||
client->flush();
|
||||
|
||||
flat_buffer buf;
|
||||
http::response<http::string_body> response;
|
||||
http::read(*client, buf, response);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(response.version(), 11);
|
||||
BOOST_REQUIRE_EQUAL(response.result(), http::status::bad_request);
|
||||
BOOST_REQUIRE_EQUAL(response.body(), "<h1>Accept header is missing or not set to 'application/json'.</h1>\r\n");
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(ShutdownTlsConn());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(error_authenticate_cn)
|
||||
{
|
||||
CreateTestUsers();
|
||||
SetupHttpServerConnection(true);
|
||||
|
||||
http::request<boost::beast::http::string_body> request;
|
||||
request.method(http::verb::get);
|
||||
request.target("https://localhost:5665/v1/test");
|
||||
request.set(http::field::accept, "application/json");
|
||||
request.set(http::field::connection, "close");
|
||||
request.content_length(0);
|
||||
http::write(*client, request);
|
||||
client->flush();
|
||||
|
||||
flat_buffer buf;
|
||||
http::response<http::string_body> response;
|
||||
http::read(*client, buf, response);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(response.version(), 11);
|
||||
BOOST_REQUIRE_EQUAL(response.result(), http::status::ok);
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(ShutdownTlsConn());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(error_authenticate_passwd)
|
||||
{
|
||||
CreateTestUsers();
|
||||
SetupHttpServerConnection(false);
|
||||
|
||||
http::request<boost::beast::http::string_body> request;
|
||||
request.method(http::verb::get);
|
||||
request.target("https://localhost:5665/v1/test");
|
||||
request.set(http::field::authorization, "Basic " + Base64::Encode("test:test"));
|
||||
request.set(http::field::accept, "application/json");
|
||||
request.set(http::field::connection, "close");
|
||||
request.content_length(0);
|
||||
http::write(*client, request);
|
||||
client->flush();
|
||||
|
||||
flat_buffer buf;
|
||||
http::response<http::string_body> response;
|
||||
http::read(*client, buf, response);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(response.version(), 11);
|
||||
BOOST_REQUIRE_EQUAL(response.result(), http::status::ok);
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(ShutdownTlsConn());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(error_authenticate_wronguser)
|
||||
{
|
||||
CreateTestUsers();
|
||||
SetupHttpServerConnection(false);
|
||||
|
||||
http::request<boost::beast::http::string_body> request;
|
||||
request.method(http::verb::get);
|
||||
request.target("https://localhost:5665/v1/test");
|
||||
request.set(http::field::authorization, "Basic " + Base64::Encode("invalid:invalid"));
|
||||
request.set(http::field::accept, "application/json");
|
||||
request.set(http::field::connection, "close");
|
||||
request.content_length(0);
|
||||
http::write(*client, request);
|
||||
client->flush();
|
||||
|
||||
flat_buffer buf;
|
||||
http::response<http::string_body> response;
|
||||
http::read(*client, buf, response);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(response.version(), 11);
|
||||
BOOST_REQUIRE_EQUAL(response.result(), http::status::unauthorized);
|
||||
Dictionary::Ptr body = JsonDecode(response.body());
|
||||
BOOST_REQUIRE(body);
|
||||
BOOST_REQUIRE_EQUAL(body->Get("error"), 401);
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(ShutdownTlsConn());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(error_authenticate_wrongpasswd)
|
||||
{
|
||||
CreateTestUsers();
|
||||
SetupHttpServerConnection(false);
|
||||
|
||||
http::request<boost::beast::http::string_body> request;
|
||||
request.method(http::verb::get);
|
||||
request.target("https://localhost:5665/v1/test");
|
||||
request.set(http::field::authorization, "Basic " + Base64::Encode("test:invalid"));
|
||||
request.set(http::field::accept, "application/json");
|
||||
request.set(http::field::connection, "close");
|
||||
request.content_length(0);
|
||||
http::write(*client, request);
|
||||
client->flush();
|
||||
|
||||
flat_buffer buf;
|
||||
http::response<http::string_body> response;
|
||||
http::read(*client, buf, response);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(response.version(), 11);
|
||||
BOOST_REQUIRE_EQUAL(response.result(), http::status::unauthorized);
|
||||
Dictionary::Ptr body = JsonDecode(response.body());
|
||||
BOOST_REQUIRE(body);
|
||||
BOOST_REQUIRE_EQUAL(body->Get("error"), 401);
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(ShutdownTlsConn());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(reuse_connection_and_wg_abort)
|
||||
{
|
||||
CreateTestUsers();
|
||||
SetupHttpServerConnection(true);
|
||||
|
||||
http::request<boost::beast::http::string_body> request;
|
||||
request.method(http::verb::get);
|
||||
request.target("https://localhost:5665/v1/test");
|
||||
request.set(http::field::accept, "application/json");
|
||||
// request.keep_alive(true);
|
||||
http::write(*client, request);
|
||||
client->flush();
|
||||
|
||||
flat_buffer buf;
|
||||
http::response<http::string_body> response;
|
||||
http::read(*client, buf, response);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(response.version(), 11);
|
||||
BOOST_REQUIRE_EQUAL(response.result(), http::status::ok);
|
||||
BOOST_REQUIRE_EQUAL(response.body(), "test");
|
||||
|
||||
http::write(*client, request);
|
||||
client->flush();
|
||||
|
||||
wg->Join();
|
||||
|
||||
response.body() = "";
|
||||
http::read(*client, buf, response);
|
||||
BOOST_REQUIRE_EQUAL(response.result(), http::status::ok);
|
||||
BOOST_REQUIRE_EQUAL(response.body(), "test");
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(ShutdownTlsConn());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(liveness_disconnect)
|
||||
{
|
||||
SetupHttpServerConnection(false);
|
||||
|
||||
Utility::Sleep(11);
|
||||
BOOST_REQUIRE(conn->Disconnected());
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(ShutdownTlsConn());
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(cleanup_certs, ConfigurationDataDirCleanupFixture) {}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
x
Reference in New Issue
Block a user