/pidgin/main: ddd9e37c4b07: HTTP: PurpleHttpContentWriter support

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Mon Nov 5 19:12:22 EST 2012


Changeset: ddd9e37c4b0743b16cad4798d132a7320d4f440d
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-11-06 01:10 +0100
Branch:	 default
URL: http://hg.pidgin.im/pidgin/main/rev/ddd9e37c4b07

Description:

HTTP: PurpleHttpContentWriter support

diffstat:

 libpurple/http.c |  57 +++++++++++++++++++++++++++++++++++++++++--------------
 libpurple/http.h |   6 ++--
 2 files changed, 45 insertions(+), 18 deletions(-)

diffs (138 lines):

diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -66,6 +66,8 @@ struct _PurpleHttpRequest
 	int contents_length;
 	PurpleHttpContentReader contents_reader;
 	gpointer contents_reader_data;
+	PurpleHttpContentWriter response_writer;
+	gpointer response_writer_data;
 
 	int timeout;
 	int max_redirects;
@@ -650,23 +652,41 @@ static gboolean _purple_http_recv_header
 	return TRUE;
 }
 
-static void _purple_http_recv_body_data(PurpleHttpConnection *hc,
+static gboolean _purple_http_recv_body_data(PurpleHttpConnection *hc,
 	const gchar *buf, int len)
 {
+	int current_offset = hc->data_length_got;
+
 	if (hc->request->max_length >= 0) {
 		if (hc->data_length_got + len > hc->request->max_length) {
 			len = hc->request->max_length - hc->data_length_got;
 			hc->length_expected = hc->length_got;
 		}
-		hc->data_length_got += len;
 	}
+	hc->data_length_got += len;
+
+	if (len == 0)
+		return TRUE;
+
+	if (hc->request->response_writer != NULL) {
+		gboolean succ;
+		succ = hc->request->response_writer(hc, hc->response, buf,
+			current_offset, len, hc->request->response_writer_data);
+		if (!succ) {
+			purple_debug_error("http",
+				"Cannot write using callback\n");
+			_purple_http_error(hc,
+				_("Error handling retrieved data"));
+			return FALSE;
+		}
+	} else {
+		if (hc->response->contents == NULL)
+			hc->response->contents = g_string_new("");
+		g_string_append_len(hc->response->contents, buf, len);
+	}
 
 	purple_http_conn_notify_progress_watcher(hc);
-
-	if (len == 0)
-		return;
-
-	g_string_append_len(hc->response->contents, buf, len);
+	return TRUE;
 }
 
 static gboolean _purple_http_recv_body_chunked(PurpleHttpConnection *hc,
@@ -695,8 +715,9 @@ static gboolean _purple_http_recv_body_c
 				got_now = hc->chunk_length - hc->chunk_got;
 			hc->chunk_got += got_now;
 			
-			_purple_http_recv_body_data(hc,
-				hc->response_buffer->str, got_now);
+			if (!_purple_http_recv_body_data(hc,
+				hc->response_buffer->str, got_now))
+				return FALSE;
 
 			g_string_erase(hc->response_buffer, 0, got_now);
 			hc->in_chunk = (hc->chunk_got < hc->chunk_length);
@@ -759,9 +780,6 @@ static gboolean _purple_http_recv_body_c
 static gboolean _purple_http_recv_body(PurpleHttpConnection *hc,
 	const gchar *buf, int len)
 {
-	if (hc->response->contents == NULL)
-		hc->response->contents = g_string_new("");
-
 	if (hc->is_chunked)
 	{
 		hc->length_got += len;
@@ -773,9 +791,7 @@ static gboolean _purple_http_recv_body(P
 		len = hc->length_expected - hc->length_got;
 	hc->length_got += len;
 
-	_purple_http_recv_body_data(hc, buf, len);
-
-	return TRUE;
+	return _purple_http_recv_body_data(hc, buf, len);
 }
 
 static void _purple_http_recv(gpointer _hc, gint fd, PurpleInputCondition cond)
@@ -1771,6 +1787,17 @@ void purple_http_request_set_contents_re
 	request->contents_reader_data = user_data;
 }
 
+void purple_http_request_set_response_writer(PurpleHttpRequest *request,
+	PurpleHttpContentWriter writer, gpointer user_data)
+{
+	g_return_if_fail(request != NULL);
+
+	if (writer == NULL)
+		user_data = NULL;
+	request->response_writer = writer;
+	request->response_writer_data = user_data;
+}
+
 void purple_http_request_set_timeout(PurpleHttpRequest *request, int timeout)
 {
 	g_return_if_fail(request != NULL);
diff --git a/libpurple/http.h b/libpurple/http.h
--- a/libpurple/http.h
+++ b/libpurple/http.h
@@ -90,8 +90,9 @@ typedef void (*PurpleHttpContentReader)(
  *                  previous call), can be safely ignored.
  * @param length    Length of data read.
  * @param user_data The user data passed with callback function.
+ * @return          TRUE, if succeeded, FALSE otherwise.
  */
-typedef void (*PurpleHttpContentWriter)(PurpleHttpConnection *http_conn,
+typedef gboolean (*PurpleHttpContentWriter)(PurpleHttpConnection *http_conn,
 	PurpleHttpResponse *response, const gchar *buffer, size_t offset,
 	size_t length, gpointer user_data);
 
@@ -364,10 +365,9 @@ void purple_http_request_set_contents_re
  * Set contents writer for HTTP response.
  *
  * @param request   The request.
- * @param reader    The writer callback.
+ * @param reader    The writer callback, or NULL to remove existing.
  * @param user_data The user data to pass to the callback function.
  */
-/* TODO */
 void purple_http_request_set_response_writer(PurpleHttpRequest *request,
 	PurpleHttpContentWriter writer, gpointer user_data);
 



More information about the Commits mailing list