Accept non-json content

This commit is contained in:
Gergely Polonkai 2016-01-15 13:06:23 +01:00
parent 441287a880
commit 97a169959c
4 changed files with 62 additions and 32 deletions

View File

@ -106,11 +106,16 @@
/** /**
* MatrixAPICallback: * MatrixAPICallback:
* @api: A #MatrixAPI implementation * @api: A #MatrixAPI implementation
* @content: the JSON content of the response, as a #JsonNode * @content_type: the content_type of the response
* @data: User data specified when calling original request function * @json_content: (allow-none): the JSON content of the response, as a
* @err: a #GError * #JsonNode
* @raw_content: (allow-none): the raw content of the response
* @user_data: User data specified when calling original request function
* @err: a #GError. It will hold any errors from the underlying API
* (including communication or type errors)
* *
* A callback function to use with API calls. * A callback function to use with API calls. Either @json_content or
* @raw_content will be set.
*/ */
G_DEFINE_INTERFACE(MatrixAPI, matrix_api, G_TYPE_OBJECT); G_DEFINE_INTERFACE(MatrixAPI, matrix_api, G_TYPE_OBJECT);

View File

@ -35,8 +35,10 @@ typedef struct _MatrixAPIInterface MatrixAPIInterface;
typedef struct _MatrixAPI MatrixAPI; typedef struct _MatrixAPI MatrixAPI;
typedef void (*MatrixAPICallback)(MatrixAPI *api, typedef void (*MatrixAPICallback)(MatrixAPI *api,
JsonNode *content, const gchar *content_type,
gpointer data, JsonNode *json_content,
GByteArray *raw_content,
gpointer user_data,
GError *err); GError *err);
struct _MatrixAPIInterface { struct _MatrixAPIInterface {

View File

@ -75,6 +75,7 @@ typedef struct {
JsonNode *request_content; JsonNode *request_content;
MatrixAPICallback callback; MatrixAPICallback callback;
gpointer callback_data; gpointer callback_data;
gboolean accept_non_json;
} MatrixHTTPAPIRequest; } MatrixHTTPAPIRequest;
GParamSpec *obj_properties[N_PROPERTIES] = {NULL,}; GParamSpec *obj_properties[N_PROPERTIES] = {NULL,};
@ -455,6 +456,7 @@ _response_callback(SoupSession *session,
MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private(api); MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private(api);
GError *err = NULL; GError *err = NULL;
JsonNode *content = NULL; JsonNode *content = NULL;
GByteArray *raw_content = NULL;
if (msg->status_code < SOUP_STATUS_CONTINUE) { if (msg->status_code < SOUP_STATUS_CONTINUE) {
err = g_error_new(MATRIX_API_ERROR, err = g_error_new(MATRIX_API_ERROR,
@ -467,6 +469,9 @@ _response_callback(SoupSession *session,
const guint8 *data; const guint8 *data;
gsize datalen; gsize datalen;
JsonParser *parser; JsonParser *parser;
SoupURI *request_uri = soup_message_get_uri(msg);
const gchar *request_url = soup_uri_get_path(request_uri)
+ strlen(API_ENDPOINT);
buffer = soup_message_body_flatten(msg->response_body); buffer = soup_message_body_flatten(msg->response_body);
soup_buffer_get_data(buffer, &data, &datalen); soup_buffer_get_data(buffer, &data, &datalen);
@ -475,9 +480,7 @@ _response_callback(SoupSession *session,
if (json_parser_load_from_data(parser, if (json_parser_load_from_data(parser,
(const gchar *)data, datalen, (const gchar *)data, datalen,
&err)) { &err)) {
SoupURI *request_uri = soup_message_get_uri(msg); g_debug("Data (%s): %s", request_url, data);
g_debug("Data (%s): %s", soup_uri_get_path(request_uri) + strlen(API_ENDPOINT), data);
content = json_parser_get_root(parser); content = json_parser_get_root(parser);
if (JSON_NODE_HOLDS_OBJECT(content)) { if (JSON_NODE_HOLDS_OBJECT(content)) {
@ -602,10 +605,18 @@ _response_callback(SoupSession *session,
g_debug("Bad response: %s", data); g_debug("Bad response: %s", data);
} }
} else { // Invalid JSON } else { // Invalid JSON
err = g_error_new(MATRIX_API_ERROR, if (request->accept_non_json) {
MATRIX_API_ERROR_BAD_RESPONSE, raw_content = g_byte_array_sized_new(datalen);
"Malformed response (invalid JSON)"); g_byte_array_append(raw_content, data, datalen);
g_debug("Malformed response: %s", data); g_debug("Binary data (%s): %" G_GSIZE_FORMAT " bytes",
request_url,
datalen);
} else {
err = g_error_new(MATRIX_API_ERROR,
MATRIX_API_ERROR_BAD_RESPONSE,
"Malformed response (invalid JSON)");
g_debug("Malformed response (%s): %s", request_url, data);
}
} }
} }
@ -613,7 +624,11 @@ _response_callback(SoupSession *session,
if (request->callback) { if (request->callback) {
request->callback( request->callback(
MATRIX_API(api), MATRIX_API(api),
soup_message_headers_get_content_type(
msg->response_headers,
NULL),
content, content,
raw_content,
request->callback_data, request->callback_data,
err); err);
} }
@ -651,6 +666,7 @@ _send(MatrixHTTPAPI *api,
const gchar *path, const gchar *path,
GHashTable *params, GHashTable *params,
const JsonNode *content, const JsonNode *content,
gboolean accept_non_json,
GError **error) GError **error)
{ {
MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private(api); MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private(api);
@ -728,6 +744,7 @@ _send(MatrixHTTPAPI *api,
request->api = api; request->api = api;
request->callback = callback; request->callback = callback;
request->callback_data = user_data; request->callback_data = user_data;
request->accept_non_json = accept_non_json;
soup_session_queue_message(priv->soup_session, soup_session_queue_message(priv->soup_session,
message, message,
@ -753,7 +770,7 @@ i_login(MatrixAPI *api,
_send(MATRIX_HTTP_API(api), _send(MATRIX_HTTP_API(api),
callback, user_data, callback, user_data,
"POST", "login", NULL, body, "POST", "login", NULL, body,
error); FALSE, error);
} }
static void static void
@ -886,7 +903,7 @@ i_create_room(MatrixAPI *api,
_send(MATRIX_HTTP_API(api), _send(MATRIX_HTTP_API(api),
callback, user_data, callback, user_data,
"POST", "createRoom", NULL, body, "POST", "createRoom", NULL, body,
error); FALSE, error);
} }
static void static void
@ -912,7 +929,7 @@ i_initial_sync(MatrixAPI *api,
_send(MATRIX_HTTP_API(api), _send(MATRIX_HTTP_API(api),
callback, user_data, callback, user_data,
"GET", "initialSync", params, NULL, "GET", "initialSync", params, NULL,
err); FALSE, err);
} }
static void static void
@ -939,7 +956,7 @@ i_event_stream(MatrixAPI *api,
_send(MATRIX_HTTP_API(api), _send(MATRIX_HTTP_API(api),
callback, user_data, callback, user_data,
"GET", "events", params, NULL, "GET", "events", params, NULL,
err); FALSE, err);
} }
static void static void
@ -958,7 +975,7 @@ i_leave_room(MatrixAPI *api,
_send(MATRIX_HTTP_API(api), _send(MATRIX_HTTP_API(api),
callback, user_data, callback, user_data,
"POST", path, NULL, NULL, "POST", path, NULL, NULL,
error); FALSE, error);
g_free(path); g_free(path);
} }
@ -971,7 +988,7 @@ i_list_public_rooms(MatrixAPI *api,
_send(MATRIX_HTTP_API(api), _send(MATRIX_HTTP_API(api),
callback, user_data, callback, user_data,
"GET", "publicRooms", NULL, NULL, "GET", "publicRooms", NULL, NULL,
error); FALSE, error);
} }
static void static void
@ -999,7 +1016,7 @@ i_join_room(MatrixAPI *api,
_send(MATRIX_HTTP_API(api), _send(MATRIX_HTTP_API(api),
callback, user_data, callback, user_data,
"POST", path, NULL, NULL, "POST", path, NULL, NULL,
error); FALSE, error);
g_free(path); g_free(path);
} }
@ -1020,7 +1037,7 @@ i_get_presence_list(MatrixAPI *api,
_send(MATRIX_HTTP_API(api), _send(MATRIX_HTTP_API(api),
callback, user_data, callback, user_data,
"GET", path, NULL, NULL, "GET", path, NULL, NULL,
error); FALSE, error);
g_free(path); g_free(path);
} }
@ -1041,7 +1058,7 @@ i_get_user_presence(MatrixAPI *api,
_send(MATRIX_HTTP_API(api), _send(MATRIX_HTTP_API(api),
callback, user_data, callback, user_data,
"GET", path, NULL, NULL, "GET", path, NULL, NULL,
error); FALSE, error);
g_free(path); g_free(path);
} }

View File

@ -38,8 +38,10 @@ static GOptionEntry entries[] = {
static void static void
initial_sync_finished(MatrixAPI *api, initial_sync_finished(MatrixAPI *api,
JsonNode *content, const gchar *content_type,
gpointer data, JsonNode *json_content,
GByteArray *raw_content,
gpointer user_data,
GError *err) GError *err)
{ {
g_printf("initialSync finished\n"); g_printf("initialSync finished\n");
@ -49,7 +51,9 @@ initial_sync_finished(MatrixAPI *api,
static void static void
create_room_finished(MatrixAPI *api, create_room_finished(MatrixAPI *api,
JsonNode *content, const gchar *content_type,
JsonNode *json_content,
GByteArray *raw_content,
gpointer data, gpointer data,
GError *err) GError *err)
{ {
@ -65,7 +69,9 @@ create_room_finished(MatrixAPI *api,
static void static void
get_user_presence_finished(MatrixAPI *api, get_user_presence_finished(MatrixAPI *api,
const gchar *content_type,
JsonNode *json_content, JsonNode *json_content,
GByteArray *raw_content,
gpointer data, gpointer data,
GError *err) GError *err)
{ {
@ -83,16 +89,16 @@ get_user_presence_finished(MatrixAPI *api,
soup_uri_get_scheme(avatar_uri), soup_uri_get_scheme(avatar_uri),
soup_uri_get_host(avatar_uri), soup_uri_get_host(avatar_uri),
soup_uri_get_path(avatar_uri)); soup_uri_get_path(avatar_uri));
matrix_api_media_download(api,
NULL, NULL,
soup_uri_get_host(avatar_uri),
soup_uri_get_path(avatar_uri) + 1,
NULL);
soup_uri_free(avatar_uri); soup_uri_free(avatar_uri);
} }
static void static void
login_finished(MatrixAPI *api, JsonNode *content, gpointer data, GError *err) login_finished(MatrixAPI *api,
const gchar *content_type,
JsonNode *json_content,
GByteArray *raw_content,
gpointer data,
GError *err)
{ {
JsonPath *path = json_path_new(); JsonPath *path = json_path_new();
JsonNode *result; JsonNode *result;
@ -108,7 +114,7 @@ login_finished(MatrixAPI *api, JsonNode *content, gpointer data, GError *err)
json_path_compile(path, "$.user_id", NULL); json_path_compile(path, "$.user_id", NULL);
if ((result = json_path_match(path, content)) != NULL) { if ((result = json_path_match(path, json_content)) != NULL) {
JsonArray *array = json_node_get_array(result); JsonArray *array = json_node_get_array(result);
const gchar *user_id; const gchar *user_id;