5#include <QtNetwork/private/qtnetworkglobal_p.h>
18#if QT_CONFIG(settings)
19#include "qhstsstore_p.h"
31#include "QtCore/qbuffer.h"
32#include "QtCore/qlist.h"
33#include "QtCore/qurl.h"
34#include "QtNetwork/private/qauthenticator_p.h"
35#include "QtNetwork/qsslconfiguration.h"
38#include "QtNetwork/private/http2protocol_p.h"
39#include "qhttpmultipart.h"
40#include "qhttpmultipart_p.h"
41#include "qnetworkreplyhttpimpl_p.h"
48#include "QtCore/qapplicationstatic.h"
49#include "QtCore/qloggingcategory.h"
50#include <QtCore/private/qfactoryloader_p.h>
52#if defined(Q_OS_MACOS)
53#include <QtCore/private/qcore_mac_p.h>
55#include <CoreServices/CoreServices.h>
56#include <SystemConfiguration/SystemConfiguration.h>
57#include <Security/Security.h>
60#include "qnetworkreplywasmimpl_p.h"
61#include "qhttpmultipart.h"
62#include "qhttpmultipart_p.h"
70using namespace Qt::StringLiterals;
71using namespace std::chrono_literals;
73#if defined(Q_OS_MACOS)
74Q_STATIC_LOGGING_CATEGORY(lcQnam,
"qt.network.access.manager")
77Q_APPLICATION_STATIC(QNetworkAccessFileBackendFactory, fileBackend)
79#if QT_CONFIG(private_tests)
80Q_GLOBAL_STATIC(QNetworkAccessDebugPipeBackendFactory, debugpipeBackend)
85#if defined(Q_OS_MACOS)
86bool getProxyAuth(
const QString& proxyHostname,
const QString &scheme, QString& username, QString& password)
88 CFStringRef protocolType =
nullptr;
89 if (scheme.compare(
"ftp"_L1, Qt::CaseInsensitive) == 0) {
90 protocolType = kSecAttrProtocolFTPProxy;
91 }
else if (scheme.compare(
"http"_L1, Qt::CaseInsensitive) == 0
92 || scheme.compare(
"preconnect-http"_L1, Qt::CaseInsensitive) == 0) {
93 protocolType = kSecAttrProtocolHTTPProxy;
94 }
else if (scheme.compare(
"https"_L1,Qt::CaseInsensitive)==0
95 || scheme.compare(
"preconnect-https"_L1, Qt::CaseInsensitive) == 0) {
96 protocolType = kSecAttrProtocolHTTPSProxy;
98 qCWarning(lcQnam) <<
"Cannot query user name and password for a proxy, unnknown protocol:"
103 QCFType<CFMutableDictionaryRef> query(CFDictionaryCreateMutable(kCFAllocatorDefault,
104 0,
nullptr,
nullptr));
107 CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword);
108 CFDictionaryAddValue(query, kSecAttrProtocol, protocolType);
110 QCFType<CFStringRef> serverName;
111 if (proxyHostname.size()) {
112 serverName = proxyHostname.toCFString();
113 CFDictionaryAddValue(query, kSecAttrServer, serverName);
117 CFDictionaryAddValue(query, kSecReturnAttributes, kCFBooleanTrue);
119 CFDictionaryAddValue(query, kSecReturnData, kCFBooleanTrue);
124 QCFType<CFTypeRef> replyData;
125 if (SecItemCopyMatching(query, &replyData) != errSecSuccess) {
126 qCWarning(lcQnam,
"Failed to extract user name and password from the keychain.");
130 if (!replyData || CFDictionaryGetTypeID() != CFGetTypeID(replyData)) {
131 qCWarning(lcQnam,
"Query returned data in unexpected format.");
135 CFDictionaryRef accountData = replyData.as<CFDictionaryRef>();
136 const void *value = CFDictionaryGetValue(accountData, kSecAttrAccount);
137 if (!value || CFGetTypeID(value) != CFStringGetTypeID()) {
138 qCWarning(lcQnam,
"Cannot find user name or its format is unknown.");
141 username = QString::fromCFString(
static_cast<CFStringRef>(value));
143 value = CFDictionaryGetValue(accountData, kSecValueData);
144 if (!value || CFGetTypeID(value) != CFDataGetTypeID()) {
145 qCWarning(lcQnam,
"Cannot find password or its format is unknown.");
148 const CFDataRef passData =
static_cast<
const CFDataRef>(value);
149 password = QString::fromLocal8Bit(
reinterpret_cast<
const char *>(CFDataGetBytePtr(passData)),
150 qsizetype(CFDataGetLength(passData)));
157static void ensureInitialized()
159#if QT_CONFIG(private_tests)
160 (
void) debugpipeBackend();
164 (
void) fileBackend();
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
264
265
266
267
268
269
270
271
272
273
274
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
413
414
415
416QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
417 : QObject(*
new QNetworkAccessManagerPrivate, parent)
420 d_func()->ensureBackendPluginsLoaded();
422 qRegisterMetaType<QNetworkReply::NetworkError>();
423#ifndef QT_NO_NETWORKPROXY
424 qRegisterMetaType<QNetworkProxy>();
427 qRegisterMetaType<QList<QSslError> >();
428 qRegisterMetaType<QSslConfiguration>();
429 qRegisterMetaType<QSslPreSharedKeyAuthenticator *>();
431 qRegisterMetaType<QList<std::pair<QByteArray, QByteArray>>>();
433 qRegisterMetaType<QHttpNetworkRequest>();
435 qRegisterMetaType<QNetworkReply::NetworkError>();
436 qRegisterMetaType<QSharedPointer<
char> >();
440
441
442
443
444
445
446QNetworkAccessManager::~QNetworkAccessManager()
448#ifndef QT_NO_NETWORKPROXY
449 delete d_func()->proxyFactory;
456 qDeleteAll(findChildren<QNetworkReply *>());
462#ifndef QT_NO_NETWORKPROXY
464
465
466
467
468
469
470QNetworkProxy QNetworkAccessManager::proxy()
const
472 return d_func()->proxy;
476
477
478
479
480
481
482
483
484
485
486
487
488
489void QNetworkAccessManager::setProxy(
const QNetworkProxy &proxy)
491 Q_D(QNetworkAccessManager);
492 delete d->proxyFactory;
494 d->proxyFactory =
nullptr;
498
499
500
501
502
503
504
505
506
507
508
509QNetworkProxyFactory *QNetworkAccessManager::proxyFactory()
const
511 return d_func()->proxyFactory;
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543void QNetworkAccessManager::setProxyFactory(QNetworkProxyFactory *factory)
545 Q_D(QNetworkAccessManager);
546 delete d->proxyFactory;
547 d->proxyFactory = factory;
548 d->proxy = QNetworkProxy();
553
554
555
556
557
558
559QAbstractNetworkCache *QNetworkAccessManager::cache()
const
561 Q_D(
const QNetworkAccessManager);
562 return d->networkCache;
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581void QNetworkAccessManager::setCache(QAbstractNetworkCache *cache)
583 Q_D(QNetworkAccessManager);
584 if (d->networkCache != cache) {
585 delete d->networkCache;
586 d->networkCache = cache;
588 d->networkCache->setParent(
this);
593
594
595
596
597
598
599QNetworkCookieJar *QNetworkAccessManager::cookieJar()
const
601 Q_D(
const QNetworkAccessManager);
603 d->createCookieJar();
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636void QNetworkAccessManager::setCookieJar(QNetworkCookieJar *cookieJar)
638 Q_D(QNetworkAccessManager);
639 d->cookieJarCreated =
true;
640 if (d->cookieJar != cookieJar) {
641 if (d->cookieJar && d->cookieJar->parent() ==
this)
643 d->cookieJar = cookieJar;
644 if (cookieJar && thread() == cookieJar->thread())
645 d->cookieJar->setParent(
this);
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664void QNetworkAccessManager::setStrictTransportSecurityEnabled(
bool enabled)
666 Q_D(QNetworkAccessManager);
667 d->stsEnabled = enabled;
671
672
673
674
675
676
677
678bool QNetworkAccessManager::isStrictTransportSecurityEnabled()
const
680 Q_D(
const QNetworkAccessManager);
681 return d->stsEnabled;
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
704void QNetworkAccessManager::enableStrictTransportSecurityStore(
bool enabled,
const QString &storeDir)
706#if QT_CONFIG(settings)
707 Q_D(QNetworkAccessManager);
708 d->stsStore.reset(enabled ?
new QHstsStore(storeDir) :
nullptr);
709 d->stsCache.setStore(d->stsStore.get());
713 qWarning(
"HSTS permanent store requires the feature 'settings' enabled");
718
719
720
721
722
723
724
726bool QNetworkAccessManager::isStrictTransportSecurityStoreEnabled()
const
728#if QT_CONFIG(settings)
729 Q_D(
const QNetworkAccessManager);
730 return bool(d->stsStore);
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
756void QNetworkAccessManager::addStrictTransportSecurityHosts(
const QList<QHstsPolicy> &knownHosts)
758 Q_D(QNetworkAccessManager);
759 d->stsCache.updateFromPolicies(knownHosts);
763
764
765
766
767
768
769
770
771QList<QHstsPolicy> QNetworkAccessManager::strictTransportSecurityHosts()
const
773 Q_D(
const QNetworkAccessManager);
774 return d->stsCache.policies();
778
779
780
781
782
783QNetworkReply *QNetworkAccessManager::head(
const QNetworkRequest &request)
785 return d_func()->postProcess(createRequest(QNetworkAccessManager::HeadOperation, request));
789
790
791
792
793
794
795
796
797
798QNetworkReply *QNetworkAccessManager::get(
const QNetworkRequest &request)
800 return d_func()->postProcess(createRequest(QNetworkAccessManager::GetOperation, request));
804
805
806
807
808
809
810
811
812
814QNetworkReply *QNetworkAccessManager::get(
const QNetworkRequest &request, QIODevice *data)
816 QNetworkRequest newRequest(request);
817 return d_func()->postProcess(
818 createRequest(QNetworkAccessManager::GetOperation, newRequest, data));
822
823
824
825
826
827
828
829
830
832QNetworkReply *QNetworkAccessManager::get(
const QNetworkRequest &request,
const QByteArray &data)
834 QBuffer *buffer =
new QBuffer;
835 buffer->setData(data);
836 buffer->open(QIODevice::ReadOnly);
838 QNetworkReply *reply = get(request, buffer);
839 buffer->setParent(reply);
844
845
846
847
848
849
850
851
852
853
854
855
856
857QNetworkReply *QNetworkAccessManager::post(
const QNetworkRequest &request, QIODevice *data)
859 return d_func()->postProcess(createRequest(QNetworkAccessManager::PostOperation, request, data));
863
864
865
866
867
868QNetworkReply *QNetworkAccessManager::post(
const QNetworkRequest &request,
const QByteArray &data)
870 QBuffer *buffer =
new QBuffer;
871 buffer->setData(data);
872 buffer->open(QIODevice::ReadOnly);
874 QNetworkReply *reply = post(request, buffer);
875 buffer->setParent(reply);
880
881
882
883
884
885
886
887
888
890#if QT_CONFIG(http) || defined(Q_OS_WASM)
892
893
894
895
896
897
898
899
900
901
902
903QNetworkReply *QNetworkAccessManager::post(
const QNetworkRequest &request, QHttpMultiPart *multiPart)
905 QNetworkRequest newRequest = d_func()->prepareMultipart(request, multiPart);
906 QIODevice *device = multiPart->d_func()->device;
907 QNetworkReply *reply = post(newRequest, device);
912
913
914
915
916
917
918
919
920
921
922
923QNetworkReply *QNetworkAccessManager::put(
const QNetworkRequest &request, QHttpMultiPart *multiPart)
925 QNetworkRequest newRequest = d_func()->prepareMultipart(request, multiPart);
926 QIODevice *device = multiPart->d_func()->device;
927 QNetworkReply *reply = put(newRequest, device);
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951QNetworkReply *QNetworkAccessManager::put(
const QNetworkRequest &request, QIODevice *data)
953 return d_func()->postProcess(createRequest(QNetworkAccessManager::PutOperation, request, data));
957
958
959
960
961
962QNetworkReply *QNetworkAccessManager::put(
const QNetworkRequest &request,
const QByteArray &data)
964 QBuffer *buffer =
new QBuffer;
965 buffer->setData(data);
966 buffer->open(QIODevice::ReadOnly);
968 QNetworkReply *reply = put(request, buffer);
969 buffer->setParent(reply);
974
975
976
977
978
979
980
981
982
985
986
987
988
989
990
991
992
993
994QNetworkReply *QNetworkAccessManager::deleteResource(
const QNetworkRequest &request)
996 return d_func()->postProcess(createRequest(QNetworkAccessManager::DeleteOperation, request));
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1018void QNetworkAccessManager::connectToHostEncrypted(
const QString &hostName, quint16 port,
1019 const QSslConfiguration &sslConfiguration)
1021 connectToHostEncrypted(hostName, port, sslConfiguration, QString());
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1044void QNetworkAccessManager::connectToHostEncrypted(
const QString &hostName, quint16 port,
1045 const QSslConfiguration &sslConfiguration,
1046 const QString &peerName)
1049 url.setHost(hostName);
1051 url.setScheme(
"preconnect-https"_L1);
1052 QNetworkRequest request(url);
1053 if (sslConfiguration != QSslConfiguration::defaultConfiguration())
1054 request.setSslConfiguration(sslConfiguration);
1058 if (!sslConfiguration.allowedNextProtocols().contains(QSslConfiguration::ALPNProtocolHTTP2))
1059 request.setAttribute(QNetworkRequest::Http2AllowedAttribute,
false);
1061 request.setPeerVerifyName(peerName);
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077void QNetworkAccessManager::connectToHost(
const QString &hostName, quint16 port)
1080 url.setHost(hostName);
1082 url.setScheme(
"preconnect-http"_L1);
1083 QNetworkRequest request(url);
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104void QNetworkAccessManager::setRedirectPolicy(QNetworkRequest::RedirectPolicy policy)
1106 Q_D(QNetworkAccessManager);
1107 d->redirectPolicy = policy;
1111
1112
1113
1114
1115
1116
1117QNetworkRequest::RedirectPolicy QNetworkAccessManager::redirectPolicy()
const
1119 Q_D(
const QNetworkAccessManager);
1120 return d->redirectPolicy;
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142QNetworkReply *QNetworkAccessManager::sendCustomRequest(
const QNetworkRequest &request,
const QByteArray &verb, QIODevice *data)
1144 QNetworkRequest newRequest(request);
1145 newRequest.setAttribute(QNetworkRequest::CustomVerbAttribute, verb);
1146 return d_func()->postProcess(createRequest(QNetworkAccessManager::CustomOperation, newRequest, data));
1150
1151
1152
1153
1154
1155
1156
1157QNetworkReply *QNetworkAccessManager::sendCustomRequest(
const QNetworkRequest &request,
const QByteArray &verb,
const QByteArray &data)
1159 QBuffer *buffer =
new QBuffer;
1160 buffer->setData(data);
1161 buffer->open(QIODevice::ReadOnly);
1163 QNetworkReply *reply = sendCustomRequest(request, verb, buffer);
1164 buffer->setParent(reply);
1168#if QT_CONFIG(http) || defined(Q_OS_WASM)
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183QNetworkReply *QNetworkAccessManager::sendCustomRequest(
const QNetworkRequest &request,
const QByteArray &verb, QHttpMultiPart *multiPart)
1185 QNetworkRequest newRequest = d_func()->prepareMultipart(request, multiPart);
1186 QIODevice *device = multiPart->d_func()->device;
1187 QNetworkReply *reply = sendCustomRequest(newRequest, verb, device);
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op,
1206 const QNetworkRequest &originalReq,
1207 QIODevice *outgoingData)
1209 Q_D(QNetworkAccessManager);
1211 QNetworkRequest req(originalReq);
1212 if (redirectPolicy() != QNetworkRequest::NoLessSafeRedirectPolicy
1213 && req.attribute(QNetworkRequest::RedirectPolicyAttribute).isNull()) {
1214 req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, redirectPolicy());
1217#if QT_CONFIG(http) || defined (Q_OS_WASM)
1218 if (req.transferTimeoutAsDuration() == 0ms)
1219 req.setTransferTimeout(transferTimeoutAsDuration());
1222 if (autoDeleteReplies()
1223 && req.attribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute).isNull()) {
1224 req.setAttribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute,
true);
1227 bool isLocalFile = req.url().isLocalFile();
1228 QString scheme = req.url().scheme();
1231 if (scheme ==
"local+http"_L1) {
1232 scheme = u"unix+http"_s;
1233 QUrl url = req.url();
1234 url.setScheme(scheme);
1240 if (op == QNetworkAccessManager::GetOperation
1241 || op == QNetworkAccessManager::HeadOperation) {
1244 || scheme ==
"assets"_L1
1246 || scheme ==
"qrc"_L1) {
1247 return new QNetworkReplyFileImpl(
this, req, op);
1250 if (scheme ==
"data"_L1)
1251 return new QNetworkReplyDataImpl(
this, req, op);
1254 QNetworkRequest::CacheLoadControl mode =
1255 static_cast<QNetworkRequest::CacheLoadControl>(
1256 req.attribute(QNetworkRequest::CacheLoadControlAttribute,
1257 QNetworkRequest::PreferNetwork).toInt());
1258 if (mode == QNetworkRequest::AlwaysCache) {
1260 QNetworkReplyImpl *reply =
new QNetworkReplyImpl(
this);
1261 QNetworkReplyImplPrivate *priv = reply->d_func();
1262 priv->manager =
this;
1263 priv->backend =
new QNetworkAccessCacheBackend();
1264 priv->backend->setManagerPrivate(
this->d_func());
1265 priv->backend->setParent(reply);
1266 priv->backend->setReplyPrivate(priv);
1267 priv->setup(op, req, outgoingData);
1271 QNetworkRequest request = req;
1272 auto h = request.headers();
1274 if (!h.contains(QHttpHeaders::WellKnownHeader::ContentLength) &&
1275 outgoingData && !outgoingData->isSequential() && outgoingData->size()) {
1278 h.append(QHttpHeaders::WellKnownHeader::ContentLength,
1279 QByteArray::number(outgoingData->size()));
1282 if (
static_cast<QNetworkRequest::LoadControl>
1283 (request.attribute(QNetworkRequest::CookieLoadControlAttribute,
1284 QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Automatic) {
1286 QList<QNetworkCookie> cookies = d->cookieJar->cookiesForUrl(request.url());
1287 if (!cookies.isEmpty())
1288 h.replaceOrAppend(QHttpHeaders::WellKnownHeader::Cookie,
1289 QNetworkHeadersPrivate::fromCookieList(cookies));
1292 request.setHeaders(std::move(h));
1294 Q_UNUSED(isLocalFile);
1296 if (scheme ==
"http"_L1 || scheme ==
"https"_L1 || scheme.isEmpty()) {
1297 QNetworkReplyWasmImpl *reply =
new QNetworkReplyWasmImpl(
this);
1298 QNetworkReplyWasmImplPrivate *priv = reply->d_func();
1299 priv->manager =
this;
1300 priv->setup(op, request, outgoingData);
1306 constexpr char16_t httpSchemes[][17] = {
1311 u"preconnect-https",
1316 if (std::find(std::begin(httpSchemes), std::end(httpSchemes), scheme) != std::end(httpSchemes)) {
1319 const bool isLocalSocket = scheme.startsWith(
"unix"_L1);
1320 if (!isLocalSocket && isStrictTransportSecurityEnabled()
1321 && d->stsCache.isKnownHost(request.url())) {
1322 QUrl stsUrl(request.url());
1332 if (stsUrl.port() == 80)
1333 stsUrl.setPort(443);
1334 stsUrl.setScheme(
"https"_L1);
1335 request.setUrl(stsUrl);
1338 QNetworkReplyHttpImpl *reply =
new QNetworkReplyHttpImpl(
this, request, op, outgoingData);
1344 QNetworkReplyImpl *reply =
new QNetworkReplyImpl(
this);
1345 QNetworkReplyImplPrivate *priv = reply->d_func();
1346 priv->manager =
this;
1353 priv->backend = d->findBackend(op, request);
1355 if (priv->backend) {
1356 priv->backend->setParent(reply);
1357 priv->backend->setReplyPrivate(priv);
1361 reply->setSslConfiguration(request.sslConfiguration());
1365 priv->setup(op, request, outgoingData);
1371
1372
1373
1374
1375
1376
1377
1378
1379QStringList QNetworkAccessManager::supportedSchemes()
const
1381 QStringList schemes;
1382 QNetworkAccessManager *self =
const_cast<QNetworkAccessManager *>(
this);
1383 QMetaObject::invokeMethod(self,
"supportedSchemesImplementation", Qt::DirectConnection,
1384 Q_RETURN_ARG(QStringList, schemes));
1385 schemes.removeDuplicates();
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404QStringList QNetworkAccessManager::supportedSchemesImplementation()
const
1406 Q_D(
const QNetworkAccessManager);
1408 QStringList schemes = d->backendSupportedSchemes();
1411 schemes << QStringLiteral(
"http");
1412 schemes << QStringLiteral(
"unix+http");
1413 schemes << QStringLiteral(
"local+http");
1415 if (QSslSocket::supportsSsl())
1416 schemes << QStringLiteral(
"https");
1419 schemes << QStringLiteral(
"data");
1424
1425
1426
1427
1428
1429
1430
1431
1432void QNetworkAccessManager::clearAccessCache()
1434 QNetworkAccessManagerPrivate::clearAuthenticationCache(
this);
1435 QNetworkAccessManagerPrivate::clearConnectionCache(
this);
1439
1440
1441
1442
1443
1444
1445
1446
1447void QNetworkAccessManager::clearConnectionCache()
1449 QNetworkAccessManagerPrivate::clearConnectionCache(
this);
1454
1455
1456
1457
1458
1459
1460
1461
1462bool QNetworkAccessManager::autoDeleteReplies()
const
1464 return d_func()->autoDeleteReplies;
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481void QNetworkAccessManager::setAutoDeleteReplies(
bool shouldAutoDelete)
1483 d_func()->autoDeleteReplies = shouldAutoDelete;
1487
1488
1489
1490
1491
1492
1493
1496
1497
1498
1499
1500
1501
1502
1503
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515std::chrono::milliseconds QNetworkAccessManager::transferTimeoutAsDuration()
const
1517 return d_func()->transferTimeout;
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537void QNetworkAccessManager::setTransferTimeout(std::chrono::milliseconds duration)
1539 d_func()->transferTimeout = duration;
1542void QNetworkAccessManagerPrivate::_q_replyFinished(QNetworkReply *reply)
1544 Q_Q(QNetworkAccessManager);
1546 emit q->finished(reply);
1547 if (reply->request().attribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute,
false).toBool())
1548 QMetaObject::invokeMethod(reply, [reply] { reply->deleteLater(); }, Qt::QueuedConnection);
1551void QNetworkAccessManagerPrivate::_q_replyEncrypted(QNetworkReply *reply)
1554 Q_Q(QNetworkAccessManager);
1555 emit q->encrypted(reply);
1561void QNetworkAccessManagerPrivate::_q_replySslErrors(
const QList<QSslError> &errors)
1564 Q_Q(QNetworkAccessManager);
1565 QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender());
1567 emit q->sslErrors(reply, errors);
1574void QNetworkAccessManagerPrivate::_q_replyPreSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator)
1576 Q_Q(QNetworkAccessManager);
1577 QNetworkReply *reply = qobject_cast<QNetworkReply *>(q->sender());
1579 emit q->preSharedKeyAuthenticationRequired(reply, authenticator);
1583QNetworkReply *QNetworkAccessManagerPrivate::postProcess(QNetworkReply *reply)
1585 Q_Q(QNetworkAccessManager);
1586 QNetworkReplyPrivate::setManager(reply, q);
1587 q->connect(reply, &QNetworkReply::finished, reply,
1588 [
this, reply]() { _q_replyFinished(reply); });
1591
1592 q->connect(reply, &QNetworkReply::encrypted, reply,
1593 [
this, reply]() { _q_replyEncrypted(reply); });
1594 q->connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(_q_replySslErrors(QList<QSslError>)));
1595 q->connect(reply, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), SLOT(_q_replyPreSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)));
1601void QNetworkAccessManagerPrivate::createCookieJar()
const
1603 if (!cookieJarCreated) {
1605 QNetworkAccessManagerPrivate *that =
const_cast<QNetworkAccessManagerPrivate *>(
this);
1606 that->cookieJar =
new QNetworkCookieJar(that->q_func());
1607 that->cookieJarCreated =
true;
1611void QNetworkAccessManagerPrivate::authenticationRequired(QAuthenticator *authenticator,
1612 QNetworkReply *reply,
1615 QUrl *urlForLastAuthentication,
1616 bool allowAuthenticationReuse)
1618 Q_Q(QNetworkAccessManager);
1623 if (allowAuthenticationReuse && (urlForLastAuthentication->isEmpty()
1624 || url != *urlForLastAuthentication)) {
1626 if (!url.userName().isEmpty() && !url.password().isEmpty()
1627 && (url.userName() != authenticator->user()
1628 || url.password() != authenticator->password())) {
1629 authenticator->setUser(url.userName(QUrl::FullyDecoded));
1630 authenticator->setPassword(url.password(QUrl::FullyDecoded));
1631 *urlForLastAuthentication = url;
1632 authenticationManager->cacheCredentials(url, authenticator);
1636 QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedCredentials(url, authenticator);
1638 && (cred.user != authenticator->user() || cred.password != authenticator->password())) {
1639 authenticator->setUser(cred.user);
1640 authenticator->setPassword(cred.password);
1641 *urlForLastAuthentication = url;
1651 *urlForLastAuthentication = url;
1652 emit q->authenticationRequired(reply, authenticator);
1653 if (allowAuthenticationReuse)
1654 authenticationManager->cacheCredentials(url, authenticator);
1657#ifndef QT_NO_NETWORKPROXY
1658void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(
const QUrl &url,
1659 const QNetworkProxy &proxy,
1661 QAuthenticator *authenticator,
1662 QNetworkProxy *lastProxyAuthentication)
1664 Q_Q(QNetworkAccessManager);
1665 QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*authenticator);
1666 if (proxy != *lastProxyAuthentication && (!priv || !priv->hasFailed)) {
1667 QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedProxyCredentials(proxy);
1668 if (!cred.isNull()) {
1669 authenticator->setUser(cred.user);
1670 authenticator->setPassword(cred.password);
1675#if defined(Q_OS_MACOS)
1680 if (getProxyAuth(proxy.hostName(), url.scheme(), username, password)) {
1683 QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedProxyCredentials(proxy);
1684 if (!priv->hasFailed || cred.user != username || cred.password != password) {
1685 authenticator->setUser(username);
1686 authenticator->setPassword(password);
1687 authenticationManager->cacheProxyCredentials(proxy, authenticator);
1700 *lastProxyAuthentication = proxy;
1701 emit q->proxyAuthenticationRequired(proxy, authenticator);
1702 authenticationManager->cacheProxyCredentials(proxy, authenticator);
1705QList<QNetworkProxy> QNetworkAccessManagerPrivate::queryProxy(
const QNetworkProxyQuery &query)
1707 QList<QNetworkProxy> proxies;
1709 proxies = proxyFactory->queryProxy(query);
1710 if (proxies.isEmpty()) {
1711 qWarning(
"QNetworkAccessManager: factory %p has returned an empty result set",
1713 proxies << QNetworkProxy::NoProxy;
1715 }
else if (proxy.type() == QNetworkProxy::DefaultProxy) {
1717 return QNetworkProxyFactory::proxyForQuery(query);
1726void QNetworkAccessManagerPrivate::clearAuthenticationCache(QNetworkAccessManager *manager)
1728 manager->d_func()->authenticationManager->clearCache();
1731void QNetworkAccessManagerPrivate::clearConnectionCache(QNetworkAccessManager *manager)
1733 manager->d_func()->destroyThread();
1736QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate()
1741QThread * QNetworkAccessManagerPrivate::createThread()
1744 thread =
new QThread;
1745 thread->setObjectName(QStringLiteral(
"QNetworkAccessManager thread"));
1752void QNetworkAccessManagerPrivate::destroyThread()
1756 thread->wait(QDeadlineTimer(5000));
1757 if (thread->isFinished())
1760 QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
1766#if QT_CONFIG(http) || defined(Q_OS_WASM)
1768QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(
const QNetworkRequest &request, QHttpMultiPart *multiPart)
1771 QNetworkRequest newRequest(request);
1772 auto h = newRequest.headers();
1775 if (!h.contains(QHttpHeaders::WellKnownHeader::ContentType)) {
1776 QByteArray contentType;
1777 contentType.reserve(34 + multiPart->d_func()->boundary.size());
1778 contentType +=
"multipart/";
1779 switch (multiPart->d_func()->contentType) {
1780 case QHttpMultiPart::RelatedType:
1781 contentType +=
"related";
1783 case QHttpMultiPart::FormDataType:
1784 contentType +=
"form-data";
1786 case QHttpMultiPart::AlternativeType:
1787 contentType +=
"alternative";
1790 contentType +=
"mixed";
1794 contentType +=
"; boundary=\"" + multiPart->d_func()->boundary +
'"';
1795 h.append(QHttpHeaders::WellKnownHeader::ContentType, contentType);
1800 if (!h.contains(QHttpHeaders::WellKnownHeader::MIMEVersion))
1801 h.append(QHttpHeaders::WellKnownHeader::MIMEVersion,
"1.0"_ba);
1803 newRequest.setHeaders(std::move(h));
1805 QIODevice *device = multiPart->d_func()->device;
1806 if (!device->isReadable()) {
1807 if (!device->isOpen()) {
1808 if (!device->open(QIODevice::ReadOnly))
1809 qWarning(
"could not open device for reading");
1811 qWarning(
"device is not readable");
1820
1821
1822
1823
1824void QNetworkAccessManagerPrivate::ensureBackendPluginsLoaded()
1826 Q_CONSTINIT
static QBasicMutex mutex;
1827 std::unique_lock locker(mutex);
1830#if QT_CONFIG(library)
1831 qnabfLoader->update();
1834 while (qnabfLoader->instance(index))
1840#include "moc_qnetworkaccessmanager.cpp"
Combined button and popup list for selecting options.
#define QNetworkAccessBackendFactory_iid