kodi: add PR6408

Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
Stephan Raue 2015-02-15 20:36:22 +01:00
parent c0662f2e80
commit d3b8a3ace1

View File

@ -0,0 +1,73 @@
From d8fff72de0159160fb4ca1c249c8365e9e1b6785 Mon Sep 17 00:00:00 2001
From: wsnipex <wsnipex@a1.net>
Date: Wed, 11 Feb 2015 16:58:25 +0100
Subject: [PATCH] [curl] use better method to stat shoutcast and friends
---
xbmc/filesystem/CurlFile.cpp | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/xbmc/filesystem/CurlFile.cpp b/xbmc/filesystem/CurlFile.cpp
index 7d68dab..ee63ff5 100644
--- a/xbmc/filesystem/CurlFile.cpp
+++ b/xbmc/filesystem/CurlFile.cpp
@@ -123,6 +123,19 @@ extern "C" size_t header_callback(void *ptr, size_t size, size_t nmemb, void *st
return state->HeaderCallback(ptr, size, nmemb);
}
+/* used only by CCurlFile::Stat to bail out of unwanted transfers */
+extern "C" int transfer_abort_callback(void *clientp,
+ curl_off_t dltotal,
+ curl_off_t dlnow,
+ curl_off_t ultotal,
+ curl_off_t ulnow)
+{
+ if(dlnow > 0)
+ return 1;
+ else
+ return 0;
+}
+
/* fix for silly behavior of realloc */
static inline void* realloc_simple(void *ptr, size_t size)
{
@@ -1285,7 +1298,6 @@ int CCurlFile::Stat(const CURL& url, struct __stat64* buffer)
SetRequestHeaders(m_state);
g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, g_advancedSettings.m_curlconnecttimeout);
g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_NOBODY, 1);
- g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/
g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME , 1);
if(url2.IsProtocol("ftp"))
@@ -1311,25 +1323,20 @@ int CCurlFile::Stat(const CURL& url, struct __stat64* buffer)
|| result == CURLE_RECV_ERROR /* some silly shoutcast servers */ )
{
/* some http servers and shoutcast servers don't give us any data on a head request */
- /* request normal and just fail out, it's their loss */
+ /* request normal and just bail out via progress meter callback after we received data */
/* somehow curl doesn't reset CURLOPT_NOBODY properly so reset everything */
SetCommonOptions(m_state);
SetRequestHeaders(m_state);
g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_TIMEOUT, g_advancedSettings.m_curlconnecttimeout);
- g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_RANGE, "0-0");
- g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_WRITEDATA, NULL); /* will cause write failure*/
- g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME, 1);
- result = g_curlInterface.easy_perform(m_state->m_easyHandle);
- }
+ g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_FILETIME, 1);
+ g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_XFERINFOFUNCTION, transfer_abort_callback);
+ g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_NOPROGRESS, 0);
- if( result == CURLE_HTTP_RANGE_ERROR )
- {
- /* crap can't use the range option, disable it and try again */
- g_curlInterface.easy_setopt(m_state->m_easyHandle, CURLOPT_RANGE, NULL);
result = g_curlInterface.easy_perform(m_state->m_easyHandle);
+
}
- if( result != CURLE_WRITE_ERROR && result != CURLE_OK )
+ if( result != CURLE_ABORTED_BY_CALLBACK && result != CURLE_OK )
{
g_curlInterface.easy_release(&m_state->m_easyHandle, NULL);
errno = ENOENT;