refactor: GTK favicon lookup improvements (#4278)
This commit is contained in:
parent
f2418f6111
commit
22d12aedc5
|
@ -7,6 +7,7 @@
|
|||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <glib/gstdio.h> /* g_remove() */
|
||||
|
||||
|
@ -19,10 +20,13 @@
|
|||
#include "FaviconCache.h"
|
||||
#include "Utils.h" /* gtr_get_host_from_url() */
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::array<char const*, 4> const image_types = { "ico", "png", "gif", "jpg" };
|
||||
constexpr auto TimeoutSecs = 15s;
|
||||
constexpr auto ImageTypes = std::array<std::string_view, 4>{ "ico"sv, "png"sv, "gif"sv, "jpg"sv };
|
||||
|
||||
struct favicon_data
|
||||
{
|
||||
|
@ -31,11 +35,12 @@ struct favicon_data
|
|||
std::string host;
|
||||
std::string contents;
|
||||
size_t type = 0;
|
||||
long code = 0;
|
||||
};
|
||||
|
||||
Glib::ustring get_url(std::string const& host, size_t image_type)
|
||||
{
|
||||
return fmt::format("http://{}/favicon.{}", host, image_types.at(image_type));
|
||||
return fmt::format("http://{}/favicon.{}", host, ImageTypes.at(image_type));
|
||||
}
|
||||
|
||||
std::string favicon_get_cache_dir()
|
||||
|
@ -88,12 +93,12 @@ bool favicon_web_done_idle_cb(std::unique_ptr<favicon_data> fav)
|
|||
pixbuf = favicon_load_from_cache(fav->host);
|
||||
}
|
||||
|
||||
if (pixbuf == nullptr && ++fav->type < image_types.size()) /* keep trying */
|
||||
if (fav->code == 404 && pixbuf == nullptr && ++fav->type < ImageTypes.size()) /* keep trying */
|
||||
{
|
||||
fav->contents.clear();
|
||||
auto* const session = fav->session;
|
||||
auto const next_url = get_url(fav->host, fav->type);
|
||||
tr_sessionFetch(session, { next_url.raw(), favicon_web_done_cb, fav.release() });
|
||||
tr_sessionFetch(session, { next_url.raw(), favicon_web_done_cb, fav.release(), TimeoutSecs });
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -106,6 +111,7 @@ void favicon_web_done_cb(tr_web::FetchResponse const& response)
|
|||
{
|
||||
auto* const fav = static_cast<favicon_data*>(response.user_data);
|
||||
fav->contents = response.body;
|
||||
fav->code = response.status;
|
||||
Glib::signal_idle().connect([fav]() { return favicon_web_done_idle_cb(std::unique_ptr<favicon_data>(fav)); });
|
||||
}
|
||||
|
||||
|
@ -128,8 +134,7 @@ void gtr_get_favicon(
|
|||
data->session = session;
|
||||
data->func = pixbuf_ready_func;
|
||||
data->host = host;
|
||||
|
||||
tr_sessionFetch(session, { get_url(host, 0).raw(), favicon_web_done_cb, data.release() });
|
||||
tr_sessionFetch(session, { get_url(host, 0).raw(), favicon_web_done_cb, data.release(), TimeoutSecs });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <algorithm> // std::copy_n()
|
||||
#include <cctype>
|
||||
#include <chrono>
|
||||
#include <cstdio> /* fprintf() */
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
@ -425,7 +426,7 @@ void tr_tracker_http_announce(
|
|||
auto url = tr_urlbuf{};
|
||||
announce_url_new(url, session, request);
|
||||
auto options = tr_web::FetchOptions{ url.sv(), onAnnounceDone, d };
|
||||
options.timeout_secs = 45L;
|
||||
options.timeout_secs = 45s;
|
||||
options.sndbuf = 4096;
|
||||
options.rcvbuf = 4096;
|
||||
|
||||
|
@ -697,7 +698,7 @@ void tr_tracker_http_scrape(tr_session const* session, tr_scrape_request const&
|
|||
scrape_url_new(scrape_url, request);
|
||||
tr_logAddTrace(fmt::format("Sending scrape to libcurl: '{}'", scrape_url), request.log_name);
|
||||
auto options = tr_web::FetchOptions{ scrape_url, onScrapeDone, d };
|
||||
options.timeout_secs = 30L;
|
||||
options.timeout_secs = 30s;
|
||||
options.sndbuf = 4096;
|
||||
options.rcvbuf = 4096;
|
||||
session->fetch(std::move(options));
|
||||
|
|
|
@ -409,7 +409,7 @@ public:
|
|||
(void)curl_easy_setopt(e, CURLOPT_USERAGENT, ua.c_str());
|
||||
}
|
||||
|
||||
(void)curl_easy_setopt(e, CURLOPT_TIMEOUT, task->timeoutSecs());
|
||||
(void)curl_easy_setopt(e, CURLOPT_TIMEOUT, static_cast<long>(task->timeoutSecs().count()));
|
||||
(void)curl_easy_setopt(e, CURLOPT_URL, task->url().c_str());
|
||||
(void)curl_easy_setopt(e, CURLOPT_VERBOSE, impl->curl_verbose ? 1L : 0L);
|
||||
(void)curl_easy_setopt(e, CURLOPT_WRITEDATA, task);
|
||||
|
@ -550,7 +550,8 @@ public:
|
|||
curl_easy_getinfo(e, CURLINFO_TOTAL_TIME, &total_time);
|
||||
curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &task->response.status);
|
||||
task->response.did_connect = task->response.status > 0 || req_bytes_sent > 0;
|
||||
task->response.did_timeout = task->response.status == 0 && total_time >= task->timeoutSecs();
|
||||
task->response.did_timeout = task->response.status == 0 &&
|
||||
std::chrono::duration<double>(total_time) >= task->timeoutSecs();
|
||||
curl_multi_remove_handle(multi.get(), e);
|
||||
task->done();
|
||||
delete task;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
@ -22,11 +23,11 @@ public:
|
|||
// when a fetch() finishes.
|
||||
struct FetchResponse
|
||||
{
|
||||
long status; // http server response, e.g. 200
|
||||
long status = 0; // http server response, e.g. 200
|
||||
std::string body;
|
||||
bool did_connect;
|
||||
bool did_timeout;
|
||||
void* user_data;
|
||||
bool did_connect = false;
|
||||
bool did_timeout = false;
|
||||
void* user_data = nullptr;
|
||||
};
|
||||
|
||||
// Callback to invoke when fetch() is done
|
||||
|
@ -42,10 +43,15 @@ public:
|
|||
V6,
|
||||
};
|
||||
|
||||
FetchOptions(std::string_view url_in, FetchDoneFunc&& done_func_in, void* done_func_user_data_in)
|
||||
FetchOptions(
|
||||
std::string_view url_in,
|
||||
FetchDoneFunc&& done_func_in,
|
||||
void* done_func_user_data_in,
|
||||
std::chrono::seconds timeout_secs_in = DefaultTimeoutSecs)
|
||||
: url{ url_in }
|
||||
, done_func{ std::move(done_func_in) }
|
||||
, done_func_user_data{ done_func_user_data_in }
|
||||
, timeout_secs{ timeout_secs_in }
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -73,7 +79,7 @@ public:
|
|||
std::optional<int> rcvbuf;
|
||||
|
||||
// Maximum time to wait before timeout
|
||||
int timeout_secs = DefaultTimeoutSecs;
|
||||
std::chrono::seconds timeout_secs = DefaultTimeoutSecs;
|
||||
|
||||
// If provided, this buffer will be used to hold the response body.
|
||||
// Provided for webseeds, which need to set low-level callbacks on
|
||||
|
@ -83,7 +89,7 @@ public:
|
|||
// IP protocol to use when making the request
|
||||
IPProtocol ip_proto = IPProtocol::ANY;
|
||||
|
||||
static constexpr int DefaultTimeoutSecs = 120;
|
||||
static auto inline constexpr DefaultTimeoutSecs = std::chrono::seconds{ 120 };
|
||||
};
|
||||
|
||||
void fetch(FetchOptions&& options);
|
||||
|
|
Loading…
Reference in New Issue