From 7554691cfdf1194e00d4e4b8937bb940031ce3b2 Mon Sep 17 00:00:00 2001 From: amass Date: Fri, 10 Jan 2025 21:49:22 +0800 Subject: [PATCH] remove some code. --- Server/Application.cpp | 101 ++++++++++++++++++++++----------- Server/Application.h | 9 ++- Server/CMakeLists.txt | 1 - Server/HttpSession.cpp | 45 ++++++++------- Server/HttpSession.h | 18 ++++-- Server/Listener.cpp | 63 -------------------- Server/Listener.h | 25 -------- Server/WebRTC/SignalServer.cpp | 14 +++++ Server/WebRTC/SignalServer.h | 2 + Server/main.cpp | 8 +-- 10 files changed, 132 insertions(+), 154 deletions(-) delete mode 100644 Server/Listener.cpp delete mode 100644 Server/Listener.h diff --git a/Server/Application.cpp b/Server/Application.cpp index db89296..a02d6c9 100644 --- a/Server/Application.cpp +++ b/Server/Application.cpp @@ -9,6 +9,7 @@ #include "SystemUsage.h" #include "WeChatContext/CorporationContext.h" #include +#include #include #include #include @@ -17,22 +18,23 @@ constexpr auto IpcUrl = "ipc:///tmp/nng_ipc_server"; static std::vector urlFilter = { - "/", - "/search", - "/LoginPage", - "/MessageBoard", - "/我的笔记", - "/我的笔记/", - "/我的博客", + "/", "/search", "/LoginPage", "/MessageBoard", "/我的笔记", "/我的笔记/", "/我的博客", }; -Application::Application(const std::string &path) - : ApplicationSettings(path), m_router{std::make_shared>()} { +class ApplicationPrivate { +public: + std::shared_ptr> router; + std::shared_ptr acceptor; +}; + +Application::Application(const std::string &path) : ApplicationSettings(path), m_d{new ApplicationPrivate()} { + using namespace boost::urls; + m_d->router = std::make_shared>(); // clang-format off - m_router->insert("/{path*}",[this](HttpSession &session, const Request &request, const boost::urls::matches &matches) { + m_d->router->insert("/{path*}",[this](HttpSession &session, const Request &request, const matches &matches) { using namespace boost::beast; - boost::urls::url_view view(request.target()); + url_view view(request.target()); auto target = view.path(); LOG(info) << target; if (target.find("..") != boost::beast::string_view::npos) { @@ -65,12 +67,12 @@ Application::Application(const std::string &path) session.reply(std::move(res)); }); - m_router->insert("/wechat/{session*}",[this](HttpSession &session, const Request &request, const boost::urls::matches &matches) { + m_d->router->insert("/wechat/{session*}",[this](HttpSession &session, const Request &request, const matches &matches) { ServiceLogic::onWechat(shared_from_this(), request, [&session](auto &&response) { session.reply(std::move(response)); }); }); - m_router->insert("/api/v1/tasklist", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) { + m_d->router->insert("/api/v1/tasklist", [this](HttpSession &session, const Request &request, const matches &matches) { using namespace boost::beast; auto database = Database::session(); Tasks tasks = database->find(); @@ -86,7 +88,7 @@ Application::Application(const std::string &path) session.reply(std::move(s)); }); - m_router->insert("/api/v1/task/add", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) mutable { + m_d->router->insert("/api/v1/task/add", [this](HttpSession &session, const Request &request, const matches &matches) mutable { using namespace boost::beast; using namespace std::chrono; LOG(info) << "add task: " << request.body(); @@ -118,7 +120,7 @@ Application::Application(const std::string &path) session.reply(std::move(s)); }); - m_router->insert("/api/v1/task/delete/{id}", [this](HttpSession &session, const Request &request,const boost::urls::matches &matches) { + m_d->router->insert("/api/v1/task/delete/{id}", [this](HttpSession &session, const Request &request,const matches &matches) { using namespace boost::beast; LOG(info) << "delete task: " << matches.at("id"); auto database = Database::session();; @@ -139,14 +141,14 @@ Application::Application(const std::string &path) session.reply(std::move(s)); }); - m_router->insert("/notify", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) { + m_d->router->insert("/notify", [this](HttpSession &session, const Request &request, const matches &matches) { auto corp = Amass::Singleton::instance(); corp->notify(request); session.reply( ServiceLogic::make_200(request, "notify successed.\n", "text/html")); }); - m_router->insert("/api/v1/visit_analysis", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) { + m_d->router->insert("/api/v1/visit_analysis", [this](HttpSession &session, const Request &request, const matches &matches) { using namespace boost::beast; auto rootJson = boost::json::parse(request.body()); auto &root = rootJson.as_object(); @@ -188,7 +190,7 @@ Application::Application(const std::string &path) session.reply(std::move(s)); }); - m_router->insert("/api/v1/most_viewed_urls", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) { + m_d->router->insert("/api/v1/most_viewed_urls", [this](HttpSession &session, const Request &request, const matches &matches) { using namespace boost::beast; int size = 5; std::error_code error; @@ -226,7 +228,7 @@ Application::Application(const std::string &path) session.reply(std::move(s)); }); - m_router->insert("/api/v1/latest_viewed_urls", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) { + m_d->router->insert("/api/v1/latest_viewed_urls", [this](HttpSession &session, const Request &request, const matches &matches) { using namespace boost::beast; using namespace std::chrono; int size = 5; @@ -265,7 +267,7 @@ Application::Application(const std::string &path) s.prepare_payload(); session.reply(std::move(s)); }); - m_router->insert("/api/v1/search/reindex", [this](HttpSession &session, const Request &request, const boost::urls::matches &matches) { + m_d->router->insert("/api/v1/search/reindex", [this](HttpSession &session, const Request &request, const matches &matches) { using namespace boost::beast; std::string authorizationHeader; if (request.count(http::field::authorization)) { @@ -326,24 +328,59 @@ Application::Application(const std::string &path) alarmTask(); } +Application::~Application() { + if (m_d != nullptr) { + delete m_d; + } +} + boost::asio::io_context &Application::ioContext() { return *m_ioContext->ioContext(); } -const Application::RequestHandler *Application::find(boost::urls::segments_encoded_view path, - boost::urls::matches_base &matches) const noexcept { - const Application::RequestHandler *ret = nullptr; - try { - ret = m_router->find(path, matches); - } catch (const std::exception &e) { - boost::stacktrace::stacktrace trace = boost::stacktrace::stacktrace::from_current_exception(); - LOG(error) << e.what() << ", trace:\n" << trace; - } - return ret; +void Application::insertUrl(std::string_view url, RequestHandler &&handler) { + m_d->router->insert(url, std::move(handler)); } -void Application::insertUrl(std::string_view url, RequestHandler &&handler) { - m_router->insert(url, std::move(handler)); +void Application::startAcceptHttpConnections(const std::string &address, uint16_t port) { + m_d->acceptor = std::make_shared(*m_ioContext->ioContext()); + boost::beast::error_code error; + boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::make_address(address), port); + m_d->acceptor->open(endpoint.protocol(), error); + if (error) { + LOG(error) << error.message(); + return; + } + m_d->acceptor->set_option(boost::asio::socket_base::reuse_address(true), error); + if (error) { + LOG(error) << error.message(); + return; + } + m_d->acceptor->bind(endpoint, error); + if (error) { + LOG(error) << error.message(); + return; + } + m_d->acceptor->listen(boost::asio::socket_base::max_listen_connections, error); + if (error) { + LOG(error) << error.message(); + return; + } + asyncAcceptHttpConnections(); +} + +void Application::asyncAcceptHttpConnections() { + auto socket = std::make_shared(boost::asio::make_strand(*m_ioContext->ioContext())); + m_d->acceptor->async_accept(*socket, [self{shared_from_this()}, socket](const boost::system::error_code &error) { + if (error) { + if (error == boost::asio::error::operation_aborted) return; + LOG(error) << error.message(); + } else { + auto session = std::make_shared(std::move(*socket), self->m_d->router); + session->run(); + } + self->asyncAcceptHttpConnections(); + }); } int Application::exec() { diff --git a/Server/Application.h b/Server/Application.h index 2f104a2..8a9165c 100644 --- a/Server/Application.h +++ b/Server/Application.h @@ -3,10 +3,10 @@ #include "ApplicationSettings.h" #include "Singleton.h" -#include "router.hpp" #include #include #include +#include "matches.hpp" class HttpSession; class SystemUsage; @@ -18,6 +18,7 @@ class Socket; } } // namespace Nng +class ApplicationPrivate; class Application : public ApplicationSettings, public std::enable_shared_from_this { public: using Pointer = std::shared_ptr; @@ -36,21 +37,23 @@ public: INITIALIZE_FIELDS(Server, Port, Threads, ApplicationRoot, DocumentRoot); Application(const std::string &path); + ~Application(); boost::asio::io_context &ioContext(); int exec(); - const RequestHandler *find(boost::urls::segments_encoded_view path, boost::urls::matches_base &matches) const noexcept; + void startAcceptHttpConnections(const std::string &address, uint16_t port); void insertUrl(std::string_view url, RequestHandler &&handler); static void requetExit(); protected: void alarmTask(); void startAcceptRequest(); + void asyncAcceptHttpConnections(); private: + ApplicationPrivate *m_d = nullptr; int m_status = 0; std::shared_ptr m_ioContext; - std::shared_ptr> m_router; std::shared_ptr m_timer; std::shared_ptr m_systemUsage; std::shared_ptr m_replyer; diff --git a/Server/CMakeLists.txt b/Server/CMakeLists.txt index a88e363..d56b8bb 100644 --- a/Server/CMakeLists.txt +++ b/Server/CMakeLists.txt @@ -5,7 +5,6 @@ add_subdirectory(WebRTC) add_executable(Server main.cpp Application.h Application.cpp HttpSession.h HttpSession.cpp - Listener.h Listener.cpp ResponseUtility.h ResponseUtility.cpp ServiceLogic.h ServiceLogic.inl ServiceLogic.cpp ServiceManager.h diff --git a/Server/HttpSession.cpp b/Server/HttpSession.cpp index c64235f..cee3d00 100644 --- a/Server/HttpSession.cpp +++ b/Server/HttpSession.cpp @@ -1,5 +1,7 @@ #include "HttpSession.h" -#include "Application.h" +#include "BoostLog.h" +#include +#include #include #include #include @@ -7,7 +9,8 @@ #include #include -HttpSession::HttpSession(boost::asio::ip::tcp::socket &&socket) : m_stream(std::move(socket)) { +HttpSession::HttpSession(boost::asio::ip::tcp::socket &&socket, const std::shared_ptr> &router) + : m_stream(std::move(socket)), m_router(router) { } void HttpSession::run() { @@ -18,6 +21,10 @@ boost::beast::tcp_stream::executor_type HttpSession::executor() { return m_stream.get_executor(); } +boost::asio::ip::tcp::socket HttpSession::releaseSocket() { + return m_stream.release_socket(); +} + void HttpSession::errorReply(const Request &request, boost::beast::http::status status, boost::beast::string_view message) { using namespace boost::beast; // invalid route @@ -43,23 +50,25 @@ void HttpSession::doRead() { // Set the timeout. m_stream.expires_after(std::chrono::seconds(30)); - boost::beast::http::async_read( - m_stream, m_buffer, *m_parser, - [self{shared_from_this()}](const boost::system::error_code &ec, std::size_t bytes_transferred) { - self->onRead(ec, bytes_transferred); - }); + // clang-format off + boost::beast::http::async_read(m_stream, m_buffer, *m_parser, [self{shared_from_this()}](const boost::system::error_code &ec, std::size_t bytes_transferred) { + self->onRead(ec, bytes_transferred); + }); + // clang-format on } -void HttpSession::onRead(boost::beast::error_code ec, std::size_t) { +void HttpSession::onRead(const boost::beast::error_code &error, std::size_t) { using namespace boost::beast; - // This means they closed the connection - if (ec == http::error::end_of_stream) { - m_stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); + if (error) { + if (error == http::error::end_of_stream) { + boost::beast::error_code e; + m_stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_send, e); + } else if (error != boost::asio::error::operation_aborted) { + LOG(info) << error << " : " << error.message(); + } return; - } - if (ec) { - if (ec == boost::asio::error::operation_aborted) return; - LOG(info) << ec << " : " << ec.message(); + } else if (m_router.expired()) { + LOG(error) << "router is null."; return; } @@ -70,11 +79,9 @@ void HttpSession::onRead(boost::beast::error_code ec, std::size_t) { errorReply(request, http::status::bad_request, "Illegal request-target"); return; } - - auto application = Amass::Singleton::instance(); - + auto router = m_router.lock(); boost::urls::matches matches; - auto handler = application->find(*path, matches); + auto handler = router->find(*path, matches); if (handler) { try { (*handler)(*this, request, matches); diff --git a/Server/HttpSession.h b/Server/HttpSession.h index 0a54c54..1b39934 100644 --- a/Server/HttpSession.h +++ b/Server/HttpSession.h @@ -1,7 +1,12 @@ #ifndef HTTPSESSION_H #define HTTPSESSION_H -#include "boost/beast.hpp" +#include "router.hpp" +#include +#include +#include +#include +#include #include #include #include @@ -10,14 +15,12 @@ */ class HttpSession : public std::enable_shared_from_this { void doRead(); - void onRead(boost::beast::error_code ec, std::size_t); void onWrite(boost::beast::error_code ec, std::size_t, bool close); - // void sendResponse(boost::beast::http::response &&response); - public: using Request = boost::beast::http::request; - HttpSession(boost::asio::ip::tcp::socket &&socket); + using RequestHandler = std::function; + HttpSession(boost::asio::ip::tcp::socket &&socket, const std::shared_ptr> &router); template void reply(Response &&response) { using ResponseType = typename std::decay_t; @@ -28,10 +31,15 @@ public: } void errorReply(const Request &request, boost::beast::http::status status, boost::beast::string_view message); boost::beast::tcp_stream::executor_type executor(); + boost::asio::ip::tcp::socket releaseSocket(); void run(); +protected: + void onRead(const boost::beast::error_code &error, std::size_t); + private: boost::beast::tcp_stream m_stream; + std::weak_ptr> m_router; boost::beast::flat_buffer m_buffer{std::numeric_limits::max()}; std::optional> m_parser; }; diff --git a/Server/Listener.cpp b/Server/Listener.cpp deleted file mode 100644 index 55aae03..0000000 --- a/Server/Listener.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "Listener.h" -#include "HttpSession.h" -#include -#include - -Listener::Listener(boost::asio::io_context &ioc, boost::asio::ip::tcp::endpoint endpoint) - : m_ioContext(ioc), m_acceptor(ioc) { - boost::beast::error_code ec; - - // Open the acceptor - m_acceptor.open(endpoint.protocol(), ec); - if (ec) { - fail(ec, "open"); - return; - } - - // Allow address reuse - m_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); - if (ec) { - fail(ec, "set_option"); - return; - } - - // Bind to the server address - m_acceptor.bind(endpoint, ec); - if (ec) { - fail(ec, "bind"); - return; - } - - // Start listening for connections - m_acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); - if (ec) { - fail(ec, "listen"); - return; - } -} - -void Listener::startAccept() { - // The new connection gets its own strand - auto client = std::make_shared(boost::asio::make_strand(m_ioContext)); - m_acceptor.async_accept( - *client, [self{shared_from_this()}, client](const boost::system::error_code &ec) { self->onAccept(ec, client); }); -} - -void Listener::fail(boost::beast::error_code ec, char const *what) { - // Don't report on canceled operations - if (ec == boost::asio::error::operation_aborted) return; - std::cerr << what << ": " << ec.message() << "\n"; -} - -// Handle a connection -void Listener::onAccept(boost::beast::error_code ec, std::shared_ptr socket) { - if (ec) { - if (ec == boost::asio::error::operation_aborted) return; - std::cerr << "accept: " << ec.message() << "\n"; - - } else { // Launch a new session for this connection - auto session = std::make_shared(std::move(*socket)); - session->run(); - } - startAccept(); -} diff --git a/Server/Listener.h b/Server/Listener.h deleted file mode 100644 index 081e746..0000000 --- a/Server/Listener.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef LISTENER_H -#define LISTENER_H - -#include -#include -#include -#include - -class Listener : public std::enable_shared_from_this { -public: - Listener(boost::asio::io_context &ioc, boost::asio::ip::tcp::endpoint endpoint); - - // Start accepting incoming connections - void startAccept(); - -protected: - void fail(boost::beast::error_code ec, char const *what); - void onAccept(boost::beast::error_code ec, std::shared_ptr socket); - -private: - boost::asio::io_context &m_ioContext; - boost::asio::ip::tcp::acceptor m_acceptor; -}; - -#endif // LISTENER_H diff --git a/Server/WebRTC/SignalServer.cpp b/Server/WebRTC/SignalServer.cpp index 6e3a1e0..f4075a6 100644 --- a/Server/WebRTC/SignalServer.cpp +++ b/Server/WebRTC/SignalServer.cpp @@ -1,4 +1,18 @@ #include "SignalServer.h" +#include "../Application.h" +#include + +SignalServer::SignalServer(Application &app) { + using namespace boost::urls; + // clang-format off + app.insertUrl("/api/v1/webrtc/signal/{id}", [this](HttpSession &session, const Application::Request &request, const matches &matches) { + auto id = matches.at("id"); + if (boost::beast::websocket::is_upgrade(request)) { + auto ws = std::make_shared(); + } + }); + // clang-format on +} void SignalServer::join(const std::string &id, WebSocketSignalSession *client) { m_clients.insert({id, client}); diff --git a/Server/WebRTC/SignalServer.h b/Server/WebRTC/SignalServer.h index 6d513bc..57f497b 100644 --- a/Server/WebRTC/SignalServer.h +++ b/Server/WebRTC/SignalServer.h @@ -6,9 +6,11 @@ #include class WebSocketSignalSession; +class Application; class SignalServer { public: + SignalServer(Application &app); void join(const std::string &id, WebSocketSignalSession *client); void leave(const std::string &id); WebSocketSignalSession *client(const std::string &id); diff --git a/Server/main.cpp b/Server/main.cpp index 03c35ae..f71aca7 100644 --- a/Server/main.cpp +++ b/Server/main.cpp @@ -2,7 +2,6 @@ #include "BoostLog.h" #include "Database/Session.h" #include "IoContext.h" -#include "Listener.h" #include "Live2dBackend.h" #include "MediaServer.h" #include "ProxyListener.h" @@ -10,6 +9,7 @@ #include "WeChatContext/CorporationContext.h" #include "WeChatContext/WeChatContext.h" #include "WebApplication/Application.h" +#include #include #include #include @@ -64,11 +64,7 @@ int main(int argc, char const *argv[]) { } BOOST_ASSERT_MSG(!application->getServer().empty(), "server.empty() == true"); Database::initialize(std::format("{}/database.sqlite", application->getApplicationRoot())); - auto address = boost::asio::ip::make_address(application->getServer()); - auto listener = - std::make_shared(application->ioContext(), boost::asio::ip::tcp::endpoint{address, application->getPort()}); - listener->startAccept(); - + application->startAcceptHttpConnections(application->getServer(), application->getPort()); auto wechatContext = Singleton::instance(application->ioContext()); auto corpContext = Singleton::instance(application->ioContext()); corpContext->start();