|
11 | 11 | #include <common/json_filter.h> |
12 | 12 | #include <common/json_param.h> |
13 | 13 | #include <common/json_stream.h> |
| 14 | +#include <common/jsonrpc_io.h> |
14 | 15 | #include <common/memleak.h> |
15 | 16 | #include <common/plugin.h> |
16 | 17 | #include <common/route.h> |
@@ -98,10 +99,8 @@ struct plugin { |
98 | 99 | /* Asynchronous RPC interaction */ |
99 | 100 | struct io_conn *io_rpc_conn; |
100 | 101 | struct list_head rpc_js_list; |
101 | | - char *rpc_buffer; |
102 | | - size_t rpc_used, rpc_len_read, rpc_read_offset; |
103 | | - jsmn_parser rpc_parser; |
104 | | - jsmntok_t *rpc_toks; |
| 102 | + struct jsonrpc_io *jsonrpc_in; |
| 103 | + |
105 | 104 | /* Tracking async RPC requests */ |
106 | 105 | STRMAP(struct out_req *) out_reqs; |
107 | 106 | u64 next_outreq_id; |
@@ -1365,73 +1364,33 @@ static void rpc_conn_finished(struct io_conn *conn, |
1365 | 1364 | plugin_err(plugin, "Lost connection to the RPC socket."); |
1366 | 1365 | } |
1367 | 1366 |
|
1368 | | -static bool rpc_read_response_one(struct plugin *plugin) |
1369 | | -{ |
1370 | | - const jsmntok_t *jrtok; |
1371 | | - bool complete; |
1372 | | - |
1373 | | - if (!json_parse_input(&plugin->rpc_parser, &plugin->rpc_toks, |
1374 | | - plugin->rpc_buffer + plugin->rpc_read_offset, |
1375 | | - plugin->rpc_used - plugin->rpc_read_offset, |
1376 | | - &complete)) { |
1377 | | - plugin_err(plugin, "Failed to parse RPC JSON response '%.*s'", |
1378 | | - (int)(plugin->rpc_used - plugin->rpc_read_offset), |
1379 | | - plugin->rpc_buffer + plugin->rpc_read_offset); |
1380 | | - } |
1381 | | - |
1382 | | - if (!complete) { |
1383 | | - /* We need more. */ |
1384 | | - goto compact; |
1385 | | - } |
1386 | | - |
1387 | | - /* Empty buffer? (eg. just whitespace). */ |
1388 | | - if (tal_count(plugin->rpc_toks) == 1) { |
1389 | | - jsmn_init(&plugin->rpc_parser); |
1390 | | - toks_reset(plugin->rpc_toks); |
1391 | | - goto compact; |
1392 | | - } |
1393 | | - |
1394 | | - jrtok = json_get_member(plugin->rpc_buffer + plugin->rpc_read_offset, |
1395 | | - plugin->rpc_toks, "jsonrpc"); |
1396 | | - if (!jrtok) { |
1397 | | - plugin_err(plugin, "JSON-RPC message does not contain \"jsonrpc\" field: '%.*s'", |
1398 | | - (int)(plugin->rpc_used - plugin->rpc_read_offset), |
1399 | | - plugin->rpc_buffer + plugin->rpc_read_offset); |
1400 | | - } |
1401 | | - |
1402 | | - handle_rpc_reply(plugin, plugin->rpc_buffer + plugin->rpc_read_offset, plugin->rpc_toks); |
1403 | | - |
1404 | | - /* Move this object out of the buffer */ |
1405 | | - plugin->rpc_read_offset += plugin->rpc_toks[0].end; |
1406 | | - jsmn_init(&plugin->rpc_parser); |
1407 | | - toks_reset(plugin->rpc_toks); |
1408 | | - return true; |
1409 | | - |
1410 | | -compact: |
1411 | | - memmove(plugin->rpc_buffer, plugin->rpc_buffer + plugin->rpc_read_offset, |
1412 | | - plugin->rpc_used - plugin->rpc_read_offset); |
1413 | | - plugin->rpc_used -= plugin->rpc_read_offset; |
1414 | | - plugin->rpc_read_offset = 0; |
1415 | | - return false; |
1416 | | -} |
1417 | 1367 |
|
1418 | 1368 | static struct io_plan *rpc_conn_read_response(struct io_conn *conn, |
1419 | 1369 | struct plugin *plugin) |
1420 | 1370 | { |
1421 | | - plugin->rpc_used += plugin->rpc_len_read; |
1422 | | - if (plugin->rpc_used == tal_count(plugin->rpc_buffer)) |
1423 | | - tal_resize(&plugin->rpc_buffer, plugin->rpc_used * 2); |
| 1371 | + /* Gather an parse any new bytes */ |
| 1372 | + for (;;) { |
| 1373 | + const jsmntok_t *toks; |
| 1374 | + const char *buf; |
| 1375 | + const char *err; |
1424 | 1376 |
|
1425 | | - /* Read and process all messages from the connection */ |
1426 | | - while (rpc_read_response_one(plugin)) |
1427 | | - ; |
| 1377 | + err = jsonrpc_io_parse(tmpctx, |
| 1378 | + plugin->jsonrpc_in, |
| 1379 | + &toks, &buf); |
| 1380 | + if (err) |
| 1381 | + plugin_err(plugin, "%s", err); |
| 1382 | + |
| 1383 | + if (!toks) |
| 1384 | + break; |
| 1385 | + |
| 1386 | + handle_rpc_reply(plugin, buf, toks); |
| 1387 | + jsonrpc_io_parse_done(plugin->jsonrpc_in); |
| 1388 | + } |
1428 | 1389 |
|
1429 | | - /* Read more, if there is. */ |
1430 | | - return io_read_partial(plugin->io_rpc_conn, |
1431 | | - plugin->rpc_buffer + plugin->rpc_used, |
1432 | | - tal_bytelen(plugin->rpc_buffer) - plugin->rpc_used, |
1433 | | - &plugin->rpc_len_read, |
1434 | | - rpc_conn_read_response, plugin); |
| 1390 | + /* Read more */ |
| 1391 | + return jsonrpc_io_read(conn, plugin->jsonrpc_in, |
| 1392 | + rpc_conn_read_response, |
| 1393 | + plugin); |
1435 | 1394 | } |
1436 | 1395 |
|
1437 | 1396 | static struct io_plan *rpc_conn_write_request(struct io_conn *conn, |
@@ -2416,14 +2375,9 @@ static struct plugin *new_plugin(const tal_t *ctx, |
2416 | 2375 | jsmn_init(&p->parser); |
2417 | 2376 | p->toks = toks_alloc(p); |
2418 | 2377 | /* Async RPC */ |
2419 | | - p->rpc_buffer = tal_arr(p, char, 64); |
| 2378 | + p->jsonrpc_in = jsonrpc_io_new(p); |
2420 | 2379 | list_head_init(&p->rpc_js_list); |
2421 | 2380 | p->io_rpc_conn = NULL; |
2422 | | - p->rpc_used = 0; |
2423 | | - p->rpc_read_offset = 0; |
2424 | | - p->rpc_len_read = 0; |
2425 | | - jsmn_init(&p->rpc_parser); |
2426 | | - p->rpc_toks = toks_alloc(p); |
2427 | 2381 | p->next_outreq_id = 0; |
2428 | 2382 | strmap_init(&p->out_reqs); |
2429 | 2383 | p->beglist = NULL; |
|
0 commit comments