[libcalamares] Refactor request internals

- distinguish timeouts from other failures
 - git synchronousPing() a more detailed result, which is
   still bool-compatible.
This commit is contained in:
Adriaan de Groot 2019-08-26 15:24:58 +02:00
parent f0be7fd4aa
commit e2c6591a77
2 changed files with 41 additions and 14 deletions

View File

@ -107,7 +107,7 @@ Manager::setCheckHasInternetUrl( const QUrl& url )
* On failure, returns nullptr (e.g. bad URL, timeout). The request * On failure, returns nullptr (e.g. bad URL, timeout). The request
* is marked for later automatic deletion, so don't store the pointer. * is marked for later automatic deletion, so don't store the pointer.
*/ */
static QNetworkReply* static QPair< RequestStatus, QNetworkReply* >
synchronousRun( const std::unique_ptr< QNetworkAccessManager >& nam, const QUrl& url, const RequestOptions& options ) synchronousRun( const std::unique_ptr< QNetworkAccessManager >& nam, const QUrl& url, const RequestOptions& options )
{ {
QNetworkRequest request = QNetworkRequest( url ); QNetworkRequest request = QNetworkRequest( url );
@ -119,7 +119,7 @@ synchronousRun( const std::unique_ptr< QNetworkAccessManager >& nam, const QUrl&
if ( reply->error() ) if ( reply->error() )
{ {
reply->deleteLater(); reply->deleteLater();
return nullptr; return qMakePair( RequestStatus( RequestStatus::Failed ), nullptr );
} }
options.applyToRequest( &request ); options.applyToRequest( &request );
@ -135,23 +135,30 @@ synchronousRun( const std::unique_ptr< QNetworkAccessManager >& nam, const QUrl&
if ( options.hasTimeout() && !timer.isActive() ) if ( options.hasTimeout() && !timer.isActive() )
{ {
reply->deleteLater(); reply->deleteLater();
return nullptr; return qMakePair( RequestStatus( RequestStatus::Timeout ), nullptr );
} }
reply->deleteLater(); reply->deleteLater();
return reply; return qMakePair( RequestStatus( RequestStatus::Ok ), reply );
} }
bool RequestStatus
Manager::synchronousPing( const QUrl& url, const RequestOptions& options ) Manager::synchronousPing( const QUrl& url, const RequestOptions& options )
{ {
if ( !url.isValid() ) if ( !url.isValid() )
{ {
return false; return RequestStatus::Failed;
} }
auto* reply = synchronousRun( d->m_nam, url, options ); auto reply = synchronousRun( d->m_nam, url, options );
return reply && reply->bytesAvailable(); if ( reply.first )
{
return reply.second->bytesAvailable() ? RequestStatus::Ok : RequestStatus::Empty;
}
else
{
return reply.first;
}
} }
QByteArray QByteArray
@ -162,8 +169,8 @@ Manager::synchronousGet( const QUrl& url, const RequestOptions& options )
return QByteArray(); return QByteArray();
} }
auto* reply = synchronousRun( d->m_nam, url, options ); auto reply = synchronousRun( d->m_nam, url, options );
return reply ? reply->readAll() : QByteArray(); return reply.first ? reply.second->readAll() : QByteArray();
} }
} // namespace Network } // namespace Network

View File

@ -70,6 +70,22 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS( RequestOptions::Flags ); Q_DECLARE_OPERATORS_FOR_FLAGS( RequestOptions::Flags );
struct RequestStatus
{
enum State
{
Ok,
Timeout, // Timeout exceeded
Failed, // bad Url
Empty // for ping(), response is empty
};
RequestStatus( State s = Ok );
operator bool() const { return m_s == Ok; }
State m_s;
};
class DLLEXPORT Manager : QObject class DLLEXPORT Manager : QObject
{ {
Q_OBJECT Q_OBJECT
@ -87,15 +103,19 @@ public:
/** @brief Checks if the given @p url returns data. /** @brief Checks if the given @p url returns data.
* *
* Returns @c true if it does; @c false means no data, typically * Returns a RequestStatus, which converts to @c true if the ping
* because of an error or no network access. * was successful. Other status reasons convert to @c false,
* typically because of no data, a Url error or no network access.
*
* May return Empty if the request was successful but returned
* no data at all.
*/ */
bool synchronousPing( const QUrl& url, const RequestOptions& options = RequestOptions() ); RequestStatus synchronousPing( const QUrl& url, const RequestOptions& options = RequestOptions() );
/** @brief Downloads the data from a given @p url /** @brief Downloads the data from a given @p url
* *
* Returns the data as a QByteArray, or an empty * Returns the data as a QByteArray, or an empty
* array if any error occurred. * array if any error occurred (or no data was returned).
*/ */
QByteArray synchronousGet( const QUrl& url, const RequestOptions& options = RequestOptions() ); QByteArray synchronousGet( const QUrl& url, const RequestOptions& options = RequestOptions() );