Add support for http path prefixing in LWS client

This commit is contained in:
Lee *!* Clagett
2025-12-09 13:17:44 -05:00
parent d476d95064
commit efba3e7b2d
6 changed files with 32 additions and 23 deletions
+14 -14
View File
@@ -925,7 +925,7 @@ namespace lwsf { namespace internal { namespace backend
};
lock.unlock();
const auto response = rpc::invoke<rpc::login_response>(client, login);
const auto response = rpc::invoke<rpc::login_response>(client, client_prefix, login);
if (!response)
{
if (response == rpc_unapproved)
@@ -956,7 +956,7 @@ namespace lwsf { namespace internal { namespace backend
rpc::login login{primary.address, primary.view.sec};
{
lock.unlock();
const auto response = rpc::invoke<rpc::get_subaddrs>(client, login).value();
const auto response = rpc::invoke<rpc::get_subaddrs>(client, client_prefix, login).value();
lock.lock();
if (update_lookaheads(*this, response.all_subaddrs))
return new_account;
@@ -967,7 +967,7 @@ namespace lwsf { namespace internal { namespace backend
fill_upsert(*this, request.subaddrs_);
lock.unlock();
const auto response = rpc::invoke<rpc::upsert_subaddrs_response>(client, request).value();
const auto response = rpc::invoke<rpc::upsert_subaddrs_response>(client, client_prefix, request).value();
lock.lock();
update_lookaheads(*this, response.all_subaddrs);
}
@@ -1025,11 +1025,11 @@ namespace lwsf { namespace internal { namespace backend
}
expect<rpc::get_unspent_outs_response> outs_response{common_error::kInvalidArgument};
const auto txs_response = rpc::invoke<rpc::get_address_txs>(client, login);
const auto txs_response = rpc::invoke<rpc::get_address_txs>(client, client_prefix, login);
if (txs_response)
{
const rpc::get_unspent_outs_request request{login, rpc::uint64_string(0), 0, true};
outs_response = rpc::invoke<rpc::get_unspent_outs_response>(client, request);
outs_response = rpc::invoke<rpc::get_unspent_outs_response>(client, client_prefix, request);
}
lock.lock();
@@ -1061,7 +1061,7 @@ namespace lwsf { namespace internal { namespace backend
fill_upsert(*this, request.subaddrs_);
lock.unlock();
const auto response = rpc::invoke<rpc::upsert_subaddrs_response>(client, request);
const auto response = rpc::invoke<rpc::upsert_subaddrs_response>(client, client_prefix, request);
lock.lock();
if (response && update_lookaheads(*this, response->all_subaddrs))
lookahead_error = {};
@@ -1083,7 +1083,7 @@ namespace lwsf { namespace internal { namespace backend
};
lock.unlock();
const auto upsert_response = rpc::invoke<rpc::upsert_subaddrs_response>(client, upsert_request);
const auto upsert_response = rpc::invoke<rpc::upsert_subaddrs_response>(client, client_prefix, upsert_request);
lock.lock();
if (upsert_response)
@@ -1105,7 +1105,7 @@ namespace lwsf { namespace internal { namespace backend
};
lock.unlock();
const auto provision_response = rpc::invoke<rpc::provision_subaddrs_response>(client, provision_request);
const auto provision_response = rpc::invoke<rpc::provision_subaddrs_response>(client, client_prefix, provision_request);
lock.lock();
if (provision_response)
@@ -1184,7 +1184,7 @@ namespace lwsf { namespace internal { namespace backend
};
lock.unlock();
const auto response = rpc::invoke<rpc::provision_subaddrs_response>(client, request);
const auto response = rpc::invoke<rpc::provision_subaddrs_response>(client, client_prefix, request);
lock.lock();
if (response)
server_lookahead = std::max(server_lookahead, needed_maj_i);
@@ -1224,7 +1224,7 @@ namespace lwsf { namespace internal { namespace backend
};
lock.unlock();
const auto response = rpc::invoke<rpc::provision_subaddrs_response>(client, request);
const auto response = rpc::invoke<rpc::provision_subaddrs_response>(client, client_prefix, request);
lock.lock();
if (response)
@@ -1266,7 +1266,7 @@ namespace lwsf { namespace internal { namespace backend
fill_upsert(*this, request.subaddrs_);
lock.unlock();
const auto response = rpc::invoke<rpc::upsert_subaddrs_response>(client, request);
const auto response = rpc::invoke<rpc::upsert_subaddrs_response>(client, client_prefix, request);
lock.lock();
if (!response)
return (lookahead_error = handle_lookahead_error(response.error()));
@@ -1306,7 +1306,7 @@ namespace lwsf { namespace internal { namespace backend
rpc::import_request login{{primary.address, primary.view.sec}, height};
lock.unlock();
auto import = rpc::invoke<rpc::import_response>(client, login);
auto import = rpc::invoke<rpc::import_response>(client, client_prefix, login);
lock.lock();
if (!import)
@@ -1364,7 +1364,7 @@ namespace lwsf { namespace internal { namespace backend
expect<std::vector<rpc::random_outputs>> wallet::get_decoys(const rpc::get_random_outs_request& req)
{
auto resp = rpc::invoke<rpc::get_random_outs_response>(client, req);
auto resp = rpc::invoke<rpc::get_random_outs_response>(client, client_prefix, req);
if (!resp)
return resp.error();
return {std::move(resp->amount_outs)};
@@ -1373,6 +1373,6 @@ namespace lwsf { namespace internal { namespace backend
std::error_code wallet::send_tx(epee::byte_slice tx_bytes)
{
const rpc::submit_raw_tx_request request{std::move(tx_bytes)};
return rpc::invoke<rpc::submit_raw_tx_response>(client, request).error();
return rpc::invoke<rpc::submit_raw_tx_response>(client, client_prefix, request).error();
}
}}} // lwsf // internal // backend
+1
View File
@@ -235,6 +235,7 @@ namespace lwsf { namespace internal { namespace backend
Monero::WalletListener* listener;
rpc::http_client client;
account primary;
std::string client_prefix;
std::vector<std::uint64_t> per_byte_fee; //!< by priority level
std::error_code refresh_error; //!< Cached because `refresh(...)` is rate limited
std::error_code lookahead_error; //!< warnings/errors of `server_lookahead` value
+8 -1
View File
@@ -92,7 +92,7 @@ namespace lwsf { namespace internal { namespace rpc
return instance;
}
expect<std::string> invoke_payload(http_client& client, const boost::string_ref endpoint, const epee::byte_slice payload)
expect<std::string> invoke_payload(http_client& client, const boost::string_ref prefix, boost::string_ref endpoint, const epee::byte_slice payload)
{
static const epee::net_utils::http::fields_list headers{
{"Content-Type", "application/json; charset=utf-8"}
@@ -104,6 +104,13 @@ namespace lwsf { namespace internal { namespace rpc
return {error::no_response};
}
std::string real;
if (!prefix.empty())
{
real = std::string{prefix} + std::string{endpoint};
endpoint = real;
}
const epee::net_utils::http::http_response_info* response = nullptr;
if (!client.invoke(endpoint, "POST", {reinterpret_cast<const char*>(payload.data()), payload.size()}, config::rpc_timeout, std::addressof(response), headers))
return {error::no_response};
+3 -3
View File
@@ -70,17 +70,17 @@ namespace lwsf { namespace internal { namespace rpc
}
//! Send `payload` to `client` at uri `endpoint`, and \return payload response
expect<std::string> invoke_payload(http_client& client, boost::string_ref endpoint, epee::byte_slice payload);
expect<std::string> invoke_payload(http_client& client, boost::string_ref prefix, boost::string_ref endpoint, epee::byte_slice payload);
template<typename F, typename G>
expect<F> invoke(http_client& client, const G& in)
expect<F> invoke(http_client& client, boost::string_ref prefix, const G& in)
{
epee::byte_stream sink{};
std::error_code error = wire::json::to_bytes(sink, in);
if (error)
return error;
expect<std::string> result = invoke_payload(client, F::endpoint(), epee::byte_slice{std::move(sink)});
expect<std::string> result = invoke_payload(client, prefix, F::endpoint(), epee::byte_slice{std::move(sink)});
if (!result)
return result.error();
+3 -2
View File
@@ -788,8 +788,6 @@ namespace lwsf { namespace internal
epee::net_utils::http::url_content url{};
if (!epee::net_utils::parse_url(daemon_address, url))
throw std::runtime_error{"Invalid LWS URL: " + daemon_address};
if (!url.m_uri_content.m_path.empty())
throw std::runtime_error{"LWS URL contains path (unsupported)"};
if (!proxy_address.empty() && !setProxy(proxy_address))
return false;
@@ -835,7 +833,10 @@ namespace lwsf { namespace internal
}
}
const boost::unique_lock<boost::mutex> lock{data_->sync};
data_->client.set_server(std::move(url.host), std::to_string(url.port), std::move(login), std::move(options));
data_->passed_login = false;
data_->client_prefix = std::move(url.uri);
}
catch (const std::exception& e)
{
+3 -3
View File
@@ -58,6 +58,7 @@ namespace lwsf
class wallet_manager : public Monero::WalletManager
{
rpc::http_client client_;
std::string client_prefix_;
std::string error_;
rpc::daemon_status cached_;
std::chrono::steady_clock::time_point cached_last_;
@@ -66,7 +67,7 @@ namespace lwsf
{
if (std::chrono::steady_clock::now() - cached_last_ > config::daemon_status_cache)
{
const auto resp = rpc::invoke<rpc::daemon_status>(client_, rpc::empty{});
const auto resp = rpc::invoke<rpc::daemon_status>(client_, client_prefix_, rpc::empty{});
if (!resp)
{
error_ = resp.error().message();
@@ -395,8 +396,6 @@ namespace lwsf
epee::net_utils::http::url_content url{};
if (!epee::net_utils::parse_url(address, url))
throw std::runtime_error{"Invalid LWS URL: " + address};
if (!url.m_uri_content.m_path.empty())
throw std::runtime_error{"LWS URL contains path (unsupported)"};
const bool use_ssl = (url.schema == "https");
epee::net_utils::ssl_options_t options{
@@ -411,6 +410,7 @@ namespace lwsf
url.port = 80;
}
client_prefix_ = std::move(url.uri);
client_.set_server(std::move(url.host), std::to_string(url.port), boost::none, std::move(options));
}