Committing updates.

This commit is contained in:
Преподобный Ален
2021-11-03 00:02:21 +03:00
parent 2832907231
commit ae95edd345
2 changed files with 166 additions and 90 deletions

View File

@@ -51,7 +51,7 @@ namespace Apostol {
CString to_string(unsigned long Value) {
TCHAR szString[_INT_T_LEN + 1] = {0};
sprintf(szString, "%lu", Value);
return CString(szString);
return {szString};
}
//--------------------------------------------------------------------------------------------------------------
@@ -62,11 +62,9 @@ namespace Apostol {
CWebService::CWebService(CModuleProcess *AProcess): CApostolModule(AProcess, "web service") {
m_SyncPeriod = BPS_DEFAULT_SYNC_PERIOD;
m_ServerIndex = -1;
m_KeyIndex = 0;
m_ActiveIndex = -1;
m_FixedDate = 0;
m_RandomDate = 0;
m_Status = psStopped;
@@ -74,6 +72,8 @@ namespace Apostol {
m_DefaultServer.Value().URI = BPS_SERVER_URL;
m_DefaultServer.Value().PGP.Name = BPS_BM_SERVER_ADDRESS;
m_CurrentServer = m_DefaultServer;
CWebService::InitMethods();
}
//--------------------------------------------------------------------------------------------------------------
@@ -113,7 +113,7 @@ namespace Apostol {
//--------------------------------------------------------------------------------------------------------------
void CWebService::LoadOAuth2(const CString &FileName, const CString &ProviderName, const CString &ApplicationName,
CProviders &Providers) {
CProviders &Providers) {
CString ConfigFile(FileName);
@@ -1166,12 +1166,14 @@ namespace Apostol {
} else {
Node = YAML::Load(pServerRequest->Content.c_str());
}
const auto &BTCKeys = CurrentServer().Value().BTCKeys;
if (m_BTCKeys.Count() < 2)
if (BTCKeys.Count() < 2)
throw ExceptionFrm("Bitcoin keys cannot be empty.");
for (int i = 0; i < m_BTCKeys.Count(); ++i) {
if (m_BTCKeys[i].IsEmpty())
for (int i = 0; i < BTCKeys.Count(); ++i) {
if (BTCKeys[i].IsEmpty())
throw ExceptionFrm("Bitcoin KEY%d cannot be empty.", i);
}
@@ -1180,7 +1182,7 @@ namespace Apostol {
auto& Data = Deal.Data();
if (Data.Order == doCreate) {
Data.Payment.Address = Deal.GetPaymentHD(m_BTCKeys.Names(0), m_BTCKeys.Names(1),
Data.Payment.Address = Deal.GetPaymentHD(BTCKeys.Names(0), BTCKeys.Names(1),
Deal.Data().Transaction.Key, BitcoinConfig.version_hd, BitcoinConfig.version_script);
Node["deal"]["date"] = Data.Date.c_str();
@@ -1485,20 +1487,34 @@ namespace Apostol {
}
//--------------------------------------------------------------------------------------------------------------
int CWebService::NextServerIndex() {
m_ServerIndex++;
if (m_ServerIndex >= m_Servers.Count())
m_ServerIndex = -1;
return m_ServerIndex;
const CServer &CWebService::CurrentServer() const {
return m_CurrentServer;
}
//--------------------------------------------------------------------------------------------------------------
const CServer &CWebService::CurrentServer() const {
if (m_Servers.Count() == 0 && m_ServerIndex == -1)
int CWebService::NextServerIndex() {
m_ActiveIndex++;
if (m_ActiveIndex >= m_Servers.Count())
m_ActiveIndex = -1;
return m_ActiveIndex;
}
//--------------------------------------------------------------------------------------------------------------
CServer &CWebService::ActiveServer() {
if (m_Servers.Count() == 0 && m_ActiveIndex == -1)
return m_DefaultServer;
if (m_ServerIndex == -1)
if (m_ActiveIndex == -1)
return m_Servers[0];
return m_Servers[m_ServerIndex];
return m_Servers[m_ActiveIndex];
}
//--------------------------------------------------------------------------------------------------------------
const CServer &CWebService::ActiveServer() const {
if (m_Servers.Count() == 0 && m_ActiveIndex == -1)
return m_DefaultServer;
if (m_ActiveIndex == -1)
return m_Servers[0];
return m_Servers[m_ActiveIndex];
}
//--------------------------------------------------------------------------------------------------------------
@@ -1614,15 +1630,16 @@ namespace Apostol {
}
//--------------------------------------------------------------------------------------------------------------
void CWebService::FetchPGP(CKeyContext &PGP) {
void CWebService::FetchPGP(CServer &Server) {
const auto& caServerContext = CurrentServer().Value();
Log()->Debug(0, "Trying to fetch a PGP key \"%s\" from: %s", Server.Name().c_str(), Server.Value().URI.c_str());
Log()->Debug(0, "Trying to fetch a PGP key \"%s\" from: %s", PGP.Name.c_str(), caServerContext.URI.c_str());
auto OnRequest = [this, &Server](CHTTPClient *Sender, CHTTPRequest *ARequest) {
auto &PGP = Server.Value().PGP;
auto OnRequest = [this, &PGP](CHTTPClient *Sender, CHTTPRequest *ARequest) {
PGP.StatusTime = Now();
PGP.Status = CKeyContext::ksFetching;
PGP.RunTime = PGP.StatusTime + (CDateTime) 30 / SecsPerDay;
CHTTPRequest::Prepare(ARequest, "GET", CString().Format("/api/v1/key/public?account=%s&type=pgp", PGP.Name.c_str()).c_str());
@@ -1631,58 +1648,61 @@ namespace Apostol {
DebugRequest(ARequest);
};
auto OnExecute = [this, &PGP](CTCPConnection *AConnection) {
auto OnExecute = [this, &Server](CTCPConnection *AConnection) {
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
if (pConnection == nullptr)
return true;
if (pConnection != nullptr) {
auto pReply = pConnection->Reply();
auto pReply = pConnection->Reply();
DebugReply(pReply);
DebugReply(pReply);
auto &PGP = Server.Value().PGP;
try {
PGP.StatusTime = Now();
PGP.Status = CKeyContext::ksError;
PGP.RunTime = PGP.StatusTime + (CDateTime) 30 / SecsPerDay;
JsonStringToKey(pReply->Content, PGP.Key);
try {
JsonStringToKey(pReply->Content, PGP.Key);
if (PGP.Key.IsEmpty())
throw Delphi::Exception::Exception("Not found.");
if (PGP.Key.IsEmpty())
throw Delphi::Exception::Exception("Not found.");
DebugMessage("[PGP] Key:\n%s\n", PGP.Key.c_str());
CStringPairs ServerList;
CStringPairs ServerList;
CStringList BTCKeys;
ParsePGPKey(PGP.Key, ServerList, Server.Value().BTCKeys);
ParsePGPKey(PGP.Key, ServerList, BTCKeys);
if (ServerList.Count() != 0) {
CStringPairs::ConstEnumerator em(ServerList);
while (em.MoveNext()) {
const auto &current = em.Current();
if (m_Servers.IndexOfName(current.Name()) == -1) {
m_Servers.AddPair(current.Name(), CServerContext(current.Value()));
if (ServerList.Count() != 0) {
CStringPairs::ConstEnumerator em(ServerList);
while (em.MoveNext()) {
const auto &current = em.Current();
if (m_Servers.IndexOfName(current.Name()) == -1) {
m_Servers.AddPair(current.Name(), CServerContext(current.Value()));
}
}
}
PGP.Status = CKeyContext::ksSuccess;
PGP.RunTime = GetRandomDate(10 * 60, m_SyncPeriod * 60, PGP.StatusTime); // 10..m_SyncPeriod min
m_CurrentServer = Server;
Log()->Debug(APP_LOG_DEBUG_CORE, "[CurrentServer]\n");
Log()->Debug(APP_LOG_DEBUG_CORE, "[Name]\n%s", m_CurrentServer.Name().c_str());
Log()->Debug(APP_LOG_DEBUG_CORE, "[PGP]\n%s", m_CurrentServer.Value().PGP.Key.c_str());
Log()->Debug(APP_LOG_DEBUG_CORE, "[BTCKeys]\n%s", m_CurrentServer.Value().BTCKeys.Text().c_str());
} catch (Delphi::Exception::Exception &e) {
Log()->Error(APP_LOG_INFO, 0, "[CurrentServer] Message: %s", e.what());
}
m_BTCKeys = BTCKeys;
PGP.Status = CKeyContext::ksSuccess;
m_RandomDate = GetRandomDate(10 * 60, m_SyncPeriod * 60, Now()); // 10..m_SyncPeriod min
} catch (Delphi::Exception::Exception &e) {
Log()->Error(APP_LOG_INFO, 0, "[PGP] Message: %s", e.what());
PGP.Status = CKeyContext::ksError;
m_RandomDate = Now() + (CDateTime) 30 / SecsPerDay;
pConnection->CloseConnection(true);
}
pConnection->CloseConnection(true);
return true;
};
auto OnException = [this, &PGP](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
auto OnException = [&Server](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
if (pConnection != nullptr) {
@@ -1691,15 +1711,18 @@ namespace Apostol {
if (pClient != nullptr) {
Log()->Error(APP_LOG_EMERG, 0, "[%s:%d] %s", pClient->Host().c_str(), pClient->Port(), E.what());
auto &PGP = Server.Value().PGP;
PGP.StatusTime = Now();
PGP.Status = CKeyContext::ksError;
m_RandomDate = Now() + (CDateTime) 5 / SecsPerDay;
PGP.RunTime = PGP.StatusTime + (CDateTime) 30 / SecsPerDay;
}
DebugReply(pConnection->Reply());
}
};
CLocation Location(caServerContext.URI);
CLocation Location(Server.Value().URI);
auto pClient = GetClient(Location.hostname, Location.port == 0 ? BPS_SERVER_PORT : Location.port);
pClient->OnRequest(OnRequest);
@@ -1710,40 +1733,48 @@ namespace Apostol {
}
//--------------------------------------------------------------------------------------------------------------
void CWebService::FetchBTC(CKeyContext &BTC) {
void CWebService::FetchBTC(CServer &Server) {
const auto& caServerContext = CurrentServer().Value();
Log()->Debug(0, "Trying to fetch a BTC key \"%s\" from: %s", Server.Name().c_str(), Server.Value().URI.c_str());
Log()->Debug(0, "Trying to fetch a BTC key \"%s\" from: %s", BTC.Name.c_str(), caServerContext.URI.c_str());
auto OnRequest = [this, &Server](CHTTPClient *Sender, CHTTPRequest *ARequest) {
auto &BTC = Server.Value().BTC;
auto OnRequest = [this, &BTC](CHTTPClient *Sender, CHTTPRequest *ARequest) {
const auto& caServerContext = CurrentServer().Value();
BTC.StatusTime = Now();
BTC.Status = CKeyContext::ksFetching;
BTC.RunTime = BTC.StatusTime + (CDateTime) 30 / SecsPerDay;
CHTTPRequest::Prepare(ARequest, "GET", CString().Format("/api/v1/key/public?account=%s&type=btc", BTC.Name.c_str()).c_str());
ARequest->AddHeader("Authorization", "Bearer " + m_Tokens[SYSTEM_PROVIDER_NAME]["access_token"]);
};
auto OnExecute = [this, &BTC](CTCPConnection *AConnection) {
auto OnExecute = [this, &Server](CTCPConnection *AConnection) {
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
auto pReply = pConnection->Reply();
auto &BTC = Server.Value().BTC;
BTC.StatusTime = Now();
BTC.Status = CKeyContext::ksError;
BTC.RunTime = BTC.StatusTime + (CDateTime) 30 / SecsPerDay;
try {
CString Key;
JsonStringToKey(pReply->Content, Key);
if (!Key.IsEmpty()) {
m_BTCKeys.Add(Key);
m_KeyIndex++;
//FetchBTC();
Server.Value().BTCKeys.Add(Key);
}
} catch (Delphi::Exception::Exception &e) {
Log()->Error(APP_LOG_INFO, 0, "[BTC] Message: %s", e.what());
if (m_BTCKeys.Count() == 0) {
if (Server.Value().BTCKeys.Count() == 0) {
BTC.Status = CKeyContext::ksError;
} else {
BTC.Status = CKeyContext::ksSuccess;
BTC.RunTime = GetRandomDate(10 * 60, m_SyncPeriod * 60, BTC.StatusTime); // 10..m_SyncPeriod min
}
}
@@ -1752,15 +1783,20 @@ namespace Apostol {
return true;
};
auto OnException = [&BTC](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
auto OnException = [&Server](CTCPConnection *AConnection, const Delphi::Exception::Exception &E) {
auto pConnection = dynamic_cast<CHTTPClientConnection *> (AConnection);
auto pClient = dynamic_cast<CHTTPClient *> (pConnection->Client());
Log()->Error(APP_LOG_EMERG, 0, "[%s:%d] %s", pClient->Host().c_str(), pClient->Port(), E.what());
auto &BTC = Server.Value().BTC;
BTC.StatusTime = Now();
BTC.Status = CKeyContext::ksError;
BTC.RunTime = BTC.StatusTime + (CDateTime) 30 / SecsPerDay;
};
CLocation Location(caServerContext.URI);
CLocation Location(Server.Value().URI);
auto pClient = GetClient(Location.hostname, Location.port == 0 ? BPS_SERVER_PORT : Location.port);
pClient->OnRequest(OnRequest);
@@ -1771,12 +1807,14 @@ namespace Apostol {
}
//--------------------------------------------------------------------------------------------------------------
void CWebService::FetchKeys() {
m_KeyIndex = 0;
if (NextServerIndex() != -1) {
m_PGP.Status = CKeyContext::ksUnknown;
FetchPGP(m_PGP);
FetchPGP(m_Servers[m_ServerIndex].Value().PGP);
void CWebService::FetchKeys(CDateTime Now) {
while (NextServerIndex() != -1) {
auto& Server = ActiveServer();
auto& PGP = Server.Value().PGP;
if (Now >= PGP.RunTime) {
PGP.Status = CKeyContext::ksUnknown;
FetchPGP(Server);
}
}
}
//--------------------------------------------------------------------------------------------------------------
@@ -1824,9 +1862,7 @@ namespace Apostol {
}
if (m_Status == psRunning) {
if (now >= m_RandomDate) {
FetchKeys();
}
FetchKeys(now);
}
}
//--------------------------------------------------------------------------------------------------------------

View File

@@ -50,22 +50,46 @@ namespace Apostol {
} Status;
CDateTime StatusTime;
CDateTime RunTime;
CKeyContext(): Status(ksUnknown), StatusTime(Now()) {
CKeyContext(): Status(ksUnknown), StatusTime(Now()), RunTime(0) {
Name = BPS_BM_SERVER_ADDRESS;
}
CKeyContext(const CString& Name, const CString& Key): CKeyContext() {
CKeyContext(const CString &Name, const CString &Key): CKeyContext() {
this->Name = Name;
this->Key = Key;
}
CKeyContext(const CKeyContext &KeyContext): CKeyContext() {
Assign(KeyContext);
}
void Assign(const CKeyContext &KeyContext) {
this->Name = KeyContext.Name;
this->Key = KeyContext.Key;
this->Status = KeyContext.Status;
this->StatusTime = KeyContext.StatusTime;
this->RunTime = KeyContext.RunTime;
}
CKeyContext& operator= (const CKeyContext &KeyContext) {
if (this != &KeyContext) {
Assign(KeyContext);
}
return *this;
};
};
struct CServerContext {
CString URI;
CKeyContext PGP;
CString URI {};
CKeyContext PGP {};
CKeyContext BTC {};
CStringList BTCKeys;
CServerContext() = default;
@@ -73,6 +97,24 @@ namespace Apostol {
this->URI = URI;
}
CServerContext(const CServerContext &ServerContext): CServerContext() {
Assign(ServerContext);
}
void Assign(const CServerContext &ServerContext) {
this->URI = ServerContext.URI;
this->PGP = ServerContext.PGP;
this->BTC = ServerContext.BTC;
this->BTCKeys = ServerContext.BTCKeys;
}
CServerContext& operator= (const CServerContext &ServerContext) {
if (this != &ServerContext) {
Assign(ServerContext);
}
return *this;
};
};
typedef TPair<CServerContext> CServer;
@@ -89,21 +131,16 @@ namespace Apostol {
CProcessStatus m_Status;
CServer m_DefaultServer;
CServer m_DefaultServer {};
CServer m_CurrentServer {};
int m_SyncPeriod;
int m_ServerIndex;
int m_KeyIndex;
int m_ActiveIndex;
CDateTime m_FixedDate;
CDateTime m_RandomDate;
CKeyContext m_PGP;
CServerList m_Servers;
CStringList m_BTCKeys;
CProviders m_Providers;
CStringListPairs m_Tokens;
@@ -135,8 +172,11 @@ namespace Apostol {
const CServer &CurrentServer() const;
void FetchPGP(CKeyContext& PGP);
void FetchBTC(CKeyContext& BTC);
CServer &ActiveServer();
const CServer &ActiveServer() const;
void FetchPGP(CServer& Server);
void FetchBTC(CServer& Server);
static int CheckFee(const CString& Fee);
@@ -171,7 +211,7 @@ namespace Apostol {
bool Enabled() override;
void FetchKeys();
void FetchKeys(CDateTime Now);
void Reload();