Merge pull request #8063 from heinrich5991/pr_ddnet_register_error

Show error from masterserver in console
This commit is contained in:
heinrich5991 2024-03-04 23:08:25 +00:00 committed by GitHub
commit c15733eda3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 62 additions and 13 deletions

@ -1 +1 @@
Subproject commit 4d796ea119b52c8901286e14ab96faf7353a5d59
Subproject commit a4fbe0e52338a129bc3ac2e3a1de54de1d175279

View file

@ -21,6 +21,7 @@ class CRegister : public IRegister
STATUS_OK,
STATUS_NEEDCHALLENGE,
STATUS_NEEDINFO,
STATUS_ERROR,
PROTOCOL_TW6_IPV6 = 0,
PROTOCOL_TW6_IPV4,
@ -156,6 +157,10 @@ bool CRegister::StatusFromString(int *pResult, const char *pString)
{
*pResult = STATUS_NEEDINFO;
}
else if(str_comp(pString, "error") == 0)
{
*pResult = STATUS_ERROR;
}
else
{
*pResult = -1;
@ -302,6 +307,7 @@ void CRegister::CProtocol::SendRegister()
}
pRegister->LogProgress(HTTPLOG::FAILURE);
pRegister->IpResolve(ProtocolToIpresolve(m_Protocol));
pRegister->FailOnErrorStatus(false);
int RequestIndex;
{
@ -413,9 +419,8 @@ void CRegister::CProtocol::CJob::Run()
m_pRegister->Wait();
if(m_pRegister->State() != EHttpState::DONE)
{
// TODO: log the error response content from master
// TODO: exponential backoff
log_error(ProtocolToSystem(m_Protocol), "error response from master");
log_error(ProtocolToSystem(m_Protocol), "error sending request to master");
return;
}
json_value *pJson = m_pRegister->ResultJson();
@ -439,6 +444,25 @@ void CRegister::CProtocol::CJob::Run()
json_value_free(pJson);
return;
}
if(Status == STATUS_ERROR)
{
const json_value &Message = Json["message"];
if(Message.type != json_string)
{
json_value_free(pJson);
log_error(ProtocolToSystem(m_Protocol), "invalid JSON error response from master");
return;
}
log_error(ProtocolToSystem(m_Protocol), "error response from master: %d: %s", m_pRegister->StatusCode(), (const char *)Message);
json_value_free(pJson);
return;
}
if(m_pRegister->StatusCode() >= 400)
{
log_error(ProtocolToSystem(m_Protocol), "non-success status code %d from master without error code", m_pRegister->StatusCode());
json_value_free(pJson);
return;
}
{
CLockScope ls(m_pShared->m_Lock);
if(Status != STATUS_OK || Status != m_pShared->m_LatestResponseStatus)

View file

@ -139,7 +139,10 @@ bool CHttpRequest::ConfigureHandle(void *pHandle)
#endif
curl_easy_setopt(pH, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(pH, CURLOPT_MAXREDIRS, 4L);
curl_easy_setopt(pH, CURLOPT_FAILONERROR, 1L);
if(m_FailOnErrorStatus)
{
curl_easy_setopt(pH, CURLOPT_FAILONERROR, 1L);
}
curl_easy_setopt(pH, CURLOPT_URL, m_aUrl);
curl_easy_setopt(pH, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(pH, CURLOPT_USERAGENT, GAME_NAME " " GAME_RELEASE_VERSION " (" CONF_PLATFORM_STRING "; " CONF_ARCH_STRING ")");
@ -256,8 +259,16 @@ int CHttpRequest::ProgressCallback(void *pUser, double DlTotal, double DlCurr, d
return pTask->m_Abort ? -1 : 0;
}
void CHttpRequest::OnCompletionInternal(unsigned int Result)
void CHttpRequest::OnCompletionInternal(void *pHandle, unsigned int Result)
{
if(pHandle)
{
CURL *pH = (CURL *)pHandle;
long StatusCode;
curl_easy_getinfo(pH, CURLINFO_RESPONSE_CODE, &StatusCode);
m_StatusCode = StatusCode;
}
EHttpState State;
const CURLcode Code = static_cast<CURLcode>(Result);
if(Code != CURLE_OK)
@ -373,6 +384,12 @@ const SHA256_DIGEST &CHttpRequest::ResultSha256() const
return m_ActualSha256;
}
int CHttpRequest::StatusCode() const
{
dbg_assert(State() == EHttpState::DONE, "Request not done");
return m_StatusCode;
}
bool CHttp::Init(std::chrono::milliseconds ShutdownDelay)
{
m_ShutdownDelay = ShutdownDelay;
@ -478,7 +495,7 @@ void CHttp::RunLoop()
auto pRequest = std::move(RequestIt->second);
m_RunningRequests.erase(RequestIt);
pRequest->OnCompletionInternal(pMsg->data.result);
pRequest->OnCompletionInternal(pMsg->easy_handle, pMsg->data.result);
curl_multi_remove_handle(m_pMultiH, pMsg->easy_handle);
curl_easy_cleanup(pMsg->easy_handle);
}
@ -534,20 +551,21 @@ void CHttp::RunLoop()
for(auto &pRequest : m_PendingRequests)
{
str_copy(pRequest->m_aErr, "Shutting down");
pRequest->OnCompletionInternal(CURLE_ABORTED_BY_CALLBACK);
pRequest->OnCompletionInternal(nullptr, CURLE_ABORTED_BY_CALLBACK);
}
for(auto &ReqPair : m_RunningRequests)
{
auto &[pHandle, pRequest] = ReqPair;
str_copy(pRequest->m_aErr, "Shutting down");
pRequest->OnCompletionInternal(pHandle, CURLE_ABORTED_BY_CALLBACK);
if(Cleanup)
{
curl_multi_remove_handle(m_pMultiH, pHandle);
curl_easy_cleanup(pHandle);
}
str_copy(pRequest->m_aErr, "Shutting down");
pRequest->OnCompletionInternal(CURLE_ABORTED_BY_CALLBACK);
}
if(Cleanup)
@ -564,7 +582,7 @@ void CHttp::Run(std::shared_ptr<IHttpRequest> pRequest)
if(m_Shutdown)
{
str_copy(pRequestImpl->m_aErr, "Shutting down");
pRequestImpl->OnCompletionInternal(CURLE_ABORTED_BY_CALLBACK);
pRequestImpl->OnCompletionInternal(nullptr, CURLE_ABORTED_BY_CALLBACK);
return;
}
m_Cv.wait(Lock, [this]() { return m_State != CHttp::UNINITIALIZED; });

View file

@ -111,14 +111,19 @@ class CHttpRequest : public IHttpRequest
HTTPLOG m_LogProgress = HTTPLOG::ALL;
IPRESOLVE m_IpResolve = IPRESOLVE::WHATEVER;
bool m_FailOnErrorStatus = true;
char m_aErr[256]; // 256 == CURL_ERROR_SIZE
std::atomic<EHttpState> m_State{EHttpState::QUEUED};
std::atomic<bool> m_Abort{false};
int m_StatusCode = 0;
// Abort the request with an error if `BeforeInit()` returns false.
bool BeforeInit();
bool ConfigureHandle(void *pHandle); // void * == CURL *
void OnCompletionInternal(unsigned int Result); // unsigned int == CURLcode
// `pHandle` can be nullptr if no handle was ever created for this request.
void OnCompletionInternal(void *pHandle, unsigned int Result); // void * == CURL *, unsigned int == CURLcode
// Abort the request if `OnData()` returns something other than
// `DataSize`.
@ -140,6 +145,7 @@ public:
void MaxResponseSize(int64_t MaxResponseSize) { m_MaxResponseSize = MaxResponseSize; }
void LogProgress(HTTPLOG LogProgress) { m_LogProgress = LogProgress; }
void IpResolve(IPRESOLVE IpResolve) { m_IpResolve = IpResolve; }
void FailOnErrorStatus(bool FailOnErrorStatus) { m_FailOnErrorStatus = FailOnErrorStatus; }
void WriteToFile(IStorage *pStorage, const char *pDest, int StorageType);
void ExpectSha256(const SHA256_DIGEST &Sha256) { m_ExpectedSha256 = Sha256; }
void Head() { m_Type = REQUEST::HEAD; }
@ -198,8 +204,9 @@ public:
void Result(unsigned char **ppResult, size_t *pResultLength) const;
json_value *ResultJson() const;
const SHA256_DIGEST &ResultSha256() const;
int StatusCode() const;
};
inline std::unique_ptr<CHttpRequest> HttpHead(const char *pUrl)