QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
qgsfiledownloader.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsfiledownloader.cpp
3 --------------------------------------
4 Date : November 2016
5 Copyright : (C) 2016 by Alessandro Pasotti
6 Email : apasotti at boundlessgeo dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsfiledownloader.h"
17#include "moc_qgsfiledownloader.cpp"
20#include "qgsapplication.h"
21#include "qgsauthmanager.h"
22#include "qgsvariantutils.h"
23
24#include <QNetworkAccessManager>
25#include <QNetworkRequest>
26#include <QNetworkReply>
27#ifndef QT_NO_SSL
28#include <QSslError>
29#endif
30
31QgsFileDownloader::QgsFileDownloader( const QUrl &url, const QString &outputFileName, const QString &authcfg, bool delayStart, Qgis::HttpMethod httpMethod, const QByteArray &data )
32 : mUrl( url )
33 , mDownloadCanceled( false )
34 , mHttpMethod( httpMethod )
35 , mData( data )
36{
37 if ( !outputFileName.isEmpty() )
38 mFile.setFileName( outputFileName );
39 mAuthCfg = authcfg;
40 if ( !delayStart )
42}
43
44
46{
47 if ( mReply )
48 {
49 mReply->abort();
50 mReply->deleteLater();
51 }
52}
53
55{
57
58 QNetworkRequest request( mUrl );
59 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy );
60 QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsFileDownloader" ) );
61 if ( !mAuthCfg.isEmpty() )
62 {
64 }
65
66 if ( mReply )
67 {
68 disconnect( mReply, &QNetworkReply::readyRead, this, &QgsFileDownloader::onReadyRead );
69 disconnect( mReply, &QNetworkReply::finished, this, &QgsFileDownloader::onFinished );
70 disconnect( mReply, &QNetworkReply::downloadProgress, this, &QgsFileDownloader::onDownloadProgress );
71 mReply->abort();
72 mReply->deleteLater();
73 }
74
75 switch ( mHttpMethod )
76 {
78 {
79 mReply = nam->get( request );
80 break;
81 }
83 {
84 mReply = nam->post( request, mData );
85 break;
86 }
87 }
88
89 if ( !mAuthCfg.isEmpty() )
90 {
92 }
93
94 connect( mReply, &QNetworkReply::readyRead, this, &QgsFileDownloader::onReadyRead );
95 connect( mReply, &QNetworkReply::finished, this, &QgsFileDownloader::onFinished );
96 connect( mReply, &QNetworkReply::downloadProgress, this, &QgsFileDownloader::onDownloadProgress );
97 connect( nam, qOverload< QNetworkReply *>( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsFileDownloader::onRequestTimedOut, Qt::UniqueConnection );
98#ifndef QT_NO_SSL
99 connect( nam, &QgsNetworkAccessManager::sslErrors, this, &QgsFileDownloader::onSslErrors, Qt::UniqueConnection );
100#endif
101}
102
104{
105 mDownloadCanceled = true;
106 emit downloadCanceled();
107 onFinished();
108}
109
110void QgsFileDownloader::onRequestTimedOut( QNetworkReply *reply )
111{
112 if ( reply == mReply )
113 error( tr( "Network request %1 timed out" ).arg( mUrl.toString() ) );
114}
115
116#ifndef QT_NO_SSL
117void QgsFileDownloader::onSslErrors( QNetworkReply *reply, const QList<QSslError> &errors )
118{
119 if ( reply == mReply )
120 {
121 QStringList errorMessages;
122 errorMessages.reserve( errors.size() + 1 );
123 errorMessages << QStringLiteral( "SSL Errors: " );
124
125 for ( const QSslError &error : errors )
126 errorMessages << error.errorString();
127
128 error( errorMessages );
129 }
130}
131#endif
132
133
134void QgsFileDownloader::error( const QStringList &errorMessages )
135{
136 for ( const QString &error : errorMessages )
137 mErrors << error;
138
139 if ( mReply )
140 mReply->abort();
141 emit downloadError( mErrors );
142}
143
144void QgsFileDownloader::error( const QString &errorMessage )
145{
146 error( QStringList() << errorMessage );
147}
148
149void QgsFileDownloader::onReadyRead()
150{
151 Q_ASSERT( mReply );
152 if ( mFile.fileName().isEmpty() )
153 {
154 error( tr( "No output filename specified" ) );
155 onFinished();
156 }
157 else if ( ! mFile.isOpen() && ! mFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
158 {
159 error( tr( "Cannot open output file: %1" ).arg( mFile.fileName() ) );
160 onFinished();
161 }
162 else
163 {
164 const QByteArray data = mReply->readAll();
165 mFile.write( data );
166 }
167}
168
169void QgsFileDownloader::onFinished()
170{
171 // when canceled
172 if ( ! mErrors.isEmpty() || mDownloadCanceled )
173 {
174 if ( mFile.isOpen() )
175 mFile.close();
176 if ( mFile.exists() )
177 mFile.remove();
178 }
179 else
180 {
181 // download finished normally
182 if ( mFile.isOpen() )
183 {
184 mFile.flush();
185 mFile.close();
186 }
187
188 if ( mReply->error() )
189 {
190 mFile.remove();
191 error( tr( "Download failed: %1" ).arg( mReply->errorString() ) );
192 }
193 else
194 {
195 emit downloadCompleted( mReply->url() );
196 }
197 }
198 emit downloadExited();
199 this->deleteLater();
200}
201
202
203void QgsFileDownloader::onDownloadProgress( qint64 bytesReceived, qint64 bytesTotal )
204{
205 if ( mDownloadCanceled )
206 {
207 return;
208 }
209 emit downloadProgress( bytesReceived, bytesTotal );
210}
211
HttpMethod
Different methods of HTTP requests.
Definition qgis.h:971
@ Post
POST method.
@ Get
GET method.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
bool updateNetworkRequest(QNetworkRequest &request, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkRequest with an authentication config.
bool updateNetworkReply(QNetworkReply *reply, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkReply with an authentication config (used to skip known SSL errors,...
void cancelDownload()
Call to abort the download and delete this object after the cancellation has been processed.
void downloadExited()
Emitted always when the downloader exits.
void downloadCanceled()
Emitted when the download was canceled by the user.
void downloadError(QStringList errorMessages)
Emitted when an error makes the download fail.
void startDownload()
Called to start the download.
QgsFileDownloader(const QUrl &url, const QString &outputFileName, const QString &authcfg=QString(), bool delayStart=false, Qgis::HttpMethod httpMethod=Qgis::HttpMethod::Get, const QByteArray &data=QByteArray())
QgsFileDownloader.
void downloadCompleted(const QUrl &url)
Emitted when the download has completed successfully.
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
Emitted when data are ready to be processed.
network access manager for QGIS
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
void requestTimedOut(QgsNetworkRequestParameters request)
Emitted when a network request has timed out.
#define QgsSetRequestInitiatorClass(request, _class)