File indexing completed on 2025-01-05 03:59:36
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2006-2007 Torsten Rahn <tackat@kde.org> 0004 // SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org> 0005 // SPDX-FileCopyrightText: 2008, 2009 Jens-Michael Hoffmann <jensmh@gmx.de> 0006 // SPDX-FileCopyrightText: 2008 Pino Toscano <pino@kde.org> 0007 // 0008 0009 #include "HttpJob.h" 0010 0011 #include <QNetworkAccessManager> 0012 0013 #include "HttpDownloadManager.h" 0014 0015 #include "digikam_debug.h" 0016 0017 using namespace Marble; 0018 0019 class Marble::HttpJobPrivate 0020 { 0021 public: 0022 HttpJobPrivate( const QUrl & sourceUrl, const QString & destFileName, 0023 const QString &id, QNetworkAccessManager *networkAccessManager ); 0024 0025 QUrl m_sourceUrl; 0026 QString m_destinationFileName; 0027 QString m_initiatorId; 0028 int m_trialsLeft; 0029 DownloadUsage m_downloadUsage; 0030 QString m_userAgent; 0031 QNetworkAccessManager *const m_networkAccessManager; 0032 QNetworkReply *m_networkReply; 0033 }; 0034 0035 HttpJobPrivate::HttpJobPrivate( const QUrl & sourceUrl, const QString & destFileName, 0036 const QString &id, QNetworkAccessManager *networkAccessManager ) 0037 : m_sourceUrl( sourceUrl ), 0038 m_destinationFileName( destFileName ), 0039 m_initiatorId( id ), 0040 m_trialsLeft( 3 ), 0041 m_downloadUsage( DownloadBrowse ), 0042 // FIXME: remove initialization depending on if empty pluginId 0043 // results in valid user agent string 0044 m_userAgent( QString::fromUtf8("unknown") ), 0045 m_networkAccessManager( networkAccessManager ), 0046 m_networkReply( nullptr ) 0047 { 0048 } 0049 0050 0051 HttpJob::HttpJob( const QUrl & sourceUrl, const QString & destFileName, const QString &id, QNetworkAccessManager *networkAccessManager ) 0052 : d( new HttpJobPrivate( sourceUrl, destFileName, id, networkAccessManager ) ) 0053 { 0054 } 0055 0056 HttpJob::~HttpJob() 0057 { 0058 delete d; 0059 } 0060 0061 QUrl HttpJob::sourceUrl() const 0062 { 0063 return d->m_sourceUrl; 0064 } 0065 0066 void HttpJob::setSourceUrl( const QUrl &url ) 0067 { 0068 d->m_sourceUrl = url; 0069 } 0070 0071 QString HttpJob::initiatorId() const 0072 { 0073 return d->m_initiatorId; 0074 } 0075 0076 void HttpJob::setInitiatorId( const QString &id ) 0077 { 0078 d->m_initiatorId = id; 0079 } 0080 0081 QString HttpJob::destinationFileName() const 0082 { 0083 return d->m_destinationFileName; 0084 } 0085 0086 void HttpJob::setDestinationFileName( const QString &fileName ) 0087 { 0088 d->m_destinationFileName = fileName; 0089 } 0090 0091 bool HttpJob::tryAgain() 0092 { 0093 if( d->m_trialsLeft > 0 ) { 0094 d->m_trialsLeft--; 0095 return true; 0096 } 0097 else { 0098 return false; 0099 } 0100 } 0101 0102 DownloadUsage HttpJob::downloadUsage() const 0103 { 0104 return d->m_downloadUsage; 0105 } 0106 0107 void HttpJob::setDownloadUsage( const DownloadUsage usage ) 0108 { 0109 d->m_downloadUsage = usage; 0110 } 0111 0112 void HttpJob::setUserAgentPluginId( const QString & pluginId ) const 0113 { 0114 d->m_userAgent = pluginId; 0115 } 0116 0117 QByteArray HttpJob::userAgent() const 0118 { 0119 switch ( d->m_downloadUsage ) { 0120 case DownloadBrowse: 0121 return HttpDownloadManager::userAgent(QString::fromUtf8("Browser"), d->m_userAgent); 0122 case DownloadBulk: 0123 return HttpDownloadManager::userAgent(QString::fromUtf8("BulkDownloader"), d->m_userAgent); 0124 default: 0125 qCCritical(DIGIKAM_MARBLE_LOG) << "Unknown download usage value:" << d->m_downloadUsage; 0126 return HttpDownloadManager::userAgent(QString::fromUtf8("unknown"), d->m_userAgent); 0127 } 0128 } 0129 0130 void HttpJob::execute() 0131 { 0132 QNetworkRequest request( d->m_sourceUrl ); 0133 request.setAttribute( QNetworkRequest::HttpPipeliningAllowedAttribute, true ); 0134 request.setRawHeader( QByteArray("User-Agent"), 0135 userAgent() ); 0136 d->m_networkReply = d->m_networkAccessManager->get( request ); 0137 0138 connect( d->m_networkReply, SIGNAL(downloadProgress(qint64,qint64)), 0139 SLOT(downloadProgress(qint64,qint64))); 0140 connect( d->m_networkReply, SIGNAL(errorOccurred(QNetworkReply::NetworkError)), 0141 SLOT(error(QNetworkReply::NetworkError))); 0142 connect( d->m_networkReply, SIGNAL(finished()), 0143 SLOT(finished())); 0144 } 0145 void HttpJob::downloadProgress( qint64 bytesReceived, qint64 bytesTotal ) 0146 { 0147 Q_UNUSED(bytesReceived); 0148 Q_UNUSED(bytesTotal); 0149 // qCDebug(DIGIKAM_MARBLE_LOG) << "downloadProgress" << destinationFileName() 0150 // << bytesReceived << '/' << bytesTotal; 0151 } 0152 0153 void HttpJob::error( QNetworkReply::NetworkError code ) 0154 { 0155 qCDebug(DIGIKAM_MARBLE_LOG) << "error" << destinationFileName() << code; 0156 } 0157 0158 void HttpJob::finished() 0159 { 0160 QNetworkReply::NetworkError const error = d->m_networkReply->error(); 0161 // qCDebug(DIGIKAM_MARBLE_LOG) << "finished" << destinationFileName() 0162 // << "error" << error; 0163 0164 const QVariant httpPipeliningWasUsed = 0165 d->m_networkReply->attribute( QNetworkRequest::HttpPipeliningWasUsedAttribute ); 0166 if ( !httpPipeliningWasUsed.isNull() ) 0167 qCDebug(DIGIKAM_MARBLE_LOG) << "http pipelining used:" << httpPipeliningWasUsed.toBool(); 0168 0169 switch ( error ) { 0170 case QNetworkReply::NoError: { 0171 // check if we are redirected 0172 const QVariant redirectionAttribute = 0173 d->m_networkReply->attribute( QNetworkRequest::RedirectionTargetAttribute ); 0174 if ( !redirectionAttribute.isNull() ) { 0175 Q_EMIT redirected( this, redirectionAttribute.toUrl() ); 0176 } 0177 else { 0178 // no redirection occurred 0179 const QByteArray data = d->m_networkReply->readAll(); 0180 Q_EMIT dataReceived( this, data ); 0181 } 0182 } 0183 break; 0184 0185 default: 0186 Q_EMIT jobDone( this, 1 ); 0187 } 0188 0189 d->m_networkReply->disconnect( this ); 0190 // No delete. This method is called by a signal QNetworkReply::finished. 0191 d->m_networkReply->deleteLater(); 0192 d->m_networkReply = nullptr; 0193 } 0194 0195 #include "moc_HttpJob.cpp"