diff options
author | Gary Kramlich <grim@reaperworld.com> | 2019-10-13 00:56:28 +0000 |
---|---|---|
committer | Gary Kramlich <grim@reaperworld.com> | 2019-10-13 00:56:28 +0000 |
commit | 64a833516d903037ddaf6a4fc932ff65a4b86d20 (patch) | |
tree | 8a873ed40f1bb2f54887f3570c0a4b3510d292a6 | |
parent | cb7b8aad5de2a1151f0c0cc72648ef618fd147af (diff) | |
parent | 1dd143c86b03c83660e1a40f991c82da6936a9e8 (diff) | |
download | pidgin-64a833516d903037ddaf6a4fc932ff65a4b86d20.tar.gz |
Merged in default (pull request #598)
Convert Gadu-Gadu to libsoup
Approved-by: Gary Kramlich
-rw-r--r-- | libpurple/protocols/gg/avatar.c | 249 | ||||
-rw-r--r-- | libpurple/protocols/gg/avatar.h | 9 | ||||
-rw-r--r-- | libpurple/protocols/gg/edisc.c | 428 | ||||
-rw-r--r-- | libpurple/protocols/gg/edisc.h | 2 | ||||
-rw-r--r-- | libpurple/protocols/gg/gg.c | 21 | ||||
-rw-r--r-- | libpurple/protocols/gg/gg.h | 4 | ||||
-rw-r--r-- | libpurple/protocols/gg/meson.build | 2 | ||||
-rw-r--r-- | libpurple/protocols/gg/oauth/oauth-parameter.c | 2 | ||||
-rw-r--r-- | libpurple/protocols/gg/oauth/oauth-purple.c | 79 | ||||
-rw-r--r-- | libpurple/protocols/gg/oauth/oauth.c | 4 | ||||
-rw-r--r-- | libpurple/protocols/gg/pubdir-prpl.c | 78 |
11 files changed, 382 insertions, 496 deletions
diff --git a/libpurple/protocols/gg/avatar.c b/libpurple/protocols/gg/avatar.c index f9ca551b58..c6a8d2be3a 100644 --- a/libpurple/protocols/gg/avatar.c +++ b/libpurple/protocols/gg/avatar.c @@ -48,21 +48,16 @@ typedef struct { uin_t uin; time_t timestamp; - PurpleConnection *gc; - PurpleHttpConnection *request; } ggp_avatar_buddy_update_req; -static gboolean ggp_avatar_buddy_update_next(PurpleConnection *gc); - #define GGP_AVATAR_BUDDY_URL "http://avatars.gg.pl/%u/s,big" /* Own avatar setting */ -typedef struct -{ - PurpleImage *img; -} ggp_avatar_own_data; +struct _ggp_avatar_session_data { + PurpleImage *own_img; +}; #define GGP_AVATAR_RESPONSE_MAX 10240 @@ -74,88 +69,27 @@ static inline ggp_avatar_session_data * ggp_avatar_get_avdata(PurpleConnection *gc) { GGPInfo *accdata = purple_connection_get_protocol_data(gc); - return &accdata->avatar_data; -} - -static gboolean -ggp_avatar_timer_cb(gpointer _gc) -{ - PurpleConnection *gc = _gc; - ggp_avatar_session_data *avdata; - - PURPLE_ASSERT_CONNECTION_IS_VALID(gc); - - avdata = ggp_avatar_get_avdata(gc); - if (avdata->current_update != NULL) { - if (purple_debug_is_verbose()) { - purple_debug_misc("gg", - "ggp_avatar_timer_cb(%p): there is already an " - "update running", - gc); - } - return TRUE; - } - - while (!ggp_avatar_buddy_update_next(gc)) - ; - - return TRUE; + return accdata->avatar_data; } void ggp_avatar_setup(PurpleConnection *gc) { - ggp_avatar_session_data *avdata = ggp_avatar_get_avdata(gc); - - avdata->pending_updates = NULL; - avdata->current_update = NULL; - avdata->own_data = g_new0(ggp_avatar_own_data, 1); + GGPInfo *info = purple_connection_get_protocol_data(gc); - avdata->timer = g_timeout_add_seconds(1, ggp_avatar_timer_cb, gc); + info->avatar_data = g_new0(ggp_avatar_session_data, 1); } void ggp_avatar_cleanup(PurpleConnection *gc) { - ggp_avatar_session_data *avdata = ggp_avatar_get_avdata(gc); + GGPInfo *info = purple_connection_get_protocol_data(gc); - g_source_remove(avdata->timer); - - if (avdata->current_update != NULL) { - ggp_avatar_buddy_update_req *current_update = - avdata->current_update; - - purple_http_conn_cancel(current_update->request); - g_free(current_update); - } - avdata->current_update = NULL; - - g_free(avdata->own_data); - - g_list_free_full(avdata->pending_updates, &g_free); - avdata->pending_updates = NULL; + g_free(info->avatar_data); } /******************************************************************************* * Buddy avatars updating. ******************************************************************************/ -void ggp_avatar_buddy_update(PurpleConnection *gc, uin_t uin, time_t timestamp) -{ - ggp_avatar_session_data *avdata = ggp_avatar_get_avdata(gc); - ggp_avatar_buddy_update_req *pending_update = - g_new(ggp_avatar_buddy_update_req, 1); /* TODO: leak? */ - - if (purple_debug_is_verbose()) { - purple_debug_misc("gg", "ggp_avatar_buddy_update(%p, %u, %lu)\n", gc, - uin, timestamp); - } - - pending_update->uin = uin; - pending_update->timestamp = timestamp; - - avdata->pending_updates = g_list_append(avdata->pending_updates, - pending_update); -} - void ggp_avatar_buddy_remove(PurpleConnection *gc, uin_t uin) { if (purple_debug_is_verbose()) { @@ -167,31 +101,24 @@ void ggp_avatar_buddy_remove(PurpleConnection *gc, uin_t uin) } static void -ggp_avatar_buddy_update_received(PurpleHttpConnection *http_conn, - PurpleHttpResponse *response, - gpointer _pending_update) +ggp_avatar_buddy_update_received(G_GNUC_UNUSED SoupSession *session, + SoupMessage *msg, gpointer _pending_update) { ggp_avatar_buddy_update_req *pending_update = _pending_update; PurpleBuddy *buddy; PurpleAccount *account; PurpleConnection *gc = pending_update->gc; - ggp_avatar_session_data *avdata; gchar timestamp_str[20]; const gchar *got_data; size_t got_len; PURPLE_ASSERT_CONNECTION_IS_VALID(gc); - avdata = ggp_avatar_get_avdata(gc); - g_assert(pending_update == avdata->current_update); - avdata->current_update = NULL; - - if (!purple_http_response_is_successful(response)) { + if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { purple_debug_error("gg", "ggp_avatar_buddy_update_received: bad response " "while getting avatar for %u: %s", - pending_update->uin, - purple_http_response_get_error(response)); + pending_update->uin, msg->reason_phrase); g_free(pending_update); return; } @@ -210,7 +137,8 @@ ggp_avatar_buddy_update_received(PurpleHttpConnection *http_conn, g_snprintf(timestamp_str, sizeof(timestamp_str), "%lu", pending_update->timestamp); - got_data = purple_http_response_get_data(response, &got_len); + got_data = msg->response_body->data; + got_len = msg->response_body->length; purple_buddy_icons_set_for_user(account, purple_buddy_get_name(buddy), g_memdup(got_data, got_len), got_len, timestamp_str); @@ -222,83 +150,77 @@ ggp_avatar_buddy_update_received(PurpleHttpConnection *http_conn, g_free(pending_update); } -/* return TRUE if avatar update was performed or there is no new requests, - FALSE if we can request another one immediately */ -static gboolean ggp_avatar_buddy_update_next(PurpleConnection *gc) +void +ggp_avatar_buddy_update(PurpleConnection *gc, uin_t uin, time_t timestamp) { - PurpleHttpRequest *req; - ggp_avatar_session_data *avdata = ggp_avatar_get_avdata(gc); - GList *pending_update_it; + GGPInfo *info = purple_connection_get_protocol_data(gc); + gchar *url; + SoupMessage *req; ggp_avatar_buddy_update_req *pending_update; PurpleBuddy *buddy; PurpleAccount *account = purple_connection_get_account(gc); time_t old_timestamp; const char *old_timestamp_str; - pending_update_it = g_list_first(avdata->pending_updates); - if (pending_update_it == NULL) - return TRUE; + if (purple_debug_is_verbose()) { + purple_debug_misc("gg", "ggp_avatar_buddy_update(%p, %u, %lu)", gc, uin, + timestamp); + } - pending_update = pending_update_it->data; - avdata->pending_updates = g_list_remove(avdata->pending_updates, - pending_update); - buddy = purple_blist_find_buddy(account, ggp_uin_to_str(pending_update->uin)); + buddy = purple_blist_find_buddy(account, ggp_uin_to_str(uin)); if (!buddy) { - if (ggp_str_to_uin(purple_account_get_username(account)) == - pending_update->uin) - { - purple_debug_misc("gg", - "ggp_avatar_buddy_update_next(%p): own " - "avatar update requested, but we don't have " - "ourselves on buddy list\n", gc); + if (ggp_str_to_uin(purple_account_get_username(account)) == uin) { + purple_debug_misc( + "gg", + "ggp_avatar_buddy_update(%p): own avatar update requested, " + "but we don't have ourselves on buddy list", + gc); } else { purple_debug_warning("gg", - "ggp_avatar_buddy_update_next(%p): " - "%u update requested, but he's not on buddy " - "list\n", gc, pending_update->uin); + "ggp_avatar_buddy_update(%p): %u update " + "requested, but he's not on buddy list", + gc, uin); } - return FALSE; + return; } old_timestamp_str = purple_buddy_icons_get_checksum_for_user(buddy); old_timestamp = old_timestamp_str ? g_ascii_strtoull( old_timestamp_str, NULL, 10) : 0; - if (old_timestamp == pending_update->timestamp) { + if (old_timestamp == timestamp) { if (purple_debug_is_verbose()) { purple_debug_misc("gg", - "ggp_avatar_buddy_update_next(%p): " - "%u have up to date avatar with ts=%lu\n", gc, - pending_update->uin, pending_update->timestamp); + "ggp_avatar_buddy_update(%p): %u have up to date " + "avatar with ts=%lu", + gc, uin, timestamp); } - return FALSE; + return; } - if (old_timestamp > pending_update->timestamp) { + if (old_timestamp > timestamp) { purple_debug_warning("gg", - "ggp_avatar_buddy_update_next(%p): " - "saved timestamp for %u is newer than received " - "(%lu > %lu)\n", gc, pending_update->uin, old_timestamp, - pending_update->timestamp); + "ggp_avatar_buddy_update(%p): saved timestamp for " + "%u is newer than received (%lu > %lu)", + gc, uin, old_timestamp, timestamp); } purple_debug_info("gg", - "ggp_avatar_buddy_update_next(%p): " - "updating %u with ts=%lu...\n", gc, pending_update->uin, - pending_update->timestamp); + "ggp_avatar_buddy_update(%p): updating %u with ts=%lu...", + gc, uin, timestamp); + pending_update = g_new(ggp_avatar_buddy_update_req, 1); + pending_update->uin = uin; + pending_update->timestamp = timestamp; pending_update->gc = gc; - avdata->current_update = pending_update; - - req = purple_http_request_new(NULL); - purple_http_request_set_url_printf(req, GGP_AVATAR_BUDDY_URL, - pending_update->uin); - purple_http_request_header_set(req, "User-Agent", GGP_AVATAR_USERAGENT); - purple_http_request_set_max_len(req, GGP_AVATAR_SIZE_MAX); - pending_update->request = purple_http_request(gc, req, - ggp_avatar_buddy_update_received, pending_update); - purple_http_request_unref(req); - - return TRUE; + + url = g_strdup_printf(GGP_AVATAR_BUDDY_URL, pending_update->uin); + req = soup_message_new("GET", url); + g_free(url); + soup_message_headers_replace(req->request_headers, "User-Agent", + GGP_AVATAR_USERAGENT); + // purple_http_request_set_max_len(req, GGP_AVATAR_SIZE_MAX); + soup_session_queue_message( + info->http, req, ggp_avatar_buddy_update_received, pending_update); } /******************************************************************************* @@ -314,74 +236,69 @@ static gboolean ggp_avatar_buddy_update_next(PurpleConnection *gc) */ static void -ggp_avatar_own_sent(PurpleHttpConnection *http_conn, - PurpleHttpResponse *response, gpointer user_data) +ggp_avatar_own_sent(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg, + gpointer user_data) { - PurpleConnection *gc = purple_http_conn_get_purple_connection(http_conn); + PurpleConnection *gc = user_data; PURPLE_ASSERT_CONNECTION_IS_VALID(gc); - if (!purple_http_response_is_successful(response)) { - purple_debug_error("gg", "ggp_avatar_own_sent: avatar not sent. %s", - purple_http_response_get_error(response)); + if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { + purple_debug_error("gg", "ggp_avatar_own_sent: avatar not sent. %s\n", + msg->reason_phrase); return; } purple_debug_info("gg", "ggp_avatar_own_sent: %s\n", - purple_http_response_get_data(response, NULL)); + msg->response_body->data); } static void ggp_avatar_own_got_token(PurpleConnection *gc, const gchar *token, gpointer _img) { - PurpleHttpRequest *req; + GGPInfo *info = purple_connection_get_protocol_data(gc); + ggp_avatar_session_data *avdata = ggp_avatar_get_avdata(gc); + SoupMessage *req; PurpleImage *img = _img; - ggp_avatar_own_data *own_data = ggp_avatar_get_avdata(gc)->own_data; - gchar *img_data, *img_data_e, *request_data; + gchar *img_data, *uin_str; PurpleAccount *account = purple_connection_get_account(gc); uin_t uin = ggp_str_to_uin(purple_account_get_username(account)); - if (img != own_data->img) { + if (img != avdata->own_img) { purple_debug_warning("gg", "ggp_avatar_own_got_token: " "avatar was changed in meantime\n"); return; } - own_data->img = NULL; + avdata->own_img = NULL; img_data = g_base64_encode(purple_image_get_data(img), purple_image_get_data_size(img)); - img_data_e = g_uri_escape_string(img_data, NULL, FALSE); - g_free(img_data); - request_data = g_strdup_printf("uin=%d&photo=%s", uin, img_data_e); - g_free(img_data_e); + uin_str = g_strdup_printf("%d", uin); purple_debug_misc("gg", "ggp_avatar_own_got_token: " "uploading new avatar...\n"); - req = purple_http_request_new("http://avatars.nowe.gg/upload"); - purple_http_request_set_max_len(req, GGP_AVATAR_RESPONSE_MAX); - purple_http_request_set_method(req, "POST"); - purple_http_request_header_set(req, "Authorization", token); - purple_http_request_header_set(req, "From", "avatars to avatars"); - purple_http_request_header_set(req, "Content-Type", - "application/x-www-form-urlencoded"); - purple_http_request_set_contents(req, request_data, -1); - purple_http_request(gc, req, ggp_avatar_own_sent, NULL); - purple_http_request_unref(req); - - g_free(request_data); + req = soup_form_request_new("POST", "http://avatars.nowe.gg/upload", "uin", + uin_str, "photo", img_data, NULL); + // purple_http_request_set_max_len(req, GGP_AVATAR_RESPONSE_MAX); + soup_message_headers_replace(req->request_headers, "Authorization", token); + soup_message_headers_replace(req->request_headers, "From", + "avatars to avatars"); + soup_session_queue_message(info->http, req, ggp_avatar_own_sent, gc); + g_free(img_data); + g_free(uin_str); } void ggp_avatar_own_set(PurpleConnection *gc, PurpleImage *img) { - ggp_avatar_own_data *own_data; + ggp_avatar_session_data *avdata; PURPLE_ASSERT_CONNECTION_IS_VALID(gc); purple_debug_info("gg", "ggp_avatar_own_set(%p, %p)", gc, img); - own_data = ggp_avatar_get_avdata(gc)->own_data; + avdata = ggp_avatar_get_avdata(gc); if (img == NULL) { purple_debug_warning("gg", "ggp_avatar_own_set: avatar removing is " @@ -389,7 +306,7 @@ ggp_avatar_own_set(PurpleConnection *gc, PurpleImage *img) return; } - own_data->img = img; + avdata->own_img = img; ggp_oauth_request(gc, ggp_avatar_own_got_token, img, NULL, NULL); } diff --git a/libpurple/protocols/gg/avatar.h b/libpurple/protocols/gg/avatar.h index ca4300b279..5f929af7f6 100644 --- a/libpurple/protocols/gg/avatar.h +++ b/libpurple/protocols/gg/avatar.h @@ -33,14 +33,7 @@ #include <internal.h> #include <libgadu.h> -typedef struct -{ - guint timer; - GList *pending_updates; - - gpointer current_update; - gpointer own_data; -} ggp_avatar_session_data; +typedef struct _ggp_avatar_session_data ggp_avatar_session_data; void ggp_avatar_setup(PurpleConnection *gc); void ggp_avatar_cleanup(PurpleConnection *gc); diff --git a/libpurple/protocols/gg/edisc.c b/libpurple/protocols/gg/edisc.c index 39914f0964..82633a1344 100644 --- a/libpurple/protocols/gg/edisc.c +++ b/libpurple/protocols/gg/edisc.c @@ -53,12 +53,12 @@ struct _ggp_edisc_session_data GHashTable *xfers_initialized; GHashTable *xfers_history; - PurpleHttpCookieJar *cookies; + SoupSession *session; gchar *security_token; - PurpleHttpConnection *auth_request; + SoupMessage *auth_request; gboolean auth_done; - GList *auth_pending; + GSList *auth_pending; }; struct _GGPXfer @@ -71,9 +71,7 @@ struct _GGPXfer gboolean allowed, ready; PurpleConnection *gc; - PurpleHttpConnection *hc; - - gsize already_read; + SoupMessage *msg; }; typedef enum @@ -103,14 +101,17 @@ ggp_edisc_get_sdata(PurpleConnection *gc) return accdata->edisc_data; } -void ggp_edisc_setup(PurpleConnection *gc) +void +ggp_edisc_setup(PurpleConnection *gc, GProxyResolver *resolver) { GGPInfo *accdata = purple_connection_get_protocol_data(gc); ggp_edisc_session_data *sdata = g_new0(ggp_edisc_session_data, 1); accdata->edisc_data = sdata; - sdata->cookies = purple_http_cookie_jar_new(); + sdata->session = soup_session_new_with_options( + SOUP_SESSION_PROXY_RESOLVER, resolver, + SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_COOKIE_JAR, NULL); sdata->xfers_initialized = g_hash_table_new(g_str_hash, g_str_equal); sdata->xfers_history = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); } @@ -121,11 +122,11 @@ void ggp_edisc_cleanup(PurpleConnection *gc) g_return_if_fail(sdata != NULL); - purple_http_conn_cancel(sdata->auth_request); - g_list_free_full(sdata->auth_pending, g_free); + soup_session_abort(sdata->session); + g_slist_free_full(sdata->auth_pending, g_free); g_free(sdata->security_token); - purple_http_cookie_jar_unref(sdata->cookies); + g_object_unref(sdata->session); g_hash_table_destroy(sdata->xfers_initialized); g_hash_table_destroy(sdata->xfers_history); @@ -136,27 +137,32 @@ void ggp_edisc_cleanup(PurpleConnection *gc) * Misc. ******************************************************************************/ -static void ggp_edisc_set_defaults(PurpleHttpRequest *req) +static void +ggp_edisc_set_defaults(SoupMessage *msg) { - purple_http_request_set_max_len(req, GGP_EDISC_RESPONSE_MAX); - purple_http_request_header_set(req, "X-gged-api-version", - GGP_EDISC_API); + // purple_http_request_set_max_len(msg, GGP_EDISC_RESPONSE_MAX); + soup_message_headers_replace(msg->request_headers, "X-gged-api-version", + GGP_EDISC_API); /* optional fields */ - purple_http_request_header_set(req, "User-Agent", "Mozilla/5.0 (Windows" - " NT 6.1; rv:11.0) Gecko/20120613 GG/11.0.0.8169 (WINNT_x86-msv" - "c; pl; beta; standard)"); - purple_http_request_header_set(req, "Accept", "text/html,application/xh" - "tml+xml,application/xml;q=0.9,*/*;q=0.8"); - purple_http_request_header_set(req, "Accept-Language", - "pl,en-us;q=0.7,en;q=0.3"); - /* purple_http_request_header_set(req, "Accept-Encoding", - * "gzip, deflate"); */ - purple_http_request_header_set(req, "Accept-Charset", - "ISO-8859-2,utf-8;q=0.7,*;q=0.7"); - purple_http_request_header_set(req, "Connection", "keep-alive"); - purple_http_request_header_set(req, "Content-Type", - "application/x-www-form-urlencoded; charset=UTF-8"); + soup_message_headers_replace( + msg->request_headers, "User-Agent", + "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20120613 " + "GG/11.0.0.8169 (WINNT_x86-msvc; pl; beta; standard)"); + soup_message_headers_replace( + msg->request_headers, "Accept", + "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); + soup_message_headers_replace(msg->request_headers, "Accept-Language", + "pl,en-us;q=0.7,en;q=0.3"); + /* soup_message_headers_replace(msg->request_headers, "Accept-Encoding", + * "gzip, deflate"); */ + soup_message_headers_replace(msg->request_headers, "Accept-Charset", + "ISO-8859-2,utf-8;q=0.7,*;q=0.7"); + soup_message_headers_replace(msg->request_headers, "Connection", + "keep-alive"); + soup_message_headers_replace( + msg->request_headers, "Content-Type", + "application/x-www-form-urlencoded; charset=UTF-8"); } static int ggp_edisc_parse_error(const gchar *data) @@ -226,30 +232,6 @@ static void ggp_edisc_xfer_error(PurpleXfer *xfer, const gchar *msg) purple_xfer_end(xfer); } -static void ggp_edisc_xfer_progress_watcher(PurpleHttpConnection *hc, - gboolean reading_state, int processed, int total, gpointer _xfer) -{ - PurpleXfer *xfer = _xfer; - gboolean eof; - int total_real; - - if (purple_xfer_get_xfer_type(xfer) == PURPLE_XFER_TYPE_RECEIVE) { - if (!reading_state) - return; - } else { - if (reading_state) - return; - } - - eof = (processed >= total); - total_real = purple_xfer_get_size(xfer); - if (eof || processed > total_real) - processed = total_real; /* just to be sure */ - - purple_xfer_set_bytes_sent(xfer, processed); - purple_xfer_update_progress(xfer); -} - /******************************************************************************* * Authentication. ******************************************************************************/ @@ -263,30 +245,27 @@ static void ggp_ggdrive_auth_results(PurpleConnection *gc, gboolean success) { ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc); - GList *it; + GSList *it; purple_debug_info("gg", "ggp_ggdrive_auth_results(gc=%p): %d", gc, success); g_return_if_fail(sdata != NULL); - it = g_list_first(sdata->auth_pending); - while (it) { + for (it = sdata->auth_pending; it; it = g_slist_delete_link(it, it)) { ggp_edisc_auth_data *auth = it->data; - it = g_list_next(it); auth->cb(gc, success, auth->user_data); g_free(auth); } - g_list_free(sdata->auth_pending); sdata->auth_pending = NULL; sdata->auth_done = TRUE; } static void -ggp_ggdrive_auth_done(PurpleHttpConnection *hc, PurpleHttpResponse *response, +ggp_ggdrive_auth_done(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg, gpointer user_data) { - PurpleConnection *gc = purple_http_conn_get_purple_connection(hc); + PurpleConnection *gc = user_data; ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc); JsonParser *parser; JsonObject *result; @@ -296,16 +275,16 @@ ggp_ggdrive_auth_done(PurpleHttpConnection *hc, PurpleHttpResponse *response, sdata->auth_request = NULL; - if (!purple_http_response_is_successful(response)) { + if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { purple_debug_misc("gg", "ggp_ggdrive_auth_done: authentication failed due to " "unsuccessful request (code = %d)", - purple_http_response_get_code(response)); + msg->status_code); ggp_ggdrive_auth_results(gc, FALSE); return; } - parser = ggp_json_parse(purple_http_response_get_data(response, NULL)); + parser = ggp_json_parse(msg->response_body->data); result = json_node_get_object(json_parser_get_root(parser)); result = json_object_get_object_member(result, "result"); if (json_object_has_member(result, "status")) @@ -319,14 +298,14 @@ ggp_ggdrive_auth_done(PurpleHttpConnection *hc, PurpleHttpResponse *response, status); if (purple_debug_is_verbose()) { purple_debug_misc("gg", "ggp_ggdrive_auth_done: result = %s", - purple_http_response_get_data(response, NULL)); + msg->response_body->data); } ggp_ggdrive_auth_results(gc, FALSE); return; } - sdata->security_token = g_strdup( - purple_http_response_get_header(response, "X-gged-security-token")); + sdata->security_token = g_strdup(soup_message_headers_get_one( + msg->response_headers, "X-gged-security-token")); if (!sdata->security_token) { purple_debug_misc("gg", "ggp_ggdrive_auth_done: authentication failed " "due to missing security token header"); @@ -350,7 +329,8 @@ ggp_ggdrive_auth(PurpleConnection *gc, ggp_ggdrive_auth_cb cb, ggp_edisc_auth_data *auth; const gchar *imtoken; gchar *metadata; - PurpleHttpRequest *req; + gchar *tmp; + SoupMessage *msg; g_return_if_fail(sdata != NULL); @@ -368,7 +348,7 @@ ggp_ggdrive_auth(PurpleConnection *gc, ggp_ggdrive_auth_cb cb, auth = g_new0(ggp_edisc_auth_data, 1); auth->cb = cb; auth->user_data = user_data; - sdata->auth_pending = g_list_prepend(sdata->auth_pending, auth); + sdata->auth_pending = g_slist_prepend(sdata->auth_pending, auth); if (sdata->auth_request) { return; @@ -376,11 +356,8 @@ ggp_ggdrive_auth(PurpleConnection *gc, ggp_ggdrive_auth_cb cb, purple_debug_info("gg", "ggp_ggdrive_auth(gc=%p)", gc); - req = purple_http_request_new("https://drive.mpa.gg.pl/signin"); - purple_http_request_set_method(req, "PUT"); - - ggp_edisc_set_defaults(req); - purple_http_request_set_cookie_jar(req, sdata->cookies); + msg = soup_message_new("PUT", "https://drive.mpa.gg.pl/signin"); + ggp_edisc_set_defaults(msg); metadata = g_strdup_printf("{" @@ -392,16 +369,18 @@ ggp_ggdrive_auth(PurpleConnection *gc, ggp_ggdrive_auth_cb cb, g_random_int_range(1, 1 << 16), purple_get_host_name(), ggp_libgaduw_version(gc)); - purple_http_request_header_set_printf(req, "Authorization", "IMToken %s", - imtoken); - purple_http_request_header_set_printf(req, "X-gged-user", "gg/pl:%u", - accdata->session->uin); - purple_http_request_header_set(req, "X-gged-client-metadata", metadata); + tmp = g_strdup_printf("IMToken %s", imtoken); + soup_message_headers_replace(msg->request_headers, "Authorization", tmp); + g_free(tmp); + tmp = g_strdup_printf("gg/pl:%u", accdata->session->uin); + soup_message_headers_replace(msg->request_headers, "X-gged-user", tmp); + g_free(tmp); + soup_message_headers_replace(msg->request_headers, "X-gged-client-metadata", + metadata); g_free(metadata); - sdata->auth_request = - purple_http_request(gc, req, ggp_ggdrive_auth_done, NULL); - purple_http_request_unref(req); + soup_session_queue_message(sdata->session, msg, ggp_ggdrive_auth_done, gc); + sdata->auth_request = msg; } static void @@ -460,14 +439,13 @@ ggp_edisc_xfer_can_receive_file(PurpleProtocolXfer *prplxfer, return PURPLE_BUDDY_IS_ONLINE(buddy); } -static void ggp_edisc_xfer_send_init_ticket_created(PurpleHttpConnection *hc, - PurpleHttpResponse *response, gpointer _xfer) +static void +ggp_edisc_xfer_send_init_ticket_created(G_GNUC_UNUSED SoupSession *session, + SoupMessage *msg, gpointer _xfer) { - ggp_edisc_session_data *sdata = ggp_edisc_get_sdata( - purple_http_conn_get_purple_connection(hc)); PurpleXfer *xfer = _xfer; GGPXfer *edisc_xfer = GGP_XFER(xfer); - const gchar *data = purple_http_response_get_data(response, NULL); + ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(edisc_xfer->gc); ggp_edisc_xfer_ack_status ack_status; JsonParser *parser; JsonObject *ticket; @@ -477,10 +455,10 @@ static void ggp_edisc_xfer_send_init_ticket_created(PurpleHttpConnection *hc, g_return_if_fail(sdata != NULL); - edisc_xfer->hc = NULL; + edisc_xfer->msg = NULL; - if (!purple_http_response_is_successful(response)) { - int error_id = ggp_edisc_parse_error(data); + if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { + int error_id = ggp_edisc_parse_error(msg->response_body->data); if (error_id == 206) /* recipient not logged in */ ggp_edisc_xfer_error(xfer, _("Recipient not logged in")); @@ -493,7 +471,7 @@ static void ggp_edisc_xfer_send_init_ticket_created(PurpleHttpConnection *hc, return; } - parser = ggp_json_parse(data); + parser = ggp_json_parse(msg->response_body->data); ticket = json_node_get_object(json_parser_get_root(parser)); ticket = json_object_get_object_member(ticket, "result"); ticket = json_object_get_object_member(ticket, "send_ticket"); @@ -530,7 +508,7 @@ ggp_edisc_xfer_send_init_authenticated(PurpleConnection *gc, gboolean success, gpointer _xfer) { ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc); - PurpleHttpRequest *req; + SoupMessage *msg; PurpleXfer *xfer = _xfer; GGPXfer *edisc_xfer = GGP_XFER(xfer); gchar *data; @@ -546,14 +524,11 @@ ggp_edisc_xfer_send_init_authenticated(PurpleConnection *gc, gboolean success, g_return_if_fail(sdata != NULL); - req = purple_http_request_new("https://drive.mpa.gg.pl/send_ticket"); - purple_http_request_set_method(req, "PUT"); + msg = soup_message_new("PUT", "https://drive.mpa.gg.pl/send_ticket"); + ggp_edisc_set_defaults(msg); - ggp_edisc_set_defaults(req); - purple_http_request_set_cookie_jar(req, sdata->cookies); - - purple_http_request_header_set(req, "X-gged-security-token", - sdata->security_token); + soup_message_headers_replace(msg->request_headers, "X-gged-security-token", + sdata->security_token); data = g_strdup_printf("{\"send_ticket\":{" "\"recipient\":\"%s\"," @@ -563,12 +538,13 @@ ggp_edisc_xfer_send_init_authenticated(PurpleConnection *gc, gboolean success, purple_xfer_get_remote_user(xfer), edisc_xfer->filename, (int)purple_xfer_get_size(xfer)); - purple_http_request_set_contents(req, data, -1); - g_free(data); + soup_message_set_request(msg, + "application/x-www-form-urlencoded; charset=UTF-8", + SOUP_MEMORY_TAKE, data, -1); - edisc_xfer->hc = purple_http_request( - gc, req, ggp_edisc_xfer_send_init_ticket_created, xfer); - purple_http_request_unref(req); + soup_session_queue_message(sdata->session, msg, + ggp_edisc_xfer_send_init_ticket_created, xfer); + edisc_xfer->msg = msg; } static void @@ -585,47 +561,38 @@ ggp_edisc_xfer_send_init(PurpleXfer *xfer) xfer); } -static void ggp_edisc_xfer_send_reader(PurpleHttpConnection *hc, - gchar *buffer, size_t offset, size_t length, gpointer _xfer, - PurpleHttpContentReaderCb cb) +static void +ggp_edisc_xfer_send_reader(SoupMessage *msg, gpointer _xfer) { PurpleXfer *xfer = _xfer; - GGPXfer *edisc_xfer; - int stored; - gboolean success, eof = FALSE; + guchar *buffer; + /* FIXME: The read/write xfer implementation sizes this dynamically. */ + gsize length = 4096; + gssize stored; - g_return_if_fail(xfer != NULL); - edisc_xfer = GGP_XFER(xfer); - g_return_if_fail(edisc_xfer != NULL); + buffer = g_new(guchar, length); + stored = purple_xfer_read_file(xfer, buffer, length); - if (edisc_xfer->already_read != offset) { - purple_debug_error("gg", "ggp_edisc_xfer_send_reader: " - "Invalid offset (%" G_GSIZE_FORMAT " != %" G_GSIZE_FORMAT ")\n", - edisc_xfer->already_read, offset); - ggp_edisc_xfer_error(xfer, _("Error while reading a file")); + if (stored < 0) { + GGPXfer *edisc_xfer = GGP_XFER(xfer); + ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(edisc_xfer->gc); + soup_session_cancel_message(sdata->session, msg, SOUP_STATUS_IO_ERROR); return; } - stored = purple_xfer_read_file(xfer, (guchar *)buffer, length); - - if (stored < 0) - success = FALSE; - else { - success = TRUE; - edisc_xfer->already_read += stored; - eof = ((goffset)edisc_xfer->already_read >= purple_xfer_get_size(xfer)); + soup_message_body_append(msg->request_body, SOUP_MEMORY_TAKE, buffer, + stored); + if (purple_xfer_get_bytes_sent(xfer) >= purple_xfer_get_size(xfer)) { + soup_message_body_complete(msg->request_body); } - - cb(hc, success, eof, stored); } static void -ggp_edisc_xfer_send_done(PurpleHttpConnection *hc, PurpleHttpResponse *response, +ggp_edisc_xfer_send_done(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg, gpointer _xfer) { PurpleXfer *xfer = _xfer; GGPXfer *edisc_xfer = GGP_XFER(xfer); - const gchar *data = purple_http_response_get_data(response, NULL); JsonParser *parser; JsonObject *result; int result_status = -1; @@ -636,14 +603,14 @@ ggp_edisc_xfer_send_done(PurpleHttpConnection *hc, PurpleHttpResponse *response, g_return_if_fail(edisc_xfer != NULL); - edisc_xfer->hc = NULL; + edisc_xfer->msg = NULL; - if (!purple_http_response_is_successful(response)) { + if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { ggp_edisc_xfer_error(xfer, _("Error while sending a file")); return; } - parser = ggp_json_parse(data); + parser = ggp_json_parse(msg->response_body->data); result = json_node_get_object(json_parser_get_root(parser)); result = json_object_get_object_member(result, "result"); if (json_object_has_member(result, "status")) { @@ -664,7 +631,7 @@ static void ggp_edisc_xfer_send_start(PurpleXfer *xfer) ggp_edisc_session_data *sdata; GGPXfer *edisc_xfer; gchar *upload_url, *filename_e; - PurpleHttpRequest *req; + SoupMessage *msg; g_return_if_fail(xfer != NULL); edisc_xfer = GGP_XFER(xfer); @@ -676,30 +643,30 @@ static void ggp_edisc_xfer_send_start(PurpleXfer *xfer) upload_url = g_strdup_printf("https://drive.mpa.gg.pl/me/file/outbox/" "%s%%2C%s", edisc_xfer->ticket_id, filename_e); g_free(filename_e); - req = purple_http_request_new(upload_url); + msg = soup_message_new("PUT", upload_url); g_free(upload_url); - purple_http_request_set_method(req, "PUT"); - purple_http_request_set_timeout(req, -1); - - ggp_edisc_set_defaults(req); - purple_http_request_set_cookie_jar(req, sdata->cookies); - - purple_http_request_header_set(req, "X-gged-local-revision", "0"); - purple_http_request_header_set(req, "X-gged-security-token", - sdata->security_token); - purple_http_request_header_set(req, "X-gged-metadata", - "{\"node_type\": \"file\"}"); - - purple_http_request_set_contents_reader(req, ggp_edisc_xfer_send_reader, - purple_xfer_get_size(xfer), xfer); - - edisc_xfer->hc = purple_http_request(edisc_xfer->gc, req, - ggp_edisc_xfer_send_done, xfer); - purple_http_request_unref(req); + ggp_edisc_set_defaults(msg); + + soup_message_headers_replace(msg->request_headers, "X-gged-local-revision", + "0"); + soup_message_headers_replace(msg->request_headers, "X-gged-security-token", + sdata->security_token); + soup_message_headers_replace(msg->request_headers, "X-gged-metadata", + "{\"node_type\": \"file\"}"); + + soup_message_set_flags(msg, SOUP_MESSAGE_CAN_REBUILD); + soup_message_body_set_accumulate(msg->request_body, FALSE); + soup_message_headers_set_content_length(msg->request_headers, + purple_xfer_get_size(xfer)); + g_signal_connect(msg, "wrote-headers", + G_CALLBACK(ggp_edisc_xfer_send_reader), xfer); + g_signal_connect(msg, "wrote-chunk", G_CALLBACK(ggp_edisc_xfer_send_reader), + xfer); - purple_http_conn_set_progress_watcher(edisc_xfer->hc, - ggp_edisc_xfer_progress_watcher, xfer, 250000); + soup_session_queue_message(sdata->session, msg, ggp_edisc_xfer_send_done, + xfer); + edisc_xfer->msg = msg; } PurpleXfer * ggp_edisc_xfer_send_new(PurpleProtocolXfer *prplxfer, PurpleConnection *gc, const char *who) @@ -762,8 +729,8 @@ ggp_edisc_xfer_recv_new(PurpleConnection *gc, const char *who) } static void -ggp_edisc_xfer_recv_ack_done(PurpleHttpConnection *hc, - PurpleHttpResponse *response, gpointer _xfer) +ggp_edisc_xfer_recv_ack_done(G_GNUC_UNUSED SoupSession *session, + SoupMessage *msg, gpointer _xfer) { PurpleXfer *xfer = _xfer; GGPXfer *edisc_xfer; @@ -773,45 +740,43 @@ ggp_edisc_xfer_recv_ack_done(PurpleHttpConnection *hc, } edisc_xfer = GGP_XFER(xfer); - edisc_xfer->hc = NULL; + edisc_xfer->msg = NULL; - if (!purple_http_response_is_successful(response)) { + if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { ggp_edisc_xfer_error(xfer, _("Cannot confirm file transfer.")); return; } purple_debug_info("gg", "ggp_edisc_xfer_recv_ack_done: [%s]\n", - purple_http_response_get_data(response, NULL)); + msg->response_body->data); } static void ggp_edisc_xfer_recv_ack(PurpleXfer *xfer, gboolean accept) { GGPXfer *edisc_xfer = GGP_XFER(xfer); ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(edisc_xfer->gc); - PurpleHttpRequest *req; + SoupMessage *msg; g_return_if_fail(sdata != NULL); edisc_xfer->allowed = accept; - req = purple_http_request_new(ggp_edisc_xfer_ticket_url( - edisc_xfer->ticket_id)); - purple_http_request_set_method(req, "PUT"); + msg = soup_message_new("PUT", + ggp_edisc_xfer_ticket_url(edisc_xfer->ticket_id)); + ggp_edisc_set_defaults(msg); - ggp_edisc_set_defaults(req); - purple_http_request_set_cookie_jar(req, sdata->cookies); - purple_http_request_header_set(req, "X-gged-security-token", - sdata->security_token); + soup_message_headers_replace(msg->request_headers, "X-gged-security-token", + sdata->security_token); + soup_message_headers_replace(msg->request_headers, "X-gged-ack-status", + accept ? "allow" : "reject"); - purple_http_request_header_set(req, "X-gged-ack-status", - accept ? "allow" : "reject"); - - edisc_xfer->hc = purple_http_request(edisc_xfer->gc, req, - accept ? ggp_edisc_xfer_recv_ack_done : NULL, xfer); - purple_http_request_unref(req); + soup_session_queue_message(sdata->session, msg, + accept ? ggp_edisc_xfer_recv_ack_done : NULL, + xfer); + edisc_xfer->msg = msg; if (!accept) { - edisc_xfer->hc = NULL; + edisc_xfer->msg = NULL; } } @@ -838,42 +803,37 @@ static void ggp_edisc_xfer_recv_ticket_completed(PurpleXfer *xfer) purple_xfer_start(xfer, -1, NULL, 0); } -static gboolean ggp_edisc_xfer_recv_writer(PurpleHttpConnection *http_conn, - PurpleHttpResponse *response, const gchar *buffer, size_t offset, - size_t length, gpointer _xfer) +static void +ggp_edisc_xfer_recv_writer(SoupMessage *msg, SoupBuffer *chunk, gpointer _xfer) { PurpleXfer *xfer = _xfer; - gssize stored; - - g_return_val_if_fail(xfer != NULL, FALSE); - - stored = purple_xfer_write_file(xfer, (guchar *)buffer, length) ? - (gssize)length : -1; - - if (stored < 0 || (gsize)stored != length) { - purple_debug_error("gg", "ggp_edisc_xfer_recv_writer: " - "saved too less\n"); - return FALSE; - } + GGPXfer *edisc_xfer = GGP_XFER(xfer); + ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(edisc_xfer->gc); + gboolean stored; - if (stored > purple_xfer_get_bytes_remaining(xfer)) { - purple_debug_error("gg", "ggp_edisc_xfer_recv_writer: " - "saved too much (%" G_GSSIZE_FORMAT " > %" G_GOFFSET_FORMAT ")\n", - stored, purple_xfer_get_bytes_remaining(xfer)); - return FALSE; + if (chunk->length > purple_xfer_get_bytes_remaining(xfer)) { + purple_debug_error( + "gg", + "ggp_edisc_xfer_recv_writer: saved too much (%" G_GSIZE_FORMAT + " > %" G_GOFFSET_FORMAT ")", + chunk->length, purple_xfer_get_bytes_remaining(xfer)); + soup_session_cancel_message(sdata->session, msg, SOUP_STATUS_IO_ERROR); + return; } - /* May look redundant with ggp_edisc_xfer_progress_watcher, - * but it isn't! - */ - purple_xfer_set_bytes_sent(xfer, - purple_xfer_get_bytes_sent(xfer) + stored); + stored = purple_xfer_write_file(xfer, (const guchar *)chunk->data, + chunk->length); - return TRUE; + if (!stored) { + purple_debug_error("gg", "ggp_edisc_xfer_recv_writer: saved too less"); + soup_session_cancel_message(sdata->session, msg, SOUP_STATUS_IO_ERROR); + return; + } } -static void ggp_edisc_xfer_recv_done(PurpleHttpConnection *hc, - PurpleHttpResponse *response, gpointer _xfer) +static void +ggp_edisc_xfer_recv_done(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg, + gpointer _xfer) { PurpleXfer *xfer = _xfer; GGPXfer *edisc_xfer = GGP_XFER(xfer); @@ -881,9 +841,9 @@ static void ggp_edisc_xfer_recv_done(PurpleHttpConnection *hc, if (purple_xfer_is_cancelled(xfer)) return; - edisc_xfer->hc = NULL; + edisc_xfer->msg = NULL; - if (!purple_http_response_is_successful(response)) { + if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { ggp_edisc_xfer_error(xfer, _("Error while receiving a file")); return; } @@ -904,7 +864,7 @@ ggp_edisc_xfer_recv_start(PurpleXfer *xfer) ggp_edisc_session_data *sdata; GGPXfer *edisc_xfer; gchar *upload_url; - PurpleHttpRequest *req; + SoupMessage *msg; g_return_if_fail(xfer != NULL); edisc_xfer = GGP_XFER(xfer); @@ -918,32 +878,26 @@ ggp_edisc_xfer_recv_start(PurpleXfer *xfer) edisc_xfer->ticket_id, purple_url_encode(purple_xfer_get_filename(xfer)), GGP_EDISC_API, sdata->security_token); - req = purple_http_request_new(upload_url); + msg = soup_message_new("GET", upload_url); g_free(upload_url); - purple_http_request_set_timeout(req, -1); + ggp_edisc_set_defaults(msg); + // purple_http_request_set_max_len(msg, purple_xfer_get_size(xfer) + 1); - ggp_edisc_set_defaults(req); - purple_http_request_set_max_len(req, purple_xfer_get_size(xfer) + 1); - purple_http_request_set_cookie_jar(req, sdata->cookies); - - purple_http_request_set_response_writer(req, ggp_edisc_xfer_recv_writer, - xfer); - - edisc_xfer->hc = purple_http_request(edisc_xfer->gc, req, - ggp_edisc_xfer_recv_done, xfer); - purple_http_request_unref(req); + soup_message_body_set_accumulate(msg->response_body, FALSE); + g_signal_connect(msg, "got-chunk", G_CALLBACK(ggp_edisc_xfer_recv_writer), + xfer); - purple_http_conn_set_progress_watcher( - edisc_xfer->hc, ggp_edisc_xfer_progress_watcher, xfer, 250000); + soup_session_queue_message(sdata->session, msg, ggp_edisc_xfer_recv_done, + xfer); + edisc_xfer->msg = msg; } static void -ggp_edisc_xfer_recv_ticket_update_got(PurpleHttpConnection *hc, - PurpleHttpResponse *response, - gpointer user_data) +ggp_edisc_xfer_recv_ticket_update_got(G_GNUC_UNUSED SoupSession *session, + SoupMessage *msg, gpointer user_data) { - PurpleConnection *gc = purple_http_conn_get_purple_connection(hc); + PurpleConnection *gc = user_data; PurpleXfer *xfer; GGPXfer *edisc_xfer; JsonParser *parser; @@ -955,18 +909,18 @@ ggp_edisc_xfer_recv_ticket_update_got(PurpleHttpConnection *hc, uin_t sender, recipient; int file_size; - if (!purple_http_response_is_successful(response)) { + if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { purple_debug_error("gg", "ggp_edisc_xfer_recv_ticket_update_got: cannot " "fetch update for ticket (code=%d)", - purple_http_response_get_code(response)); + msg->status_code); return; } sdata = ggp_edisc_get_sdata(gc); g_return_if_fail(sdata != NULL); - parser = ggp_json_parse(purple_http_response_get_data(response, NULL)); + parser = ggp_json_parse(msg->response_body->data); result = json_node_get_object(json_parser_get_root(parser)); result = json_object_get_object_member(result, "result"); if (json_object_has_member(result, "status")) @@ -1046,7 +1000,7 @@ ggp_edisc_xfer_recv_ticket_update_authenticated(PurpleConnection *gc, gpointer _ticket) { ggp_edisc_session_data *sdata = ggp_edisc_get_sdata(gc); - PurpleHttpRequest *req; + SoupMessage *msg; gchar *ticket = _ticket; g_return_if_fail(sdata != NULL); @@ -1061,17 +1015,16 @@ ggp_edisc_xfer_recv_ticket_update_authenticated(PurpleConnection *gc, return; } - req = purple_http_request_new(ggp_edisc_xfer_ticket_url(ticket)); + msg = soup_message_new("GET", ggp_edisc_xfer_ticket_url(ticket)); g_free(ticket); - ggp_edisc_set_defaults(req); - purple_http_request_set_cookie_jar(req, sdata->cookies); + ggp_edisc_set_defaults(msg); - purple_http_request_header_set(req, "X-gged-security-token", - sdata->security_token); + soup_message_headers_replace(msg->request_headers, "X-gged-security-token", + sdata->security_token); - purple_http_request(gc, req, ggp_edisc_xfer_recv_ticket_update_got, NULL); - purple_http_request_unref(req); + soup_session_queue_message(sdata->session, msg, + ggp_edisc_xfer_recv_ticket_update_got, gc); } static void @@ -1190,11 +1143,12 @@ ggp_xfer_finalize(GObject *obj) { GGPXfer *edisc_xfer = GGP_XFER(obj); ggp_edisc_session_data *sdata; - g_free(edisc_xfer->filename); - purple_http_conn_cancel(edisc_xfer->hc); - sdata = ggp_edisc_get_sdata(edisc_xfer->gc); + g_free(edisc_xfer->filename); + soup_session_cancel_message(sdata->session, edisc_xfer->msg, + SOUP_STATUS_CANCELLED); + if (edisc_xfer->ticket_id != NULL) { g_hash_table_remove(sdata->xfers_initialized, edisc_xfer->ticket_id); diff --git a/libpurple/protocols/gg/edisc.h b/libpurple/protocols/gg/edisc.h index 0608f5c395..811df84e1b 100644 --- a/libpurple/protocols/gg/edisc.h +++ b/libpurple/protocols/gg/edisc.h @@ -41,7 +41,7 @@ G_DECLARE_FINAL_TYPE(GGPXfer, ggp_xfer, GGP, XFER, PurpleXfer); void ggp_xfer_register(GTypeModule *module); /* Setting up. */ -void ggp_edisc_setup(PurpleConnection *gc); +void ggp_edisc_setup(PurpleConnection *gc, GProxyResolver *resolver); void ggp_edisc_cleanup(PurpleConnection *gc); /* General xfer functions. */ diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c index 22013f69cb..d21993f6e4 100644 --- a/libpurple/protocols/gg/gg.c +++ b/libpurple/protocols/gg/gg.c @@ -707,17 +707,30 @@ static void ggp_login(PurpleAccount *account) GGPInfo *info; const char *address; const gchar *encryption_type, *protocol_version; + GProxyResolver *resolver; + GError *error; purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_HTML | PURPLE_CONNECTION_FLAG_NO_URLDESC); + resolver = purple_proxy_get_proxy_resolver(account, &error); + if (resolver == NULL) { + purple_debug_error("gg", "Unable to get account proxy resolver: %s", + error->message); + purple_connection_g_error(gc, error); + return; + } + glp = g_new0(struct gg_login_params, 1); glp->struct_size = sizeof(struct gg_login_params); info = g_new0(GGPInfo, 1); purple_connection_set_protocol_data(gc, info); + info->http = soup_session_new_with_options(SOUP_SESSION_PROXY_RESOLVER, + resolver, NULL); + ggp_tcpsocket_setup(gc, glp); ggp_image_setup(gc); ggp_avatar_setup(gc); @@ -726,7 +739,8 @@ static void ggp_login(PurpleAccount *account) ggp_status_setup(gc); ggp_chat_setup(gc); ggp_message_setup(gc); - ggp_edisc_setup(gc); + ggp_edisc_setup(gc, resolver); + g_object_unref(resolver); glp->uin = ggp_str_to_uin(purple_account_get_username(account)); glp->password = @@ -843,6 +857,11 @@ static void ggp_close(PurpleConnection *gc) purple_input_remove(info->inpa); g_free(info->imtoken); + if (info->http) { + soup_session_abort(info->http); + g_object_unref(info->http); + } + purple_connection_set_protocol_data(gc, NULL); g_free(info); } diff --git a/libpurple/protocols/gg/gg.h b/libpurple/protocols/gg/gg.h index c99a7c6265..9c11a5f82e 100644 --- a/libpurple/protocols/gg/gg.h +++ b/libpurple/protocols/gg/gg.h @@ -27,6 +27,7 @@ #include <gmodule.h> #include <libgadu.h> +#include <libsoup/soup.h> #include "internal.h" #include "search.h" @@ -60,13 +61,14 @@ typedef struct typedef struct { struct gg_session *session; + SoupSession *http; guint inpa; gchar *imtoken; gboolean imtoken_warned; ggp_image_session_data *image_data; - ggp_avatar_session_data avatar_data; + ggp_avatar_session_data *avatar_data; ggp_roster_session_data roster_data; ggp_multilogon_session_data *multilogon_data; ggp_status_session_data *status_data; diff --git a/libpurple/protocols/gg/meson.build b/libpurple/protocols/gg/meson.build index 6f224a7fb9..a00647d9e0 100644 --- a/libpurple/protocols/gg/meson.build +++ b/libpurple/protocols/gg/meson.build @@ -53,6 +53,6 @@ GGSOURCES = [ if DYNAMIC_GG gg_prpl = shared_library('gg', GGSOURCES, - dependencies : [libgadu, json, libpurple_dep, glib], + dependencies : [libgadu, json, libpurple_dep, libsoup, glib], install : true, install_dir : PURPLE_PLUGINDIR) endif diff --git a/libpurple/protocols/gg/oauth/oauth-parameter.c b/libpurple/protocols/gg/oauth/oauth-parameter.c index 09facf86ff..566c30d5df 100644 --- a/libpurple/protocols/gg/oauth/oauth-parameter.c +++ b/libpurple/protocols/gg/oauth/oauth-parameter.c @@ -104,7 +104,7 @@ char *gg_oauth_parameter_join(gg_oauth_parameter_t *list, int header) len += 1; } - res = malloc(len + 1); + res = g_malloc(len + 1); if (res == NULL) return NULL; diff --git a/libpurple/protocols/gg/oauth/oauth-purple.c b/libpurple/protocols/gg/oauth/oauth-purple.c index 5efdbbbcb3..df4dba2bfc 100644 --- a/libpurple/protocols/gg/oauth/oauth-purple.c +++ b/libpurple/protocols/gg/oauth/oauth-purple.c @@ -28,6 +28,7 @@ */ #include "oauth-purple.h" +#include "gg.h" #include "oauth.h" #include "../utils.h" @@ -59,17 +60,16 @@ static void ggp_oauth_data_free(ggp_oauth_data *data) } static void -ggp_oauth_access_token_got(PurpleHttpConnection *http_conn, - PurpleHttpResponse *response, gpointer user_data) +ggp_oauth_access_token_got(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg, + gpointer user_data) { ggp_oauth_data *data = user_data; gchar *token, *token_secret; PurpleXmlNode *xml; - const gchar *xml_raw; gboolean succ = TRUE; - xml_raw = purple_http_response_get_data(response, NULL); - xml = purple_xmlnode_from_str(xml_raw, -1); + xml = purple_xmlnode_from_str(msg->response_body->data, + msg->response_body->length); if (xml == NULL) { purple_debug_error("gg", "ggp_oauth_access_token_got: invalid xml"); ggp_oauth_data_free(data); @@ -112,26 +112,23 @@ ggp_oauth_access_token_got(PurpleHttpConnection *http_conn, } static void -ggp_oauth_authorization_done(PurpleHttpConnection *http_conn, - PurpleHttpResponse *response, gpointer user_data) +ggp_oauth_authorization_done(SoupSession *session, SoupMessage *msg, + gpointer user_data) { ggp_oauth_data *data = user_data; PurpleAccount *account; - PurpleHttpRequest *req; char *auth; const char *method = "POST"; const char *url = "http://api.gadu-gadu.pl/access_token"; - int response_code; PURPLE_ASSERT_CONNECTION_IS_VALID(data->gc); account = purple_connection_get_account(data->gc); - response_code = purple_http_response_get_code(response); - if (response_code != 302) { + if (msg->status_code != 302) { purple_debug_error("gg", "ggp_oauth_authorization_done: failed (code = %d)", - response_code); + msg->status_code); ggp_oauth_data_free(data); return; } @@ -144,32 +141,29 @@ ggp_oauth_authorization_done(PurpleHttpConnection *http_conn, purple_connection_get_password(data->gc), data->token, data->token_secret); - req = purple_http_request_new(url); - purple_http_request_set_max_len(req, GGP_OAUTH_RESPONSE_MAX); - purple_http_request_set_method(req, method); - purple_http_request_header_set(req, "Authorization", auth); - purple_http_request(data->gc, req, ggp_oauth_access_token_got, data); - purple_http_request_unref(req); + msg = soup_message_new(method, url); + // purple_http_request_set_max_len(req, GGP_OAUTH_RESPONSE_MAX); + soup_message_headers_replace(msg->request_headers, "Authorization", auth); + soup_session_queue_message(session, msg, ggp_oauth_access_token_got, data); - free(auth); + g_free(auth); } -static void ggp_oauth_request_token_got(PurpleHttpConnection *http_conn, - PurpleHttpResponse *response, gpointer user_data) +static void +ggp_oauth_request_token_got(SoupSession *session, SoupMessage *msg, + gpointer user_data) { ggp_oauth_data *data = user_data; PurpleAccount *account; - PurpleHttpRequest *req; PurpleXmlNode *xml; gchar *request_data; gboolean succ = TRUE; - const gchar *xml_raw; PURPLE_ASSERT_CONNECTION_IS_VALID(data->gc); account = purple_connection_get_account(data->gc); - if (!purple_http_response_is_successful(response)) { + if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { purple_debug_error("gg", "ggp_oauth_request_token_got: " "requested token not received\n"); ggp_oauth_data_free(data); @@ -179,8 +173,8 @@ static void ggp_oauth_request_token_got(PurpleHttpConnection *http_conn, purple_debug_misc("gg", "ggp_oauth_request_token_got: " "got request token, doing authorization...\n"); - xml_raw = purple_http_response_get_data(response, NULL); - xml = purple_xmlnode_from_str(xml_raw, -1); + xml = purple_xmlnode_from_str(msg->response_body->data, + msg->response_body->length); if (xml == NULL) { purple_debug_error("gg", "ggp_oauth_request_token_got: " "invalid xml\n"); @@ -205,17 +199,14 @@ static void ggp_oauth_request_token_got(PurpleHttpConnection *http_conn, purple_account_get_username(account), purple_connection_get_password(data->gc)); - req = purple_http_request_new("https://login.gadu-gadu.pl/authorize"); - purple_http_request_set_max_len(req, GGP_OAUTH_RESPONSE_MAX); + msg = soup_message_new("POST", "https://login.gadu-gadu.pl/authorize"); + // purple_http_request_set_max_len(msg, GGP_OAUTH_RESPONSE_MAX); /* we don't need any results, nor 302 redirection */ - purple_http_request_set_max_redirects(req, 0); - purple_http_request_set_method(req, "POST"); - purple_http_request_header_set(req, "Content-Type", "application/x-www-form-urlencoded"); - purple_http_request_set_contents(req, request_data, -1); - purple_http_request(data->gc, req, ggp_oauth_authorization_done, data); - purple_http_request_unref(req); - - g_free(request_data); + soup_message_set_flags(msg, SOUP_MESSAGE_NO_REDIRECT); + soup_message_set_request(msg, "application/x-www-form-urlencoded", + SOUP_MEMORY_TAKE, request_data, -1); + soup_session_queue_message(session, msg, ggp_oauth_authorization_done, + data); } void @@ -223,8 +214,9 @@ ggp_oauth_request(PurpleConnection *gc, ggp_oauth_request_cb callback, gpointer user_data, const gchar *sign_method, const gchar *sign_url) { + GGPInfo *info = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc); - PurpleHttpRequest *req; + SoupMessage *msg; char *auth; const char *method = "POST"; const char *url = "http://api.gadu-gadu.pl/request_token"; @@ -243,12 +235,11 @@ ggp_oauth_request(PurpleConnection *gc, ggp_oauth_request_cb callback, data->sign_method = g_strdup(sign_method); data->sign_url = g_strdup(sign_url); - req = purple_http_request_new(url); - purple_http_request_set_max_len(req, GGP_OAUTH_RESPONSE_MAX); - purple_http_request_set_method(req, method); - purple_http_request_header_set(req, "Authorization", auth); - purple_http_request(gc, req, ggp_oauth_request_token_got, data); - purple_http_request_unref(req); + msg = soup_message_new(method, url); + // purple_http_request_set_max_len(req, GGP_OAUTH_RESPONSE_MAX); + soup_message_headers_replace(msg->request_headers, "Authorization", auth); + soup_session_queue_message(info->http, msg, ggp_oauth_request_token_got, + data); - free(auth); + g_free(auth); } diff --git a/libpurple/protocols/gg/oauth/oauth.c b/libpurple/protocols/gg/oauth/oauth.c index 1ca3c458bf..60affd48a4 100644 --- a/libpurple/protocols/gg/oauth/oauth.c +++ b/libpurple/protocols/gg/oauth/oauth.c @@ -122,7 +122,7 @@ gg_oauth_generate_header(const char *method, const char *url, signature = gg_oauth_generate_signature(method, url, request, consumer_secret, token_secret); - free(request); + g_free(request); gg_oauth_parameter_free(params); params = NULL; @@ -138,7 +138,7 @@ gg_oauth_generate_header(const char *method, const char *url, gg_oauth_parameter_set(¶ms, "oauth_signature_method", "HMAC-SHA1"); gg_oauth_parameter_set(¶ms, "oauth_signature", signature); - free(signature); + g_free(signature); res = gg_oauth_parameter_join(params, 1); diff --git a/libpurple/protocols/gg/pubdir-prpl.c b/libpurple/protocols/gg/pubdir-prpl.c index 65ec0a1085..76804e21b9 100644 --- a/libpurple/protocols/gg/pubdir-prpl.c +++ b/libpurple/protocols/gg/pubdir-prpl.c @@ -28,6 +28,7 @@ */ #include "pubdir-prpl.h" +#include "gg.h" #include <debug.h> #include <http.h> @@ -135,8 +136,9 @@ ggp_pubdir_request_free(ggp_pubdir_request *request) g_free(request); } -static void ggp_pubdir_got_data(PurpleHttpConnection *http_conn, - PurpleHttpResponse *response, gpointer _request) +static void +ggp_pubdir_got_data(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg, + gpointer _request) { ggp_pubdir_request *request = _request; PurpleConnection *gc = request->gc; @@ -147,7 +149,7 @@ static void ggp_pubdir_got_data(PurpleHttpConnection *http_conn, int record_count, i; ggp_pubdir_record *records; - xml_raw = purple_http_response_get_data(response, NULL); + xml_raw = msg->response_body->data; if (purple_debug_is_verbose() && purple_debug_is_unsafe()) { purple_debug_misc("gg", "ggp_pubdir_got_data: xml=[%s]\n", @@ -272,7 +274,9 @@ static void ggp_pubdir_get_info_got_token(PurpleConnection *gc, const gchar *token, gpointer _request) { - PurpleHttpRequest *req; + GGPInfo *info = NULL; + gchar *url; + SoupMessage *msg; ggp_pubdir_request *request = _request; PURPLE_ASSERT_CONNECTION_IS_VALID(gc); @@ -283,12 +287,14 @@ ggp_pubdir_get_info_got_token(PurpleConnection *gc, const gchar *token, return; } - req = purple_http_request_new(NULL); - purple_http_request_set_url_printf(req, "http://api.gadu-gadu.pl/users/%u", - request->params.user_info.uin); - purple_http_request_header_set(req, "Authorization", token); - purple_http_request(gc, req, ggp_pubdir_got_data, request); - purple_http_request_unref(req); + info = purple_connection_get_protocol_data(gc); + + url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u", + request->params.user_info.uin); + msg = soup_message_new("GET", url); + g_free(url); + soup_message_headers_replace(msg->request_headers, "Authorization", token); + soup_session_queue_message(info->http, msg, ggp_pubdir_got_data, request); } void @@ -501,7 +507,9 @@ static gchar * ggp_pubdir_search_make_query(const ggp_pubdir_search_form *form) static void ggp_pubdir_search_got_token(PurpleConnection *gc, const gchar *token, gpointer _request) { - PurpleHttpRequest *req; + GGPInfo *info = NULL; + gchar *url; + SoupMessage *msg; ggp_pubdir_request *request = _request; gchar *query; @@ -517,12 +525,14 @@ static void ggp_pubdir_search_got_token(PurpleConnection *gc, query = ggp_pubdir_search_make_query(request->params.search_form); - req = purple_http_request_new(NULL); - purple_http_request_set_url_printf(req, "http://api.gadu-gadu.pl%s", query); - purple_http_request_header_set(req, "Authorization", token); - purple_http_request(gc, req, ggp_pubdir_got_data, request); - purple_http_request_unref(req); + info = purple_connection_get_protocol_data(gc); + + url = g_strdup_printf("http://api.gadu-gadu.pl%s", query); + msg = soup_message_new("GET", url); + soup_message_headers_replace(msg->request_headers, "Authorization", token); + soup_session_queue_message(info->http, msg, ggp_pubdir_got_data, request); + g_free(url); g_free(query); } @@ -744,17 +754,16 @@ ggp_pubdir_search(PurpleConnection *gc, const ggp_pubdir_search_form *form) ******************************************************************************/ static void -ggp_pubdir_set_info_got_response(PurpleHttpConnection *http_conn, - PurpleHttpResponse *response, - gpointer user_data) +ggp_pubdir_set_info_got_response(G_GNUC_UNUSED SoupSession *session, + SoupMessage *msg, gpointer user_data) { - if (!purple_http_response_is_successful(response)) { + if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { purple_debug_error("gg", "ggp_pubdir_set_info_got_response: failed"); return; } purple_debug_info("gg", "ggp_pubdir_set_info_got_response: [%s]", - purple_http_response_get_data(response, NULL)); + msg->response_body->data); /* <result><status>0</status></result> */ /* TODO: notify about failure */ @@ -763,8 +772,10 @@ ggp_pubdir_set_info_got_response(PurpleHttpConnection *http_conn, static void ggp_pubdir_set_info_got_token(PurpleConnection *gc, const gchar *token, gpointer _record) { - PurpleHttpRequest *req; ggp_pubdir_record *record = _record; + GGPInfo *info = NULL; + SoupMessage *msg; + gchar *url; gchar *request_data; gchar *name, *surname, *city; uin_t uin = record->uin; @@ -777,6 +788,8 @@ static void ggp_pubdir_set_info_got_token(PurpleConnection *gc, return; } + info = purple_connection_get_protocol_data(gc); + name = g_uri_escape_string(record->first_name, NULL, FALSE); surname = g_uri_escape_string(record->last_name, NULL, FALSE); city = g_uri_escape_string(record->city, NULL, FALSE); @@ -801,18 +814,15 @@ static void ggp_pubdir_set_info_got_token(PurpleConnection *gc, "query [%s]\n", request_data); } - req = purple_http_request_new(NULL); - purple_http_request_set_method(req, "PUT"); - purple_http_request_set_url_printf(req, - "http://api.gadu-gadu.pl/users/%u.xml", uin); - purple_http_request_header_set(req, "Authorization", token); - purple_http_request_header_set(req, "Content-Type", - "application/x-www-form-urlencoded"); - purple_http_request_set_contents(req, request_data, -1); - purple_http_request(gc, req, ggp_pubdir_set_info_got_response, NULL); - purple_http_request_unref(req); - - g_free(request_data); + url = g_strdup_printf("http://api.gadu-gadu.pl/users/%u.xml", uin); + msg = soup_message_new("PUT", url); + soup_message_headers_replace(msg->request_headers, "Authorization", token); + soup_message_set_request(msg, "application/x-www-form-urlencoded", + SOUP_MEMORY_TAKE, request_data, -1); + soup_session_queue_message(info->http, msg, + ggp_pubdir_set_info_got_response, NULL); + + g_free(url); ggp_pubdir_record_free(record, 1); } |