diff --git a/src/libcalamares/network/Manager.cpp b/src/libcalamares/network/Manager.cpp index 66721c812..857a93b69 100644 --- a/src/libcalamares/network/Manager.cpp +++ b/src/libcalamares/network/Manager.cpp @@ -27,6 +27,23 @@ namespace CalamaresUtils { namespace Network { +void +RequestOptions::applyToRequest( QNetworkRequest* request ) const +{ + if ( m_flags & Flag::FollowRedirect ) + { + // Follows all redirects except unsafe ones (https to http). + request->setAttribute( QNetworkRequest::FollowRedirectsAttribute, true ); + } + + if ( m_flags & Flag::FakeUserAgent ) + { + // 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)" ); + } +} + struct Manager::Private { std::unique_ptr< QNetworkAccessManager > m_nam; @@ -82,16 +99,17 @@ Manager::setCheckHasInternetUrl( const QUrl& url ) } bool -Manager::synchronousPing( const QUrl& url ) +Manager::synchronousPing( const QUrl& url, const RequestOptions& options ) { if ( !url.isValid() ) { return false; } - QNetworkRequest req = QNetworkRequest( url ); - QNetworkReply* reply = d->m_nam->get( req ); + QNetworkRequest request = QNetworkRequest( url ); + QNetworkReply* reply = d->m_nam->get( request ); QEventLoop loop; + options.applyToRequest( &request ); connect( reply, &QNetworkReply::finished, &loop, &QEventLoop::quit ); loop.exec(); reply->deleteLater(); @@ -99,7 +117,7 @@ Manager::synchronousPing( const QUrl& url ) } QByteArray -Manager::synchronousGet( const QUrl& url ) +Manager::synchronousGet( const QUrl& url, const RequestOptions& options ) { if ( !url.isValid() ) { @@ -109,6 +127,7 @@ Manager::synchronousGet( const QUrl& url ) QNetworkRequest request( url ); QNetworkReply* reply = d->m_nam->get( request ); QEventLoop loop; + options.applyToRequest( &request ); connect( reply, &QNetworkReply::finished, &loop, &QEventLoop::quit ); loop.exec(); reply->deleteLater(); diff --git a/src/libcalamares/network/Manager.h b/src/libcalamares/network/Manager.h index 1c965d27e..7f12925ef 100644 --- a/src/libcalamares/network/Manager.h +++ b/src/libcalamares/network/Manager.h @@ -25,12 +25,46 @@ #include #include +#include #include +class QNetworkRequest; + namespace CalamaresUtils { namespace Network { +class DLLEXPORT RequestOptions +{ +public: + enum Flag + { + FollowRedirect = 0x1, + FakeUserAgent = 0x100 + }; + Q_DECLARE_FLAGS( Flags, Flag ) + + RequestOptions() + : m_flags( 0 ) + , m_timeout( -1 ) + { + } + + RequestOptions( Flags f, std::chrono::milliseconds timeout = std::chrono::milliseconds( -1 ) ) + : m_flags( f ) + , m_timeout( timeout ) + { + } + + void applyToRequest( QNetworkRequest* ) const; + +private: + Flags m_flags; + std::chrono::milliseconds m_timeout; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS( RequestOptions::Flags ); + class DLLEXPORT Manager : QObject { Q_OBJECT @@ -51,14 +85,14 @@ public: * Returns @c true if it does; @c false means no data, typically * because of an error or no network access. */ - bool synchronousPing( const QUrl& url ); + bool synchronousPing( const QUrl& url, const RequestOptions& options = RequestOptions() ); /** @brief Downloads the data from a given @p url * * Returns the data as a QByteArray, or an empty * array if any error occurred. */ - QByteArray synchronousGet( const QUrl& url ); + QByteArray synchronousGet( const QUrl& url, const RequestOptions& options = RequestOptions() ); /// @brief Set the URL which is used for the general "is there internet" check. void setCheckHasInternetUrl( const QUrl& url );