mirror of
https://github.com/transmission/transmission
synced 2025-03-08 21:04:25 +00:00
refactor: add libtransmission::Settings (#6575)
* refactor: add libtransmission::Settings * refactor: move RPC server's settings into tr_rpc_server::Settings * build: update project.pbxproj --------- Co-authored-by: Dzmitry Neviadomski <nevack.d@gmail.com>
This commit is contained in:
parent
168d56cefc
commit
340d0d4966
7 changed files with 263 additions and 111 deletions
|
@ -448,6 +448,8 @@
|
|||
ED20B87C28589274005FA6BE /* common_defs.h in Headers */ = {isa = PBXBuildFile; fileRef = ED20B87B28589274005FA6BE /* common_defs.h */; };
|
||||
ED20B87F285892C5005FA6BE /* crc32_multipliers.h in Headers */ = {isa = PBXBuildFile; fileRef = ED20B87D285892C5005FA6BE /* crc32_multipliers.h */; };
|
||||
ED20B880285892C5005FA6BE /* crc32_tables.h in Headers */ = {isa = PBXBuildFile; fileRef = ED20B87E285892C5005FA6BE /* crc32_tables.h */; };
|
||||
ED67FB422B70FCE400D8A037 /* settings.cc in Sources */ = {isa = PBXBuildFile; fileRef = ED67FB402B70FCE400D8A037 /* settings.cc */; };
|
||||
ED67FB432B70FCE400D8A037 /* settings.h in Headers */ = {isa = PBXBuildFile; fileRef = ED67FB412B70FCE400D8A037 /* settings.h */; };
|
||||
ED86936F2ADAE34D00342B1A /* DefaultAppHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED86936E2ADAE34D00342B1A /* DefaultAppHelper.mm */; };
|
||||
ED8A163F2735A8AA000D61F9 /* peer-mgr-active-requests.h in Headers */ = {isa = PBXBuildFile; fileRef = ED8A163B2735A8AA000D61F9 /* peer-mgr-active-requests.h */; };
|
||||
ED8A16402735A8AA000D61F9 /* peer-mgr-active-requests.cc in Sources */ = {isa = PBXBuildFile; fileRef = ED8A163C2735A8AA000D61F9 /* peer-mgr-active-requests.cc */; };
|
||||
|
@ -1363,6 +1365,8 @@
|
|||
ED20B87B28589274005FA6BE /* common_defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common_defs.h; sourceTree = "<group>"; };
|
||||
ED20B87D285892C5005FA6BE /* crc32_multipliers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crc32_multipliers.h; path = lib/crc32_multipliers.h; sourceTree = "<group>"; };
|
||||
ED20B87E285892C5005FA6BE /* crc32_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crc32_tables.h; path = lib/crc32_tables.h; sourceTree = "<group>"; };
|
||||
ED67FB402B70FCE400D8A037 /* settings.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = settings.cc; sourceTree = "<group>"; };
|
||||
ED67FB412B70FCE400D8A037 /* settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings.h; sourceTree = "<group>"; };
|
||||
ED86936D2ADAE34D00342B1A /* DefaultAppHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DefaultAppHelper.h; sourceTree = "<group>"; };
|
||||
ED86936E2ADAE34D00342B1A /* DefaultAppHelper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DefaultAppHelper.mm; sourceTree = "<group>"; };
|
||||
ED8A163B2735A8AA000D61F9 /* peer-mgr-active-requests.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = "peer-mgr-active-requests.h"; sourceTree = "<group>"; };
|
||||
|
@ -1884,6 +1888,8 @@
|
|||
CCEBA596277340F6DF9F4483 /* session-alt-speeds.h */,
|
||||
D5C306568A7346FFFB8EFAD1 /* session-settings.cc */,
|
||||
D5C306568A7346FFFB8EFAD3 /* session-settings.h */,
|
||||
ED67FB402B70FCE400D8A037 /* settings.cc */,
|
||||
ED67FB412B70FCE400D8A037 /* settings.h */,
|
||||
D9057D68C13B75636539B681 /* variant-converters.cc */,
|
||||
A25D2CBB0CF4C7190096A262 /* stats.cc */,
|
||||
A25D2CBA0CF4C7190096A262 /* stats.h */,
|
||||
|
@ -2398,6 +2404,7 @@
|
|||
A29DF8BE0DB2545F00D04E5A /* verify.h in Headers */,
|
||||
C1FEE57B1C3223CC00D62832 /* watchdir.h in Headers */,
|
||||
A2AAB6650DE0D08B00E04DDA /* blocklist.h in Headers */,
|
||||
ED67FB432B70FCE400D8A037 /* settings.h in Headers */,
|
||||
A2A4E9210DE0F7E9000CE197 /* web.h in Headers */,
|
||||
A25E03E20E4015380086C225 /* tr-getopt.h in Headers */,
|
||||
A21FBBAB0EDA78C300BC3C51 /* bandwidth.h in Headers */,
|
||||
|
@ -3173,6 +3180,7 @@
|
|||
C1033E081A3279B800EF44D8 /* crypto-utils-ccrypto.cc in Sources */,
|
||||
A22CFCA80FC24ED80009BD3E /* tr-dht.cc in Sources */,
|
||||
0A6169A70FE5C9A200C66CE6 /* bitfield.cc in Sources */,
|
||||
ED67FB422B70FCE400D8A037 /* settings.cc in Sources */,
|
||||
1BB44E07B1B52E28291B4E32 /* file-piece-map.cc in Sources */,
|
||||
A25964A6106D73A800453B31 /* announcer.cc in Sources */,
|
||||
66F977825E65AD498C028BB0 /* announce-list.cc in Sources */,
|
||||
|
|
|
@ -118,6 +118,8 @@ target_sources(${TR_NAME}
|
|||
session-thread.h
|
||||
session.cc
|
||||
session.h
|
||||
settings.cc
|
||||
settings.h
|
||||
stats.cc
|
||||
stats.h
|
||||
subprocess-posix.cc
|
||||
|
|
|
@ -400,7 +400,7 @@ bool isHostnameAllowed(tr_rpc_server const* server, evhttp_request const* req)
|
|||
}
|
||||
|
||||
/* If whitelist is disabled, no restrictions. */
|
||||
if (!server->is_host_whitelist_enabled_)
|
||||
if (!server->settings_.is_host_whitelist_enabled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -460,7 +460,7 @@ bool is_authorized(tr_rpc_server const* server, char const* auth_header)
|
|||
auto decoded = std::string_view{ decoded_str };
|
||||
auto const username = tr_strv_sep(&decoded, ':');
|
||||
auto const password = decoded;
|
||||
return server->username() == username && tr_ssha1_matches(server->salted_password_, password);
|
||||
return server->username() == username && tr_ssha1_matches(server->settings().salted_password, password);
|
||||
}
|
||||
|
||||
void handle_request(struct evhttp_request* req, void* arg)
|
||||
|
@ -474,7 +474,7 @@ void handle_request(struct evhttp_request* req, void* arg)
|
|||
{
|
||||
evhttp_add_header(req->output_headers, "Server", MY_REALM);
|
||||
|
||||
if (server->is_anti_brute_force_enabled() && server->login_attempts_ >= server->anti_brute_force_limit_)
|
||||
if (server->is_anti_brute_force_enabled() && server->login_attempts_ >= server->settings().anti_brute_force_limit)
|
||||
{
|
||||
send_simple_response(req, HttpErrorForbidden);
|
||||
return;
|
||||
|
@ -659,7 +659,7 @@ void start_server(tr_rpc_server* server)
|
|||
auto const port = server->port();
|
||||
|
||||
bool const success = server->bind_address_->is_unix_addr() ?
|
||||
bindUnixSocket(base, httpd, address.c_str(), server->socket_mode_) :
|
||||
bindUnixSocket(base, httpd, address.c_str(), server->settings().socket_mode) :
|
||||
(evhttp_bind_socket(httpd, address.c_str(), port.host()) != -1);
|
||||
|
||||
auto const addr_port_str = server->bind_address_->to_string(port);
|
||||
|
@ -750,12 +750,12 @@ auto parse_whitelist(std::string_view whitelist)
|
|||
|
||||
void tr_rpc_server::set_enabled(bool is_enabled)
|
||||
{
|
||||
is_enabled_ = is_enabled;
|
||||
settings_.is_enabled = is_enabled;
|
||||
|
||||
session->run_in_session_thread(
|
||||
[this]()
|
||||
{
|
||||
if (!is_enabled_)
|
||||
if (!settings_.is_enabled)
|
||||
{
|
||||
stop_server(this);
|
||||
}
|
||||
|
@ -768,12 +768,12 @@ void tr_rpc_server::set_enabled(bool is_enabled)
|
|||
|
||||
void tr_rpc_server::set_port(tr_port port) noexcept
|
||||
{
|
||||
if (port_ == port)
|
||||
if (settings_.port == port)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
port_ = port;
|
||||
settings_.port = port;
|
||||
|
||||
if (is_enabled())
|
||||
{
|
||||
|
@ -783,35 +783,34 @@ void tr_rpc_server::set_port(tr_port port) noexcept
|
|||
|
||||
void tr_rpc_server::set_url(std::string_view url)
|
||||
{
|
||||
url_ = url;
|
||||
tr_logAddDebug(fmt::format("setting our URL to '{:s}'", url_));
|
||||
settings_.url = url;
|
||||
tr_logAddDebug(fmt::format("setting our URL to '{:s}'", url));
|
||||
}
|
||||
|
||||
void tr_rpc_server::set_whitelist(std::string_view whitelist)
|
||||
{
|
||||
this->whitelist_str_ = whitelist;
|
||||
this->whitelist_ = parse_whitelist(whitelist);
|
||||
settings_.whitelist_str = whitelist;
|
||||
whitelist_ = parse_whitelist(whitelist);
|
||||
}
|
||||
|
||||
// --- PASSWORD
|
||||
|
||||
void tr_rpc_server::set_username(std::string_view username)
|
||||
{
|
||||
username_ = username;
|
||||
tr_logAddDebug(fmt::format("setting our username to '{:s}'", username_));
|
||||
settings_.username = username;
|
||||
tr_logAddDebug(fmt::format("setting our username to '{:s}'", username));
|
||||
}
|
||||
|
||||
void tr_rpc_server::set_password(std::string_view password) noexcept
|
||||
{
|
||||
auto const is_salted = tr_ssha1_test(password);
|
||||
salted_password_ = is_salted ? password : tr_ssha1(password);
|
||||
|
||||
tr_logAddDebug(fmt::format("setting our salted password to '{:s}'", salted_password_));
|
||||
settings_.salted_password = is_salted ? password : tr_ssha1(password);
|
||||
tr_logAddDebug(fmt::format("setting our salted password to '{:s}'", settings_.salted_password));
|
||||
}
|
||||
|
||||
void tr_rpc_server::set_password_enabled(bool enabled)
|
||||
{
|
||||
authentication_required_ = enabled;
|
||||
settings_.authentication_required = enabled;
|
||||
tr_logAddDebug(fmt::format("setting password-enabled to '{}'", enabled));
|
||||
}
|
||||
|
||||
|
@ -822,7 +821,7 @@ std::string tr_rpc_server::get_bind_address() const
|
|||
|
||||
void tr_rpc_server::set_anti_brute_force_enabled(bool enabled) noexcept
|
||||
{
|
||||
is_anti_brute_force_enabled_ = enabled;
|
||||
settings_.is_anti_brute_force_enabled = enabled;
|
||||
|
||||
if (!enabled)
|
||||
{
|
||||
|
@ -832,60 +831,47 @@ void tr_rpc_server::set_anti_brute_force_enabled(bool enabled) noexcept
|
|||
|
||||
// --- LIFECYCLE
|
||||
|
||||
tr_rpc_server::tr_rpc_server(tr_session* session_in, tr_variant const& settings)
|
||||
tr_rpc_server::tr_rpc_server(tr_session* session_in, Settings settings)
|
||||
: compressor{ libdeflate_alloc_compressor(DeflateLevel), libdeflate_free_compressor }
|
||||
, web_client_dir_{ tr_getWebClientDir(session_in) }
|
||||
, bind_address_{ std::make_unique<class tr_rpc_address>() }
|
||||
, session{ session_in }
|
||||
{
|
||||
load(settings);
|
||||
load(std::move(settings));
|
||||
}
|
||||
|
||||
void tr_rpc_server::load(tr_variant const& src)
|
||||
void tr_rpc_server::load(Settings settings)
|
||||
{
|
||||
auto const* const src_map = src.get_if<tr_variant::Map>();
|
||||
if (src_map != nullptr)
|
||||
settings_ = std::move(settings);
|
||||
|
||||
if (!tr_strv_ends_with(settings_.url, '/'))
|
||||
{
|
||||
#define V(key, field, type, default_value, comment) \
|
||||
if (auto const iter = src_map->find(key); iter != std::end(*src_map)) \
|
||||
{ \
|
||||
if (auto val = libtransmission::VariantConverter::load<decltype(field)>(iter->second); val) \
|
||||
{ \
|
||||
this->field = *val; \
|
||||
} \
|
||||
}
|
||||
RPC_SETTINGS_FIELDS(V)
|
||||
#undef V
|
||||
settings_.url = fmt::format("{:s}/", settings_.url);
|
||||
}
|
||||
|
||||
if (!tr_strv_ends_with(url_, '/'))
|
||||
{
|
||||
url_ = fmt::format("{:s}/", url_);
|
||||
}
|
||||
host_whitelist_ = parse_whitelist(settings_.host_whitelist_str);
|
||||
set_password_enabled(settings_.authentication_required);
|
||||
set_whitelist(settings_.whitelist_str);
|
||||
set_username(settings_.username);
|
||||
set_password(settings_.salted_password);
|
||||
|
||||
this->host_whitelist_ = parse_whitelist(host_whitelist_str_);
|
||||
this->set_password_enabled(authentication_required_);
|
||||
this->set_whitelist(whitelist_str_);
|
||||
this->set_username(username_);
|
||||
this->set_password(salted_password_);
|
||||
|
||||
if (!bind_address_->from_string(bind_address_str_))
|
||||
if (!bind_address_->from_string(settings_.bind_address_str))
|
||||
{
|
||||
// NOTE: bind_address_ is default initialized to INADDR_ANY
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("The '{key}' setting is '{value}' but must be an IPv4 or IPv6 address or a Unix socket path. Using default value '0.0.0.0'"),
|
||||
fmt::arg("key", tr_quark_get_string_view(TR_KEY_rpc_bind_address)),
|
||||
fmt::arg("value", bind_address_str_)));
|
||||
fmt::arg("value", settings_.bind_address_str)));
|
||||
}
|
||||
|
||||
if (bind_address_->is_unix_addr())
|
||||
{
|
||||
this->set_whitelist_enabled(false);
|
||||
this->is_host_whitelist_enabled_ = false;
|
||||
set_whitelist_enabled(false);
|
||||
settings_.is_host_whitelist_enabled = false;
|
||||
}
|
||||
if (this->is_enabled())
|
||||
{
|
||||
auto const rpc_uri = bind_address_->to_string(this->port()) + this->url_;
|
||||
auto const rpc_uri = bind_address_->to_string(port()) + settings_.url;
|
||||
tr_logAddInfo(fmt::format(_("Serving RPC and Web requests on {address}"), fmt::arg("address", rpc_uri)));
|
||||
session->run_in_session_thread(start_server, this);
|
||||
|
||||
|
@ -906,26 +892,6 @@ void tr_rpc_server::load(tr_variant const& src)
|
|||
}
|
||||
}
|
||||
|
||||
tr_variant tr_rpc_server::settings() const
|
||||
{
|
||||
auto settings = tr_variant::Map{};
|
||||
#define V(key, field, type, default_value, comment) \
|
||||
settings.try_emplace(key, libtransmission::VariantConverter::save<decltype(field)>(field));
|
||||
RPC_SETTINGS_FIELDS(V)
|
||||
#undef V
|
||||
return tr_variant{ std::move(settings) };
|
||||
}
|
||||
|
||||
tr_variant tr_rpc_server::default_settings()
|
||||
{
|
||||
auto settings = tr_variant::Map{};
|
||||
#define V(key, field, type, default_value, comment) \
|
||||
settings.try_emplace(key, libtransmission::VariantConverter::save<decltype(field)>(default_value));
|
||||
RPC_SETTINGS_FIELDS(V)
|
||||
#undef V
|
||||
return tr_variant{ std::move(settings) };
|
||||
}
|
||||
|
||||
tr_rpc_server::~tr_rpc_server()
|
||||
{
|
||||
stop_server(this);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "libtransmission/net.h"
|
||||
#include "libtransmission/quark.h"
|
||||
#include "libtransmission/settings.h"
|
||||
#include "libtransmission/utils-ev.h"
|
||||
|
||||
class tr_rpc_address;
|
||||
|
@ -31,26 +32,59 @@ namespace libtransmission
|
|||
class Timer;
|
||||
}
|
||||
|
||||
#define RPC_SETTINGS_FIELDS(V) \
|
||||
V(TR_KEY_anti_brute_force_enabled, is_anti_brute_force_enabled_, bool, false, "") \
|
||||
V(TR_KEY_anti_brute_force_threshold, anti_brute_force_limit_, size_t, 100U, "") \
|
||||
V(TR_KEY_rpc_authentication_required, authentication_required_, bool, false, "") \
|
||||
V(TR_KEY_rpc_bind_address, bind_address_str_, std::string, "0.0.0.0", "") \
|
||||
V(TR_KEY_rpc_enabled, is_enabled_, bool, false, "") \
|
||||
V(TR_KEY_rpc_host_whitelist, host_whitelist_str_, std::string, "", "") \
|
||||
V(TR_KEY_rpc_host_whitelist_enabled, is_host_whitelist_enabled_, bool, true, "") \
|
||||
V(TR_KEY_rpc_port, port_, tr_port, tr_port::from_host(TR_DEFAULT_RPC_PORT), "") \
|
||||
V(TR_KEY_rpc_password, salted_password_, std::string, "", "") \
|
||||
V(TR_KEY_rpc_socket_mode, socket_mode_, tr_mode_t, 0750, "") \
|
||||
V(TR_KEY_rpc_url, url_, std::string, TR_DEFAULT_RPC_URL_STR, "") \
|
||||
V(TR_KEY_rpc_username, username_, std::string, "", "") \
|
||||
V(TR_KEY_rpc_whitelist, whitelist_str_, std::string, TR_DEFAULT_RPC_WHITELIST, "") \
|
||||
V(TR_KEY_rpc_whitelist_enabled, is_whitelist_enabled_, bool, true, "")
|
||||
|
||||
class tr_rpc_server
|
||||
{
|
||||
public:
|
||||
tr_rpc_server(tr_session* session, tr_variant const& settings);
|
||||
class Settings final : public libtransmission::Settings
|
||||
{
|
||||
public:
|
||||
Settings() = default;
|
||||
|
||||
explicit Settings(tr_variant const& src)
|
||||
{
|
||||
load(src);
|
||||
}
|
||||
|
||||
// NB: When adding a field here, you must also add it to
|
||||
// fields() if you want it to be in session-settings.json
|
||||
size_t anti_brute_force_limit = 100U;
|
||||
bool authentication_required = false;
|
||||
std::string bind_address_str = "0.0.0.0";
|
||||
std::string host_whitelist_str = "";
|
||||
bool is_anti_brute_force_enabled = false;
|
||||
bool is_enabled = false;
|
||||
bool is_host_whitelist_enabled = true;
|
||||
bool is_whitelist_enabled = true;
|
||||
tr_port port = tr_port::from_host(TR_DEFAULT_RPC_PORT);
|
||||
std::string salted_password = "";
|
||||
tr_mode_t socket_mode = 0750;
|
||||
std::string url = TR_DEFAULT_RPC_URL_STR;
|
||||
std::string username = "";
|
||||
std::string whitelist_str = TR_DEFAULT_RPC_WHITELIST;
|
||||
|
||||
private:
|
||||
[[nodiscard]] Fields fields() override
|
||||
{
|
||||
return {
|
||||
{ TR_KEY_anti_brute_force_enabled, &is_anti_brute_force_enabled },
|
||||
{ TR_KEY_anti_brute_force_threshold, &anti_brute_force_limit },
|
||||
{ TR_KEY_rpc_authentication_required, &authentication_required },
|
||||
{ TR_KEY_rpc_bind_address, &bind_address_str },
|
||||
{ TR_KEY_rpc_enabled, &is_enabled },
|
||||
{ TR_KEY_rpc_host_whitelist, &host_whitelist_str },
|
||||
{ TR_KEY_rpc_host_whitelist_enabled, &is_host_whitelist_enabled },
|
||||
{ TR_KEY_rpc_port, &port },
|
||||
{ TR_KEY_rpc_password, &salted_password },
|
||||
{ TR_KEY_rpc_socket_mode, &socket_mode },
|
||||
{ TR_KEY_rpc_url, &url },
|
||||
{ TR_KEY_rpc_username, &username },
|
||||
{ TR_KEY_rpc_whitelist, &whitelist_str },
|
||||
{ TR_KEY_rpc_whitelist_enabled, &is_whitelist_enabled },
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
tr_rpc_server(tr_session* session, Settings settings);
|
||||
~tr_rpc_server();
|
||||
|
||||
tr_rpc_server(tr_rpc_server&) = delete;
|
||||
|
@ -58,84 +92,87 @@ public:
|
|||
tr_rpc_server& operator=(tr_rpc_server&) = delete;
|
||||
tr_rpc_server& operator=(tr_rpc_server&&) = delete;
|
||||
|
||||
void load(tr_variant const& src);
|
||||
[[nodiscard]] tr_variant settings() const;
|
||||
[[nodiscard]] static tr_variant default_settings();
|
||||
void load(Settings settings);
|
||||
|
||||
[[nodiscard]] constexpr Settings const& settings() const
|
||||
{
|
||||
return settings_;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr tr_port port() const noexcept
|
||||
{
|
||||
return port_;
|
||||
return settings_.port;
|
||||
}
|
||||
|
||||
void set_port(tr_port port) noexcept;
|
||||
|
||||
[[nodiscard]] constexpr auto is_enabled() const noexcept
|
||||
{
|
||||
return is_enabled_;
|
||||
return settings_.is_enabled;
|
||||
}
|
||||
|
||||
void set_enabled(bool is_enabled);
|
||||
|
||||
[[nodiscard]] constexpr auto is_whitelist_enabled() const noexcept
|
||||
{
|
||||
return is_whitelist_enabled_;
|
||||
return settings_.is_whitelist_enabled;
|
||||
}
|
||||
|
||||
constexpr void set_whitelist_enabled(bool is_whitelist_enabled) noexcept
|
||||
{
|
||||
is_whitelist_enabled_ = is_whitelist_enabled;
|
||||
settings_.is_whitelist_enabled = is_whitelist_enabled;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto const& whitelist() const noexcept
|
||||
{
|
||||
return whitelist_str_;
|
||||
return settings_.whitelist_str;
|
||||
}
|
||||
|
||||
void set_whitelist(std::string_view whitelist);
|
||||
|
||||
[[nodiscard]] constexpr auto const& username() const noexcept
|
||||
{
|
||||
return username_;
|
||||
return settings_.username;
|
||||
}
|
||||
|
||||
void set_username(std::string_view username);
|
||||
|
||||
[[nodiscard]] constexpr auto is_password_enabled() const noexcept
|
||||
{
|
||||
return authentication_required_;
|
||||
return settings_.authentication_required;
|
||||
}
|
||||
|
||||
void set_password_enabled(bool enabled);
|
||||
|
||||
[[nodiscard]] constexpr auto const& get_salted_password() const noexcept
|
||||
{
|
||||
return salted_password_;
|
||||
return settings_.salted_password;
|
||||
}
|
||||
|
||||
void set_password(std::string_view password) noexcept;
|
||||
|
||||
[[nodiscard]] constexpr auto is_anti_brute_force_enabled() const noexcept
|
||||
{
|
||||
return is_anti_brute_force_enabled_;
|
||||
return settings_.is_anti_brute_force_enabled;
|
||||
}
|
||||
|
||||
void set_anti_brute_force_enabled(bool enabled) noexcept;
|
||||
|
||||
[[nodiscard]] constexpr auto get_anti_brute_force_limit() const noexcept
|
||||
{
|
||||
return anti_brute_force_limit_;
|
||||
return settings_.anti_brute_force_limit;
|
||||
}
|
||||
|
||||
constexpr void set_anti_brute_force_limit(int limit) noexcept
|
||||
{
|
||||
anti_brute_force_limit_ = limit;
|
||||
settings_.anti_brute_force_limit = limit;
|
||||
}
|
||||
|
||||
std::unique_ptr<libdeflate_compressor, void (*)(libdeflate_compressor*)> compressor;
|
||||
|
||||
[[nodiscard]] constexpr auto const& url() const noexcept
|
||||
{
|
||||
return url_;
|
||||
return settings_.url;
|
||||
}
|
||||
|
||||
void set_url(std::string_view url);
|
||||
|
@ -144,12 +181,10 @@ public:
|
|||
|
||||
[[nodiscard]] constexpr auto socket_mode() const noexcept
|
||||
{
|
||||
return socket_mode_;
|
||||
return settings_.socket_mode;
|
||||
}
|
||||
|
||||
#define V(key, name, type, default_value, comment) type name = type{ default_value };
|
||||
RPC_SETTINGS_FIELDS(V)
|
||||
#undef V
|
||||
Settings settings_;
|
||||
|
||||
std::vector<std::string> host_whitelist_;
|
||||
std::vector<std::string> whitelist_;
|
||||
|
|
|
@ -460,18 +460,18 @@ tr_address tr_session::bind_address(tr_address_type type) const noexcept
|
|||
tr_variant tr_sessionGetDefaultSettings()
|
||||
{
|
||||
auto ret = tr_variant::make_map();
|
||||
ret.merge(tr_session_settings::default_settings());
|
||||
ret.merge(tr_rpc_server::default_settings());
|
||||
ret.merge(tr_rpc_server::Settings{}.save());
|
||||
ret.merge(tr_session_alt_speeds::default_settings());
|
||||
ret.merge(tr_session_settings::default_settings());
|
||||
return ret;
|
||||
}
|
||||
|
||||
tr_variant tr_sessionGetSettings(tr_session const* session)
|
||||
{
|
||||
auto settings = tr_variant::make_map();
|
||||
settings.merge(session->settings_.settings());
|
||||
settings.merge(session->alt_speeds_.settings());
|
||||
settings.merge(session->rpc_server_->settings());
|
||||
settings.merge(session->rpc_server_->settings().save());
|
||||
settings.merge(session->settings_.settings());
|
||||
tr_variantDictAddInt(&settings, TR_KEY_message_level, tr_logGetLevel());
|
||||
return settings;
|
||||
}
|
||||
|
@ -752,7 +752,7 @@ void tr_session::setSettings(tr_variant const& settings, bool force)
|
|||
|
||||
// delegate loading out the other settings
|
||||
alt_speeds_.load(settings);
|
||||
rpc_server_->load(settings);
|
||||
rpc_server_->load(tr_rpc_server::Settings{ settings });
|
||||
}
|
||||
|
||||
void tr_session::setSettings(tr_session_settings&& settings_in, bool force)
|
||||
|
@ -2117,7 +2117,7 @@ tr_session::tr_session(std::string_view config_dir, tr_variant const& settings_d
|
|||
, settings_{ settings_dict }
|
||||
, session_id_{ tr_time }
|
||||
, peer_mgr_{ tr_peerMgrNew(this), &tr_peerMgrFree }
|
||||
, rpc_server_{ std::make_unique<tr_rpc_server>(this, settings_dict) }
|
||||
, rpc_server_{ std::make_unique<tr_rpc_server>(this, tr_rpc_server::Settings{ settings_dict }) }
|
||||
, now_timer_{ timer_maker_->create([this]() { on_now_timer(); }) }
|
||||
, queue_timer_{ timer_maker_->create([this]() { on_queue_timer(); }) }
|
||||
, save_timer_{ timer_maker_->create([this]() { on_save_timer(); }) }
|
||||
|
|
86
libtransmission/settings.cc
Normal file
86
libtransmission/settings.cc
Normal file
|
@ -0,0 +1,86 @@
|
|||
// This file Copyright © Mnemosyne LLC.
|
||||
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||
// or any future license endorsed by Mnemosyne LLC.
|
||||
// License text can be found in the licenses/ folder.
|
||||
|
||||
#include <variant>
|
||||
|
||||
#include "libtransmission/settings.h"
|
||||
#include "libtransmission/variant.h"
|
||||
|
||||
namespace libtransmission
|
||||
{
|
||||
namespace
|
||||
{
|
||||
struct LoadVisitor
|
||||
{
|
||||
explicit constexpr LoadVisitor(tr_variant const& src)
|
||||
: src_{ src }
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void operator()(T* const tgt)
|
||||
{
|
||||
if (auto val = VariantConverter::load<T>(src_))
|
||||
{
|
||||
*tgt = *val;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
tr_variant const& src_;
|
||||
};
|
||||
|
||||
struct SaveVisitor
|
||||
{
|
||||
constexpr SaveVisitor(tr_variant::Map& tgt, tr_quark key)
|
||||
: tgt_{ tgt }
|
||||
, key_{ key }
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void operator()(T const* const src)
|
||||
{
|
||||
tgt_.try_emplace(key_, VariantConverter::save<T>(*src));
|
||||
}
|
||||
|
||||
private:
|
||||
tr_variant::Map& tgt_;
|
||||
tr_quark key_;
|
||||
};
|
||||
} // unnamed namespace
|
||||
|
||||
void Settings::load(tr_variant const& src)
|
||||
{
|
||||
auto const* map = src.get_if<tr_variant::Map>();
|
||||
if (map == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& [key, prop_vptr] : fields())
|
||||
{
|
||||
if (auto const iter = map->find(key); iter != std::end(*map))
|
||||
{
|
||||
std::visit(LoadVisitor{ iter->second }, prop_vptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr_variant Settings::save() const
|
||||
{
|
||||
auto const fields = const_cast<Settings*>(this)->fields();
|
||||
|
||||
auto map = tr_variant::Map{};
|
||||
map.reserve(std::size(fields));
|
||||
|
||||
for (auto const& [key, prop_vptr] : fields)
|
||||
{
|
||||
std::visit(SaveVisitor{ map, key }, prop_vptr);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
} // namespace libtransmission
|
55
libtransmission/settings.h
Normal file
55
libtransmission/settings.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
// This file Copyright © Mnemosyne LLC.
|
||||
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
||||
// or any future license endorsed by Mnemosyne LLC.
|
||||
// License text can be found in the licenses/ folder.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef> // for size_t
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "libtransmission/transmission.h"
|
||||
|
||||
#include "libtransmission/log.h" // for tr_log_level
|
||||
#include "libtransmission/net.h" // for tr_port, tr_tos_t
|
||||
#include "libtransmission/open-files.h" // for tr_open_files::Preallocation
|
||||
#include "libtransmission/peer-io.h" // tr_preferred_transport
|
||||
#include "libtransmission/quark.h"
|
||||
#include "libtransmission/variant.h"
|
||||
|
||||
namespace libtransmission
|
||||
{
|
||||
|
||||
class Settings
|
||||
{
|
||||
public:
|
||||
void load(tr_variant const& src);
|
||||
|
||||
[[nodiscard]] tr_variant save() const;
|
||||
|
||||
protected:
|
||||
using field_key_type = tr_quark;
|
||||
using field_mapped_type = std::variant<
|
||||
bool*,
|
||||
double*,
|
||||
size_t*,
|
||||
std::string*,
|
||||
tr_encryption_mode*,
|
||||
tr_log_level*,
|
||||
tr_mode_t*,
|
||||
tr_open_files::Preallocation*,
|
||||
tr_port*,
|
||||
tr_preferred_transport*,
|
||||
tr_tos_t*,
|
||||
tr_verify_added_mode*>;
|
||||
using field_value_type = std::pair<const field_key_type, field_mapped_type>;
|
||||
using Fields = std::vector<field_value_type>;
|
||||
|
||||
Settings() = default;
|
||||
|
||||
[[nodiscard]] virtual Fields fields() = 0;
|
||||
};
|
||||
} // namespace libtransmission
|
Loading…
Add table
Reference in a new issue