завел https

This commit is contained in:
2024-10-30 10:24:02 +03:00
parent d6851052b4
commit 2fef65d9d9
15 changed files with 372 additions and 224 deletions

View File

@@ -9,6 +9,33 @@
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/formatter_parser.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/ssl/context.hpp>
#include <cstddef>
#include <memory>
#include <fstream>
namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
static std::vector<char> loadFile(const std::string& path) {
std::ifstream is(path, std::ios::in | std::ios::binary);
if (!is) {
throw std::runtime_error("File not found");
}
std::vector<char> content;
for (;;) {
char buf[512];
auto len = is.read(buf, sizeof(buf)).gcount();
if (len <= 0) {
break;
}
content.insert(content.end(), buf, buf + len);
}
return content;
}
namespace mime_types = http::server::mime_types;
@@ -43,19 +70,36 @@ void init_logging() {
log::add_common_attributes();
}
int main(int argc, char *argv[]) {
try {
// Check command line arguments.
if (argc != 3) {
std::cerr << "Usage: http_server <address> <port>\n";
std::cerr << " For IPv4, try:\n";
std::cerr << " receiver 0.0.0.0 80\n";
std::cerr << " For IPv6, try:\n";
std::cerr << " receiver 0::0 80\n";
return 1;
static void initResources(http::server::Server& s) {
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/", "static/login.html", mime_types::text_html));
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/favicon.ico", "static/favicon.png", mime_types::image_png));
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/js/vue.js", "static/js/vue.js", mime_types::javascript));
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/api/statistics", [](const auto& req, auto& rep) {
if (req.method != "GET") {
http::server::stock_reply(http::server::bad_request, rep);
}
rep.status = http::server::ok;
rep.headers.clear();
rep.headers.push_back({.name = "Content-Type", .value = to_string(mime_types::json)});
const char* json = R"({"key":"value"})";
rep.content.insert(rep.content.end(), json, json + strlen(json));
}));
}
int main(int argc, char *argv[]) {
try {
prctl(PR_SET_NAME, "main", 0, 0, 0);
// Check command line arguments.
if (argc != 4 && argc != 5) {
std::cerr << "Usage: http_server <ssl|nossl> <address> <port> [static files directory]\n";
std::cerr << " For IPv4, try:\n";
std::cerr << " receiver nossl 0.0.0.0 80\n";
std::cerr << " For IPv6, try:\n";
std::cerr << " receiver nossl 0::0 80\n";
return 1;
}
init_logging();
boost::log::core::get()->add_thread_attribute("Scope", boost::log::attributes::named_scope());
@@ -67,26 +111,40 @@ int main(int argc, char *argv[]) {
#endif
// Initialise the server.
http::server::server s(argv[1], argv[2]);
std::unique_ptr<http::server::Server> s;
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/", "static/login.html", mime_types::text_html));
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/favicon.ico", "static/favicon.png", mime_types::image_png));
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/js/vue.js", "static/js/vue.js", mime_types::javascript));
if (strcmp(argv[1], "nossl") == 0) {
s = std::make_unique<http::server::Server>(argv[2], argv[3]);
initResources(*s);
s->run();
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/api/statistics", [](const auto& req, auto& rep) {
if (req.method != "GET") {
http::server::stock_reply(http::server::bad_request, rep);
}
} else if (strcmp(argv[1], "ssl") == 0) {
const auto cert = loadFile("cert.pem");
const auto key = loadFile("key.pem");
const auto dh = loadFile("dh.pem");
rep.status = http::server::ok;
rep.headers.clear();
rep.headers.push_back({.name = "Content-Type", .value = to_string(mime_types::json)});
const char* json = R"({"key":"value"})";
rep.content.insert(rep.content.end(), json, json + strlen(json));
}));
auto ctx = std::make_shared<ssl::context>(ssl::context::tlsv12);
// Run the server until stopped.
s.run();
ctx->set_password_callback(
[](std::size_t, ssl::context_base::password_purpose) {
return "test";
});
ctx->set_options(ssl::context::default_workarounds | ssl::context::no_sslv2 | ssl::context::single_dh_use);
ctx->use_certificate_chain(boost::asio::buffer(cert));
ctx->use_private_key(boost::asio::buffer(key), ssl::context::file_format::pem);
ctx->use_tmp_dh(boost::asio::buffer(dh));
s = std::make_unique<http::server::Server>(argv[2], argv[3], ctx);
initResources(*s);
s->run();
} else {
std::cerr << "Unsupported ssl mode: " << argv[1] << std::endl;
return 1;
}
} catch (std::exception &e) {
BOOST_LOG_TRIVIAL(error) << e.what() << std::endl;
return -1;