TrinityCore
Loading...
Searching...
No Matches
LoginHttpSession.cpp
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#include "LoginHttpSession.h"
19#include "DatabaseEnv.h"
20#include "HttpSocket.h"
21#include "HttpSslSocket.h"
23#include "LoginRESTService.h"
24#include "SslContext.h"
25#include "Util.h"
26#include <boost/container/static_vector.hpp>
27#include <boost/uuid/uuid_io.hpp>
28
29namespace
30{
31std::shared_ptr<Trinity::Net::Http::SessionState> ObtainSessionState(Trinity::Net::Http::RequestContext& context, boost::asio::ip::address const& remoteAddress)
32{
33 std::shared_ptr<Trinity::Net::Http::SessionState> state;
34 auto cookieItr = context.request.find(boost::beast::http::field::cookie);
35 if (cookieItr != context.request.end())
36 {
37 std::vector<std::string_view> cookies = Trinity::Tokenize(Trinity::Net::Http::ToStdStringView(cookieItr->value()), ';', false);
38 auto sessionIdItr = std::ranges::find_if(cookies, [](std::string_view const& cookie)
39 {
40 return cookie.length() > Battlenet::LoginHttpSession::SESSION_ID_COOKIE.length()
42 });
43 if (sessionIdItr != cookies.end())
44 {
45 sessionIdItr->remove_prefix(Battlenet::LoginHttpSession::SESSION_ID_COOKIE.length());
46 state = sLoginService.FindAndRefreshSessionState(*sessionIdItr, remoteAddress);
47 }
48 }
49 if (!state)
50 {
51 state = sLoginService.CreateNewSessionState(remoteAddress);
52
53 std::string_view host = Trinity::Net::Http::ToStdStringView(context.request[boost::beast::http::field::host]);
54 if (size_t port = host.find(':'); port != std::string_view::npos)
55 host.remove_suffix(host.length() - port);
56
57 context.response.insert(boost::beast::http::field::set_cookie, Trinity::StringFormat("{}{}; Path=/bnetserver; Domain={}; Secure; HttpOnly; SameSite=None",
58 Battlenet::LoginHttpSession::SESSION_ID_COOKIE, boost::uuids::to_string(state->Id), host));
59 }
60 return state;
61}
62
63template<typename SocketImpl>
64class LoginHttpSocketImpl final : public SocketImpl
65{
66public:
67 using BaseSocket = SocketImpl;
68
69 explicit LoginHttpSocketImpl(Trinity::Net::IoContextTcpSocket&& socket, Battlenet::LoginHttpSession& owner)
70 : BaseSocket(std::move(socket)), _owner(owner)
71 {
72 }
73
74 LoginHttpSocketImpl(LoginHttpSocketImpl const&) = delete;
75 LoginHttpSocketImpl(LoginHttpSocketImpl&&) = delete;
76 LoginHttpSocketImpl& operator=(LoginHttpSocketImpl const&) = delete;
77 LoginHttpSocketImpl& operator=(LoginHttpSocketImpl&&) = delete;
78
79 ~LoginHttpSocketImpl() = default;
80
81 void Start() override
82 {
83 // build initializer chain
84 boost::container::static_vector<std::shared_ptr<Trinity::Net::SocketConnectionInitializer>, 4> initializers;
85
86 initializers.stable_emplace_back(std::make_shared<Trinity::Net::IpBanCheckConnectionInitializer<Battlenet::LoginHttpSession>>(&_owner));
87
88 if constexpr (std::is_same_v<BaseSocket, Trinity::Net::Http::SslSocket>)
89 initializers.stable_emplace_back(std::make_shared<Trinity::Net::SslHandshakeConnectionInitializer<BaseSocket>>(this));
90
91 initializers.stable_emplace_back(std::make_shared<Trinity::Net::Http::HttpConnectionInitializer<BaseSocket>>(this));
92 initializers.stable_emplace_back(std::make_shared<Trinity::Net::ReadConnectionInitializer<BaseSocket>>(this));
93
94 Trinity::Net::SocketConnectionInitializer::SetupChain(std::span(initializers.data(), initializers.size()))->Start();
95 }
96
98 {
99 return sLoginService.HandleRequest(_owner.shared_from_this(), context);
100 }
101
102protected:
103 std::shared_ptr<Trinity::Net::Http::SessionState> ObtainSessionState(Trinity::Net::Http::RequestContext& context) const override
104 {
105 return ::ObtainSessionState(context, this->GetRemoteIpAddress());
106 }
107
109};
110
111template<>
112LoginHttpSocketImpl<Trinity::Net::Http::SslSocket>::LoginHttpSocketImpl(Trinity::Net::IoContextTcpSocket&& socket, Battlenet::LoginHttpSession& owner)
113 : BaseSocket(std::move(socket), Battlenet::SslContext::instance()), _owner(owner)
114{
115}
116}
117
118namespace Battlenet
119{
121 : _socket(!SslContext::UsesDevWildcardCertificate()
122 ? std::shared_ptr<AbstractSocket>(std::make_shared<LoginHttpSocketImpl<Trinity::Net::Http::SslSocket>>(std::move(socket), *this))
123 : std::shared_ptr<AbstractSocket>(std::make_shared<LoginHttpSocketImpl<Trinity::Net::Http::Socket>>(std::move(socket), *this)))
124{
125}
126
128
130{
131 TC_LOG_TRACE("server.http.session", "{} Accepted connection", GetClientInfo());
132
133 return _socket->Start();
134}
135
137{
138 if (!_socket->Update())
139 return false;
140
142 return true;
143}
144
146{
147 _queryProcessor.AddCallback(std::move(queryCallback));
148}
149}
#define TC_LOG_TRACE(filterType__, message__,...)
Definition Log.h:178
#define sLoginService
static constexpr std::string_view SESSION_ID_COOKIE
void QueueQuery(QueryCallback &&queryCallback)
std::string GetClientInfo() const override
LoginHttpSession(Trinity::Net::IoContextTcpSocket &&socket)
std::shared_ptr< Trinity::Net::Http::AbstractSocket > _socket
QueryCallbackProcessor _queryProcessor
std::string_view ToStdStringView(boost::beast::string_view bsw)
Definition HttpCommon.h:43
boost::asio::basic_stream_socket< boost::asio::ip::tcp, boost::asio::io_context::executor_type > IoContextTcpSocket
Definition Socket.h:40
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition Util.cpp:57
std::string StringFormat(FormatString< Args... > fmt, Args &&... args) noexcept
Default TC string format function.
STL namespace.
static std::shared_ptr< SocketConnectionInitializer > & SetupChain(std::span< std::shared_ptr< SocketConnectionInitializer > > initializers)