HTTPDownloader: Drop Common namespace

Annoying to type...
This commit is contained in:
Stenzek 2023-11-06 23:23:44 +10:00 committed by refractionpcsx2
parent e9a4d9702c
commit c557ea1b6f
8 changed files with 155 additions and 171 deletions

View File

@ -21,8 +21,6 @@
#include "common/StringUtil.h"
#include "common/Timer.h"
using namespace Common;
static constexpr float DEFAULT_TIMEOUT_IN_SECONDS = 30;
static constexpr u32 DEFAULT_MAX_ACTIVE_REQUESTS = 4;
@ -55,7 +53,7 @@ void HTTPDownloader::CreateRequest(std::string url, Request::Callback callback)
req->type = Request::Type::Get;
req->url = std::move(url);
req->callback = std::move(callback);
req->start_time = Timer::GetCurrentValue();
req->start_time = Common::Timer::GetCurrentValue();
std::unique_lock<std::mutex> lock(m_pending_http_request_lock);
if (LockedGetActiveRequestCount() < m_max_active_requests)
@ -75,7 +73,7 @@ void HTTPDownloader::CreatePostRequest(std::string url, std::string post_data, R
req->url = std::move(url);
req->post_data = std::move(post_data);
req->callback = std::move(callback);
req->start_time = Timer::GetCurrentValue();
req->start_time = Common::Timer::GetCurrentValue();
std::unique_lock<std::mutex> lock(m_pending_http_request_lock);
if (LockedGetActiveRequestCount() < m_max_active_requests)
@ -94,7 +92,7 @@ void HTTPDownloader::LockedPollRequests(std::unique_lock<std::mutex>& lock)
InternalPollRequests();
const Common::Timer::Value current_time = Timer::GetCurrentValue();
const Common::Timer::Value current_time = Common::Timer::GetCurrentValue();
u32 active_requests = 0;
u32 unstarted_requests = 0;

View File

@ -23,87 +23,83 @@
#include <string_view>
#include <vector>
namespace Common
class HTTPDownloader
{
class HTTPDownloader
public:
enum : s32
{
public:
enum : s32
{
HTTP_STATUS_CANCELLED = -3,
HTTP_STATUS_TIMEOUT = -2,
HTTP_STATUS_ERROR = -1,
HTTP_STATUS_OK = 200
};
struct Request
{
using Data = std::vector<u8>;
using Callback = std::function<void(s32 status_code, const std::string& content_type, Data data)>;
enum class Type
{
Get,
Post,
};
enum class State
{
Pending,
Cancelled,
Started,
Receiving,
Complete,
};
HTTPDownloader* parent;
Callback callback;
std::string url;
std::string post_data;
std::string content_type;
Data data;
u64 start_time;
s32 status_code = 0;
u32 content_length = 0;
Type type = Type::Get;
std::atomic<State> state{State::Pending};
};
HTTPDownloader();
virtual ~HTTPDownloader();
static std::unique_ptr<HTTPDownloader> Create(const char* user_agent = DEFAULT_USER_AGENT);
static std::string URLEncode(const std::string_view& str);
static std::string URLDecode(const std::string_view& str);
static std::string GetExtensionForContentType(const std::string& content_type);
void SetTimeout(float timeout);
void SetMaxActiveRequests(u32 max_active_requests);
void CreateRequest(std::string url, Request::Callback callback);
void CreatePostRequest(std::string url, std::string post_data, Request::Callback callback);
void PollRequests();
void WaitForAllRequests();
bool HasAnyRequests();
static const char DEFAULT_USER_AGENT[];
protected:
virtual Request* InternalCreateRequest() = 0;
virtual void InternalPollRequests() = 0;
virtual bool StartRequest(Request* request) = 0;
virtual void CloseRequest(Request* request) = 0;
void LockedAddRequest(Request* request);
u32 LockedGetActiveRequestCount();
void LockedPollRequests(std::unique_lock<std::mutex>& lock);
float m_timeout;
u32 m_max_active_requests;
std::mutex m_pending_http_request_lock;
std::vector<Request*> m_pending_http_requests;
HTTP_STATUS_CANCELLED = -3,
HTTP_STATUS_TIMEOUT = -2,
HTTP_STATUS_ERROR = -1,
HTTP_STATUS_OK = 200
};
} // namespace Common
struct Request
{
using Data = std::vector<u8>;
using Callback = std::function<void(s32 status_code, const std::string& content_type, Data data)>;
enum class Type
{
Get,
Post,
};
enum class State
{
Pending,
Cancelled,
Started,
Receiving,
Complete,
};
HTTPDownloader* parent;
Callback callback;
std::string url;
std::string post_data;
std::string content_type;
Data data;
u64 start_time;
s32 status_code = 0;
u32 content_length = 0;
Type type = Type::Get;
std::atomic<State> state{State::Pending};
};
HTTPDownloader();
virtual ~HTTPDownloader();
static std::unique_ptr<HTTPDownloader> Create(const char* user_agent = DEFAULT_USER_AGENT);
static std::string URLEncode(const std::string_view& str);
static std::string URLDecode(const std::string_view& str);
static std::string GetExtensionForContentType(const std::string& content_type);
void SetTimeout(float timeout);
void SetMaxActiveRequests(u32 max_active_requests);
void CreateRequest(std::string url, Request::Callback callback);
void CreatePostRequest(std::string url, std::string post_data, Request::Callback callback);
void PollRequests();
void WaitForAllRequests();
bool HasAnyRequests();
static const char DEFAULT_USER_AGENT[];
protected:
virtual Request* InternalCreateRequest() = 0;
virtual void InternalPollRequests() = 0;
virtual bool StartRequest(Request* request) = 0;
virtual void CloseRequest(Request* request) = 0;
void LockedAddRequest(Request* request);
u32 LockedGetActiveRequestCount();
void LockedPollRequests(std::unique_lock<std::mutex>& lock);
float m_timeout;
u32 m_max_active_requests;
std::mutex m_pending_http_request_lock;
std::vector<Request*> m_pending_http_requests;
};

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -26,8 +26,6 @@
#include <pthread.h>
#include <signal.h>
using namespace Common;
HTTPDownloaderCurl::HTTPDownloaderCurl()
: HTTPDownloader()
{

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -21,34 +21,31 @@
#include <mutex>
#include <curl/curl.h>
namespace Common
class HTTPDownloaderCurl final : public HTTPDownloader
{
class HTTPDownloaderCurl final : public HTTPDownloader
public:
HTTPDownloaderCurl();
~HTTPDownloaderCurl() override;
bool Initialize(const char* user_agent);
protected:
Request* InternalCreateRequest() override;
void InternalPollRequests() override;
bool StartRequest(HTTPDownloader::Request* request) override;
void CloseRequest(HTTPDownloader::Request* request) override;
private:
struct Request : HTTPDownloader::Request
{
public:
HTTPDownloaderCurl();
~HTTPDownloaderCurl() override;
bool Initialize(const char* user_agent);
protected:
Request* InternalCreateRequest() override;
void InternalPollRequests() override;
bool StartRequest(HTTPDownloader::Request* request) override;
void CloseRequest(HTTPDownloader::Request* request) override;
private:
struct Request : HTTPDownloader::Request
{
CURL* handle = nullptr;
std::atomic_bool closed{false};
};
static size_t WriteCallback(char* ptr, size_t size, size_t nmemb, void* userdata);
void ProcessRequest(Request* req);
std::string m_user_agent;
std::unique_ptr<cb::ThreadPool> m_thread_pool;
std::mutex m_cancel_mutex;
CURL* handle = nullptr;
std::atomic_bool closed{false};
};
} // namespace Common
static size_t WriteCallback(char* ptr, size_t size, size_t nmemb, void* userdata);
void ProcessRequest(Request* req);
std::string m_user_agent;
std::unique_ptr<cb::ThreadPool> m_thread_pool;
std::mutex m_cancel_mutex;
};

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -25,8 +25,6 @@
#pragma comment(lib, "winhttp.lib")
using namespace Common;
HTTPDownloaderWinHttp::HTTPDownloaderWinHttp()
: HTTPDownloader()
{

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -20,34 +20,31 @@
#include <winhttp.h>
namespace Common
class HTTPDownloaderWinHttp final : public HTTPDownloader
{
class HTTPDownloaderWinHttp final : public HTTPDownloader
public:
HTTPDownloaderWinHttp();
~HTTPDownloaderWinHttp() override;
bool Initialize(const char* user_agent);
protected:
Request* InternalCreateRequest() override;
void InternalPollRequests() override;
bool StartRequest(HTTPDownloader::Request* request) override;
void CloseRequest(HTTPDownloader::Request* request) override;
private:
struct Request : HTTPDownloader::Request
{
public:
HTTPDownloaderWinHttp();
~HTTPDownloaderWinHttp() override;
bool Initialize(const char* user_agent);
protected:
Request* InternalCreateRequest() override;
void InternalPollRequests() override;
bool StartRequest(HTTPDownloader::Request* request) override;
void CloseRequest(HTTPDownloader::Request* request) override;
private:
struct Request : HTTPDownloader::Request
{
std::wstring object_name;
HINTERNET hConnection = NULL;
HINTERNET hRequest = NULL;
u32 io_position = 0;
};
static void CALLBACK HTTPStatusCallback(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus,
LPVOID lpvStatusInformation, DWORD dwStatusInformationLength);
HINTERNET m_hSession = NULL;
std::wstring object_name;
HINTERNET hConnection = NULL;
HINTERNET hRequest = NULL;
u32 io_position = 0;
};
} // namespace Common
static void CALLBACK HTTPStatusCallback(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus,
LPVOID lpvStatusInformation, DWORD dwStatusInformationLength);
HINTERNET m_hSession = NULL;
};

View File

@ -143,8 +143,8 @@ namespace Achievements
static void UpdateGameSummary();
static void DownloadImage(std::string url, std::string cache_filename);
static bool CreateClient(rc_client_t** client, std::unique_ptr<Common::HTTPDownloader>* http);
static void DestroyClient(rc_client_t** client, std::unique_ptr<Common::HTTPDownloader>* http);
static bool CreateClient(rc_client_t** client, std::unique_ptr<HTTPDownloader>* http);
static void DestroyClient(rc_client_t** client, std::unique_ptr<HTTPDownloader>* http);
static void ClientMessageCallback(const char* message, const rc_client_t* client);
static uint32_t ClientReadMemory(uint32_t address, uint8_t* buffer, uint32_t num_bytes, rc_client_t* client);
static void ClientServerCall(
@ -203,7 +203,7 @@ namespace Achievements
static std::recursive_mutex s_achievements_mutex;
static rc_client_t* s_client;
static std::string s_image_directory;
static std::unique_ptr<Common::HTTPDownloader> s_http_downloader;
static std::unique_ptr<HTTPDownloader> s_http_downloader;
static u32 s_game_disc_crc;
static std::string s_game_hash;
@ -352,8 +352,8 @@ std::string Achievements::GetGameHash()
void Achievements::DownloadImage(std::string url, std::string cache_filename)
{
auto callback = [cache_filename](s32 status_code, std::string content_type, Common::HTTPDownloader::Request::Data data) {
if (status_code != Common::HTTPDownloader::HTTP_STATUS_OK)
auto callback = [cache_filename](s32 status_code, std::string content_type, HTTPDownloader::Request::Data data) {
if (status_code != HTTPDownloader::HTTP_STATUS_OK)
return;
if (!FileSystem::WriteBinaryFile(cache_filename.c_str(), data.data(), data.size()))
@ -472,9 +472,9 @@ bool Achievements::Initialize()
return true;
}
bool Achievements::CreateClient(rc_client_t** client, std::unique_ptr<Common::HTTPDownloader>* http)
bool Achievements::CreateClient(rc_client_t** client, std::unique_ptr<HTTPDownloader>* http)
{
*http = Common::HTTPDownloader::Create(GetUserAgent().c_str());
*http = HTTPDownloader::Create(GetUserAgent().c_str());
if (!*http)
{
Host::ReportErrorAsync("Achievements Error", "Failed to create HTTPDownloader, cannot use achievements");
@ -501,7 +501,7 @@ bool Achievements::CreateClient(rc_client_t** client, std::unique_ptr<Common::HT
return true;
}
void Achievements::DestroyClient(rc_client_t** client, std::unique_ptr<Common::HTTPDownloader>* http)
void Achievements::DestroyClient(rc_client_t** client, std::unique_ptr<HTTPDownloader>* http)
{
(*http)->WaitForAllRequests();
@ -649,10 +649,10 @@ uint32_t Achievements::ClientReadMemory(uint32_t address, uint8_t* buffer, uint3
void Achievements::ClientServerCall(
const rc_api_request_t* request, rc_client_server_callback_t callback, void* callback_data, rc_client_t* client)
{
Common::HTTPDownloader::Request::Callback hd_callback = [callback, callback_data](s32 status_code, std::string content_type,
Common::HTTPDownloader::Request::Data data) {
HTTPDownloader::Request::Callback hd_callback = [callback, callback_data](s32 status_code, std::string content_type,
HTTPDownloader::Request::Data data) {
rc_api_server_response_t rr;
rr.http_status_code = (status_code <= 0) ? (status_code == Common::HTTPDownloader::HTTP_STATUS_CANCELLED ?
rr.http_status_code = (status_code <= 0) ? (status_code == HTTPDownloader::HTTP_STATUS_CANCELLED ?
RC_API_SERVER_RESPONSE_CLIENT_ERROR :
RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR) :
status_code;
@ -662,7 +662,7 @@ void Achievements::ClientServerCall(
callback(&rr, callback_data);
};
Common::HTTPDownloader* http = static_cast<Common::HTTPDownloader*>(rc_client_get_userdata(client));
HTTPDownloader* http = static_cast<HTTPDownloader*>(rc_client_get_userdata(client));
// TODO: Content-type for post
if (request->post_data)
@ -1645,9 +1645,9 @@ bool Achievements::Login(const char* username, const char* password, Error* erro
// We need to use a temporary client if achievements aren't currently active.
rc_client_t* client = s_client;
Common::HTTPDownloader* http = s_http_downloader.get();
HTTPDownloader* http = s_http_downloader.get();
const bool is_temporary_client = (client == nullptr);
std::unique_ptr<Common::HTTPDownloader> temporary_downloader;
std::unique_ptr<HTTPDownloader> temporary_downloader;
ScopedGuard temporary_client_guard = [&client, is_temporary_client, &temporary_downloader]() {
if (is_temporary_client)
DestroyClient(&client, &temporary_downloader);

View File

@ -1267,14 +1267,14 @@ bool GameList::DownloadCovers(const std::vector<std::string>& url_templates, boo
{
std::string url(url_template);
if (has_title)
StringUtil::ReplaceAll(&url, "${title}", Common::HTTPDownloader::URLEncode(entry.title));
StringUtil::ReplaceAll(&url, "${title}", HTTPDownloader::URLEncode(entry.title));
if (has_file_title)
{
std::string display_name(FileSystem::GetDisplayNameFromPath(entry.path));
StringUtil::ReplaceAll(&url, "${filetitle}", Common::HTTPDownloader::URLEncode(Path::GetFileTitle(display_name)));
StringUtil::ReplaceAll(&url, "${filetitle}", HTTPDownloader::URLEncode(Path::GetFileTitle(display_name)));
}
if (has_serial)
StringUtil::ReplaceAll(&url, "${serial}", Common::HTTPDownloader::URLEncode(entry.serial));
StringUtil::ReplaceAll(&url, "${serial}", HTTPDownloader::URLEncode(entry.serial));
download_urls.emplace_back(entry.path, std::move(url));
}
@ -1286,7 +1286,7 @@ bool GameList::DownloadCovers(const std::vector<std::string>& url_templates, boo
return false;
}
std::unique_ptr<Common::HTTPDownloader> downloader(Common::HTTPDownloader::Create());
std::unique_ptr<HTTPDownloader> downloader(HTTPDownloader::Create());
if (!downloader)
{
progress->DisplayError("Failed to create HTTP downloader.");
@ -1315,11 +1315,11 @@ bool GameList::DownloadCovers(const std::vector<std::string>& url_templates, boo
}
// we could actually do a few in parallel here...
std::string filename(Common::HTTPDownloader::URLDecode(url));
std::string filename(HTTPDownloader::URLDecode(url));
downloader->CreateRequest(
std::move(url), [use_serial, &save_callback, entry_path = std::move(entry_path), filename = std::move(filename)](
s32 status_code, const std::string& content_type, Common::HTTPDownloader::Request::Data data) {
if (status_code != Common::HTTPDownloader::HTTP_STATUS_OK || data.empty())
s32 status_code, const std::string& content_type, HTTPDownloader::Request::Data data) {
if (status_code != HTTPDownloader::HTTP_STATUS_OK || data.empty())
return;
std::unique_lock lock(s_mutex);
@ -1330,7 +1330,7 @@ bool GameList::DownloadCovers(const std::vector<std::string>& url_templates, boo
// prefer the content type from the response for the extension
// otherwise, if it's missing, and the request didn't have an extension.. fall back to jpegs.
std::string template_filename;
std::string content_type_extension(Common::HTTPDownloader::GetExtensionForContentType(content_type));
std::string content_type_extension(HTTPDownloader::GetExtensionForContentType(content_type));
// don't treat the domain name as an extension..
const std::string::size_type last_slash = filename.find('/');