2525#include <common/codex32.h>
2626#include <common/json_command.h>
2727#include <common/json_filter.h>
28+ #include <common/jsonrpc_io.h>
2829#include <common/memleak.h>
2930#include <common/timeout.h>
3031#include <common/trace.h>
@@ -78,18 +79,8 @@ struct json_connection {
7879 /* Logging for this json connection. */
7980 struct logger * log ;
8081
81- /* The buffer (required to interpret tokens). */
82- char * buffer ;
83-
84- /* Internal state: */
85- /* How much is already filled. */
86- size_t used ;
87- /* How much has just been filled. */
88- size_t len_read ;
89-
90- /* JSON parsing state. */
91- jsmn_parser input_parser ;
92- jsmntok_t * input_toks ;
82+ /* The buffer and state reading in the JSON commands */
83+ struct jsonrpc_io * json_in ;
9384
9485 /* Local deprecated support? */
9586 bool deprecated_ok ;
@@ -1210,93 +1201,61 @@ static struct io_plan *stream_out_complete(struct io_conn *conn,
12101201static struct io_plan * read_json (struct io_conn * conn ,
12111202 struct json_connection * jcon )
12121203{
1213- bool complete ;
12141204 bool in_transaction = false;
12151205 struct timemono start_time = time_mono ();
1206+ size_t len_read ;
1207+ const jsmntok_t * toks ;
1208+ const char * buffer , * error ;
12161209
1217- if (jcon -> len_read )
1218- log_io (jcon -> log , LOG_IO_IN , NULL , "" ,
1219- jcon -> buffer + jcon -> used , jcon -> len_read );
1220-
1221- /* Resize larger if we're full. */
1222- jcon -> used += jcon -> len_read ;
1223- if (jcon -> used == tal_count (jcon -> buffer ))
1224- tal_resize (& jcon -> buffer , jcon -> used * 2 );
1210+ buffer = jsonrpc_newly_read (jcon -> json_in , & len_read );
1211+ if (len_read )
1212+ log_io (jcon -> log , LOG_IO_IN , NULL , "" , buffer , len_read );
12251213
12261214 /* We wait for pending output to be consumed, to avoid DoS */
12271215 if (tal_count (jcon -> js_arr ) != 0 ) {
1228- jcon -> len_read = 0 ;
12291216 return io_wait (conn , conn , read_json , jcon );
12301217 }
12311218
12321219again :
1233- if (!json_parse_input (& jcon -> input_parser , & jcon -> input_toks ,
1234- jcon -> buffer , jcon -> used ,
1235- & complete )) {
1236- json_command_malformed (
1237- jcon , "null" ,
1238- tal_fmt (tmpctx , "Invalid token in json input: '%s'" ,
1239- tal_hexstr (tmpctx , jcon -> buffer , jcon -> used )));
1220+ error = jsonrpc_io_parse (tmpctx , jcon -> json_in , & toks , & buffer );
1221+ if (error ) {
1222+ json_command_malformed (jcon , "null" , error );
12401223 if (in_transaction )
12411224 db_commit_transaction (jcon -> ld -> wallet -> db );
12421225 return io_halfclose (conn );
12431226 }
12441227
1245- if (!complete )
1246- goto read_more ;
1247-
1248- /* Empty buffer? (eg. just whitespace). */
1249- if (tal_count (jcon -> input_toks ) == 1 ) {
1250- jcon -> used = 0 ;
1251-
1252- /* Reset parser. */
1253- jsmn_init (& jcon -> input_parser );
1254- toks_reset (jcon -> input_toks );
1228+ if (!toks )
12551229 goto read_more ;
1256- }
12571230
12581231 if (!in_transaction ) {
12591232 db_begin_transaction (jcon -> ld -> wallet -> db );
12601233 in_transaction = true;
12611234 }
1262- parse_request (jcon , jcon -> buffer , jcon -> input_toks );
1263-
1264- /* Remove first {}. */
1265- memmove (jcon -> buffer , jcon -> buffer + jcon -> input_toks [0 ].end ,
1266- tal_count (jcon -> buffer ) - jcon -> input_toks [0 ].end );
1267- jcon -> used -= jcon -> input_toks [0 ].end ;
1268-
1269- /* Reset parser. */
1270- jsmn_init (& jcon -> input_parser );
1271- toks_reset (jcon -> input_toks );
1235+ parse_request (jcon , buffer , toks );
1236+ jsonrpc_io_parse_done (jcon -> json_in );
12721237
1273- /* Do we have more already read? */
1274- if (jcon -> used ) {
1275- if (!jcon -> db_batching ) {
1238+ if (!jcon -> db_batching ) {
1239+ db_commit_transaction (jcon -> ld -> wallet -> db );
1240+ in_transaction = false;
1241+ } else {
1242+ /* FIXME: io_always() should interleave with
1243+ * real IO, and then we should rotate order we
1244+ * service fds in, to avoid starvation. */
1245+ if (time_greater (timemono_between (time_mono (),
1246+ start_time ),
1247+ time_from_msec (250 ))) {
12761248 db_commit_transaction (jcon -> ld -> wallet -> db );
1277- in_transaction = false;
1278- } else {
1279- /* FIXME: io_always() should interleave with
1280- * real IO, and then we should rotate order we
1281- * service fds in, to avoid starvation. */
1282- if (time_greater (timemono_between (time_mono (),
1283- start_time ),
1284- time_from_msec (250 ))) {
1285- db_commit_transaction (jcon -> ld -> wallet -> db );
1286- /* Call us back, as if we read nothing new */
1287- jcon -> len_read = 0 ;
1288- return io_always (conn , read_json , jcon );
1289- }
1249+ /* Call us back, as if we read nothing new */
1250+ return io_always (conn , read_json , jcon );
12901251 }
1291- goto again ;
12921252 }
1253+ goto again ;
12931254
12941255read_more :
12951256 if (in_transaction )
12961257 db_commit_transaction (jcon -> ld -> wallet -> db );
1297- return io_read_partial (conn , jcon -> buffer + jcon -> used ,
1298- tal_count (jcon -> buffer ) - jcon -> used ,
1299- & jcon -> len_read , read_json , jcon );
1258+ return jsonrpc_io_read (conn , jcon -> json_in , read_json , jcon );
13001259}
13011260
13021261static struct io_plan * jcon_connected (struct io_conn * conn ,
@@ -1308,12 +1267,8 @@ static struct io_plan *jcon_connected(struct io_conn *conn,
13081267 jcon = notleak (tal (conn , struct json_connection ));
13091268 jcon -> conn = conn ;
13101269 jcon -> ld = ld ;
1311- jcon -> used = 0 ;
1312- jcon -> buffer = tal_arr (jcon , char , 64 );
13131270 jcon -> js_arr = tal_arr (jcon , struct json_stream * , 0 );
1314- jcon -> len_read = 0 ;
1315- jsmn_init (& jcon -> input_parser );
1316- jcon -> input_toks = toks_alloc (jcon );
1271+ jcon -> json_in = jsonrpc_io_new (jcon );
13171272 jcon -> notifications_enabled = false;
13181273 jcon -> db_batching = false;
13191274 jcon -> deprecated_ok = ld -> deprecated_ok ;
0 commit comments