2018-12-12 08:59:42 +00:00
|
|
|
#ifndef ENGINE_CLIENT_HTTP_H
|
|
|
|
#define ENGINE_CLIENT_HTTP_H
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
#include <engine/kernel.h>
|
2018-07-11 18:17:21 +00:00
|
|
|
#include <engine/shared/jobs.h>
|
|
|
|
#include <engine/storage.h>
|
|
|
|
|
|
|
|
typedef struct _json_value json_value;
|
2019-04-04 19:38:52 +00:00
|
|
|
typedef void CURL;
|
2018-07-11 18:17:21 +00:00
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
HTTP_ERROR = -1,
|
|
|
|
HTTP_QUEUED,
|
|
|
|
HTTP_RUNNING,
|
|
|
|
HTTP_DONE,
|
|
|
|
HTTP_ABORTED,
|
|
|
|
};
|
|
|
|
|
2020-09-04 17:56:30 +00:00
|
|
|
struct CTimeout
|
|
|
|
{
|
|
|
|
long ConnectTimeoutMs;
|
|
|
|
long LowSpeedLimit;
|
|
|
|
long LowSpeedTime;
|
|
|
|
};
|
|
|
|
|
2018-07-11 18:17:21 +00:00
|
|
|
class CRequest : public IJob
|
|
|
|
{
|
|
|
|
// Abort the request with an error if `BeforeInit()` or `AfterInit()`
|
2019-12-20 21:50:01 +00:00
|
|
|
// returns false. Also abort the request if `OnData()` returns
|
|
|
|
// something other than `DataSize`.
|
2019-04-04 19:38:52 +00:00
|
|
|
virtual bool BeforeInit() { return true; }
|
|
|
|
virtual bool AfterInit(void *pCurl) { return true; }
|
2018-07-11 18:17:21 +00:00
|
|
|
virtual size_t OnData(char *pData, size_t DataSize) = 0;
|
|
|
|
|
2020-09-24 07:52:11 +00:00
|
|
|
virtual void OnProgress() {}
|
2018-07-11 18:17:21 +00:00
|
|
|
|
|
|
|
char m_aUrl[256];
|
2020-09-04 17:56:30 +00:00
|
|
|
|
|
|
|
CTimeout m_Timeout;
|
2018-07-11 18:17:21 +00:00
|
|
|
|
|
|
|
double m_Size;
|
|
|
|
double m_Current;
|
|
|
|
int m_Progress;
|
2020-09-22 13:10:35 +00:00
|
|
|
bool m_LogProgress;
|
2018-07-11 18:17:21 +00:00
|
|
|
|
|
|
|
std::atomic<int> m_State;
|
|
|
|
std::atomic<bool> m_Abort;
|
|
|
|
|
|
|
|
static int ProgressCallback(void *pUser, double DlTotal, double DlCurr, double UlTotal, double UlCurr);
|
|
|
|
static size_t WriteCallback(char *pData, size_t Size, size_t Number, void *pUser);
|
|
|
|
|
|
|
|
void Run();
|
2019-04-04 19:38:52 +00:00
|
|
|
int RunImpl(CURL *pHandle);
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2020-09-24 07:52:11 +00:00
|
|
|
protected:
|
|
|
|
virtual int OnCompletion(int State) { return State; }
|
|
|
|
|
2018-07-11 18:17:21 +00:00
|
|
|
public:
|
2020-09-22 13:10:35 +00:00
|
|
|
CRequest(const char *pUrl, CTimeout Timeout, bool LogProgress = true);
|
2018-07-11 18:17:21 +00:00
|
|
|
|
|
|
|
double Current() const { return m_Current; }
|
|
|
|
double Size() const { return m_Size; }
|
|
|
|
int Progress() const { return m_Progress; }
|
|
|
|
int State() const { return m_State; }
|
|
|
|
void Abort() { m_Abort = true; }
|
|
|
|
};
|
|
|
|
|
|
|
|
class CGet : public CRequest
|
|
|
|
{
|
|
|
|
virtual size_t OnData(char *pData, size_t DataSize);
|
|
|
|
|
|
|
|
size_t m_BufferSize;
|
|
|
|
size_t m_BufferLength;
|
|
|
|
unsigned char *m_pBuffer;
|
|
|
|
|
|
|
|
public:
|
2020-09-04 17:56:30 +00:00
|
|
|
CGet(const char *pUrl, CTimeout Timeout);
|
2018-07-11 18:17:21 +00:00
|
|
|
~CGet();
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
size_t ResultSize() const
|
|
|
|
{
|
|
|
|
if(!Result())
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return m_BufferSize;
|
|
|
|
}
|
|
|
|
}
|
2018-07-11 18:17:21 +00:00
|
|
|
unsigned char *Result() const;
|
|
|
|
unsigned char *TakeResult();
|
|
|
|
json_value *ResultJson() const;
|
|
|
|
};
|
|
|
|
|
|
|
|
class CGetFile : public CRequest
|
|
|
|
{
|
|
|
|
virtual size_t OnData(char *pData, size_t DataSize);
|
2019-04-04 19:38:52 +00:00
|
|
|
virtual bool BeforeInit();
|
2018-07-11 18:17:21 +00:00
|
|
|
|
|
|
|
IStorage *m_pStorage;
|
|
|
|
|
2020-09-21 22:51:10 +00:00
|
|
|
char m_aDestFull[MAX_PATH_LENGTH];
|
2018-07-11 18:17:21 +00:00
|
|
|
IOHANDLE m_File;
|
|
|
|
|
2020-09-24 07:52:11 +00:00
|
|
|
protected:
|
2020-12-12 11:37:43 +00:00
|
|
|
char m_aDest[MAX_PATH_LENGTH];
|
|
|
|
int m_StorageType;
|
|
|
|
|
2020-09-24 07:52:11 +00:00
|
|
|
virtual int OnCompletion(int State);
|
|
|
|
|
2018-07-11 18:17:21 +00:00
|
|
|
public:
|
2020-09-22 13:10:35 +00:00
|
|
|
CGetFile(IStorage *pStorage, const char *pUrl, const char *pDest, int StorageType = -2, CTimeout Timeout = CTimeout{4000, 500, 5}, bool LogProgress = true);
|
2018-07-11 18:17:21 +00:00
|
|
|
|
|
|
|
const char *Dest() const { return m_aDest; }
|
|
|
|
};
|
|
|
|
|
|
|
|
class CPostJson : public CRequest
|
|
|
|
{
|
|
|
|
virtual size_t OnData(char *pData, size_t DataSize) { return DataSize; }
|
2019-04-04 19:38:52 +00:00
|
|
|
virtual bool AfterInit(void *pCurl);
|
2018-07-11 18:17:21 +00:00
|
|
|
|
|
|
|
char m_aJson[1024];
|
|
|
|
|
|
|
|
public:
|
2020-09-04 17:56:30 +00:00
|
|
|
CPostJson(const char *pUrl, CTimeout Timeout, const char *pJson);
|
2018-07-11 18:17:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
bool HttpInit(IStorage *pStorage);
|
|
|
|
void EscapeUrl(char *pBuf, int Size, const char *pStr);
|
2018-12-12 08:59:42 +00:00
|
|
|
#endif // ENGINE_CLIENT_HTTP_H
|