1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-12 14:14:48 +02:00

relay/api: allow array with multiple requests in websocket frame received from client

This commit is contained in:
Sébastien Helleu
2024-08-25 19:26:01 +02:00
parent 4572e46ced
commit 6bb4d64512
6 changed files with 343 additions and 133 deletions
+1
View File
@@ -4,6 +4,7 @@
### Changed
- relay/api: allow array with multiple requests in websocket frame received from client
- core, plugins: simplify help on parameters that can be repeated in commands
### Added
+67
View File
@@ -1389,6 +1389,10 @@ Requests to WeeChat are made with a JSON object containing these fields:
* `body` (object or array): the body (optional, for `POST` and `PUT` methods)
* `request_id` (string): identifier sent back in the response
Multiple requests can be sent at once using an array of objects, each object
being a separate request. +
Requests are executed in the order received (see example below).
Responses to client are made with a JSON object containing these fields:
* `code` (integer): HTTP response code (example: `200`)
@@ -1478,6 +1482,69 @@ Response:
}
----
Requests example: send two requests at once: get list of all buffers with lines
and nicks, then synchronize with the remote:
[source,json]
----
[
{
"request": "GET /api/buffers?lines=-1000&nicks=true&colors=weechat",
"request_id": "initial_sync"
},
{
"request": "POST /api/sync",
"body": {
"colors": "weechat"
}
}
]
----
[NOTE]
It is recommended to send the synchronization request together with the first
request that is fetching data, so that no events are missed.
First response (body with buffers is truncated for readability):
[source,json]
----
{
"code": 200,
"message": "OK",
"request": "GET /api/buffers?lines=-1000&nicks=true&colors=weechat",
"request_body": null,
"request_id": "initial_sync",
"body_type": "buffers",
"body": [
{
"id": 1709932823238637,
"name": "core.weechat",
"short_name": "weechat",
"number": 1,
"type": "formatted"
}
]
}
----
Second response:
[source,json]
----
{
"code": 204,
"message": "No Content",
"request": "POST /api/sync",
"request_body": {
"colors": "weechat"
},
"request_id": null,
"body_type": null,
"body": null
}
----
WeeChat pushes data to the client at any time on some events: when lines are
displayed, buffers added/removed/changed, nicks added/removed/changed, etc.
+67
View File
@@ -1406,6 +1406,10 @@ les champs suivants :
* `body` (objet ou tableau) : le corps (facultatif, pour les méthodes `POST` et `PUT`)
* `request_id` (chaîne): identifiant renvoyé dans la réponse
Plusieurs requêtes peuvent être envoyées simultanément avec un tableau d'objets,
chaque objet étant une requête séparée. +
Les requêtes sont exécutées dans l'ordre reçu (voir l'exemple ci-dessous).
Les réponses vers le client sont faites avec un objet JSON qui contient
les champs suivants :
@@ -1499,6 +1503,69 @@ Réponse :
}
----
Exemple de requêtes: envoyer deux requêtes en même temps: obtenir la liste des
tampons avec les lignes et les pseudos, puis se synchroniser avec le relay distant:
[source,json]
----
[
{
"request": "GET /api/buffers?lines=-1000&nicks=true&colors=weechat",
"request_id": "initial_sync"
},
{
"request": "POST /api/sync",
"body": {
"colors": "weechat"
}
}
]
----
[NOTE]
Il est recommandé d'envoyer la requête de synchronisation en même temps que la
première requête qui récupère les données, afin qu'aucun évènement ne soit manqué.
Première réponse (le "body" avec les tampons est tronqué pour la lisibilité) :
[source,json]
----
{
"code": 200,
"message": "OK",
"request": "GET /api/buffers?lines=-1000&nicks=true&colors=weechat",
"request_body": null,
"request_id": "initial_sync",
"body_type": "buffers",
"body": [
{
"id": 1709932823238637,
"name": "core.weechat",
"short_name": "weechat",
"number": 1,
"type": "formatted"
}
]
}
----
Seconde réponse:
[source,json]
----
{
"code": 204,
"message": "No Content",
"request": "POST /api/sync",
"request_body": {
"colors": "weechat"
},
"request_id": null,
"body_type": null,
"body": null
}
----
WeeChat pousse des données au client à tout moment sur des évènements : lorsque
des lignes sont affichées, des tampons ajoutés/supprimés/changés, des pseudos
ajoutés/supprimés/changés, etc.
+91 -50
View File
@@ -916,6 +916,71 @@ RELAY_API_PROTOCOL_CALLBACK(sync)
return RELAY_API_PROTOCOL_RC_OK;
}
/*
* Reads one request from client.
*/
void
relay_api_protocol_recv_json_request (struct t_relay_client *client,
cJSON *json)
{
cJSON *json_request, *json_request_id, *json_body;
const char *ptr_request_id;
char *string_body;
int length;
relay_http_request_reinit (client->http_req);
json_request_id = cJSON_GetObjectItem (json, "request_id");
if (json_request_id
&& !cJSON_IsString (json_request_id)
&& !cJSON_IsNull (json_request_id))
{
goto error;
}
ptr_request_id = (json_request_id) ?
cJSON_GetStringValue (json_request_id) : NULL;
free (client->http_req->id);
client->http_req->id = NULL;
client->http_req->id = (ptr_request_id) ? strdup (ptr_request_id) : NULL;
json_request = cJSON_GetObjectItem (json, "request");
if (!json_request || !cJSON_IsString (json_request))
goto error;
if (!relay_http_parse_method_path (client->http_req,
cJSON_GetStringValue (json_request)))
{
goto error;
}
json_body = cJSON_GetObjectItem (json, "body");
if (json_body)
{
string_body = cJSON_PrintUnformatted (json_body);
if (string_body)
{
length = strlen (string_body);
client->http_req->body = malloc (length + 1);
if (client->http_req->body)
{
memcpy (client->http_req->body, string_body, length + 1);
client->http_req->content_length = length;
client->http_req->body_size = length;
}
free (string_body);
}
}
relay_api_protocol_recv_http (client);
return;
error:
relay_api_msg_send_json (client, RELAY_HTTP_400_BAD_REQUEST,
NULL, NULL, NULL);
}
/*
* Reads JSON string from a client: when connected via websocket (persistent
* connection), the client is sending JSON data as a request, which is
@@ -939,74 +1004,50 @@ RELAY_API_PROTOCOL_CALLBACK(sync)
* Content-Type: application/json
*
* {"buffer": "irc.libera.#weechat","command": "hello!"}
*
* The JSON can also be an array of requests, for example to fetch all buffers
* data and synchronize at same time:
*
* [
* {
* "request": "GET /api/buffers?lines=-1000&nicks=true&colors=weechat",
* "request_id": "initial_sync"
* },
* {
* "request": "POST /api/sync",
* "body": {
* "colors":"weechat"
* }
* }
* ]
*/
void
relay_api_protocol_recv_json (struct t_relay_client *client, const char *json)
{
cJSON *json_obj, *json_request, *json_body, *json_request_id;
const char *ptr_request_id;
char *string_body;
int length;
relay_http_request_reinit (client->http_req);
cJSON *json_obj, *json_request;
json_obj = cJSON_Parse (json);
if (!json_obj)
goto error;
json_request = cJSON_GetObjectItem (json_obj, "request");
if (!json_request)
goto error;
if (!cJSON_IsString (json_request))
goto error;
if (!relay_http_parse_method_path (client->http_req,
cJSON_GetStringValue (json_request)))
{
goto error;
relay_api_msg_send_json (client, RELAY_HTTP_400_BAD_REQUEST,
NULL, NULL, NULL);
return;
}
json_body = cJSON_GetObjectItem (json_obj, "body");
if (json_body)
if (cJSON_IsArray (json_obj))
{
string_body = cJSON_PrintUnformatted (json_body);
if (string_body)
cJSON_ArrayForEach (json_request, json_obj)
{
length = strlen (string_body);
client->http_req->body = malloc (length + 1);
if (client->http_req->body)
{
memcpy (client->http_req->body, string_body, length + 1);
client->http_req->content_length = length;
client->http_req->body_size = length;
}
free (string_body);
relay_api_protocol_recv_json_request (client, json_request);
}
}
free (client->http_req->id);
client->http_req->id = NULL;
json_request_id = cJSON_GetObjectItem (json_obj, "request_id");
if (json_request_id)
else
{
if (!cJSON_IsString (json_request_id) && !cJSON_IsNull (json_request_id))
goto error;
ptr_request_id = cJSON_GetStringValue (json_request_id);
client->http_req->id = (ptr_request_id) ?
strdup (ptr_request_id) : NULL;
relay_api_protocol_recv_json_request (client, json_obj);
}
relay_api_protocol_recv_http (client);
goto end;
error:
relay_api_msg_send_json (client, RELAY_HTTP_400_BAD_REQUEST, NULL, NULL, NULL);
end:
if (json_obj)
cJSON_Delete (json_obj);
cJSON_Delete (json_obj);
}
/*
+1 -1
View File
@@ -24,7 +24,7 @@ struct t_relay_client;
enum t_relay_status;
#define RELAY_API_VERSION_MAJOR 0
#define RELAY_API_VERSION_MINOR 2
#define RELAY_API_VERSION_MINOR 3
#define RELAY_API_VERSION_PATCH 0
#define RELAY_API_VERSION_NUMBER \
((RELAY_API_VERSION_MAJOR << 16) \
@@ -51,7 +51,7 @@ extern int relay_api_protocol_command_delay;
#define WEE_CHECK_HTTP_CODE(__code, __message) \
STRNCMP_EQUAL("HTTP/1.1 " #__code " " __message "\r\n", \
data_sent, \
data_sent[0], \
strlen ("HTTP/1.1 " #__code " " __message "\r\n"));
#define WEE_CHECK_TEXT(__code, __message, __request, __body) \
@@ -63,7 +63,7 @@ extern int relay_api_protocol_command_delay;
"\"body_type\":null," \
"\"body\":null" \
"}", \
data_sent);
data_sent[0]);
#define WEE_CHECK_OBJ_STR(__expected, __json, __name) \
json_obj = cJSON_GetObjectItem (__json, __name); \
@@ -92,9 +92,9 @@ extern int relay_api_protocol_command_delay;
struct t_relay_server *ptr_relay_server = NULL;
struct t_relay_client *ptr_relay_client = NULL;
char *data_sent = NULL;
int data_sent_size = 0;
cJSON *json_body_sent = NULL;
int data_sent_index = 0;
char *data_sent[4] = { NULL, NULL, NULL, NULL };
cJSON *json_body_sent[4] = { NULL, NULL, NULL, NULL };
TEST_GROUP(RelayApiProtocol)
{
@@ -104,17 +104,16 @@ TEST_GROUP(RelayApiProtocolWithClient)
{
void free_data_sent ()
{
if (data_sent)
int i;
for (i = 0; i < 4; i++)
{
free (data_sent);
data_sent = NULL;
}
data_sent_size = 0;
if (json_body_sent)
{
cJSON_Delete (json_body_sent);
json_body_sent = NULL;
free (data_sent[i]);
data_sent[i] = NULL;
cJSON_Delete (json_body_sent[i]);
json_body_sent[i] = NULL;
}
data_sent_index = 0;
}
void test_client_recv_http_raw (const char *http_request)
@@ -172,30 +171,21 @@ TEST_GROUP(RelayApiProtocolWithClient)
(void) client;
if (data_sent)
{
free (data_sent);
data_sent = NULL;
}
data_sent_size = 0;
if (json_body_sent)
{
cJSON_Delete (json_body_sent);
json_body_sent = NULL;
}
data_sent[data_sent_index] = (char *)malloc (data_size + 1);
memcpy (data_sent[data_sent_index], data, data_size);
data_sent[data_sent_index][data_size] = '\0';
data_sent = (char *)malloc (data_size + 1);
memcpy (data_sent, data, data_size);
data_sent[data_size] = '\0';
data_sent_size = data_size;
pos_body = strstr (data_sent, "\r\n\r\n");
pos_body = strstr (data_sent[data_sent_index], "\r\n\r\n");
if (pos_body)
json_body_sent = cJSON_Parse(pos_body + 4);
json_body_sent[data_sent_index] = cJSON_Parse(pos_body + 4);
data_sent_index++;
}
void setup ()
{
int i;
/* disable auto-open of relay buffer */
config_file_option_set (relay_config_look_auto_open_buffer, "off", 1);
@@ -218,9 +208,12 @@ TEST_GROUP(RelayApiProtocolWithClient)
ptr_relay_client = relay_client_new (-1, "test", ptr_relay_server);
ptr_relay_client->fake_send_func = &fake_send_func;
data_sent = NULL;
data_sent_size = 0;
json_body_sent = NULL;
for (i = 0; i < 4; i++)
{
data_sent[i] = NULL;
json_body_sent[i] = NULL;
}
data_sent_index = 0;
}
void teardown ()
@@ -288,7 +281,7 @@ TEST(RelayApiProtocolWithClient, CbOptions)
"Content-Type: application/json; charset=utf-8\r\n"
"Content-Length: 0\r\n"
"\r\n",
data_sent);
data_sent[0]);
}
/*
@@ -308,7 +301,7 @@ TEST(RelayApiProtocolWithClient, CbHandshake)
"{\"password_hash_algo\":null,"
"\"password_hash_iterations\":100000,"
"\"totp\":false}",
data_sent);
data_sent[0]);
/* empty body */
test_client_recv_http ("POST /api/handshake", NULL, "{}");
@@ -320,7 +313,7 @@ TEST(RelayApiProtocolWithClient, CbHandshake)
"{\"password_hash_algo\":null,"
"\"password_hash_iterations\":100000,"
"\"totp\":false}",
data_sent);
data_sent[0]);
/* unknown password hash algorithm */
test_client_recv_http ("POST /api/handshake", NULL,
@@ -333,7 +326,7 @@ TEST(RelayApiProtocolWithClient, CbHandshake)
"{\"password_hash_algo\":null,"
"\"password_hash_iterations\":100000,"
"\"totp\":false}",
data_sent);
data_sent[0]);
/* two supported hash algorithms */
test_client_recv_http (
@@ -348,7 +341,7 @@ TEST(RelayApiProtocolWithClient, CbHandshake)
"{\"password_hash_algo\":\"pbkdf2+sha512\","
"\"password_hash_iterations\":100000,"
"\"totp\":false}",
data_sent);
data_sent[0]);
}
/*
@@ -362,7 +355,7 @@ TEST(RelayApiProtocolWithClient, CbVersion)
test_client_recv_http ("GET /api/version", NULL, NULL);
WEE_CHECK_HTTP_CODE(200, "OK");
json = json_body_sent;
json = json_body_sent[0];
WEE_CHECK_OBJ_STR(version_get_version (), json, "weechat_version");
WEE_CHECK_OBJ_STR(version_get_git (), json, "weechat_version_git");
WEE_CHECK_OBJ_NUM(util_version_number (version_get_version ()),
@@ -389,7 +382,7 @@ TEST(RelayApiProtocolWithClient, CbBuffers)
"Content-Length: 41\r\n"
"\r\n"
"{\"error\": \"Buffer \\\"invalid\\\" not found\"}",
data_sent);
data_sent[0]);
/* error: invalid buffer id */
test_client_recv_http ("GET /api/buffers/123", NULL, NULL);
@@ -399,7 +392,7 @@ TEST(RelayApiProtocolWithClient, CbBuffers)
"Content-Length: 37\r\n"
"\r\n"
"{\"error\": \"Buffer \\\"123\\\" not found\"}",
data_sent);
data_sent[0]);
/* error: invalid sub-resource */
test_client_recv_http ("GET /api/buffers/core.weechat/invalid", NULL, NULL);
@@ -409,7 +402,7 @@ TEST(RelayApiProtocolWithClient, CbBuffers)
"Content-Length: 59\r\n"
"\r\n"
"{\"error\": \"Sub-resource of buffers not found: \\\"invalid\\\"\"}",
data_sent);
data_sent[0]);
/* error: too many parameters in path */
test_client_recv_http ("GET /api/buffers/core.weechat/too/many/parameters",
@@ -419,14 +412,14 @@ TEST(RelayApiProtocolWithClient, CbBuffers)
"Content-Type: application/json; charset=utf-8\r\n"
"Content-Length: 0\r\n"
"\r\n",
data_sent);
data_sent[0]);
/* get all buffers */
test_client_recv_http ("GET /api/buffers", NULL, NULL);
WEE_CHECK_HTTP_CODE(200, "OK");
CHECK(json_body_sent);
CHECK(cJSON_IsArray (json_body_sent));
json = cJSON_GetArrayItem (json_body_sent, 0);
CHECK(json_body_sent[0]);
CHECK(cJSON_IsArray (json_body_sent[0]));
json = cJSON_GetArrayItem (json_body_sent[0], 0);
CHECK(json);
CHECK(cJSON_IsObject (json));
WEE_CHECK_OBJ_NUM(gui_buffers->id, json, "id");
@@ -453,9 +446,9 @@ TEST(RelayApiProtocolWithClient, CbBuffers)
gui_buffer_set (gui_buffers, "input_multiline", "1");
test_client_recv_http ("GET /api/buffers/core.weechat", NULL, NULL);
WEE_CHECK_HTTP_CODE(200, "OK");
CHECK(json_body_sent);
CHECK(cJSON_IsObject (json_body_sent));
json = json_body_sent;
CHECK(json_body_sent[0]);
CHECK(cJSON_IsObject (json_body_sent[0]));
json = json_body_sent[0];
WEE_CHECK_OBJ_NUM(gui_buffers->id, json, "id");
WEE_CHECK_OBJ_STR("core.weechat", json, "name");
WEE_CHECK_OBJ_STR("weechat", json, "short_name");
@@ -481,9 +474,9 @@ TEST(RelayApiProtocolWithClient, CbBuffers)
"GET /api/buffers/%lld", gui_buffers->id);
test_client_recv_http (str_http, NULL, NULL);
WEE_CHECK_HTTP_CODE(200, "OK");
CHECK(json_body_sent);
CHECK(cJSON_IsObject (json_body_sent));
json = json_body_sent;
CHECK(json_body_sent[0]);
CHECK(cJSON_IsObject (json_body_sent[0]));
json = json_body_sent[0];
WEE_CHECK_OBJ_NUM(gui_buffers->id, json, "id");
WEE_CHECK_OBJ_STR("core.weechat", json, "name");
WEE_CHECK_OBJ_STR("weechat", json, "short_name");
@@ -506,9 +499,9 @@ TEST(RelayApiProtocolWithClient, CbBuffers)
gui_chat_printf (NULL, "test line 2");
test_client_recv_http ("GET /api/buffers/core.weechat/lines?lines=-2", NULL, NULL);
WEE_CHECK_HTTP_CODE(200, "OK");
CHECK(json_body_sent);
CHECK(cJSON_IsArray (json_body_sent));
json = cJSON_GetArrayItem (json_body_sent, 0);
CHECK(json_body_sent[0]);
CHECK(cJSON_IsArray (json_body_sent[0]));
json = cJSON_GetArrayItem (json_body_sent[0], 0);
CHECK(json);
CHECK(cJSON_IsObject (json));
WEE_CHECK_OBJ_NUM(gui_buffers->own_lines->last_line->prev_line->data->id, json, "id");
@@ -518,7 +511,7 @@ TEST(RelayApiProtocolWithClient, CbBuffers)
WEE_CHECK_OBJ_BOOL(0, json, "highlight");
WEE_CHECK_OBJ_STR("", json, "prefix");
WEE_CHECK_OBJ_STR("test line 1", json, "message");
json = cJSON_GetArrayItem (json_body_sent, 1);
json = cJSON_GetArrayItem (json_body_sent[0], 1);
CHECK(json);
CHECK(cJSON_IsObject (json));
WEE_CHECK_OBJ_NUM(gui_buffers->own_lines->last_line->data->id, json, "id");
@@ -532,9 +525,9 @@ TEST(RelayApiProtocolWithClient, CbBuffers)
/* get nicks */
test_client_recv_http ("GET /api/buffers/core.weechat/nicks", NULL, NULL);
WEE_CHECK_HTTP_CODE(200, "OK");
CHECK(json_body_sent);
CHECK(cJSON_IsObject (json_body_sent));
json = json_body_sent;
CHECK(json_body_sent[0]);
CHECK(cJSON_IsObject (json_body_sent[0]));
json = json_body_sent[0];
WEE_CHECK_OBJ_STR("root", json, "name");
WEE_CHECK_OBJ_STR("", json, "color");
json_groups = cJSON_GetObjectItem (json, "groups");
@@ -555,9 +548,9 @@ TEST(RelayApiProtocolWithClient, CbHotlist)
/* get hotlist (empty) */
test_client_recv_http ("GET /api/hotlist", NULL, NULL);
WEE_CHECK_HTTP_CODE(200, "OK");
CHECK(json_body_sent);
CHECK(cJSON_IsArray (json_body_sent));
LONGS_EQUAL(0, cJSON_GetArraySize (json_body_sent));
CHECK(json_body_sent[0]);
CHECK(cJSON_IsArray (json_body_sent[0]));
LONGS_EQUAL(0, cJSON_GetArraySize (json_body_sent[0]));
gui_hotlist_add (gui_buffers, GUI_HOTLIST_LOW, NULL, 0);
gui_hotlist_add (gui_buffers, GUI_HOTLIST_MESSAGE, NULL, 0);
@@ -573,10 +566,10 @@ TEST(RelayApiProtocolWithClient, CbHotlist)
/* get hotlist (one buffer) */
test_client_recv_http ("GET /api/hotlist", NULL, NULL);
WEE_CHECK_HTTP_CODE(200, "OK");
CHECK(json_body_sent);
CHECK(cJSON_IsArray (json_body_sent));
LONGS_EQUAL(1, cJSON_GetArraySize (json_body_sent));
json = cJSON_GetArrayItem (json_body_sent, 0);
CHECK(json_body_sent[0]);
CHECK(cJSON_IsArray (json_body_sent[0]));
LONGS_EQUAL(1, cJSON_GetArraySize (json_body_sent[0]));
json = cJSON_GetArrayItem (json_body_sent[0], 0);
CHECK(json);
CHECK(cJSON_IsObject (json));
WEE_CHECK_OBJ_NUM(GUI_HOTLIST_HIGHLIGHT, json, "priority");
@@ -622,7 +615,7 @@ TEST(RelayApiProtocolWithClient, CbInput)
"Content-Type: application/json; charset=utf-8\r\n"
"Content-Length: 0\r\n"
"\r\n",
data_sent);
data_sent[0]);
/* error: invalid buffer name */
test_client_recv_http ("POST /api/input",
@@ -635,7 +628,7 @@ TEST(RelayApiProtocolWithClient, CbInput)
"Content-Length: 41\r\n"
"\r\n"
"{\"error\": \"Buffer \\\"invalid\\\" not found\"}",
data_sent);
data_sent[0]);
/* on core buffer, without buffer name */
record_start ();
@@ -693,12 +686,12 @@ TEST(RelayApiProtocolWithClient, CbPing)
"Content-Type: application/json; charset=utf-8\r\n"
"Content-Length: 0\r\n"
"\r\n",
data_sent);
data_sent[0]);
/* ping with a body */
test_client_recv_http ("POST /api/ping", NULL, "{\"data\": \"abcdef\"}");
WEE_CHECK_HTTP_CODE(200, "OK");
json = json_body_sent;
json = json_body_sent[0];
WEE_CHECK_OBJ_STR("abcdef", json, "data");
}
@@ -717,7 +710,7 @@ TEST(RelayApiProtocolWithClient, CbSync)
"\r\n"
"{\"error\": \"Sync resource is available only with "
"a websocket connection\"}",
data_sent);
data_sent[0]);
}
/*
@@ -741,7 +734,7 @@ TEST(RelayApiProtocolWithClient, CbSyncWebsocket)
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: Z5uTZwvwYNDm9w4HFGk26ijp/p0=\r\n"
"\r\n",
data_sent);
data_sent[0]);
test_client_recv_text ("{\"request\": \"POST /api/sync\"}");
WEE_CHECK_TEXT(204, "No Content", "POST /api/sync", "null");
@@ -785,6 +778,7 @@ TEST(RelayApiProtocolWithClient, CbSyncWebsocket)
/*
* Tests functions:
* relay_api_protocol_recv_json_request
* relay_api_protocol_recv_json
*/
@@ -804,7 +798,7 @@ TEST(RelayApiProtocolWithClient, RecvJson)
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: Z5uTZwvwYNDm9w4HFGk26ijp/p0=\r\n"
"\r\n",
data_sent);
data_sent[0]);
/* error: empty string */
test_client_recv_text ("");
@@ -833,6 +827,46 @@ TEST(RelayApiProtocolWithClient, RecvJson)
/* error: invalid request (string, resource not found) */
test_client_recv_text ("{\"request\": \"GET /api/unknown\", \"body\": {\"test\": 123}}");
WEE_CHECK_TEXT(404, "Not Found", "GET /api/unknown", "{\"test\":123}");
/* ping */
test_client_recv_text ("{\"request\": \"POST /api/ping\", \"request_id\": \"ping\"}");
STRCMP_EQUAL("{\"code\":204,"
"\"message\":\"No Content\","
"\"request\":\"POST /api/ping\","
"\"request_body\":null,"
"\"request_id\":\"ping\","
"\"body_type\":null,"
"\"body\":null"
"}",
data_sent[0]);
/* 2 ping */
test_client_recv_text ("["
"{\"request\": \"POST /api/ping\", "
"\"request_id\": \"ping1\", "
"\"body\": {\"data\": \"p1\"}}, "
"{\"request\": \"POST /api/ping\", "
"\"request_id\": \"ping2\", "
"\"body\": {\"data\": \"p2\"}}"
"]");
STRCMP_EQUAL("{\"code\":200,"
"\"message\":\"OK\","
"\"request\":\"POST /api/ping\","
"\"request_body\":{\"data\":\"p1\"},"
"\"request_id\":\"ping1\","
"\"body_type\":\"ping\","
"\"body\":{\"data\":\"p1\"}"
"}",
data_sent[0]);
STRCMP_EQUAL("{\"code\":200,"
"\"message\":\"OK\","
"\"request\":\"POST /api/ping\","
"\"request_body\":{\"data\":\"p2\"},"
"\"request_id\":\"ping2\","
"\"body_type\":\"ping\","
"\"body\":{\"data\":\"p2\"}"
"}",
data_sent[1]);
}
/*
@@ -849,7 +883,7 @@ TEST(RelayApiProtocolWithClient, RecvHttp404)
"Content-Type: application/json; charset=utf-8\r\n"
"Content-Length: 0\r\n"
"\r\n",
data_sent);
data_sent[0]);
/* resource not found: error 404 */
test_client_recv_http ("GET /unknown HTTP/1.1", NULL, NULL);
@@ -858,7 +892,7 @@ TEST(RelayApiProtocolWithClient, RecvHttp404)
"Content-Type: application/json; charset=utf-8\r\n"
"Content-Length: 0\r\n"
"\r\n",
data_sent);
data_sent[0]);
/* resource not found: error 404 */
test_client_recv_http ("GET /unknown/abc HTTP/1.1", NULL, NULL);
@@ -867,7 +901,7 @@ TEST(RelayApiProtocolWithClient, RecvHttp404)
"Content-Type: application/json; charset=utf-8\r\n"
"Content-Length: 0\r\n"
"\r\n",
data_sent);
data_sent[0]);
/* resource not found: error 404 */
test_client_recv_http ("GET /api HTTP/1.1", NULL, NULL);
@@ -876,7 +910,7 @@ TEST(RelayApiProtocolWithClient, RecvHttp404)
"Content-Type: application/json; charset=utf-8\r\n"
"Content-Length: 0\r\n"
"\r\n",
data_sent);
data_sent[0]);
/* resource not found: error 404 */
test_client_recv_http ("GET /api/unknown HTTP/1.1", NULL, NULL);
@@ -885,7 +919,7 @@ TEST(RelayApiProtocolWithClient, RecvHttp404)
"Content-Type: application/json; charset=utf-8\r\n"
"Content-Length: 0\r\n"
"\r\n",
data_sent);
data_sent[0]);
}
/*
@@ -904,7 +938,7 @@ TEST(RelayApiProtocolWithClient, RecvHttpMissingPassword)
"Content-Length: 29\r\n"
"\r\n"
"{\"error\": \"Missing password\"}",
data_sent);
data_sent[0]);
}
/*
@@ -924,5 +958,5 @@ TEST(RelayApiProtocolWithClient, RecvHttpInvalidPassword)
"Content-Length: 29\r\n"
"\r\n"
"{\"error\": \"Invalid password\"}",
data_sent);
data_sent[0]);
}