mirror of https://github.com/RPCS3/rpcs3.git
curl: add verbose logging
and really verbose logging i you use --verbose-curl
This commit is contained in:
parent
b736691bde
commit
2359ba9aed
|
@ -242,6 +242,7 @@ constexpr auto arg_installfw = "installfw";
|
||||||
constexpr auto arg_installpkg = "installpkg";
|
constexpr auto arg_installpkg = "installpkg";
|
||||||
constexpr auto arg_commit_db = "get-commit-db";
|
constexpr auto arg_commit_db = "get-commit-db";
|
||||||
constexpr auto arg_timer = "high-res-timer";
|
constexpr auto arg_timer = "high-res-timer";
|
||||||
|
constexpr auto arg_verbose_curl = "verbose-curl";
|
||||||
|
|
||||||
int find_arg(std::string arg, int& argc, char* argv[])
|
int find_arg(std::string arg, int& argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
@ -536,12 +537,17 @@ int main(int argc, char** argv)
|
||||||
parser.addOption(QCommandLineOption(arg_updating, "For internal usage."));
|
parser.addOption(QCommandLineOption(arg_updating, "For internal usage."));
|
||||||
parser.addOption(QCommandLineOption(arg_commit_db, "Update commits.lst cache. Optional arguments: <path> <sha>"));
|
parser.addOption(QCommandLineOption(arg_commit_db, "Update commits.lst cache. Optional arguments: <path> <sha>"));
|
||||||
parser.addOption(QCommandLineOption(arg_timer, "Enable high resolution timer for better performance (windows)", "enabled", "1"));
|
parser.addOption(QCommandLineOption(arg_timer, "Enable high resolution timer for better performance (windows)", "enabled", "1"));
|
||||||
|
parser.addOption(QCommandLineOption(arg_verbose_curl, "Enable verbose curl logging."));
|
||||||
parser.process(app->arguments());
|
parser.process(app->arguments());
|
||||||
|
|
||||||
// Don't start up the full rpcs3 gui if we just want the version or help.
|
// Don't start up the full rpcs3 gui if we just want the version or help.
|
||||||
if (parser.isSet(version_option) || parser.isSet(help_option))
|
if (parser.isSet(version_option) || parser.isSet(help_option))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// Set curl to verbose if needed
|
||||||
|
rpcs3::curl::s_curl_verbose = parser.isSet(arg_verbose_curl);
|
||||||
|
|
||||||
|
// Handle update of commit database
|
||||||
if (parser.isSet(arg_commit_db))
|
if (parser.isSet(arg_commit_db))
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -619,7 +625,7 @@ int main(int argc, char** argv)
|
||||||
QByteArray buf;
|
QByteArray buf;
|
||||||
|
|
||||||
// CURL handle to work with GitHub API
|
// CURL handle to work with GitHub API
|
||||||
curl_handle curl;
|
rpcs3::curl::curl_handle curl;
|
||||||
|
|
||||||
struct curl_slist* hhdr{};
|
struct curl_slist* hhdr{};
|
||||||
hhdr = curl_slist_append(hhdr, "Accept: application/vnd.github.v3+json");
|
hhdr = curl_slist_append(hhdr, "Accept: application/vnd.github.v3+json");
|
||||||
|
@ -657,10 +663,14 @@ int main(int argc, char** argv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset error buffer before we call curl_easy_perform
|
||||||
|
curl.reset_error_buffer();
|
||||||
|
|
||||||
err = curl_easy_perform(curl);
|
err = curl_easy_perform(curl);
|
||||||
if (err != CURLE_OK)
|
if (err != CURLE_OK)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Curl error:\n%s", curl_easy_strerror(err));
|
const std::string error_string = curl.get_verbose_error(err);
|
||||||
|
fprintf(stderr, "curl_easy_perform(): %s", error_string.c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,29 @@
|
||||||
|
|
||||||
LOG_CHANNEL(network_log, "NET");
|
LOG_CHANNEL(network_log, "NET");
|
||||||
|
|
||||||
|
namespace rpcs3::curl
|
||||||
|
{
|
||||||
|
|
||||||
curl_handle::curl_handle(QObject* parent) : QObject(parent)
|
curl_handle::curl_handle(QObject* parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
|
reset_error_buffer();
|
||||||
|
|
||||||
m_curl = curl_easy_init();
|
m_curl = curl_easy_init();
|
||||||
|
|
||||||
|
CURLcode err = curl_easy_setopt(m_curl, CURLOPT_ERRORBUFFER, m_error_buffer.data());
|
||||||
|
if (err != CURLE_OK) network_log.error("curl_easy_setopt(CURLOPT_ERRORBUFFER): %s", curl_easy_strerror(err));
|
||||||
|
|
||||||
|
m_uses_error_buffer = err == CURLE_OK;
|
||||||
|
|
||||||
|
err = curl_easy_setopt(m_curl, CURLOPT_VERBOSE, s_curl_verbose);
|
||||||
|
if (err != CURLE_OK) network_log.error("curl_easy_setopt(CURLOPT_VERBOSE, %d): %s", s_curl_verbose, curl_easy_strerror(err));
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// This shouldn't be needed on linux
|
// This shouldn't be needed on linux
|
||||||
const std::string path_to_cert = rpcs3::utils::get_exe_dir() + "cacert.pem";
|
const std::string path_to_cert = rpcs3::utils::get_exe_dir() + "cacert.pem";
|
||||||
const std::string ansi_path = utf8_path_to_ansi_path(path_to_cert);
|
const std::string ansi_path = utf8_path_to_ansi_path(path_to_cert);
|
||||||
|
|
||||||
const CURLcode err = curl_easy_setopt(m_curl, CURLOPT_CAINFO, ansi_path.data());
|
err = curl_easy_setopt(m_curl, CURLOPT_CAINFO, ansi_path.data());
|
||||||
if (err != CURLE_OK) network_log.error("curl_easy_setopt(CURLOPT_CAINFO, %s) error: %s", ansi_path, curl_easy_strerror(err));
|
if (err != CURLE_OK) network_log.error("curl_easy_setopt(CURLOPT_CAINFO, %s) error: %s", ansi_path, curl_easy_strerror(err));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -31,3 +44,25 @@ CURL* curl_handle::get_curl() const
|
||||||
{
|
{
|
||||||
return m_curl;
|
return m_curl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void curl_handle::reset_error_buffer()
|
||||||
|
{
|
||||||
|
ensure(m_error_buffer.size() == CURL_ERROR_SIZE);
|
||||||
|
m_error_buffer[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string curl_handle::get_verbose_error(CURLcode code)
|
||||||
|
{
|
||||||
|
if (m_uses_error_buffer)
|
||||||
|
{
|
||||||
|
ensure(m_error_buffer.size() == CURL_ERROR_SIZE);
|
||||||
|
if (m_error_buffer[0])
|
||||||
|
{
|
||||||
|
return fmt::format("Curl error (%d): %s\nDetails: %s", static_cast<int>(code), curl_easy_strerror(code), m_error_buffer.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt::format("Curl error (%d): %s", static_cast<int>(code), curl_easy_strerror(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#ifndef CURL_STATICLIB
|
#ifndef CURL_STATICLIB
|
||||||
|
@ -7,11 +8,12 @@
|
||||||
#endif
|
#endif
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
namespace rpcs3::curl
|
||||||
|
{
|
||||||
|
static bool s_curl_verbose = false;
|
||||||
|
|
||||||
class curl_handle : public QObject
|
class curl_handle : public QObject
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
CURL* m_curl = nullptr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit curl_handle(QObject* parent = nullptr);
|
explicit curl_handle(QObject* parent = nullptr);
|
||||||
~curl_handle();
|
~curl_handle();
|
||||||
|
@ -22,4 +24,14 @@ public:
|
||||||
{
|
{
|
||||||
return get_curl();
|
return get_curl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset_error_buffer();
|
||||||
|
std::string get_verbose_error(CURLcode code);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CURL* m_curl = nullptr;
|
||||||
|
bool m_uses_error_buffer = false;
|
||||||
|
std::array<char, CURL_ERROR_SIZE> m_error_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ usz curl_write_cb_compat(char* ptr, usz /*size*/, usz nmemb, void* userdata)
|
||||||
downloader::downloader(QWidget* parent)
|
downloader::downloader(QWidget* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_parent(parent)
|
, m_parent(parent)
|
||||||
, m_curl(new curl_handle(this))
|
, m_curl(new rpcs3::curl::curl_handle(this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,12 +64,15 @@ void downloader::start(const std::string& url, bool follow_location, bool show_p
|
||||||
|
|
||||||
m_thread = QThread::create([this]
|
m_thread = QThread::create([this]
|
||||||
{
|
{
|
||||||
const auto result = curl_easy_perform(m_curl->get_curl());
|
// Reset error buffer before we call curl_easy_perform
|
||||||
|
m_curl->reset_error_buffer();
|
||||||
|
|
||||||
|
const CURLcode result = curl_easy_perform(m_curl->get_curl());
|
||||||
m_curl_success = result == CURLE_OK;
|
m_curl_success = result == CURLE_OK;
|
||||||
|
|
||||||
if (!m_curl_success && !m_curl_abort)
|
if (!m_curl_success && !m_curl_abort)
|
||||||
{
|
{
|
||||||
const std::string error = "Curl error: " + std::string{ curl_easy_strerror(result) };
|
const std::string error = fmt::format("curl_easy_perform(): %s", m_curl->get_verbose_error(result));
|
||||||
network_log.error("%s", error);
|
network_log.error("%s", error);
|
||||||
Q_EMIT signal_download_error(QString::fromStdString(error));
|
Q_EMIT signal_download_error(QString::fromStdString(error));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,14 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include "util/atomic.hpp"
|
#include "util/atomic.hpp"
|
||||||
|
|
||||||
|
namespace rpcs3
|
||||||
|
{
|
||||||
|
namespace curl
|
||||||
|
{
|
||||||
class curl_handle;
|
class curl_handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class progress_dialog;
|
class progress_dialog;
|
||||||
|
|
||||||
class downloader : public QObject
|
class downloader : public QObject
|
||||||
|
@ -35,7 +42,7 @@ Q_SIGNALS:
|
||||||
private:
|
private:
|
||||||
QWidget* m_parent = nullptr;
|
QWidget* m_parent = nullptr;
|
||||||
|
|
||||||
curl_handle* m_curl = nullptr;
|
rpcs3::curl::curl_handle* m_curl = nullptr;
|
||||||
QByteArray m_curl_buf;
|
QByteArray m_curl_buf;
|
||||||
atomic_t<bool> m_curl_abort = false;
|
atomic_t<bool> m_curl_abort = false;
|
||||||
atomic_t<bool> m_curl_success = false;
|
atomic_t<bool> m_curl_success = false;
|
||||||
|
|
Loading…
Reference in New Issue