| 1005 | } |
| 1006 | |
| 1007 | static struct io_plan *read_json(struct io_conn *conn, |
| 1008 | struct json_connection *jcon) |
| 1009 | { |
| 1010 | bool complete; |
| 1011 | bool in_transaction = false; |
| 1012 | struct timemono start_time = time_mono(); |
| 1013 | |
| 1014 | if (jcon->len_read) |
| 1015 | log_io(jcon->log, LOG_IO_IN, NULL, "", |
| 1016 | jcon->buffer + jcon->used, jcon->len_read); |
| 1017 | |
| 1018 | /* Resize larger if we're full. */ |
| 1019 | jcon->used += jcon->len_read; |
| 1020 | if (jcon->used == tal_count(jcon->buffer)) |
| 1021 | tal_resize(&jcon->buffer, jcon->used * 2); |
| 1022 | |
| 1023 | /* We wait for pending output to be consumed, to avoid DoS */ |
| 1024 | if (tal_count(jcon->js_arr) != 0) { |
| 1025 | jcon->len_read = 0; |
| 1026 | return io_wait(conn, conn, read_json, jcon); |
| 1027 | } |
| 1028 | |
| 1029 | again: |
| 1030 | if (!json_parse_input(&jcon->input_parser, &jcon->input_toks, |
| 1031 | jcon->buffer, jcon->used, |
| 1032 | &complete)) { |
| 1033 | json_command_malformed( |
| 1034 | jcon, "null", |
| 1035 | tal_fmt(tmpctx, "Invalid token in json input: '%s'", |
| 1036 | tal_strndup(tmpctx, jcon->buffer, jcon->used))); |
| 1037 | if (in_transaction) |
| 1038 | db_commit_transaction(jcon->ld->wallet->db); |
| 1039 | return io_halfclose(conn); |
| 1040 | } |
| 1041 | |
| 1042 | if (!complete) |
| 1043 | goto read_more; |
| 1044 | |
| 1045 | /* Empty buffer? (eg. just whitespace). */ |
| 1046 | if (tal_count(jcon->input_toks) == 1) { |
| 1047 | jcon->used = 0; |
| 1048 | |
| 1049 | /* Reset parser. */ |
| 1050 | jsmn_init(&jcon->input_parser); |
| 1051 | toks_reset(jcon->input_toks); |
| 1052 | goto read_more; |
| 1053 | } |
| 1054 | |
| 1055 | if (!in_transaction) { |
| 1056 | db_begin_transaction(jcon->ld->wallet->db); |
| 1057 | in_transaction = true; |
| 1058 | } |
| 1059 | parse_request(jcon, jcon->input_toks); |
| 1060 | |
| 1061 | /* Remove first {}. */ |
| 1062 | memmove(jcon->buffer, jcon->buffer + jcon->input_toks[0].end, |
| 1063 | tal_count(jcon->buffer) - jcon->input_toks[0].end); |
| 1064 | jcon->used -= jcon->input_toks[0].end; |
no test coverage detected