#pragma once #include #include #include namespace uad { class HttpSession : public std::enable_shared_from_this { class Queue { enum { limit = 8 }; struct work { virtual void operator()() = 0; virtual ~work() = default; }; HttpSession& self_; std::vector> items_; public: explicit Queue(HttpSession& self); bool IsFull() const; bool OnWrite(); template void operator()(boost::beast::http::message&& msg) { struct work_impl : work { HttpSession& self_; boost::beast::http::message msg_; work_impl(HttpSession& self, boost::beast::http::message&& msg) : self_(self), msg_(std::move(msg)) { } void operator()() { boost::beast::http::async_write(self_.stream_, msg_, boost::beast::bind_front_handler(&HttpSession::OnWrite, self_.shared_from_this(), msg_.need_eof())); } }; items_.push_back(boost::make_unique(self_, std::move(msg))); if (items_.size() == 1) (*items_.front())(); } }; boost::beast::tcp_stream stream_; boost::beast::flat_buffer buffer_; std::shared_ptr doc_root_; Queue queue_; boost::optional> parser_; public: HttpSession(boost::asio::ip::tcp::socket&& socket, std::shared_ptr const& doc_root); void Run(); private: void DoRead(); void OnRead(boost::beast::error_code ec, std::size_t bytes_transferred); void OnWrite(bool close, boost::beast::error_code ec, std::size_t bytes_transferred); void DoClose(); }; }