mirror of
https://github.com/transmission/transmission.git
synced 2026-02-15 07:26:49 +00:00
refactor: no macros in transmission.h (#8099)
* refactor: replace TR_RPC_SESSION_ID_HEADER macro with TrRpcSessionIdHeader constant refactor: replace TR_RPC_RPC_VERSION_HEADER macro with TrRpcVersionHeader constant * refactor: remove macro TR_DEFAULT_RPC_PORT_STR * refactor: remove macro TR_DEFAULT_PEER_PORT_STR * refactor: remove macro TR_DEFAULT_PEER_LIMIT_GLOBAL_STR * refactor: remove macro TR_DEFAULT_PEER_LIMIT_TORRENT_STR * refactor: remove macro TR_DEFAULT_PEER_SOCKET_TOS_STR * refactor: replace DEFAULT_BLOCKLIST_FILENAME macro with TrDefaultBlocklistFilename constant * refactor: rename TrHttpServerDefaultBasePath to TrDefaultHttpServerBasePath for consistency with other defaults * refactor: group constants together near the top of transmission.h * refactor: hardcode string lengths to avoid FTBFS on older C++17 compilers * refactor: move macros to the tr_getopt clients * refactor: explicitly specify the parameter index to avoid passing in TrRpcSessionIdHeader twice * refactor: add an error message to new static_asserts
This commit is contained in:
@@ -49,6 +49,8 @@ sig_atomic_t manualUpdate = false;
|
||||
char const* torrentPath = nullptr;
|
||||
|
||||
using Arg = tr_option::Arg;
|
||||
static_assert(TrDefaultPeerPort == 51413, "update 'port' desc");
|
||||
static_assert(TrDefaultPeerSocketTos == "le", "update 'tos' desc");
|
||||
auto constexpr Options = std::array<tr_option, 20>{ {
|
||||
{ 'b', "blocklist", "Enable peer blocklists", "b", Arg::None, nullptr },
|
||||
{ 'B', "no-blocklist", "Disable peer blocklists", "B", Arg::None, nullptr },
|
||||
@@ -61,11 +63,10 @@ auto constexpr Options = std::array<tr_option, 20>{ {
|
||||
{ 'g', "config-dir", "Where to find configuration files", "g", Arg::Required, "<path>" },
|
||||
{ 'm', "portmap", "Enable portmapping via NAT-PMP or UPnP", "m", Arg::None, nullptr },
|
||||
{ 'M', "no-portmap", "Disable portmapping", "M", Arg::None, nullptr },
|
||||
{ 'p', "port", "Port for incoming peers (Default: " TR_DEFAULT_PEER_PORT_STR ")", "p", Arg::Required, "<port>" },
|
||||
{ 'p', "port", "Port for incoming peers (Default: 51413)", "p", Arg::Required, "<port>" },
|
||||
{ 't',
|
||||
"tos",
|
||||
"Peer socket DSCP / ToS setting (number, or a DSCP string, e.g. 'af11' or 'cs0', default=" TR_DEFAULT_PEER_SOCKET_TOS_STR
|
||||
")",
|
||||
"Peer socket DSCP / ToS. Number or DSCP string, e.g. 'af11' or 'cs0' (Default: 'le')",
|
||||
"t",
|
||||
Arg::Required,
|
||||
"<dscp-or-tos>" },
|
||||
|
||||
@@ -80,8 +80,13 @@ char constexpr Usage[] = "Transmission " LONG_VERSION_STRING
|
||||
"Usage: transmission-daemon [options]";
|
||||
|
||||
using Arg = tr_option::Arg;
|
||||
static_assert(TrDefaultRpcWhitelist == "127.0.0.1,::1", "update 'allowed' desc");
|
||||
static_assert(TrDefaultPeerPort == 51413, "update 'peerport' desc");
|
||||
static_assert(TrDefaultPeerLimitTorrent == 50, "update 'peerlimit-torrent' desc");
|
||||
static_assert(TrDefaultPeerLimitGlobal == 200, "update 'peerlimit-global' desc");
|
||||
static_assert(TrDefaultRpcPort == 9091 && R"(update "port" desc)");
|
||||
auto constexpr Options = std::array<tr_option, 48>{ {
|
||||
{ 'a', "allowed", "Allowed IP addresses. (Default: " TR_DEFAULT_RPC_WHITELIST ")", "a", Arg::Required, "<list>" },
|
||||
{ 'a', "allowed", "Allowed IP addresses. (Default: '127.0.0.1,::1')", "a", Arg::Required, "<list>" },
|
||||
{ 'b', "blocklist", "Enable peer blocklists", "b", Arg::None, nullptr },
|
||||
{ 'B', "no-blocklist", "Disable peer blocklists", "B", Arg::None, nullptr },
|
||||
{ 'c', "watch-dir", "Where to watch for new torrent files", "c", Arg::Required, "<directory>" },
|
||||
@@ -93,7 +98,7 @@ auto constexpr Options = std::array<tr_option, 48>{ {
|
||||
{ 'e', "logfile", "Dump the log messages to this filename", "e", Arg::Required, "<filename>" },
|
||||
{ 'f', "foreground", "Run in the foreground instead of daemonizing", "f", Arg::None, nullptr },
|
||||
{ 'g', "config-dir", "Where to look for configuration files", "g", Arg::Required, "<path>" },
|
||||
{ 'p', "port", "RPC port (Default: " TR_DEFAULT_RPC_PORT_STR ")", "p", Arg::Required, "<port>" },
|
||||
{ 'p', "port", "RPC port (Default: 9091)", "p", Arg::Required, "<port>" },
|
||||
{ 't', "auth", "Require authentication", "t", Arg::None, nullptr },
|
||||
{ 'T', "no-auth", "Don't require authentication", "T", Arg::None, nullptr },
|
||||
{ 'u', "username", "Set username for authentication", "u", Arg::Required, "<username>" },
|
||||
@@ -122,21 +127,11 @@ auto constexpr Options = std::array<tr_option, 48>{ {
|
||||
"<protocol(s)>" },
|
||||
{ 831, "utp", "*DEPRECATED* Enable µTP for peer connections", nullptr, Arg::None, nullptr },
|
||||
{ 832, "no-utp", "*DEPRECATED* Disable µTP for peer connections", nullptr, Arg::None, nullptr },
|
||||
{ 'P', "peerport", "Port for incoming peers (Default: " TR_DEFAULT_PEER_PORT_STR ")", "P", Arg::Required, "<port>" },
|
||||
{ 'P', "peerport", "Port for incoming peers (Default: 51413)", "P", Arg::Required, "<port>" },
|
||||
{ 'm', "portmap", "Enable portmapping via NAT-PMP or UPnP", "m", Arg::None, nullptr },
|
||||
{ 'M', "no-portmap", "Disable portmapping", "M", Arg::None, nullptr },
|
||||
{ 'L',
|
||||
"peerlimit-global",
|
||||
"Maximum overall number of peers (Default: " TR_DEFAULT_PEER_LIMIT_GLOBAL_STR ")",
|
||||
"L",
|
||||
Arg::Required,
|
||||
"<limit>" },
|
||||
{ 'l',
|
||||
"peerlimit-torrent",
|
||||
"Maximum number of peers per torrent (Default: " TR_DEFAULT_PEER_LIMIT_TORRENT_STR ")",
|
||||
"l",
|
||||
Arg::Required,
|
||||
"<limit>" },
|
||||
{ 'L', "peerlimit-global", "Maximum overall number of peers (Default: 200)", "L", Arg::Required, "<limit>" },
|
||||
{ 'l', "peerlimit-torrent", "Maximum number of peers per torrent (Default: 50)", "l", Arg::Required, "<limit>" },
|
||||
{ 910, "encryption-required", "Encrypt all peer connections", "er", Arg::None, nullptr },
|
||||
{ 911, "encryption-preferred", "Prefer encrypted peer connections", "ep", Arg::None, nullptr },
|
||||
{ 912, "encryption-tolerated", "Prefer unencrypted peer connections", "et", Arg::None, nullptr },
|
||||
|
||||
@@ -565,7 +565,7 @@ size_t Blocklists::update_primary_blocklist(std::string_view external_file, bool
|
||||
{
|
||||
// These rules will replace the default blocklist.
|
||||
// Build the path of the default blocklist .bin file where we'll save these rules.
|
||||
auto const bin_file = tr_pathbuf{ folder_, '/', DEFAULT_BLOCKLIST_FILENAME };
|
||||
auto const bin_file = tr_pathbuf{ folder_, '/', TrDefaultBlocklistFilename };
|
||||
|
||||
// Try to save it
|
||||
auto added = Blocklist::saveNew(external_file, bin_file, is_enabled);
|
||||
|
||||
@@ -477,7 +477,7 @@ bool isHostnameAllowed(tr_rpc_server const* server, evhttp_request* const req)
|
||||
bool test_session_id(tr_rpc_server const* server, evhttp_request* const req)
|
||||
{
|
||||
auto const* const input_headers = evhttp_request_get_input_headers(req);
|
||||
char const* const session_id = evhttp_find_header(input_headers, TR_RPC_SESSION_ID_HEADER);
|
||||
char const* const session_id = evhttp_find_header(input_headers, std::data(TrRpcSessionIdHeader));
|
||||
return session_id != nullptr && server->session->sessionId() == session_id;
|
||||
}
|
||||
|
||||
@@ -624,26 +624,26 @@ void handle_request(struct evhttp_request* req, void* arg)
|
||||
else if (!test_session_id(server, req))
|
||||
{
|
||||
auto const session_id = std::string{ server->session->sessionId() };
|
||||
evhttp_add_header(output_headers, std::data(TrRpcSessionIdHeader), session_id.c_str());
|
||||
|
||||
evhttp_add_header(output_headers, std::data(TrRpcVersionHeader), std::data(TrRpcVersionSemver));
|
||||
|
||||
auto const expose_val = fmt::format("{:s}, {:s}", TrRpcSessionIdHeader, TrRpcVersionHeader);
|
||||
evhttp_add_header(output_headers, "Access-Control-Expose-Headers", expose_val.c_str());
|
||||
|
||||
auto const body = fmt::format(
|
||||
"<p>Your request had an invalid session_id header.</p>"
|
||||
"<p>To fix this, follow these steps:"
|
||||
"<ol><li> When reading a response, get its " TR_RPC_SESSION_ID_HEADER
|
||||
" header and remember it"
|
||||
"<ol><li> When reading a response, get its {0:s} header and remember it"
|
||||
"<li> Add the updated header to your outgoing requests"
|
||||
"<li> When you get this 409 error message, resend your request with the updated header"
|
||||
"</ol></p>"
|
||||
"<p>This requirement has been added to help prevent "
|
||||
"<a href=\"https://en.wikipedia.org/wiki/Cross-site_request_forgery\">CSRF</a> "
|
||||
"attacks.</p>"
|
||||
"<p><code>{:s}: {:s}</code></p>",
|
||||
TR_RPC_SESSION_ID_HEADER,
|
||||
"<p><code>{0:s}: {1:s}</code></p>",
|
||||
TrRpcSessionIdHeader,
|
||||
session_id);
|
||||
evhttp_add_header(output_headers, TR_RPC_SESSION_ID_HEADER, session_id.c_str());
|
||||
evhttp_add_header(output_headers, TR_RPC_RPC_VERSION_HEADER, std::data(TrRpcVersionSemver));
|
||||
evhttp_add_header(
|
||||
output_headers,
|
||||
"Access-Control-Expose-Headers",
|
||||
TR_RPC_SESSION_ID_HEADER ", " TR_RPC_RPC_VERSION_HEADER);
|
||||
send_simple_response(req, 409, body.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -67,9 +67,9 @@ public:
|
||||
std::string bind_address_str = "0.0.0.0";
|
||||
std::string host_whitelist_str;
|
||||
std::string salted_password;
|
||||
std::string url = std::string{ TrHttpServerDefaultBasePath };
|
||||
std::string url = std::string{ TrDefaultHttpServerBasePath };
|
||||
std::string username;
|
||||
std::string whitelist_str = TR_DEFAULT_RPC_WHITELIST;
|
||||
std::string whitelist_str = std::string{ TrDefaultRpcWhitelist };
|
||||
tr_mode_t socket_mode = 0750;
|
||||
tr_port port = tr_port::from_host(TrDefaultRpcPort);
|
||||
|
||||
|
||||
@@ -31,6 +31,20 @@ using tr_tracker_id_t = uint32_t;
|
||||
using tr_torrent_id_t = int;
|
||||
using tr_mode_t = uint16_t;
|
||||
|
||||
inline auto constexpr TrDefaultBlocklistFilename = std::string_view{ "blocklist.bin" };
|
||||
inline auto constexpr TrDefaultHttpServerBasePath = std::string_view{ "/transmission/" };
|
||||
inline auto constexpr TrDefaultPeerLimitGlobal = 200U;
|
||||
inline auto constexpr TrDefaultPeerLimitTorrent = 50U;
|
||||
inline auto constexpr TrDefaultPeerPort = 51413U;
|
||||
inline auto constexpr TrDefaultPeerSocketTos = std::string_view{ "le" };
|
||||
inline auto constexpr TrDefaultRpcPort = 9091U;
|
||||
inline auto constexpr TrDefaultRpcWhitelist = std::string_view{ "127.0.0.1,::1" };
|
||||
|
||||
inline auto constexpr TrHttpServerRpcRelativePath = std::string_view{ "rpc" };
|
||||
inline auto constexpr TrHttpServerWebRelativePath = std::string_view{ "web/" };
|
||||
inline auto constexpr TrRpcSessionIdHeader = std::string_view{ "X-Transmission-Session-Id" };
|
||||
inline auto constexpr TrRpcVersionHeader = std::string_view{ "X-Transmission-Rpc-Version" };
|
||||
|
||||
struct tr_block_span_t
|
||||
{
|
||||
tr_block_index_t begin;
|
||||
@@ -50,9 +64,6 @@ struct tr_torrent;
|
||||
struct tr_torrent_metainfo;
|
||||
struct tr_variant;
|
||||
|
||||
#define TR_RPC_SESSION_ID_HEADER "X-Transmission-Session-Id"
|
||||
#define TR_RPC_RPC_VERSION_HEADER "X-Transmission-Rpc-Version"
|
||||
|
||||
enum tr_verify_added_mode : uint8_t
|
||||
{
|
||||
// See discussion @ https://github.com/transmission/transmission/pull/2626
|
||||
@@ -124,21 +135,6 @@ size_t tr_getDefaultConfigDirToBuf(char const* appname, char* buf, size_t buflen
|
||||
/** @brief buffer variant of `tr_getDefaultDownloadDir()`. See `tr_strv_to_buf()`. */
|
||||
size_t tr_getDefaultDownloadDirToBuf(char* buf, size_t buflen);
|
||||
|
||||
#define TR_DEFAULT_RPC_WHITELIST "127.0.0.1,::1"
|
||||
#define TR_DEFAULT_RPC_PORT_STR "9091"
|
||||
inline auto constexpr TrDefaultRpcPort = 9091U;
|
||||
#define TR_DEFAULT_PEER_PORT_STR "51413"
|
||||
inline auto constexpr TrDefaultPeerPort = 51413U;
|
||||
#define TR_DEFAULT_PEER_SOCKET_TOS_STR "le"
|
||||
#define TR_DEFAULT_PEER_LIMIT_GLOBAL_STR "200"
|
||||
inline auto constexpr TrDefaultPeerLimitGlobal = 200U;
|
||||
#define TR_DEFAULT_PEER_LIMIT_TORRENT_STR "50"
|
||||
inline auto constexpr TrDefaultPeerLimitTorrent = 50U;
|
||||
|
||||
inline auto constexpr TrHttpServerDefaultBasePath = std::string_view{ "/transmission/" };
|
||||
inline auto constexpr TrHttpServerRpcRelativePath = std::string_view{ "rpc" };
|
||||
inline auto constexpr TrHttpServerWebRelativePath = std::string_view{ "web/" };
|
||||
|
||||
/**
|
||||
* Add libtransmission's default settings to the benc dictionary.
|
||||
*
|
||||
@@ -717,10 +713,6 @@ char const* tr_blocklistGetURL(tr_session const* session);
|
||||
invokes the "blocklist_update" method */
|
||||
void tr_blocklistSetURL(tr_session* session, char const* url);
|
||||
|
||||
/** @brief the file in the $config/blocklists/ directory that's
|
||||
used by `tr_blocklistSetContent()` and "blocklist_update" */
|
||||
#define DEFAULT_BLOCKLIST_FILENAME "blocklist.bin"
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
||||
@@ -138,9 +138,11 @@ static NSString* const kWebUIURLFormat = @"http://localhost:%ld/";
|
||||
|
||||
NSURL* blocklistDir = [[NSFileManager.defaultManager URLsForDirectory:NSApplicationDirectory inDomains:NSUserDomainMask][0]
|
||||
URLByAppendingPathComponent:@"Transmission/blocklists/"];
|
||||
[NSFileManager.defaultManager moveItemAtURL:[blocklistDir URLByAppendingPathComponent:@"level1.bin"]
|
||||
toURL:[blocklistDir URLByAppendingPathComponent:@DEFAULT_BLOCKLIST_FILENAME]
|
||||
error:nil];
|
||||
[NSFileManager.defaultManager
|
||||
moveItemAtURL:[blocklistDir URLByAppendingPathComponent:@"level1.bin"]
|
||||
toURL:[blocklistDir
|
||||
URLByAppendingPathComponent:[NSString stringWithUTF8String:TrDefaultBlocklistFilename.data()]]
|
||||
error:nil];
|
||||
}
|
||||
|
||||
//save a new random port
|
||||
|
||||
@@ -238,7 +238,7 @@ tr_variant::Map Prefs::defaults()
|
||||
map.try_emplace(TR_KEY_remote_session_password, tr_variant::unmanaged_string(""sv));
|
||||
map.try_emplace(TR_KEY_remote_session_port, TrDefaultRpcPort);
|
||||
map.try_emplace(TR_KEY_remote_session_requires_authentication, false);
|
||||
map.try_emplace(TR_KEY_remote_session_url_base_path, tr_variant::unmanaged_string(TrHttpServerDefaultBasePath));
|
||||
map.try_emplace(TR_KEY_remote_session_url_base_path, tr_variant::unmanaged_string(TrDefaultHttpServerBasePath));
|
||||
map.try_emplace(TR_KEY_remote_session_username, tr_variant::unmanaged_string(""sv));
|
||||
map.try_emplace(TR_KEY_show_backup_trackers, false);
|
||||
map.try_emplace(TR_KEY_show_filterbar, true);
|
||||
|
||||
@@ -121,7 +121,7 @@ void RpcClient::sendNetworkRequest(QByteArray const& body, QFutureInterface<RpcR
|
||||
req.setRawHeader("User-Agent", "Transmisson/" SHORT_VERSION_STRING);
|
||||
if (!session_id_.isEmpty())
|
||||
{
|
||||
req.setRawHeader(TR_RPC_SESSION_ID_HEADER, session_id_);
|
||||
req.setRawHeader(SessionIdHeaderName, session_id_);
|
||||
}
|
||||
|
||||
if (verbose_)
|
||||
@@ -206,19 +206,18 @@ void RpcClient::networkRequestFinished(QNetworkReply* reply)
|
||||
}
|
||||
}
|
||||
|
||||
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 409 &&
|
||||
reply->hasRawHeader(TR_RPC_SESSION_ID_HEADER))
|
||||
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 409 && reply->hasRawHeader(SessionIdHeaderName))
|
||||
{
|
||||
// we got a 409 telling us our session id has expired.
|
||||
// update it and resubmit the request.
|
||||
|
||||
auto version_str = QString::fromUtf8("unknown");
|
||||
|
||||
if (reply->hasRawHeader(TR_RPC_RPC_VERSION_HEADER))
|
||||
if (reply->hasRawHeader(VersionHeaderName))
|
||||
{
|
||||
network_style_ = api_compat::Style::Tr5;
|
||||
|
||||
version_str = QString::fromUtf8(reply->rawHeader(TR_RPC_RPC_VERSION_HEADER));
|
||||
version_str = QString::fromUtf8(reply->rawHeader(VersionHeaderName));
|
||||
if (QVersionNumber::fromString(version_str).majorVersion() > TrRpcVersionSemverMajor)
|
||||
{
|
||||
fmt::print(
|
||||
@@ -243,7 +242,7 @@ void RpcClient::networkRequestFinished(QNetworkReply* reply)
|
||||
static_cast<int>(network_style_));
|
||||
}
|
||||
|
||||
session_id_ = reply->rawHeader(TR_RPC_SESSION_ID_HEADER);
|
||||
session_id_ = reply->rawHeader(SessionIdHeaderName);
|
||||
sendNetworkRequest(reply->property(RequestBodyKey).toByteArray(), promise);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -86,6 +86,9 @@ private slots:
|
||||
void localRequestFinished(TrVariantPtr response);
|
||||
|
||||
private:
|
||||
QByteArray const SessionIdHeaderName = std::data(TrRpcSessionIdHeader);
|
||||
QByteArray const VersionHeaderName = std::data(TrRpcVersionHeader);
|
||||
|
||||
QNetworkAccessManager* networkAccessManager();
|
||||
|
||||
void sendNetworkRequest(QByteArray const& body, QFutureInterface<RpcResponse> const& promise);
|
||||
|
||||
@@ -213,6 +213,7 @@ enum
|
||||
// --- Command-Line Arguments
|
||||
|
||||
using Arg = tr_option::Arg;
|
||||
static_assert(TrDefaultPeerPort == 51413, "update 'port' desc");
|
||||
auto constexpr Options = std::array<tr_option, 106>{ {
|
||||
{ 'a', "add", "Add torrent files by filename or URL", "a", Arg::None, nullptr },
|
||||
{ 970, "alt-speed", "Use the alternate Limits", "as", Arg::None, nullptr },
|
||||
@@ -271,7 +272,7 @@ auto constexpr Options = std::array<tr_option, 106>{ {
|
||||
{ 820, "ssl", "Use SSL when talking to daemon", nullptr, Arg::None, nullptr },
|
||||
{ 'o', "dht", "Enable distributed hash tables (DHT)", "o", Arg::None, nullptr },
|
||||
{ 'O', "no-dht", "Disable distributed hash tables (DHT)", "O", Arg::None, nullptr },
|
||||
{ 'p', "port", "Port for incoming peers (Default: " TR_DEFAULT_PEER_PORT_STR ")", "p", Arg::Required, "<port>" },
|
||||
{ 'p', "port", "Port for incoming peers (Default: 51413)", "p", Arg::Required, "<port>" },
|
||||
{ 962, "port-test", "Port testing", "pt", Arg::None, nullptr },
|
||||
{ 'P', "random-port", "Random port for incoming peers", "P", Arg::None, nullptr },
|
||||
{ 900, "priority-high", "Try to download these file(s) first", "ph", Arg::Required, "<files>" },
|
||||
@@ -875,8 +876,8 @@ void warn_if_unsupported_rpc_version(std::string_view const semver)
|
||||
[[nodiscard]] size_t parse_response_header(void* ptr, size_t size, size_t nmemb, void* vconfig)
|
||||
{
|
||||
using namespace header_utils;
|
||||
static auto const session_id_header = tr_strlower(TR_RPC_SESSION_ID_HEADER);
|
||||
static auto const rpc_version_header = tr_strlower(TR_RPC_RPC_VERSION_HEADER);
|
||||
static auto const session_id_header = tr_strlower(TrRpcSessionIdHeader);
|
||||
static auto const rpc_version_header = tr_strlower(TrRpcVersionHeader);
|
||||
|
||||
auto& config = *static_cast<RemoteConfig*>(vconfig);
|
||||
|
||||
@@ -2403,7 +2404,7 @@ CURL* tr_curl_easy_init(std::string* writebuf, RemoteConfig& config)
|
||||
|
||||
if (auto const& str = config.session_id; !std::empty(str))
|
||||
{
|
||||
auto const h = fmt::format("{:s}: {:s}", TR_RPC_SESSION_ID_HEADER, str);
|
||||
auto const h = fmt::format("{:s}: {:s}", TrRpcSessionIdHeader, str);
|
||||
auto* const custom_headers = curl_slist_append(nullptr, h.c_str());
|
||||
|
||||
(void)curl_easy_setopt(curl, CURLOPT_HTTPHEADER, custom_headers);
|
||||
@@ -3578,7 +3579,7 @@ int tr_main(int argc, char* argv[])
|
||||
|
||||
if (std::empty(rpcurl))
|
||||
{
|
||||
rpcurl = fmt::format("{:s}:{:d}{:s}{:s}", host, port, TrHttpServerDefaultBasePath, TrHttpServerRpcRelativePath);
|
||||
rpcurl = fmt::format("{:s}:{:d}{:s}{:s}", host, port, TrDefaultHttpServerBasePath, TrHttpServerRpcRelativePath);
|
||||
}
|
||||
|
||||
return process_args(rpcurl.c_str(), argc, (char const* const*)argv, config);
|
||||
|
||||
Reference in New Issue
Block a user