Skip to content

Commit

Permalink
booru/site: Add setting to limit number of active connections
Browse files Browse the repository at this point in the history
Fixes issues with konachan.com
  • Loading branch information
ahodesuka committed Dec 5, 2017
1 parent 8f22816 commit e090380
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 12 deletions.
18 changes: 12 additions & 6 deletions src/booru/imagefetcher.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "imagefetcher.h"
using namespace AhoViewer::Booru;

#include <algorithm>

int ImageFetcher::socket_cb(CURL*, curl_socket_t s, int action, void *userp, void *sockp)
{
ImageFetcher *self = static_cast<ImageFetcher*>(userp);
Expand Down Expand Up @@ -73,12 +75,6 @@ ImageFetcher::ImageFetcher()
curl_multi_setopt(m_MultiHandle, CURLMOPT_SOCKETDATA, this);
curl_multi_setopt(m_MultiHandle, CURLMOPT_TIMERFUNCTION, &ImageFetcher::timer_cb);
curl_multi_setopt(m_MultiHandle, CURLMOPT_TIMERDATA, this);

// Konachan seems to throw a 503 error if you have too many connections
// This is also inderectly controlled by the image list's threadpool size
// and the cache size setting
// TODO: Per-site setting for this
// curl_multi_setopt(m_MultiHandle, CURLMOPT_MAX_TOTAL_CONNECTIONS, 8);
}

ImageFetcher::~ImageFetcher()
Expand Down Expand Up @@ -123,6 +119,16 @@ void ImageFetcher::add_handle(Curler *curler)
curler->m_StartTime = std::chrono::steady_clock::now();
}

// Konachan seems to throw a 503 error if you have too many connections
// This is also indirectly controlled by the image list's threadpool size
// and the cache size setting. It's only changable inside the cfg file.
// 0 = unlimited, must be at least 2
void ImageFetcher::set_max_connections(unsigned int n)
{
n = n == 1 ? 2 : n;
curl_multi_setopt(m_MultiHandle, CURLMOPT_MAX_HOST_CONNECTIONS, n);
}

void ImageFetcher::remove_handle(Curler *curler)
{
if (!curler)
Expand Down
2 changes: 2 additions & 0 deletions src/booru/imagefetcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ namespace AhoViewer
void shutdown();

void add_handle(Curler *curler);

void set_max_connections(unsigned int n);
private:
struct SockInfo
{
Expand Down
1 change: 1 addition & 0 deletions src/booru/page.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ void Page::search(const std::shared_ptr<Site> &site)
m_Page = 1;
m_LastPage = false;
m_SearchTags = m_Tags;
m_ImageFetcher->set_max_connections(m_Site->get_max_connections());

// Trim leading and trailing whitespace for tab label
// and m_SearchTags which is used to display tags in other places
Expand Down
7 changes: 4 additions & 3 deletions src/booru/site.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ struct _shared_site : public Site
};

std::shared_ptr<Site> Site::create(const std::string &name, const std::string &url, const Type type,
const std::string &user, const std::string &pass)
const std::string &user, const std::string &pass, const unsigned int max_cons)
{
Type t = type == Type::UNKNOWN ? get_type_from_url(url) : type;

if (t != Type::UNKNOWN)
return std::make_shared<_shared_site>(name, url, t, user, pass);
return std::make_shared<_shared_site>(name, url, t, user, pass, max_cons);

return nullptr;
}
Expand Down Expand Up @@ -176,7 +176,7 @@ void Site::share_unlock_cb(CURL *c, curl_lock_data data, void *userp)
}

Site::Site(const std::string &name, const std::string &url, const Type type,
const std::string &user, const std::string &pass)
const std::string &user, const std::string &pass, const unsigned int max_cons)
: m_Name(name),
m_Url(url),
m_Username(user),
Expand All @@ -187,6 +187,7 @@ Site::Site(const std::string &name, const std::string &url, const Type type,
m_Type(type),
m_NewAccount(false),
m_CookieTS(0),
m_MaxConnections(max_cons),
m_ShareHandle(curl_share_init())
{
curl_share_setopt(m_ShareHandle, CURLSHOPT_LOCKFUNC, &Site::share_lock_cb);
Expand Down
8 changes: 6 additions & 2 deletions src/booru/site.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ namespace AhoViewer
const std::string &url,
const Type type = Type::UNKNOWN,
const std::string &user = "",
const std::string &pass = "");
const std::string &pass = "",
const unsigned int max_cons = 0);
static const Glib::RefPtr<Gdk::Pixbuf>& get_missing_pixbuf();

#ifdef HAVE_LIBSECRET
Expand Down Expand Up @@ -76,6 +77,7 @@ namespace AhoViewer
std::string get_cookie();
void cleanup_cookie() const;

unsigned int get_max_connections() const { return m_MaxConnections; }
CURLSH* get_share_handle() const { return m_ShareHandle; }

Glib::RefPtr<Gdk::Pixbuf> get_icon_pixbuf(const bool update = false);
Expand All @@ -91,7 +93,8 @@ namespace AhoViewer
const std::string &url,
const Type type,
const std::string &user,
const std::string &pass);
const std::string &pass,
const unsigned int max_cons);
private:
static Type get_type_from_url(const std::string &url);

Expand All @@ -113,6 +116,7 @@ namespace AhoViewer
bool m_NewAccount;
uint64_t m_CookieTS;
std::set<std::string> m_Tags;
unsigned int m_MaxConnections;
CURLSH *m_ShareHandle;
std::map<curl_lock_data, Mutex> m_MutexMap;
std::map<CURL*, ReaderMap> m_ReaderMap;
Expand Down
7 changes: 6 additions & 1 deletion src/settings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,16 @@ std::vector<std::shared_ptr<Site>>& SettingsManager::get_sites()
url = s.exists("url") ? s["url"] : "",
username = s.exists("username") ? s["username"] : "",
password = s.exists("password") ? s["password"] : "";
unsigned int max_cons = 0;
s.lookupValue("max_connections", max_cons);
max_cons = max_cons == 1 ? 2 : max_cons;
m_Sites.push_back(
Site::create(name,
url,
static_cast<Site::Type>(static_cast<int>(s["type"])),
username,
password));
password,
max_cons));
}

return m_Sites;
Expand Down Expand Up @@ -435,6 +439,7 @@ void SettingsManager::save_sites()
#ifndef HAVE_LIBSECRET
set("password", s->get_password(), Setting::TypeString, site);
#endif // !HAVE_LIBSECRET
set("max_connections", static_cast<int>(s->get_max_connections()), Setting::TypeInt, site);
s->cleanup_cookie();
}
}

0 comments on commit e090380

Please sign in to comment.