Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[Server] Use QgsBlockingNetworkRequest to download URL
1. Deduplicate code
2. We have seen crashes where we can observe the following pattern at
   the top of the stack trace. This is always happening nested inside
   another event loop somewhere, where the lower part of the stack,
   which is omitted here `[...]` can be any other `processEvents()` call
   or local `QEventLoop`, which is likely caused by interaction of the
   local event loop for downloading here with other event loops, signals
   and timers (only approximal understanding on the exact reasons from
   my side).

```
_ZNK14QMessageLogger5fatalEPKcz: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
_ZN28QgsServerParameterDefinition10raiseErrorERK7QString: /usr/lib/libqgis_server.so.3.22.14
_ZN28QgsServerParameterDefinition10raiseErrorERK7QString: /usr/lib/libqgis_server.so.3.22.14
_ZN7QObject5eventEP6QEvent: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
[symbol missing]: /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
[symbol missing]: /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
[symbol missing]: /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
_ZN9QMetaType4typeERK10QByteArray: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
[symbol missing]: /usr/lib/x86_64-linux-gnu/libQt5Network.so.5
_ZN9QMetaType8typeInfoEi: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
_ZN14QgsApplication6notifyEP7QObjectP6QEvent: /usr/lib/libqgis_core.so.3.22.14
_ZN16QCoreApplication15notifyInternal2EP7QObjectP6QEvent: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
_ZN23QCoreApplicationPrivate16sendPostedEventsEP7QObjectiP11QThreadData: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
_ZN27QEventDispatcherGlibPrivate31runTimersOnceWithNormalPriorityEv: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
[...]
```
  • Loading branch information
m-kuhn authored and github-actions[bot] committed May 6, 2023
1 parent 0c0816b commit e5d8b86
Showing 1 changed file with 9 additions and 47 deletions.
56 changes: 9 additions & 47 deletions src/server/qgsserverparameters.cpp
Expand Up @@ -15,9 +15,9 @@
* *
***************************************************************************/

#include "qgsblockingnetworkrequest.h"
#include "qgsserverparameters.h"
#include "qgsserverexception.h"
#include "qgsnetworkcontentfetcher.h"
#include "qgsmessagelog.h"
#include "qgsvariantutils.h"
#include <QObject>
Expand Down Expand Up @@ -332,65 +332,27 @@ QString QgsServerParameterDefinition::loadUrl( bool &ok ) const
return QString();
}

// fetching content
QgsNetworkContentFetcher fetcher;
QEventLoop loop;
QObject::connect( &fetcher, &QgsNetworkContentFetcher::finished, &loop, &QEventLoop::quit );

QgsMessageLog::logMessage(
QObject::tr( "Request started [url: %1]" ).arg( url.toString() ),
QStringLiteral( "Server" ) );
QNetworkRequest request( url );
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
fetcher.fetchContent( request );

//wait until content fetched
loop.exec( QEventLoop::ExcludeUserInputEvents );

QNetworkReply *reply = fetcher.reply();
if ( !reply )
{
ok = false;
QgsMessageLog::logMessage(
QObject::tr( "Request failed [error: no reply - url: %1]" ).arg( url.toString() ),
QStringLiteral( "Server" ) );
return QString();
}

const QVariant status = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute );
if ( status.isValid() && status.toInt() >= 400 )
{
ok = false;
if ( reply->error() != QNetworkReply::NoError )
{
QgsMessageLog::logMessage(
QObject::tr( "Request failed [error: %1 - url: %2]" ).arg( reply->errorString(), reply->url().toString() ),
QStringLiteral( "Server" ) );
}
const QVariant phrase = reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute );
QgsMessageLog::logMessage(
QObject::tr( "Request error [status: %1 - reason phrase: %2] for %3" ).arg( status.toInt() ).arg( phrase.toString(), reply->url().toString() ),
QStringLiteral( "Server" ) );
return QString();
}
// fetching content
QgsBlockingNetworkRequest newReq;
const QgsBlockingNetworkRequest::ErrorCode errorCode = newReq.get( request, false );

if ( reply->error() != QNetworkReply::NoError )
if ( errorCode != QgsBlockingNetworkRequest::NoError )
{
ok = false;
QgsMessageLog::logMessage(
QObject::tr( "Request failed [error: %1 - url: %2]" ).arg( reply->errorString(), reply->url().toString() ),
QObject::tr( "Request failed [error: %1 - url: %2]" ).arg( newReq.errorMessage(), url.toString() ),
QStringLiteral( "Server" ) );
return QString();
}

QgsMessageLog::logMessage(
QObject::tr( "Request finished [url: %1]" ).arg( url.toString() ),
QStringLiteral( "Server" ) );
QgsNetworkReplyContent reply = newReq.reply();

QString content = fetcher.contentAsString();
ok = ( !content.isEmpty() );
return content;
ok = !reply.content().isEmpty();
return reply.content();
}

QUrl QgsServerParameterDefinition::toUrl( bool &ok ) const
Expand Down

0 comments on commit e5d8b86

Please sign in to comment.