TrinityCore
HttpService.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITYCORE_HTTP_SERVICE_H
19#define TRINITYCORE_HTTP_SERVICE_H
20
21#include "AsioHacksFwd.h"
22#include "Concepts.h"
23#include "Define.h"
24#include "EnumFlag.h"
25#include "HttpCommon.h"
26#include "HttpSessionState.h"
27#include "Optional.h"
28#include "SocketMgr.h"
29#include <boost/uuid/uuid.hpp>
30#include <functional>
31#include <map>
32#include <set>
33#include <shared_mutex>
34
35namespace Trinity::Net::Http
36{
37class AbstractSocket;
38
40{
41 None = 0x0,
44};
45
47
49{
50 std::function<RequestHandlerResult(std::shared_ptr<AbstractSocket> session, RequestContext& context)> Func;
52};
53
55{
56public:
57 explicit DispatcherService(std::string_view loggerSuffix) : _logger("server.http.dispatcher.")
58 {
59 _logger.append(loggerSuffix);
60 }
61
62 RequestHandlerResult HandleRequest(std::shared_ptr<AbstractSocket> session, RequestContext& context);
63
64 static RequestHandlerResult HandleBadRequest(std::shared_ptr<AbstractSocket> session, RequestContext& context);
65 static RequestHandlerResult HandleUnauthorized(std::shared_ptr<AbstractSocket> session, RequestContext& context);
66 static RequestHandlerResult HandlePathNotFound(std::shared_ptr<AbstractSocket> session, RequestContext& context);
67
68protected:
69 void RegisterHandler(boost::beast::http::verb method, std::string_view path,
70 std::function<RequestHandlerResult(std::shared_ptr<AbstractSocket> session, RequestContext& context)> handler,
72
73private:
74 using HttpMethodHandlerMap = std::map<std::string, RequestHandler, std::less<>>;
75
78
79 std::string _logger;
80};
81
83{
84public:
85 explicit SessionService(std::string_view loggerSuffix) : _logger("server.http.session.")
86 {
87 _logger.append(loggerSuffix);
88 }
89
90 void Start(Asio::IoContext& ioContext);
91 void Stop();
92
93 std::shared_ptr<SessionState> FindAndRefreshSessionState(std::string_view id, boost::asio::ip::address const& address);
94 void MarkSessionInactive(boost::uuids::uuid const& id);
95
96protected:
97 void InitAndStoreSessionState(std::shared_ptr<SessionState> state, boost::asio::ip::address const& address);
98
99 void KillInactiveSessions();
100
101private:
102 std::shared_mutex _sessionsMutex;
103 std::map<boost::uuids::uuid, std::shared_ptr<SessionState>> _sessions;
104
106 std::set<boost::uuids::uuid> _inactiveSessions;
107 std::unique_ptr<Asio::DeadlineTimer> _inactiveSessionsKillTimer;
108
109 std::string _logger;
110};
111
112template<typename Callable, typename SessionImpl>
114
115template<typename SessionImpl>
116class HttpService : public SocketMgr<SessionImpl>, public DispatcherService, public SessionService
117{
118public:
119 HttpService(std::string_view loggerSuffix) : DispatcherService(loggerSuffix), SessionService(loggerSuffix), _ioContext(nullptr), _logger("server.http.")
120 {
121 _logger.append(loggerSuffix);
122 }
123
124 bool StartNetwork(Asio::IoContext& ioContext, std::string const& bindIp, uint16 port, int32 threadCount = 1) override
125 {
126 if (!SocketMgr<SessionImpl>::StartNetwork(ioContext, bindIp, port, threadCount))
127 return false;
128
129 SessionService::Start(ioContext);
130 return true;
131 }
132
133 void StopNetwork() override
134 {
137 }
138
139 // http handling
141
142 template<HttpRequestHandler<SessionImpl> Callable>
143 void RegisterHandler(boost::beast::http::verb method, std::string_view path, Callable handler, RequestHandlerFlag flags = RequestHandlerFlag::None)
144 {
145 this->DispatcherService::RegisterHandler(method, path, [handler = std::move(handler)](std::shared_ptr<AbstractSocket> session, RequestContext& context) -> RequestHandlerResult
146 {
147 return handler(std::static_pointer_cast<SessionImpl>(std::move(session)), context);
148 }, flags);
149 }
150
151 // session tracking
152 virtual std::shared_ptr<SessionState> CreateNewSessionState(boost::asio::ip::address const& address)
153 {
154 std::shared_ptr<SessionState> state = std::make_shared<SessionState>();
155 InitAndStoreSessionState(state, address);
156 return state;
157 }
158
159protected:
160 class Thread : public NetworkThread<SessionImpl>
161 {
162 protected:
163 void SocketRemoved(std::shared_ptr<SessionImpl> session) override
164 {
165 if (Optional<boost::uuids::uuid> id = session->GetSessionId())
167 }
168
169 private:
171
173 };
174
176 {
177 Thread* threads = new Thread[this->GetNetworkThreadCount()];
178 for (int32 i = 0; i < this->GetNetworkThreadCount(); ++i)
179 threads[i]._service = const_cast<HttpService*>(this);
180 return threads;
181 }
182
184 std::string _logger;
185};
186}
187
188#endif // TRINITYCORE_HTTP_SERVICE_H
#define TC_SHARED_API
Definition: Define.h:117
int32_t int32
Definition: Define.h:138
uint16_t uint16
Definition: Define.h:143
uint16 flags
Definition: DisableMgr.cpp:49
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
virtual void StopNetwork()
Definition: SocketMgr.h:72
int32 GetNetworkThreadCount() const
Definition: SocketMgr.h:111
HttpMethodHandlerMap _getHandlers
Definition: HttpService.h:76
DispatcherService(std::string_view loggerSuffix)
Definition: HttpService.h:57
HttpMethodHandlerMap _postHandlers
Definition: HttpService.h:77
void RegisterHandler(boost::beast::http::verb method, std::string_view path, std::function< RequestHandlerResult(std::shared_ptr< AbstractSocket > session, RequestContext &context)> handler, RequestHandlerFlag flags=RequestHandlerFlag::None)
std::map< std::string, RequestHandler, std::less<> > HttpMethodHandlerMap
Definition: HttpService.h:74
void SocketRemoved(std::shared_ptr< SessionImpl > session) override
Definition: HttpService.h:163
Asio::IoContext * _ioContext
Definition: HttpService.h:183
virtual std::shared_ptr< SessionState > CreateNewSessionState(boost::asio::ip::address const &address)
Definition: HttpService.h:152
NetworkThread< SessionImpl > * CreateThreads() const override
Definition: HttpService.h:175
bool StartNetwork(Asio::IoContext &ioContext, std::string const &bindIp, uint16 port, int32 threadCount=1) override
Definition: HttpService.h:124
HttpService(std::string_view loggerSuffix)
Definition: HttpService.h:119
void RegisterHandler(boost::beast::http::verb method, std::string_view path, Callable handler, RequestHandlerFlag flags=RequestHandlerFlag::None)
Definition: HttpService.h:143
std::map< boost::uuids::uuid, std::shared_ptr< SessionState > > _sessions
Definition: HttpService.h:103
std::unique_ptr< Asio::DeadlineTimer > _inactiveSessionsKillTimer
Definition: HttpService.h:107
std::set< boost::uuids::uuid > _inactiveSessions
Definition: HttpService.h:106
SessionService(std::string_view loggerSuffix)
Definition: HttpService.h:85
void Start(Asio::IoContext &ioContext)
void InitAndStoreSessionState(std::shared_ptr< SessionState > state, boost::asio::ip::address const &address)
void MarkSessionInactive(boost::uuids::uuid const &id)
DEFINE_ENUM_FLAG(RequestHandlerFlag)
std::function< RequestHandlerResult(std::shared_ptr< AbstractSocket > session, RequestContext &context)> Func
Definition: HttpService.h:50
EnumFlag< RequestHandlerFlag > Flags
Definition: HttpService.h:51