2020-09-21 17:17:34 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
2020-05-26 16:34:33 +00:00
|
|
|
//
|
2024-04-08 17:26:08 +00:00
|
|
|
// ES-DE Frontend
|
2020-06-21 12:25:28 +00:00
|
|
|
// HttpReq.h
|
2020-05-26 16:34:33 +00:00
|
|
|
//
|
2023-08-01 15:36:15 +00:00
|
|
|
// HTTP requests using libcurl.
|
|
|
|
// Used by the scraper and application updater.
|
2020-05-26 16:34:33 +00:00
|
|
|
//
|
|
|
|
|
2017-10-31 17:12:50 +00:00
|
|
|
#ifndef ES_CORE_HTTP_REQ_H
|
|
|
|
#define ES_CORE_HTTP_REQ_H
|
2013-09-15 17:56:47 +00:00
|
|
|
|
2013-10-10 18:11:01 +00:00
|
|
|
#include <curl/curl.h>
|
2023-08-01 15:36:15 +00:00
|
|
|
|
|
|
|
#include <atomic>
|
2013-10-10 18:11:01 +00:00
|
|
|
#include <map>
|
2024-04-08 17:26:08 +00:00
|
|
|
#include <mutex>
|
|
|
|
#include <queue>
|
2017-11-01 22:21:10 +00:00
|
|
|
#include <sstream>
|
2024-04-08 17:26:08 +00:00
|
|
|
#include <thread>
|
2013-09-15 17:56:47 +00:00
|
|
|
|
|
|
|
class HttpReq
|
|
|
|
{
|
|
|
|
public:
|
2023-08-01 15:36:15 +00:00
|
|
|
HttpReq(const std::string& url, bool scraperRequest);
|
2020-06-21 12:25:28 +00:00
|
|
|
~HttpReq();
|
2013-09-15 17:56:47 +00:00
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
enum Status {
|
2021-07-07 18:31:46 +00:00
|
|
|
// clang-format off
|
2021-05-24 16:51:16 +00:00
|
|
|
REQ_IN_PROGRESS, // Request is in progress.
|
2024-01-10 23:46:11 +00:00
|
|
|
REQ_SUCCESS, // Request completed successfully.
|
|
|
|
REQ_IO_ERROR, // An error occured.
|
2021-05-24 16:51:16 +00:00
|
|
|
REQ_FAILED_VERIFICATION, // Peer's certificate or fingerprint wasn't verified correctly.
|
2024-01-10 23:46:11 +00:00
|
|
|
REQ_BAD_STATUS_CODE, // HTTP error response >= 400.
|
|
|
|
REQ_RESOURCE_NOT_FOUND, // HTTP error code 404 specifically.
|
2021-05-24 16:51:16 +00:00
|
|
|
REQ_INVALID_RESPONSE, // The HTTP response was invalid.
|
|
|
|
REQ_UNDEFINED_ERROR
|
2021-07-07 18:31:46 +00:00
|
|
|
// clang-format on
|
2020-06-21 12:25:28 +00:00
|
|
|
};
|
2013-09-15 17:56:47 +00:00
|
|
|
|
2024-04-08 17:26:08 +00:00
|
|
|
Status status() { return mStatus; }
|
2023-08-01 15:36:15 +00:00
|
|
|
|
2021-07-07 18:31:46 +00:00
|
|
|
std::string getErrorMsg() { return mErrorMsg; }
|
2023-08-01 15:36:15 +00:00
|
|
|
std::string getContent() const;
|
|
|
|
long getTotalBytes() { return mTotalBytes; }
|
|
|
|
long getDownloadedBytes() { return mDownloadedBytes; }
|
2013-09-15 17:56:47 +00:00
|
|
|
|
2021-07-07 18:31:46 +00:00
|
|
|
static std::string urlEncode(const std::string& s);
|
2024-04-08 17:26:08 +00:00
|
|
|
|
|
|
|
// Called explicitly from any object that uses HttpReq.
|
2020-10-18 09:01:56 +00:00
|
|
|
static void cleanupCurlMulti()
|
|
|
|
{
|
2023-02-16 21:30:32 +00:00
|
|
|
if (sMultiHandle != nullptr) {
|
2024-04-08 17:26:08 +00:00
|
|
|
sStopPoll = true;
|
|
|
|
curl_multi_wakeup(sMultiHandle);
|
|
|
|
mPollThread->join();
|
|
|
|
mPollThread.reset();
|
2023-02-16 21:30:32 +00:00
|
|
|
curl_multi_cleanup(sMultiHandle);
|
|
|
|
sMultiHandle = nullptr;
|
2020-10-18 09:01:56 +00:00
|
|
|
}
|
2021-07-07 18:31:46 +00:00
|
|
|
}
|
2020-10-18 09:01:56 +00:00
|
|
|
|
2013-09-15 17:56:47 +00:00
|
|
|
private:
|
2023-08-01 15:36:15 +00:00
|
|
|
// Callbacks.
|
|
|
|
static int transferProgress(
|
|
|
|
void* clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
|
2023-02-16 21:30:32 +00:00
|
|
|
static size_t writeContent(void* buff, size_t size, size_t nmemb, void* req_ptr);
|
2023-08-01 15:36:15 +00:00
|
|
|
|
2021-07-07 18:31:46 +00:00
|
|
|
void onError(const std::string& msg) { mErrorMsg = msg; }
|
2013-09-15 17:56:47 +00:00
|
|
|
|
2024-04-08 17:26:08 +00:00
|
|
|
// Poll constantly to maintain network throughput even during VSyncs and other waiting states.
|
|
|
|
void pollCurl();
|
|
|
|
|
2023-02-16 21:30:32 +00:00
|
|
|
static inline CURLM* sMultiHandle;
|
2024-04-08 17:26:08 +00:00
|
|
|
static inline std::map<CURL*, HttpReq*> sRequests;
|
|
|
|
static inline std::queue<CURL*> sAddHandleQueue;
|
|
|
|
static inline std::queue<CURL*> sRemoveHandleQueue;
|
2013-09-15 17:56:47 +00:00
|
|
|
|
2024-04-08 17:26:08 +00:00
|
|
|
std::atomic<Status> mStatus;
|
2021-09-18 07:53:26 +00:00
|
|
|
CURL* mHandle;
|
2013-10-10 18:11:01 +00:00
|
|
|
|
2024-04-08 17:26:08 +00:00
|
|
|
static inline std::unique_ptr<std::thread> mPollThread;
|
|
|
|
static inline std::mutex sHandleMutex;
|
|
|
|
static inline std::mutex sRequestMutex;
|
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
std::stringstream mContent;
|
|
|
|
std::string mErrorMsg;
|
2024-04-08 17:26:08 +00:00
|
|
|
static inline std::atomic<bool> sStopPoll = false;
|
2023-08-01 15:36:15 +00:00
|
|
|
std::atomic<long> mTotalBytes;
|
|
|
|
std::atomic<long> mDownloadedBytes;
|
2024-01-10 23:46:11 +00:00
|
|
|
bool mScraperRequest;
|
2013-09-15 17:56:47 +00:00
|
|
|
};
|
2017-10-31 17:12:50 +00:00
|
|
|
|
|
|
|
#endif // ES_CORE_HTTP_REQ_H
|