aboutsummaryrefslogtreecommitdiff
path: root/src/server/bnetserver/REST/LoginRESTService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/bnetserver/REST/LoginRESTService.cpp')
-rw-r--r--src/server/bnetserver/REST/LoginRESTService.cpp491
1 files changed, 159 insertions, 332 deletions
diff --git a/src/server/bnetserver/REST/LoginRESTService.cpp b/src/server/bnetserver/REST/LoginRESTService.cpp
index 6141dc702f9..602a38dceed 100644
--- a/src/server/bnetserver/REST/LoginRESTService.cpp
+++ b/src/server/bnetserver/REST/LoginRESTService.cpp
@@ -16,71 +16,63 @@
*/
#include "LoginRESTService.h"
+#include "Base64.h"
#include "Configuration/Config.h"
#include "CryptoHash.h"
#include "CryptoRandom.h"
#include "DatabaseEnv.h"
-#include "Errors.h"
#include "IpNetwork.h"
+#include "IteratorPair.h"
#include "ProtobufJSON.h"
#include "Resolver.h"
-#include "SslContext.h"
#include "Util.h"
-#include "httpget.h"
-#include "httppost.h"
-#include "soapH.h"
+#include <boost/uuid/string_generator.hpp>
+#include <fmt/chrono.h>
-int ns1__executeCommand(soap*, char*, char**) { return SOAP_OK; }
+namespace Battlenet
+{
+LoginRESTService& LoginRESTService::Instance()
+{
+ static LoginRESTService instance;
+ return instance;
+}
-class AsyncRequest
+bool LoginRESTService::StartNetwork(Trinity::Asio::IoContext& ioContext, std::string const& bindIp, uint16 port, int32 threadCount)
{
-public:
- AsyncRequest(soap const& server) : _client(server), _responseStatus(0) { }
+ if (!HttpService::StartNetwork(ioContext, bindIp, port, threadCount))
+ return false;
- AsyncRequest(AsyncRequest const&) = delete;
- AsyncRequest& operator=(AsyncRequest const&) = delete;
- AsyncRequest(AsyncRequest&&) = default;
- AsyncRequest& operator=(AsyncRequest&&) = default;
+ using Trinity::Net::Http::RequestHandlerFlag;
- bool InvokeIfReady()
+ RegisterHandler(boost::beast::http::verb::get, "/bnetserver/login/", [this](std::shared_ptr<LoginHttpSession> session, HttpRequestContext& context)
{
- ASSERT(_callback);
- return _callback->InvokeIfReady();
- }
-
- soap* GetClient() { return &_client; }
- void SetCallback(std::unique_ptr<QueryCallback> callback) { _callback = std::move(callback); }
- int32 GetResponseStatus() const { return _responseStatus; }
- void SetResponseStatus(int32 responseStatus) { _responseStatus = responseStatus; }
+ return HandleGetForm(std::move(session), context);
+ });
-private:
- soap _client;
- std::unique_ptr<QueryCallback> _callback;
- int32 _responseStatus;
-};
+ RegisterHandler(boost::beast::http::verb::get, "/bnetserver/gameAccounts/", [this](std::shared_ptr<LoginHttpSession> session, HttpRequestContext& context)
+ {
+ return HandleGetGameAccounts(std::move(session), context);
+ });
-int32 handle_get_plugin(soap* soapClient)
-{
- return sLoginService.HandleHttpRequest(soapClient, "GET", sLoginService._getHandlers);
-}
+ RegisterHandler(boost::beast::http::verb::get, "/bnetserver/portal/", [this](std::shared_ptr<LoginHttpSession> session, HttpRequestContext& context)
+ {
+ return HandleGetPortal(std::move(session), context);
+ });
-int32 handle_post_plugin(soap* soapClient)
-{
- return sLoginService.HandleHttpRequest(soapClient, "POST", sLoginService._postHandlers);
-}
+ RegisterHandler(boost::beast::http::verb::post, "/bnetserver/login/", [this](std::shared_ptr<LoginHttpSession> session, HttpRequestContext& context)
+ {
+ return HandlePostLogin(std::move(session), context);
+ }, RequestHandlerFlag::DoNotLogRequestContent);
-bool LoginRESTService::Start(Trinity::Asio::IoContext* ioContext)
-{
- _ioContext = ioContext;
- _bindIP = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0");
- _port = sConfigMgr->GetIntDefault("LoginREST.Port", 8081);
- if (_port < 0 || _port > 0xFFFF)
+ RegisterHandler(boost::beast::http::verb::post, "/bnetserver/refreshLoginTicket/", [this](std::shared_ptr<LoginHttpSession> session, HttpRequestContext& context)
{
- TC_LOG_ERROR("server.rest", "Specified login service port ({}) out of allowed range (1-65535), defaulting to 8081", _port);
- _port = 8081;
- }
+ return HandlePostRefreshLoginTicket(std::move(session), context);
+ });
- Trinity::Asio::Resolver resolver(*ioContext);
+ _bindIP = bindIp;
+ _port = port;
+
+ Trinity::Asio::Resolver resolver(ioContext);
_hostnames[0] = sConfigMgr->GetStringDefault("LoginREST.ExternalAddress", "127.0.0.1");
Optional<boost::asio::ip::tcp::endpoint> externalAddress = resolver.Resolve(boost::asio::ip::tcp::v4(), _hostnames[0], std::to_string(_port));
@@ -103,8 +95,8 @@ bool LoginRESTService::Start(Trinity::Asio::IoContext* ioContext)
_addresses[1] = localAddress->address();
// set up form inputs
- Battlenet::JSON::Login::FormInput* input;
- _formInputs.set_type(Battlenet::JSON::Login::LOGIN_FORM);
+ JSON::Login::FormInput* input;
+ _formInputs.set_type(JSON::Login::LOGIN_FORM);
input = _formInputs.add_inputs();
input->set_input_id("account_name");
input->set_type("text");
@@ -124,16 +116,10 @@ bool LoginRESTService::Start(Trinity::Asio::IoContext* ioContext)
_loginTicketDuration = sConfigMgr->GetIntDefault("LoginREST.TicketDuration", 3600);
- _thread = std::thread(&LoginRESTService::Run, this);
+ _acceptor->AsyncAcceptWithCallback<&LoginRESTService::OnSocketAccept>();
return true;
}
-void LoginRESTService::Stop()
-{
- _stopped = true;
- _thread.join();
-}
-
std::string const& LoginRESTService::GetHostnameForClient(boost::asio::ip::address const& address) const
{
if (auto addressIndex = Trinity::Net::SelectAddressForClient(address, _addresses))
@@ -145,117 +131,53 @@ std::string const& LoginRESTService::GetHostnameForClient(boost::asio::ip::addre
return _hostnames[0];
}
-void LoginRESTService::Run()
+std::string LoginRESTService::ExtractAuthorization(HttpRequest const& request)
{
- soap soapServer(SOAP_C_UTFSTRING, SOAP_C_UTFSTRING);
-
- // check every 3 seconds if world ended
- soapServer.accept_timeout = 3;
- soapServer.recv_timeout = 5;
- soapServer.send_timeout = 5;
- if (!soap_valid_socket(soap_bind(&soapServer, _bindIP.c_str(), _port, 100)))
- {
- TC_LOG_ERROR("server.rest", "Couldn't bind to {}:{}", _bindIP, _port);
- return;
- }
-
- TC_LOG_INFO("server.rest", "Login service bound to http://{}:{}", _bindIP, _port);
-
- http_post_handlers handlers[] =
- {
- { "application/json;charset=utf-8", handle_post_plugin },
- { "application/json", handle_post_plugin },
- { nullptr, nullptr }
- };
+ using namespace std::string_view_literals;
- _getHandlers["/bnetserver/login/"] = &LoginRESTService::HandleGetForm;
- _getHandlers["/bnetserver/gameAccounts/"] = &LoginRESTService::HandleGetGameAccounts;
- _getHandlers["/bnetserver/portal/"] = &LoginRESTService::HandleGetPortal;
+ std::string ticket;
+ auto itr = request.find(boost::beast::http::field::authorization);
+ if (itr == request.end())
+ return ticket;
- _postHandlers["/bnetserver/login/"] = &LoginRESTService::HandlePostLogin;
- _postHandlers["/bnetserver/refreshLoginTicket/"] = &LoginRESTService::HandlePostRefreshLoginTicket;
+ std::string_view authorization = Trinity::Net::Http::ToStdStringView(itr->value());
+ constexpr std::string_view BASIC_PREFIX = "Basic "sv;
- soap_register_plugin_arg(&soapServer, &http_get, (void*)&handle_get_plugin);
- soap_register_plugin_arg(&soapServer, &http_post, handlers);
- soap_register_plugin_arg(&soapServer, &ContentTypePlugin::Init, (void*)"application/json;charset=utf-8");
- soap_register_plugin_arg(&soapServer, &ResponseCodePlugin::Init, nullptr);
+ if (authorization.starts_with(BASIC_PREFIX))
+ authorization.remove_prefix(BASIC_PREFIX.length());
- // Use our already ready ssl context
- soapServer.ctx = Battlenet::SslContext::instance().native_handle();
- soapServer.ssl_flags = SOAP_SSL_RSA;
+ Optional<std::vector<uint8>> decoded = Trinity::Encoding::Base64::Decode(authorization);
+ if (!decoded)
+ return ticket;
- while (!_stopped)
- {
- if (!soap_valid_socket(soap_accept(&soapServer)))
- continue; // ran into an accept timeout
-
- std::shared_ptr<AsyncRequest> soapClient = std::make_shared<AsyncRequest>(soapServer);
- if (soap_ssl_accept(soapClient->GetClient()) != SOAP_OK)
- {
- TC_LOG_DEBUG("server.rest", "Failed SSL handshake from IP={}", boost::asio::ip::address_v4(soapClient->GetClient()->ip).to_string());
- continue;
- }
-
- TC_LOG_DEBUG("server.rest", "Accepted connection from IP={}", boost::asio::ip::address_v4(soapClient->GetClient()->ip).to_string());
-
- Trinity::Asio::post(*_ioContext, [soapClient]()
- {
- soapClient->GetClient()->user = (void*)&soapClient; // this allows us to make a copy of pointer inside GET/POST handlers to increment reference count
- soap_begin(soapClient->GetClient());
- soap_begin_recv(soapClient->GetClient());
- });
- }
-
- // and release the context handle here - soap does not own it so it should not free it on exit
- soapServer.ctx = nullptr;
-
- TC_LOG_INFO("server.rest", "Login service exiting...");
-}
-
-int32 LoginRESTService::HandleHttpRequest(soap* soapClient, char const* method, HttpMethodHandlerMap const& handlers)
-{
- TC_LOG_DEBUG("server.rest", "[{}:{}] Handling {} request path=\"{}\"",
- boost::asio::ip::address_v4(soapClient->ip).to_string(), soapClient->port, method, soapClient->path);
-
- size_t pathLength = strlen(soapClient->path);
- if (char const* queryPart = strchr(soapClient->path, '?'))
- pathLength = queryPart - soapClient->path;
+ std::string_view decodedHeader(reinterpret_cast<char const*>(decoded->data()), decoded->size());
- auto handler = handlers.find(std::string{ soapClient->path, pathLength });
- if (handler != handlers.end())
- {
- int32 status = (this->*handler->second)(*reinterpret_cast<std::shared_ptr<AsyncRequest>*>(soapClient->user));
- if (status != SOAP_OK)
- {
- ResponseCodePlugin::GetForClient(soapClient)->ErrorCode = status;
- return SendResponse(soapClient, Battlenet::JSON::Login::ErrorResponse());
- }
+ if (std::size_t ticketEnd = decodedHeader.find(':'); ticketEnd != std::string_view::npos)
+ decodedHeader.remove_suffix(decodedHeader.length() - ticketEnd);
- return SOAP_OK;
- }
-
- ResponseCodePlugin::GetForClient(soapClient)->ErrorCode = 404;
- return SendResponse(soapClient, Battlenet::JSON::Login::ErrorResponse());
+ ticket = decodedHeader;
+ return ticket;
}
-int32 LoginRESTService::HandleGetForm(std::shared_ptr<AsyncRequest> request)
+LoginRESTService::RequestHandlerResult LoginRESTService::HandleGetForm(std::shared_ptr<LoginHttpSession> /*session*/, HttpRequestContext& context)
{
- return SendResponse(request->GetClient(), _formInputs);
+ context.response.set(boost::beast::http::field::content_type, "application/json;charset=utf-8");
+ context.response.body() = ::JSON::Serialize(_formInputs);
+ return RequestHandlerResult::Handled;
}
-int32 LoginRESTService::HandleGetGameAccounts(std::shared_ptr<AsyncRequest> request)
+LoginRESTService::RequestHandlerResult LoginRESTService::HandleGetGameAccounts(std::shared_ptr<LoginHttpSession> session, HttpRequestContext& context)
{
- if (!request->GetClient()->userid)
- return 401;
-
- request->SetCallback(std::make_unique<QueryCallback>(LoginDatabase.AsyncQuery([&] {
- LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_LIST);
- stmt->setString(0, request->GetClient()->userid);
- return stmt;
- }())
- .WithPreparedCallback([this, request](PreparedQueryResult result)
+ std::string ticket = ExtractAuthorization(context.request);
+ if (ticket.empty())
+ return HandleUnauthorized(std::move(session), context);
+
+ LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_LIST);
+ stmt->setString(0, ticket);
+ session->QueueQuery(LoginDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback([session, context = std::move(context)](PreparedQueryResult result) mutable
{
- Battlenet::JSON::Login::GameAccountList response;
+ JSON::Login::GameAccountList gameAccounts;
if (result)
{
auto formatDisplayName = [](char const* name) -> std::string
@@ -270,7 +192,7 @@ int32 LoginRESTService::HandleGetGameAccounts(std::shared_ptr<AsyncRequest> requ
do
{
Field* fields = result->Fetch();
- Battlenet::JSON::Login::GameAccountInfo* gameAccount = response.add_game_accounts();
+ JSON::Login::GameAccountInfo* gameAccount = gameAccounts.add_game_accounts();
gameAccount->set_display_name(formatDisplayName(fields[0].GetCString()));
gameAccount->set_expansion(fields[1].GetUInt8());
if (!fields[2].IsNull())
@@ -285,40 +207,37 @@ int32 LoginRESTService::HandleGetGameAccounts(std::shared_ptr<AsyncRequest> requ
} while (result->NextRow());
}
- SendResponse(request->GetClient(), response);
- })));
-
- Trinity::Asio::post(*_ioContext, [this, request]() { HandleAsyncRequest(request); });
+ context.response.set(boost::beast::http::field::content_type, "application/json;charset=utf-8");
+ context.response.body() = ::JSON::Serialize(gameAccounts);
+ session->SendResponse(context);
+ }));
- return SOAP_OK;
+ return RequestHandlerResult::Async;
}
-int32 LoginRESTService::HandleGetPortal(std::shared_ptr<AsyncRequest> request)
+LoginRESTService::RequestHandlerResult LoginRESTService::HandleGetPortal(std::shared_ptr<LoginHttpSession> session, HttpRequestContext& context)
{
- std::string const& hostname = GetHostnameForClient(boost::asio::ip::address_v4(request->GetClient()->ip));
- std::string response = Trinity::StringFormat("{}:{}", hostname, sConfigMgr->GetIntDefault("BattlenetPort", 1119));
-
- soap_response(request->GetClient(), SOAP_FILE);
- soap_send_raw(request->GetClient(), response.c_str(), response.length());
- return soap_end_send(request->GetClient());
+ context.response.set(boost::beast::http::field::content_type, "text/plain");
+ context.response.body() = Trinity::StringFormat("{}:{}", GetHostnameForClient(session->GetRemoteIpAddress()), sConfigMgr->GetIntDefault("BattlenetPort", 1119));
+ return RequestHandlerResult::Handled;
}
-int32 LoginRESTService::HandlePostLogin(std::shared_ptr<AsyncRequest> request)
+LoginRESTService::RequestHandlerResult LoginRESTService::HandlePostLogin(std::shared_ptr<LoginHttpSession> session, HttpRequestContext& context)
{
- char* buf = nullptr;
- size_t len = 0;
- soap_http_body(request->GetClient(), &buf, &len);
-
- Battlenet::JSON::Login::LoginForm loginForm;
- if (!buf || !JSON::Deserialize(buf, &loginForm))
+ JSON::Login::LoginForm loginForm;
+ if (!::JSON::Deserialize(context.request.body(), &loginForm))
{
- ResponseCodePlugin::GetForClient(request->GetClient())->ErrorCode = 400;
-
- Battlenet::JSON::Login::LoginResult loginResult;
- loginResult.set_authentication_state(Battlenet::JSON::Login::LOGIN);
+ JSON::Login::LoginResult loginResult;
+ loginResult.set_authentication_state(JSON::Login::LOGIN);
loginResult.set_error_code("UNABLE_TO_DECODE");
loginResult.set_error_message("There was an internal error while connecting to Battle.net. Please try again later.");
- return SendResponse(request->GetClient(), loginResult);
+
+ context.response.result(boost::beast::http::status::bad_request);
+ context.response.set(boost::beast::http::field::content_type, "application/json;charset=utf-8");
+ context.response.body() = ::JSON::Serialize(loginResult);
+ session->SendResponse(context);
+
+ return RequestHandlerResult::Handled;
}
std::string login;
@@ -340,44 +259,32 @@ int32 LoginRESTService::HandlePostLogin(std::shared_ptr<AsyncRequest> request)
std::string sentPasswordHash = CalculateShaPassHash(login, password);
- request->SetCallback(std::make_unique<QueryCallback>(LoginDatabase.AsyncQuery(stmt)
- .WithChainingPreparedCallback([request, login, sentPasswordHash, this](QueryCallback& callback, PreparedQueryResult result)
+ session->QueueQuery(LoginDatabase.AsyncQuery(stmt)
+ .WithChainingPreparedCallback([this, session, context = std::move(context), login = std::move(login), sentPasswordHash = std::move(sentPasswordHash)](QueryCallback& callback, PreparedQueryResult result) mutable
{
- if (result)
+ if (!result)
{
- Field* fields = result->Fetch();
- uint32 accountId = fields[0].GetUInt32();
- std::string pass_hash = fields[1].GetString();
- uint32 failedLogins = fields[2].GetUInt32();
- std::string loginTicket = fields[3].GetString();
- uint32 loginTicketExpiry = fields[4].GetUInt32();
- bool isBanned = fields[5].GetUInt64() != 0;
-
- if (sentPasswordHash == pass_hash)
- {
- if (loginTicket.empty() || loginTicketExpiry < time(nullptr))
- {
- std::array<uint8, 20> ticket = Trinity::Crypto::GetRandomBytes<20>();
+ JSON::Login::LoginResult loginResult;
+ loginResult.set_authentication_state(JSON::Login::DONE);
+ context.response.set(boost::beast::http::field::content_type, "application/json;charset=utf-8");
+ context.response.body() = ::JSON::Serialize(loginResult);
+ session->SendResponse(context);
+ return;
+ }
- loginTicket = "TC-" + ByteArrayToHexStr(ticket);
- }
+ Field* fields = result->Fetch();
+ uint32 accountId = fields[0].GetUInt32();
+ std::string pass_hash = fields[1].GetString();
+ uint32 failedLogins = fields[2].GetUInt32();
+ std::string loginTicket = fields[3].GetString();
+ uint32 loginTicketExpiry = fields[4].GetUInt32();
+ bool isBanned = fields[5].GetUInt64() != 0;
- LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_AUTHENTICATION);
- stmt->setString(0, loginTicket);
- stmt->setUInt32(1, time(nullptr) + _loginTicketDuration);
- stmt->setUInt32(2, accountId);
- callback.WithPreparedCallback([request, loginTicket](PreparedQueryResult)
- {
- Battlenet::JSON::Login::LoginResult loginResult;
- loginResult.set_authentication_state(Battlenet::JSON::Login::DONE);
- loginResult.set_login_ticket(loginTicket);
- sLoginService.SendResponse(request->GetClient(), loginResult);
- }).SetNextQuery(LoginDatabase.AsyncQuery(stmt));
- return;
- }
- else if (!isBanned)
+ if (sentPasswordHash != pass_hash)
+ {
+ if (!isBanned)
{
- std::string ip_address = boost::asio::ip::address_v4(request->GetClient()->ip).to_string();
+ std::string ip_address = session->GetRemoteIpAddress().to_string();
uint32 maxWrongPassword = uint32(sConfigMgr->GetIntDefault("WrongPass.MaxCount", 0));
if (sConfigMgr->GetBoolDefault("WrongPass.Logging", false))
@@ -421,31 +328,50 @@ int32 LoginRESTService::HandlePostLogin(std::shared_ptr<AsyncRequest> request)
LoginDatabase.CommitTransaction(trans);
}
}
+
+ JSON::Login::LoginResult loginResult;
+ loginResult.set_authentication_state(JSON::Login::DONE);
+
+ context.response.set(boost::beast::http::field::content_type, "application/json;charset=utf-8");
+ context.response.body() = ::JSON::Serialize(loginResult);
+ session->SendResponse(context);
+ return;
}
- Battlenet::JSON::Login::LoginResult loginResult;
- loginResult.set_authentication_state(Battlenet::JSON::Login::DONE);
- sLoginService.SendResponse(request->GetClient(), loginResult);
- })));
+ if (loginTicket.empty() || loginTicketExpiry < time(nullptr))
+ loginTicket = "TC-" + ByteArrayToHexStr(Trinity::Crypto::GetRandomBytes<20>());
- Trinity::Asio::post(*_ioContext, [this, request]() { HandleAsyncRequest(request); });
+ LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_AUTHENTICATION);
+ stmt->setString(0, loginTicket);
+ stmt->setUInt32(1, time(nullptr) + _loginTicketDuration);
+ stmt->setUInt32(2, accountId);
+ callback.WithPreparedCallback([session, context = std::move(context), loginTicket = std::move(loginTicket)](PreparedQueryResult) mutable
+ {
+ JSON::Login::LoginResult loginResult;
+ loginResult.set_authentication_state(JSON::Login::DONE);
+ loginResult.set_login_ticket(loginTicket);
+
+ context.response.set(boost::beast::http::field::content_type, "application/json;charset=utf-8");
+ context.response.body() = ::JSON::Serialize(loginResult);
+ session->SendResponse(context);
+ }).SetNextQuery(LoginDatabase.AsyncQuery(stmt));
+ }));
- return SOAP_OK;
+ return RequestHandlerResult::Async;
}
-int32 LoginRESTService::HandlePostRefreshLoginTicket(std::shared_ptr<AsyncRequest> request)
+LoginRESTService::RequestHandlerResult LoginRESTService::HandlePostRefreshLoginTicket(std::shared_ptr<LoginHttpSession> session, HttpRequestContext& context)
{
- if (!request->GetClient()->userid)
- return 401;
-
- request->SetCallback(std::make_unique<QueryCallback>(LoginDatabase.AsyncQuery([&] {
- LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_EXISTING_AUTHENTICATION);
- stmt->setString(0, request->GetClient()->userid);
- return stmt;
- }())
- .WithPreparedCallback([this, request](PreparedQueryResult result)
+ std::string ticket = ExtractAuthorization(context.request);
+ if (ticket.empty())
+ return HandleUnauthorized(std::move(session), context);
+
+ LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_EXISTING_AUTHENTICATION);
+ stmt->setString(0, ticket);
+ session->QueueQuery(LoginDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback([this, session, context = std::move(context), ticket = std::move(ticket)](PreparedQueryResult result) mutable
{
- Battlenet::JSON::Login::LoginRefreshResult loginRefreshResult;
+ JSON::Login::LoginRefreshResult loginRefreshResult;
if (result)
{
uint32 loginTicketExpiry = (*result)[0].GetUInt32();
@@ -456,7 +382,7 @@ int32 LoginRESTService::HandlePostRefreshLoginTicket(std::shared_ptr<AsyncReques
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_EXISTING_AUTHENTICATION);
stmt->setUInt32(0, uint32(now + _loginTicketDuration));
- stmt->setString(1, request->GetClient()->userid);
+ stmt->setString(1, ticket);
LoginDatabase.Execute(stmt);
}
else
@@ -465,34 +391,12 @@ int32 LoginRESTService::HandlePostRefreshLoginTicket(std::shared_ptr<AsyncReques
else
loginRefreshResult.set_is_expired(true);
- SendResponse(request->GetClient(), loginRefreshResult);
- })));
-
- Trinity::Asio::post(*_ioContext, [this, request]() { HandleAsyncRequest(request); });
-
- return SOAP_OK;
-}
-
-int32 LoginRESTService::SendResponse(soap* soapClient, google::protobuf::Message const& response)
-{
- std::string jsonResponse = JSON::Serialize(response);
-
- soap_response(soapClient, SOAP_FILE);
- soap_send_raw(soapClient, jsonResponse.c_str(), jsonResponse.length());
- return soap_end_send(soapClient);
-}
+ context.response.set(boost::beast::http::field::content_type, "application/json;charset=utf-8");
+ context.response.body() = ::JSON::Serialize(loginRefreshResult);
+ session->SendResponse(context);
+ }));
-void LoginRESTService::HandleAsyncRequest(std::shared_ptr<AsyncRequest> request)
-{
- if (!request->InvokeIfReady())
- {
- Trinity::Asio::post(*_ioContext, [this, request]() { HandleAsyncRequest(request); });
- }
- else if (request->GetResponseStatus())
- {
- ResponseCodePlugin::GetForClient(request->GetClient())->ErrorCode = request->GetResponseStatus();
- SendResponse(request->GetClient(), Battlenet::JSON::Login::ErrorResponse());
- }
+ return RequestHandlerResult::Async;
}
std::string LoginRESTService::CalculateShaPassHash(std::string const& name, std::string const& password)
@@ -510,85 +414,8 @@ std::string LoginRESTService::CalculateShaPassHash(std::string const& name, std:
return ByteArrayToHexStr(sha.GetDigest(), true);
}
-Namespace namespaces[] =
-{
- { nullptr, nullptr, nullptr, nullptr }
-};
-
-LoginRESTService& LoginRESTService::Instance()
-{
- static LoginRESTService instance;
- return instance;
-}
-
-char const* const LoginRESTService::ResponseCodePlugin::PluginId = "bnet-error-code";
-
-int32 LoginRESTService::ResponseCodePlugin::Init(soap* s, soap_plugin* p, void* /*arg*/)
-{
- ResponseCodePlugin* data = new ResponseCodePlugin();
- data->fresponse = s->fresponse;
-
- p->id = PluginId;
- p->fcopy = &Copy;
- p->fdelete = &Destroy;
- p->data = data;
-
- s->fresponse = &ChangeResponse;
- return SOAP_OK;
-}
-
-int32 LoginRESTService::ResponseCodePlugin::Copy(soap* /*s*/, soap_plugin* dst, soap_plugin* src)
-{
- dst->data = new ResponseCodePlugin(*reinterpret_cast<ResponseCodePlugin*>(src->data));
- return SOAP_OK;
-}
-
-void LoginRESTService::ResponseCodePlugin::Destroy(soap* s, soap_plugin* p)
-{
- ResponseCodePlugin* data = reinterpret_cast<ResponseCodePlugin*>(p->data);
- s->fresponse = data->fresponse;
- delete data;
-}
-
-int32 LoginRESTService::ResponseCodePlugin::ChangeResponse(soap* s, int32 originalResponse, uint64 contentLength)
-{
- ResponseCodePlugin* self = reinterpret_cast<ResponseCodePlugin*>(soap_lookup_plugin(s, PluginId));
- return self->fresponse(s, self->ErrorCode && originalResponse == SOAP_FILE ? self->ErrorCode : originalResponse, contentLength);
-}
-
-LoginRESTService::ResponseCodePlugin* LoginRESTService::ResponseCodePlugin::GetForClient(soap* s)
-{
- return ASSERT_NOTNULL(reinterpret_cast<ResponseCodePlugin*>(soap_lookup_plugin(s, PluginId)));
-}
-
-char const* const LoginRESTService::ContentTypePlugin::PluginId = "bnet-content-type";
-
-int32 LoginRESTService::ContentTypePlugin::Init(soap* s, soap_plugin* p, void* arg)
-{
- ContentTypePlugin* data = new ContentTypePlugin();
- data->fposthdr = s->fposthdr;
- data->ContentType = reinterpret_cast<char const*>(arg);
-
- p->id = PluginId;
- p->fdelete = &Destroy;
- p->data = data;
-
- s->fposthdr = &OnSetHeader;
- return SOAP_OK;
-}
-
-void LoginRESTService::ContentTypePlugin::Destroy(soap* s, soap_plugin* p)
+void LoginRESTService::OnSocketAccept(boost::asio::ip::tcp::socket&& sock, uint32 threadIndex)
{
- ContentTypePlugin* data = reinterpret_cast<ContentTypePlugin*>(p->data);
- s->fposthdr = data->fposthdr;
- delete data;
+ sLoginService.OnSocketOpen(std::move(sock), threadIndex);
}
-
-int32 LoginRESTService::ContentTypePlugin::OnSetHeader(soap* s, char const* key, char const* value)
-{
- ContentTypePlugin* self = reinterpret_cast<ContentTypePlugin*>(soap_lookup_plugin(s, PluginId));
- if (key && !strcmp("Content-Type", key))
- value = self->ContentType;
-
- return self->fposthdr(s, key, value);
}