DDNet documentation
Loading...
Searching...
No Matches
http.h
Go to the documentation of this file.
1#ifndef ENGINE_HTTP_H
2#define ENGINE_HTTP_H
3
4#include "kernel.h"
5
6#include <base/hash_ctxt.h>
7#include <base/types.h>
8
9#include <atomic>
10#include <chrono>
11#include <condition_variable>
12#include <cstdint>
13#include <memory>
14#include <mutex>
15#include <optional>
16
17typedef struct _json_value json_value;
18class IStorage;
19
28
29enum class HTTPLOG
30{
34};
35
36enum class IPRESOLVE
37{
41};
42
44{
45public:
50};
51
53{
54 friend class IHttp;
55
56public:
57 IHttpRequest(const char *pUrl);
58 virtual ~IHttpRequest();
59
61 // Skip the download if the local file is newer or as new as the remote file.
67 // Download to memory only. Get the result via `Result*`.
68 void WriteToMemory();
69 // Download to filesystem and memory.
70 void WriteToFileAndMemory(IStorage *pStorage, const char *pDest, int StorageType);
71 // Download to the filesystem only.
72 void WriteToFile(IStorage *pStorage, const char *pDest, int StorageType);
73 // Don't place the file in the specified location until
74 // `OnValidation(true)` has been called.
76 void ExpectSha256(const SHA256_DIGEST &Sha256) { m_ExpectedSha256 = Sha256; }
77
78 void Head();
79 void Post(const unsigned char *pData, size_t DataLength);
80 void PostJson(const char *pJson);
81
82 virtual void Header(const char *pNameColonValue) = 0;
83 void HeaderString(const char *pName, const char *pValue);
84 void HeaderInt(const char *pName, int Value);
85
86 const char *Dest() const;
87 double Current() const { return m_Current.load(std::memory_order_relaxed); }
88 double Size() const { return m_Size.load(std::memory_order_relaxed); }
89 int Progress() const { return m_Progress.load(std::memory_order_relaxed); }
90 EHttpState State() const { return m_State; }
91 bool Done() const
92 {
93 EHttpState CurrentState = State();
94 return CurrentState != EHttpState::QUEUED && CurrentState != EHttpState::RUNNING;
95 }
96 virtual void Abort() { m_Abort = true; }
97 bool IsAbortRequested() const { return m_Abort; }
98 void Wait();
99
107 {
108 public:
109 virtual ~IProgressCallback() = default;
110 virtual void OnProgress() = 0;
111 virtual void OnCompletion(EHttpState State) = 0;
112 };
114
115 // If `ValidateBeforeOverwrite` is set, this needs to be called after
116 // validating that the downloaded file has the correct format.
117 //
118 // If called with `true`, it'll place the downloaded file at the final
119 // destination, if called with `false`, it'll instead delete the
120 // temporary downloaded file.
121 void OnValidation(bool Success);
122
123 void Result(unsigned char **ppResult, size_t *pResultLength) const;
124 json_value *ResultJson() const;
125 const SHA256_DIGEST &ResultSha256() const;
126
127 int StatusCode() const;
128 std::optional<int64_t> ResultAgeSeconds() const;
129 std::optional<int64_t> ResultLastModified() const;
130
131protected:
132 static const char *const USER_AGENT_STRING;
133 enum class REQUEST
134 {
139 };
140 static const char *GetRequestType(REQUEST Type);
141
142 // Request
143 char m_aUrl[256] = "";
145 unsigned char *m_pBody = nullptr;
146 size_t m_BodyLength = 0;
147
148 // Settings
150 int64_t m_MaxResponseSize = -1;
152 bool m_SkipByFileTime = true;
156 std::optional<SHA256_DIGEST> m_ExpectedSha256 = std::nullopt;
157 int64_t m_IfModifiedSince = -1;
158
159 // Result
160 std::optional<SHA256_DIGEST> m_ActualSha256 = std::nullopt;
162 uint64_t m_ResponseLength = 0;
164 std::optional<int64_t> m_ResultDate = std::nullopt;
165 std::optional<int64_t> m_ResultLastModified = std::nullopt;
166
167 bool m_WriteToMemory = true;
168 bool m_WriteToFile = false;
169
170 // If `m_WriteToMemory` is true.
171 size_t m_BufferSize = 0;
172 unsigned char *m_pBuffer = nullptr;
173
174 // If `m_WriteToFile` is true.
175 IOHANDLE m_File = nullptr;
179
180 // Progress
181 std::atomic<double> m_Size = 0.0;
182 std::atomic<double> m_Current = 0.0;
183 std::atomic<int> m_Progress = 0;
184 std::atomic<EHttpState> m_State = EHttpState::QUEUED;
185 std::atomic<bool> m_Abort = false;
187
188 std::mutex m_WaitMutex;
189 std::condition_variable m_WaitCondition;
190
191 bool ShouldSkipRequest();
192 // Abort the request with an error if `BeforeInit()` returns false.
193 bool BeforeInit();
194
195 // Abort the request if `OnData()` returns something other than
196 // `DataSize`.
197 size_t OnData(const char *pData, size_t DataSize);
199};
200
201std::unique_ptr<IHttpRequest> CreateHttpRequest(const char *pUrl);
202
203inline std::unique_ptr<IHttpRequest> HttpHead(const char *pUrl)
204{
205 std::unique_ptr<IHttpRequest> pResult = CreateHttpRequest(pUrl);
206 pResult->Head();
207 return pResult;
208}
209
210inline std::unique_ptr<IHttpRequest> HttpGet(const char *pUrl)
211{
212 return CreateHttpRequest(pUrl);
213}
214
215inline std::unique_ptr<IHttpRequest> HttpGetFile(const char *pUrl, IStorage *pStorage, const char *pOutputFile, int StorageType)
216{
217 std::unique_ptr<IHttpRequest> pResult = HttpGet(pUrl);
218 pResult->WriteToFile(pStorage, pOutputFile, StorageType);
219 pResult->Timeout(CTimeout{4000, 0, 500, 5});
220 return pResult;
221}
222
223inline std::unique_ptr<IHttpRequest> HttpGetBoth(const char *pUrl, IStorage *pStorage, const char *pOutputFile, int StorageType)
224{
225 std::unique_ptr<IHttpRequest> pResult = HttpGet(pUrl);
226 pResult->WriteToFileAndMemory(pStorage, pOutputFile, StorageType);
227 pResult->Timeout(CTimeout{4000, 0, 500, 5});
228 return pResult;
229}
230
231inline std::unique_ptr<IHttpRequest> HttpPost(const char *pUrl, const unsigned char *pData, size_t DataLength)
232{
233 std::unique_ptr<IHttpRequest> pResult = CreateHttpRequest(pUrl);
234 pResult->Post(pData, DataLength);
235 pResult->Timeout(CTimeout{4000, 15000, 500, 5});
236 return pResult;
237}
238
239inline std::unique_ptr<IHttpRequest> HttpPostJson(const char *pUrl, const char *pJson)
240{
241 std::unique_ptr<IHttpRequest> pResult = CreateHttpRequest(pUrl);
242 pResult->PostJson(pJson);
243 pResult->Timeout(CTimeout{4000, 15000, 500, 5});
244 return pResult;
245}
246
247void EscapeUrl(char *pBuf, size_t Size, const char *pStr);
248
249template<size_t Size>
250void EscapeUrl(char (&aBuf)[Size], const char *pStr)
251{
252 EscapeUrl(aBuf, Size, pStr);
253}
254
255class IHttp : public IInterface
256{
258
259public:
260 virtual void Run(std::shared_ptr<IHttpRequest> pRequest) = 0;
261
262 virtual bool HasIpresolveBug() const = 0;
263};
264
265class IEngineHttp : public IHttp
266{
267 MACRO_INTERFACE("enginehttp")
268
269public:
270 virtual bool Init(std::chrono::milliseconds ShutdownDelay) = 0;
271 void Shutdown() override = 0;
272};
273
275
276#endif
Definition http.h:44
long m_TimeoutMs
Definition http.h:47
long m_ConnectTimeoutMs
Definition http.h:46
long m_LowSpeedLimit
Definition http.h:48
long m_LowSpeedTime
Definition http.h:49
Definition http.h:266
virtual bool Init(std::chrono::milliseconds ShutdownDelay)=0
void Shutdown() override=0
Definition http.h:107
virtual void OnCompletion(EHttpState State)=0
virtual ~IProgressCallback()=default
Definition http.h:53
void ValidateBeforeOverwrite(bool ValidateBeforeOverwrite)
Definition http.h:75
std::atomic< EHttpState > m_State
Definition http.h:184
int StatusCode() const
Definition http.cpp:168
std::mutex m_WaitMutex
Definition http.h:188
bool Done() const
Definition http.h:91
bool m_WriteToMemory
Definition http.h:167
void HeaderInt(const char *pName, int Value)
Definition http.cpp:92
std::atomic< double > m_Size
Definition http.h:181
double Current() const
Definition http.h:87
virtual ~IHttpRequest()
Definition http.cpp:25
int m_StatusCode
Definition http.h:163
bool m_WriteToFile
Definition http.h:168
CTimeout m_Timeout
Definition http.h:149
static const char *const USER_AGENT_STRING
Definition http.h:132
SHA256_CTX m_ActualSha256Ctx
Definition http.h:161
void WriteToFile(IStorage *pStorage, const char *pDest, int StorageType)
Definition http.cpp:42
void SkipByFileTime(bool SkipByFileTime)
Definition http.h:64
const char * Dest() const
Definition http.cpp:99
unsigned char * m_pBody
Definition http.h:145
void Result(unsigned char **ppResult, size_t *pResultLength) const
Definition http.cpp:145
std::optional< SHA256_DIGEST > m_ActualSha256
Definition http.h:160
void Post(const unsigned char *pData, size_t DataLength)
Definition http.cpp:69
uint64_t m_ResponseLength
Definition http.h:162
REQUEST m_Type
Definition http.h:144
static const char * GetRequestType(REQUEST Type)
Definition http.cpp:214
IHttpRequest(const char *pUrl)
Definition http.cpp:19
bool m_ValidateBeforeOverwrite
Definition http.h:155
void WriteToFileAndMemory(IStorage *pStorage, const char *pDest, int StorageType)
Definition http.cpp:58
bool IsAbortRequested() const
Definition http.h:97
double Size() const
Definition http.h:88
void Head()
Definition http.cpp:64
size_t m_BufferSize
Definition http.h:171
void OnValidation(bool Success)
Definition http.cpp:120
void Timeout(CTimeout Timeout)
Definition http.h:60
std::atomic< double > m_Current
Definition http.h:182
virtual void Header(const char *pNameColonValue)=0
virtual void Abort()
Definition http.h:96
bool m_FailOnErrorStatus
Definition http.h:154
bool m_SkipByFileTime
Definition http.h:152
size_t m_BodyLength
Definition http.h:146
bool ShouldSkipRequest()
Definition http.cpp:230
HTTPLOG m_LogProgress
Definition http.h:151
int64_t m_IfModifiedSince
Definition http.h:157
size_t OnData(const char *pData, size_t DataSize)
Definition http.cpp:273
char m_aUrl[256]
Definition http.h:143
void ExpectSha256(const SHA256_DIGEST &Sha256)
Definition http.h:76
void IpResolve(IPRESOLVE IpResolve)
Definition http.h:65
void SetProgressCallback(IProgressCallback *pCallback)
Definition http.h:113
std::condition_variable m_WaitCondition
Definition http.h:189
IOHANDLE m_File
Definition http.h:175
REQUEST
Definition http.h:134
@ POST_JSON
Definition http.h:138
@ GET
Definition http.h:135
@ POST
Definition http.h:137
@ HEAD
Definition http.h:136
std::optional< int64_t > m_ResultLastModified
Definition http.h:165
char m_aDest[IO_MAX_PATH_LENGTH]
Definition http.h:178
void OnCompletionInternal(EHttpState State)
Definition http.cpp:313
void FailOnErrorStatus(bool FailOnErrorStatus)
Definition http.h:66
IPRESOLVE m_IpResolve
Definition http.h:153
void MaxResponseSize(int64_t MaxResponseSize)
Definition http.h:62
bool BeforeInit()
Definition http.cpp:244
void LogProgress(HTTPLOG LogProgress)
Definition http.h:63
void HeaderString(const char *pName, const char *pValue)
Definition http.cpp:85
IProgressCallback * m_pProgressCallback
Definition http.h:186
std::optional< SHA256_DIGEST > m_ExpectedSha256
Definition http.h:156
void Wait()
Definition http.cpp:111
EHttpState State() const
Definition http.h:90
char m_aDestAbsolute[IO_MAX_PATH_LENGTH]
Definition http.h:177
std::optional< int64_t > ResultLastModified() const
Definition http.cpp:184
int64_t m_MaxResponseSize
Definition http.h:150
const SHA256_DIGEST & ResultSha256() const
Definition http.cpp:161
unsigned char * m_pBuffer
Definition http.h:172
friend class IHttp
Definition http.h:54
std::optional< int64_t > m_ResultDate
Definition http.h:164
json_value * ResultJson() const
Definition http.cpp:153
void WriteToMemory()
Definition http.cpp:36
int Progress() const
Definition http.h:89
void PostJson(const char *pJson)
Definition http.cpp:77
std::atomic< bool > m_Abort
Definition http.h:185
std::atomic< int > m_Progress
Definition http.h:183
char m_aDestAbsoluteTmp[IO_MAX_PATH_LENGTH]
Definition http.h:176
std::optional< int64_t > ResultAgeSeconds() const
Definition http.cpp:174
Definition http.h:256
virtual bool HasIpresolveBug() const =0
virtual void Run(std::shared_ptr< IHttpRequest > pRequest)=0
IInterface()
Definition kernel.h:19
Definition storage.h:21
struct _json_value json_value
Definition serverbrowser.h:18
constexpr auto IO_MAX_PATH_LENGTH
Definition types.h:26
void EscapeUrl(char *pBuf, size_t Size, const char *pStr)
Definition http_curl.cpp:284
std::unique_ptr< IHttpRequest > HttpGetBoth(const char *pUrl, IStorage *pStorage, const char *pOutputFile, int StorageType)
Definition http.h:223
IPRESOLVE
Definition http.h:37
@ WHATEVER
Definition http.h:38
@ V4
Definition http.h:39
@ V6
Definition http.h:40
IEngineHttp * CreateEngineHttp()
Definition http_curl.cpp:550
std::unique_ptr< IHttpRequest > HttpHead(const char *pUrl)
Definition http.h:203
std::unique_ptr< IHttpRequest > HttpPost(const char *pUrl, const unsigned char *pData, size_t DataLength)
Definition http.h:231
std::unique_ptr< IHttpRequest > HttpGet(const char *pUrl)
Definition http.h:210
std::unique_ptr< IHttpRequest > HttpPostJson(const char *pUrl, const char *pJson)
Definition http.h:239
std::unique_ptr< IHttpRequest > HttpGetFile(const char *pUrl, IStorage *pStorage, const char *pOutputFile, int StorageType)
Definition http.h:215
EHttpState
Definition http.h:21
@ DONE
Definition http.h:25
@ RUNNING
Definition http.h:24
@ ABORTED
Definition http.h:26
@ QUEUED
Definition http.h:23
@ ERROR
Definition http.h:22
std::unique_ptr< IHttpRequest > CreateHttpRequest(const char *pUrl)
Definition http_curl.cpp:279
HTTPLOG
Definition http.h:30
@ FAILURE
Definition http.h:32
@ ALL
Definition http.h:33
@ NONE
Definition http.h:31
#define MACRO_INTERFACE(Name)
Definition kernel.h:25
void * IOHANDLE
Definition logger.h:12
Definition hash.h:12