6#include "qplatformdefs.h"
11#include "qhttp1configuration.h"
12#include "qhttp2configuration.h"
13#include "private/http2protocol_p.h"
16#include "QtCore/qdatetime.h"
17#include "QtCore/qlocale.h"
18#include "QtCore/qshareddata.h"
19#include "QtCore/qtimezone.h"
20#include "QtCore/private/qduplicatetracker_p.h"
21#include "QtCore/private/qtools_p.h"
24#if QT_CONFIG(datestring)
29#include <q20algorithm.h>
33using namespace Qt::StringLiterals;
34using namespace std::chrono_literals;
36constexpr std::chrono::milliseconds QNetworkRequest::DefaultTransferTimeout;
39QT_IMPL_METATYPE_EXTERN_TAGGED(QNetworkRequest::RedirectPolicy, QNetworkRequest__RedirectPolicy)
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
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
234
235
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
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
374
375
376
377
378
379
380
381
382
383
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
420
421
422
423
424
425
426
427
428
429
430
431
434
435
436
437
438
439
441class QNetworkRequestPrivate:
public QSharedData,
public QNetworkHeadersPrivate
444 static const int maxRedirectCount = 50;
445 inline QNetworkRequestPrivate()
446 : priority(QNetworkRequest::NormalPriority)
448 , sslConfiguration(
nullptr)
450 , maxRedirectsAllowed(maxRedirectCount)
451 { qRegisterMetaType<QNetworkRequest>(); }
452 ~QNetworkRequestPrivate()
455 delete sslConfiguration;
460 QNetworkRequestPrivate(
const QNetworkRequestPrivate &other)
461 : QSharedData(other), QNetworkHeadersPrivate(other)
464 priority = other.priority;
465 maxRedirectsAllowed = other.maxRedirectsAllowed;
467 sslConfiguration =
nullptr;
468 if (other.sslConfiguration)
469 sslConfiguration =
new QSslConfiguration(*other.sslConfiguration);
471 peerVerifyName = other.peerVerifyName;
473 h1Configuration = other.h1Configuration;
474 h2Configuration = other.h2Configuration;
475 decompressedSafetyCheckThreshold = other.decompressedSafetyCheckThreshold;
477 transferTimeout = other.transferTimeout;
480 inline bool operator==(
const QNetworkRequestPrivate &other)
const
482 return url == other.url &&
483 priority == other.priority &&
484 attributes == other.attributes &&
485 maxRedirectsAllowed == other.maxRedirectsAllowed &&
486 peerVerifyName == other.peerVerifyName
488 && h1Configuration == other.h1Configuration
489 && h2Configuration == other.h2Configuration
490 && decompressedSafetyCheckThreshold == other.decompressedSafetyCheckThreshold
492 && transferTimeout == other.transferTimeout
493 && QHttpHeadersHelper::compareStrict(httpHeaders, other.httpHeaders)
499 QNetworkRequest::Priority priority;
501 mutable QSslConfiguration *sslConfiguration;
503 int maxRedirectsAllowed;
504 QString peerVerifyName;
506 QHttp1Configuration h1Configuration;
507 QHttp2Configuration h2Configuration;
508 qint64 decompressedSafetyCheckThreshold = 10ll * 1024ll * 1024ll;
510 std::chrono::milliseconds transferTimeout = 0ms;
514
515
516
517
518
519QNetworkRequest::QNetworkRequest()
520 : d(
new QNetworkRequestPrivate)
528 d->h2Configuration.setStreamReceiveWindowSize(Http2::qtDefaultStreamReceiveWindowSize);
529 d->h2Configuration.setSessionReceiveWindowSize(Http2::maxSessionReceiveWindowSize);
530 d->h2Configuration.setServerPushEnabled(
false);
535
536
537
538
539
540QNetworkRequest::QNetworkRequest(
const QUrl &url)
547
548
549QNetworkRequest::QNetworkRequest(
const QNetworkRequest &other)
555
556
557QNetworkRequest::~QNetworkRequest()
564
565
566
567
568
569bool QNetworkRequest::operator==(
const QNetworkRequest &other)
const
571 return d == other.d || *d == *other.d;
575
576
577
578
579
580
583
584
585QNetworkRequest &QNetworkRequest::operator=(
const QNetworkRequest &other)
592
593
594
595
598
599
600
601
602QUrl QNetworkRequest::url()
const
608
609
610
611
612void QNetworkRequest::setUrl(
const QUrl &url)
618
619
620
621
622
623
624QHttpHeaders QNetworkRequest::headers()
const
630
631
632
633
634
635
636
637
638
639
640void QNetworkRequest::setHeaders(QHttpHeaders &&newHeaders)
642 d->setHeaders(std::move(newHeaders));
646
647
648
649void QNetworkRequest::setHeaders(
const QHttpHeaders &newHeaders)
651 d->setHeaders(newHeaders);
655
656
657
658
659
660
661QVariant QNetworkRequest::header(KnownHeaders header)
const
663 return d->cookedHeaders.value(header);
667
668
669
670
671
672
673void QNetworkRequest::setHeader(KnownHeaders header,
const QVariant &value)
675 d->setCookedHeader(header, value);
679
680
681
682
683
684
685bool QNetworkRequest::hasRawHeader(QAnyStringView headerName)
const
687 return d->headers().contains(headerName);
691
692
693
694
695
696
697
698
699
700
701QByteArray QNetworkRequest::rawHeader(QAnyStringView headerName)
const
703 return d->rawHeader(headerName);
707
708
709
710
711
712QList<QByteArray> QNetworkRequest::rawHeaderList()
const
714 return d->rawHeadersKeys();
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739void QNetworkRequest::setRawHeader(
const QByteArray &headerName,
const QByteArray &headerValue)
741 d->setRawHeader(headerName, headerValue);
745
746
747
748
749
750
751
752
753QVariant QNetworkRequest::attribute(Attribute code,
const QVariant &defaultValue)
const
755 return d->attributes.value(code, defaultValue);
759
760
761
762
763
764
765
766void QNetworkRequest::setAttribute(Attribute code,
const QVariant &value)
769 d->attributes.insert(code, value);
771 d->attributes.remove(code);
776
777
778
779
780
781QSslConfiguration QNetworkRequest::sslConfiguration()
const
783 if (!d->sslConfiguration)
784 d->sslConfiguration =
new QSslConfiguration(QSslConfiguration::defaultConfiguration());
785 return *d->sslConfiguration;
789
790
791
792
793
794
795
796void QNetworkRequest::setSslConfiguration(
const QSslConfiguration &config)
798 if (!d->sslConfiguration)
799 d->sslConfiguration =
new QSslConfiguration(config);
801 *d->sslConfiguration = config;
806
807
808
809
810
811
812
813
814
815
816void QNetworkRequest::setOriginatingObject(QObject *object)
818 d->originatingObject = object;
822
823
824
825
826
827
828
829
830QObject *QNetworkRequest::originatingObject()
const
832 return d->originatingObject.data();
836
837
838
839
840
841
842QNetworkRequest::Priority QNetworkRequest::priority()
const
848
849
850
851
852
853
854
855
856
859
860
861
862
863
864
865
866
867
868
869void QNetworkRequest::setPriority(Priority priority)
871 d->priority = priority;
875
876
877
878
879
880
881
882int QNetworkRequest::maximumRedirectsAllowed()
const
884 return d->maxRedirectsAllowed;
888
889
890
891
892
893
894
895void QNetworkRequest::setMaximumRedirectsAllowed(
int maxRedirectsAllowed)
897 d->maxRedirectsAllowed = maxRedirectsAllowed;
901
902
903
904
905
906
907
908QString QNetworkRequest::peerVerifyName()
const
910 return d->peerVerifyName;
914
915
916
917
918
919
920
921void QNetworkRequest::setPeerVerifyName(
const QString &peerName)
923 d->peerVerifyName = peerName;
928
929
930
931
932
933
934
935QHttp1Configuration QNetworkRequest::http1Configuration()
const
937 return d->h1Configuration;
940
941
942
943
944
945
946void QNetworkRequest::setHttp1Configuration(
const QHttp1Configuration &configuration)
948 d->h1Configuration = configuration;
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972QHttp2Configuration QNetworkRequest::http2Configuration()
const
974 return d->h2Configuration;
978
979
980
981
982
983
984
985
986
987
988
989
990void QNetworkRequest::setHttp2Configuration(
const QHttp2Configuration &configuration)
992 d->h2Configuration = configuration;
996
997
998
999
1000
1001
1002
1003
1004
1005qint64 QNetworkRequest::decompressedSafetyCheckThreshold()
const
1007 return d->decompressedSafetyCheckThreshold;
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032void QNetworkRequest::setDecompressedSafetyCheckThreshold(qint64 threshold)
1034 d->decompressedSafetyCheckThreshold = threshold;
1038#if QT_CONFIG(http) || defined (Q_OS_WASM)
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1052
1053
1054
1055
1056
1057
1058
1059
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071std::chrono::milliseconds QNetworkRequest::transferTimeoutAsDuration()
const
1073 return d->transferTimeout;
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090void QNetworkRequest::setTransferTimeout(std::chrono::milliseconds duration)
1092 d->transferTimeout = duration;
1099 QHttpHeaders::WellKnownHeader wellKnownHeader;
1100 QNetworkRequest::KnownHeaders knownHeader;
1103constexpr bool operator<(
const HeaderPair &lhs,
const HeaderPair &rhs)
1105 return lhs.wellKnownHeader < rhs.wellKnownHeader;
1108constexpr bool operator<(
const HeaderPair &lhs, QHttpHeaders::WellKnownHeader rhs)
1110 return lhs.wellKnownHeader < rhs;
1113constexpr bool operator<(QHttpHeaders::WellKnownHeader lhs,
const HeaderPair &rhs)
1115 return lhs < rhs.wellKnownHeader;
1121 { QHttpHeaders::WellKnownHeader::ContentDisposition, QNetworkRequest::KnownHeaders::ContentDispositionHeader },
1122 { QHttpHeaders::WellKnownHeader::ContentLength, QNetworkRequest::KnownHeaders::ContentLengthHeader },
1123 { QHttpHeaders::WellKnownHeader::ContentType, QNetworkRequest::KnownHeaders::ContentTypeHeader },
1124 { QHttpHeaders::WellKnownHeader::Cookie, QNetworkRequest::KnownHeaders::CookieHeader },
1125 { QHttpHeaders::WellKnownHeader::ETag, QNetworkRequest::KnownHeaders::ETagHeader },
1126 { QHttpHeaders::WellKnownHeader::IfMatch , QNetworkRequest::KnownHeaders::IfMatchHeader },
1127 { QHttpHeaders::WellKnownHeader::IfModifiedSince, QNetworkRequest::KnownHeaders::IfModifiedSinceHeader },
1128 { QHttpHeaders::WellKnownHeader::IfNoneMatch, QNetworkRequest::KnownHeaders::IfNoneMatchHeader },
1129 { QHttpHeaders::WellKnownHeader::LastModified, QNetworkRequest::KnownHeaders::LastModifiedHeader},
1130 { QHttpHeaders::WellKnownHeader::Location, QNetworkRequest::KnownHeaders::LocationHeader},
1131 { QHttpHeaders::WellKnownHeader::Server, QNetworkRequest::KnownHeaders::ServerHeader },
1132 { QHttpHeaders::WellKnownHeader::SetCookie, QNetworkRequest::KnownHeaders::SetCookieHeader },
1133 { QHttpHeaders::WellKnownHeader::UserAgent, QNetworkRequest::KnownHeaders::UserAgentHeader }
1136static_assert(std::size(knownHeadersArr) == size_t(QNetworkRequest::KnownHeaders::NumKnownHeaders));
1142 if (it == std::end(knownHeadersArr) || key < *it)
1143 return std::nullopt;
1144 return it->knownHeader;
1149 auto pred = [key](
const HeaderPair &pair) {
return pair.knownHeader == key; };
1151 if (it == std::end(knownHeadersArr))
1152 return std::nullopt;
1153 return it->wellKnownHeader;
1157 QNetworkCookie::RawForm type,
1158 QByteArrayView separator)
1161 for (
const QNetworkCookie &cookie : cookies) {
1162 result += cookie.toRawForm(type);
1163 result += separator;
1165 if (!result.isEmpty())
1166 result.chop(separator.size());
1171 QByteArrayView separator)
1173 const QList<QNetworkCookie> *cookies = get_if<QList<QNetworkCookie>>(&value);
1176 return makeCookieHeader(*cookies, type, separator);
1182 case QNetworkRequest::ContentTypeHeader:
1183 case QNetworkRequest::ContentLengthHeader:
1184 case QNetworkRequest::ContentDispositionHeader:
1185 case QNetworkRequest::UserAgentHeader:
1186 case QNetworkRequest::ServerHeader:
1187 case QNetworkRequest::ETagHeader:
1188 case QNetworkRequest::IfMatchHeader:
1189 case QNetworkRequest::IfNoneMatchHeader:
1190 return value.toByteArray();
1192 case QNetworkRequest::LocationHeader:
1193 switch (value.userType()) {
1194 case QMetaType::QUrl:
1195 return value.toUrl().toEncoded();
1198 return value.toByteArray();
1201 case QNetworkRequest::LastModifiedHeader:
1202 case QNetworkRequest::IfModifiedSinceHeader:
1203 switch (value.userType()) {
1205 case QMetaType::QDate:
1206 return QNetworkHeadersPrivate::toHttpDate(value.toDate().startOfDay(QTimeZone::UTC));
1207 case QMetaType::QDateTime:
1208 return QNetworkHeadersPrivate::toHttpDate(value.toDateTime());
1211 return value.toByteArray();
1214 case QNetworkRequest::CookieHeader:
1215 return makeCookieHeader(value, QNetworkCookie::NameAndValueOnly,
"; ");
1217 case QNetworkRequest::SetCookieHeader:
1218 return makeCookieHeader(value, QNetworkCookie::Full,
", ");
1221 Q_UNREACHABLE_RETURN({});
1227 if (headerName.isEmpty())
1230 auto is = [headerName](QByteArrayView what) {
1231 return headerName.compare(what, Qt::CaseInsensitive) == 0;
1234 switch (QtMiscUtils::toAsciiLower(headerName.front())) {
1236 if (is(
"content-type"))
1237 return QNetworkRequest::ContentTypeHeader;
1238 else if (is(
"content-length"))
1239 return QNetworkRequest::ContentLengthHeader;
1240 else if (is(
"cookie"))
1241 return QNetworkRequest::CookieHeader;
1242 else if (is(
"content-disposition"))
1243 return QNetworkRequest::ContentDispositionHeader;
1248 return QNetworkRequest::ETagHeader;
1252 if (is(
"if-modified-since"))
1253 return QNetworkRequest::IfModifiedSinceHeader;
1255 return QNetworkRequest::IfMatchHeader;
1256 if (is(
"if-none-match"))
1257 return QNetworkRequest::IfNoneMatchHeader;
1262 return QNetworkRequest::LocationHeader;
1263 else if (is(
"last-modified"))
1264 return QNetworkRequest::LastModifiedHeader;
1268 if (is(
"set-cookie"))
1269 return QNetworkRequest::SetCookieHeader;
1270 else if (is(
"server"))
1271 return QNetworkRequest::ServerHeader;
1275 if (is(
"user-agent"))
1276 return QNetworkRequest::UserAgentHeader;
1285 QDateTime dt = QNetworkHeadersPrivate::fromHttpDate(raw);
1293 QList<QNetworkCookie> result;
1294 for (
auto cookie : QLatin1StringView(raw).tokenize(
';'_L1)) {
1295 QList<QNetworkCookie> parsed = QNetworkCookie::parseCookies(cookie.trimmed());
1296 if (parsed.size() != 1)
1307 const QByteArrayView trimmed = raw.trimmed();
1308 if (!trimmed.startsWith(
'"') && !trimmed.startsWith(R"(W/")"))
1311 if (!trimmed.endsWith(
'"'))
1314 return QString::fromLatin1(trimmed);
1320 const QByteArrayView trimmedRaw = raw.trimmed();
1321 if (trimmedRaw ==
"*")
1322 return QStringList(QStringLiteral(
"*"));
1325 for (
auto &element : QLatin1StringView(trimmedRaw).tokenize(
','_L1)) {
1326 if (
const auto trimmed = element.trimmed(); op(trimmed))
1327 tags += QString::fromLatin1(trimmed);
1335 return parseMatchImpl(raw, [](QByteArrayView element) {
1336 return element.startsWith(
'"') && element.endsWith(
'"');
1342 return parseMatchImpl(raw, [](QByteArrayView element) {
1343 return (element.startsWith(
'"') || element.startsWith(R"(W/")")) && element.endsWith(
'"');
1352 case QNetworkRequest::UserAgentHeader:
1353 case QNetworkRequest::ServerHeader:
1354 case QNetworkRequest::ContentTypeHeader:
1355 case QNetworkRequest::ContentDispositionHeader:
1357 return QString::fromLatin1(value);
1359 case QNetworkRequest::ContentLengthHeader: {
1361 qint64 result = QByteArrayView(value).trimmed().toLongLong(&ok);
1367 case QNetworkRequest::LocationHeader: {
1368 QUrl result = QUrl::fromEncoded(value, QUrl::StrictMode);
1369 if (result.isValid() && !result.scheme().isEmpty())
1374 case QNetworkRequest::LastModifiedHeader:
1375 case QNetworkRequest::IfModifiedSinceHeader:
1376 return parseHttpDate(value);
1378 case QNetworkRequest::ETagHeader:
1379 return parseETag(value);
1381 case QNetworkRequest::IfMatchHeader:
1382 return parseIfMatch(value);
1384 case QNetworkRequest::IfNoneMatchHeader:
1385 return parseIfNoneMatch(value);
1387 case QNetworkRequest::CookieHeader:
1388 return QVariant::fromValue(parseCookieHeader(value));
1390 case QNetworkRequest::SetCookieHeader:
1391 return QVariant::fromValue(QNetworkCookie::parseCookies(value));
1394 Q_UNREACHABLE_RETURN({});
1405 case QNetworkRequest::IfMatchHeader: {
1407 for (
const auto &val : values)
1408 res << parseIfMatch(val);
1411 case QNetworkRequest::IfNoneMatchHeader: {
1413 for (
const auto &val : values)
1414 res << parseIfNoneMatch(val);
1417 case QNetworkRequest::CookieHeader: {
1418 auto listOpt = QNetworkHeadersPrivate::toCookieList(values);
1419 return listOpt.has_value() ? QVariant::fromValue(listOpt.value()) : QVariant();
1421 case QNetworkRequest::SetCookieHeader: {
1422 QList<QNetworkCookie> res;
1423 for (
const auto &val : values)
1424 res << QNetworkCookie::parseCookies(val);
1425 return QVariant::fromValue(res);
1428 return parseHeaderValue(header, values.first());
1435 return name.compare(QHttpHeaders::wellKnownHeaderName(QHttpHeaders::WellKnownHeader::SetCookie),
1436 Qt::CaseInsensitive) == 0;
1441 return name == QHttpHeaders::WellKnownHeader::SetCookie;
1444template<
class HeaderName>
1446 QByteArrayView value)
1448 headers.removeAll(header);
1454 if (isSetCookie(header)) {
1455 for (
auto cookie : QLatin1StringView(value).tokenize(
'\n'_L1))
1456 headers.append(QHttpHeaders::WellKnownHeader::SetCookie, cookie);
1458 headers.append(header, value);
1467 rawHeaderCache.headersList = fromHttpToRaw(httpHeaders);
1474 if (httpHeaders.isEmpty())
1477 QList<QByteArray> result;
1478 result.reserve(httpHeaders.size());
1479 QDuplicateTracker<QByteArray> seen(httpHeaders.size());
1481 for (qsizetype i = 0; i < httpHeaders.size(); i++) {
1482 const auto nameL1 = httpHeaders.nameAt(i);
1483 const auto name =
QByteArray(nameL1.data(), nameL1.size());
1484 if (seen.hasSeen(name))
1495 QByteArrayView setCookieStr = QHttpHeaders::wellKnownHeaderName(
1496 QHttpHeaders::WellKnownHeader::SetCookie);
1497 if (QAnyStringView::compare(headerName, setCookieStr, Qt::CaseInsensitive) != 0)
1498 return httpHeaders.combinedValue(headerName);
1501 const char* separator =
"";
1502 for (qsizetype i = 0; i < httpHeaders.size(); ++i) {
1503 if (QAnyStringView::compare(httpHeaders.nameAt(i), headerName, Qt::CaseInsensitive) == 0) {
1504 result.append(separator);
1505 result.append(httpHeaders.valueAt(i));
1518 setFromRawHeader(httpHeaders, key, value);
1519 parseAndSetHeader(key, value);
1521 invalidateHeaderCache();
1525 const QVariant &value)
1527 const auto wellKnownOpt = toWellKnownHeader(header);
1528 if (!wellKnownOpt) {
1530 qWarning(
"QNetworkRequest::setHeader: invalid header value KnownHeader(%d) received", header);
1534 if (value.isNull()) {
1535 httpHeaders.removeAll(wellKnownOpt.value());
1538 QByteArray rawValue = headerValue(header, value);
1539 if (rawValue.isEmpty()) {
1540 qWarning(
"QNetworkRequest::setHeader: QVariant of type %s cannot be used with header %s",
1542 QHttpHeaders::wellKnownHeaderName(wellKnownOpt.value()).constData());
1546 setFromRawHeader(httpHeaders, wellKnownOpt.value(), rawValue);
1550 invalidateHeaderCache();
1560 httpHeaders = newHeaders;
1561 setCookedFromHttp(httpHeaders);
1562 invalidateHeaderCache();
1567 httpHeaders = std::move(newHeaders);
1568 setCookedFromHttp(httpHeaders);
1569 invalidateHeaderCache();
1574 httpHeaders.replaceOrAppend(name, value);
1577 const auto knownHeaderOpt = toKnownHeader(name);
1579 parseAndSetHeader(knownHeaderOpt.value(), value);
1581 invalidateHeaderCache();
1586 httpHeaders.clear();
1588 invalidateHeaderCache();
1594 const int parsedKeyAsInt = parseHeaderName(key);
1595 if (parsedKeyAsInt != -1) {
1596 const QNetworkRequest::KnownHeaders parsedKey
1597 =
static_cast<QNetworkRequest::KnownHeaders>(parsedKeyAsInt);
1598 parseAndSetHeader(parsedKey, value);
1603 QByteArrayView value)
1605 if (value.isNull()) {
1607 }
else if (key == QNetworkRequest::ContentLengthHeader
1608 && cookedHeaders.contains(QNetworkRequest::ContentLengthHeader)) {
1612 cookedHeaders.insert(key, parseHeaderValue(key, value));
1621 switch (month_str[0]) {
1623 switch (month_str[1]) {
1627 switch (month_str[2] ) {
1638 switch (month_str[2] ) {
1646 switch (month_str[1]) {
1674 int pos = value.indexOf(
',');
1676#if QT_CONFIG(datestring)
1679 dt = QDateTime::fromString(QString::fromLatin1(value), Qt::TextDate);
1685 int day, year, hour, minute, second;
1688 if (sscanf_s(value.constData(),
"%*3s, %d %3s %d %d:%d:%d 'GMT'", &day, month_name, 4, &year, &hour, &minute, &second) == 6)
1692 if (sscanf(value.constData(),
"%*3s, %d %3s %d %d:%d:%d 'GMT'", &day, month_name, &year, &hour, &minute, &second) == 6)
1694 dt = QDateTime(QDate(year, name_to_month(month_name), day), QTime(hour, minute, second));
1696 QLocale c = QLocale::c();
1698 QString sansWeekday = QString::fromLatin1(value.constData() + pos + 2);
1700 dt = c.toDateTime(sansWeekday,
"dd-MMM-yy hh:mm:ss 'GMT'"_L1);
1706 dt.setTimeZone(QTimeZone::UTC);
1712 return QLocale::c().toString(dt.toUTC(), u"ddd, dd MMM yyyy hh:mm:ss 'GMT'").toLatin1();
1716 const QHttpHeaders &headers)
1718 if (headers.isEmpty())
1722 QHash<QByteArray, qsizetype> nameToIndex;
1723 list.reserve(headers.size());
1724 nameToIndex.reserve(headers.size());
1726 for (qsizetype i = 0; i < headers.size(); ++i) {
1727 const auto nameL1 = headers.nameAt(i);
1728 const auto value = headers.valueAt(i);
1730 const bool isSetCookie = nameL1 == QHttpHeaders::wellKnownHeaderName(
1731 QHttpHeaders::WellKnownHeader::SetCookie);
1733 const auto name =
QByteArray(nameL1.data(), nameL1.size());
1734 if (
auto it = nameToIndex.find(name); it != nameToIndex.end()) {
1735 list[it.value()].second += isSetCookie ?
"\n" :
", ";
1736 list[it.value()].second += value;
1738 nameToIndex[name] = list.size();
1739 list.emplaceBack(name, value.toByteArray());
1751 QHttpHeaders headers;
1752 headers.reserve(raw.size());
1754 for (
const auto &[key, value] : raw) {
1755 const bool isSetCookie = key.compare(QHttpHeaders::wellKnownHeaderName(
1756 QHttpHeaders::WellKnownHeader::SetCookie),
1757 Qt::CaseInsensitive) == 0;
1759 for (
auto header : QLatin1StringView(value).tokenize(
'\n'_L1))
1760 headers.append(key, header);
1762 headers.append(key, value);
1772 return std::nullopt;
1775 qint64 res = value.toLongLong(&ok);
1778 return std::nullopt;
1782 const QList<QByteArray> &values)
1785 return std::nullopt;
1787 QList<QNetworkCookie> cookies;
1788 for (
const auto &s : values)
1789 cookies += QNetworkCookie::parseCookies(s);
1791 if (cookies.empty())
1792 return std::nullopt;
1798 return makeCookieHeader(cookies, QNetworkCookie::NameAndValueOnly,
"; ");
1802 const QList<QByteArray> &values)
1805 return std::nullopt;
1807 QList<QNetworkCookie> cookies;
1808 for (
const auto &s : values)
1809 cookies += parseCookieHeader(s);
1811 if (cookies.empty())
1812 return std::nullopt;
1826 QMap<QNetworkRequest::KnownHeaders, QList<QByteArray>> multipleHeadersMap;
1827 for (
int i = 0; i < newHeaders.size(); ++i) {
1828 const auto name = newHeaders.nameAt(i);
1829 const auto value = newHeaders.valueAt(i);
1831 const int parsedKeyAsInt = parseHeaderName(name);
1832 if (parsedKeyAsInt == -1)
1835 const QNetworkRequest::KnownHeaders parsedKey
1836 =
static_cast<QNetworkRequest::KnownHeaders>(parsedKeyAsInt);
1838 auto &list = multipleHeadersMap[parsedKey];
1839 list.append(value.toByteArray());
1842 for (
auto i = multipleHeadersMap.cbegin(), end = multipleHeadersMap.cend(); i != end; ++i)
1843 cookedHeaders.insert(i.key(), parseHeaderValue(i.key(), i.value()));
1848#include "moc_qnetworkrequest.cpp"
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
Combined button and popup list for selecting options.
static int name_to_month(const char *month_str)
static QStringList parseMatchImpl(QByteArrayView raw, T op)
static bool isSetCookie(QByteArrayView name)
static QList< QNetworkCookie > parseCookieHeader(QByteArrayView raw)
static int parseHeaderName(QByteArrayView headerName)
static std::optional< QNetworkRequest::KnownHeaders > toKnownHeader(QHttpHeaders::WellKnownHeader key)
static QVariant parseETag(QByteArrayView raw)
static QVariant parseHeaderValue(QNetworkRequest::KnownHeaders header, QByteArrayView value)
static QVariant parseHttpDate(QByteArrayView raw)
static QByteArray headerValue(QNetworkRequest::KnownHeaders header, const QVariant &value)
static QByteArray makeCookieHeader(const QList< QNetworkCookie > &cookies, QNetworkCookie::RawForm type, QByteArrayView separator)
static QStringList parseIfMatch(QByteArrayView raw)
static QStringList parseIfNoneMatch(QByteArrayView raw)
static void setFromRawHeader(QHttpHeaders &headers, HeaderName header, QByteArrayView value)
static std::optional< QHttpHeaders::WellKnownHeader > toWellKnownHeader(QNetworkRequest::KnownHeaders key)
static constexpr HeaderPair knownHeadersArr[]