mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-19 21:27:57 +00:00
Implement HTTP GET /restful/meshms/<SID>/conversationlist.json
This commit is contained in:
parent
94274ba5fa
commit
8897563d09
@ -2084,3 +2084,28 @@ void http_request_simple_response(struct http_request *r, uint16_t result, const
|
||||
r->response.content_generator = NULL;
|
||||
http_request_start_response(r);
|
||||
}
|
||||
|
||||
int generate_http_content_from_strbuf_chunks(
|
||||
struct http_request *r,
|
||||
char *buf,
|
||||
size_t bufsz,
|
||||
struct http_content_generator_result *result,
|
||||
HTTP_CONTENT_GENERATOR_STRBUF_CHUNKER *chunker
|
||||
)
|
||||
{
|
||||
assert(bufsz > 0);
|
||||
strbuf b = strbuf_local((char *)buf, bufsz);
|
||||
int ret;
|
||||
while ((ret = chunker(r, b)) != -1) {
|
||||
if (strbuf_overrun(b)) {
|
||||
if (r->debug_flag && *r->debug_flag)
|
||||
DEBUGF("overrun by %zu bytes", strbuf_count(b) - strbuf_len(b));
|
||||
result->need = strbuf_count(b) + 1 - result->generated;
|
||||
break;
|
||||
}
|
||||
result->generated = strbuf_len(b);
|
||||
if (ret == 0)
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -152,6 +152,9 @@ void http_request_response_static(struct http_request *r, int result, const char
|
||||
void http_request_response_generated(struct http_request *r, int result, const char *mime_type, HTTP_CONTENT_GENERATOR *);
|
||||
void http_request_simple_response(struct http_request *r, uint16_t result, const char *body);
|
||||
|
||||
typedef int (HTTP_CONTENT_GENERATOR_STRBUF_CHUNKER)(struct http_request *, strbuf);
|
||||
int generate_http_content_from_strbuf_chunks(struct http_request *, char *, size_t, struct http_content_generator_result *, HTTP_CONTENT_GENERATOR_STRBUF_CHUNKER *);
|
||||
|
||||
typedef int HTTP_REQUEST_PARSER(struct http_request *);
|
||||
typedef void HTTP_RENDERER(struct http_request *, strbuf);
|
||||
|
||||
|
196
rhizome_http.c
196
rhizome_http.c
@ -50,6 +50,7 @@ static HTTP_HANDLER restful_rhizome_bundlelist_json;
|
||||
static HTTP_HANDLER restful_rhizome_newsince;
|
||||
static HTTP_HANDLER restful_rhizome_insert;
|
||||
static HTTP_HANDLER restful_rhizome_;
|
||||
static HTTP_HANDLER restful_meshms_;
|
||||
|
||||
static HTTP_HANDLER rhizome_status_page;
|
||||
static HTTP_HANDLER rhizome_file_page;
|
||||
@ -68,6 +69,7 @@ struct http_handler paths[]={
|
||||
{"/restful/rhizome/newsince/", restful_rhizome_newsince},
|
||||
{"/restful/rhizome/insert", restful_rhizome_insert},
|
||||
{"/restful/rhizome/", restful_rhizome_},
|
||||
{"/restful/meshms/", restful_meshms_},
|
||||
{"/rhizome/status", rhizome_status_page},
|
||||
{"/rhizome/file/", rhizome_file_page},
|
||||
{"/rhizome/import", rhizome_direct_import},
|
||||
@ -255,6 +257,12 @@ static void finalise_union_rhizome_insert(rhizome_http_request *r)
|
||||
rhizome_fail_write(&r->u.insert.write);
|
||||
}
|
||||
|
||||
static void finalise_union_meshms_conversationlist(rhizome_http_request *r)
|
||||
{
|
||||
meshms_free_conversations(r->u.mclist.conv);
|
||||
r->u.mclist.conv = NULL;
|
||||
}
|
||||
|
||||
static void rhizome_server_finalise_http_request(struct http_request *hr)
|
||||
{
|
||||
rhizome_http_request *r = (rhizome_http_request *) hr;
|
||||
@ -424,13 +432,26 @@ static int restful_rhizome_bundlelist_json(rhizome_http_request *r, const char *
|
||||
int ret = authorize(&r->http);
|
||||
if (ret)
|
||||
return ret;
|
||||
r->u.list.phase = LIST_HEADER;
|
||||
r->u.list.rowcount = 0;
|
||||
bzero(&r->u.list.cursor, sizeof r->u.list.cursor);
|
||||
r->u.rhlist.phase = LIST_HEADER;
|
||||
r->u.rhlist.rowcount = 0;
|
||||
bzero(&r->u.rhlist.cursor, sizeof r->u.rhlist.cursor);
|
||||
http_request_response_generated(&r->http, 200, "application/json", restful_rhizome_bundlelist_json_content);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HTTP_CONTENT_GENERATOR_STRBUF_CHUNKER restful_rhizome_bundlelist_json_content_chunk;
|
||||
|
||||
static int restful_rhizome_bundlelist_json_content(struct http_request *hr, unsigned char *buf, size_t bufsz, struct http_content_generator_result *result)
|
||||
{
|
||||
rhizome_http_request *r = (rhizome_http_request *) hr;
|
||||
int ret = rhizome_list_open(&r->u.rhlist.cursor);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
ret = generate_http_content_from_strbuf_chunks(hr, (char *)buf, bufsz, result, restful_rhizome_bundlelist_json_content_chunk);
|
||||
rhizome_list_release(&r->u.rhlist.cursor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int restful_rhizome_newsince(rhizome_http_request *r, const char *remainder)
|
||||
{
|
||||
r->http.response.header.content_type = "application/json";
|
||||
@ -445,17 +466,18 @@ static int restful_rhizome_newsince(rhizome_http_request *r, const char *remaind
|
||||
int ret = authorize(&r->http);
|
||||
if (ret)
|
||||
return ret;
|
||||
r->u.list.phase = LIST_HEADER;
|
||||
r->u.list.rowcount = 0;
|
||||
bzero(&r->u.list.cursor, sizeof r->u.list.cursor);
|
||||
r->u.list.cursor.rowid_since = rowid;
|
||||
r->u.list.end_time = gettime_ms() + config.rhizome.api.restful.newsince_timeout * 1000;
|
||||
r->u.rhlist.phase = LIST_HEADER;
|
||||
r->u.rhlist.rowcount = 0;
|
||||
bzero(&r->u.rhlist.cursor, sizeof r->u.rhlist.cursor);
|
||||
r->u.rhlist.cursor.rowid_since = rowid;
|
||||
r->u.rhlist.end_time = gettime_ms() + config.rhizome.api.restful.newsince_timeout * 1000;
|
||||
http_request_response_generated(&r->http, 200, "application/json", restful_rhizome_bundlelist_json_content);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int restful_rhizome_bundlelist_json_content_chunk(struct rhizome_http_request *r, strbuf b)
|
||||
static int restful_rhizome_bundlelist_json_content_chunk(struct http_request *hr, strbuf b)
|
||||
{
|
||||
rhizome_http_request *r = (rhizome_http_request *) hr;
|
||||
const char *headers[] = {
|
||||
".token",
|
||||
"_id",
|
||||
@ -472,7 +494,7 @@ static int restful_rhizome_bundlelist_json_content_chunk(struct rhizome_http_req
|
||||
"recipient",
|
||||
"name"
|
||||
};
|
||||
switch (r->u.list.phase) {
|
||||
switch (r->u.rhlist.phase) {
|
||||
case LIST_HEADER:
|
||||
strbuf_puts(b, "{\n\"header\":[");
|
||||
unsigned i;
|
||||
@ -483,36 +505,36 @@ static int restful_rhizome_bundlelist_json_content_chunk(struct rhizome_http_req
|
||||
}
|
||||
strbuf_puts(b, "],\n\"rows\":[");
|
||||
if (!strbuf_overrun(b))
|
||||
r->u.list.phase = LIST_ROWS;
|
||||
r->u.rhlist.phase = LIST_ROWS;
|
||||
return 1;
|
||||
case LIST_ROWS:
|
||||
{
|
||||
int ret = rhizome_list_next(&r->u.list.cursor);
|
||||
int ret = rhizome_list_next(&r->u.rhlist.cursor);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
if (ret == 0) {
|
||||
time_ms_t now;
|
||||
if (r->u.list.cursor.rowid_since == 0 || (now = gettime_ms()) >= r->u.list.end_time) {
|
||||
if (r->u.rhlist.cursor.rowid_since == 0 || (now = gettime_ms()) >= r->u.rhlist.end_time) {
|
||||
strbuf_puts(b, "\n]\n}\n");
|
||||
if (!strbuf_overrun(b))
|
||||
r->u.list.phase = LIST_DONE;
|
||||
r->u.rhlist.phase = LIST_DONE;
|
||||
return 0;
|
||||
}
|
||||
time_ms_t wake_at = now + config.rhizome.api.restful.newsince_poll_ms;
|
||||
if (wake_at > r->u.list.end_time)
|
||||
wake_at = r->u.list.end_time;
|
||||
if (wake_at > r->u.rhlist.end_time)
|
||||
wake_at = r->u.rhlist.end_time;
|
||||
http_request_pause_response(&r->http, wake_at);
|
||||
return 0;
|
||||
}
|
||||
rhizome_manifest *m = r->u.list.cursor.manifest;
|
||||
rhizome_manifest *m = r->u.rhlist.cursor.manifest;
|
||||
assert(m->filesize != RHIZOME_SIZE_UNSET);
|
||||
rhizome_lookup_author(m);
|
||||
if (r->u.list.rowcount != 0)
|
||||
if (r->u.rhlist.rowcount != 0)
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_puts(b, "\n[");
|
||||
if (m->rowid > r->u.list.rowid_highest) {
|
||||
if (m->rowid > r->u.rhlist.rowid_highest) {
|
||||
strbuf_json_string(b, alloca_list_token(m->rowid));
|
||||
r->u.list.rowid_highest = m->rowid;
|
||||
r->u.rhlist.rowid_highest = m->rowid;
|
||||
} else
|
||||
strbuf_json_null(b);
|
||||
strbuf_putc(b, ',');
|
||||
@ -552,8 +574,8 @@ static int restful_rhizome_bundlelist_json_content_chunk(struct rhizome_http_req
|
||||
strbuf_json_string(b, m->name);
|
||||
strbuf_puts(b, "]");
|
||||
if (!strbuf_overrun(b)) {
|
||||
rhizome_list_commit(&r->u.list.cursor);
|
||||
++r->u.list.rowcount;
|
||||
rhizome_list_commit(&r->u.rhlist.cursor);
|
||||
++r->u.rhlist.rowcount;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -563,29 +585,6 @@ static int restful_rhizome_bundlelist_json_content_chunk(struct rhizome_http_req
|
||||
abort();
|
||||
}
|
||||
|
||||
static int restful_rhizome_bundlelist_json_content(struct http_request *hr, unsigned char *buf, size_t bufsz, struct http_content_generator_result *result)
|
||||
{
|
||||
rhizome_http_request *r = (rhizome_http_request *) hr;
|
||||
assert(bufsz > 0);
|
||||
int ret = rhizome_list_open(&r->u.list.cursor);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
strbuf b = strbuf_local((char *)buf, bufsz);
|
||||
while ((ret = restful_rhizome_bundlelist_json_content_chunk(r, b)) != -1) {
|
||||
if (strbuf_overrun(b)) {
|
||||
if (config.debug.rhizome)
|
||||
DEBUGF("overrun by %zu bytes", strbuf_count(b) - strbuf_len(b));
|
||||
result->need = strbuf_count(b) + 1 - result->generated;
|
||||
break;
|
||||
}
|
||||
result->generated = strbuf_len(b);
|
||||
if (ret == 0)
|
||||
break;
|
||||
}
|
||||
rhizome_list_release(&r->u.list.cursor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HTTP_REQUEST_PARSER restful_rhizome_insert_end;
|
||||
static int insert_mime_part_start(struct http_request *);
|
||||
static int insert_mime_part_end(struct http_request *);
|
||||
@ -1049,6 +1048,113 @@ static int restful_rhizome_bid_decrypted_bin(rhizome_http_request *r, const char
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HTTP_HANDLER restful_meshms_conversationlist_json;
|
||||
|
||||
static int restful_meshms_(rhizome_http_request *r, const char *remainder)
|
||||
{
|
||||
r->http.response.header.content_type = "application/json";
|
||||
if (!is_rhizome_http_enabled())
|
||||
return 403;
|
||||
HTTP_HANDLER *handler = NULL;
|
||||
const char *end;
|
||||
if (strn_to_sid_t(&r->sid, remainder, &end) != -1) {
|
||||
if (strcmp(end, "/conversationlist.json") == 0) {
|
||||
handler = restful_meshms_conversationlist_json;
|
||||
remainder = "";
|
||||
}
|
||||
}
|
||||
if (handler == NULL)
|
||||
return 404;
|
||||
if (r->http.verb != HTTP_VERB_GET)
|
||||
return 405;
|
||||
int ret = authorize(&r->http);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = handler(r, remainder);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HTTP_CONTENT_GENERATOR restful_meshms_conversationlist_json_content;
|
||||
|
||||
static int restful_meshms_conversationlist_json(rhizome_http_request *r, const char *remainder)
|
||||
{
|
||||
if (*remainder)
|
||||
return 404;
|
||||
assert(r->finalise_union == NULL);
|
||||
r->finalise_union = finalise_union_meshms_conversationlist;
|
||||
r->u.mclist.phase = LIST_HEADER;
|
||||
r->u.mclist.rowcount = 0;
|
||||
r->u.mclist.conv = NULL;
|
||||
if (meshms_conversations_list(&r->sid, NULL, &r->u.mclist.conv))
|
||||
return -1;
|
||||
meshms_conversation_iterator_start(&r->u.mclist.iter, r->u.mclist.conv);
|
||||
http_request_response_generated(&r->http, 200, "application/json", restful_meshms_conversationlist_json_content);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HTTP_CONTENT_GENERATOR_STRBUF_CHUNKER restful_meshms_conversationlist_json_content_chunk;
|
||||
|
||||
static int restful_meshms_conversationlist_json_content(struct http_request *hr, unsigned char *buf, size_t bufsz, struct http_content_generator_result *result)
|
||||
{
|
||||
return generate_http_content_from_strbuf_chunks(hr, (char *)buf, bufsz, result, restful_meshms_conversationlist_json_content_chunk);
|
||||
}
|
||||
|
||||
static int restful_meshms_conversationlist_json_content_chunk(struct http_request *hr, strbuf b)
|
||||
{
|
||||
rhizome_http_request *r = (rhizome_http_request *) hr;
|
||||
const char *headers[] = {
|
||||
"_id",
|
||||
"recipient",
|
||||
"read",
|
||||
"last_message",
|
||||
"read_offset"
|
||||
};
|
||||
switch (r->u.mclist.phase) {
|
||||
case LIST_HEADER:
|
||||
strbuf_puts(b, "{\n\"header\":[");
|
||||
unsigned i;
|
||||
for (i = 0; i != NELS(headers); ++i) {
|
||||
if (i)
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_json_string(b, headers[i]);
|
||||
}
|
||||
strbuf_puts(b, "],\n\"rows\":[");
|
||||
if (!strbuf_overrun(b))
|
||||
r->u.mclist.phase = LIST_ROWS;
|
||||
return 1;
|
||||
case LIST_ROWS:
|
||||
if (r->u.mclist.iter.current == NULL) {
|
||||
strbuf_puts(b, "\n]\n}\n");
|
||||
if (!strbuf_overrun(b))
|
||||
r->u.mclist.phase = LIST_DONE;
|
||||
return 0;
|
||||
} else {
|
||||
if (r->u.mclist.rowcount != 0)
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_puts(b, "\n[");
|
||||
strbuf_sprintf(b, "%u", r->u.mclist.rowcount);
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_json_hex(b, r->u.mclist.iter.current->them.binary, sizeof r->u.mclist.iter.current->them.binary);
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_json_boolean(b, r->u.mclist.iter.current->read_offset >= r->u.mclist.iter.current->their_last_message);
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_sprintf(b, "%"PRIu64, r->u.mclist.iter.current->their_last_message);
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_sprintf(b, "%"PRIu64, r->u.mclist.iter.current->read_offset);
|
||||
strbuf_puts(b, "]");
|
||||
if (!strbuf_overrun(b)) {
|
||||
meshms_conversation_iterator_advance(&r->u.mclist.iter);
|
||||
++r->u.mclist.rowcount;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case LIST_DONE:
|
||||
return 0;
|
||||
}
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int neighbour_page(rhizome_http_request *r, const char *remainder)
|
||||
{
|
||||
if (r->http.verb != HTTP_VERB_GET)
|
||||
|
@ -21,12 +21,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#define __SERVAL_DNA__RHIZOME_HTTP_H
|
||||
|
||||
#include "rhizome.h"
|
||||
#include "meshms.h"
|
||||
#include "http_server.h"
|
||||
|
||||
int is_rhizome_http_server_running();
|
||||
|
||||
/* Rhizome-specific HTTP request handling.
|
||||
*/
|
||||
enum list_phase { LIST_HEADER = 0, LIST_ROWS, LIST_DONE };
|
||||
|
||||
typedef struct rhizome_http_request
|
||||
{
|
||||
struct http_request http; // MUST BE FIRST ELEMENT
|
||||
@ -109,13 +110,23 @@ typedef struct rhizome_http_request
|
||||
/* For responses that list manifests.
|
||||
*/
|
||||
struct {
|
||||
enum { LIST_HEADER = 0, LIST_ROWS, LIST_DONE } phase;
|
||||
enum list_phase phase;
|
||||
uint64_t rowid_highest;
|
||||
size_t rowcount;
|
||||
time_ms_t end_time;
|
||||
struct rhizome_list_cursor cursor;
|
||||
}
|
||||
list;
|
||||
rhlist;
|
||||
|
||||
/* For responses that list MeshMS conversations.
|
||||
*/
|
||||
struct {
|
||||
enum list_phase phase;
|
||||
size_t rowcount;
|
||||
struct meshms_conversations *conv;
|
||||
struct meshms_conversation_iterator iter;
|
||||
}
|
||||
mclist;
|
||||
|
||||
} u;
|
||||
|
||||
|
@ -51,7 +51,7 @@ setup() {
|
||||
CR='
'
|
||||
VT=' '
|
||||
setup_curl 7
|
||||
setup_jq 1.2
|
||||
setup_jq 1.3
|
||||
setup_servald
|
||||
set_instance +A
|
||||
set_rhizome_config
|
||||
@ -171,52 +171,38 @@ add_bundles() {
|
||||
done
|
||||
}
|
||||
|
||||
transform_bundlelist_json() {
|
||||
# The following jq(1) incantation transforms the JSON array in
|
||||
# bundlelist.json from the following form (which is optimised for
|
||||
# transmission size):
|
||||
transform_list_json() {
|
||||
# The following jq(1) incantation transforms a JSON array in from the
|
||||
# following form (which is optimised for transmission size):
|
||||
# {
|
||||
# "header":[
|
||||
# ".token", "_id", "service", "id", "version","date",".inserttime",
|
||||
# ".author",".fromhere","filesize","filehash","sender","recipient",
|
||||
# "name"
|
||||
# ],
|
||||
# "header":[ "label1", "label2", "label3", ... ],
|
||||
# "rows":[
|
||||
# [ "xx", rowid1, "service1", bundleid1, version1, .... ],
|
||||
# [ null, rowid2, "service2", bundleid2, version2, .... ],
|
||||
# [ row1value1, row1value2, row1value3, ... ],
|
||||
# [ row2value1, row2value2, row2value3, ... ],
|
||||
# ...
|
||||
# [ null, rowidN, "serviceN", bundleidN, versionN, .... ]
|
||||
# [ rowNvalue1, rowNvalue2, rowNvalue3, ... ]
|
||||
# ]
|
||||
# }
|
||||
#
|
||||
# into an array of JSON objects:
|
||||
# [
|
||||
# {
|
||||
# "__index": 0,
|
||||
# ".token": "xx",
|
||||
# "_id": rowid1,
|
||||
# "service": service1,
|
||||
# "id": bundleid1,
|
||||
# "version": version1,
|
||||
# "label1": row1value1,
|
||||
# "label2": row1value2,
|
||||
# "label3": row1value3,
|
||||
# ...
|
||||
# },
|
||||
# {
|
||||
# "__index": 1,
|
||||
# ".token": null,
|
||||
# "_id": rowid2,
|
||||
# "service": service2,
|
||||
# "id": bundleid2,
|
||||
# "version": version2,
|
||||
# "label1": row2value1,
|
||||
# "label2": row2value2,
|
||||
# "label3": row2value3,
|
||||
# ...
|
||||
# },
|
||||
# ...
|
||||
# {
|
||||
# "__index": 2,
|
||||
# ".token": null,
|
||||
# "_id": rowidN,
|
||||
# "service": serviceN,
|
||||
# "id": bundleidN,
|
||||
# "version": versionN,
|
||||
# "label1": rowNvalue1,
|
||||
# "label2": rowNvalue2,
|
||||
# "label3": rowNvalue3,
|
||||
# ...
|
||||
# }
|
||||
# ]
|
||||
@ -250,7 +236,7 @@ test_RhizomeList() {
|
||||
tfw_cat http.headers bundlelist.json
|
||||
tfw_preserve bundlelist.json
|
||||
assert [ "$(jq '.rows | length' bundlelist.json)" = $NBUNDLES ]
|
||||
transform_bundlelist_json bundlelist.json array_of_objects.json
|
||||
transform_list_json bundlelist.json array_of_objects.json
|
||||
tfw_preserve array_of_objects.json
|
||||
for ((n = 0; n != NBUNDLES; ++n)); do
|
||||
if [ "${ROWID[$n]}" -eq "$ROWID_MAX" ]; then
|
||||
@ -299,7 +285,7 @@ setup_RhizomeNewSince() {
|
||||
--basic --user harry:potter \
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/bundlelist.json"
|
||||
assert [ "$(jq '.rows | length' bundlelist.json)" = 6 ]
|
||||
transform_bundlelist_json bundlelist.json array_of_objects.json
|
||||
transform_list_json bundlelist.json array_of_objects.json
|
||||
token=$(jq --raw-output '.[0][".token"]' array_of_objects.json)
|
||||
assert [ -n "$token" ]
|
||||
}
|
||||
@ -319,7 +305,7 @@ test_RhizomeNewSince() {
|
||||
echo ']}' >>newsince$i.json
|
||||
assert [ $(jq . newsince$i.json | wc -c) -ne 0 ]
|
||||
fi
|
||||
transform_bundlelist_json newsince$i.json objects$i.json
|
||||
transform_list_json newsince$i.json objects$i.json
|
||||
tfw_preserve newsince$i.json objects$i.json
|
||||
for ((n = 0; n <= 5; ++n)); do
|
||||
assertJq objects$i.json "contains([{id:\"${BID[$n]}\"}]) | not"
|
||||
@ -891,8 +877,89 @@ test_RhizomeInsertIncorrectFilehash() {
|
||||
}
|
||||
|
||||
doc_MeshmsListConversations="HTTP RESTful list MeshMS conversations as JSON"
|
||||
Xtest_MeshmsListConversations() {
|
||||
:
|
||||
setup_MeshmsListConversations() {
|
||||
IDENTITY_COUNT=5
|
||||
setup
|
||||
# create 3 threads, with all permutations of incoming and outgoing messages
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA2 "Message1"
|
||||
executeOk_servald meshms send message $SIDA3 $SIDA1 "Message2"
|
||||
executeOk_servald meshms send message $SIDA1 $SIDA4 "Message3"
|
||||
executeOk_servald meshms send message $SIDA4 $SIDA1 "Message4"
|
||||
}
|
||||
test_MeshmsListConversations() {
|
||||
executeOk curl \
|
||||
--silent --fail --show-error \
|
||||
--output conversationlist1.json \
|
||||
--dump-header http.headers \
|
||||
--basic --user harry:potter \
|
||||
"http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/conversationlist.json"
|
||||
tfw_cat http.headers conversationlist1.json
|
||||
tfw_preserve conversationlist1.json
|
||||
assert [ "$(jq '.rows | length' conversationlist1.json)" = 3 ]
|
||||
transform_list_json conversationlist1.json conversations1.json
|
||||
tfw_preserve conversations1.json
|
||||
assertJq conversations1.json \
|
||||
"contains([
|
||||
{ recipient: \"$SIDA2\",
|
||||
read: true,
|
||||
last_message: 0,
|
||||
read_offset: 0
|
||||
}
|
||||
])"
|
||||
assertJq conversations1.json \
|
||||
"contains([
|
||||
{ recipient: \"$SIDA3\",
|
||||
read: false,
|
||||
last_message: 11,
|
||||
read_offset: 0
|
||||
}
|
||||
])"
|
||||
assertJq conversations1.json \
|
||||
"contains([
|
||||
{ recipient: \"$SIDA4\",
|
||||
read: false,
|
||||
last_message: 14,
|
||||
read_offset: 0
|
||||
}
|
||||
])"
|
||||
# mark all incoming messages as read
|
||||
executeOk_servald meshms read messages $SIDA1
|
||||
tfw_cat --stderr
|
||||
executeOk curl \
|
||||
--silent --fail --show-error \
|
||||
--output conversationlist2.json \
|
||||
--dump-header http.headers \
|
||||
--basic --user harry:potter \
|
||||
"http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/conversationlist.json"
|
||||
tfw_cat http.headers conversationlist2.json
|
||||
tfw_preserve conversationlist2.json
|
||||
assert [ "$(jq '.rows | length' conversationlist2.json)" = 3 ]
|
||||
transform_list_json conversationlist2.json conversations2.json
|
||||
tfw_preserve conversations2.json
|
||||
assertJq conversations2.json \
|
||||
"contains([
|
||||
{ recipient: \"$SIDA2\",
|
||||
read: true,
|
||||
last_message: 0,
|
||||
read_offset: 0
|
||||
}
|
||||
])"
|
||||
assertJq conversations2.json \
|
||||
"contains([
|
||||
{ recipient: \"$SIDA3\",
|
||||
read: true,
|
||||
last_message: 11,
|
||||
read_offset: 11
|
||||
}
|
||||
])"
|
||||
assertJq conversations2.json \
|
||||
"contains([
|
||||
{ recipient: \"$SIDA4\",
|
||||
read: true,
|
||||
last_message: 14,
|
||||
read_offset: 14
|
||||
}
|
||||
])"
|
||||
}
|
||||
|
||||
doc_MeshmsListMessages="HTTP RESTful list MeshMS messages in one conversation as JSON"
|
||||
|
Loading…
Reference in New Issue
Block a user