Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Revert "Revert QgsBlockingNetworkRequest"
With recent changes in QgsNetworkAccessManager this should be
safe to resurrect (fingers crossed!). Also simplify code a lot,
because now QgsNetworkAccessManager handles waking the worker
thread after the auth request is handled.

Add a lot more tests
  • Loading branch information
nyalldawson committed Feb 1, 2019
1 parent c03ce93 commit 4908ef1
Show file tree
Hide file tree
Showing 16 changed files with 1,371 additions and 62 deletions.
146 changes: 146 additions & 0 deletions python/core/auto_generated/qgsblockingnetworkrequest.sip.in
@@ -0,0 +1,146 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsblockingnetworkrequest.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/



class QgsBlockingNetworkRequest : QObject
{
%Docstring
A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy
and authentication settings.

This class should be used whenever a blocking network request is required. Unlike implementations
which rely on QApplication.processEvents() or creation of a QEventLoop, this class is completely
thread safe and can be used on either the main thread or background threads without issue.

Redirects are automatically handled by the class.

After completion of a request, the reply content should be retrieved by calling getReplyContent().
This method returns a QgsNetworkReplyContent container, which is safe and cheap to copy and pass
between threads without issue.

.. versionadded:: 3.6
%End

%TypeHeaderCode
#include "qgsblockingnetworkrequest.h"
%End
public:

enum ErrorCode
{
NoError,
NetworkError,
TimeoutError,
ServerExceptionError,
};

explicit QgsBlockingNetworkRequest();
%Docstring
Constructor for QgsBlockingNetworkRequest
%End

~QgsBlockingNetworkRequest();

ErrorCode get( QNetworkRequest &request, bool forceRefresh = false, QgsFeedback *feedback = 0 );
%Docstring
Performs a "get" operation on the specified ``request``.

If ``forceRefresh`` is false then previously cached replies may be used for the request. If
it is set to true then a new query is always performed.

If an authCfg() has been set, then any authentication configuration required will automatically be applied to
``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().

If an error was encountered then a specific ErrorCode will be returned, and a detailed error message
can be retrieved by calling errorMessage().

.. seealso:: :py:func:`post`
%End

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``.

If ``forceRefresh`` is false then previously cached replies may be used for the request. If
it is set to true then a new query is always performed.

If an authCfg() has been set, then any authentication configuration required will automatically be applied to
``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().

If an error was encountered then a specific ErrorCode will be returned, and a detailed error message
can be retrieved by calling errorMessage().

.. seealso:: :py:func:`get`
%End

QString errorMessage() const;
%Docstring
Returns the error message string, after a get() or post() request has been made.\
%End

QgsNetworkReplyContent reply() const;
%Docstring
Returns the content of the network reply, after a get() or post() request has been made.
%End

QString authCfg() const;
%Docstring
Returns the authentication config id which will be used during the request.

.. seealso:: :py:func:`setAuthCfg`
%End

void setAuthCfg( const QString &authCfg );
%Docstring
Sets the authentication config id which should be used during the request.

.. seealso:: :py:func:`authCfg`
%End

public slots:

void abort();
%Docstring
Aborts the network request immediately.
%End

signals:

void downloadProgress( qint64, qint64 );
%Docstring
Emitted when when data arrives during a request.
%End

void downloadFinished();
%Docstring
Emitted once a request has finished downloading.
%End

};


/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsblockingnetworkrequest.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
47 changes: 47 additions & 0 deletions python/core/auto_generated/qgsnetworkaccessmanager.sip.in
Expand Up @@ -11,6 +11,7 @@




class QgsNetworkRequestParameters
{
%Docstring
Expand Down Expand Up @@ -251,6 +252,52 @@ Sets the maximum timeout ``time`` for network requests, in milliseconds.

.. seealso:: :py:func:`timeout`

.. versionadded:: 3.6
%End

static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = 0 );
%Docstring
Posts a GET request to obtain the contents of the target request and returns a new QgsNetworkReplyContent object for reading.
The current thread will be blocked until the request is returned.

This method is safe to call in either the main thread or a worker thread.

If ``forceRefresh`` is false then previously cached replies may be used for the request. If
it is set to true then a new query is always performed.

If an ``authCfg`` has been specified, then that authentication configuration required will automatically be applied to
``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 contents of the reply will be returned after the request is completed or an error occurs.

.. seealso:: :py:func:`blockingPost`

.. versionadded:: 3.6
%End

static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = 0 );
%Docstring
Posts a POST request to obtain the contents of the target ``request``, using the given ``data``, and returns a new
QgsNetworkReplyContent object for reading. The current thread will be blocked until the request is returned.

This method is safe to call in either the main thread or a worker thread.

If ``forceRefresh`` is false then previously cached replies may be used for the request. If
it is set to true then a new query is always performed.

If an ``authCfg`` has been specified, then that authentication configuration required will automatically be applied to
``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 contents of the reply will be returned after the request is completed or an error occurs.

.. seealso:: :py:func:`blockingGet`

.. versionadded:: 3.6
%End

Expand Down
4 changes: 4 additions & 0 deletions python/core/auto_generated/qgsnetworkreply.sip.in
Expand Up @@ -109,6 +109,10 @@ Returns the unique ID identifying the original request which this response was f
Returns the original network request.
%End

void setContent( const QByteArray &content );

QByteArray content() const;

};

/************************************************************************
Expand Down
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -318,6 +318,7 @@
%Include auto_generated/qgsactionscoperegistry.sip
%Include auto_generated/qgsanimatedicon.sip
%Include auto_generated/qgsauxiliarystorage.sip
%Include auto_generated/qgsblockingnetworkrequest.sip
%Include auto_generated/qgsbrowsermodel.sip
%Include auto_generated/qgsbrowserproxymodel.sip
%Include auto_generated/qgscoordinatereferencesystem.sip
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -1589,6 +1589,10 @@ QgisApp::~QgisApp()
qDeleteAll( mCustomDropHandlers );
qDeleteAll( mCustomLayoutDropHandlers );

// replace gui based network access managers with failing only ones
QgsNetworkAccessManager::instance()->setSslErrorHandler( qgis::make_unique< QgsSslErrorHandler >() );
QgsNetworkAccessManager::instance()->setAuthHandler( qgis::make_unique< QgsNetworkAuthenticationHandler >() );

const QList<QgsMapCanvas *> canvases = mapCanvases();
for ( QgsMapCanvas *canvas : canvases )
{
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -153,6 +153,7 @@ SET(QGIS_CORE_SRCS
qgsattributeeditorelement.cpp
qgsauxiliarystorage.cpp
qgsbearingutils.cpp
qgsblockingnetworkrequest.cpp
qgsbrowsermodel.cpp
qgsbrowserproxymodel.cpp
qgscachedfeatureiterator.cpp
Expand Down Expand Up @@ -602,6 +603,7 @@ SET(QGIS_CORE_MOC_HDRS
qgsactionscoperegistry.h
qgsanimatedicon.h
qgsauxiliarystorage.h
qgsblockingnetworkrequest.h
qgsbrowsermodel.h
qgsbrowserproxymodel.h
qgscoordinatereferencesystem.h
Expand Down

0 comments on commit 4908ef1

Please sign in to comment.