2021-11-21 23:37:36 +00:00
|
|
|
#include <boost/asio.hpp>
|
|
|
|
#include <boost/beast.hpp>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
namespace asio = boost::asio;
|
|
|
|
namespace beast = boost::beast;
|
|
|
|
namespace http = beast::http;
|
|
|
|
using boost::asio::ip::tcp;
|
|
|
|
|
|
|
|
class Server {
|
|
|
|
using tcp_acceptor = asio::use_awaitable_t<>::as_default_on_t<tcp::acceptor>;
|
|
|
|
using tcp_socket = asio::use_awaitable_t<>::as_default_on_t<tcp::socket>;
|
|
|
|
|
|
|
|
asio::awaitable<void> HandleRequest(tcp_socket socket) {
|
|
|
|
bool close;
|
|
|
|
beast::flat_buffer buffer;
|
|
|
|
|
|
|
|
do {
|
|
|
|
http::request<http::empty_body> req;
|
|
|
|
co_await http::async_read(socket, buffer, req);
|
|
|
|
|
|
|
|
http::response<http::string_body> res{http::status::ok, req.version()};
|
|
|
|
res.keep_alive(req.keep_alive());
|
|
|
|
res.body() = "foo\n";
|
|
|
|
co_await http::async_write(socket, res);
|
|
|
|
close = res.need_eof();
|
|
|
|
} while (!close);
|
|
|
|
|
|
|
|
socket.shutdown(tcp::socket::shutdown_send);
|
|
|
|
co_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
asio::awaitable<void> Listen() {
|
|
|
|
auto executor = co_await asio::this_coro::executor;
|
|
|
|
tcp_acceptor acceptor{executor, {tcp::v4(), 8080}};
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
tcp_socket socket = co_await acceptor.async_accept();
|
|
|
|
co_spawn(executor, HandleRequest(std::move(socket)), asio::detached);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
Server(asio::io_context *context) {
|
|
|
|
co_spawn(*context, Listen(), asio::detached);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-11-08 14:00:16 +00:00
|
|
|
int main() {
|
2021-11-21 23:37:36 +00:00
|
|
|
asio::io_context context;
|
|
|
|
asio::signal_set signals{context, SIGINT, SIGTERM};
|
|
|
|
signals.async_wait([&](auto, auto) { context.stop(); });
|
|
|
|
Server server{&context};
|
|
|
|
|
|
|
|
context.run();
|
2021-11-08 14:00:16 +00:00
|
|
|
return 0;
|
|
|
|
}
|