refactor: use symbolic names for server relative paths (#8080)

* refactor: use TrHttpServerDefaultBasePath in remote.cc

refactor: use TrHttpServerRpcRelativePath in remote.cc

* refactor: use TrHttpServerDefaultBasePath in rpc-server.cc

refactor: use TrHttpServerRpcRelativePath in rpc-server.cc

* refactor: remove unused TR_DEFAULT_RPC_URL_STR
This commit is contained in:
Charles Kerr
2026-01-08 08:12:26 -06:00
committed by GitHub
parent 0b6d02c186
commit 9236827ba5
4 changed files with 33 additions and 34 deletions

View File

@@ -315,12 +315,17 @@ void handle_web_client(struct evhttp_request* req, tr_rpc_server const* server)
return;
}
// convert the URL path component (ex: "/transmission/web/images/favicon.png")
// into a filesystem path (ex: "/usr/share/transmission/web/images/favicon.png")
// convert the URL path component into a filesystem path, e.g.
// "/transmission/web/images/favicon.png" ->
// "/usr/share/transmission/web/images/favicon.png")
auto subpath = std::string_view{ evhttp_request_get_uri(req) };
// remove the "/transmission/web/" prefix
static auto constexpr Web = "web/"sv;
auto subpath = std::string_view{ evhttp_request_get_uri(req) }.substr(std::size(server->url()) + std::size(Web));
// remove the web base path eg "/transmission/web/"
{
auto const& base_path = server->url();
static auto constexpr Web = TrHttpServerWebRelativePath;
subpath = subpath.substr(std::size(base_path) + std::size(Web));
}
// remove any trailing query / fragment
subpath = subpath.substr(0, subpath.find_first_of("?#"sv));
@@ -580,17 +585,20 @@ void handle_request(struct evhttp_request* req, void* arg)
server->login_attempts_ = 0;
auto const* const uri = evhttp_request_get_uri(req);
auto const uri_sv = std::string_view{ uri };
auto const location = tr_strv_starts_with(uri_sv, server->url()) ? uri_sv.substr(std::size(server->url())) : ""sv;
// eg '/transmission/web/' and '/transmission/rpc'
auto const& base_path = server->url();
auto const web_base_path = tr_urlbuf{ base_path, TrHttpServerWebRelativePath };
auto const rpc_base_path = tr_urlbuf{ base_path, TrHttpServerRpcRelativePath };
auto const deprecated_web_path = tr_urlbuf{ base_path, "web" /*no trailing slash*/ };
if (std::empty(location) || location == "web"sv)
char const* const uri = evhttp_request_get_uri(req);
if (!tr_strv_starts_with(uri, base_path) || uri == deprecated_web_path)
{
auto const new_location = fmt::format("{:s}web/", server->url());
evhttp_add_header(output_headers, "Location", new_location.c_str());
evhttp_add_header(output_headers, "Location", web_base_path.c_str());
send_simple_response(req, HTTP_MOVEPERM, nullptr);
}
else if (tr_strv_starts_with(location, "web/"sv))
else if (tr_strv_starts_with(uri, web_base_path))
{
handle_web_client(req, server);
}
@@ -638,7 +646,7 @@ void handle_request(struct evhttp_request* req, void* arg)
send_simple_response(req, 409, body.c_str());
}
#endif
else if (tr_strv_starts_with(location, "rpc"sv))
else if (tr_strv_starts_with(uri, rpc_base_path))
{
handle_rpc(req, server);
}
@@ -648,7 +656,7 @@ void handle_request(struct evhttp_request* req, void* arg)
fmt::format(
fmt::runtime(_("Unknown URI from {host}: '{uri}'")),
fmt::arg("host", remote_host),
fmt::arg("uri", uri_sv)));
fmt::arg("uri", uri)));
send_simple_response(req, HTTP_NOTFOUND, uri);
}
}
@@ -983,9 +991,9 @@ void tr_rpc_server::load(Settings&& settings)
{
settings_ = std::move(settings);
if (!tr_strv_ends_with(settings_.url, '/'))
if (std::string& path = settings_.url; !tr_strv_ends_with(path, '/'))
{
settings_.url = fmt::format("{:s}/", settings_.url);
path = fmt::format("{:s}/", path);
}
host_whitelist_ = parse_whitelist(settings_.host_whitelist_str);
@@ -1012,7 +1020,8 @@ void tr_rpc_server::load(Settings&& settings)
}
if (this->is_enabled())
{
auto const rpc_uri = bind_address_->to_string(port()) + settings_.url;
auto const& base_path = url();
auto const rpc_uri = bind_address_->to_string(port()) + base_path;
tr_logAddInfo(fmt::format(fmt::runtime(_("Serving RPC and Web requests on {address}")), fmt::arg("address", rpc_uri)));
session->run_in_session_thread(start_server, this);

View File

@@ -67,7 +67,7 @@ public:
std::string bind_address_str = "0.0.0.0";
std::string host_whitelist_str;
std::string salted_password;
std::string url = TR_DEFAULT_RPC_URL_STR;
std::string url = std::string{ TrHttpServerDefaultBasePath };
std::string username;
std::string whitelist_str = TR_DEFAULT_RPC_WHITELIST;
tr_mode_t socket_mode = 0750;

View File

@@ -136,7 +136,6 @@ 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_RPC_URL_STR "/transmission/"
#define TR_DEFAULT_PEER_PORT_STR "51413"
inline auto constexpr TrDefaultPeerPort = 51413U;
#define TR_DEFAULT_PEER_SOCKET_TOS_STR "le"
@@ -145,7 +144,7 @@ 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{ TR_DEFAULT_RPC_URL_STR };
inline auto constexpr TrHttpServerDefaultBasePath = std::string_view{ "/transmission/" };
inline auto constexpr TrHttpServerRpcRelativePath = std::string_view{ "rpc" };
inline auto constexpr TrHttpServerWebRelativePath = std::string_view{ "web/" };

View File

@@ -50,10 +50,6 @@ using namespace libtransmission::Values;
namespace
{
auto constexpr DefaultPort = uint16_t{ TrDefaultRpcPort };
char constexpr DefaultHost[] = "localhost";
char constexpr DefaultUrl[] = TR_DEFAULT_RPC_URL_STR "rpc/";
char constexpr MyName[] = "transmission-remote";
char constexpr Usage[] = "transmission-remote " LONG_VERSION_STRING
"\n"
@@ -3522,12 +3518,12 @@ void get_host_and_port_and_rpc_url(
auto const sv = std::string_view{ argv[1] };
if (tr_strv_starts_with(sv, "http://")) /* user passed in http rpc url */
{
rpcurl = fmt::format("{:s}/rpc/", sv.substr(7));
rpcurl = fmt::format("{:s}/{:s}", sv.substr(7), TrHttpServerRpcRelativePath);
}
else if (tr_strv_starts_with(sv, "https://")) /* user passed in https rpc url */
{
config.use_ssl = true;
rpcurl = fmt::format("{:s}/rpc/", sv.substr(8));
rpcurl = fmt::format("{:s}/{:s}", sv.substr(8), TrHttpServerRpcRelativePath);
}
else if (parse_port_string(sv, port))
{
@@ -3568,8 +3564,8 @@ int tr_main(int argc, char* argv[])
tr_locale_set_global("");
auto config = RemoteConfig{};
auto port = DefaultPort;
auto host = std::string{};
auto port = uint16_t{ TrDefaultRpcPort };
auto host = std::string{ "localhost" };
auto rpcurl = std::string{};
if (argc < 2)
@@ -3580,14 +3576,9 @@ int tr_main(int argc, char* argv[])
get_host_and_port_and_rpc_url(argc, argv, host, port, rpcurl, config);
if (std::empty(host))
{
host = DefaultHost;
}
if (std::empty(rpcurl))
{
rpcurl = fmt::format("{:s}:{:d}{:s}", host, port, DefaultUrl);
rpcurl = fmt::format("{:s}:{:d}{:s}{:s}", host, port, TrHttpServerDefaultBasePath, TrHttpServerRpcRelativePath);
}
return process_args(rpcurl.c_str(), argc, (char const* const*)argv, config);