/pidgin/main: b057fee9d11a: HTTP progress watcher support
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Tue Oct 23 06:49:39 EDT 2012
Changeset: b057fee9d11a2ee93b588a37b4f33ea3ab9f8e98
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2012-10-23 12:48 +0200
Branch: default
URL: http://hg.pidgin.im/pidgin/main/rev/b057fee9d11a
Description:
HTTP progress watcher support
diffstat:
libpurple/http.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
libpurple/http.h | 27 +++++++++++++++++++++++++
2 files changed, 87 insertions(+), 0 deletions(-)
diffs (169 lines):
diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -78,6 +78,7 @@ struct _PurpleHttpConnection
PurpleConnection *gc;
PurpleHttpCallback callback;
gpointer user_data;
+ gboolean is_reading;
PurpleHttpURL *url;
PurpleHttpRequest *request;
@@ -103,6 +104,11 @@ struct _PurpleHttpConnection
GList *link_global, *link_gc;
guint timeout_handle;
+
+ PurpleHttpProgressWatcher watcher;
+ gpointer watcher_user_data;
+ guint watcher_interval_threshold;
+ gint64 watcher_last_call;
};
struct _PurpleHttpResponse
@@ -149,6 +155,7 @@ static time_t purple_http_rfc1123_to_tim
static PurpleHttpConnection * purple_http_connection_new(
PurpleHttpRequest *request, PurpleConnection *gc);
static void purple_http_connection_terminate(PurpleHttpConnection *hc);
+static void purple_http_conn_notify_progress_watcher(PurpleHttpConnection *hc);
static PurpleHttpResponse * purple_http_response_new(void);
static void purple_http_response_free(PurpleHttpResponse *response);
@@ -662,6 +669,8 @@ static void _purple_http_recv_body_data(
hc->data_length_got += len;
}
+ purple_http_conn_notify_progress_watcher(hc);
+
if (len == 0)
return;
@@ -1017,12 +1026,14 @@ static void _purple_http_send(gpointer _
if (writing_headers) {
hc->request_header_written += written;
+ purple_http_conn_notify_progress_watcher(hc);
if (hc->request_header_written < hc->request_header->len)
return;
if (hc->request->contents_length > 0)
return;
} else {
hc->request_contents_written += written;
+ purple_http_conn_notify_progress_watcher(hc);
if (hc->contents_reader_buffer)
g_string_erase(hc->contents_reader_buffer, 0, written);
if (hc->request_contents_written < hc->request->contents_length)
@@ -1030,6 +1041,7 @@ static void _purple_http_send(gpointer _
}
/* request is completely written, let's read the response */
+ hc->is_reading = TRUE;
purple_input_remove(hs->inpa);
hs->inpa = 0;
if (hs->is_ssl)
@@ -1192,6 +1204,8 @@ static gboolean _purple_http_reconnect(P
hc->in_chunk = FALSE;
hc->chunks_done = FALSE;
+ purple_http_conn_notify_progress_watcher(hc);
+
return TRUE;
}
@@ -1387,6 +1401,52 @@ PurpleConnection * purple_http_conn_get_
return http_conn->gc;
}
+void purple_http_conn_set_progress_watcher(PurpleHttpConnection *http_conn,
+ PurpleHttpProgressWatcher watcher, gpointer user_data,
+ guint interval_threshold)
+{
+ g_return_if_fail(http_conn != NULL);
+
+ http_conn->watcher = watcher;
+ http_conn->watcher_user_data = user_data;
+ http_conn->watcher_interval_threshold = interval_threshold;
+}
+
+static void purple_http_conn_notify_progress_watcher(
+ PurpleHttpConnection *hc)
+{
+ gint64 now;
+ gboolean reading_state;
+ int processed, total;
+
+ g_return_if_fail(hc != NULL);
+
+ if (hc->watcher == NULL)
+ return;
+
+ reading_state = hc->is_reading;
+ if (reading_state) {
+ total = hc->length_expected;
+ processed = hc->length_got;
+ } else {
+ total = hc->request->contents_length;
+ processed = hc->request_contents_written;
+ if (total == 0)
+ total = -1;
+ }
+ if (total != -1 && total < processed) {
+ purple_debug_warning("http", "Processed too much\n");
+ total = processed;
+ }
+
+ now = g_get_monotonic_time();
+ if (hc->watcher_last_call + hc->watcher_interval_threshold
+ > now && processed != total)
+ return;
+ hc->watcher_last_call = now;
+ hc->watcher(hc, reading_state, processed, total, hc->watcher_user_data);
+}
+
/*** Cookie jar API ***********************************************************/
static PurpleHttpCookie * purple_http_cookie_new(const gchar *value);
diff --git a/libpurple/http.h b/libpurple/http.h
--- a/libpurple/http.h
+++ b/libpurple/http.h
@@ -95,6 +95,19 @@ typedef void (*PurpleHttpContentWriter)(
PurpleHttpResponse *response, const gchar *buffer, size_t offset,
size_t length, gpointer user_data);
+/**
+ * An callback for watching HTTP connection progress.
+ *
+ * @param http_conn The HTTP Connection.
+ * @param reading_state FALSE, is we are sending the request, TRUE, when reading
+ * the response.
+ * @param processed The amount of data already processed.
+ * @param total Total amount of data (in current state).
+ * @param user_data The user data passed with callback function.
+ */
+typedef void (*PurpleHttpProgressWatcher)(PurpleHttpConnection *http_conn,
+ gboolean reading_state, int processed, int total, gpointer user_data);
+
G_BEGIN_DECLS
/**************************************************************************/
@@ -184,6 +197,20 @@ PurpleHttpCookieJar * purple_http_conn_g
PurpleConnection * purple_http_conn_get_purple_connection(
PurpleHttpConnection *http_conn);
+/**
+ * Sets the watcher, called after writing or reading data to/from HTTP stream.
+ * May be used for updating transfer progress gauge.
+ *
+ * @param http_conn The HTTP connection.
+ * @param watcher The watcher.
+ * @param user_data The user data to pass to the callback function.
+ * @param interval_threshold Minimum interval (in microseconds) of calls to
+ * watcher.
+ */
+void purple_http_conn_set_progress_watcher(PurpleHttpConnection *http_conn,
+ PurpleHttpProgressWatcher watcher, gpointer user_data,
+ guint interval_threshold);
+
/*@}*/
More information about the Commits
mailing list