Navigation Menu

Skip to content

Commit

Permalink
QgsBlockingNetworkRequest: Allow canceling via QgsFeedback
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Dec 20, 2018
1 parent 18376c4 commit d1a1d75
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 13 deletions.
8 changes: 6 additions & 2 deletions python/core/auto_generated/qgsblockingnetworkrequest.sip.in
Expand Up @@ -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``.

Expand All @@ -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().

Expand All @@ -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``.

Expand All @@ -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().

Expand Down
23 changes: 15 additions & 8 deletions src/core/qgsblockingnetworkrequest.cpp
Expand Up @@ -19,6 +19,7 @@
#include "qgsnetworkaccessmanager.h"
#include "qgsauthmanager.h"
#include "qgsmessagelog.h"
#include "qgsfeedback.h"
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 );
Expand All @@ -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 ) )
{
Expand Down Expand Up @@ -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 )
{
Expand All @@ -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 );
Expand Down
14 changes: 11 additions & 3 deletions src/core/qgsblockingnetworkrequest.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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().
*
Expand All @@ -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.
Expand All @@ -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().
*
Expand All @@ -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.\
Expand Down Expand Up @@ -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();

Expand Down

0 comments on commit d1a1d75

Please sign in to comment.