From a6b3d0b9cada67d3315c5320d426141310ac5f0a Mon Sep 17 00:00:00 2001
From: Lawrence Rust <lvr@softsystem.co.uk>
Date: Wed, 27 Jul 2011 15:34:53 +0200
Subject: [PATCH] DownloadManager: Fix SEGV after timeout
1. Fix a SEGV that can occur if a download times out. If a caller makes
a synchronous call then downloadNow will timeout after 10 seconds but
downloadFinished, which is a slot, can be called after control has returned
to the caller and the QByteArray data buffer has been deallocated.
2. Allow the caller to set their own User-Agent header.
3. Provide better error reporting.
Signed-off-by: Lawrence Rust <lvr@softsystem.co.uk>
---
mythtv/libs/libmythbase/mythdownloadmanager.cpp | 20 ++++++++++++--------
1 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/mythtv/libs/libmythbase/mythdownloadmanager.cpp b/mythtv/libs/libmythbase/mythdownloadmanager.cpp
index 2d3d645..2e24806 100644
a
|
b
|
void MythDownloadManager::downloadQNetworkRequest(MythDownloadInfo *dlInfo) |
608 | 608 | request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, |
609 | 609 | QNetworkRequest::PreferCache); |
610 | 610 | |
611 | | request.setRawHeader("User-Agent", |
612 | | "MythDownloadManager v" MYTH_BINARY_VERSION); |
| 611 | if (!request.hasRawHeader("User-Agent")) |
| 612 | request.setRawHeader("User-Agent", |
| 613 | "MythDownloadManager v" MYTH_BINARY_VERSION); |
613 | 614 | |
614 | 615 | if (dlInfo->m_post) |
615 | 616 | dlInfo->m_reply = m_manager->post(request, *dlInfo->m_data); |
… |
… |
bool MythDownloadManager::downloadNow(MythDownloadInfo *dlInfo, bool deleteInfo) |
666 | 667 | if (!dlInfo->m_done) |
667 | 668 | { |
668 | 669 | dlInfo->m_syncMode = false; // Let downloadFinished() cleanup for us |
| 670 | dlInfo->m_data = 0; // !! Otherwise downloadFinished will write to this |
669 | 671 | if ((dlInfo->m_reply) && |
670 | 672 | (dlInfo->m_errorCode == QNetworkReply::NoError)) |
671 | 673 | dlInfo->m_reply->abort(); |
… |
… |
void MythDownloadManager::downloadError(QNetworkReply::NetworkError errorCode) |
713 | 715 | { |
714 | 716 | QNetworkReply *reply = (QNetworkReply*)sender(); |
715 | 717 | |
716 | | LOG(VB_FILE, LOG_DEBUG, LOC + QString("downloadError(%1) (for reply %2)") |
717 | | .arg(errorCode).arg((long long)reply)); |
| 718 | // NB The errorString includes the URL |
| 719 | LOG(VB_FILE, LOG_DEBUG, LOC + QString("downloadError %1 ") |
| 720 | .arg(errorCode) + reply->errorString() ); |
718 | 721 | |
719 | 722 | QMutexLocker locker(m_infoLock); |
720 | 723 | if (!m_downloadReplies.contains(reply)) |
… |
… |
void MythDownloadManager::downloadFinished(MythDownloadInfo *dlInfo) |
803 | 806 | if (dlInfo->m_preferCache) |
804 | 807 | request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, |
805 | 808 | QNetworkRequest::PreferCache); |
806 | | request.setRawHeader("User-Agent", |
807 | | "MythDownloadManager v" MYTH_BINARY_VERSION); |
| 809 | if (!request.hasRawHeader("User-Agent")) |
| 810 | request.setRawHeader("User-Agent", |
| 811 | "MythDownloadManager v" MYTH_BINARY_VERSION); |
808 | 812 | |
809 | 813 | if (dlInfo->m_post) |
810 | 814 | dlInfo->m_reply = m_manager->post(request, *dlInfo->m_data); |
… |
… |
void MythDownloadManager::downloadFinished(MythDownloadInfo *dlInfo) |
891 | 895 | args << dlInfo->m_url; |
892 | 896 | args << dlInfo->m_outFile; |
893 | 897 | args << QString::number(dlInfo->m_bytesTotal); |
894 | | args << QString(); // placeholder for error string |
895 | | args << QString::number((int)dlInfo->m_errorCode); |
| 898 | args << (reply ? reply->errorString() : QString()); // placeholder for error string |
| 899 | args << QString::number((int)(reply ? reply->error() : dlInfo->m_errorCode)); |
896 | 900 | |
897 | 901 | QCoreApplication::postEvent(dlInfo->m_caller, |
898 | 902 | new MythEvent("DOWNLOAD_FILE FINISHED", args)); |