diff --git a/mythtv/libs/libmythbase/mythsingledownload.cpp b/mythtv/libs/libmythbase/mythsingledownload.cpp
index 95db42d..0ade2f3 100644
--- a/mythtv/libs/libmythbase/mythsingledownload.cpp
+++ b/mythtv/libs/libmythbase/mythsingledownload.cpp
@@ -9,9 +9,9 @@
  */
 
 bool MythSingleDownload::DownloadURL(const QString &url, QByteArray *buffer,
-                                     uint timeout)
+                                     uint timeout, uint redirs)
 {
-    QMutexLocker  lock(&m_lock);
+    m_lock.lock();
 
     // create custom temporary event loop on stack
     QEventLoop   event_loop;
@@ -43,25 +43,45 @@ bool MythSingleDownload::DownloadURL(const QString &url, QByteArray *buffer,
         LOG(VB_GENERAL, LOG_ERR, QString("MythSingleDownload evenloop failed"));
     }
 
-    QMutexLocker  replylock(&m_replylock);
+    m_replylock.lock();
     if (m_timer.isActive())
     {
         m_timer.stop();
         m_errorcode = m_reply->error();
+
+        QString redir = m_reply->attribute(
+            QNetworkRequest::RedirectionTargetAttribute).toUrl().toString();
+
+        if (redir.length())
+        {
+            if (redirs > 3)
+            {
+                LOG(VB_GENERAL, LOG_ERR, QString("%1: too many redirects").arg(url));
+                ret = false;
+            }
+            else
+            {
+                LOG(VB_GENERAL, LOG_INFO, QString("%1 -> %2").arg(url).arg(redir));
+                m_replylock.unlock();
+                m_lock.unlock();
+                return DownloadURL(redir, buffer, timeout, redirs + 1);
+            }
+        }
+
         if (m_errorcode == QNetworkReply::NoError)
         {
             *buffer += m_reply->readAll();
             delete m_reply;
             m_reply = NULL;
             m_errorstring.clear();
-            return true;
+            ret = true;
         }
         else
         {
             m_errorstring = m_reply->errorString();
             delete m_reply;
             m_reply = NULL;
-            return false;
+            ret = false;
         }
     }
     else
@@ -71,8 +91,11 @@ bool MythSingleDownload::DownloadURL(const QString &url, QByteArray *buffer,
         m_reply->abort();
         delete m_reply;
         m_reply = NULL;
-        return false;
+        ret = false;
     }
+    m_replylock.unlock();
+    m_lock.unlock();
+    return ret;
 }
 
 void MythSingleDownload::Cancel(void)
diff --git a/mythtv/libs/libmythbase/mythsingledownload.h b/mythtv/libs/libmythbase/mythsingledownload.h
index af7144d..7c4e38d 100644
--- a/mythtv/libs/libmythbase/mythsingledownload.h
+++ b/mythtv/libs/libmythbase/mythsingledownload.h
@@ -28,7 +28,8 @@ class MBASE_PUBLIC MythSingleDownload : public QObject
    MythSingleDownload(void) : m_reply(NULL), m_errorcode(QNetworkReply::NoError) { ; }
    ~MythSingleDownload(void) { ; }
 
-   bool DownloadURL(const QString &url, QByteArray *buffer, uint timeout = 30000);
+   bool DownloadURL(const QString &url, QByteArray *buffer, uint timeout = 30000,
+                    uint redirs = 0);
    void Cancel(void);
    QString ErrorString(void) const { return m_errorstring; }
    QNetworkReply::NetworkError ErrorCode(void) const { return m_errorcode; }
