aboutsummaryrefslogtreecommitdiff
path: root/src/httprpc.cpp
diff options
context:
space:
mode:
authorMatthew Zipkin <pinheadmz@gmail.com>2023-02-27 13:03:45 -0500
committerRyan Ofsky <ryan@ofsky.org>2024-03-07 19:13:27 -0500
commita64a2b77e09bff784a2635ba19ff4aa6582bb5a5 (patch)
tree445a07f3a8882d1650351ab3bf1fb403bced68cf /src/httprpc.cpp
parentdf6e3756d6feaf1856e7886820b70874209fd90b (diff)
downloadbitcoin-a64a2b77e09bff784a2635ba19ff4aa6582bb5a5.tar.xz
rpc: refactor single/batch requests
Simplify the request handling flow so that errors and results only come from JSONRPCExec()
Diffstat (limited to 'src/httprpc.cpp')
-rw-r--r--src/httprpc.cpp24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/httprpc.cpp b/src/httprpc.cpp
index aef20c24fc..53f994efd7 100644
--- a/src/httprpc.cpp
+++ b/src/httprpc.cpp
@@ -185,7 +185,7 @@ static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req)
// Set the URI
jreq.URI = req->GetURI();
- std::string strReply;
+ UniValue reply;
bool user_has_whitelist = g_rpc_whitelist.count(jreq.authUser);
if (!user_has_whitelist && g_rpc_whitelist_default) {
LogPrintf("RPC User %s not allowed to call any methods\n", jreq.authUser);
@@ -200,13 +200,12 @@ static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req)
req->WriteReply(HTTP_FORBIDDEN);
return false;
}
- UniValue result = tableRPC.execute(jreq);
- // Send reply
- strReply = JSONRPCReplyObj(std::move(result), NullUniValue, jreq.id).write() + "\n";
+ reply = JSONRPCExec(jreq);
// array of requests
} else if (valRequest.isArray()) {
+ // Check authorization for each request's method
if (user_has_whitelist) {
for (unsigned int reqIdx = 0; reqIdx < valRequest.size(); reqIdx++) {
if (!valRequest[reqIdx].isObject()) {
@@ -223,13 +222,26 @@ static bool HTTPReq_JSONRPC(const std::any& context, HTTPRequest* req)
}
}
}
- strReply = JSONRPCExecBatch(jreq, valRequest.get_array());
+
+ // Execute each request
+ reply = UniValue::VARR;
+ for (size_t i{0}; i < valRequest.size(); ++i) {
+ // Batches include errors in the batch response, they do not throw
+ try {
+ jreq.parse(valRequest[i]);
+ reply.push_back(JSONRPCExec(jreq));
+ } catch (UniValue& e) {
+ reply.push_back(JSONRPCReplyObj(NullUniValue, std::move(e), jreq.id));
+ } catch (const std::exception& e) {
+ reply.push_back(JSONRPCReplyObj(NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id));
+ }
+ }
}
else
throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
req->WriteHeader("Content-Type", "application/json");
- req->WriteReply(HTTP_OK, strReply);
+ req->WriteReply(HTTP_OK, reply.write() + "\n");
} catch (UniValue& e) {
JSONErrorReply(req, std::move(e), jreq.id);
return false;