File indexing completed on 2024-04-28 15:15:44

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