Wed, 07 Nov 2012 01:34:56 +0100
HTTP: don't freeze download on files larger than buffer size
| libpurple/http.c | file | annotate | diff | comparison | revisions |
--- a/libpurple/http.c Tue Nov 06 19:55:35 2012 +0100 +++ b/libpurple/http.c Wed Nov 07 01:34:56 2012 +0100 @@ -431,7 +431,9 @@ static void _purple_http_disconnect(PurpleHttpConnection *hc); static void _purple_http_gen_headers(PurpleHttpConnection *hc); -static void _purple_http_recv(gpointer _hc, gint fd, PurpleInputCondition cond); +static gboolean _purple_http_recv_loopbody(PurpleHttpConnection *hc, gint fd); +static void _purple_http_recv(gpointer _hc, gint fd, + PurpleInputCondition cond); static void _purple_http_recv_ssl(gpointer _hc, PurpleSslConnection *ssl_connection, PurpleInputCondition cond); static void _purple_http_send(gpointer _hc, gint fd, PurpleInputCondition cond); @@ -795,25 +797,26 @@ return _purple_http_recv_body_data(hc, buf, len); } -static void _purple_http_recv(gpointer _hc, gint fd, PurpleInputCondition cond) +static gboolean _purple_http_recv_loopbody(PurpleHttpConnection *hc, gint fd) { - PurpleHttpConnection *hc = _hc; PurpleHttpSocket *hs = &hc->socket; int len; gchar buf[4096]; + gboolean got_anything; if (hs->is_ssl) len = purple_ssl_read(hs->ssl_connection, buf, sizeof(buf)); else len = read(fd, buf, sizeof(buf)); + got_anything = (len > 0); if (len < 0 && errno == EAGAIN) - return; + return FALSE; if (len < 0) { _purple_http_error(hc, _("Error reading from %s: %s"), hc->url->host, g_strerror(errno)); - return; + return FALSE; } /* EOF */ @@ -823,7 +826,7 @@ purple_debug_warning("http", "No more data while reading" " contents\n"); _purple_http_error(hc, _("Error parsing HTTP")); - return; + return FALSE; } if (hc->headers_got) hc->length_expected = hc->length_got; @@ -831,13 +834,13 @@ purple_debug_warning("http", "No more data while " "parsing headers\n"); _purple_http_error(hc, _("Error parsing HTTP")); - return; + return FALSE; } } if (!hc->headers_got && len > 0) { if (!_purple_http_recv_headers(hc, buf, len)) - return; + return FALSE; len = 0; if (hc->headers_got) { if (!purple_http_headers_get_int(hc->response->headers, @@ -855,12 +858,12 @@ _purple_http_recv_body(hc, buffer, buffer_len); } if (!hc->headers_got) - return; + return got_anything; } if (len > 0) { if (!_purple_http_recv_body(hc, buf, len)) - return; + return FALSE; } if (hc->is_chunked && hc->chunks_done) @@ -873,7 +876,7 @@ hc->response->code = 0; purple_debug_warning("http", "No headers got\n"); _purple_http_error(hc, _("Error parsing HTTP")); - return; + return FALSE; } if (purple_debug_is_unsafe() && purple_debug_is_verbose()) { @@ -899,7 +902,7 @@ if (hc->response->code == 407) { _purple_http_error(hc, _("Invalid proxy credentials")); - return; + return FALSE; } redirect = purple_http_headers_get(hc->response->headers, @@ -925,13 +928,22 @@ purple_http_url_free(url); _purple_http_reconnect(hc); - return; + return FALSE; } _purple_http_disconnect(hc); purple_http_connection_terminate(hc); - return; + return FALSE; } + + return got_anything; +} + +static void _purple_http_recv(gpointer _hc, gint fd, PurpleInputCondition cond) +{ + PurpleHttpConnection *hc = _hc; + + while (_purple_http_recv_loopbody(hc, fd)); } static void _purple_http_recv_ssl(gpointer _hc,