Tue, 06 Nov 2012 01:10:40 +0100
HTTP: PurpleHttpContentWriter support
| libpurple/http.c | file | annotate | diff | comparison | revisions | |
| libpurple/http.h | file | annotate | diff | comparison | revisions |
--- a/libpurple/http.c Mon Nov 05 18:15:24 2012 -0500 +++ b/libpurple/http.c Tue Nov 06 01:10:40 2012 +0100 @@ -66,6 +66,8 @@ 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 @@ 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 @@ 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(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 @@ 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 @@ 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);
--- a/libpurple/http.h Mon Nov 05 18:15:24 2012 -0500 +++ b/libpurple/http.h Tue Nov 06 01:10:40 2012 +0100 @@ -90,8 +90,9 @@ * 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 @@ * 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);