aboutsummaryrefslogtreecommitdiffstats
path: root/src/input
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2011-08-23 20:46:51 +0200
committerMax Kellermann <max@duempel.org>2011-08-23 20:46:51 +0200
commit8d70f808d981f34adef23d1e57b5b5fc9223c05b (patch)
treec8e513451898577174c213ba76bb3e56440c488c /src/input
parent7c887af1ea26cba22826475412a8ce437f87961f (diff)
downloadmpd-8d70f808d981f34adef23d1e57b5b5fc9223c05b.tar.gz
mpd-8d70f808d981f34adef23d1e57b5b5fc9223c05b.tar.xz
mpd-8d70f808d981f34adef23d1e57b5b5fc9223c05b.zip
input/curl: limit the receive buffer size
Diffstat (limited to '')
-rw-r--r--src/input/curl_input_plugin.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/input/curl_input_plugin.c b/src/input/curl_input_plugin.c
index ae645bddf..d6424c2c6 100644
--- a/src/input/curl_input_plugin.c
+++ b/src/input/curl_input_plugin.c
@@ -43,6 +43,13 @@
#define G_LOG_DOMAIN "input_curl"
/**
+ * Do not buffer more than this number of bytes. It should be a
+ * reasonable limit that doesn't make low-end machines suffer too
+ * much, but doesn't cause stuttering on high-latency lines.
+ */
+static const size_t CURL_MAX_BUFFERED = 512 * 1024;
+
+/**
* Buffers created by input_curl_writefunction().
*/
struct buffer {
@@ -144,6 +151,25 @@ input_curl_finish(void)
curl_global_cleanup();
}
+/**
+ * Determine the total sizes of all buffers, including portions that
+ * have already been consumed.
+ */
+G_GNUC_PURE
+static size_t
+curl_total_buffer_size(const struct input_curl *c)
+{
+ size_t total = 0;
+
+ for (GList *i = g_queue_peek_head_link(c->buffers);
+ i != NULL; i = g_list_next(i)) {
+ struct buffer *buffer = i->data;
+ total += buffer->size;
+ }
+
+ return total;
+}
+
static void
buffer_free_callback(gpointer data, G_GNUC_UNUSED gpointer user_data)
{
@@ -473,6 +499,10 @@ static int
input_curl_buffer(struct input_stream *is, GError **error_r)
{
struct input_curl *c = (struct input_curl *)is;
+
+ if (curl_total_buffer_size(c) >= CURL_MAX_BUFFERED)
+ return 0;
+
CURLMcode mcode;
int running_handles;
bool ret;