terminal-web-server/src/server/connection.hpp

124 lines
3.7 KiB
C++

#ifndef HTTP_CONNECTION_HPP
#define HTTP_CONNECTION_HPP
#include <boost/asio.hpp>
#include <boost/asio/ssl/context.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <boost/beast/core/tcp_stream.hpp>
#include <array>
#include <memory>
#include "reply.hpp"
#include "request.hpp"
#include "request_parser.hpp"
namespace http::server {
using request_handler = std::function<void(const Request &req, reply &rep)>;
class ConnectionManager;
/// Represents a single Connection from a client. Base class
class ConnectionBase {
public:
ConnectionBase(const ConnectionBase &) = delete;
ConnectionBase &operator=(const ConnectionBase &) = delete;
ConnectionBase() = default;
/// Start the first asynchronous operation for the Connection.
virtual void start() = 0;
/// Stop all asynchronous operations associated with the Connection.
virtual void stop() = 0;
virtual ~ConnectionBase() = default;
};
class Connection final : public ConnectionBase, public std::enable_shared_from_this<Connection> {
public:
/// Construct a Connection with the given socket.
explicit Connection(boost::asio::ip::tcp::socket socket, ConnectionManager &manager, request_handler handler);
/// Start the first asynchronous operation for the Connection.
void start() override;
/// Stop all asynchronous operations associated with the Connection.
void stop() override;
~Connection() override;
private:
/// Perform an asynchronous read operation.
void doRead();
/// Perform an asynchronous write operation.
void doWrite();
/// Socket for the Connection.
boost::asio::ip::tcp::socket socket_;
/// The manager for this Connection.
ConnectionManager &connection_manager_;
/// The handler used to process the incoming request.
request_handler request_handler_;
/// Buffer for incoming data.
std::array<char, 2048> buffer_{};
/// The incoming request.
Request request_;
/// The parser for the incoming request.
RequestParser request_parser_;
/// The reply to be sent back to the client.
reply reply_;
};
class SslConnection final : public ConnectionBase, public std::enable_shared_from_this<SslConnection> {
public:
/// Construct a Connection with the given socket.
explicit SslConnection(boost::asio::ip::tcp::socket socket, ConnectionManager &manager, request_handler handler, const std::shared_ptr<boost::asio::ssl::context>& ctx);
/// Start the first asynchronous operation for the Connection.
void start() override;
/// Stop all asynchronous operations associated with the Connection.
void stop() override;
~SslConnection() override;
private:
/// Perform an asynchronous read operation.
void doRead();
/// Perform an asynchronous write operation.
void doWrite();
/// Socket for the Connection.
boost::asio::ssl::stream<boost::beast::tcp_stream> stream_;
/// The manager for this Connection.
ConnectionManager &connection_manager_;
/// The handler used to process the incoming request.
request_handler request_handler_;
/// Buffer for incoming data.
std::array<char, 2048> buffer_{};
/// The incoming request.
Request request_;
/// The parser for the incoming request.
RequestParser request_parser_;
/// The reply to be sent back to the client.
reply reply_;
};
typedef std::shared_ptr<ConnectionBase> connection_ptr;
} // namespace http::Server
#endif // HTTP_CONNECTION_HPP