#pragma once #include "data/LedgerCacheInterface.hpp" #include "util/Taggable.hpp" #include "web/AdminVerificationStrategy.hpp" #include "web/ProxyIpResolver.hpp" #include "web/SslWsSession.hpp" #include "web/dosguard/DOSGuardInterface.hpp" #include "web/impl/HttpBase.hpp" #include "web/interface/Concepts.hpp" #include "web/interface/ConnectionBase.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace web { using tcp = boost::asio::ip::tcp; /** * @brief Represents a HTTPS connection established by a client. * * It will handle the upgrade to secure websocket, pass the ownership of the socket to the upgrade * session. Otherwise, it will pass control to the base class. * * @tparam HandlerType The type of the server handler to use */ template class SslHttpSession : public impl::HttpBase, public std::enable_shared_from_this> { boost::asio::ssl::stream stream_; std::reference_wrapper tagFactory_; std::uint32_t maxWsSendingQueueSize_; public: /** * @brief Create a new SSL session. * * @param socket The socket. Ownership is transferred to HttpSession * @param ip Client's IP address * @param adminVerification The admin verification strategy to use * @param proxyIpResolver The client ip resolver if a request was forwarded by a proxy * @param ctx The SSL context * @param tagFactory A factory that is used to generate tags to track requests and sessions * @param dosGuard The denial of service guard to use * @param handler The server handler to use * @param cache The ledger cache to use * @param buffer Buffer with initial data received from the peer * @param maxWsSendingQueueSize The maximum size of the sending queue for websocket */ explicit SslHttpSession( tcp::socket&& socket, std::string const& ip, std::shared_ptr const& adminVerification, std::shared_ptr proxyIpResolver, boost::asio::ssl::context& ctx, std::reference_wrapper tagFactory, std::reference_wrapper dosGuard, std::shared_ptr const& handler, std::reference_wrapper cache, boost::beast::flat_buffer buffer, std::uint32_t maxWsSendingQueueSize ) : impl::HttpBase( ip, tagFactory, adminVerification, std::move(proxyIpResolver), dosGuard, handler, cache, std::move(buffer) ) , stream_(std::move(socket), ctx) , tagFactory_(tagFactory) , maxWsSendingQueueSize_(maxWsSendingQueueSize) { } ~SslHttpSession() override = default; /** @return The SSL stream. */ boost::asio::ssl::stream& stream() { return stream_; } /** @brief Initiates the handshake. */ void run() { auto self = this->shared_from_this(); boost::asio::dispatch(stream_.get_executor(), [self]() { // Set the timeout. boost::beast::get_lowest_layer(self->stream()).expires_after(std::chrono::seconds(30)); // Perform the SSL handshake // Note, this is the buffered version of the handshake. self->stream_.async_handshake( boost::asio::ssl::stream_base::server, self->buffer_.data(), boost::beast::bind_front_handler(&SslHttpSession::onHandshake, self) ); }); } /** * @brief Handles the handshake. * * @param ec Error code if any * @param bytesUsed The total amount of data read from the stream */ void onHandshake(boost::beast::error_code ec, std::size_t bytesUsed) { if (ec) return this->httpFail(ec, "handshake"); this->buffer_.consume(bytesUsed); this->doRead(); } /** @brief Closes the underlying connection. */ void doClose() { boost::beast::get_lowest_layer(stream_).expires_after(std::chrono::seconds(30)); stream_.async_shutdown( boost::beast::bind_front_handler(&SslHttpSession::onShutdown, this->shared_from_this()) ); } /** * @brief Handles a connection shutdown. * * @param ec Error code if any */ void onShutdown(boost::beast::error_code ec) { if (ec) return this->httpFail(ec, "shutdown"); // At this point the connection is closed gracefully } /** @brief Upgrades connection to secure websocket. */ void upgrade() { std::make_shared>( std::move(stream_), this->clientIp_, tagFactory_, this->dosGuard_, this->handler_, std::move(this->buffer_), std::move(this->req_), ConnectionBase::isAdmin(), maxWsSendingQueueSize_ ) ->run(); } }; } // namespace web