Skip to content

Commit

Permalink
abort browser wms item get capabilities request on deleteLater, fix for
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed Aug 27, 2015
1 parent e0d5a0b commit c285ed1
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 42 deletions.
104 changes: 66 additions & 38 deletions src/providers/wms/qgswmscapabilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1854,20 +1854,33 @@ int QgsWmsCapabilities::identifyCapabilities() const

// -----------------

QgsWmsCapabilitiesDownload::QgsWmsCapabilitiesDownload( QObject *parent )
: QObject( parent )
, mCapabilitiesReply( 0 )
, mIsAborted( false )
{
}

QgsWmsCapabilitiesDownload::QgsWmsCapabilitiesDownload( const QString& baseUrl, const QgsWmsAuthorization& auth, QObject *parent )
: QObject( parent )
, mBaseUrl( baseUrl )
, mAuth( auth )
, mCapabilitiesReply( NULL )
, mCapabilitiesReply( 0 )
, mIsAborted( false )
{
}

bool QgsWmsCapabilitiesDownload::downloadCapabilities( const QString& baseUrl, const QgsWmsAuthorization& auth )
{
mBaseUrl = baseUrl;
mAuth = auth;
return downloadCapabilities();
}

bool QgsWmsCapabilitiesDownload::downloadCapabilities()
{
QgsDebugMsg( "entering." );

mIsAborted = false;
QString url = mBaseUrl;
QgsDebugMsg( "url = " + url );
if ( !url.contains( "SERVICE=WMTS" ) &&
Expand All @@ -1886,6 +1899,10 @@ bool QgsWmsCapabilitiesDownload::downloadCapabilities()
QgsDebugMsg( QString( "getcapabilities: %1" ).arg( url ) );
// This is causing Qt warning: "Cannot create children for a parent that is in a different thread."
// but it only means that the reply will have no parent
if ( mIsAborted )
{
return false;
}
mCapabilitiesReply = QgsNetworkAccessManager::instance()->get( request );

connect( mCapabilitiesReply, SIGNAL( finished() ), this, SLOT( capabilitiesReplyFinished() ), Qt::DirectConnection );
Expand All @@ -1898,7 +1915,15 @@ bool QgsWmsCapabilitiesDownload::downloadCapabilities()
return mError.isEmpty();
}


void QgsWmsCapabilitiesDownload::abort()
{
QgsDebugMsg( "Entered" );
mIsAborted = true;
if ( mCapabilitiesReply )
{
mCapabilitiesReply->abort();
}
}

void QgsWmsCapabilitiesDownload::capabilitiesReplyProgress( qint64 bytesReceived, qint64 bytesTotal )
{
Expand All @@ -1910,54 +1935,57 @@ void QgsWmsCapabilitiesDownload::capabilitiesReplyProgress( qint64 bytesReceived
void QgsWmsCapabilitiesDownload::capabilitiesReplyFinished()
{
QgsDebugMsg( "entering." );
if ( mCapabilitiesReply->error() == QNetworkReply::NoError )
if ( !mIsAborted )
{
QgsDebugMsg( "reply ok" );
QVariant redirect = mCapabilitiesReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
if ( !redirect.isNull() )
if ( mCapabilitiesReply->error() == QNetworkReply::NoError )
{
emit statusChanged( tr( "Capabilities request redirected." ) );

const QUrl& toUrl = redirect.toUrl();
mCapabilitiesReply->request();
if ( toUrl == mCapabilitiesReply->url() )
QgsDebugMsg( "reply ok" );
QVariant redirect = mCapabilitiesReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
if ( !redirect.isNull() )
{
mError = tr( "Redirect loop detected: %1" ).arg( toUrl.toString() );
QgsMessageLog::logMessage( mError, tr( "WMS" ) );
mHttpCapabilitiesResponse.clear();
emit statusChanged( tr( "Capabilities request redirected." ) );

const QUrl& toUrl = redirect.toUrl();
mCapabilitiesReply->request();
if ( toUrl == mCapabilitiesReply->url() )
{
mError = tr( "Redirect loop detected: %1" ).arg( toUrl.toString() );
QgsMessageLog::logMessage( mError, tr( "WMS" ) );
mHttpCapabilitiesResponse.clear();
}
else
{
QNetworkRequest request( toUrl );
mAuth.setAuthorization( request );
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork );
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );

mCapabilitiesReply->deleteLater();
QgsDebugMsg( QString( "redirected getcapabilities: %1" ).arg( redirect.toString() ) );
mCapabilitiesReply = QgsNetworkAccessManager::instance()->get( request );

connect( mCapabilitiesReply, SIGNAL( finished() ), this, SLOT( capabilitiesReplyFinished() ) );
connect( mCapabilitiesReply, SIGNAL( downloadProgress( qint64, qint64 ) ), this, SLOT( capabilitiesReplyProgress( qint64, qint64 ) ) );
return;
}
}
else
{
QNetworkRequest request( toUrl );
mAuth.setAuthorization( request );
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork );
request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
mHttpCapabilitiesResponse = mCapabilitiesReply->readAll();

mCapabilitiesReply->deleteLater();
QgsDebugMsg( QString( "redirected getcapabilities: %1" ).arg( redirect.toString() ) );
mCapabilitiesReply = QgsNetworkAccessManager::instance()->get( request );

connect( mCapabilitiesReply, SIGNAL( finished() ), this, SLOT( capabilitiesReplyFinished() ) );
connect( mCapabilitiesReply, SIGNAL( downloadProgress( qint64, qint64 ) ), this, SLOT( capabilitiesReplyProgress( qint64, qint64 ) ) );
return;
if ( mHttpCapabilitiesResponse.isEmpty() )
{
mError = tr( "empty of capabilities: %1" ).arg( mCapabilitiesReply->errorString() );
}
}
}
else
{
mHttpCapabilitiesResponse = mCapabilitiesReply->readAll();

if ( mHttpCapabilitiesResponse.isEmpty() )
{
mError = tr( "empty of capabilities: %1" ).arg( mCapabilitiesReply->errorString() );
}
mError = tr( "Download of capabilities failed: %1" ).arg( mCapabilitiesReply->errorString() );
QgsMessageLog::logMessage( mError, tr( "WMS" ) );
mHttpCapabilitiesResponse.clear();
}
}
else
{
mError = tr( "Download of capabilities failed: %1" ).arg( mCapabilitiesReply->errorString() );
QgsMessageLog::logMessage( mError, tr( "WMS" ) );
mHttpCapabilitiesResponse.clear();
}

mCapabilitiesReply->deleteLater();
mCapabilitiesReply = 0;
Expand Down
7 changes: 7 additions & 0 deletions src/providers/wms/qgswmscapabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -683,14 +683,20 @@ class QgsWmsCapabilitiesDownload : public QObject
Q_OBJECT

public:
QgsWmsCapabilitiesDownload( QObject* parent = 0 );

QgsWmsCapabilitiesDownload( const QString& baseUrl, const QgsWmsAuthorization& auth, QObject* parent = 0 );

bool downloadCapabilities();

bool downloadCapabilities( const QString& baseUrl, const QgsWmsAuthorization& auth );

QString lastError() const { return mError; }

QByteArray response() const { return mHttpCapabilitiesResponse; }

/** Abort network request immediately */
void abort();
signals:
/** \brief emit a signal to be caught by qgisapp and display a msg on status bar */
void statusChanged( QString const & theStatusQString );
Expand Down Expand Up @@ -720,6 +726,7 @@ class QgsWmsCapabilitiesDownload : public QObject
/** Capabilities of the WMS (raw) */
QByteArray mHttpCapabilitiesResponse;

bool mIsAborted;
};


Expand Down
20 changes: 16 additions & 4 deletions src/providers/wms/qgswmsdataitems.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,26 @@
QgsWMSConnectionItem::QgsWMSConnectionItem( QgsDataItem* parent, QString name, QString path, QString uri )
: QgsDataCollectionItem( parent, name, path )
, mUri( uri )
, mCapabilitiesDownload( 0 )
{
mIconName = "mIconConnect.png";
mCapabilitiesDownload = new QgsWmsCapabilitiesDownload();
}

QgsWMSConnectionItem::~QgsWMSConnectionItem()
{
QgsDebugMsg( "Entered" );
delete mCapabilitiesDownload;
}

void QgsWMSConnectionItem::deleteLater()
{
QgsDebugMsg( "Entered" );
if ( mCapabilitiesDownload )
{
mCapabilitiesDownload->abort();
}
QgsDataCollectionItem::deleteLater();
}

QVector<QgsDataItem*> QgsWMSConnectionItem::createChildren()
Expand All @@ -52,9 +66,7 @@ QVector<QgsDataItem*> QgsWMSConnectionItem::createChildren()
return children;
}

QgsWmsCapabilitiesDownload capDownload( wmsSettings.baseUrl(), wmsSettings.authorization() );

bool res = capDownload.downloadCapabilities();
bool res = mCapabilitiesDownload->downloadCapabilities( wmsSettings.baseUrl(), wmsSettings.authorization() );

if ( !res )
{
Expand All @@ -63,7 +75,7 @@ QVector<QgsDataItem*> QgsWMSConnectionItem::createChildren()
}

QgsWmsCapabilities caps;
if ( !caps.parseResponse( capDownload.response(), wmsSettings.parserSettings() ) )
if ( !caps.parseResponse( mCapabilitiesDownload->response(), wmsSettings.parserSettings() ) )
{
children.append( new QgsErrorItem( this, tr( "Failed to parse capabilities" ), mPath + "/error" ) );
return children;
Expand Down
4 changes: 4 additions & 0 deletions src/providers/wms/qgswmsdataitems.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include "qgsdatasourceuri.h"
#include "qgswmsprovider.h"

class QgsWmsCapabilitiesDownload;

class QgsWMSConnectionItem : public QgsDataCollectionItem
{
Q_OBJECT
Expand All @@ -34,9 +36,11 @@ class QgsWMSConnectionItem : public QgsDataCollectionItem
public slots:
void editConnection();
void deleteConnection();
virtual void deleteLater() override;

private:
QString mUri;
QgsWmsCapabilitiesDownload *mCapabilitiesDownload;
};

// WMS Layers may be nested, so that they may be both QgsDataCollectionItem and QgsLayerItem
Expand Down

0 comments on commit c285ed1

Please sign in to comment.