From 56f763a4a83f6410b1bd9e1f8b41240df535ebc9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 2 Nov 2014 12:59:45 +0100 Subject: [PATCH] input/curl: forget Content-Length (and more) after redirect Fixes playback of redirected streams. --- NEWS | 2 ++ src/input/plugins/CurlInputPlugin.cxx | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/NEWS b/NEWS index 2f04931e6..a9fabed98 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.19.2 (not yet released) +* input + - curl: fix redirected streams * playlist - don't allow empty playlist name - m3u: don't ignore unterminated last line diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx index 0028158a3..1e1a46108 100644 --- a/src/input/plugins/CurlInputPlugin.cxx +++ b/src/input/plugins/CurlInputPlugin.cxx @@ -109,6 +109,13 @@ struct CurlInputStream final : public AsyncInputStream { */ void FreeEasyIndirect(); + /** + * Called when a new response begins. This is used to discard + * headers from previous responses (for example authentication + * and redirects). + */ + void ResponseBoundary(); + void HeaderReceived(const char *name, std::string &&value); size_t DataReceived(const void *ptr, size_t size); @@ -597,6 +604,20 @@ CurlInputStream::~CurlInputStream() FreeEasyIndirect(); } +inline void +CurlInputStream::ResponseBoundary() +{ + /* undo all effects of HeaderReceived() because the previous + response was not applicable for this stream */ + + seekable = false; + size = UNKNOWN_SIZE; + ClearMimeType(); + ClearTag(); + + // TODO: reset the IcyInputStream? +} + inline void CurlInputStream::HeaderReceived(const char *name, std::string &&value) { @@ -645,6 +666,11 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream) size *= nmemb; const char *header = (const char *)ptr; + if (size > 5 && memcmp(header, "HTTP/", 5) == 0) { + c.ResponseBoundary(); + return size; + } + const char *end = header + size; char name[64];