завел https
This commit is contained in:
110
src/main.cpp
110
src/main.cpp
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user