From 9e2d486b19c9e982d72075282be28602d0b19789 Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Mon, 4 Jan 2016 16:47:55 +0100 Subject: [PATCH] Start reimplementing HTTP API with the new interface --- .../matrix-glib/matrix-glib-sections.txt | 6 +- src/matrix-api.c | 4 +- src/matrix-http-api.c | 167 ++++++--- src/matrix-http-api.h | 347 ------------------ src/test-client.c | 10 +- 5 files changed, 121 insertions(+), 413 deletions(-) diff --git a/docs/reference/matrix-glib/matrix-glib-sections.txt b/docs/reference/matrix-glib/matrix-glib-sections.txt index a00900e..f67ffac 100644 --- a/docs/reference/matrix-glib/matrix-glib-sections.txt +++ b/docs/reference/matrix-glib/matrix-glib-sections.txt @@ -166,11 +166,7 @@ matrix_http_api_new matrix_http_api_get_validate_certificate matrix_http_api_set_validate_certificate matrix_http_api_get_base_url -matrix_http_api_register_account -matrix_http_api_login -matrix_http_api_initial_sync -matrix_http_api_create_room -matrix_http_api_join_room + MatrixHTTPAPI MatrixHTTPAPIClass diff --git a/src/matrix-api.c b/src/matrix-api.c index 60a741a..44d03d3 100644 --- a/src/matrix-api.c +++ b/src/matrix-api.c @@ -426,8 +426,8 @@ matrix_api_default_init(MatrixAPIInterface *iface) /** * MatrixAPI:token: * - * The token to use for authorization. The matrix_http_api_login() - * and matrix_http_api_register_account() calls set this + * The token to use for authorization. The matrix_api_login() and + * matrix_api_register_account() calls must set this * automatically. */ g_object_interface_install_property( diff --git a/src/matrix-http-api.c b/src/matrix-http-api.c index d7bc7bb..95e287e 100644 --- a/src/matrix-http-api.c +++ b/src/matrix-http-api.c @@ -72,20 +72,22 @@ typedef struct { GParamSpec *obj_properties[N_PROPERTIES] = {NULL,}; static void matrix_http_api_matrix_api_init(MatrixAPIInterface *iface); +static void i_set_token(MatrixAPI *api, const gchar *token); +static const gchar *i_get_token(MatrixAPI *api); G_DEFINE_TYPE_WITH_CODE(MatrixHTTPAPI, matrix_http_api, G_TYPE_OBJECT, G_ADD_PRIVATE(MatrixHTTPAPI) - G_IMPLEMENT_INTERFACE(MATRIX_TYPE_API, matrix_http_api_matrix_api_init)); - -static void -matrix_http_api_matrix_api_init(MatrixAPIInterface *iface) -{ - iface->login = matrix_http_api_login; -} + G_IMPLEMENT_INTERFACE(MATRIX_TYPE_API, + matrix_http_api_matrix_api_init)); static void matrix_http_api_finalize(GObject *gobject) { + MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private( + MATRIX_HTTP_API(gobject)); + + g_free(priv->token); + g_signal_handlers_destroy(gobject); G_OBJECT_CLASS(matrix_http_api_parent_class)->finalize(gobject); } @@ -126,8 +128,7 @@ matrix_http_api_set_property(GObject *gobject, last_occurence = g_strrstr(base_url, API_ENDPOINT); /* Check if the provided URL already ends with the API endpoint */ - if ((g_strcmp0(last_occurence, API_ENDPOINT) == 0) || - (g_strcmp0(last_occurence, API_ENDPOINT"/") == 0)) { + if (g_strcmp0(last_occurence, API_ENDPOINT) == 0) { /* if so, just use it */ url = g_strdup(base_url); } else { @@ -143,12 +144,16 @@ matrix_http_api_set_property(GObject *gobject, } url_tmp = g_strdup(base_url); + + /* Cut trailing slash, if present */ if (url_tmp[strlen(url_tmp) - 1] == '/') { url_tmp[strlen(url_tmp) - 1] = 0; } url = g_strdup_printf("%s%s", url_tmp, API_ENDPOINT); g_free(url_tmp); + + g_debug("Set base URL to %s", url); } priv->uri = soup_uri_new(url); @@ -158,11 +163,7 @@ matrix_http_api_set_property(GObject *gobject, } case PROP_TOKEN: - if (priv->token) { - g_free(priv->token); - } - - priv->token = g_strdup(g_value_get_string(value)); + i_set_token(MATRIX_API(api), g_value_get_string(value)); break; @@ -192,7 +193,8 @@ matrix_http_api_get_property(GObject *gobject, break; case PROP_TOKEN: - g_value_set_string(value, priv->token); + g_value_set_string(value, + i_get_token(MATRIX_API(api))); break; @@ -222,6 +224,9 @@ matrix_http_api_class_init(MatrixHTTPAPIClass *klass) "TRUE if server certificates should be validated", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property(gobject_class, + PROP_VALIDATE_CERTIFICATE, + obj_properties[PROP_VALIDATE_CERTIFICATE]); /** * MatrixHTTPAPI:base-url: @@ -235,23 +240,11 @@ matrix_http_api_class_init(MatrixHTTPAPIClass *klass) "Matrix.org home server to connect to.", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property(gobject_class, + PROP_BASE_URL, + obj_properties[PROP_BASE_URL]); - /** - * MatrixHTTPAPI:token: - * - * The token to use for authorization. The matrix_http_api_login() - * and matrix_http_api_register_account() calls set this - * automatically. - */ - obj_properties[PROP_TOKEN] = g_param_spec_string( - "token", "Authorization token", - "The token to use for authorization", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobject_class, - N_PROPERTIES, - obj_properties); + g_object_class_override_property(gobject_class, PROP_TOKEN, "token"); } static void @@ -283,6 +276,25 @@ matrix_http_api_new(const gchar *base_url, const gchar *token) NULL); } +static void +i_set_token(MatrixAPI *api, const gchar *token) +{ + MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private( + MATRIX_HTTP_API(api)); + + g_free(priv->token); + priv->token = g_strdup(token); +} + +static const gchar * +i_get_token(MatrixAPI *api) +{ + MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private( + MATRIX_HTTP_API(api)); + + return priv->token; +} + /** * matrix_http_api_set_validate_certificate: * @api: a #MatrixHTTPAPI implementation @@ -317,9 +329,9 @@ matrix_http_api_get_validate_certificate(MatrixHTTPAPI *api) } static void -response_callback(SoupSession *session, - SoupMessage *msg, - MatrixHTTPAPIRequest *request) +_response_callback(SoupSession *session, + SoupMessage *msg, + MatrixHTTPAPIRequest *request) { MatrixHTTPAPI *api = request->api; MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private(api); @@ -358,9 +370,9 @@ response_callback(SoupSession *session, const gchar *access_token; if ((access_token = json_node_get_string(node)) != NULL) { - g_debug("Access token: %s", access_token); - g_free(priv->token); - priv->token = g_strdup(access_token); + g_debug("Got new access token: %s", access_token); + + i_set_token(MATRIX_API(api), access_token); } } @@ -441,14 +453,21 @@ matrix_http_api_get_base_url(MatrixHTTPAPI *api) } static void -matrix_http_api_send(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *method, - const gchar *path, - const JsonNode *content, - GError **error) +_send(MatrixHTTPAPI *api, + MatrixAPICallback callback, + gpointer user_data, + const gchar *method, + const gchar *path, + const JsonNode *content, + GError **error) { + MatrixHTTPAPIPrivate *priv = matrix_http_api_get_instance_private(api); + SoupURI *request_path; + SoupMessage *message; + gchar *data; + gsize datalen; + MatrixHTTPAPIRequest *request; + if (!g_str_is_ascii(method)) { g_warning("Method must be ASCII encoded!"); @@ -464,15 +483,47 @@ matrix_http_api_send(MatrixAPI *api, return; } + request_path = soup_uri_new_with_base(priv->uri, path); + message = soup_message_new_from_uri(method, request_path); + soup_uri_free(request_path); + + if (content) { + JsonGenerator *generator; + + generator = json_generator_new(); + json_generator_set_root(generator, (JsonNode *)content); + data = json_generator_to_data(generator, &datalen); + } else { + data = g_strdup(""); + datalen = 0; + } + + soup_message_set_flags(message, SOUP_MESSAGE_NO_REDIRECT); + soup_message_set_request(message, + "application/json", + SOUP_MEMORY_TAKE, + data, datalen); + g_object_ref(message); + + request = g_new0(MatrixHTTPAPIRequest, 1); + request->request_content = (JsonNode *)content; + request->api = api; + request->callback = callback; + request->callback_data = user_data; + + soup_session_queue_message(priv->soup_session, + message, + (SoupSessionCallback)_response_callback, + request); } void -matrix_http_api_login(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *type, - const JsonNode *content, - GError **error) +i_login(MatrixAPI *api, + MatrixAPICallback callback, + gpointer user_data, + const gchar *type, + const JsonNode *content, + GError **error) { JsonNode *body; JsonObject *root_object; @@ -481,8 +532,16 @@ matrix_http_api_login(MatrixAPI *api, root_object = json_node_get_object(body); json_object_set_string_member(root_object, "type", type); - matrix_http_api_send(api, - callback, user_data, - "POST", "/login", body, - error); + _send(MATRIX_HTTP_API(api), + callback, user_data, + "POST", "login", body, + error); +} + +static void +matrix_http_api_matrix_api_init(MatrixAPIInterface *iface) +{ + iface->set_token = i_set_token; + iface->get_token = i_get_token; + iface->login = i_login; } diff --git a/src/matrix-http-api.h b/src/matrix-http-api.h index 15fee58..044f3e5 100644 --- a/src/matrix-http-api.h +++ b/src/matrix-http-api.h @@ -54,353 +54,6 @@ const gchar *matrix_http_api_get_base_url(MatrixHTTPAPI *api); MatrixHTTPAPI *matrix_http_api_new(const gchar *base_url, const gchar *token); -/* Media */ -void matrix_http_api_media_download(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *server_name, - const gchar *media_id); -void matrix_http_api_media_thumbnail(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *server_name, - const gchar *media_id, - guint width, - guint height, - MatrixAPIResizeMethod method); -void matrix_http_api_media_upload(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *content_type, - const GByteArray *content); - -/* Presence */ -void matrix_http_api_get_presence_list(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id); -void matrix_http_api_update_presence_list(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - GList *drop_ids, - GList *invite_ids); -void matrix_http_api_get_user_presence(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id); -void matrix_http_api_set_user_presence(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - MatrixAPIPresence presence, - const gchar *status_message); - -/* Push notifications */ -void matrix_http_api_set_pushers(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - MatrixAPIPusher *pusher); -void matrix_http_api_get_pushers(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data); -void matrix_http_api_delete_pusher(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *scope, - MatrixAPIPusherKind kind, - const gchar *rule_id); -void matrix_http_api_get_pusher(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *scope, - MatrixAPIPusherKind kind, - const gchar *rule_id); -void matrix_http_api_add_pusher(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *scope, - MatrixAPIPusherKind kind, - const gchar *rule_id, - const gchar *before, - const gchar *after, - GList *actions, - GList *conditions); -void matrix_http_api_toggle_pusher(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *scope, - MatrixAPIPusherKind kind, - const gchar *rule_id, - gboolean enabled); - -/* Room creation */ -void matrix_http_api_create_room(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - MatrixAPIRoomPreset preset, - const gchar *room_name, - const gchar *room_alias, - const gchar *topic, - MatrixAPIRoomVisibility visibility, - JsonNode *creation_content, - GList *initial_state, - GList *invitees); - -/* Room directory */ -void matrix_http_api_delete_room_alias(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_alias); -void matrix_http_api_get_room_id(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_alias); -void matrix_http_api_create_room_alias(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id, - const gchar *room_alias); - -/* Room discovery */ -void matrix_http_api_list_public_rooms(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data); - -/* Room membership */ - -void matrix_http_api_ban_user(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id, - const gchar *user_id, - const gchar *reason); -void matrix_http_api_forget_room(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id); -void matrix_http_api_invite_user_3rdparty(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id, - const gchar *address, - const gchar *medium, - const gchar *id_server); -void matrix_http_api_invite_user(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id, - const gchar *user_id); -void matrix_http_api_join_room(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id_or_alias); -void matrix_http_api_leave_room(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id); - -/* Room participation */ - -void matrix_http_api_event_stream(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *from_token, - gulong timeout); -void matrix_http_api_get_event(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *event_id); -void matrix_http_api_initial_sync(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - guint limit, - gboolean archived); -void matrix_http_api_get_event_context(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id, - const gchar *event_id, - guint limit); -void matrix_http_api_initial_sync_room(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id); -void matrix_http_api_list_room_members(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id); -void matrix_http_api_list_room_messages(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id, - const gchar *from_token, - MatrixAPIEventDirection direction, - guint limit); -void matrix_http_api_send_event_receipt(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id, - MatrixAPIReceiptType type, - const gchar *event_id, - JsonNode *receipt); -void matrix_http_api_redact_event(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id, - const gchar *event_id, - const gchar *txn_id, - const gchar *reason); -void matrix_http_api_send_message_event(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id, - const gchar *event_type, - const gchar *txn_id, - const JsonNode *content); -void matrix_http_api_get_room_state(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id, - const gchar *event_type, - const gchar *state_key); -void matrix_http_api_send_room_event(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *room_id, - const gchar *event_type, - const gchar *state_key, - JsonNode *content); -void matrix_http_api_notify_room_typing(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - const gchar *room_id, - guint timeout, - gboolean typing); -void matrix_http_api_sync(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *filter_id, - const JsonNode *filter, - const gchar *since, - gboolean full_state, - gboolean set_presence, - gulong timeout); -void matrix_http_api_create_filter(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - MatrixAPIFilter *filter); -void matrix_http_api_download_filter(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - const gchar *filter_id); - -/* Search */ -void *search_reserved; - -/* Server administration */ - -void matrix_http_api_whois(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id); - -/* Session management */ - -void matrix_http_api_login(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *type, - const JsonNode *content, - GError **error); -void matrix_http_api_token_refresh(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *refresh_token); - -/* User data */ - -void matrix_http_api_get_3pids(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data); -void matrix_http_api_add_3pid(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - gboolean bind_creds, - GList *threepid_creds); -void matrix_http_api_change_password(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *new_password); -void matrix_http_api_get_profile(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id); -void matrix_http_api_get_avatar_url(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id); -void matrix_http_api_set_avatar_url(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - const gchar *avatar_url); -void matrix_http_api_get_display_name(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id); -void matrix_http_api_set_display_name(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - const gchar *display_name); -void matrix_http_api_register_account(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - gboolean bind_email, - const gchar *username, - const gchar *password); -void matrix_http_api_set_account_data(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - const gchar *type, - JsonNode *content); -void matrix_http_api_set_room_account_data(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - const gchar *room_id, - const gchar *type, - JsonNode *content); -void matrix_http_api_get_room_tags(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - const gchar *room_id); -void matrix_http_api_delete_room_tag(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - const gchar *room_id, - const gchar *tag); -void matrix_http_api_add_room_tag(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data, - const gchar *user_id, - const gchar *room_id, - const gchar *tag, - JsonNode *content); - -/* VoIP */ - -void matrix_http_api_get_turn_server(MatrixAPI *api, - MatrixAPICallback callback, - gpointer user_data); - G_END_DECLS #endif /* __MATRIX_HTTP_API_H__ */ diff --git a/src/test-client.c b/src/test-client.c index 0c7c3f1..dd70d06 100644 --- a/src/test-client.c +++ b/src/test-client.c @@ -134,11 +134,11 @@ main(int argc, char *argv[]) json_builder_end_object(builder); login_content = json_builder_get_root(builder); - matrix_http_api_login(MATRIX_API(api), - login_finished, loop, - "m.login.password", - login_content, - &err); + matrix_api_login(MATRIX_API(api), + login_finished, loop, + "m.login.password", + login_content, + &err); if (err) { g_warning("Error: %s", err->message);