diff --git a/.gitmodules b/.gitmodules
index 2ca84d342b7a..af29087557de 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -47,3 +47,6 @@
[submodule "ext/rcheevos"]
path = ext/rcheevos
url = https://github.com/RetroAchievements/rcheevos.git
+[submodule "ext/naett"]
+ path = ext/naett
+ url = https://github.com/hrydgard/naett.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dddcf33403ab..452b74f1a8bd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -219,6 +219,16 @@ else()
set(CoreLinkType STATIC)
endif()
+if(NOT ANDROID AND NOT WIN32 AND NOT APPLE)
+ set(HTTPS_NOT_AVAILABLE ON)
+endif()
+
+# Made this flag negative because it's hopefully quite temporary and didn't
+# want to have to update all build systems.
+if(HTTPS_NOT_AVAILABLE)
+ add_definitions(-DHTTPS_NOT_AVAILABLE)
+endif()
+
# Work around for some misfeature of the current glslang build system
include_directories(ext/glslang)
@@ -710,6 +720,10 @@ add_library(Common STATIC
Common/Net/HTTPClient.h
Common/Net/HTTPHeaders.cpp
Common/Net/HTTPHeaders.h
+ Common/Net/HTTPNaettRequest.cpp
+ Common/Net/HTTPNaettRequest.h
+ Common/Net/HTTPRequest.cpp
+ Common/Net/HTTPRequest.h
Common/Net/HTTPServer.cpp
Common/Net/HTTPServer.h
Common/Net/NetBuffer.cpp
@@ -2223,6 +2237,10 @@ endif()
target_link_libraries(${CoreLibName} Common native kirk cityhash sfmt19937 xbrz xxhash rcheevos ${GlslangLibs}
${CoreExtraLibs} ${OPENGL_LIBRARIES} ${X11_LIBRARIES} ${CMAKE_DL_LIBS})
+if(NOT HTTPS_NOT_AVAILABLE)
+ target_link_libraries(${CoreLibName} naett)
+endif()
+
target_compile_features(${CoreLibName} PUBLIC cxx_std_17)
if(FFmpeg_FOUND)
diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj
index 2e5a95a43b5a..2b80aaa4d227 100644
--- a/Common/Common.vcxproj
+++ b/Common/Common.vcxproj
@@ -399,6 +399,7 @@
+
@@ -490,10 +491,12 @@
+
+
@@ -847,6 +850,7 @@
+
@@ -934,10 +938,12 @@
+
+
diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters
index deb16350c311..5527848423d1 100644
--- a/Common/Common.vcxproj.filters
+++ b/Common/Common.vcxproj.filters
@@ -512,6 +512,15 @@
System
+
+ Net
+
+
+ ext\naett
+
+
+ Net
+
@@ -959,6 +968,15 @@
System
+
+ Net
+
+
+ ext\naett
+
+
+ Net
+
@@ -1069,6 +1087,9 @@
{d6d5f6e0-1c72-496b-af11-6d52d5123033}
+
+ {34f45db9-5c08-49cb-b349-b9e760ce3213}
+
diff --git a/Common/Net/HTTPClient.cpp b/Common/Net/HTTPClient.cpp
index 83f4bf20831b..9fc37de0821b 100644
--- a/Common/Net/HTTPClient.cpp
+++ b/Common/Net/HTTPClient.cpp
@@ -444,42 +444,21 @@ int Client::ReadResponseEntity(net::Buffer *readbuf, const std::vector Downloader::StartDownload(const std::string &url, const Path &outfile, ProgressBarMode mode, const char *acceptMime) {
- std::shared_ptr dl(new Download(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 Downloader::StartDownloadWithCallback(
- const std::string &url,
- const Path &outfile,
- ProgressBarMode mode,
- std::function callback,
- const std::string &name,
- const char *acceptMime) {
- std::shared_ptr dl(new Download(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 Downloader::AsyncPostWithCallback(
- const std::string &url,
- const std::string &postData,
- const std::string &postMime,
- ProgressBarMode mode,
- std::function callback,
- const std::string &name) {
- std::shared_ptr dl(new Download(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
diff --git a/Common/Net/HTTPClient.h b/Common/Net/HTTPClient.h
index 88b76f116ea7..df6bcd6c2a95 100644
--- a/Common/Net/HTTPClient.h
+++ b/Common/Net/HTTPClient.h
@@ -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,140 +90,52 @@ class Client : public net::Connection {
double dataTimeout_ = 900.0;
};
-enum class RequestMethod {
- GET,
- POST,
-};
-
-enum class ProgressBarMode {
- NONE,
- VISIBLE,
- DELAYED,
-};
-
// Really an asynchronous request.
-class Download {
+class HTTPDownload : public Download {
public:
- Download(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode = ProgressBarMode::DELAYED, const std::string &name = "");
- ~Download();
+ HTTPDownload(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode = ProgressBarMode::DELAYED, const std::string &name = "");
+ ~HTTPDownload();
- void SetAccept(const char *mime) {
- acceptMime_ = mime;
- }
-
- void SetUserAgent(const std::string &userAgent) {
- userAgent_ = userAgent;
- }
+ void Start() override;
+ void Join() override;
- void Start();
-
- void Join();
-
- // 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; }
-
- bool Done() const { return completed_; }
- bool Failed() const { return failed_; }
+ bool Done() override { return completed_; }
+ bool Failed() const override { return failed_; }
// NOTE! The value of ResultCode is INVALID until Done() returns true.
- int ResultCode() const { return resultCode_; }
+ int ResultCode() const override { return resultCode_; }
- std::string url() const { return url_; }
- const Path &outfile() const { return outfile_; }
+ const Path &outfile() const override { return outfile_; }
// If not downloading to a file, access this to get the result.
- Buffer &buffer() { return buffer_; }
- const Buffer &buffer() const { return buffer_; }
+ Buffer &buffer() override { return buffer_; }
+ const Buffer &buffer() const override { return buffer_; }
- void Cancel() {
+ void Cancel() override {
cancelled_ = true;
}
- bool IsCancelled() const {
+ bool IsCancelled() const override {
return cancelled_;
}
- // 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 callback) {
- callback_ = callback;
- }
- void RunCallback() {
- if (callback_) {
- callback_(*this);
- }
- }
-
private:
void Do(); // Actually does the download. Runs on thread.
int Perform(const std::string &url);
std::string RedirectLocation(const std::string &baseUrl);
void SetFailed(int code);
- RequestMethod method_;
- net::RequestProgress progress_;
std::string postData_;
- std::string userAgent_;
Buffer buffer_;
std::vector responseHeaders_;
- std::string url_;
Path outfile_;
std::thread thread_;
- const char *acceptMime_ = "*/*";
std::string postMime_;
int resultCode_ = 0;
bool completed_ = false;
bool failed_ = false;
bool cancelled_ = false;
- ProgressBarMode progressBarMode_;
bool joined_ = false;
- std::string name_;
- std::function callback_;
-};
-
-using std::shared_ptr;
-
-class Downloader {
-public:
- ~Downloader() {
- CancelAll();
- }
-
- std::shared_ptr StartDownload(const std::string &url, const Path &outfile, ProgressBarMode mode, const char *acceptMime = nullptr);
-
- std::shared_ptr StartDownloadWithCallback(
- const std::string &url,
- const Path &outfile,
- ProgressBarMode mode,
- std::function callback,
- const std::string &name = "",
- const char *acceptMime = nullptr);
-
- std::shared_ptr 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 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> downloads_;
- // These get copied to downloads_ in Update(). It's so that callbacks can add new downloads
- // while running.
- std::vector> newDownloads_;
-
- std::string userAgent_;
};
} // http
diff --git a/Common/Net/HTTPNaettRequest.cpp b/Common/Net/HTTPNaettRequest.cpp
new file mode 100644
index 000000000000..87ca991ee9af
--- /dev/null
+++ b/Common/Net/HTTPNaettRequest.cpp
@@ -0,0 +1,127 @@
+#ifndef HTTPS_NOT_AVAILABLE
+
+#include
+
+#include "Common/Net/HTTPRequest.h"
+#include "Common/Net/HTTPNaettRequest.h"
+#include "Common/Thread/ThreadUtil.h"
+#include "Common/StringUtils.h"
+#include "Common/Log.h"
+
+#include "ext/naett/naett.h"
+
+namespace http {
+
+HTTPSDownload::HTTPSDownload(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode, const std::string &name)
+ : Download(method, url, name, &cancelled_, progressBarMode), method_(method), postData_(postData), postMime_(postMime), outfile_(outfile) {
+}
+
+HTTPSDownload::~HTTPSDownload() {
+ Join();
+}
+
+void HTTPSDownload::Start() {
+ _dbg_assert_(!req_);
+ _dbg_assert_(!res_);
+
+ std::vector options;
+ options.push_back(naettMethod(method_ == RequestMethod::GET ? "GET" : "POST"));
+ options.push_back(naettHeader("Accept", acceptMime_));
+ options.push_back(naettUserAgent(userAgent_.c_str()));
+ if (!postMime_.empty()) {
+ options.push_back(naettHeader("Content-Type", postMime_.c_str()));
+ }
+ if (method_ == RequestMethod::POST) {
+ if (!postData_.empty()) {
+ // Note: Naett does not take ownership over the body.
+ options.push_back(naettBody(postData_.data(), (int)postData_.size()));
+ }
+ } else {
+ _dbg_assert_(postData_.empty());
+ }
+ // 30 s timeout - not sure what's reasonable?
+ options.push_back(naettTimeout(30 * 1000)); // milliseconds
+
+ const naettOption **opts = (const naettOption **)options.data();
+ req_ = naettRequestWithOptions(url_.c_str(), (int)options.size(), opts);
+ res_ = naettMake(req_);
+
+ progress_.Update(0, 0, false);
+}
+
+void HTTPSDownload::Join() {
+ if (!res_ || !req_)
+ return; // No pending operation.
+ // Tear down.
+ if (completed_ && res_) {
+ _dbg_assert_(req_);
+ naettClose(res_);
+ naettFree(req_);
+ res_ = nullptr;
+ req_ = nullptr;
+ } else {
+ ERROR_LOG(IO, "HTTPSDownload::Join not implemented");
+ }
+}
+
+bool HTTPSDownload::Done() {
+ if (completed_)
+ return true;
+
+ if (!naettComplete(res_)) {
+ int total = 0;
+ int size = naettGetTotalBytesRead(res_, &total);
+ progress_.Update(size, total, false);
+ return false;
+ }
+
+ // -1000 is a code specified by us to represent cancellation, that is unlikely to ever collide with naett error codes.
+ resultCode_ = IsCancelled() ? -1000 : naettGetStatus(res_);
+ if (resultCode_ < 0) {
+ // It's a naett error. Translate and handle.
+ switch (resultCode_) {
+ case naettConnectionError: // -1
+ ERROR_LOG(IO, "Connection error");
+ break;
+ case naettProtocolError: // -2
+ ERROR_LOG(IO, "Protocol error");
+ break;
+ case naettReadError: // -3
+ ERROR_LOG(IO, "Read error");
+ break;
+ case naettWriteError: // -4
+ ERROR_LOG(IO, "Write error");
+ break;
+ case naettGenericError: // -5
+ ERROR_LOG(IO, "Generic error");
+ break;
+ default:
+ ERROR_LOG(IO, "Unhandled naett error %d", resultCode_);
+ break;
+ }
+ failed_ = true;
+ progress_.Update(0, 0, true);
+ } else if (resultCode_ == 200) {
+ int bodyLength;
+ const void *body = naettGetBody(res_, &bodyLength);
+ char *dest = buffer_.Append(bodyLength);
+ memcpy(dest, body, bodyLength);
+ if (!outfile_.empty() && !buffer_.FlushToFile(outfile_)) {
+ ERROR_LOG(IO, "Failed writing download to '%s'", outfile_.c_str());
+ }
+ progress_.Update(bodyLength, bodyLength, true);
+ } else {
+ WARN_LOG(IO, "Naett request failed: %d", resultCode_);
+ failed_ = true;
+ progress_.Update(0, 0, true);
+ }
+
+ completed_ = true;
+
+ // The callback will be called later.
+ return true;
+}
+
+} // namespace http
+
+#endif // HTTPS_NOT_AVAILABLE
diff --git a/Common/Net/HTTPNaettRequest.h b/Common/Net/HTTPNaettRequest.h
new file mode 100644
index 000000000000..4fa5c93d165f
--- /dev/null
+++ b/Common/Net/HTTPNaettRequest.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#include
+
+#include "Common/Net/HTTPRequest.h"
+
+#ifndef HTTPS_NOT_AVAILABLE
+
+#include "ext/naett/naett.h"
+
+namespace http {
+
+// Really an asynchronous request.
+class HTTPSDownload : public Download {
+public:
+ HTTPSDownload(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode = ProgressBarMode::DELAYED, const std::string &name = "");
+ ~HTTPSDownload();
+
+ void Start() override;
+ void Join() override;
+
+ // Also acts as a Poll.
+ bool Done() override;
+ bool Failed() const override { return failed_; }
+
+ // NOTE! The value of ResultCode is INVALID until Done() returns true.
+ int ResultCode() const override { return resultCode_; }
+
+ const Path &outfile() const override { return outfile_; }
+
+ // If not downloading to a file, access this to get the result.
+ Buffer &buffer() override { return buffer_; }
+ const Buffer &buffer() const override { return buffer_; }
+
+ void Cancel() override {
+ cancelled_ = true;
+ }
+
+ bool IsCancelled() const override {
+ return cancelled_;
+ }
+
+private:
+ RequestMethod method_;
+ std::string postData_;
+ Buffer buffer_;
+ std::vector responseHeaders_;
+ Path outfile_;
+ std::string postMime_;
+ int resultCode_ = 0;
+ bool completed_ = false;
+ bool failed_ = false;
+ bool cancelled_ = false;
+ bool joined_ = false;
+
+ // Naett state
+ naettReq *req_ = nullptr;
+ naettRes *res_ = nullptr;
+};
+
+} // namespace http
+
+#endif // HTTPS_NOT_AVAILABLE
diff --git a/Common/Net/HTTPRequest.cpp b/Common/Net/HTTPRequest.cpp
new file mode 100644
index 000000000000..e982ff81f9a5
--- /dev/null
+++ b/Common/Net/HTTPRequest.cpp
@@ -0,0 +1,147 @@
+#include "Common/Net/HTTPRequest.h"
+#include "Common/Net/HTTPClient.h"
+#include "Common/Net/HTTPNaettRequest.h"
+#include "Common/TimeUtil.h"
+#include "Common/StringUtils.h"
+#include "Common/Log.h"
+#include "Common/System/OSD.h"
+
+namespace http {
+
+Download::Download(RequestMethod method, const std::string &url, const std::string &name, bool *cancelled, ProgressBarMode mode) : method_(method), url_(url), name_(name), progress_(cancelled), progressBarMode_(mode) {
+ progress_.callback = [=](int64_t bytes, int64_t contentLength, bool done) {
+ std::string message;
+ if (!name_.empty()) {
+ message = name_;
+ } else {
+ std::size_t pos = url_.rfind('/');
+ if (pos != std::string::npos) {
+ message = url_.substr(pos + 1);
+ } else {
+ message = url_;
+ }
+ }
+ if (progressBarMode_ != ProgressBarMode::NONE) {
+ if (!done) {
+ g_OSD.SetProgressBar(url_, std::move(message), 0.0f, (float)contentLength, (float)bytes, progressBarMode_ == ProgressBarMode::DELAYED ? 3.0f : 0.0f); // delay 3 seconds before showing.
+ } else {
+ g_OSD.RemoveProgressBar(url_, Failed() ? false : true, 0.5f);
+ }
+ }
+ };
+}
+
+bool RequestManager::IsHttpsUrl(const std::string &url) {
+ return startsWith(url, "https:");
+}
+
+std::shared_ptr RequestManager::StartDownload(const std::string &url, const Path &outfile, ProgressBarMode mode, const char *acceptMime) {
+ std::shared_ptr dl;
+ if (IsHttpsUrl(url)) {
+#ifndef HTTPS_NOT_AVAILABLE
+ dl.reset(new HTTPSDownload(RequestMethod::GET, url, "", "", outfile, mode));
+#else
+ return std::shared_ptr();
+#endif
+ } else {
+ dl.reset(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 RequestManager::StartDownloadWithCallback(
+ const std::string &url,
+ const Path &outfile,
+ ProgressBarMode mode,
+ std::function callback,
+ const std::string &name,
+ const char *acceptMime) {
+ std::shared_ptr dl;
+ if (IsHttpsUrl(url)) {
+#ifndef HTTPS_NOT_AVAILABLE
+ dl.reset(new HTTPSDownload(RequestMethod::GET, url, "", "", outfile, mode, name));
+#else
+ return std::shared_ptr();
+#endif
+ } else {
+ dl.reset(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 RequestManager::AsyncPostWithCallback(
+ const std::string &url,
+ const std::string &postData,
+ const std::string &postMime,
+ ProgressBarMode mode,
+ std::function callback,
+ const std::string &name) {
+ std::shared_ptr dl;
+ if (IsHttpsUrl(url)) {
+#ifndef HTTPS_NOT_AVAILABLE
+ dl.reset(new HTTPSDownload(RequestMethod::POST, url, postData, postMime, Path(), mode, name));
+#else
+ return std::shared_ptr();
+#endif
+ } else {
+ dl.reset(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
diff --git a/Common/Net/HTTPRequest.h b/Common/Net/HTTPRequest.h
new file mode 100644
index 000000000000..0e7686009b19
--- /dev/null
+++ b/Common/Net/HTTPRequest.h
@@ -0,0 +1,129 @@
+#pragma once
+
+#include
+#include
+#include
+
+#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(RequestMethod method, const std::string &url, const std::string &name, bool *cancelled, ProgressBarMode mode);
+ virtual ~Download() {}
+
+ void SetAccept(const char *mime) {
+ acceptMime_ = mime;
+ }
+
+ void SetUserAgent(const std::string &userAgent) {
+ userAgent_ = userAgent;
+ }
+
+ // 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 callback) {
+ callback_ = callback;
+ }
+ void RunCallback() {
+ if (callback_) {
+ callback_(*this);
+ }
+ }
+
+ virtual void Start() = 0;
+ virtual void Join() = 0;
+
+ virtual bool Done() = 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 callback_;
+ RequestMethod method_;
+ std::string url_;
+ std::string name_;
+ const char *acceptMime_ = "*/*";
+ std::string userAgent_;
+
+ net::RequestProgress progress_;
+ ProgressBarMode progressBarMode_;
+
+private:
+};
+
+using std::shared_ptr;
+
+class RequestManager {
+public:
+ ~RequestManager() {
+ CancelAll();
+ }
+
+ std::shared_ptr StartDownload(const std::string &url, const Path &outfile, ProgressBarMode mode, const char *acceptMime = nullptr);
+
+ std::shared_ptr StartDownloadWithCallback(
+ const std::string &url,
+ const Path &outfile,
+ ProgressBarMode mode,
+ std::function callback,
+ const std::string &name = "",
+ const char *acceptMime = nullptr);
+
+ std::shared_ptr 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 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:
+ bool IsHttpsUrl(const std::string &url);
+
+ std::vector> downloads_;
+ // These get copied to downloads_ in Update(). It's so that callbacks can add new downloads
+ // while running.
+ std::vector> newDownloads_;
+
+ std::string userAgent_;
+};
+
+} // namespace net
diff --git a/Common/Net/NetBuffer.cpp b/Common/Net/NetBuffer.cpp
index 3cdbbcd189e6..06310a6c8388 100644
--- a/Common/Net/NetBuffer.cpp
+++ b/Common/Net/NetBuffer.cpp
@@ -22,6 +22,18 @@
namespace net {
+void RequestProgress::Update(int64_t downloaded, int64_t totalBytes, bool done) {
+ if (totalBytes) {
+ progress = (double)downloaded / (double)totalBytes;
+ } else {
+ progress = 0.01f;
+ }
+
+ if (callback) {
+ callback(downloaded, totalBytes, done);
+ }
+}
+
bool Buffer::FlushSocket(uintptr_t sock, double timeout, bool *cancelled) {
static constexpr float CANCEL_INTERVAL = 0.25f;
for (size_t pos = 0, end = data_.size(); pos < end; ) {
diff --git a/Common/Net/NetBuffer.h b/Common/Net/NetBuffer.h
index 85b1421d2849..32525ad3f754 100644
--- a/Common/Net/NetBuffer.h
+++ b/Common/Net/NetBuffer.h
@@ -12,16 +12,7 @@ class RequestProgress {
RequestProgress() {}
explicit RequestProgress(bool *c) : cancelled(c) {}
- void Update(int64_t downloaded, int64_t totalBytes, bool done) {
- if (totalBytes) {
- progress = (double)downloaded / (double)totalBytes;
- } else {
- progress = 0.01f;
- }
- if (callback) {
- callback(downloaded, totalBytes, done);
- }
- }
+ void Update(int64_t downloaded, int64_t totalBytes, bool done);
float progress = 0.0f;
float kBps = 0.0f;
diff --git a/Common/Net/Resolve.cpp b/Common/Net/Resolve.cpp
index 76f0055f50fb..2438fc5b3360 100644
--- a/Common/Net/Resolve.cpp
+++ b/Common/Net/Resolve.cpp
@@ -30,8 +30,18 @@
#include "Common/Log.h"
#include "Common/TimeUtil.h"
+#ifndef HTTPS_NOT_AVAILABLE
+#include "ext/naett/naett.h"
+#endif
+
+#if PPSSPP_PLATFORM(ANDROID)
+#include
+extern JavaVM *gJvm;
+#endif
+
namespace net {
+static bool g_naettInitialized;
void Init()
{
@@ -40,6 +50,17 @@ void Init()
WSADATA wsaData = {0};
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
+ if (!g_naettInitialized) {
+#ifndef HTTPS_NOT_AVAILABLE
+#if PPSSPP_PLATFORM(ANDROID)
+ _assert_(gJvm != nullptr);
+ naettInit(gJvm);
+#else
+ naettInit(NULL);
+#endif
+#endif
+ g_naettInitialized = true;
+ }
}
void Shutdown()
diff --git a/Common/Render/Text/draw_text_android.cpp b/Common/Render/Text/draw_text_android.cpp
index cab0bdca7e15..d1e6244cb27e 100644
--- a/Common/Render/Text/draw_text_android.cpp
+++ b/Common/Render/Text/draw_text_android.cpp
@@ -1,4 +1,5 @@
#include "ppsspp_config.h"
+
#include "Common/Log.h"
#include "Common/StringUtils.h"
#include "Common/System/Display.h"
diff --git a/Common/System/Request.cpp b/Common/System/Request.cpp
index dbfcff7c62b0..8e78352908a5 100644
--- a/Common/System/Request.cpp
+++ b/Common/System/Request.cpp
@@ -1,3 +1,5 @@
+#include "ppsspp_config.h"
+
#include
#include "Common/System/Request.h"
@@ -6,6 +8,17 @@
#include "Common/File/Path.h"
#include "Common/TimeUtil.h"
+#if PPSSPP_PLATFORM(ANDROID)
+
+// Maybe not the most natural place for this, but not sure what would be. It needs to be in the Common project
+// unless we want to make another System_ function to retrieve it.
+
+#include
+
+JavaVM *gJvm = nullptr;
+
+#endif
+
RequestManager g_requestManager;
const char *RequestTypeAsString(SystemRequestType type) {
diff --git a/Common/System/System.h b/Common/System/System.h
index fd1ca445a512..17eeda194d05 100644
--- a/Common/System/System.h
+++ b/Common/System/System.h
@@ -136,6 +136,8 @@ enum SystemProperty {
SYSPROP_CAN_CREATE_SHORTCUT,
+ SYSPROP_SUPPORTS_HTTPS,
+
// Available as Int:
SYSPROP_SYSTEMVERSION,
SYSPROP_DISPLAY_XRES,
diff --git a/Common/UI/IconCache.cpp b/Common/UI/IconCache.cpp
index f5b28881a0c2..830655e3dfc0 100644
--- a/Common/UI/IconCache.cpp
+++ b/Common/UI/IconCache.cpp
@@ -239,6 +239,7 @@ bool IconCache::InsertIcon(const std::string &key, IconFormat format, std::strin
}
if (data.empty()) {
+ _dbg_assert_(false);
ERROR_LOG(G3D, "Can't insert empty data into icon cache");
return false;
}
diff --git a/Core/Config.cpp b/Core/Config.cpp
index 316157d3e5d0..70eb254f2e24 100644
--- a/Core/Config.cpp
+++ b/Core/Config.cpp
@@ -57,7 +57,7 @@
#include "GPU/Common/FramebufferManagerCommon.h"
// TODO: Find a better place for this.
-http::Downloader g_DownloadManager;
+http::RequestManager g_DownloadManager;
Config g_Config;
@@ -1174,7 +1174,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
if (iRunCount % 10 == 0 && bCheckForNewVersion) {
const char *versionUrl = "http://www.ppsspp.org/version.json";
const char *acceptMime = "application/json, text/*; q=0.9, */*; q=0.8";
- g_DownloadManager.StartDownloadWithCallback(versionUrl, Path(), http::ProgressBarMode::NONE, &DownloadCompletedCallback, acceptMime);
+ g_DownloadManager.StartDownloadWithCallback(versionUrl, Path(), http::ProgressBarMode::NONE, &DownloadCompletedCallback, "version", acceptMime);
}
INFO_LOG(LOADER, "Loading controller config: %s", controllerIniFilename_.c_str());
diff --git a/Core/Config.h b/Core/Config.h
index bd1b4223a186..98edbd35b5c5 100644
--- a/Core/Config.h
+++ b/Core/Config.h
@@ -42,7 +42,7 @@ enum ChatPositions {
namespace http {
class Download;
- class Downloader;
+ class RequestManager;
}
struct UrlEncoder;
@@ -595,6 +595,6 @@ struct Config {
std::string CreateRandMAC();
// TODO: Find a better place for this.
-extern http::Downloader g_DownloadManager;
+extern http::RequestManager g_DownloadManager;
extern Config g_Config;
diff --git a/Core/RetroAchievements.cpp b/Core/RetroAchievements.cpp
index 84302c812315..3821470ada8a 100644
--- a/Core/RetroAchievements.cpp
+++ b/Core/RetroAchievements.cpp
@@ -349,8 +349,10 @@ void Initialize() {
// Provide a logging function to simplify debugging
rc_client_enable_logging(g_rcClient, RC_CLIENT_LOG_LEVEL_VERBOSE, log_message_callback);
- // Disable SSL for now.
- rc_client_set_host(g_rcClient, "http://retroachievements.org");
+ if (!System_GetPropertyBool(SYSPROP_SUPPORTS_HTTPS)) {
+ // Disable SSL if not supported by our platform implementation.
+ rc_client_set_host(g_rcClient, "http://retroachievements.org");
+ }
rc_client_set_event_handler(g_rcClient, event_handler_callback);
diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp
index 2e70d892331f..cfb81e9dbd0b 100644
--- a/Core/Util/PortManager.cpp
+++ b/Core/Util/PortManager.cpp
@@ -49,11 +49,10 @@ std::recursive_mutex upnpLock;
std::deque upnpReqs;
PortManager::PortManager():
- urls(0),
- datas(0),
m_InitState(UPNP_INITSTATE_NONE),
m_LocalPort(UPNP_LOCAL_PORT_ANY),
m_leaseDuration("43200") {
+ // Don't call net::Init or similar here, we don't want stuff like that to happen before main.
}
PortManager::~PortManager() {
diff --git a/Core/Util/PortManager.h b/Core/Util/PortManager.h
index f284788a38f0..31b9f67f9552 100644
--- a/Core/Util/PortManager.h
+++ b/Core/Util/PortManager.h
@@ -108,8 +108,8 @@ class PortManager {
// Uninitialize/Reset the state
void Terminate();
- struct UPNPUrls* urls = NULL;
- struct IGDdatas* datas = NULL;
+ struct UPNPUrls* urls = nullptr;
+ struct IGDdatas* datas = nullptr;
int m_InitState = UPNP_INITSTATE_NONE;
int m_LocalPort = UPNP_LOCAL_PORT_ANY;
diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp
index f46af287ad02..955592a492c8 100644
--- a/SDL/SDLMain.cpp
+++ b/SDL/SDLMain.cpp
@@ -529,6 +529,10 @@ bool System_GetPropertyBool(SystemProperty prop) {
return true;
case SYSPROP_SUPPORTS_OPEN_FILE_IN_EDITOR:
return true; // FileUtil.cpp: OpenFileInEditor
+#ifndef HTTPS_NOT_AVAILABLE
+ case SYSPROP_SUPPORTS_HTTPS:
+ return true;
+#endif
#if PPSSPP_PLATFORM(MAC)
case SYSPROP_HAS_FOLDER_BROWSER:
case SYSPROP_HAS_FILE_BROWSER:
diff --git a/UI/Store.cpp b/UI/Store.cpp
index 0ad19143f653..dbe14d46ddea 100644
--- a/UI/Store.cpp
+++ b/UI/Store.cpp
@@ -35,7 +35,12 @@
#include "UI/EmuScreen.h"
#include "UI/Store.h"
-const std::string storeBaseUrl = "http://store.ppsspp.org/";
+const char *storeBaseUrlHttp = "http://store.ppsspp.org/";
+const char *storeBaseUrlHttps = "https://store.ppsspp.org/";
+
+static std::string StoreBaseUrl() {
+ return System_GetPropertyBool(SYSPROP_SUPPORTS_HTTPS) ? storeBaseUrlHttps : storeBaseUrlHttp;
+}
// baseUrl is assumed to have a trailing slash, and not contain any subdirectories.
std::string ResolveUrl(std::string baseUrl, std::string url) {
@@ -53,16 +58,20 @@ std::string ResolveUrl(std::string baseUrl, std::string url) {
class HttpImageFileView : public UI::View {
public:
- HttpImageFileView(http::Downloader *downloader, const std::string &path, UI::ImageSizeMode sizeMode = UI::IS_DEFAULT, bool useIconCache = true, UI::LayoutParams *layoutParams = nullptr)
- : UI::View(layoutParams), path_(path), sizeMode_(sizeMode), downloader_(downloader), useIconCache_(useIconCache) {
+ HttpImageFileView(http::RequestManager *requestManager, const std::string &path, UI::ImageSizeMode sizeMode = UI::IS_DEFAULT, bool useIconCache = true, UI::LayoutParams *layoutParams = nullptr)
+ : UI::View(layoutParams), path_(path), sizeMode_(sizeMode), requestManager_(requestManager), useIconCache_(useIconCache) {
if (useIconCache && g_iconCache.MarkPending(path_)) {
const char *acceptMime = "image/png, image/jpeg, image/*; q=0.9, */*; q=0.8";
- downloader_->StartDownloadWithCallback(path_, Path(), http::ProgressBarMode::DELAYED, [&](http::Download &download) {
+ requestManager_->StartDownloadWithCallback(path_, Path(), http::ProgressBarMode::DELAYED, [&](http::Download &download) {
if (download.ResultCode() == 200) {
std::string data;
download.buffer().TakeAll(&data);
- g_iconCache.InsertIcon(path_, IconFormat::PNG, std::move(data));
+ if (!data.empty()) {
+ g_iconCache.InsertIcon(path_, IconFormat::PNG, std::move(data));
+ } else {
+ g_iconCache.Cancel(path_);
+ }
} else {
g_iconCache.Cancel(path_);
}
@@ -96,7 +105,7 @@ class HttpImageFileView : public UI::View {
std::string path_; // or cache key
uint32_t color_ = 0xFFFFFFFF;
UI::ImageSizeMode sizeMode_;
- http::Downloader *downloader_;
+ http::RequestManager *requestManager_;
std::shared_ptr download_;
std::string textureData_;
@@ -165,7 +174,7 @@ void HttpImageFileView::Draw(UIContext &dc) {
if (!texture_ && !textureFailed_ && !path_.empty() && !download_) {
auto cb = std::bind(&HttpImageFileView::DownloadCompletedCallback, this, std::placeholders::_1);
const char *acceptMime = "image/png, image/jpeg, image/*; q=0.9, */*; q=0.8";
- downloader_->StartDownloadWithCallback(path_, Path(), http::ProgressBarMode::NONE, cb, acceptMime);
+ requestManager_->StartDownloadWithCallback(path_, Path(), http::ProgressBarMode::NONE, cb, acceptMime);
}
if (!textureData_.empty()) {
@@ -275,7 +284,7 @@ void ProductView::CreateViews() {
Clear();
if (!entry_.iconURL.empty()) {
- Add(new HttpImageFileView(&g_DownloadManager, ResolveUrl(storeBaseUrl, entry_.iconURL), IS_FIXED))->SetFixedSize(144, 88);
+ Add(new HttpImageFileView(&g_DownloadManager, ResolveUrl(StoreBaseUrl(), entry_.iconURL), IS_FIXED))->SetFixedSize(144, 88);
}
Add(new TextView(entry_.name));
Add(new TextView(entry_.author));
@@ -346,7 +355,7 @@ void ProductView::Update() {
std::string ProductView::DownloadURL() {
if (entry_.downloadURL.empty()) {
// Construct the URL.
- return storeBaseUrl + "files/" + entry_.file + ".zip";
+ return StoreBaseUrl() + "files/" + entry_.file + ".zip";
} else {
// Use the provided URL, for external hosting.
return entry_.downloadURL;
@@ -401,7 +410,7 @@ StoreScreen::StoreScreen() {
lang_ = g_Config.sLanguageIni;
loading_ = true;
- std::string indexPath = storeBaseUrl + "index.json";
+ std::string indexPath = StoreBaseUrl() + "index.json";
const char *acceptMime = "application/json, */*; q=0.8";
listing_ = g_DownloadManager.StartDownload(indexPath, Path(), http::ProgressBarMode::DELAYED, acceptMime);
}
diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj
index e5a72c7d3278..3e9878bf65ae 100644
--- a/UWP/CommonUWP/CommonUWP.vcxproj
+++ b/UWP/CommonUWP/CommonUWP.vcxproj
@@ -114,6 +114,8 @@
+
+
@@ -259,6 +261,7 @@
+
@@ -273,6 +276,8 @@
+
+
@@ -398,6 +403,7 @@
+
diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters
index 2dfc1ae39763..2eedf9e8c653 100644
--- a/UWP/CommonUWP/CommonUWP.vcxproj.filters
+++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters
@@ -94,6 +94,9 @@
{8b92cc15-8e3e-45b1-ba80-ad39b1a9cdc8}
+
+ {403c3154-5e8a-4da1-ba82-8f69bef25e14}
+
@@ -444,6 +447,15 @@
System
+
+ Net
+
+
+ Net
+
+
+ ext\naett
+
@@ -841,6 +853,15 @@
System
+
+ Net
+
+
+ Net
+
+
+ ext\naett
+
diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj
index f345af5f1a47..881a31cab516 100644
--- a/Windows/PPSSPP.vcxproj
+++ b/Windows/PPSSPP.vcxproj
@@ -249,7 +249,7 @@
stdcpp17
- uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
../ffmpeg/Windows/x86/lib
true
Windows
@@ -289,7 +289,7 @@
stdcpp17
- uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
../ffmpeg/Windows/x86_64/lib
true
$(OutDir)$(ProjectName).pdb
@@ -325,7 +325,7 @@
stdcpp17
- uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)
+ winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)
../ffmpeg/Windows/aarch64/lib
true
$(OutDir)$(ProjectName).pdb
@@ -359,7 +359,7 @@
stdcpp17
- uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)
+ winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)
../ffmpeg/Windows/arm/lib
true
$(OutDir)$(ProjectName).pdb
@@ -397,7 +397,7 @@
stdcpp17
- uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
../ffmpeg/Windows/x86/lib;%(AdditionalLibraryDirectories)
$(OutDir)$(TargetName)$(TargetExt)
true
@@ -446,7 +446,7 @@
stdcpp17
- uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
../ffmpeg/Windows/x86_64/lib;%(AdditionalLibraryDirectories)
true
Windows
@@ -489,7 +489,7 @@
stdcpp17
- uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)
+ winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)
../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories)
true
Windows
@@ -530,7 +530,7 @@
stdcpp17
- uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)
+ winhttp.lib;uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)
../ffmpeg/Windows/arm/lib;%(AdditionalLibraryDirectories)
true
Windows
diff --git a/Windows/main.cpp b/Windows/main.cpp
index 7fe8de2ddc55..6cbd2e6243e5 100644
--- a/Windows/main.cpp
+++ b/Windows/main.cpp
@@ -375,6 +375,8 @@ bool System_GetPropertyBool(SystemProperty prop) {
return true;
case SYSPROP_SUPPORTS_OPEN_FILE_IN_EDITOR:
return true; // FileUtil.cpp: OpenFileInEditor
+ case SYSPROP_SUPPORTS_HTTPS:
+ return true;
default:
return false;
}
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
index bfb6874e63b2..4fe1d0df45d4 100644
--- a/android/jni/Android.mk
+++ b/android/jni/Android.mk
@@ -79,7 +79,10 @@ SPIRV_CROSS_FILES := \
$(SRC)/ext/SPIRV-Cross/spirv_glsl.cpp \
$(SRC)/ext/SPIRV-Cross/spirv_parser.cpp \
$(SRC)/ext/SPIRV-Cross/spirv_cross_parsed_ir.cpp
-
+
+NAETT_FILES := \
+ ${SRC}/ext/naett/naett.c
+
RCHEEVOS_FILES := \
${SRC}/ext/rcheevos/src/rapi/rc_api_common.c \
${SRC}/ext/rcheevos/src/rapi/rc_api_editor.c \
@@ -178,6 +181,7 @@ EXEC_AND_LIB_FILES := \
$(VMA_FILES) \
$(SPIRV_CROSS_FILES) \
$(RCHEEVOS_FILES) \
+ $(NAETT_FILES) \
$(EXT_FILES) \
$(NATIVE_FILES) \
$(SRC)/Common/Buffer.cpp \
@@ -238,6 +242,8 @@ 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/HTTPNaettRequest.cpp \
$(SRC)/Common/Net/HTTPServer.cpp \
$(SRC)/Common/Net/NetBuffer.cpp \
$(SRC)/Common/Net/Resolve.cpp \
diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp
index ca80a429ba71..61c737396c9a 100644
--- a/android/jni/app-android.cpp
+++ b/android/jni/app-android.cpp
@@ -158,7 +158,8 @@ static int desiredBackbufferSizeX;
static int desiredBackbufferSizeY;
// Cache the class loader so we can use it from native threads. Required for TextAndroid.
-static JavaVM* gJvm = nullptr;
+extern JavaVM *gJvm;
+
static jobject gClassLoader;
static jmethodID gFindClassMethod;
@@ -534,6 +535,10 @@ bool System_GetPropertyBool(SystemProperty prop) {
}
case SYSPROP_HAS_KEYBOARD:
return deviceType != DEVICE_TYPE_VR;
+#ifndef HTTPS_NOT_AVAILABLE
+ case SYSPROP_SUPPORTS_HTTPS:
+ return true;
+#endif
default:
return false;
}
diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt
index 8fc0581d45b0..9bbb9b7a7452 100644
--- a/ext/CMakeLists.txt
+++ b/ext/CMakeLists.txt
@@ -31,6 +31,9 @@ add_subdirectory(snappy)
add_subdirectory(udis86)
add_subdirectory(SPIRV-Cross-build)
add_subdirectory(rcheevos-build)
+if(NOT HTTPS_NOT_AVAILABLE)
+ add_subdirectory(naett-build)
+endif()
if(USE_DISCORD AND NOT IOS AND NOT LIBRETRO)
add_subdirectory(discord-rpc-build)
endif()
diff --git a/ext/naett b/ext/naett
new file mode 160000
index 000000000000..24438d3d6c6e
--- /dev/null
+++ b/ext/naett
@@ -0,0 +1 @@
+Subproject commit 24438d3d6c6e4639b51237ac34cebf25781d5f0a
diff --git a/ext/naett-build/CMakeLists.txt b/ext/naett-build/CMakeLists.txt
new file mode 100644
index 000000000000..6b3b4893466e
--- /dev/null
+++ b/ext/naett-build/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required (VERSION 3.2.0)
+project (naett)
+
+set(SRC_DIR ../naett)
+
+set(ALL_SOURCE_FILES
+ ${SRC_DIR}/naett.c
+ )
+
+add_library(naett STATIC ${ALL_SOURCE_FILES})
diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj
index 695f20dbe4fa..65cc85d5b46c 100644
--- a/headless/Headless.vcxproj
+++ b/headless/Headless.vcxproj
@@ -191,7 +191,7 @@
Console
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;d3dx9d.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;d3dx9d.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
0x00400000
false
true
@@ -225,7 +225,7 @@
Console
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;d3dx9d.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;d3dx9d.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
0x00400000
false
true
@@ -258,7 +258,7 @@
Console
true
- ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)
+ winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/aarch64/lib
@@ -289,7 +289,7 @@
Console
true
- ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)
+ winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/arm/lib
@@ -323,7 +323,7 @@
true
true
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;d3dx9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;d3dx9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
0x00400000
false
true
@@ -362,7 +362,7 @@
true
true
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;d3dx9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;d3dx9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
0x00400000
false
true
@@ -400,7 +400,7 @@
true
true
true
- ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)
+ winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories)
@@ -435,7 +435,7 @@
true
true
true
- ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)
+ winhttp.lib;ole32.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;shell32.lib;advapi32.lib;gdi32.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/arm/lib;%(AdditionalLibraryDirectories)
diff --git a/ios/main.mm b/ios/main.mm
index 18d23f851775..4ca2f041ddbd 100644
--- a/ios/main.mm
+++ b/ios/main.mm
@@ -168,7 +168,10 @@ bool System_GetPropertyBool(SystemProperty prop) {
#endif
case SYSPROP_CAN_JIT:
return get_debugged();
-
+#ifndef HTTPS_NOT_AVAILABLE
+ case SYSPROP_SUPPORTS_HTTPS:
+ return true;
+#endif
default:
return false;
}
diff --git a/libretro/Makefile.common b/libretro/Makefile.common
index 29bc7de7e4b6..8c6a90ca0608 100644
--- a/libretro/Makefile.common
+++ b/libretro/Makefile.common
@@ -224,6 +224,8 @@ SOURCES_C += \
$(EXTDIR)/rcheevos/src/rhash/md5.c
COREFLAGS += -DSTACK_LINE_READER_BUFFER_SIZE=1024
+COREFLAGS += -DHTTPS_NOT_AVAILABLE
+
ifeq ($(PLATFORM_EXT), android)
COREFLAGS += -DHAVE_DLFCN_H
else ifneq ($(PLATFORM_EXT), win32)
@@ -351,6 +353,8 @@ SOURCES_CXX += \
$(COMMONDIR)/Net/HTTPClient.cpp \
$(COMMONDIR)/Net/HTTPHeaders.cpp \
$(COMMONDIR)/Net/HTTPServer.cpp \
+ $(COMMONDIR)/Net/HTTPRequest.cpp \
+ $(COMMONDIR)/Net/HTTPNaettRequest.cpp \
$(COMMONDIR)/Net/NetBuffer.cpp \
$(COMMONDIR)/Net/Resolve.cpp \
$(COMMONDIR)/Net/Sinks.cpp \
diff --git a/unittest/UnitTests.vcxproj b/unittest/UnitTests.vcxproj
index e96bfd789215..7417f4f38b63 100644
--- a/unittest/UnitTests.vcxproj
+++ b/unittest/UnitTests.vcxproj
@@ -181,7 +181,7 @@
Console
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/x86/lib
@@ -205,7 +205,7 @@
Console
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/x86_64/lib
@@ -229,7 +229,7 @@
Console
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/aarch64/lib
@@ -254,7 +254,7 @@
Console
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/arm/lib
@@ -283,7 +283,7 @@
true
true
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/x86/lib
@@ -313,7 +313,7 @@
true
true
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/x86_64/lib
@@ -343,7 +343,7 @@
true
true
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/aarch64/lib
@@ -373,7 +373,7 @@
true
true
true
- mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)
+ winhttp.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Ws2_32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dsound.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies)
/ignore:4049 /ignore:4217 %(AdditionalOptions)
../ffmpeg/Windows/arm/lib