Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qnetworkaccessbackend.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
11#include "QtCore/qmutex.h"
12#include "QtCore/qstringlist.h"
13
16#include "qhostinfo.h"
17
18#include "private/qnoncontiguousbytedevice_p.h"
19
20QT_BEGIN_NAMESPACE
21
22class QNetworkAccessBackendFactoryData: public QList<QNetworkAccessBackendFactory *>
23{
24public:
25 QNetworkAccessBackendFactoryData()
26 {
27 valid.ref();
28 }
29 ~QNetworkAccessBackendFactoryData()
30 {
31 QMutexLocker locker(&mutex); // why do we need to lock?
32 valid.deref();
33 }
34
35 QRecursiveMutex mutex;
36 //this is used to avoid (re)constructing factory data from destructors of other global classes
37 static QBasicAtomicInt valid;
38};
39Q_GLOBAL_STATIC(QNetworkAccessBackendFactoryData, factoryData)
40Q_CONSTINIT QBasicAtomicInt QNetworkAccessBackendFactoryData::valid = Q_BASIC_ATOMIC_INITIALIZER(0);
41
56
57QNetworkAccessBackend *
58QNetworkAccessManagerPrivate::findBackend(QNetworkAccessManager::Operation op,
59 const QNetworkRequest &request)
60{
61 if (QNetworkAccessBackendFactoryData::valid.loadRelaxed()) {
62 QMutexLocker locker(&factoryData()->mutex);
63 QNetworkAccessBackendFactoryData::ConstIterator it = factoryData()->constBegin(),
64 end = factoryData()->constEnd();
65 while (it != end) {
66 QNetworkAccessBackend *backend = (*it)->create(op, request);
67 if (backend) {
68 backend->setManagerPrivate(this);
69 return backend; // found a factory that handled our request
70 }
71 ++it;
72 }
73 }
74 return nullptr;
75}
76
78{
79 if (QNetworkAccessBackendFactoryData::valid.loadRelaxed()) {
80 QMutexLocker locker(&factoryData()->mutex);
81 QNetworkAccessBackendFactoryData::ConstIterator it = factoryData()->constBegin();
82 QNetworkAccessBackendFactoryData::ConstIterator end = factoryData()->constEnd();
83 QStringList schemes;
84 while (it != end) {
85 schemes += (*it)->supportedSchemes();
86 ++it;
87 }
88 return schemes;
89 }
90 return QStringList();
91}
92
93/*!
94 \class QNetworkAccessBackendFactory
95 \brief QNetworkAccessBackendFactory is the base class to inherit
96 from for Qt to instantiate and query your QNetworkAccessBackend
97 plugin.
98 \since 6.0
99 \internal
100
101//! [semi-private-notice]
102 The class is considered semi-private and as such requires linking
103 to "NetworkPrivate" to access the header. Furthermore it means
104 the class is not under the same binary compatibility restrictions
105 as the rest of Qt. While we still try to avoid breakage it may
106 still occur. The class is primarily meant to be used by plugins
107 which would be recompiled every time Qt is updated.
108//! [semi-private-notice]
109
110 This class acts as the primary interface to the plugin and must
111 be derived from. It deals with both querying supported schemes
112 and the creation of QNetworkAccessBackend
113
114 Since they are both abstract function you are required to
115 implement supportedSchemes() and create().
116*/
117
118/*!
119 \fn QStringList QNetworkAccessBackendFactory::supportedSchemes() const
120
121 Override this method in your own derived class to let Qt know
122 what schemes your class can handle.
123*/
124
125/*!
126 \fn QNetworkAccessBackendFactory::create(QNetworkAccessManager::Operation op, const QNetworkRequest &request) const
127
128 Override this method in your own class and return a
129 heap-allocated instance of your class derived from
130 QNetworkAccessBackend.
131
132 If \a op or a property of \a request is not supported (for
133 example the URL's scheme) then you must return \nullptr.
134
135 \sa QNetworkRequest::attribute(), QNetworkRequest::url(), QUrl::scheme()
136*/
137
138/*!
139 \class QNetworkAccessBackend
140 \brief QNetworkAccessBackend is the base class for implementing
141 support for schemes used by QNetworkAccessManager.
142 \since 6.0
143 \internal
144
145 \include access/qnetworkaccessbackend.cpp semi-private-notice
146
147 This class can be derived from to add support for further schemes
148 in QNetworkAccessManager.
149
150 The design of QNetworkAccessBackend makes it possible to specialize
151 behavior as needed for certain backends.
152 This was done using the (currently) 3 enums TargetType,
153 SecurityFeatures and IOFeatures. For example while only open()
154 and close() are abstract functions you are also required to
155 implement either read() or readPointer() and advanceReadPointer()
156 depending on whether you enable IOFeature::ZeroCopy or not.
157 Read more about it in the documentation for each of the
158 enumerators.
159
160 \sa TargetType, SecurityFeatures, IOFeatures
161*/
162
163/*!
164 \enum QNetworkAccessBackend::TargetType
165
166 Use the values in this enum to specify what type of target
167 the plugin supports. Setting the right type can be important,
168 for example: proxyList() is only available for a Networked
169 plugin.
170
171 \value Networked
172 The plugin supports and expect to connect to networked
173 resources. E.g. over TCP, UDP or similar.
174 \value Local
175 The plugin supports and expects to access local files,
176 generate data and/or locally connected devices.
177*/
178
179/*!
180 \enum QNetworkAccessBackend::SecurityFeature
181
182 Use the values in this enum to specify what type of security
183 features the plugin may utilize. Setting the right type(s)
184 can be important, for example: setSslConfiguration() may not
185 be called for any plugin that do not claim to support TLS.
186
187 \value None
188 No specific features are claimed to be supported.
189 \value TLS
190 The plugin supports and expects to use TLS.
191*/
192
193/*!
194 \enum QNetworkAccessBackend::IOFeature
195
196 Use the values in this enum to specify what type of IO
197 features the plugin may utilize.
198
199 \value None
200 No specific features are claimed to be supported.
201 \value ZeroCopy
202 The plugin will have raw data available in contiguous
203 segments and can return a pointer to the data at request.
204 Claiming to support this requires implementing readPointer()
205 and advanceReadPointer().
206 \value NeedResetableUpload
207 The plugin may encounter scenarios where data to upload that
208 has already been consumed needs to be restored and re-sent.
209 E.g. some data was consumed and sent before a redirect
210 response was received, and after the redirect the
211 previously-consumed data needs to be re-sent.
212 \omitvalue SupportsSynchronousMode
213*/
214
215/*!
216 Constructs the QNetworkAccessBackend.
217 You can opt in to specific backend behaviors with \a targetTypes,
218 \a securityFeatures and \a ioFeatures.
219 See their respective enums and values for more information.
220
221 \sa TargetType, SecurityFeature, IOFeature
222*/
223QNetworkAccessBackend::QNetworkAccessBackend(TargetTypes targetTypes,
224 SecurityFeatures securityFeatures,
225 IOFeatures ioFeatures)
226 : QObject(*(new QNetworkAccessBackendPrivate), nullptr)
227{
228 Q_D(QNetworkAccessBackend);
229 d->m_targetTypes = targetTypes;
230 d->m_securityFeatures = securityFeatures;
231 d->m_ioFeatures = ioFeatures;
232}
233
234/*!
235 \overload
236*/
237QNetworkAccessBackend::QNetworkAccessBackend(TargetTypes targetTypes)
238 : QNetworkAccessBackend(targetTypes, SecurityFeature::None, IOFeature::None)
239{
240}
241
242/*!
243 \overload
244*/
245QNetworkAccessBackend::QNetworkAccessBackend(TargetTypes targetTypes,
246 SecurityFeatures securityFeatures)
247 : QNetworkAccessBackend(targetTypes, securityFeatures, IOFeature::None)
248{
249}
250
251/*!
252 \overload
253*/
254QNetworkAccessBackend::QNetworkAccessBackend(TargetTypes targetTypes, IOFeatures ioFeatures)
255 : QNetworkAccessBackend(targetTypes, SecurityFeature::None, ioFeatures)
256{
257}
258
259/*!
260 Destructs the QNetworkAccessBackend base class.
261*/
262QNetworkAccessBackend::~QNetworkAccessBackend()
263{
264 delete d_func()->wrappedUploadByteDevice;
265}
266
267/*!
268 Returns the security related features that the backend claims to
269 support.
270
271 \sa SecurityFeature
272*/
273QNetworkAccessBackend::SecurityFeatures QNetworkAccessBackend::securityFeatures() const noexcept
274{
275 return d_func()->m_securityFeatures;
276}
277
278/*!
279 Returns the TargetTypes that the backend claims to target.
280
281 \sa TargetType
282*/
283QNetworkAccessBackend::TargetTypes QNetworkAccessBackend::targetTypes() const noexcept
284{
285 return d_func()->m_targetTypes;
286}
287
288/*!
289 Returns the I/O features that the backend claims to support.
290
291 \sa IOFeature
292*/
293QNetworkAccessBackend::IOFeatures QNetworkAccessBackend::ioFeatures() const noexcept
294{
295 return d_func()->m_ioFeatures;
296}
297
298/*!
299 Prepares the backend and calls open().
300 E.g. for TargetType::Networked it will prepare proxyList().
301
302 \sa TargetType, targetTypes
303*/
304bool QNetworkAccessBackend::start()
305{
306 Q_D(QNetworkAccessBackend);
307#ifndef QT_NO_NETWORKPROXY
308 if (targetTypes() & QNetworkAccessBackend::TargetType::Networked)
309 d->m_reply->proxyList = d->m_manager->queryProxy(QNetworkProxyQuery(url()));
310#endif
311
312 // now start the request
313 open();
314 return true;
315}
316
317/*!
318 \fn void QNetworkAccessBackend::open() = 0
319
320 You must implement this in your derived class.
321 During this call you must open the connection and begin the request
322 (see: request()).
323
324 As the connection progresses you must call the various public and
325 protected slots on QNetworkAccessBackend. As an example, when you have
326 received some data you must call readyRead(). And when all the data has been
327 received you must call finished(). This could, for example, be done by
328 binding signals inside your own implementation to the slots, or by calling
329 them directly.
330
331 \sa close()
332*/
333
334/*!
335 \fn void QNetworkAccessBackend::close() = 0
336
337 You must implement this function in your derived class.
338 This function gets called when the QNetworkReply is closed or aborted.
339
340 You should not emit an error or call finished() during this call since
341 QtNetwork will set and emit the \c{QNetworkReply::OperationCanceledError}
342 error by itself after control flow returns from this function.
343*/
344
345/*!
346 \fn qint64 QNetworkAccessBackend::bytesAvailable() const = 0
347
348 You must implement this function in your derived class.
349 This function is called at various times. It may be called because the user
350 called QNetworkReply::bytesAvailable(), and it may be called before an
351 attempt to read is made.
352
353 While this function doesn't technically need to return an accurate number,
354 it may result in reduced performance if it does not. This function must
355 return zero if there are no bytes available.
356*/
357
358#if QT_CONFIG(ssl)
359/*!
360 Passes a \a configuration with the user's desired TLS
361 configuration. If you don't have the TLS security feature this
362 may not be called.
363
364 \sa SecurityFeature, securityFeatures
365*/
366void QNetworkAccessBackend::setSslConfiguration(const QSslConfiguration &configuration)
367{
368 Q_UNUSED(configuration);
369 if (securityFeatures() & SecurityFeature::TLS) {
370 qWarning("Backend (%s) claiming to use TLS hasn't overridden setSslConfiguration.",
371 metaObject()->className());
372 }
373}
374
375/*!
376 Override this and return the QSslConfiguration used if you
377 have the TLS security feature
378
379 \sa SecurityFeature, securityFeatures
380*/
381QSslConfiguration QNetworkAccessBackend::sslConfiguration() const
382{
383 if (securityFeatures() & SecurityFeature::TLS) {
384 qWarning("Backend (%s) claiming to use TLS hasn't overridden sslConfiguration.",
385 metaObject()->className());
386 }
387 return {};
388}
389#endif
390
391/*!
392 This function will be called when the user wants to ignore
393 all TLS handshake errors. Derive this function if TLS is
394 supported.
395
396 \sa SecurityFeature, securityFeatures
397*/
398void QNetworkAccessBackend::ignoreSslErrors()
399{
400 if (securityFeatures() & SecurityFeature::TLS) {
401 qWarning("Backend (%s) claiming to use TLS hasn't overridden ignoreSslErrors.",
402 metaObject()->className());
403 }
404}
405
406/*!
407 This function will be called when the user wants to ignore
408 specific \a errors. Derive this function if TLS is supported.
409
410 \sa SecurityFeature, securityFeatures
411*/
412void QNetworkAccessBackend::ignoreSslErrors(const QList<QSslError> &errors)
413{
414 Q_UNUSED(errors);
415 if (securityFeatures() & SecurityFeature::TLS) {
416 qWarning("Backend (%s) claiming to use TLS hasn't overridden ignoreSslErrors.",
417 metaObject()->className());
418 }
419}
420
421/*!
422 The data which the returned value views must stay valid until
423 at least the next call to a non-const function. advanceReadPointer
424 will be called if any of the data was used.
425
426 Note: This will only be called if IOFeature::ZeroCopy was
427 specified in the call to the constructor.
428
429 \sa advanceReadPointer, read
430*/
431QByteArrayView QNetworkAccessBackend::readPointer()
432{
433 if (ioFeatures() & IOFeature::ZeroCopy) {
434 qWarning("Backend (%s) claiming to support ZeroCopy hasn't overridden readPointer.",
435 metaObject()->className());
436 }
437 return {};
438}
439
440/*!
441 This function is to notify your class that \a distance
442 bytes have been read using readPointer and next time
443 readPointer() is called those bytes should not be included.
444
445 Note: This will only be called if IOFeature::ZeroCopy was
446 specified in the call to the constructor.
447
448 \sa readPointer
449*/
450void QNetworkAccessBackend::advanceReadPointer(qint64 distance)
451{
452 Q_UNUSED(distance);
453 if (ioFeatures() & IOFeature::ZeroCopy) {
454 qWarning("Backend (%s) claiming to support ZeroCopy hasn't overridden advanceReadPointer.",
455 metaObject()->className());
456 }
457}
458
459/*!
460 Implement this function to support reading from the resource
461 made available by your plugin.
462 Store data in \a data, up to a maximum of \a maxlen bytes.
463 Then return the total amount of bytes that was copied.
464
465 \sa readPointer, wantToRead
466*/
467qint64 QNetworkAccessBackend::read(char *data, qint64 maxlen)
468{
469 Q_UNUSED(data);
470 Q_UNUSED(maxlen);
471 if ((ioFeatures() & IOFeature::ZeroCopy) == 0) {
472 qWarning("Backend (%s) is not ZeroCopy and has not implemented read(...)!",
473 metaObject()->className());
474 }
475 return 0;
476}
477
478/*!
479 This is called before we read if there are no bytes available
480 and we are ready to read more. Return \c true if new data was
481 made available.
482
483 \sa read, readPointer
484*/
485bool QNetworkAccessBackend::wantToRead()
486{
487 // Base implementation does nothing
488 return false;
489}
490
491#if QT_CONFIG(networkproxy)
492/*!
493 Returns a list of proxies configured for the URL returned by
494 url().
495
496 It is only valid to call this function if TargetType::Networked
497 was specified in the call to the constructor.
498*/
499QList<QNetworkProxy> QNetworkAccessBackend::proxyList() const
500{
501 Q_ASSERT(targetTypes() & TargetType::Networked);
502 return d_func()->m_reply->proxyList;
503}
504#endif
505
506/*!
507 Returns the current URL of the reply
508*/
509QUrl QNetworkAccessBackend::url() const
510{
511 return d_func()->m_reply->url;
512}
513
514/*!
515 Sets the URL of the reply. This could e.g. be needed if a
516 redirect or similar was performed.
517*/
518void QNetworkAccessBackend::setUrl(const QUrl &url)
519{
520 d_func()->m_reply->url = url;
521}
522
523/*!
524 Returns the value of the \a header.
525 If no such header was known it returns a default-constructed
526 QVariant.
527
528 \sa setHeader, rawHeader, setRawHeader
529*/
530QVariant QNetworkAccessBackend::header(QNetworkRequest::KnownHeaders header) const
531{
532 return d_func()->m_reply->cookedHeaders.value(header);
533}
534
535/*!
536 Sets the value of the \a header to \a value.
537 This can be queried on the QNetworkReply instance which was
538 returned when calling one of the appropriate functions on
539 QNetworkAccessManager.
540
541 \sa header, rawHeader, setRawHeader
542*/
543void QNetworkAccessBackend::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
544{
545 d_func()->m_reply->setCookedHeader(header, value);
546}
547
548/*!
549 Returns the value of the \a header.
550 If no such header was known it returns a default-constructed
551 QVariant.
552
553 \sa setHeader, rawHeader, setRawHeader
554*/
555QByteArray QNetworkAccessBackend::rawHeader(const QByteArray &header) const
556{
557 return d_func()->m_reply->q_func()->rawHeader(header);
558}
559
560/*!
561 Sets the value of the \a header to \a value.
562
563 This value is accessible on the QNetworkReply instance which was
564 returned when calling one of the appropriate functions on
565 QNetworkAccessManager.
566
567 \sa header, rawHeader, setRawHeader
568*/
569void QNetworkAccessBackend::setRawHeader(const QByteArray &header, const QByteArray &value)
570{
571 d_func()->m_reply->setRawHeader(header, value);
572}
573
574/*!
575 \since 6.8
576
577 Returns headers that are set in this QNetworkAccessBackend instance.
578
579 \sa setHeaders()
580*/
581QHttpHeaders QNetworkAccessBackend::headers() const
582{
583 return d_func()->m_reply->headers();
584}
585
586/*!
587 \since 6.8
588
589 Sets \a newHeaders as headers, overriding any previously set headers.
590
591 These headers are accessible on the QNetworkReply instance which was
592 returned when calling one of the appropriate functions on
593 QNetworkAccessManager.
594
595 \sa headers()
596*/
597void QNetworkAccessBackend::setHeaders(QHttpHeaders &&newHeaders)
598{
599 d_func()->m_reply->setHeaders(std::move(newHeaders));
600}
601
602/*!
603 \overload
604 \since 6.8
605*/
606void QNetworkAccessBackend::setHeaders(const QHttpHeaders &newHeaders)
607{
608 d_func()->m_reply->setHeaders(newHeaders);
609}
610
611/*!
612 Returns the operation which was requested when calling
613 QNetworkAccessManager.
614*/
615QNetworkAccessManager::Operation QNetworkAccessBackend::operation() const
616{
617 return d_func()->m_reply->operation;
618}
619
620/*!
621 Returns \c true if setCachingEnabled was previously called with \c true.
622 Returns \c false otherwise, which is the default value.
623
624 \sa setCachingEnabled
625*/
626bool QNetworkAccessBackend::isCachingEnabled() const
627{
628 return d_func()->m_canCache;
629}
630
631/*!
632 If \a canCache is \c true then this hints to us that we can cache
633 the reply that is created.
634
635 \sa isCachingEnabled
636*/
637void QNetworkAccessBackend::setCachingEnabled(bool canCache)
638{
639 d_func()->m_canCache = canCache;
640}
641
642/*!
643 Set \a attribute to \a value. If \c{value.isValid()} returns
644 \c false then the attribute is unset.
645
646 This value is accessible on the QNetworkReply instance which was
647 returned when calling one of the appropriate functions on
648 QNetworkAccessManager.
649*/
650void QNetworkAccessBackend::setAttribute(QNetworkRequest::Attribute attribute,
651 const QVariant &value)
652{
653 Q_D(QNetworkAccessBackend);
654 if (value.isValid())
655 d->m_reply->attributes.insert(attribute, value);
656 else
657 d->m_reply->attributes.remove(attribute);
658}
659
660/*!
661 Creates a QIODevice for the data provided to upload, if any.
662
663 Emission of upload progress is handled internally as the device
664 gets read from.
665
666 Returns a pointer to a device with data or nullptr if there was
667 no data to upload.
668*/
669QIODevice *QNetworkAccessBackend::createUploadByteDevice()
670{
671 Q_D(QNetworkAccessBackend);
672
673 if (d->m_reply->outgoingDataBuffer)
674 d->uploadByteDevice =
675 QNonContiguousByteDeviceFactory::createShared(d->m_reply->outgoingDataBuffer);
676 else if (d->m_reply->outgoingData) {
677 d->uploadByteDevice =
678 QNonContiguousByteDeviceFactory::createShared(d->m_reply->outgoingData);
679 } else {
680 return nullptr;
681 }
682
683 // We want signal emissions only for normal asynchronous uploads
684 if (!isSynchronous()) {
685 connect(d->uploadByteDevice.get(), &QNonContiguousByteDevice::readProgress, this,
686 [this](qint64 a, qint64 b) {
687 Q_D(QNetworkAccessBackend);
688 if (!d->m_reply->isFinished)
689 d->m_reply->emitUploadProgress(a, b);
690 });
691 }
692
693 d->wrappedUploadByteDevice = QNonContiguousByteDeviceFactory::wrap(d->uploadByteDevice.get());
694 return d->wrappedUploadByteDevice;
695}
696
697/*!
698 Returns the upload byte device associated with the current
699 request. This does not create the request but simply returns
700 the pointer stored in this base class so it doesn't need to be
701 stored in the subclass too.
702*/
703QIODevice *QNetworkAccessBackend::uploadByteDevice()
704{
705 return d_func()->wrappedUploadByteDevice;
706}
707
708/*!
709 \internal
710 Returns \c true if synchronous mode is enabled.
711 If it is disabled or not supported it will return \c {false}.
712*/
713bool QNetworkAccessBackend::isSynchronous() const
714{
715 return d_func()->m_isSynchronous;
716}
717
718/*!
719 \internal
720 Enables or disables synchronous mode depending on \a synchronous
721 if the backend supports it. Otherwise it will always be disabled.
722*/
723void QNetworkAccessBackend::setSynchronous(bool synchronous)
724{
725 if ((ioFeatures() & IOFeature::SupportsSynchronousMode) == 0)
726 return;
727 d_func()->m_isSynchronous = synchronous;
728}
729
730/*!
731 Call this slot when you have more data available to notify
732 the backend that we can attempt to read again.
733*/
734void QNetworkAccessBackend::readyRead()
735{
736 d_func()->m_reply->backendNotify(QNetworkReplyImplPrivate::NotifyDownstreamReadyWrite);
737}
738
739/*!
740 Call this slot when there will be no more data available,
741 regardless of whether the transfer was successful or unsuccessful.
742 For unsuccessful transfers make sure to call error() first!
743*/
744void QNetworkAccessBackend::finished()
745{
746 d_func()->m_reply->finished();
747}
748
749/*!
750 Call this slot if an error occurs. An error would be something
751 you cannot recover from (e.g. the file requested is missing).
752 The \a code and \a errorString is transferred to and stored in
753 the QNetworkReply and the \a code is emitted through the
754 QNetworkReply::errorOccurred() signal.
755*/
756void QNetworkAccessBackend::error(QNetworkReply::NetworkError code, const QString &errorString)
757{
758 Q_ASSERT(!d_func()->m_reply->isFinished);
759 d_func()->m_reply->error(code, errorString);
760}
761
762#ifndef QT_NO_NETWORKPROXY
763/*!
764 Call this slot if, when connecting through a proxy, it requests
765 authentication. This may cause the
766 QNetworkAccessManager::proxyAuthenticationRequired() signal to be
767 emitted if the credentials are not already stored in an internal
768 cache.
769 To be able to make the lookup in the cache and potentially the
770 subsequent request the \a proxy needs to be known. The credentials
771 will be stored in \a authenticator. While \a authenticator is a
772 pointer, passing \c nullptr is invalid.
773*/
774void QNetworkAccessBackend::proxyAuthenticationRequired(const QNetworkProxy &proxy,
775 QAuthenticator *authenticator)
776{
777 Q_D(QNetworkAccessBackend);
778 Q_ASSERT(authenticator);
779 d->m_manager->proxyAuthenticationRequired(QUrl(), proxy, isSynchronous(), authenticator,
780 &d->m_reply->lastProxyAuthentication);
781}
782#endif
783
784/*!
785 Call this slot if the remote resource requests authentication.
786 This may cause the
787 QNetworkAccessManager::authenticationRequired() signal to be
788 emitted if the credentials are not already stored in an internal
789 cache.
790 The credentials will be stored in \a authenticator. While
791 \a authenticator is a pointer, passing \c nullptr is invalid.
792*/
793void QNetworkAccessBackend::authenticationRequired(QAuthenticator *authenticator)
794{
795 Q_D(QNetworkAccessBackend);
796 Q_ASSERT(authenticator);
797 d->m_manager->authenticationRequired(authenticator, d->m_reply->q_func(), isSynchronous(),
798 d->m_reply->url, &d->m_reply->urlForLastAuthentication);
799}
800
801/*!
802 Call this slot, if appropriate, after having processed and
803 updated metadata (e.g. headers).
804*/
805void QNetworkAccessBackend::metaDataChanged()
806{
807 d_func()->m_reply->metaDataChanged();
808}
809
810/*!
811 Call this slot if, when connecting to the resource, a redirect
812 to \a destination was requested.
813*/
814void QNetworkAccessBackend::redirectionRequested(const QUrl &destination)
815{
816 d_func()->m_reply->redirectionRequested(destination);
817}
818
819/*!
820 \internal
821*/
822void QNetworkAccessBackend::setReplyPrivate(QNetworkReplyImplPrivate *reply)
823{
824 d_func()->m_reply = reply;
825}
826
827/*!
828 \internal
829*/
830void QNetworkAccessBackend::setManagerPrivate(QNetworkAccessManagerPrivate *manager)
831{
832 d_func()->m_manager = manager;
833}
834
835/*!
836 Returns the network cache object that was available when the
837 request was started. Returns \c nullptr if none was available.
838*/
839QAbstractNetworkCache *QNetworkAccessBackend::networkCache() const
840{
841 return d_func()->m_manager->networkCache;
842}
843
844// -- QNetworkAccessBackendFactory
845/*!
846 Constructs QNetworkAccessBackendFactory
847*/
848QNetworkAccessBackendFactory::QNetworkAccessBackendFactory()
849{
850 if (factoryData())
851 factoryData->append(this);
852}
853
854/*!
855 Destructs QNetworkAccessBackendFactory
856*/
857QNetworkAccessBackendFactory::~QNetworkAccessBackendFactory()
858{
859 if (factoryData.exists())
860 factoryData->removeAll(this);
861};
862
863QT_END_NAMESPACE
864
865#include "moc_qnetworkaccessbackend_p.cpp"
QNetworkReplyImplPrivate * m_reply
QNetworkAccessBackend::SecurityFeatures m_securityFeatures
QNetworkAccessBackend::IOFeatures m_ioFeatures
QNetworkAccessManagerPrivate * m_manager
std::shared_ptr< QNonContiguousByteDevice > uploadByteDevice
QNetworkAccessBackend::TargetTypes m_targetTypes
QStringList backendSupportedSchemes() const
QNetworkAccessBackend * findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request)