2020-09-21 17:17:34 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
2020-05-26 16:34:33 +00:00
|
|
|
//
|
2020-09-21 17:17:34 +00:00
|
|
|
// EmulationStation Desktop Edition
|
2020-06-21 12:25:28 +00:00
|
|
|
// HttpReq.h
|
2020-05-26 16:34:33 +00:00
|
|
|
//
|
2020-06-21 12:25:28 +00:00
|
|
|
// HTTP request functions.
|
|
|
|
// Used by Scraper, GamesDBJSONScraper, GamesDBJSONScraperResources and
|
|
|
|
// ScreenScraper to download game information and media files.
|
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>
|
|
|
|
#include <map>
|
2017-11-01 22:21:10 +00:00
|
|
|
#include <sstream>
|
2013-09-15 17:56:47 +00:00
|
|
|
|
2020-05-26 16:34:33 +00:00
|
|
|
// Usage:
|
|
|
|
// HttpReq myRequest("www.duckduckgo.com", "/index.html");
|
|
|
|
//
|
|
|
|
// For blocking behavior:
|
|
|
|
// while (myRequest.status() == HttpReq::REQ_IN_PROGRESS);
|
|
|
|
//
|
|
|
|
// For non-blocking behavior:
|
2020-07-13 18:58:25 +00:00
|
|
|
// Check 'if (myRequest.status() != HttpReq::REQ_IN_PROGRESS)' in some sort of update method.
|
2020-05-26 16:34:33 +00:00
|
|
|
//
|
|
|
|
// Once one of those calls complete, the request is ready.
|
|
|
|
//
|
|
|
|
// Do something like this to capture errors:
|
2020-07-13 18:58:25 +00:00
|
|
|
// if (myRequest.status() != REQ_SUCCESS) {
|
2020-05-26 16:34:33 +00:00
|
|
|
// // An error occured.
|
|
|
|
// LOG(LogError) << "HTTP request error - " << myRequest.getErrorMessage();
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// This is how to read the returned content:
|
|
|
|
// std::string content = myRequest.getContent();
|
2013-09-15 17:56:47 +00:00
|
|
|
|
|
|
|
class HttpReq
|
|
|
|
{
|
|
|
|
public:
|
2020-06-21 12:25:28 +00:00
|
|
|
HttpReq(const std::string& url);
|
|
|
|
~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.
|
|
|
|
REQ_SUCCESS, // Request completed successfully, get it with getContent().
|
|
|
|
REQ_IO_ERROR, // Some error happened, get it with getErrorMsg().
|
|
|
|
REQ_FAILED_VERIFICATION, // Peer's certificate or fingerprint wasn't verified correctly.
|
|
|
|
REQ_BAD_STATUS_CODE, // Some invalid HTTP response status code happened (non-200).
|
|
|
|
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
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
Status status(); // Process any received data and return the status afterwards.
|
2021-07-07 18:31:46 +00:00
|
|
|
std::string getErrorMsg() { return mErrorMsg; }
|
2020-06-21 12:25:28 +00:00
|
|
|
std::string getContent() const; // mStatus must be REQ_SUCCESS.
|
2013-09-15 17:56:47 +00:00
|
|
|
|
2021-07-07 18:31:46 +00:00
|
|
|
static std::string urlEncode(const std::string& s);
|
2020-06-21 12:25:28 +00:00
|
|
|
static bool isUrl(const std::string& s);
|
2013-09-24 07:02:14 +00:00
|
|
|
|
2020-10-18 09:01:56 +00:00
|
|
|
static void cleanupCurlMulti()
|
|
|
|
{
|
|
|
|
if (s_multi_handle != nullptr) {
|
|
|
|
curl_multi_cleanup(s_multi_handle);
|
|
|
|
s_multi_handle = nullptr;
|
|
|
|
}
|
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:
|
2020-06-21 12:25:28 +00:00
|
|
|
static size_t write_content(void* buff, size_t size, size_t nmemb, void* req_ptr);
|
2021-07-07 18:31:46 +00:00
|
|
|
void onError(const std::string& msg) { mErrorMsg = msg; }
|
2013-09-15 17:56:47 +00:00
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
// God dammit libcurl why can't you have some way to check the status of an
|
|
|
|
// individual handle why do I have to handle ALL messages at once.
|
|
|
|
static std::map<CURL*, HttpReq*> s_requests;
|
2013-09-15 17:56:47 +00:00
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
static CURLM* s_multi_handle;
|
2013-09-15 17:56:47 +00:00
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
Status mStatus;
|
2021-09-18 07:53:26 +00:00
|
|
|
CURL* mHandle;
|
2013-10-10 18:11:01 +00:00
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
std::stringstream mContent;
|
|
|
|
std::string mErrorMsg;
|
2013-09-15 17:56:47 +00:00
|
|
|
};
|
2017-10-31 17:12:50 +00:00
|
|
|
|
|
|
|
#endif // ES_CORE_HTTP_REQ_H
|