diff --git a/common/json_stream.c b/common/json_stream.c index 6e5d96c7e..45ac30ebd 100644 --- a/common/json_stream.c +++ b/common/json_stream.c @@ -82,6 +82,31 @@ void json_stream_append(struct json_stream *js, memcpy(dest, str, len); } +/* We promise it will end in '\n\n' */ +void json_stream_double_cr(struct json_stream *js) +{ + const char *contents; + size_t len, cr_needed; + + if (!js->jout) + return; + + /* Must be well-formed at this point! */ + json_out_finished(js->jout); + + contents = json_out_contents(js->jout, &len); + /* It's an object (with an id!): definitely can't be less that "{}" */ + assert(len >= 2); + if (contents[len-1] == '\n') { + if (contents[len-2] == '\n') + return; + cr_needed = 1; + } else + cr_needed = 2; + + json_stream_append(js, "\n\n", cr_needed); +} + void json_stream_close(struct json_stream *js, struct command *writer) { /* FIXME: We use writer == NULL for malformed: make writer a void *? @@ -89,8 +114,7 @@ void json_stream_close(struct json_stream *js, struct command *writer) assert(js->writer == writer); /* Should be well-formed at this point! */ - json_out_finished(js->jout); - json_stream_append(js, "\n\n", strlen("\n\n")); + json_stream_double_cr(js); json_stream_flush(js); js->writer = NULL; } diff --git a/common/json_stream.h b/common/json_stream.h index 0446d9fb4..816a09fe0 100644 --- a/common/json_stream.h +++ b/common/json_stream.h @@ -160,6 +160,8 @@ struct io_plan *json_stream_output_(struct json_stream *js, void *arg), void *arg); +/* Ensure there's a double \n after a JSON response. */ +void json_stream_double_cr(struct json_stream *js); void json_stream_flush(struct json_stream *js); #endif /* LIGHTNING_COMMON_JSON_STREAM_H */ diff --git a/lightningd/plugin.c b/lightningd/plugin.c index c737a08c6..10027eeb7 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -774,14 +774,6 @@ static void json_stream_forward_change_id(struct json_stream *stream, json_stream_append(stream, new_id, strlen(new_id)); json_stream_append(stream, buffer + idtok->end + offset, toks->end - idtok->end - offset); - - /* We promise it will end in '\n\n' */ - /* It's an object (with an id!): definitely can't be less that "{}" */ - assert(toks->end - toks->start >= 2); - if (buffer[toks->end-1] != '\n') - json_stream_append(stream, "\n\n", 2); - else if (buffer[toks->end-2] != '\n') - json_stream_append(stream, "\n", 1); } static void plugin_rpcmethod_cb(const char *buffer, @@ -794,6 +786,7 @@ static void plugin_rpcmethod_cb(const char *buffer, response = json_stream_raw_for_cmd(cmd); json_stream_forward_change_id(response, buffer, toks, idtok, cmd->id); + json_stream_double_cr(response); command_raw_complete(cmd, response); list_del(&call->list); @@ -851,6 +844,7 @@ static struct command_result *plugin_rpcmethod_dispatch(struct command *cmd, snprintf(id, ARRAY_SIZE(id), "%"PRIu64, req->id); json_stream_forward_change_id(req->stream, buffer, toks, idtok, id); + json_stream_double_cr(req->stream); plugin_request_send(plugin, req); req->stream = NULL;