2021-12-24 11:17:46 +00:00
|
|
|
#ifndef ENGINE_SHARED_HTTP_H
|
|
|
|
#define ENGINE_SHARED_HTTP_H
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2021-10-28 11:50:01 +00:00
|
|
|
#include <atomic>
|
2018-07-11 18:17:21 +00:00
|
|
|
#include <engine/shared/jobs.h>
|
|
|
|
|
|
|
|
typedef struct _json_value json_value;
|
2022-05-05 12:49:25 +00:00
|
|
|
class IStorage;
|
2018-07-11 18:17:21 +00:00
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
HTTP_ERROR = -1,
|
|
|
|
HTTP_QUEUED,
|
|
|
|
HTTP_RUNNING,
|
|
|
|
HTTP_DONE,
|
|
|
|
HTTP_ABORTED,
|
|
|
|
};
|
|
|
|
|
2021-06-14 22:12:06 +00:00
|
|
|
enum class HTTPLOG
|
|
|
|
{
|
|
|
|
NONE,
|
|
|
|
FAILURE,
|
|
|
|
ALL,
|
|
|
|
};
|
|
|
|
|
2022-03-07 14:01:37 +00:00
|
|
|
enum class IPRESOLVE
|
|
|
|
{
|
|
|
|
WHATEVER,
|
|
|
|
V4,
|
|
|
|
V6,
|
|
|
|
};
|
|
|
|
|
2020-09-04 17:56:30 +00:00
|
|
|
struct CTimeout
|
|
|
|
{
|
|
|
|
long ConnectTimeoutMs;
|
|
|
|
long LowSpeedLimit;
|
|
|
|
long LowSpeedTime;
|
|
|
|
};
|
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
class CHttpRequest : public IJob
|
2018-07-11 18:17:21 +00:00
|
|
|
{
|
2022-05-05 12:49:25 +00:00
|
|
|
enum class REQUEST
|
|
|
|
{
|
|
|
|
GET = 0,
|
|
|
|
HEAD,
|
|
|
|
POST_JSON,
|
|
|
|
};
|
|
|
|
char m_aUrl[256] = {0};
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
void *m_pHeaders = nullptr;
|
|
|
|
unsigned char *m_pBody = nullptr;
|
|
|
|
size_t m_BodyLength = 0;
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
CTimeout m_Timeout = CTimeout{0, 0, 0};
|
|
|
|
REQUEST m_Type = REQUEST::GET;
|
2020-09-04 17:56:30 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
bool m_WriteToFile = false;
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
// If `m_WriteToFile` is false.
|
|
|
|
size_t m_BufferSize = 0;
|
|
|
|
size_t m_BufferLength = 0;
|
|
|
|
unsigned char *m_pBuffer = nullptr;
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
// If `m_WriteToFile` is true.
|
|
|
|
IOHANDLE m_File = nullptr;
|
|
|
|
char m_aDestAbsolute[IO_MAX_PATH_LENGTH] = {0};
|
|
|
|
char m_aDest[IO_MAX_PATH_LENGTH] = {0};
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
std::atomic<double> m_Size{0.0};
|
|
|
|
std::atomic<double> m_Current{0.0};
|
|
|
|
std::atomic<int> m_Progress{0};
|
|
|
|
HTTPLOG m_LogProgress = HTTPLOG::ALL;
|
|
|
|
IPRESOLVE m_IpResolve = IPRESOLVE::WHATEVER;
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
std::atomic<int> m_State{HTTP_QUEUED};
|
|
|
|
std::atomic<bool> m_Abort{false};
|
2020-09-24 07:52:11 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
void Run();
|
|
|
|
// Abort the request with an error if `BeforeInit()` returns false.
|
|
|
|
bool BeforeInit();
|
|
|
|
int RunImpl(void *pUser);
|
2018-07-11 20:46:04 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
// Abort the request if `OnData()` returns something other than
|
|
|
|
// `DataSize`.
|
|
|
|
size_t OnData(char *pData, size_t DataSize);
|
2018-07-11 20:46:04 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
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);
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
protected:
|
|
|
|
virtual void OnProgress() {}
|
|
|
|
virtual int OnCompletion(int State);
|
2018-07-11 18:17:21 +00:00
|
|
|
|
|
|
|
public:
|
2022-05-05 12:49:25 +00:00
|
|
|
CHttpRequest(const char *pUrl);
|
|
|
|
~CHttpRequest();
|
|
|
|
|
|
|
|
void Timeout(CTimeout Timeout) { m_Timeout = Timeout; }
|
|
|
|
void LogProgress(HTTPLOG LogProgress) { m_LogProgress = LogProgress; }
|
|
|
|
void IpResolve(IPRESOLVE IpResolve) { m_IpResolve = IpResolve; }
|
|
|
|
void WriteToFile(IStorage *pStorage, const char *pDest, int StorageType);
|
|
|
|
void Head() { m_Type = REQUEST::HEAD; }
|
|
|
|
void PostJson(const char *pJson)
|
|
|
|
{
|
|
|
|
m_Type = REQUEST::POST_JSON;
|
|
|
|
m_BodyLength = str_length(pJson);
|
|
|
|
m_pBody = (unsigned char *)malloc(m_BodyLength);
|
|
|
|
mem_copy(m_pBody, pJson, m_BodyLength);
|
|
|
|
}
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
const char *Dest()
|
2020-09-26 19:41:58 +00:00
|
|
|
{
|
2022-05-05 12:49:25 +00:00
|
|
|
if(m_WriteToFile)
|
2020-09-26 19:41:58 +00:00
|
|
|
{
|
2022-05-05 12:49:25 +00:00
|
|
|
return m_aDest;
|
2020-09-26 19:41:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-05-05 12:49:25 +00:00
|
|
|
return nullptr;
|
2020-09-26 19:41:58 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-05 12:49:25 +00:00
|
|
|
|
|
|
|
double Current() const { return m_Current.load(std::memory_order_relaxed); }
|
|
|
|
double Size() const { return m_Size.load(std::memory_order_relaxed); }
|
|
|
|
int Progress() const { return m_Progress.load(std::memory_order_relaxed); }
|
|
|
|
int State() const { return m_State; }
|
|
|
|
void Abort() { m_Abort = true; }
|
|
|
|
|
|
|
|
void Result(unsigned char **ppResult, size_t *pResultLength) const;
|
2018-07-11 18:17:21 +00:00
|
|
|
json_value *ResultJson() const;
|
|
|
|
};
|
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
inline std::unique_ptr<CHttpRequest> HttpHead(const char *pUrl)
|
2018-07-11 18:17:21 +00:00
|
|
|
{
|
2022-05-05 12:49:25 +00:00
|
|
|
std::unique_ptr<CHttpRequest> pResult = std::unique_ptr<CHttpRequest>(new CHttpRequest(pUrl));
|
|
|
|
pResult->Head();
|
|
|
|
return pResult;
|
|
|
|
}
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
inline std::unique_ptr<CHttpRequest> HttpGet(const char *pUrl)
|
2018-07-11 18:17:21 +00:00
|
|
|
{
|
2022-05-05 12:49:25 +00:00
|
|
|
return std::unique_ptr<CHttpRequest>(new CHttpRequest(pUrl));
|
|
|
|
}
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
inline std::unique_ptr<CHttpRequest> HttpGetFile(const char *pUrl, IStorage *pStorage, const char *pOutputFile, int StorageType)
|
|
|
|
{
|
|
|
|
std::unique_ptr<CHttpRequest> pResult = HttpGet(pUrl);
|
|
|
|
pResult->WriteToFile(pStorage, pOutputFile, StorageType);
|
|
|
|
pResult->Timeout(CTimeout{4000, 500, 5});
|
|
|
|
return pResult;
|
|
|
|
}
|
2018-07-11 18:17:21 +00:00
|
|
|
|
2022-05-05 12:49:25 +00:00
|
|
|
inline std::unique_ptr<CHttpRequest> HttpPostJson(const char *pUrl, const char *pJson)
|
|
|
|
{
|
|
|
|
std::unique_ptr<CHttpRequest> pResult = std::unique_ptr<CHttpRequest>(new CHttpRequest(pUrl));
|
|
|
|
pResult->PostJson(pJson);
|
|
|
|
return pResult;
|
|
|
|
}
|
2018-07-11 18:17:21 +00:00
|
|
|
|
|
|
|
bool HttpInit(IStorage *pStorage);
|
|
|
|
void EscapeUrl(char *pBuf, int Size, const char *pStr);
|
2021-12-24 11:17:46 +00:00
|
|
|
#endif // ENGINE_SHARED_HTTP_H
|