/cpw/tomkiewicz/http: 4d41b1f7b95f: Cancelling all HTTP connecti...
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Tue Oct 16 14:49:50 EDT 2012
Changeset: 4d41b1f7b95f7370096165eb7526a1aa494e9b32
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2012-10-16 20:49 +0200
Branch: default
URL: http://hg.pidgin.im/cpw/tomkiewicz/http/rev/4d41b1f7b95f
Description:
Cancelling all HTTP connections on account disconnect or app shutdown
diffstat:
libpurple/http.c | 101 +++++++++++++++++++++++++++++++++++++++++--
libpurple/http.h | 13 +++--
libpurple/protocols/gg/gg.c | 30 +++++-------
3 files changed, 116 insertions(+), 28 deletions(-)
diffs (273 lines):
diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -84,6 +84,8 @@ struct _PurpleHttpConnection
gboolean is_chunked, in_chunk, chunks_done;
int chunk_length, chunk_got;
+
+ GList *link_global, *link_gc;
};
struct _PurpleHttpResponse
@@ -113,7 +115,7 @@ struct _PurpleHttpHeaders
};
static PurpleHttpConnection * purple_http_connection_new(
- PurpleHttpRequest *request);
+ PurpleHttpRequest *request, PurpleConnection *gc);
static void purple_http_connection_terminate(PurpleHttpConnection *hc);
static PurpleHttpResponse * purple_http_response_new(void);
@@ -127,6 +129,23 @@ static gchar * purple_http_url_print(Pur
static GRegex *purple_http_re_url, *purple_http_re_url_host;
+/**
+ * Values: pointers to running PurpleHttpConnection.
+ */
+static GList *purple_http_hc_list;
+
+/**
+ * Keys: pointers to PurpleConnection.
+ * Values: GList of pointers to running PurpleHttpConnection.
+ */
+static GHashTable *purple_http_hc_by_gc;
+
+/**
+ * Keys: pointers to PurpleHttpConnection.
+ * Values: pointers to links in purple_http_hc_list.
+ */
+static GHashTable *purple_http_hc_by_ptr;
+
/*** Headers collection *******************************************************/
static PurpleHttpHeaders * purple_http_headers_new(void);
@@ -919,8 +938,7 @@ PurpleHttpConnection * purple_http_reque
g_return_val_if_fail(request != NULL, NULL);
- hc = purple_http_connection_new(request);
- hc->gc = gc;
+ hc = purple_http_connection_new(request, gc);
hc->callback = callback;
hc->user_data = user_data;
@@ -948,7 +966,8 @@ PurpleHttpConnection * purple_http_reque
static void purple_http_connection_free(PurpleHttpConnection *hc);
-static PurpleHttpConnection * purple_http_connection_new(PurpleHttpRequest *request)
+static PurpleHttpConnection * purple_http_connection_new(
+ PurpleHttpRequest *request, PurpleConnection *gc)
{
PurpleHttpConnection *hc = g_new0(PurpleHttpConnection, 1);
@@ -956,6 +975,17 @@ static PurpleHttpConnection * purple_htt
purple_http_request_ref(request);
hc->response = purple_http_response_new();
+ hc->link_global = purple_http_hc_list =
+ g_list_prepend(purple_http_hc_list, hc);
+ g_hash_table_insert(purple_http_hc_by_ptr, hc, hc->link_global);
+ if (gc) {
+ GList *gc_list = g_hash_table_lookup(purple_http_hc_by_gc, gc);
+ g_hash_table_steal(purple_http_hc_by_gc, gc);
+ hc->link_gc = gc_list = g_list_prepend(gc_list, hc);
+ g_hash_table_insert(purple_http_hc_by_gc, gc, gc_list);
+ hc->gc = gc;
+ }
+
return hc;
}
@@ -968,6 +998,23 @@ static void purple_http_connection_free(
if (hc->request_header)
g_string_free(hc->request_header, TRUE);
+ purple_http_hc_list = g_list_delete_link(purple_http_hc_list,
+ hc->link_global);
+ g_hash_table_remove(purple_http_hc_by_ptr, hc);
+ if (hc->gc) {
+ GList *gc_list, *gc_list_new;
+ gc_list = g_hash_table_lookup(purple_http_hc_by_gc, hc->gc);
+ g_assert(gc_list != NULL);
+
+ gc_list_new = g_list_delete_link(gc_list, hc->link_gc);
+ if (gc_list != gc_list_new) {
+ g_hash_table_steal(purple_http_hc_by_gc, hc->gc);
+ if (gc_list_new)
+ g_hash_table_insert(purple_http_hc_by_gc,
+ hc->gc, gc_list_new);
+ }
+ }
+
g_free(hc);
}
@@ -995,7 +1042,24 @@ void purple_http_conn_cancel(PurpleHttpC
void purple_http_conn_cancel_all(PurpleConnection *gc)
{
- purple_debug_warning("http", "purple_http_conn_cancel_all: To be implemented\n");
+ GList *gc_list = g_hash_table_lookup(purple_http_hc_by_gc, gc);
+
+ while (gc_list) {
+ PurpleHttpConnection *hc = gc_list->data;
+ gc_list = g_list_next(gc_list);
+ purple_http_conn_cancel(hc);
+ }
+
+ if (NULL != g_hash_table_lookup(purple_http_hc_by_gc, gc))
+ purple_debug_error("http", "Couldn't cancel all connections "
+ "related to gc=%p\n", gc);
+}
+
+gboolean purple_http_conn_is_running(PurpleHttpConnection *http_conn)
+{
+ if (http_conn == NULL)
+ return FALSE;
+ return (NULL != g_hash_table_lookup(purple_http_hc_by_ptr, http_conn));
}
/*** Request API **************************************************************/
@@ -1435,6 +1499,17 @@ void purple_http_init(void)
"$", G_REGEX_OPTIMIZE | G_REGEX_CASELESS,
G_REGEX_MATCH_NOTEMPTY, NULL);
+
+ purple_http_hc_list = NULL;
+ purple_http_hc_by_ptr = g_hash_table_new(g_direct_hash, g_direct_equal);
+ purple_http_hc_by_gc = g_hash_table_new_full(g_direct_hash,
+ g_direct_equal, NULL, (GDestroyNotify)g_list_free);
+}
+
+static void purple_http_foreach_conn_cancel(gpointer _hc, gpointer user_data)
+{
+ PurpleHttpConnection *hc = _hc;
+ purple_http_conn_cancel(hc);
}
void purple_http_uninit(void)
@@ -1443,4 +1518,20 @@ void purple_http_uninit(void)
purple_http_re_url = NULL;
g_regex_unref(purple_http_re_url_host);
purple_http_re_url_host = NULL;
+
+ g_list_foreach(purple_http_hc_list, purple_http_foreach_conn_cancel,
+ NULL);
+
+ if (purple_http_hc_list != NULL ||
+ 0 != g_hash_table_size(purple_http_hc_by_ptr) ||
+ 0 != g_hash_table_size(purple_http_hc_by_gc))
+ purple_debug_warning("http",
+ "Couldn't cleanup all connections.\n");
+
+ g_list_free(purple_http_hc_list);
+ purple_http_hc_list = NULL;
+ g_hash_table_destroy(purple_http_hc_by_gc);
+ purple_http_hc_by_gc = NULL;
+ g_hash_table_destroy(purple_http_hc_by_ptr);
+ purple_http_hc_by_ptr = NULL;
}
diff --git a/libpurple/http.h b/libpurple/http.h
--- a/libpurple/http.h
+++ b/libpurple/http.h
@@ -143,9 +143,16 @@ PurpleHttpConnection * purple_http_reque
void purple_http_conn_cancel(PurpleHttpConnection *http_conn);
/**
+ * Cancels all HTTP connections associated with the specified handle.
+ *
+ * @param gc The handle.
+ */
+void purple_http_conn_cancel_all(PurpleConnection *gc);
+
+/**
* Checks, if provided HTTP request is running.
*
- * @param http_conn The HTTP connection.
+ * @param http_conn The HTTP connection (may be invalid pointer).
* @return TRUE, if provided connection is currently running.
*/
gboolean purple_http_conn_is_running(PurpleHttpConnection *http_conn);
@@ -156,10 +163,6 @@ PurpleHttpRequest * purple_http_conn_get
PurpleConnection * purple_http_conn_get_purple_connection(
PurpleHttpConnection *http_conn);
-const GSList * purple_http_conn_get_all(PurpleConnection *gc);
-
-void purple_http_conn_cancel_all(PurpleConnection *gc);
-
/*@}*/
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -58,7 +58,6 @@
#include <http.h>
#include <obsolete.h>
-/*
static void ggp_test_http_cb(PurpleHttpConnection *http_conn,
PurpleHttpResponse *response, gpointer user_data)
{
@@ -85,7 +84,6 @@ static void ggp_test_http_cb(PurpleHttpC
g_free(data_tail);
}
}
-*/
static void ggp_test_http_cb2(PurpleUtilFetchUrlData *url_data,
gpointer user_data, const gchar *url_text, gsize len,
@@ -117,9 +115,6 @@ static void ggp_action_test_http(PurpleP
PurpleConnection *gc = (PurpleConnection *)action->context;
purple_debug_info("http-test", "Testing http...\n");
-// purple_http_get(gc, "http://www.wasilczyk.pl/x_ip_simple.htm",
-// ggp_test_http_cb, NULL);
-/*
purple_http_get(gc, "http://www.wasilczyk.pl/x_ip_simple.htm",
ggp_test_http_cb, NULL);
purple_http_get(gc, "http://www.wasilczyk.pl/x_ip_simple.htm",
@@ -130,27 +125,26 @@ static void ggp_action_test_http(PurpleP
ggp_test_http_cb, NULL);
purple_http_get(gc, "http://www.wasilczyk.pl/x_ip_simple.htm",
ggp_test_http_cb, NULL);
-*/
-// purple_http_get(gc, "http://google.com",
-// ggp_test_http_cb, NULL);
-// purple_http_get(gc, "http://wp.pl",
-// ggp_test_http_cb, NULL);
+ purple_http_get(gc, "http://google.com",
+ ggp_test_http_cb, NULL);
+ purple_http_get(gc, "http://wp.pl",
+ ggp_test_http_cb, NULL);
-// purple_http_get(gc, "https://www.google.pl",
-// ggp_test_http_cb, NULL);
+ purple_http_get(gc, "https://www.google.pl",
+ ggp_test_http_cb, NULL);
// purple_util_fetch_url("https://www.google.pl",
purple_util_fetch_url("http://wp.pl",
TRUE, "My Browser", TRUE, -1, ggp_test_http_cb2, NULL);
-// request = purple_http_request_new("http://wp.pl");
-// purple_http_request_set_http11(request, FALSE);
-// purple_http_request_set_max_redirects(request, 1);
-// purple_http_request_set_max_len(request, 0);
-// purple_http_request(gc, request, ggp_test_http_cb, NULL);
-// purple_http_request_unref(request);
+ request = purple_http_request_new("http://wp.pl");
+ purple_http_request_set_http11(request, FALSE);
+ purple_http_request_set_max_redirects(request, 1);
+ purple_http_request_set_max_len(request, 0);
+ purple_http_request(gc, request, ggp_test_http_cb, NULL);
+ purple_http_request_unref(request);
purple_debug_info("http-test", "Testing http started.\n");
}
More information about the Commits
mailing list