mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Break out Download and RequestManager into its own file
This commit is contained in:
1 parent
64eff0dc0b
commit
f13a07f19b
11 files changed
+228
-186
No files matched your search
@@ -710,6 +710,8 @@ add_library(Common STATIC
|
||||
Common/Net/HTTPClient.h
|
||||
Common/Net/HTTPHeaders.cpp
|
||||
Common/Net/HTTPHeaders.h
|
||||
Common/Net/HTTPRequest.cpp
|
||||
Common/Net/HTTPRequest.h
|
||||
Common/Net/HTTPServer.cpp
|
||||
Common/Net/HTTPServer.h
|
||||
Common/Net/NetBuffer.cpp
|
||||
|
||||
@@ -494,6 +494,7 @@
|
||||
<ClInclude Include="Net\HTTPClient.h" />
|
||||
<ClInclude Include="Net\HTTPHeaders.h" />
|
||||
<ClInclude Include="Net\HTTPServer.h" />
|
||||
<ClInclude Include="Net\HTTPRequest.h" />
|
||||
<ClInclude Include="Net\Resolve.h" />
|
||||
<ClInclude Include="Net\Sinks.h" />
|
||||
<ClInclude Include="Net\URL.h" />
|
||||
@@ -938,6 +939,7 @@
|
||||
<ClCompile Include="Net\HTTPClient.cpp" />
|
||||
<ClCompile Include="Net\HTTPHeaders.cpp" />
|
||||
<ClCompile Include="Net\HTTPServer.cpp" />
|
||||
<ClCompile Include="Net\HTTPRequest.cpp" />
|
||||
<ClCompile Include="Net\Resolve.cpp" />
|
||||
<ClCompile Include="Net\Sinks.cpp" />
|
||||
<ClCompile Include="Net\URL.cpp" />
|
||||
|
||||
@@ -512,6 +512,9 @@
|
||||
<ClInclude Include="System\OSD.h">
|
||||
<Filter>System</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Net\HTTPRequest.h">
|
||||
<Filter>Net</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ABI.cpp" />
|
||||
@@ -959,6 +962,9 @@
|
||||
<ClCompile Include="System\OSD.cpp">
|
||||
<Filter>System</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Net\HTTPRequest.cpp">
|
||||
<Filter>Net</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Crypto">
|
||||
@@ -1107,4 +1113,4 @@
|
||||
<Filter>ext\basis_universal</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -589,86 +589,4 @@ void HTTPDownload::Do() {
|
||||
completed_ = true;
|
||||
}
|
||||
|
||||
std::shared_ptr<Download> Downloader::StartDownload(const std::string &url, const Path &outfile, ProgressBarMode mode, const char *acceptMime) {
|
||||
std::shared_ptr<Download> dl(new HTTPDownload(RequestMethod::GET, url, "", "", outfile, mode));
|
||||
|
||||
if (!userAgent_.empty())
|
||||
dl->SetUserAgent(userAgent_);
|
||||
if (acceptMime)
|
||||
dl->SetAccept(acceptMime);
|
||||
newDownloads_.push_back(dl);
|
||||
dl->Start();
|
||||
return dl;
|
||||
}
|
||||
|
||||
std::shared_ptr<Download> Downloader::StartDownloadWithCallback(
|
||||
const std::string &url,
|
||||
const Path &outfile,
|
||||
ProgressBarMode mode,
|
||||
std::function<void(Download &)> callback,
|
||||
const std::string &name,
|
||||
const char *acceptMime) {
|
||||
std::shared_ptr<Download> dl(new HTTPDownload(RequestMethod::GET, url, "", "", outfile, mode, name));
|
||||
if (!userAgent_.empty())
|
||||
dl->SetUserAgent(userAgent_);
|
||||
if (acceptMime)
|
||||
dl->SetAccept(acceptMime);
|
||||
dl->SetCallback(callback);
|
||||
newDownloads_.push_back(dl);
|
||||
dl->Start();
|
||||
return dl;
|
||||
}
|
||||
|
||||
std::shared_ptr<Download> Downloader::AsyncPostWithCallback(
|
||||
const std::string &url,
|
||||
const std::string &postData,
|
||||
const std::string &postMime,
|
||||
ProgressBarMode mode,
|
||||
std::function<void(Download &)> callback,
|
||||
const std::string &name) {
|
||||
std::shared_ptr<Download> dl(new HTTPDownload(RequestMethod::POST, url, postData, postMime, Path(), mode, name));
|
||||
if (!userAgent_.empty())
|
||||
dl->SetUserAgent(userAgent_);
|
||||
dl->SetCallback(callback);
|
||||
newDownloads_.push_back(dl);
|
||||
dl->Start();
|
||||
return dl;
|
||||
}
|
||||
|
||||
void Downloader::Update() {
|
||||
for (auto iter : newDownloads_) {
|
||||
downloads_.push_back(iter);
|
||||
}
|
||||
newDownloads_.clear();
|
||||
|
||||
restart:
|
||||
for (size_t i = 0; i < downloads_.size(); i++) {
|
||||
auto dl = downloads_[i];
|
||||
if (dl->Done()) {
|
||||
dl->RunCallback();
|
||||
dl->Join();
|
||||
downloads_.erase(downloads_.begin() + i);
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Downloader::WaitForAll() {
|
||||
// TODO: Should lock? Though, OK if called from main thread, where Update() is called from.
|
||||
while (!downloads_.empty()) {
|
||||
Update();
|
||||
sleep_ms(10);
|
||||
}
|
||||
}
|
||||
|
||||
void Downloader::CancelAll() {
|
||||
for (size_t i = 0; i < downloads_.size(); i++) {
|
||||
downloads_[i]->Cancel();
|
||||
}
|
||||
for (size_t i = 0; i < downloads_.size(); i++) {
|
||||
downloads_[i]->Join();
|
||||
}
|
||||
downloads_.clear();
|
||||
}
|
||||
|
||||
} // http
|
||||
+1
-103
@@ -8,6 +8,7 @@
|
||||
#include "Common/File/Path.h"
|
||||
#include "Common/Net/NetBuffer.h"
|
||||
#include "Common/Net/Resolve.h"
|
||||
#include "Common/Net/HTTPRequest.h"
|
||||
|
||||
namespace net {
|
||||
|
||||
@@ -89,65 +90,6 @@ protected:
|
||||
double dataTimeout_ = 900.0;
|
||||
};
|
||||
|
||||
enum class RequestMethod {
|
||||
GET,
|
||||
POST,
|
||||
};
|
||||
|
||||
enum class ProgressBarMode {
|
||||
NONE,
|
||||
VISIBLE,
|
||||
DELAYED,
|
||||
};
|
||||
|
||||
class Download {
|
||||
public:
|
||||
Download(const std::string &url, const std::string &name, bool *cancelled) : url_(url), name_(name), progress_(cancelled) {}
|
||||
virtual ~Download() {}
|
||||
|
||||
virtual void SetAccept(const char *mime) = 0;
|
||||
virtual void SetUserAgent(const std::string &userAgent) = 0;
|
||||
|
||||
// NOTE: Completion callbacks (which these are) are deferred until RunCallback is called. This is so that
|
||||
// the call will end up on the thread that calls g_DownloadManager.Update().
|
||||
void SetCallback(std::function<void(Download &)> callback) {
|
||||
callback_ = callback;
|
||||
}
|
||||
void RunCallback() {
|
||||
if (callback_) {
|
||||
callback_(*this);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Start() = 0;
|
||||
virtual void Join() = 0;
|
||||
|
||||
virtual bool Done() const = 0;
|
||||
virtual bool Failed() const = 0;
|
||||
|
||||
virtual int ResultCode() const = 0;
|
||||
|
||||
// Returns 1.0 when done. That one value can be compared exactly - or just use Done().
|
||||
float Progress() const { return progress_.progress; }
|
||||
float SpeedKBps() const { return progress_.kBps; }
|
||||
std::string url() const { return url_; }
|
||||
virtual const Path &outfile() const = 0;
|
||||
|
||||
virtual void Cancel() = 0;
|
||||
virtual bool IsCancelled() const = 0;
|
||||
|
||||
virtual Buffer &buffer() = 0;
|
||||
virtual const Buffer &buffer() const = 0;
|
||||
|
||||
protected:
|
||||
std::function<void(Download &)> callback_;
|
||||
std::string url_;
|
||||
std::string name_;
|
||||
net::RequestProgress progress_;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
// Really an asynchronous request.
|
||||
class HTTPDownload : public Download {
|
||||
public:
|
||||
@@ -208,48 +150,4 @@ private:
|
||||
bool joined_ = false;
|
||||
};
|
||||
|
||||
using std::shared_ptr;
|
||||
|
||||
class Downloader {
|
||||
public:
|
||||
~Downloader() {
|
||||
CancelAll();
|
||||
}
|
||||
|
||||
std::shared_ptr<Download> StartDownload(const std::string &url, const Path &outfile, ProgressBarMode mode, const char *acceptMime = nullptr);
|
||||
|
||||
std::shared_ptr<Download> StartDownloadWithCallback(
|
||||
const std::string &url,
|
||||
const Path &outfile,
|
||||
ProgressBarMode mode,
|
||||
std::function<void(Download &)> callback,
|
||||
const std::string &name = "",
|
||||
const char *acceptMime = nullptr);
|
||||
|
||||
std::shared_ptr<Download> AsyncPostWithCallback(
|
||||
const std::string &url,
|
||||
const std::string &postData,
|
||||
const std::string &postMime, // Use postMime = "application/x-www-form-urlencoded" for standard form-style posts, such as used by retroachievements. For encoding form data manually we have MultipartFormDataEncoder.
|
||||
ProgressBarMode mode,
|
||||
std::function<void(Download &)> callback,
|
||||
const std::string &name = "");
|
||||
|
||||
// Drops finished downloads from the list.
|
||||
void Update();
|
||||
void CancelAll();
|
||||
|
||||
void WaitForAll();
|
||||
void SetUserAgent(const std::string &userAgent) {
|
||||
userAgent_ = userAgent;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<Download>> downloads_;
|
||||
// These get copied to downloads_ in Update(). It's so that callbacks can add new downloads
|
||||
// while running.
|
||||
std::vector<std::shared_ptr<Download>> newDownloads_;
|
||||
|
||||
std::string userAgent_;
|
||||
};
|
||||
|
||||
} // http
|
||||
@@ -0,0 +1,89 @@
|
||||
#include "Common/Net/HTTPRequest.h"
|
||||
#include "Common/Net/HTTPClient.h"
|
||||
#include "Common/TimeUtil.h"
|
||||
|
||||
namespace http {
|
||||
|
||||
std::shared_ptr<Download> RequestManager::StartDownload(const std::string &url, const Path &outfile, ProgressBarMode mode, const char *acceptMime) {
|
||||
std::shared_ptr<Download> dl(new HTTPDownload(RequestMethod::GET, url, "", "", outfile, mode));
|
||||
|
||||
if (!userAgent_.empty())
|
||||
dl->SetUserAgent(userAgent_);
|
||||
if (acceptMime)
|
||||
dl->SetAccept(acceptMime);
|
||||
newDownloads_.push_back(dl);
|
||||
dl->Start();
|
||||
return dl;
|
||||
}
|
||||
|
||||
std::shared_ptr<Download> RequestManager::StartDownloadWithCallback(
|
||||
const std::string &url,
|
||||
const Path &outfile,
|
||||
ProgressBarMode mode,
|
||||
std::function<void(Download &)> callback,
|
||||
const std::string &name,
|
||||
const char *acceptMime) {
|
||||
std::shared_ptr<Download> dl(new HTTPDownload(RequestMethod::GET, url, "", "", outfile, mode, name));
|
||||
if (!userAgent_.empty())
|
||||
dl->SetUserAgent(userAgent_);
|
||||
if (acceptMime)
|
||||
dl->SetAccept(acceptMime);
|
||||
dl->SetCallback(callback);
|
||||
newDownloads_.push_back(dl);
|
||||
dl->Start();
|
||||
return dl;
|
||||
}
|
||||
|
||||
std::shared_ptr<Download> RequestManager::AsyncPostWithCallback(
|
||||
const std::string &url,
|
||||
const std::string &postData,
|
||||
const std::string &postMime,
|
||||
ProgressBarMode mode,
|
||||
std::function<void(Download &)> callback,
|
||||
const std::string &name) {
|
||||
std::shared_ptr<Download> dl(new HTTPDownload(RequestMethod::POST, url, postData, postMime, Path(), mode, name));
|
||||
if (!userAgent_.empty())
|
||||
dl->SetUserAgent(userAgent_);
|
||||
dl->SetCallback(callback);
|
||||
newDownloads_.push_back(dl);
|
||||
dl->Start();
|
||||
return dl;
|
||||
}
|
||||
|
||||
void RequestManager::Update() {
|
||||
for (auto iter : newDownloads_) {
|
||||
downloads_.push_back(iter);
|
||||
}
|
||||
newDownloads_.clear();
|
||||
|
||||
restart:
|
||||
for (size_t i = 0; i < downloads_.size(); i++) {
|
||||
auto dl = downloads_[i];
|
||||
if (dl->Done()) {
|
||||
dl->RunCallback();
|
||||
dl->Join();
|
||||
downloads_.erase(downloads_.begin() + i);
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RequestManager::WaitForAll() {
|
||||
// TODO: Should lock? Though, OK if called from main thread, where Update() is called from.
|
||||
while (!downloads_.empty()) {
|
||||
Update();
|
||||
sleep_ms(10);
|
||||
}
|
||||
}
|
||||
|
||||
void RequestManager::CancelAll() {
|
||||
for (size_t i = 0; i < downloads_.size(); i++) {
|
||||
downloads_[i]->Cancel();
|
||||
}
|
||||
for (size_t i = 0; i < downloads_.size(); i++) {
|
||||
downloads_[i]->Join();
|
||||
}
|
||||
downloads_.clear();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,117 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "Common/File/Path.h"
|
||||
#include "Common/Net/NetBuffer.h"
|
||||
|
||||
namespace http {
|
||||
|
||||
enum class RequestMethod {
|
||||
GET,
|
||||
POST,
|
||||
};
|
||||
|
||||
enum class ProgressBarMode {
|
||||
NONE,
|
||||
VISIBLE,
|
||||
DELAYED,
|
||||
};
|
||||
|
||||
// Abstract request.
|
||||
class Download {
|
||||
public:
|
||||
Download(const std::string &url, const std::string &name, bool *cancelled) : url_(url), name_(name), progress_(cancelled) {}
|
||||
virtual ~Download() {}
|
||||
|
||||
virtual void SetAccept(const char *mime) = 0;
|
||||
virtual void SetUserAgent(const std::string &userAgent) = 0;
|
||||
|
||||
// NOTE: Completion callbacks (which these are) are deferred until RunCallback is called. This is so that
|
||||
// the call will end up on the thread that calls g_DownloadManager.Update().
|
||||
void SetCallback(std::function<void(Download &)> callback) {
|
||||
callback_ = callback;
|
||||
}
|
||||
void RunCallback() {
|
||||
if (callback_) {
|
||||
callback_(*this);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Start() = 0;
|
||||
virtual void Join() = 0;
|
||||
|
||||
virtual bool Done() const = 0;
|
||||
virtual bool Failed() const = 0;
|
||||
|
||||
virtual int ResultCode() const = 0;
|
||||
|
||||
// Returns 1.0 when done. That one value can be compared exactly - or just use Done().
|
||||
float Progress() const { return progress_.progress; }
|
||||
float SpeedKBps() const { return progress_.kBps; }
|
||||
std::string url() const { return url_; }
|
||||
virtual const Path &outfile() const = 0;
|
||||
|
||||
virtual void Cancel() = 0;
|
||||
virtual bool IsCancelled() const = 0;
|
||||
|
||||
// Response
|
||||
virtual Buffer &buffer() = 0;
|
||||
virtual const Buffer &buffer() const = 0;
|
||||
|
||||
protected:
|
||||
std::function<void(Download &)> callback_;
|
||||
std::string url_;
|
||||
std::string name_;
|
||||
net::RequestProgress progress_;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
using std::shared_ptr;
|
||||
|
||||
class RequestManager {
|
||||
public:
|
||||
~RequestManager() {
|
||||
CancelAll();
|
||||
}
|
||||
|
||||
std::shared_ptr<Download> StartDownload(const std::string &url, const Path &outfile, ProgressBarMode mode, const char *acceptMime = nullptr);
|
||||
|
||||
std::shared_ptr<Download> StartDownloadWithCallback(
|
||||
const std::string &url,
|
||||
const Path &outfile,
|
||||
ProgressBarMode mode,
|
||||
std::function<void(Download &)> callback,
|
||||
const std::string &name = "",
|
||||
const char *acceptMime = nullptr);
|
||||
|
||||
std::shared_ptr<Download> AsyncPostWithCallback(
|
||||
const std::string &url,
|
||||
const std::string &postData,
|
||||
const std::string &postMime, // Use postMime = "application/x-www-form-urlencoded" for standard form-style posts, such as used by retroachievements. For encoding form data manually we have MultipartFormDataEncoder.
|
||||
ProgressBarMode mode,
|
||||
std::function<void(Download &)> callback,
|
||||
const std::string &name = "");
|
||||
|
||||
// Drops finished downloads from the list.
|
||||
void Update();
|
||||
void CancelAll();
|
||||
|
||||
void WaitForAll();
|
||||
void SetUserAgent(const std::string &userAgent) {
|
||||
userAgent_ = userAgent;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<Download>> downloads_;
|
||||
// These get copied to downloads_ in Update(). It's so that callbacks can add new downloads
|
||||
// while running.
|
||||
std::vector<std::shared_ptr<Download>> newDownloads_;
|
||||
|
||||
std::string userAgent_;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
@@ -114,6 +114,7 @@
|
||||
<ClInclude Include="..\..\Common\GPU\GPUBackendCommon.h" />
|
||||
<ClInclude Include="..\..\Common\GPU\Vulkan\VulkanLoader.h" />
|
||||
<ClInclude Include="..\..\Common\Math\Statistics.h" />
|
||||
<ClInclude Include="..\..\Common\Net\HTTPRequest.h" />
|
||||
<ClInclude Include="..\..\Common\Net\NetBuffer.h" />
|
||||
<ClInclude Include="..\..\Common\Data\Collections\ConstMap.h" />
|
||||
<ClInclude Include="..\..\Common\Data\Collections\FixedSizeQueue.h" />
|
||||
@@ -273,6 +274,7 @@
|
||||
<ClCompile Include="..\..\Common\GPU\GPUBackendCommon.cpp" />
|
||||
<ClCompile Include="..\..\Common\GPU\Vulkan\VulkanLoader.cpp" />
|
||||
<ClCompile Include="..\..\Common\Math\Statistics.cpp" />
|
||||
<ClCompile Include="..\..\Common\Net\HTTPRequest.cpp" />
|
||||
<ClCompile Include="..\..\Common\Net\NetBuffer.cpp" />
|
||||
<ClCompile Include="..\..\Common\Data\Color\RGBAUtil.cpp" />
|
||||
<ClCompile Include="..\..\Common\Data\Convert\SmallDataConvert.cpp" />
|
||||
|
||||
@@ -444,6 +444,9 @@
|
||||
<ClCompile Include="..\..\Common\System\OSD.cpp">
|
||||
<Filter>System</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Common\Net\HTTPRequest.cpp">
|
||||
<Filter>Net</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="targetver.h" />
|
||||
@@ -841,6 +844,9 @@
|
||||
<ClInclude Include="..\..\Common\System\OSD.h">
|
||||
<Filter>System</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Common\Net\HTTPRequest.h">
|
||||
<Filter>Net</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\Common\Math\fast\fast_matrix_neon.S">
|
||||
|
||||
@@ -238,6 +238,7 @@ EXEC_AND_LIB_FILES := \
|
||||
$(SRC)/Common/Math/lin/matrix4x4.cpp.arm \
|
||||
$(SRC)/Common/Net/HTTPClient.cpp \
|
||||
$(SRC)/Common/Net/HTTPHeaders.cpp \
|
||||
$(SRC)/Common/Net/HTTPRequest.cpp \
|
||||
$(SRC)/Common/Net/HTTPServer.cpp \
|
||||
$(SRC)/Common/Net/NetBuffer.cpp \
|
||||
$(SRC)/Common/Net/Resolve.cpp \
|
||||
|
||||
@@ -351,6 +351,7 @@ SOURCES_CXX += \
|
||||
$(COMMONDIR)/Net/HTTPClient.cpp \
|
||||
$(COMMONDIR)/Net/HTTPHeaders.cpp \
|
||||
$(COMMONDIR)/Net/HTTPServer.cpp \
|
||||
$(COMMONDIR)/Net/HTTPRequest.cpp \
|
||||
$(COMMONDIR)/Net/NetBuffer.cpp \
|
||||
$(COMMONDIR)/Net/Resolve.cpp \
|
||||
$(COMMONDIR)/Net/Sinks.cpp \
|
||||
|
||||
Reference in new issue
Block a user