diff options
author | Matthew Zipkin <pinheadmz@gmail.com> | 2023-02-27 13:03:45 -0500 |
---|---|---|
committer | Ryan Ofsky <ryan@ofsky.org> | 2024-03-07 19:13:27 -0500 |
commit | a64a2b77e09bff784a2635ba19ff4aa6582bb5a5 (patch) | |
tree | 445a07f3a8882d1650351ab3bf1fb403bced68cf /src/httprpc.cpp | |
parent | df6e3756d6feaf1856e7886820b70874209fd90b (diff) | |
download | bitcoin-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.cpp | 24 |
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; |