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:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user