QGIS API Documentation 3.36.0-Maidenhead (09951dc0acf)
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"
18#include "qgsapplication.h"
19#include "qgsauthmanager.h"
20#include "qgsvariantutils.h"
21
22#include <QNetworkAccessManager>
23#include <QNetworkRequest>
24#include <QNetworkReply>
25#ifndef QT_NO_SSL
26#include <QSslError>
27#endif
28
29QgsFileDownloader::QgsFileDownloader( const QUrl &url, const QString &outputFileName, const QString &authcfg, bool delayStart, Qgis::HttpMethod httpMethod, const QByteArray &data )
30 : mUrl( url )
31 , mDownloadCanceled( false )
32 , mHttpMethod( httpMethod )
33 , mData( data )
34{
35 if ( !outputFileName.isEmpty() )
36 mFile.setFileName( outputFileName );
37 mAuthCfg = authcfg;
38 if ( !delayStart )
40}
41
42
44{
45 if ( mReply )
46 {
47 mReply->abort();
48 mReply->deleteLater();
49 }
50}
51
53{
55
56 QNetworkRequest request( mUrl );
57 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy );
58 QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsFileDownloader" ) );
59 if ( !mAuthCfg.isEmpty() )
60 {
62 }
63
64 if ( mReply )
65 {
66 disconnect( mReply, &QNetworkReply::readyRead, this, &QgsFileDownloader::onReadyRead );
67 disconnect( mReply, &QNetworkReply::finished, this, &QgsFileDownloader::onFinished );
68 disconnect( mReply, &QNetworkReply::downloadProgress, this, &QgsFileDownloader::onDownloadProgress );
69 mReply->abort();
70 mReply->deleteLater();
71 }
72
73 switch ( mHttpMethod )
74 {
76 {
77 mReply = nam->get( request );
78 break;
79 }
81 {
82 mReply = nam->post( request, mData );
83 break;
84 }
85 }
86
87 if ( !mAuthCfg.isEmpty() )
88 {
90 }
91
92 connect( mReply, &QNetworkReply::readyRead, this, &QgsFileDownloader::onReadyRead );
93 connect( mReply, &QNetworkReply::finished, this, &QgsFileDownloader::onFinished );
94 connect( mReply, &QNetworkReply::downloadProgress, this, &QgsFileDownloader::onDownloadProgress );
95 connect( nam, qOverload< QNetworkReply *>( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsFileDownloader::onRequestTimedOut, Qt::UniqueConnection );
96#ifndef QT_NO_SSL
97 connect( nam, &QgsNetworkAccessManager::sslErrors, this, &QgsFileDownloader::onSslErrors, Qt::UniqueConnection );
98#endif
99}
100
102{
103 mDownloadCanceled = true;
104 emit downloadCanceled();
105 onFinished();
106}
107
108void QgsFileDownloader::onRequestTimedOut( QNetworkReply *reply )
109{
110 if ( reply == mReply )
111 error( tr( "Network request %1 timed out" ).arg( mUrl.toString() ) );
112}
113
114#ifndef QT_NO_SSL
115void QgsFileDownloader::onSslErrors( QNetworkReply *reply, const QList<QSslError> &errors )
116{
117 if ( reply == mReply )
118 {
119 QStringList errorMessages;
120 errorMessages.reserve( errors.size() + 1 );
121 errorMessages << QStringLiteral( "SSL Errors: " );
122
123 for ( const QSslError &error : errors )
124 errorMessages << error.errorString();
125
126 error( errorMessages );
127 }
128}
129#endif
130
131
132void QgsFileDownloader::error( const QStringList &errorMessages )
133{
134 for ( const QString &error : errorMessages )
135 mErrors << error;
136
137 if ( mReply )
138 mReply->abort();
139 emit downloadError( mErrors );
140}
141
142void QgsFileDownloader::error( const QString &errorMessage )
143{
144 error( QStringList() << errorMessage );
145}
146
147void QgsFileDownloader::onReadyRead()
148{
149 Q_ASSERT( mReply );
150 if ( mFile.fileName().isEmpty() )
151 {
152 error( tr( "No output filename specified" ) );
153 onFinished();
154 }
155 else if ( ! mFile.isOpen() && ! mFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
156 {
157 error( tr( "Cannot open output file: %1" ).arg( mFile.fileName() ) );
158 onFinished();
159 }
160 else
161 {
162 const QByteArray data = mReply->readAll();
163 mFile.write( data );
164 }
165}
166
167void QgsFileDownloader::onFinished()
168{
169 // when canceled
170 if ( ! mErrors.isEmpty() || mDownloadCanceled )
171 {
172 if ( mFile.isOpen() )
173 mFile.close();
174 if ( mFile.exists() )
175 mFile.remove();
176 }
177 else
178 {
179 // download finished normally
180 if ( mFile.isOpen() )
181 {
182 mFile.flush();
183 mFile.close();
184 }
185
186 if ( mReply->error() )
187 {
188 mFile.remove();
189 error( tr( "Download failed: %1" ).arg( mReply->errorString() ) );
190 }
191 else
192 {
193 emit downloadCompleted( mReply->url() );
194 }
195 }
196 emit downloadExited();
197 this->deleteLater();
198}
199
200
201void QgsFileDownloader::onDownloadProgress( qint64 bytesReceived, qint64 bytesTotal )
202{
203 if ( mDownloadCanceled )
204 {
205 return;
206 }
207 emit downloadProgress( bytesReceived, bytesTotal );
208}
209
HttpMethod
Different methods of HTTP requests.
Definition qgis.h:772
@ 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)