mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 23:55:40 +00:00
HTTPDownloader: Fix user agent sending on Windows/Android
This commit is contained in:
parent
251043f11a
commit
d41b5be908
|
@ -19,16 +19,16 @@ AndroidHTTPDownloader::~AndroidHTTPDownloader()
|
||||||
env->DeleteGlobalRef(m_URLDownloader_class);
|
env->DeleteGlobalRef(m_URLDownloader_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<HTTPDownloader> HTTPDownloader::Create()
|
std::unique_ptr<HTTPDownloader> HTTPDownloader::Create(const char* user_agent)
|
||||||
{
|
{
|
||||||
std::unique_ptr<AndroidHTTPDownloader> instance(std::make_unique<AndroidHTTPDownloader>());
|
std::unique_ptr<AndroidHTTPDownloader> instance(std::make_unique<AndroidHTTPDownloader>());
|
||||||
if (!instance->Initialize())
|
if (!instance->Initialize(user_agent))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidHTTPDownloader::Initialize()
|
bool AndroidHTTPDownloader::Initialize(const char* user_agent)
|
||||||
{
|
{
|
||||||
JNIEnv* env = AndroidHelpers::GetJNIEnv();
|
JNIEnv* env = AndroidHelpers::GetJNIEnv();
|
||||||
jclass klass = env->FindClass("com/github/stenzek/duckstation/URLDownloader");
|
jclass klass = env->FindClass("com/github/stenzek/duckstation/URLDownloader");
|
||||||
|
@ -39,7 +39,7 @@ bool AndroidHTTPDownloader::Initialize()
|
||||||
if (!m_URLDownloader_class)
|
if (!m_URLDownloader_class)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_URLDownloader_constructor = env->GetMethodID(klass, "<init>", "()V");
|
m_URLDownloader_constructor = env->GetMethodID(klass, "<init>", "(Ljava/lang/String;)V");
|
||||||
m_URLDownloader_get = env->GetMethodID(klass, "get", "(Ljava/lang/String;)Z");
|
m_URLDownloader_get = env->GetMethodID(klass, "get", "(Ljava/lang/String;)Z");
|
||||||
m_URLDownloader_post = env->GetMethodID(klass, "post", "(Ljava/lang/String;[B)Z");
|
m_URLDownloader_post = env->GetMethodID(klass, "post", "(Ljava/lang/String;[B)Z");
|
||||||
m_URLDownloader_getStatusCode = env->GetMethodID(klass, "getStatusCode", "()I");
|
m_URLDownloader_getStatusCode = env->GetMethodID(klass, "getStatusCode", "()I");
|
||||||
|
@ -50,6 +50,7 @@ bool AndroidHTTPDownloader::Initialize()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_user_agent = user_agent;
|
||||||
m_thread_pool = std::make_unique<cb::ThreadPool>(m_max_active_requests);
|
m_thread_pool = std::make_unique<cb::ThreadPool>(m_max_active_requests);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -68,8 +69,10 @@ void AndroidHTTPDownloader::ProcessRequest(Request* req)
|
||||||
JNIEnv* env;
|
JNIEnv* env;
|
||||||
if (AndroidHelpers::GetJavaVM()->AttachCurrentThread(&env, nullptr) == JNI_OK)
|
if (AndroidHelpers::GetJavaVM()->AttachCurrentThread(&env, nullptr) == JNI_OK)
|
||||||
{
|
{
|
||||||
jobject obj = env->NewObject(m_URLDownloader_class, m_URLDownloader_constructor);
|
|
||||||
jstring url_string = env->NewStringUTF(req->url.c_str());
|
jstring url_string = env->NewStringUTF(req->url.c_str());
|
||||||
|
jstring user_agent_string = env->NewStringUTF(m_user_agent.c_str());
|
||||||
|
|
||||||
|
jobject obj = env->NewObject(m_URLDownloader_class, m_URLDownloader_constructor, user_agent_string);
|
||||||
jboolean result;
|
jboolean result;
|
||||||
if (req->post_data.empty())
|
if (req->post_data.empty())
|
||||||
{
|
{
|
||||||
|
@ -85,6 +88,7 @@ void AndroidHTTPDownloader::ProcessRequest(Request* req)
|
||||||
}
|
}
|
||||||
|
|
||||||
env->DeleteLocalRef(url_string);
|
env->DeleteLocalRef(url_string);
|
||||||
|
env->DeleteLocalRef(user_agent_string);
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@ public:
|
||||||
AndroidHTTPDownloader();
|
AndroidHTTPDownloader();
|
||||||
~AndroidHTTPDownloader() override;
|
~AndroidHTTPDownloader() override;
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize(const char* user_agent);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Request* InternalCreateRequest() override;
|
Request* InternalCreateRequest() override;
|
||||||
|
@ -30,6 +30,7 @@ private:
|
||||||
|
|
||||||
void ProcessRequest(Request* req);
|
void ProcessRequest(Request* req);
|
||||||
|
|
||||||
|
std::string m_user_agent;
|
||||||
std::unique_ptr<cb::ThreadPool> m_thread_pool;
|
std::unique_ptr<cb::ThreadPool> m_thread_pool;
|
||||||
std::mutex m_cancel_mutex;
|
std::mutex m_cancel_mutex;
|
||||||
|
|
||||||
|
|
|
@ -15,17 +15,21 @@ import java.net.URL;
|
||||||
public class URLDownloader {
|
public class URLDownloader {
|
||||||
private int statusCode = -1;
|
private int statusCode = -1;
|
||||||
private byte[] data = null;
|
private byte[] data = null;
|
||||||
|
private final String userAgent;
|
||||||
|
|
||||||
public URLDownloader() {
|
public URLDownloader(String userAgent) {
|
||||||
|
this.userAgent = userAgent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static private HttpURLConnection getConnection(String url) {
|
private HttpURLConnection getConnection(String url) {
|
||||||
try {
|
try {
|
||||||
final URL parsedUrl = new URL(url);
|
final URL parsedUrl = new URL(url);
|
||||||
HttpURLConnection connection = (HttpURLConnection) parsedUrl.openConnection();
|
HttpURLConnection connection = (HttpURLConnection) parsedUrl.openConnection();
|
||||||
if (connection == null)
|
if (connection == null)
|
||||||
throw new RuntimeException(String.format("openConnection(%s) returned null", url));
|
throw new RuntimeException(String.format("openConnection(%s) returned null", url));
|
||||||
|
|
||||||
|
if (userAgent != null)
|
||||||
|
connection.addRequestProperty("User-Agent", userAgent);
|
||||||
return connection;
|
return connection;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
@ -213,14 +213,13 @@ static std::string GetUserAgent()
|
||||||
|
|
||||||
bool Initialize(bool test_mode, bool use_first_disc_from_playlist, bool enable_rich_presence, bool challenge_mode)
|
bool Initialize(bool test_mode, bool use_first_disc_from_playlist, bool enable_rich_presence, bool challenge_mode)
|
||||||
{
|
{
|
||||||
s_http_downloader = FrontendCommon::HTTPDownloader::Create();
|
s_http_downloader = FrontendCommon::HTTPDownloader::Create(GetUserAgent().c_str());
|
||||||
if (!s_http_downloader)
|
if (!s_http_downloader)
|
||||||
{
|
{
|
||||||
Log_ErrorPrint("Failed to create HTTP downloader, cannot use cheevos");
|
Log_ErrorPrint("Failed to create HTTP downloader, cannot use cheevos");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_http_downloader->SetUserAgent(GetUserAgent());
|
|
||||||
g_active = true;
|
g_active = true;
|
||||||
g_challenge_mode = challenge_mode;
|
g_challenge_mode = challenge_mode;
|
||||||
s_test_mode = test_mode;
|
s_test_mode = test_mode;
|
||||||
|
@ -408,11 +407,11 @@ bool Login(const char* username, const char* password)
|
||||||
|
|
||||||
// create a temporary downloader if we're not initialized
|
// create a temporary downloader if we're not initialized
|
||||||
Assert(!g_active);
|
Assert(!g_active);
|
||||||
std::unique_ptr<FrontendCommon::HTTPDownloader> http_downloader = FrontendCommon::HTTPDownloader::Create();
|
std::unique_ptr<FrontendCommon::HTTPDownloader> http_downloader =
|
||||||
|
FrontendCommon::HTTPDownloader::Create(GetUserAgent().c_str());
|
||||||
if (!http_downloader)
|
if (!http_downloader)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
http_downloader->SetUserAgent(GetUserAgent());
|
|
||||||
SendLogin(username, password, http_downloader.get(), LoginCallback);
|
SendLogin(username, password, http_downloader.get(), LoginCallback);
|
||||||
http_downloader->WaitForAllRequests();
|
http_downloader->WaitForAllRequests();
|
||||||
|
|
||||||
|
|
|
@ -4,26 +4,21 @@
|
||||||
#include "common/timer.h"
|
#include "common/timer.h"
|
||||||
Log_SetChannel(HTTPDownloader);
|
Log_SetChannel(HTTPDownloader);
|
||||||
|
|
||||||
static constexpr char DEFAULT_USER_AGENT[] =
|
|
||||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0";
|
|
||||||
static constexpr float DEFAULT_TIMEOUT_IN_SECONDS = 30;
|
static constexpr float DEFAULT_TIMEOUT_IN_SECONDS = 30;
|
||||||
static constexpr u32 DEFAULT_MAX_ACTIVE_REQUESTS = 4;
|
static constexpr u32 DEFAULT_MAX_ACTIVE_REQUESTS = 4;
|
||||||
|
|
||||||
namespace FrontendCommon {
|
namespace FrontendCommon {
|
||||||
|
|
||||||
|
const char HTTPDownloader::DEFAULT_USER_AGENT[] =
|
||||||
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0";
|
||||||
|
|
||||||
HTTPDownloader::HTTPDownloader()
|
HTTPDownloader::HTTPDownloader()
|
||||||
: m_user_agent(DEFAULT_USER_AGENT), m_timeout(DEFAULT_TIMEOUT_IN_SECONDS),
|
: m_timeout(DEFAULT_TIMEOUT_IN_SECONDS), m_max_active_requests(DEFAULT_MAX_ACTIVE_REQUESTS)
|
||||||
m_max_active_requests(DEFAULT_MAX_ACTIVE_REQUESTS)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTPDownloader::~HTTPDownloader() = default;
|
HTTPDownloader::~HTTPDownloader() = default;
|
||||||
|
|
||||||
void HTTPDownloader::SetUserAgent(std::string name)
|
|
||||||
{
|
|
||||||
m_user_agent = std::move(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HTTPDownloader::SetTimeout(float timeout)
|
void HTTPDownloader::SetTimeout(float timeout)
|
||||||
{
|
{
|
||||||
m_timeout = timeout;
|
m_timeout = timeout;
|
||||||
|
|
|
@ -52,9 +52,8 @@ public:
|
||||||
HTTPDownloader();
|
HTTPDownloader();
|
||||||
virtual ~HTTPDownloader();
|
virtual ~HTTPDownloader();
|
||||||
|
|
||||||
static std::unique_ptr<HTTPDownloader> Create();
|
static std::unique_ptr<HTTPDownloader> Create(const char* user_agent = DEFAULT_USER_AGENT);
|
||||||
|
|
||||||
void SetUserAgent(std::string name);
|
|
||||||
void SetTimeout(float timeout);
|
void SetTimeout(float timeout);
|
||||||
void SetMaxActiveRequests(u32 max_active_requests);
|
void SetMaxActiveRequests(u32 max_active_requests);
|
||||||
|
|
||||||
|
@ -63,6 +62,8 @@ public:
|
||||||
void PollRequests();
|
void PollRequests();
|
||||||
void WaitForAllRequests();
|
void WaitForAllRequests();
|
||||||
|
|
||||||
|
static const char DEFAULT_USER_AGENT[];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Request* InternalCreateRequest() = 0;
|
virtual Request* InternalCreateRequest() = 0;
|
||||||
virtual void InternalPollRequests() = 0;
|
virtual void InternalPollRequests() = 0;
|
||||||
|
|
|
@ -13,10 +13,10 @@ HTTPDownloaderCurl::HTTPDownloaderCurl() : HTTPDownloader() {}
|
||||||
|
|
||||||
HTTPDownloaderCurl::~HTTPDownloaderCurl() = default;
|
HTTPDownloaderCurl::~HTTPDownloaderCurl() = default;
|
||||||
|
|
||||||
std::unique_ptr<HTTPDownloader> HTTPDownloader::Create()
|
std::unique_ptr<HTTPDownloader> HTTPDownloader::Create(const char* user_agent)
|
||||||
{
|
{
|
||||||
std::unique_ptr<HTTPDownloaderCurl> instance(std::make_unique<HTTPDownloaderCurl>());
|
std::unique_ptr<HTTPDownloaderCurl> instance(std::make_unique<HTTPDownloaderCurl>());
|
||||||
if (!instance->Initialize())
|
if (!instance->Initialize(user_agent))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
|
@ -25,7 +25,7 @@ std::unique_ptr<HTTPDownloader> HTTPDownloader::Create()
|
||||||
static bool s_curl_initialized = false;
|
static bool s_curl_initialized = false;
|
||||||
static std::once_flag s_curl_initialized_once_flag;
|
static std::once_flag s_curl_initialized_once_flag;
|
||||||
|
|
||||||
bool HTTPDownloaderCurl::Initialize()
|
bool HTTPDownloaderCurl::Initialize(const char* user_agent)
|
||||||
{
|
{
|
||||||
if (!s_curl_initialized)
|
if (!s_curl_initialized)
|
||||||
{
|
{
|
||||||
|
@ -45,6 +45,8 @@ bool HTTPDownloaderCurl::Initialize()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_user_agent = user_agent;
|
||||||
m_thread_pool = std::make_unique<cb::ThreadPool>(m_max_active_requests);
|
m_thread_pool = std::make_unique<cb::ThreadPool>(m_max_active_requests);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -75,8 +77,8 @@ void HTTPDownloaderCurl::ProcessRequest(Request* req)
|
||||||
long response_code = 0;
|
long response_code = 0;
|
||||||
curl_easy_getinfo(req->handle, CURLINFO_RESPONSE_CODE, &response_code);
|
curl_easy_getinfo(req->handle, CURLINFO_RESPONSE_CODE, &response_code);
|
||||||
req->status_code = static_cast<s32>(response_code);
|
req->status_code = static_cast<s32>(response_code);
|
||||||
Log_DevPrintf("Request for '%s' returned status code %d and %zu bytes",
|
Log_DevPrintf("Request for '%s' returned status code %d and %zu bytes", req->url.c_str(), req->status_code,
|
||||||
req->url.c_str(), req->status_code, req->data.size());
|
req->data.size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@ public:
|
||||||
HTTPDownloaderCurl();
|
HTTPDownloaderCurl();
|
||||||
~HTTPDownloaderCurl() override;
|
~HTTPDownloaderCurl() override;
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize(const char* user_agent);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Request* InternalCreateRequest() override;
|
Request* InternalCreateRequest() override;
|
||||||
|
@ -32,6 +32,7 @@ private:
|
||||||
static size_t WriteCallback(char* ptr, size_t size, size_t nmemb, void* userdata);
|
static size_t WriteCallback(char* ptr, size_t size, size_t nmemb, void* userdata);
|
||||||
void ProcessRequest(Request* req);
|
void ProcessRequest(Request* req);
|
||||||
|
|
||||||
|
std::string m_user_agent;
|
||||||
std::unique_ptr<cb::ThreadPool> m_thread_pool;
|
std::unique_ptr<cb::ThreadPool> m_thread_pool;
|
||||||
std::mutex m_cancel_mutex;
|
std::mutex m_cancel_mutex;
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,16 +22,16 @@ HTTPDownloaderWinHttp::~HTTPDownloaderWinHttp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<HTTPDownloader> HTTPDownloader::Create()
|
std::unique_ptr<HTTPDownloader> HTTPDownloader::Create(const char* user_agent)
|
||||||
{
|
{
|
||||||
std::unique_ptr<HTTPDownloaderWinHttp> instance(std::make_unique<HTTPDownloaderWinHttp>());
|
std::unique_ptr<HTTPDownloaderWinHttp> instance(std::make_unique<HTTPDownloaderWinHttp>());
|
||||||
if (!instance->Initialize())
|
if (!instance->Initialize(user_agent))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HTTPDownloaderWinHttp::Initialize()
|
bool HTTPDownloaderWinHttp::Initialize(const char* user_agent)
|
||||||
{
|
{
|
||||||
// WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY is not supported before Win8.1.
|
// WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY is not supported before Win8.1.
|
||||||
const DWORD dwAccessType =
|
const DWORD dwAccessType =
|
||||||
|
|
|
@ -13,7 +13,7 @@ public:
|
||||||
HTTPDownloaderWinHttp();
|
HTTPDownloaderWinHttp();
|
||||||
~HTTPDownloaderWinHttp() override;
|
~HTTPDownloaderWinHttp() override;
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize(const char* user_agent);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Request* InternalCreateRequest() override;
|
Request* InternalCreateRequest() override;
|
||||||
|
|
Loading…
Reference in a new issue