/pidgin/main: 918507303f45: HTTP API: PurpleHttpContentReader su...
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Mon Oct 22 19:13:13 EDT 2012
Changeset: 918507303f45a62c581916cbbd0b01ffc5e1b56a
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2012-10-23 01:13 +0200
Branch: default
URL: http://hg.pidgin.im/pidgin/main/rev/918507303f45
Description:
HTTP API: PurpleHttpContentReader support
diffstat:
libpurple/http.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
libpurple/http.h | 12 ++++----
2 files changed, 85 insertions(+), 7 deletions(-)
diffs (185 lines):
diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -33,6 +33,7 @@
#define PURPLE_HTTP_URL_CREDENTIALS_CHARS "a-z0-9.,~_/*!&%?=+\\^-"
#define PURPLE_HTTP_MAX_RECV_BUFFER_LEN 10240
+#define PURPLE_HTTP_MAX_READ_BUFFER_LEN 10240
#define PURPLE_HTTP_REQUEST_DEFAULT_MAX_REDIRECTS 20
#define PURPLE_HTTP_REQUEST_DEFAULT_TIMEOUT 30
@@ -63,6 +64,8 @@ struct _PurpleHttpRequest
gchar *contents;
int contents_length;
+ PurpleHttpContentReader contents_reader;
+ gpointer contents_reader_data;
int timeout;
int max_redirects;
@@ -86,6 +89,9 @@ struct _PurpleHttpConnection
gboolean main_header_got, headers_got;
GString *response_buffer;
+ GString *contents_reader_buffer;
+ gboolean contents_reader_requested;
+
int redirects_count;
int data_length_got;
@@ -916,6 +922,33 @@ static void _purple_http_recv_ssl(gpoint
_purple_http_recv(_hc, -1, cond);
}
+static void _purple_http_send_got_data(PurpleHttpConnection *hc,
+ gboolean success, gboolean eof, size_t stored)
+{
+ int estimated_length;
+
+ g_return_if_fail(hc != NULL);
+
+ if (!success) {
+ _purple_http_error(hc, _("Error requesting data to write"));
+ return;
+ }
+
+ hc->contents_reader_requested = FALSE;
+ g_string_set_size(hc->contents_reader_buffer, stored);
+ if (!eof)
+ return;
+
+ estimated_length = hc->request_contents_written + stored;
+
+ if (hc->request->contents_length != -1 &&
+ hc->request->contents_length != estimated_length) {
+ purple_debug_warning("http",
+ "Invalid amount of data has been written\n");
+ }
+ hc->request->contents_length = estimated_length;
+}
+
static void _purple_http_send(gpointer _hc, gint fd, PurpleInputCondition cond)
{
PurpleHttpConnection *hc = _hc;
@@ -924,6 +957,11 @@ static void _purple_http_send(gpointer _
const gchar *write_from;
gboolean writing_headers;
+ /* Waiting for data. This could be written more efficiently, by removing
+ * (and later, adding) hs->inpa. */
+ if (hc->contents_reader_requested)
+ return;
+
_purple_http_gen_headers(hc);
writing_headers =
@@ -933,8 +971,26 @@ static void _purple_http_send(gpointer _
hc->request_header_written;
write_len = hc->request_header->len -
hc->request_header_written;
+ } else if (hc->request->contents_reader) {
+ if (hc->contents_reader_requested)
+ return; /* waiting for data */
+ if (!hc->contents_reader_buffer)
+ hc->contents_reader_buffer = g_string_new("");
+ if (hc->contents_reader_buffer->len == 0) {
+ hc->contents_reader_requested = TRUE;
+ g_string_set_size(hc->contents_reader_buffer,
+ PURPLE_HTTP_MAX_READ_BUFFER_LEN);
+ hc->request->contents_reader(hc,
+ hc->contents_reader_buffer->str,
+ hc->request_contents_written,
+ PURPLE_HTTP_MAX_READ_BUFFER_LEN,
+ hc->request->contents_reader_data,
+ _purple_http_send_got_data);
+ return;
+ }
+ write_from = hc->contents_reader_buffer->str;
+ write_len = hc->contents_reader_buffer->len;
} else {
- /* TODO: write_from - other write methods */
write_from = hc->request->contents +
hc->request_contents_written;
write_len = hc->request->contents_length -
@@ -967,6 +1023,8 @@ static void _purple_http_send(gpointer _
return;
} else {
hc->request_contents_written += written;
+ if (hc->contents_reader_buffer)
+ g_string_erase(hc->contents_reader_buffer, 0, written);
if (hc->request_contents_written < hc->request->contents_length)
return;
}
@@ -1234,6 +1292,9 @@ static void purple_http_connection_free(
purple_http_request_unref(hc->request);
purple_http_response_free(hc->response);
+ if (hc->contents_reader_buffer)
+ g_string_free(hc->contents_reader_buffer, TRUE);
+
if (hc->request_header)
g_string_free(hc->request_header, TRUE);
@@ -1628,6 +1689,9 @@ void purple_http_request_set_contents(Pu
g_return_if_fail(request != NULL);
g_return_if_fail(length >= -1);
+ request->contents_reader = NULL;
+ request->contents_reader_data = NULL;
+
g_free(request->contents);
if (contents == NULL || length == 0) {
request->contents = NULL;
@@ -1641,6 +1705,20 @@ void purple_http_request_set_contents(Pu
request->contents_length = length;
}
+void purple_http_request_set_contents_reader(PurpleHttpRequest *request,
+ PurpleHttpContentReader reader, int contents_length, gpointer user_data)
+{
+ g_return_if_fail(request != NULL);
+ g_return_if_fail(reader != NULL);
+ g_return_if_fail(contents_length >= -1);
+
+ g_free(request->contents);
+ request->contents = NULL;
+ request->contents_length = contents_length;
+ request->contents_reader = reader;
+ request->contents_reader_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
@@ -63,7 +63,7 @@ typedef void (*PurpleHttpCallback)(Purpl
* An callback called after storing data requested by PurpleHttpContentReader.
*/
typedef void (*PurpleHttpContentReaderCb)(PurpleHttpConnection *http_conn,
- gboolean success, size_t stored);
+ gboolean success, gboolean eof, size_t stored);
/**
* An callback for getting large request contents (ie. from file stored on
@@ -325,13 +325,13 @@ void purple_http_request_set_contents(Pu
* Sets contents reader for HTTP request, used mainly for possible large
* uploads.
*
- * @param request The request.
- * @param reader The reader callback.
- * @param user_data The user data to pass to the callback function.
+ * @param request The request.
+ * @param reader The reader callback.
+ * @param contents_size The size of all contents.
+ * @param user_data The user data to pass to the callback function.
*/
-/* TODO */
void purple_http_request_set_contents_reader(PurpleHttpRequest *request,
- PurpleHttpContentReader reader, gpointer user_data);
+ PurpleHttpContentReader reader, int contents_length, gpointer user_data);
/**
* Set contents writer for HTTP response.
More information about the Commits
mailing list