HTTP: Set final m_State after running completion function

Ensures that we don't delete a file that is being used by ingame map
downloader already.

As reported by Jupeyy in #2901
This commit is contained in:
def 2020-09-24 09:52:11 +02:00
parent 1c3244a8f5
commit 2be54a30ad
3 changed files with 39 additions and 31 deletions

View file

@ -88,18 +88,19 @@ CRequest::CRequest(const char *pUrl, CTimeout Timeout, bool LogProgress)
void CRequest::Run()
{
int FinalState;
if(!BeforeInit())
{
m_State = HTTP_ERROR;
OnCompletion();
return;
FinalState = HTTP_ERROR;
}
else
{
CURL *pHandle = curl_easy_init();
FinalState = RunImpl(pHandle);
curl_easy_cleanup(pHandle);
}
CURL *pHandle = curl_easy_init();
m_State = RunImpl(pHandle);
curl_easy_cleanup(pHandle);
OnCompletion();
m_State = OnCompletion(FinalState);
}
int CRequest::RunImpl(CURL *pHandle)
@ -144,10 +145,6 @@ int CRequest::RunImpl(CURL *pHandle)
dbg_msg("http", "http %s", m_aUrl);
m_State = HTTP_RUNNING;
int Ret = curl_easy_perform(pHandle);
if(!BeforeCompletion())
{
return HTTP_ERROR;
}
if(Ret != CURLE_OK)
{
if(g_Config.m_DbgCurl || m_LogProgress)
@ -253,7 +250,8 @@ size_t CGet::OnData(char *pData, size_t DataSize)
CGetFile::CGetFile(IStorage *pStorage, const char *pUrl, const char *pDest, int StorageType, CTimeout Timeout, bool LogProgress)
: CRequest(pUrl, Timeout, LogProgress),
m_pStorage(pStorage),
m_StorageType(StorageType)
m_StorageType(StorageType),
m_File(0)
{
str_copy(m_aDest, pDest, sizeof(m_aDest));
@ -285,17 +283,19 @@ size_t CGetFile::OnData(char *pData, size_t DataSize)
return io_write(m_File, pData, DataSize);
}
bool CGetFile::BeforeCompletion()
int CGetFile::OnCompletion(int State)
{
return io_close(m_File) == 0;
}
if(m_File && io_close(m_File) != 0)
{
State = HTTP_ERROR;
}
void CGetFile::OnCompletion()
{
if(State() == HTTP_ERROR || State() == HTTP_ABORTED)
if(State == HTTP_ERROR || State == HTTP_ABORTED)
{
m_pStorage->RemoveFile(m_aDestFull, IStorage::TYPE_ABSOLUTE);
}
return State;
}
CPostJson::CPostJson(const char *pUrl, CTimeout Timeout, const char *pJson)

View file

@ -33,9 +33,7 @@ class CRequest : public IJob
virtual bool AfterInit(void *pCurl) { return true; }
virtual size_t OnData(char *pData, size_t DataSize) = 0;
virtual void OnProgress() { }
virtual bool BeforeCompletion() { return true; }
virtual void OnCompletion() { }
virtual void OnProgress() {}
char m_aUrl[256];
@ -55,6 +53,9 @@ class CRequest : public IJob
void Run();
int RunImpl(CURL *pHandle);
protected:
virtual int OnCompletion(int State) { return State; }
public:
CRequest(const char *pUrl, CTimeout Timeout, bool LogProgress = true);
@ -87,8 +88,6 @@ class CGetFile : public CRequest
{
virtual size_t OnData(char *pData, size_t DataSize);
virtual bool BeforeInit();
virtual bool BeforeCompletion();
virtual void OnCompletion();
IStorage *m_pStorage;
@ -97,6 +96,9 @@ class CGetFile : public CRequest
int m_StorageType;
IOHANDLE m_File;
protected:
virtual int OnCompletion(int State);
public:
CGetFile(IStorage *pStorage, const char *pUrl, const char *pDest, int StorageType = -2, CTimeout Timeout = CTimeout{4000, 500, 5}, bool LogProgress = true);

View file

@ -18,8 +18,10 @@ class CUpdaterFetchTask : public CGetFile
char m_aBuf2[256];
CUpdater *m_pUpdater;
void OnCompletion();
void OnProgress();
virtual void OnProgress();
protected:
virtual int OnCompletion(int State);
public:
CUpdaterFetchTask(CUpdater *pUpdater, const char *pFile, const char *pDestPath);
@ -55,8 +57,10 @@ void CUpdaterFetchTask::OnProgress()
lock_unlock(m_pUpdater->m_Lock);
}
void CUpdaterFetchTask::OnCompletion()
int CUpdaterFetchTask::OnCompletion(int State)
{
State = CGetFile::OnCompletion(State);
const char *b = 0;
for(const char *a = Dest(); *a; a++)
if(*a == '/')
@ -64,18 +68,20 @@ void CUpdaterFetchTask::OnCompletion()
b = b ? b : Dest();
if(!str_comp(b, "update.json"))
{
if(State() == HTTP_DONE)
if(State == HTTP_DONE)
m_pUpdater->SetCurrentState(IUpdater::GOT_MANIFEST);
else if(State() == HTTP_ERROR)
else if(State == HTTP_ERROR)
m_pUpdater->SetCurrentState(IUpdater::FAIL);
}
else if(!str_comp(b, m_pUpdater->m_aLastFile))
{
if(State() == HTTP_DONE)
if(State == HTTP_DONE)
m_pUpdater->SetCurrentState(IUpdater::MOVE_FILES);
else if(State() == HTTP_ERROR)
else if(State == HTTP_ERROR)
m_pUpdater->SetCurrentState(IUpdater::FAIL);
}
return State;
}
CUpdater::CUpdater()