Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsnetworkaccessmanager.h - description
3 : : -------------------
4 : : begin : 2010-05-08
5 : : copyright : (C) 2010 by Juergen E. Fischer
6 : : email : jef at norbit dot de
7 : : ***************************************************************************/
8 : :
9 : : /***************************************************************************
10 : : * *
11 : : * This program is free software; you can redistribute it and/or modify *
12 : : * it under the terms of the GNU General Public License as published by *
13 : : * the Free Software Foundation; either version 2 of the License, or *
14 : : * (at your option) any later version. *
15 : : * *
16 : : ***************************************************************************/
17 : :
18 : : #ifndef QGSNETWORKACCESSMANAGER_H
19 : : #define QGSNETWORKACCESSMANAGER_H
20 : :
21 : : #include <QList>
22 : : #include "qgsnetworkreply.h"
23 : : #include "qgis_sip.h"
24 : : #include <QStringList>
25 : : #include <QNetworkAccessManager>
26 : : #include <QNetworkProxy>
27 : : #include <QNetworkRequest>
28 : : #include <QMutex>
29 : : #include <QWaitCondition>
30 : : #include <memory>
31 : :
32 : : #include "qgis_core.h"
33 : : #include "qgis_sip.h"
34 : :
35 : : class QgsFeedback;
36 : :
37 : : #ifndef SIP_RUN
38 : : #include "qgsconfig.h"
39 : : constexpr int sFilePrefixLength = CMAKE_SOURCE_DIR[sizeof( CMAKE_SOURCE_DIR ) - 1] == '/' ? sizeof( CMAKE_SOURCE_DIR ) + 1 : sizeof( CMAKE_SOURCE_DIR );
40 : :
41 : : #define QgsSetRequestInitiatorClass(request, _class) request.setAttribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorClass ), _class ); request.setAttribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorRequestId ), QString(QString( __FILE__ ).mid( sFilePrefixLength ) + ':' + QString::number( __LINE__ ) + " (" + __FUNCTION__ + ")") );
42 : : #define QgsSetRequestInitiatorId(request, str) request.setAttribute( static_cast< QNetworkRequest::Attribute >( QgsNetworkRequestParameters::AttributeInitiatorRequestId ), QString(QString( __FILE__ ).mid( sFilePrefixLength ) + ':' + QString::number( __LINE__ ) + " (" + __FUNCTION__ + "): " + str) );
43 : : #endif
44 : :
45 : : /**
46 : : * \class QgsNetworkRequestParameters
47 : : * \ingroup core
48 : : * \brief Encapsulates parameters and properties of a network request.
49 : : * \since QGIS 3.6
50 : : */
51 : 0 : class CORE_EXPORT QgsNetworkRequestParameters
52 : : {
53 : : public:
54 : :
55 : : //! Custom request attributes
56 : : enum RequestAttributes
57 : : {
58 : : AttributeInitiatorClass = QNetworkRequest::User + 3000, //!< Class name of original object which created the request
59 : : AttributeInitiatorRequestId, //!< Internal ID used by originator object to identify requests
60 : : };
61 : :
62 : : /**
63 : : * Default constructor.
64 : : */
65 : 0 : QgsNetworkRequestParameters() = default;
66 : :
67 : : /**
68 : : * Constructor for QgsNetworkRequestParameters, with the specified network
69 : : * \a operation and original \a request.
70 : : */
71 : : QgsNetworkRequestParameters( QNetworkAccessManager::Operation operation,
72 : : const QNetworkRequest &request,
73 : : int requestId,
74 : : const QByteArray &content = QByteArray() );
75 : :
76 : : /**
77 : : * Returns the request operation, e.g. GET or POST.
78 : : */
79 : : QNetworkAccessManager::Operation operation() const { return mOperation; }
80 : :
81 : : /**
82 : : * Returns the network request.
83 : : *
84 : : * This is the original network request sent to QgsNetworkAccessManager, but with QGIS specific
85 : : * configuration options such as proxy handling and SSL exceptions applied.
86 : : */
87 : : QNetworkRequest request() const { return mRequest; }
88 : :
89 : : /**
90 : : * Returns a string identifying the thread which the request originated from.
91 : : */
92 : : QString originatingThreadId() const { return mOriginatingThreadId; }
93 : :
94 : : /**
95 : : * Returns a unique ID identifying the request.
96 : : */
97 : : int requestId() const { return mRequestId; }
98 : :
99 : : /**
100 : : * Returns the request's content. This is only used for POST or PUT operation
101 : : * requests.
102 : : */
103 : : QByteArray content() const { return mContent; }
104 : :
105 : : /**
106 : : * Returns the class name of the object which initiated this request.
107 : : *
108 : : * This is only available for QNetworkRequests which have had the
109 : : * QgsNetworkRequestParameters::AttributeInitiatorClass attribute set.
110 : : *
111 : : * \see initiatorRequestId()
112 : : */
113 : : QString initiatorClassName() const { return mInitiatorClass; }
114 : :
115 : : /**
116 : : * Returns the internal ID used by the object which initiated this request to identify
117 : : * individual requests.
118 : : *
119 : : * This is only available for QNetworkRequests which have had the
120 : : * QgsNetworkRequestParameters::AttributeInitiatorRequestId attribute set.
121 : : *
122 : : * \see initiatorClassName()
123 : : */
124 : : QVariant initiatorRequestId() const { return mInitiatorRequestId; }
125 : :
126 : : private:
127 : :
128 : : QNetworkAccessManager::Operation mOperation;
129 : : QNetworkRequest mRequest;
130 : : QString mOriginatingThreadId;
131 : 0 : int mRequestId = 0;
132 : : QByteArray mContent;
133 : : QString mInitiatorClass;
134 : : QVariant mInitiatorRequestId;
135 : : };
136 : :
137 : : class QgsNetworkAccessManager;
138 : :
139 : : #ifndef SIP_RUN
140 : :
141 : : /**
142 : : * \class QgsSslErrorHandler
143 : : * \brief SSL error handler, used for responding to SSL errors encountered during network requests.
144 : : * \ingroup core
145 : : *
146 : : * \brief QgsSslErrorHandler responds to SSL errors encountered during network requests. The
147 : : * base QgsSslErrorHandler class responds to SSL errors only by logging the errors,
148 : : * and uses the default Qt response, which is to abort the request.
149 : : *
150 : : * Subclasses can override this behavior by implementing their own handleSslErrors()
151 : : * method. QgsSslErrorHandlers are ONLY ever called from the main thread, so it
152 : : * is safe to utilize gui widgets and dialogs during handleSslErrors (e.g. to
153 : : * present prompts to users notifying them of the errors and asking them
154 : : * to choose the appropriate response.).
155 : : *
156 : : * If a reply is coming from background thread, that thread is blocked while handleSslErrors()
157 : : * is running.
158 : : *
159 : : * If the errors should be ignored and the request allowed to proceed, the subclasses'
160 : : * handleSslErrors() method MUST call QNetworkReply::ignoreSslErrors() on the specified
161 : : * QNetworkReply object.
162 : : *
163 : : * An application instance can only have a single SSL error handler. The current
164 : : * SSL error handler is set by calling QgsNetworkAccessManager::setSslErrorHandler().
165 : : * By default an instance of the logging-only QgsSslErrorHandler base class is used.
166 : : *
167 : : * \since QGIS 3.6
168 : : */
169 : 3 : class CORE_EXPORT QgsSslErrorHandler
170 : : {
171 : :
172 : : public:
173 : :
174 : 6 : virtual ~QgsSslErrorHandler() = default;
175 : :
176 : : /**
177 : : * Called whenever SSL \a errors are encountered during a network \a reply.
178 : : *
179 : : * Subclasses should reimplement this method to implement their own logic
180 : : * regarding whether or not these SSL errors should be ignored, and how
181 : : * to present them to users.
182 : : *
183 : : * The base class method just logs errors and leaves the default Qt response
184 : : * to SSL errors, which is to abort the network request on any errors.
185 : : */
186 : : virtual void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
187 : :
188 : : };
189 : :
190 : : /**
191 : : * \class QgsNetworkAuthenticationHandler
192 : : * \brief Network authentication handler, used for responding to network authentication requests during network requests.
193 : : * \ingroup core
194 : : *
195 : : * \brief QgsNetworkAuthenticationHandler responds to authentication requests encountered during network requests. The
196 : : * base QgsNetworkAuthenticationHandler class responds to requests only by logging the request,
197 : : * but does not provide any username or password to allow the request to proceed.
198 : : *
199 : : * Subclasses can override this behavior by implementing their own handleAuthRequest()
200 : : * method. QgsNetworkAuthenticationHandler are ONLY ever called from the main thread, so it
201 : : * is safe to utilize gui widgets and dialogs during handleAuthRequest (e.g. to
202 : : * present prompts to users requesting the username and password).
203 : : *
204 : : * If a reply is coming from background thread, that thread is blocked while handleAuthRequest()
205 : : * is running.
206 : : *
207 : : * An application instance can only have a single network authentication handler. The current
208 : : * authentication handler is set by calling QgsNetworkAccessManager::setAuthHandler().
209 : : * By default an instance of the logging-only QgsNetworkAuthenticationHandler base class is used.
210 : : *
211 : : * \since QGIS 3.6
212 : : */
213 : 3 : class CORE_EXPORT QgsNetworkAuthenticationHandler
214 : : {
215 : :
216 : : public:
217 : :
218 : 6 : virtual ~QgsNetworkAuthenticationHandler() = default;
219 : :
220 : : /**
221 : : * Called whenever network authentication requests are encountered during a network \a reply.
222 : : *
223 : : * Subclasses should reimplement this method to implement their own logic
224 : : * regarding how to handle the requests and whether they should be presented to users.
225 : : *
226 : : * The base class method just logs the request but does not provide any username/password resolution.
227 : : */
228 : : virtual void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
229 : :
230 : : };
231 : : #endif
232 : :
233 : :
234 : : /**
235 : : * \class QgsNetworkAccessManager
236 : : * \brief network access manager for QGIS
237 : : * \ingroup core
238 : : *
239 : : * \brief This class implements the QGIS network access manager. It's a singleton
240 : : * that can be used across QGIS.
241 : : *
242 : : * Plugins can insert proxy factories and thereby redirect requests to
243 : : * individual proxies.
244 : : *
245 : : * If no proxy factories are there or none returns a proxy for an URL a
246 : : * fallback proxy can be set. There's also a exclude list that defines URLs
247 : : * that the fallback proxy should not be used for, then no proxy will be used.
248 : : *
249 : : * \since 1.5
250 : : */
251 : 6 : class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
252 : : {
253 : 0 : Q_OBJECT
254 : :
255 : : public:
256 : :
257 : : /**
258 : : * Returns a pointer to the active QgsNetworkAccessManager
259 : : * for the current thread.
260 : : *
261 : : * With the \a connectionType parameter it is possible to setup the default connection
262 : : * type that is used to handle signals that might require user interaction and therefore
263 : : * need to be handled on the main thread. See in-depth discussion below.
264 : : *
265 : : * \param connectionType In most cases the default of using a ``Qt::BlockingQueuedConnection``
266 : : * is ok, to make a background thread wait for the main thread to answer such a request is
267 : : * fine and anything else is dangerous.
268 : : * However, in case the request was started on the main thread, one should execute a
269 : : * local event loop in a helper thread and freeze the main thread for the duration of the
270 : : * download. In this case, if an authentication request is sent from the background thread
271 : : * network access manager, the background thread should be blocked, the main thread be woken
272 : : * up, processEvents() executed once, the main thread frozen again and the background thread
273 : : * continued.
274 : : */
275 : : static QgsNetworkAccessManager *instance( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
276 : :
277 : : QgsNetworkAccessManager( QObject *parent = nullptr );
278 : :
279 : : #ifndef SIP_RUN
280 : :
281 : : /**
282 : : * Sets the application SSL error \a handler, which is used to respond to SSL errors encountered
283 : : * during network requests.
284 : : *
285 : : * Ownership of \a handler is transferred to the main thread QgsNetworkAccessManager instance.
286 : : *
287 : : * This method must ONLY be called on the main thread QgsNetworkAccessManager. It is not
288 : : * necessary to set handlers for background threads -- the main thread QgsSslErrorHandler will
289 : : * automatically be used in a thread-safe manner for any SSL errors encountered on background threads.
290 : : *
291 : : * The default QgsSslErrorHandler responds to SSL errors only by logging the errors,
292 : : * and uses the default Qt response, which is to abort the request.
293 : : *
294 : : * \note Not available in Python bindings.
295 : : * \since QGIS 3.6
296 : : */
297 : : void setSslErrorHandler( std::unique_ptr< QgsSslErrorHandler > handler );
298 : :
299 : : /**
300 : : * Sets the application network authentication \a handler, which is used to respond to network
301 : : * authentication prompts during network requests.
302 : : *
303 : : * Ownership of \a handler is transferred to the main thread QgsNetworkAccessManager instance.
304 : : *
305 : : * This method must ONLY be called on the main thread QgsNetworkAccessManager. It is not
306 : : * necessary to set handlers for background threads -- the main thread QgsNetworkAuthenticationHandler will
307 : : * automatically be used in a thread-safe manner for any authentication requests encountered on background threads.
308 : : *
309 : : * The default QgsNetworkAuthenticationHandler responds to request only by logging the request,
310 : : * but does not provide any username or password resolution.
311 : : *
312 : : * \note Not available in Python bindings.
313 : : * \since QGIS 3.6
314 : : */
315 : : void setAuthHandler( std::unique_ptr< QgsNetworkAuthenticationHandler > handler );
316 : : #endif
317 : :
318 : : /**
319 : : * Inserts a \a factory into the proxy factories list.
320 : : *
321 : : * Ownership of \a factory is transferred to the manager.
322 : : *
323 : : * \see removeProxyFactory()
324 : : * \see proxyFactories()
325 : : */
326 : : void insertProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFER );
327 : :
328 : : /**
329 : : * Removes a \a factory from the proxy factories list.
330 : : *
331 : : * \see insertProxyFactory()
332 : : * \see proxyFactories()
333 : : */
334 : : void removeProxyFactory( QNetworkProxyFactory *factory SIP_TRANSFERBACK );
335 : :
336 : : /**
337 : : * Returns a list of proxy factories used by the manager.
338 : : *
339 : : * \see insertProxyFactory()
340 : : * \see proxyFactories()
341 : : */
342 : : const QList<QNetworkProxyFactory *> proxyFactories() const;
343 : :
344 : : /**
345 : : * Returns the fallback proxy used by the manager.
346 : : *
347 : : * The fallback proxy is used for URLs which no other proxy factory returned proxies for.
348 : : *
349 : : * \see proxyFactories()
350 : : * \see setFallbackProxyAndExcludes()
351 : : */
352 : : const QNetworkProxy &fallbackProxy() const;
353 : :
354 : : /**
355 : : * Returns the proxy exclude list.
356 : : *
357 : : * This list consists of the beginning of URL strings which will not use the fallback proxy.
358 : : *
359 : : * \see noProxyList()
360 : : * \see fallbackProxy()
361 : : * \see setFallbackProxyAndExcludes()
362 : : */
363 : : QStringList excludeList() const;
364 : :
365 : : /**
366 : : * Returns the no proxy list.
367 : : *
368 : : * This list consists of the beginning of URL strings which will not use any proxy at all
369 : : *
370 : : * \see excludeList()
371 : : * \see fallbackProxy()
372 : : * \see setFallbackProxyAndExcludes()
373 : : */
374 : : QStringList noProxyList() const;
375 : :
376 : : /**
377 : : * Sets the fallback \a proxy and URLs which shouldn't use it.
378 : : *
379 : : * The fallback proxy is used for URLs which no other proxy factory returned proxies for.
380 : : * The \a excludes list specifies the beginning of URL strings which will not use this fallback proxy.
381 : : * The \a noProxyURLs list specifies the beginning of URL strings which will not use any proxy at all
382 : : *
383 : : * \see fallbackProxy()
384 : : * \see excludeList()
385 : : * \see noProxyList()
386 : : */
387 : : void setFallbackProxyAndExcludes( const QNetworkProxy &proxy, const QStringList &excludes, const QStringList &noProxyURLs );
388 : :
389 : : /**
390 : : * Returns the name for QNetworkRequest::CacheLoadControl.
391 : : *
392 : : * \see cacheLoadControlFromName()
393 : : */
394 : : static QString cacheLoadControlName( QNetworkRequest::CacheLoadControl control );
395 : :
396 : : /**
397 : : * Returns QNetworkRequest::CacheLoadControl from a \a name.
398 : : *
399 : : * \see cacheLoadControlName()
400 : : */
401 : : static QNetworkRequest::CacheLoadControl cacheLoadControlFromName( const QString &name );
402 : :
403 : : /**
404 : : * Setup the QgsNetworkAccessManager (NAM) according to the user's settings.
405 : : * The \a connectionType sets up the default connection type that is used to
406 : : * handle signals that might require user interaction and therefore
407 : : * need to be handled on the main thread. See in-depth discussion in the documentation
408 : : * for the constructor of this class.
409 : : */
410 : : void setupDefaultProxyAndCache( Qt::ConnectionType connectionType = Qt::BlockingQueuedConnection );
411 : :
412 : : #ifndef SIP_RUN
413 : :
414 : : /**
415 : : * Returns TRUE if all network caching is disabled.
416 : : *
417 : : * \see setCacheDisabled()
418 : : * \note Not available in Python bindings.
419 : : * \since QGIS 3.18
420 : : */
421 : 3 : bool cacheDisabled() const { return mCacheDisabled; }
422 : :
423 : : /**
424 : : * Sets whether all network caching should be disabled.
425 : : *
426 : : * If \a disabled is TRUE then all caching will be disabled, causing all requests
427 : : * to be retrieved from the network regardless of the request's attributes.
428 : : *
429 : : * \see cacheDisabled()
430 : : * \note Not available in Python bindings.
431 : : * \since QGIS 3.18
432 : : */
433 : 3 : void setCacheDisabled( bool disabled ) { mCacheDisabled = disabled; }
434 : : #endif
435 : :
436 : : /**
437 : : * Returns whether the system proxy should be used.
438 : : */
439 : 0 : bool useSystemProxy() const { return mUseSystemProxy; }
440 : :
441 : : /**
442 : : * Returns the network timeout length, in milliseconds.
443 : : *
444 : : * \see setTimeout()
445 : : * \since QGIS 3.6
446 : : */
447 : : static int timeout();
448 : :
449 : : /**
450 : : * Sets the maximum timeout \a time for network requests, in milliseconds.
451 : : * If set to 0, no timeout is set.
452 : : *
453 : : * \see timeout()
454 : : * \since QGIS 3.6
455 : : */
456 : : static void setTimeout( int time );
457 : :
458 : : /**
459 : : * Posts a GET request to obtain the contents of the target request and returns a new QgsNetworkReplyContent object for reading.
460 : : * The current thread will be blocked until the request is returned.
461 : : *
462 : : * This method is safe to call in either the main thread or a worker thread.
463 : : *
464 : : * If \a forceRefresh is FALSE then previously cached replies may be used for the request. If
465 : : * it is set to TRUE then a new query is always performed.
466 : : *
467 : : * If an \a authCfg has been specified, then that authentication configuration required will automatically be applied to
468 : : * \a request. There is no need to manually apply the authentication to the request prior to calling
469 : : * this method.
470 : : *
471 : : * The optional \a feedback argument can be used to abort ongoing requests.
472 : : *
473 : : * The contents of the reply will be returned after the request is completed or an error occurs.
474 : : *
475 : : * \see blockingPost()
476 : : * \since QGIS 3.6
477 : : */
478 : : static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr );
479 : :
480 : : /**
481 : : * Posts a POST request to obtain the contents of the target \a request, using the given \a data, and returns a new
482 : : * QgsNetworkReplyContent object for reading. The current thread will be blocked until the request is returned.
483 : : *
484 : : * This method is safe to call in either the main thread or a worker thread.
485 : : *
486 : : * If \a forceRefresh is FALSE then previously cached replies may be used for the request. If
487 : : * it is set to TRUE then a new query is always performed.
488 : : *
489 : : * If an \a authCfg has been specified, then that authentication configuration required will automatically be applied to
490 : : * \a request. There is no need to manually apply the authentication to the request prior to calling
491 : : * this method.
492 : : *
493 : : * The optional \a feedback argument can be used to abort ongoing requests.
494 : : *
495 : : * The contents of the reply will be returned after the request is completed or an error occurs.
496 : : *
497 : : * \see blockingGet()
498 : : * \since QGIS 3.6
499 : : */
500 : : static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr );
501 : :
502 : : signals:
503 : :
504 : : /**
505 : : * \deprecated Use the thread-safe requestAboutToBeCreated( QgsNetworkRequestParameters ) signal instead.
506 : : */
507 : : Q_DECL_DEPRECATED void requestAboutToBeCreated( QNetworkAccessManager::Operation, const QNetworkRequest &, QIODevice * ) SIP_DEPRECATED;
508 : :
509 : : /**
510 : : * Emitted when a network request is about to be created.
511 : : *
512 : : * This signal is propagated to the main thread QgsNetworkAccessManager instance, so it is necessary
513 : : * only to connect to the main thread's signal in order to receive notifications about requests
514 : : * created in any thread.
515 : : *
516 : : * \see finished( QgsNetworkReplyContent )
517 : : * \see requestTimedOut( QgsNetworkRequestParameters )
518 : : * \since QGIS 3.6
519 : : */
520 : : void requestAboutToBeCreated( QgsNetworkRequestParameters request );
521 : :
522 : : /**
523 : : * Emitted whenever a pending network reply is finished.
524 : : *
525 : : * The \a reply parameter will contain a QgsNetworkReplyContent object, containing all the useful
526 : : * information relating to the reply, including headers and reply content.
527 : : *
528 : : * This signal is propagated to the main thread QgsNetworkAccessManager instance, so it is necessary
529 : : * only to connect to the main thread's signal in order to receive notifications about requests
530 : : * created in any thread.
531 : : *
532 : : * \see requestAboutToBeCreated( QgsNetworkRequestParameters )
533 : : * \see requestTimedOut( QgsNetworkRequestParameters )
534 : : * \since QGIS 3.6
535 : : */
536 : : void finished( QgsNetworkReplyContent reply );
537 : :
538 : : /**
539 : : * Emitted when a network request has timed out.
540 : : *
541 : : * This signal is propagated to the main thread QgsNetworkAccessManager instance, so it is necessary
542 : : * only to connect to the main thread's signal in order to receive notifications about requests
543 : : * created in any thread.
544 : : *
545 : : * \see requestAboutToBeCreated( QgsNetworkRequestParameters )
546 : : * \see finished( QgsNetworkReplyContent )
547 : : * \since QGIS 3.6
548 : : */
549 : : void requestTimedOut( QgsNetworkRequestParameters request );
550 : :
551 : : /**
552 : : * Emitted when a network reply receives a progress report.
553 : : *
554 : : * The \a requestId argument reflects the unique ID identifying the original request which the progress report relates to.
555 : : *
556 : : * The \a bytesReceived parameter indicates the number of bytes received, while \a bytesTotal indicates the total number
557 : : * of bytes expected to be downloaded. If the number of bytes to be downloaded is not known, \a bytesTotal will be -1.
558 : : *
559 : : * This signal is propagated to the main thread QgsNetworkAccessManager instance, so it is necessary
560 : : * only to connect to the main thread's signal in order to receive notifications about requests
561 : : * created in any thread.
562 : : *
563 : : * \since QGIS 3.6
564 : : */
565 : : void downloadProgress( int requestId, qint64 bytesReceived, qint64 bytesTotal );
566 : :
567 : : /**
568 : : * Emitted when a network request prompts an authentication request.
569 : : *
570 : : * The \a requestId argument reflects the unique ID identifying the original request which the authentication relates to.
571 : : *
572 : : * This signal is propagated to the main thread QgsNetworkAccessManager instance, so it is necessary
573 : : * only to connect to the main thread's signal in order to receive notifications about authentication requests
574 : : * from any thread.
575 : : *
576 : : * This signal is for debugging and logging purposes only, and cannot be used to respond to the
577 : : * requests. See QgsNetworkAuthenticationHandler for details on how to handle authentication requests.
578 : : *
579 : : * \see requestAuthDetailsAdded()
580 : : * \since QGIS 3.6
581 : : */
582 : : void requestRequiresAuth( int requestId, const QString &realm );
583 : :
584 : : /**
585 : : * Emitted when network authentication details have been added to a request.
586 : : *
587 : : * The \a requestId argument reflects the unique ID identifying the original request which the authentication relates to.
588 : : *
589 : : * This signal is always sent from the main thread QgsNetworkAccessManager instance, so it is necessary
590 : : * only to connect to the main thread's signal in order to receive notifications about authentication requests
591 : : * from any thread.
592 : : *
593 : : * This signal is for debugging and logging purposes only, and should not be used to respond to the
594 : : * requests. See QgsNetworkAuthenticationHandler for details on how to handle authentication requests.
595 : : *
596 : : * \see requestRequiresAuth()
597 : : * \since QGIS 3.6
598 : : */
599 : : void requestAuthDetailsAdded( int requestId, const QString &realm, const QString &user, const QString &password );
600 : :
601 : : #ifndef QT_NO_SSL
602 : :
603 : : /**
604 : : * Emitted when a network request encounters SSL \a errors.
605 : : *
606 : : * The \a requestId argument reflects the unique ID identifying the original request which the SSL error relates to.
607 : : *
608 : : * This signal is propagated to the main thread QgsNetworkAccessManager instance, so it is necessary
609 : : * only to connect to the main thread's signal in order to receive notifications about SSL errors
610 : : * from any thread.
611 : : *
612 : : * This signal is for debugging and logging purposes only, and cannot be used to respond to the errors.
613 : : * See QgsSslErrorHandler for details on how to handle SSL errors and potentially ignore them.
614 : : *
615 : : * \since QGIS 3.6
616 : : */
617 : : void requestEncounteredSslErrors( int requestId, const QList<QSslError> &errors );
618 : :
619 : : #ifndef SIP_RUN
620 : : ///@cond PRIVATE
621 : : // these signals are for internal use only - it's not safe to connect by external code
622 : : void sslErrorsOccurred( QNetworkReply *, const QList<QSslError> &errors );
623 : : void sslErrorsHandled( QNetworkReply *reply );
624 : : ///@endcond
625 : : #endif
626 : :
627 : : #endif
628 : :
629 : : /**
630 : : * \deprecated Use the thread-safe requestAboutToBeCreated( QgsNetworkRequestParameters ) signal instead.
631 : : */
632 : : Q_DECL_DEPRECATED void requestCreated( QNetworkReply * ) SIP_DEPRECATED;
633 : :
634 : : void requestTimedOut( QNetworkReply * );
635 : :
636 : : #ifndef SIP_RUN
637 : : ///@cond PRIVATE
638 : : // these signals are for internal use only - it's not safe to connect by external code
639 : : void authRequestOccurred( QNetworkReply *, QAuthenticator *auth );
640 : : void authRequestHandled( QNetworkReply *reply );
641 : : ///@endcond
642 : : #endif
643 : :
644 : :
645 : : private slots:
646 : : void abortRequest();
647 : :
648 : : void onReplyFinished( QNetworkReply *reply );
649 : :
650 : : void onReplyDownloadProgress( qint64 bytesReceived, qint64 bytesTotal );
651 : : #ifndef QT_NO_SSL
652 : : void onReplySslErrors( const QList<QSslError> &errors );
653 : :
654 : : void handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
655 : : #endif
656 : :
657 : : void onAuthRequired( QNetworkReply *reply, QAuthenticator *auth );
658 : : void handleAuthRequest( QNetworkReply *reply, QAuthenticator *auth );
659 : :
660 : : protected:
661 : : QNetworkReply *createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData = nullptr ) override;
662 : :
663 : : private:
664 : : #ifndef QT_NO_SSL
665 : : void unlockAfterSslErrorHandled();
666 : : void afterSslErrorHandled( QNetworkReply *reply );
667 : : #endif
668 : :
669 : : void unlockAfterAuthRequestHandled();
670 : : void afterAuthRequestHandled( QNetworkReply *reply );
671 : :
672 : : void pauseTimeout( QNetworkReply *reply );
673 : : void restartTimeout( QNetworkReply *reply );
674 : : static int getRequestId( QNetworkReply *reply );
675 : :
676 : : QList<QNetworkProxyFactory *> mProxyFactories;
677 : : QNetworkProxy mFallbackProxy;
678 : : QStringList mExcludedURLs;
679 : : QStringList mNoProxyURLs;
680 : : bool mUseSystemProxy = false;
681 : : bool mInitialized = false;
682 : : bool mCacheDisabled = false;
683 : : static QgsNetworkAccessManager *sMainNAM;
684 : : // ssl error handler, will be set for main thread ONLY
685 : : std::unique_ptr< QgsSslErrorHandler > mSslErrorHandler;
686 : : // only in use by worker threads, unused in main thread
687 : : QMutex mSslErrorHandlerMutex;
688 : : // only in use by worker threads, unused in main thread
689 : : QWaitCondition mSslErrorWaitCondition;
690 : :
691 : : // auth request handler, will be set for main thread ONLY
692 : : std::unique_ptr< QgsNetworkAuthenticationHandler > mAuthHandler;
693 : : // only in use by worker threads, unused in main thread
694 : : QMutex mAuthRequestHandlerMutex;
695 : : // only in use by worker threads, unused in main thread
696 : : QWaitCondition mAuthRequestWaitCondition;
697 : :
698 : : };
699 : :
700 : : #endif // QGSNETWORKACCESSMANAGER_H
|