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"