libplugin: jsonrpc_request_whole_object_start() for more custom request handling.

commando wants to see the whole reply object, and also not to assume params is
an object.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2022-07-16 14:30:17 +09:30
parent d0a55a62b3
commit d3e64c3970
2 changed files with 33 additions and 7 deletions

View File

@@ -165,7 +165,8 @@ jsonrpc_request_start_(struct plugin *plugin, struct command *cmd,
json_add_string(out->js, "jsonrpc", "2.0");
json_add_u64(out->js, "id", out->id);
json_add_string(out->js, "method", method);
json_object_start(out->js, "params");
if (out->errcb)
json_object_start(out->js, "params");
return out;
}
@@ -551,16 +552,26 @@ static void handle_rpc_reply(struct plugin *plugin, const jsmntok_t *toks)
uintmap_del(&plugin->out_reqs, out->id);
contenttok = json_get_member(plugin->rpc_buffer, toks, "error");
if (contenttok)
res = out->errcb(out->cmd, plugin->rpc_buffer,
contenttok, out->arg);
else {
if (contenttok) {
if (out->errcb)
res = out->errcb(out->cmd, plugin->rpc_buffer,
contenttok, out->arg);
else
res = out->cb(out->cmd, plugin->rpc_buffer,
toks, out->arg);
} else {
contenttok = json_get_member(plugin->rpc_buffer, toks, "result");
if (!contenttok)
plugin_err(plugin, "Bad JSONRPC, no 'error' nor 'result': '%.*s'",
json_tok_full_len(toks),
json_tok_full(plugin->rpc_buffer, toks));
res = out->cb(out->cmd, plugin->rpc_buffer, contenttok, out->arg);
/* errcb is NULL if it's a single whole-object callback */
if (out->errcb)
res = out->cb(out->cmd, plugin->rpc_buffer, contenttok,
out->arg);
else
res = out->cb(out->cmd, plugin->rpc_buffer, toks,
out->arg);
}
assert(res == &pending || res == &complete);
@@ -570,7 +581,8 @@ struct command_result *
send_outreq(struct plugin *plugin, const struct out_req *req)
{
/* The "param" object. */
json_object_end(req->js);
if (req->errcb)
json_object_end(req->js);
json_object_end(req->js);
json_stream_close(req->js, req->cmd);

View File

@@ -117,6 +117,8 @@ struct out_req *jsonrpc_request_start_(struct plugin *plugin,
void *arg),
void *arg);
/* This variant has callbacks received whole obj, not "result" or
* "error" members. */
#define jsonrpc_request_start(plugin, cmd, method, cb, errcb, arg) \
jsonrpc_request_start_((plugin), (cmd), (method), \
typesafe_cb_preargs(struct command_result *, void *, \
@@ -132,6 +134,18 @@ struct out_req *jsonrpc_request_start_(struct plugin *plugin,
(arg))
/* This variant has callbacks received whole obj, not "result" or
* "error" members. It also doesn't start params{}. */
#define jsonrpc_request_whole_object_start(plugin, cmd, method, cb, arg) \
jsonrpc_request_start_((plugin), (cmd), (method), \
typesafe_cb_preargs(struct command_result *, void *, \
(cb), (arg), \
struct command *command, \
const char *buf, \
const jsmntok_t *result), \
NULL, \
(arg))
/* Helper to create a JSONRPC2 response stream with a "result" object. */
struct json_stream *jsonrpc_stream_success(struct command *cmd);