refactor: GTK favicon lookup improvements (#4278)

This commit is contained in:
Charles Kerr 2022-11-29 18:09:32 -06:00 committed by GitHub
parent f2418f6111
commit 22d12aedc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 17 deletions

View File

@ -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 });
}
}

View File

@ -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));

View File

@ -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;

View File

@ -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);