audacia/libraries/lib-network-manager/curl/CurlHandleManager.h

128 lines
3.0 KiB
C++

/*!********************************************************************
Audacity: A Digital Audio Editor
@file CurlHandleManager.h
@brief Declare a class responsible for reuse of CURL hanldes.
Dmitry Vedenko
**********************************************************************/
#pragma once
#include <string>
#include <chrono>
#include <vector>
#include <mutex>
#include <curl/curl.h>
#include "CurlStringList.h"
#include "../IResponseFactory.h"
#include "../CookiesList.h"
#include "../HeadersList.h"
namespace audacity
{
namespace network_manager
{
class CurlHandleManager final
{
public:
class Handle final
{
friend class CurlHandleManager;
Handle (CurlHandleManager* owner, CURL* handle, RequestVerb verb, std::string url) noexcept;
public:
Handle (Handle&& rhs) noexcept;
~Handle () noexcept;
Handle& operator = (Handle&& rhs) noexcept;
template<typename... Args>
CURLcode setOption (CURLoption option, Args... value) noexcept
{
return curl_easy_setopt (mHandle, option, value...);
}
CURLcode setOption (CURLoption option, const std::string& value) noexcept;
CURLcode appendCookie (const Cookie& cookie) noexcept;
CURLcode appendCookies (const CookiesList& cookie) noexcept;
void appendHeader (const Header& header);
void appendHeaders (const HeadersList& headers);
struct Result final
{
CURLcode Code;
std::string Message;
};
Result perform ();
void markKeepAlive ();
bool isHandleFromCache () const noexcept;
unsigned getHTTPCode () const noexcept;
void reset () noexcept;
private:
CURL* mHandle { nullptr };
CurlHandleManager* mOwner { nullptr };
RequestVerb mVerb;
std::string mUrl;
CurlStringList mHeaders;
bool mUserAgentSet { false };
bool mReuse { false };
bool mHandleFromCache { false };
};
CurlHandleManager ();
~CurlHandleManager ();
void setProxy (std::string proxy);
Handle getHandle (RequestVerb verb, const std::string& url);
private:
using RequestClock = std::chrono::steady_clock;
using RequestTimePoint = RequestClock::time_point;
static constexpr std::chrono::milliseconds KEEP_ALIVE_IDLE { std::chrono::seconds (120) };
static constexpr std::chrono::milliseconds KEEP_ALIVE_PROBE { std::chrono::seconds (60) };
struct CachedHandle final
{
RequestVerb Verb;
std::string SchemeAndDomain;
CURL* Handle { nullptr };
RequestTimePoint RequestTime;
};
std::string getUserAgent () const;
CURL* getCurlHandleFromCache (RequestVerb verb, const std::string& url);
void cacheHandle (Handle& handle);
void cleanupHandlesCache ();
static std::string GetSchemeAndDomain (const std::string& url);
std::string mProxy;
std::string mUserAgent;
std::mutex mHandleCacheLock;
std::vector<CachedHandle> mHandleCache;
};
}
}