QgsBlockingNetworkRequest: Allow canceling via QgsFeedback

This commit is contained in:
Nyall Dawson 2018-11-13 11:14:55 +10:00
parent 18376c4ae3
commit d1a1d7570e
3 changed files with 32 additions and 13 deletions

View File

@ -47,7 +47,7 @@ Constructor for QgsBlockingNetworkRequest
~QgsBlockingNetworkRequest();
ErrorCode get( QNetworkRequest &request, bool forceRefresh = false );
ErrorCode get( QNetworkRequest &request, bool forceRefresh = false, QgsFeedback *feedback = 0 );
%Docstring
Performs a "get" operation on the specified ``request``.
@ -58,6 +58,8 @@ If an authCfg() has been set, then any authentication configuration required wil
``request``. There is no need to manually apply the authentication to the request prior to calling
this method.
The optional ``feedback`` argument can be used to abort ongoing requests.
The method will return NoError if the get operation was successful. The contents of the reply can be retrieved
by calling reply().
@ -67,7 +69,7 @@ can be retrieved by calling errorMessage().
.. seealso:: :py:func:`post`
%End
ErrorCode post( QNetworkRequest &request, const QByteArray &data, bool forceRefresh = false );
ErrorCode post( QNetworkRequest &request, const QByteArray &data, bool forceRefresh = false, QgsFeedback *feedback = 0 );
%Docstring
Performs a "post" operation on the specified ``request``, using the given ``data``.
@ -78,6 +80,8 @@ If an authCfg() has been set, then any authentication configuration required wil
``request``. There is no need to manually apply the authentication to the request prior to calling
this method.
The optional ``feedback`` argument can be used to abort ongoing requests.
The method will return NoError if the get operation was successful. The contents of the reply can be retrieved
by calling reply().

View File

@ -19,6 +19,7 @@
#include "qgsnetworkaccessmanager.h"
#include "qgsauthmanager.h"
#include "qgsmessagelog.h"
#include "qgsfeedback.h"
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
@ -55,20 +56,21 @@ void QgsBlockingNetworkRequest::setAuthCfg( const QString &authCfg )
mAuthCfg = authCfg;
}
QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::get( QNetworkRequest &request, bool forceRefresh )
QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::get( QNetworkRequest &request, bool forceRefresh, QgsFeedback *feedback )
{
return doRequest( Get, request, forceRefresh );
return doRequest( Get, request, forceRefresh, feedback );
}
QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::post( QNetworkRequest &request, const QByteArray &data, bool forceRefresh )
QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::post( QNetworkRequest &request, const QByteArray &data, bool forceRefresh, QgsFeedback *feedback )
{
mPostData = data;
return doRequest( Post, request, forceRefresh );
return doRequest( Post, request, forceRefresh, feedback );
}
QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBlockingNetworkRequest::Method method, QNetworkRequest &request, bool forceRefresh )
QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBlockingNetworkRequest::Method method, QNetworkRequest &request, bool forceRefresh, QgsFeedback *feedback )
{
mMethod = method;
mFeedback = feedback;
abort(); // cancel previous
mIsAborted = false;
@ -98,7 +100,10 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
bool threadFinished = false;
bool success = false;
std::function<void()> downloaderFunction = [ this, request, &waitConditionMutex, &waitCondition, &threadFinished, &success ]()
if ( mFeedback )
connect( mFeedback, &QgsFeedback::canceled, this, &QgsBlockingNetworkRequest::abort );
std::function<void()> downloaderFunction = [ this, request, &waitConditionMutex, &waitCondition, &threadFinished, &success, feedback ]()
{
if ( QThread::currentThread() != QgsApplication::instance()->thread() )
QgsNetworkAccessManager::instance( Qt::DirectConnection );
@ -117,6 +122,8 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( QgsBl
};
mReply->setReadBufferSize( READ_BUFFER_SIZE_HINT );
if ( mFeedback )
connect( mFeedback, &QgsFeedback::canceled, mReply, &QNetworkReply::abort );
if ( !mAuthCfg.isEmpty() && !QgsApplication::authManager()->updateNetworkReply( mReply, mAuthCfg ) )
{
@ -221,7 +228,7 @@ void QgsBlockingNetworkRequest::replyProgress( qint64 bytesReceived, qint64 byte
if ( bytesReceived != 0 )
mGotNonEmptyResponse = true;
if ( !mIsAborted && mReply )
if ( !mIsAborted && mReply && ( !mFeedback || !mFeedback->isCanceled() ) )
{
if ( mReply->error() == QNetworkReply::NoError )
{
@ -241,7 +248,7 @@ void QgsBlockingNetworkRequest::replyFinished()
{
if ( !mIsAborted && mReply )
{
if ( mReply->error() == QNetworkReply::NoError )
if ( mReply->error() == QNetworkReply::NoError && ( !mFeedback || !mFeedback->isCanceled() ) )
{
QgsDebugMsgLevel( QStringLiteral( "reply OK" ), 2 );
QVariant redirect = mReply->attribute( QNetworkRequest::RedirectionTargetAttribute );

View File

@ -17,9 +17,11 @@
#include "qgis_core.h"
#include "qgsnetworkreply.h"
#include "qgsfeedback.h"
#include <QThread>
#include <QObject>
#include <functional>
#include <QPointer>
class QNetworkRequest;
class QNetworkReply;
@ -70,6 +72,8 @@ class CORE_EXPORT QgsBlockingNetworkRequest : public QObject
* \a request. There is no need to manually apply the authentication to the request prior to calling
* this method.
*
* The optional \a feedback argument can be used to abort ongoing requests.
*
* The method will return NoError if the get operation was successful. The contents of the reply can be retrieved
* by calling reply().
*
@ -78,7 +82,7 @@ class CORE_EXPORT QgsBlockingNetworkRequest : public QObject
*
* \see post()
*/
ErrorCode get( QNetworkRequest &request, bool forceRefresh = false );
ErrorCode get( QNetworkRequest &request, bool forceRefresh = false, QgsFeedback *feedback = nullptr );
/**
* Performs a "post" operation on the specified \a request, using the given \a data.
@ -90,6 +94,8 @@ class CORE_EXPORT QgsBlockingNetworkRequest : public QObject
* \a request. There is no need to manually apply the authentication to the request prior to calling
* this method.
*
* The optional \a feedback argument can be used to abort ongoing requests.
*
* The method will return NoError if the get operation was successful. The contents of the reply can be retrieved
* by calling reply().
*
@ -98,7 +104,7 @@ class CORE_EXPORT QgsBlockingNetworkRequest : public QObject
*
* \see get()
*/
ErrorCode post( QNetworkRequest &request, const QByteArray &data, bool forceRefresh = false );
ErrorCode post( QNetworkRequest &request, const QByteArray &data, bool forceRefresh = false, QgsFeedback *feedback = nullptr );
/**
* Returns the error message string, after a get() or post() request has been made.\
@ -185,7 +191,9 @@ class CORE_EXPORT QgsBlockingNetworkRequest : public QObject
int mExpirationSec = 30;
ErrorCode doRequest( Method method, QNetworkRequest &request, bool forceRefresh );
QPointer< QgsFeedback > mFeedback;
ErrorCode doRequest( Method method, QNetworkRequest &request, bool forceRefresh, QgsFeedback *feedback = nullptr );
QString errorMessageFailedAuth();