diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index a4f52d5b7..c3754e1c2 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -22,26 +22,24 @@ #include "NetInstallPage.h" #include "PackageModel.h" - #include "ui_page_netinst.h" + #include "JobQueue.h" +#include "network/Manager.h" #include "utils/Logger.h" #include "utils/Retranslator.h" #include "utils/Yaml.h" -#include -#include -#include - #include +#include using CalamaresUtils::yamlToVariant; NetInstallPage::NetInstallPage( QWidget* parent ) : QWidget( parent ) , ui( new Ui::Page_NetInst ) - , m_networkManager( this ) + , m_reply( nullptr ) , m_groups( nullptr ) { ui->setupUi( this ); @@ -55,14 +53,14 @@ NetInstallPage::readGroups( const QByteArray& yamlData ) YAML::Node groups = YAML::Load( yamlData.constData() ); if ( !groups.IsSequence() ) + { cWarning() << "netinstall groups data does not form a sequence."; + } Q_ASSERT( groups.IsSequence() ); m_groups = new PackageModel( groups ); - CALAMARES_RETRANSLATE( - m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Name" ) ); - m_groups->setHeaderData( 1, Qt::Horizontal, tr( "Description" ) ); ) + CALAMARES_RETRANSLATE( m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Name" ) ); + m_groups->setHeaderData( 1, Qt::Horizontal, tr( "Description" ) ); ) return true; - } catch ( YAML::Exception& e ) { @@ -71,29 +69,53 @@ NetInstallPage::readGroups( const QByteArray& yamlData ) } } +/// @brief Convenience to zero out and deleteLater on the reply, used in dataIsHere +struct ReplyDeleter +{ + QNetworkReply*& p; + + ~ReplyDeleter() + { + if ( p ) + { + p->deleteLater(); + } + p = nullptr; + } +}; + void -NetInstallPage::dataIsHere( QNetworkReply* reply ) +NetInstallPage::dataIsHere() { - cDebug() << "NetInstall group data received" << reply->url(); - reply->deleteLater(); + if ( !m_reply || !m_reply->isFinished() ) + { + cWarning() << "NetInstall data called too early."; + return; + } + + cDebug() << "NetInstall group data received" << m_reply->url(); + + ReplyDeleter d { m_reply }; // If m_required is *false* then we still say we're ready // even if the reply is corrupt or missing. - if ( reply->error() != QNetworkReply::NoError ) + if ( m_reply->error() != QNetworkReply::NoError ) { cWarning() << "unable to fetch netinstall package lists."; - cDebug() << Logger::SubEntry << "Netinstall reply error: " << reply->error(); - cDebug() << Logger::SubEntry << "Request for url: " << reply->url().toString() << " failed with: " << reply->errorString(); - ui->netinst_status->setText( tr( "Network Installation. (Disabled: Unable to fetch package lists, check your network connection)" ) ); + cDebug() << Logger::SubEntry << "Netinstall reply error: " << m_reply->error(); + cDebug() << Logger::SubEntry << "Request for url: " << m_reply->url().toString() + << " failed with: " << m_reply->errorString(); + ui->netinst_status->setText( + tr( "Network Installation. (Disabled: Unable to fetch package lists, check your network connection)" ) ); emit checkReady( !m_required ); return; } - if ( !readGroups( reply->readAll() ) ) + if ( !readGroups( m_reply->readAll() ) ) { cWarning() << "netinstall groups data was received, but invalid."; - cDebug() << Logger::SubEntry << "Url: " << reply->url().toString(); - cDebug() << Logger::SubEntry << "Headers: " << reply->rawHeaderList(); + cDebug() << Logger::SubEntry << "Url: " << m_reply->url().toString(); + cDebug() << Logger::SubEntry << "Headers: " << m_reply->rawHeaderList(); ui->netinst_status->setText( tr( "Network Installation. (Disabled: Received invalid groups data)" ) ); emit checkReady( !m_required ); return; @@ -110,7 +132,9 @@ PackageModel::PackageItemDataList NetInstallPage::selectedPackages() const { if ( m_groups ) + { return m_groups->getPackages(); + } else { cWarning() << "no netinstall groups are available."; @@ -121,24 +145,23 @@ NetInstallPage::selectedPackages() const void NetInstallPage::loadGroupList( const QString& confUrl ) { + using namespace CalamaresUtils::Network; + cDebug() << "NetInstall loading groups from" << confUrl; - QNetworkRequest request; - request.setUrl( QUrl( confUrl ) ); - // Follows all redirects except unsafe ones (https to http). - request.setAttribute( QNetworkRequest::FollowRedirectsAttribute, true ); - // Not everybody likes the default User Agent used by this class (looking at you, - // sourceforge.net), so let's set a more descriptive one. - request.setRawHeader( "User-Agent", "Mozilla/5.0 (compatible; Calamares)" ); - - connect( &m_networkManager, &QNetworkAccessManager::finished, - this, &NetInstallPage::dataIsHere ); - auto* rq = m_networkManager.get( request ); - if ( rq->error() ) + QNetworkReply* reply = Manager::instance().asynchronouseGet( + QUrl( confUrl ), + RequestOptions( RequestOptions::FakeUserAgent | RequestOptions::FollowRedirect, std::chrono::seconds( 30 ) ) ); + + if ( !reply ) { - cDebug() << Logger::Continuation << "request failed immediately," << rq->errorString(); - rq->deleteLater(); + cDebug() << Logger::Continuation << "request failed immediately."; ui->netinst_status->setText( tr( "Network Installation. (Disabled: Incorrect configuration)" ) ); } + else + { + m_reply = reply; + connect( reply, &QNetworkReply::finished, this, &NetInstallPage::dataIsHere ); + } } void diff --git a/src/modules/netinstall/NetInstallPage.h b/src/modules/netinstall/NetInstallPage.h index b2887304b..fbd60a8fd 100644 --- a/src/modules/netinstall/NetInstallPage.h +++ b/src/modules/netinstall/NetInstallPage.h @@ -24,14 +24,10 @@ #include "PackageModel.h" #include "PackageTreeItem.h" -#include -#include +#include #include -// required forward declarations -class QByteArray; class QNetworkReply; -class QString; namespace Ui { @@ -57,10 +53,7 @@ public: // corrupt or unavailable data causes checkReady() to be emitted // true (not-required) or false. void setRequired( bool ); - bool getRequired() const - { - return m_required; - } + bool getRequired() const { return m_required; } // Returns the list of packages belonging to groups that are // selected in the view in this given moment. No data is cached here, so @@ -68,7 +61,7 @@ public: PackageModel::PackageItemDataList selectedPackages() const; public slots: - void dataIsHere( QNetworkReply* ); + void dataIsHere(); signals: void checkReady( bool ); @@ -81,11 +74,9 @@ private: Ui::Page_NetInst* ui; - // Handles connection with the remote URL storing the configuration. - QNetworkAccessManager m_networkManager; - + QNetworkReply* m_reply; PackageModel* m_groups; bool m_required; }; -#endif // NETINSTALLPAGE_H +#endif // NETINSTALLPAGE_H