/*! @file @id $Id$ */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 #include #include #include #include #include #ifndef LOG #define LOG qDebug()<<__PRETTY_FUNCTION__ #endif class DownloadManager: public QObject { Q_OBJECT; public: DownloadManager& operator+=(QNetworkReply* reply) { LOG; add(reply); return *this; } static QString networkError(QNetworkReply::NetworkError err) { LOG<Unknown network error (code: %1).") .arg(err); } } Q_SIGNALS: void progress(qint64 done, qint64 total); void started(); void finished(); void error(QString); void metaDataChanged(QNetworkReply*); public Q_SLOTS: void add(QNetworkReply* reply) { LOG<<_downloads.size()<url().toString(); LOG<&)), SLOT(sslErrors(const QList&)))); assert(connect(reply, SIGNAL(uploadProgress(qint64, qint64)), SLOT(uploadProgress(qint64, qint64)))); if (_downloads.size()==1) started(); } void abort() { while (_downloads.size()) _downloads.begin()->first->abort(); } private: void calcProgress() { //LOG; qint64 done(0); qint64 total(0); for (Downloads::iterator it(_downloads.begin()); it!=_downloads.end(); ++it) { done += it->second.progress.first; total += it->second.progress.second; } progress(done, total); } private Q_SLOTS: void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) { //LOG<(sender())].progress.first = bytesReceived; _downloads[qobject_cast(sender())].progress.second = bytesTotal; calcProgress(); } void error(QNetworkReply::NetworkError code) { LOG<<"Status:"<(sender())); _downloads[reply].error += tr("

Network Error

" "
URL:
%1
" "
Error Code:
%3
" "
Error Details:
%2
") .arg(reply->url().toString()) .arg(networkError(code)) .arg(code); } void slotDestroyed(QObject* obj) { LOG<<_downloads.size(); _downloads.erase((QNetworkReply*)obj); } void slotFinished() { LOG<<_downloads.size(); QNetworkReply* reply(qobject_cast(sender())); if (_downloads[reply].error.size()) error(_downloads[reply].error); _downloads.erase(reply); if (_downloads.size()==0) finished(); } void slotMetaDataChanged() { LOG; QNetworkReply* reply(qobject_cast(sender())); if (!reply) return; LOG<<"Location:"<header(QNetworkRequest::LocationHeader) .toString(); LOG<<"Content-Type:"<header(QNetworkRequest::ContentTypeHeader) .toString(); LOG<<"Content-Disposition:"<rawHeader("Content-Disposition"); LOG<<"Status:"<error()); LOG<<"URL:"<url().toString(); LOG<<"File:"<url().toLocalFile(); LOG<<"Path:"<url().path(); metaDataChanged(reply); } void sslErrors(const QList & errors) { LOG; QNetworkReply* reply(qobject_cast(sender())); for (QList::const_iterator err(errors.begin()); err!=errors.end(); ++err) { LOG<<"SSL-Error: "<<(int)err->error()<<": "<errorString(); LOG<<"Certificate Issuer: " <<"O="<certificate().issuerInfo(QSslCertificate::Organization) <<"CN="<certificate().issuerInfo(QSslCertificate::CommonName) <<"L="<certificate().issuerInfo(QSslCertificate::LocalityName) <<"OU="<certificate().issuerInfo(QSslCertificate::OrganizationalUnitName) <<"C="<certificate().issuerInfo(QSslCertificate::CountryName) <<"ST="<certificate().issuerInfo(QSslCertificate::StateOrProvinceName); LOG<<"Certificate Subject: " <<"O="<certificate().subjectInfo(QSslCertificate::Organization) <<"CN="<certificate().subjectInfo(QSslCertificate::CommonName) <<"L="<certificate().subjectInfo(QSslCertificate::LocalityName) <<"OU="<certificate().subjectInfo(QSslCertificate::OrganizationalUnitName) <<"C="<certificate().subjectInfo(QSslCertificate::CountryName) <<"ST="<certificate().subjectInfo(QSslCertificate::StateOrProvinceName); LOG<<"Certificate:\n"<certificate().toPem(); _downloads[reply].error += tr("

SSL Error

" "
URL:
%1
" "
Error Code:
%3
" "
Error Details:
%2
" "" "" "" "" "" "" "" "" "
Certificate Issuer
Organization:%4
Common Name:%5
Location:%6
Organizational Unit:%7
Country:%8
State or Provive:%9
" "" "" "" "" "" "" "" "" "
Certificate Subject
Organization:%10
Common Name:%11
Location:%12
Organizational Unit:%13
Country:%14
State or Provive:%15
") .arg(reply->url().toString()) .arg(err->errorString()) .arg(err->error()) .arg(err->certificate().issuerInfo(QSslCertificate::Organization)) .arg(err->certificate().issuerInfo(QSslCertificate::CommonName)) .arg(err->certificate().issuerInfo(QSslCertificate::LocalityName)) .arg(err->certificate().issuerInfo(QSslCertificate::OrganizationalUnitName)) .arg(err->certificate().issuerInfo(QSslCertificate::CountryName)) .arg(err->certificate().issuerInfo(QSslCertificate::StateOrProvinceName)) .arg(err->certificate().subjectInfo(QSslCertificate::Organization)) .arg(err->certificate().subjectInfo(QSslCertificate::CommonName)) .arg(err->certificate().subjectInfo(QSslCertificate::LocalityName)) .arg(err->certificate().subjectInfo(QSslCertificate::OrganizationalUnitName)) .arg(err->certificate().subjectInfo(QSslCertificate::CountryName)) .arg(err->certificate().subjectInfo(QSslCertificate::StateOrProvinceName)); } } void uploadProgress(qint64 bytesSent, qint64 bytesTotal) { //LOG<(sender())].progress.first = bytesSent; _downloads[qobject_cast(sender())].progress.second = bytesTotal; calcProgress(); } private: typedef std::pair Progress; struct Download { Progress progress; QString error; }; typedef std::map Downloads; Downloads _downloads; };