Код: Выделить всё
sudo apt update
sudo apt install libboost-all-dev libssl-dev autobahn-cpp-dev libwebsocketpp-dev libasio-dev libboost-dev libboost-system-dev libboost-thread-dev
Код: Выделить всё
sudo apt-get install build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev libboost-all-dev
Код: Выделить всё
ln -s /home/gt/Downloads/boost_1_85_0 /usr/local/include/boost
Код: Выделить всё
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/asio/ssl/context.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include <string>
namespace beast = boost::beast;
namespace http = beast::http;
namespace net = boost::asio;
using tcp = boost::asio::ip::tcp;
using ssl_stream = beast::ssl_stream<beast::tcp_stream>;
// Этот класс будет обрабатывать запросы
class http_session : public std::enable_shared_from_this<http_session> {
ssl_stream stream_;
beast::flat_buffer buffer_;
public:
http_session(tcp::socket socket, ssl::context& ctx)
: stream_(std::move(socket), ctx) {
}
void run() {
do_handshake();
}
private:
void do_handshake() {
// Установим SSL/TLS соединение
stream_.async_handshake(ssl::stream_base::server,
beast::bind_front_handler(&http_session::on_handshake, shared_from_this()));
}
void on_handshake(beast::error_code ec) {
if(ec) {
std::cerr << "Handshake error: " << ec.message() << std::endl;
return;
}
do_read();
}
void do_read() {
// Читаем запрос
http::async_read(stream_, buffer_, request_,
beast::bind_front_handler(&http_session::on_read, shared_from_this()));
}
void on_read(beast::error_code ec, std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if(ec) {
std::cerr << "Read error: " << ec.message() << std::endl;
return;
}
// Отправка ответа
std::string response_body = "Hello, SSL world!";
http::response<http::string_body> response{http::status::ok, request_.version()};
response.set(http::field::server, "Beast");
response.set(http::field::content_type, "text/plain");
response.content_length(response_body.size());
response.body() = std::move(response_body);
response.prepare_payload();
// Отправка ответа
http::async_write(stream_, response,
beast::bind_front_handler(&http_session::on_write, shared_from_this(), response.need_eof()));
}
void on_write(bool close, beast::error_code ec, std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if(ec) {
std::cerr << "Write error: " << ec.message() << std::endl;
return;
}
if(close) {
return; // Закрытие соединения
}
do_read(); // Чтение следующего запроса
}
http::request<http::string_body> request_;
};
// Серверный класс
class http_server {
public:
http_server(net::io_context& ioc, ssl::context& ctx, tcp::endpoint endpoint)
: acceptor_(ioc, endpoint) {
do_accept(ctx);
}
private:
tcp::acceptor acceptor_;
void do_accept(ssl::context& ctx) {
acceptor_.async_accept(
[this, &ctx](beast::error_code ec, tcp::socket socket) {
if (!ec) {
std::make_shared<http_session>(std::move(socket), ctx)->run();
}
do_accept(ctx);
});
}
};
int main(int argc, char* argv[]) {
try {
asio::io_context io_context;
// Настройка контекста SSL
ssl::context ctx(ssl::context::sslv23);
ctx.set_options(ssl::context::default_workarounds | ssl::context::no_sslv2 | ssl::context::no_sslv3);
// Укажите путь к вашему SSL сертификату и закрытому ключу
ctx.use_certificate_chain_file("server.crt");
ctx.use_private_key_file("server.key", ssl::context::pem);
net::io_context ioc;
// Создаем серверный экземпляр
tcp::endpoint endpoint{tcp::v4(), 8080};
http_server server(ioc, ctx, endpoint);
ioc.run();
} catch (std::exception& e) {
std::cerr << "Ошибка: " << e.what() << std::endl;
}
}
Сессия: Каждая сессия использует ssl_stream, чтобы обеспечить SSL/TLS защиту.
Асинхронные операции: Используются асинхронные функции async_handshake, async_read, и async_write для обработки сетевых операций не блокируя основной поток.
Обработка запросов: После получения запроса сервер формирует простой текстовый ответ.
Компиляция:
Код: Выделить всё
g++ -std=c++11 -o web-https web-https.cpp -lboost_system -lpthread -lssl -lcrypto
Код: Выделить всё
g++ -std=c++11 -o web-https web-https.cpp -I/home/gt/Downloads/boost_1_85_0 -L/home/gt/Downloads/boost_1_85_0/stage/lib -lboost_system -lpthread -lssl -lcrypto
Код: Выделить всё
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt
Код: Выделить всё
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost"
Код: Выделить всё
# Создание ключа
openssl genrsa -out mykey.key 2048
# Создание запроса на сертификат
openssl req -new -key mykey.key -out myrequest.csr
# Создание самоподписанного сертификата
openssl x509 -req -days 365 -in myrequest.csr -signkey mykey.key -out mycert.crt
Код: Выделить всё
gdb ./your_program
run
# После сбоев
bt # Покажет стек вызовов
Код: Выделить всё
valgrind ./your_program