diff options
author | Lena Biliaieva <lena.biliaieva@qt.io> | 2024-04-22 16:23:31 +0200 |
---|---|---|
committer | Lena Biliaieva <lena.biliaieva@qt.io> | 2024-05-02 22:11:44 +0200 |
commit | 78b0d507ce8728c6287196f78b7c428d9bbdcda3 (patch) | |
tree | 10ac09dadc052a606f1210b2966bae09d025342c /src/network | |
parent | f97e60a4f0602e1478c888ff1043276966c93387 (diff) |
Add QHttpHeaders methods to QNetworkCacheMetaData
[ChangeLog][QtNetwork][QNetworkCacheMetaData] Added headers() and
setHeaders() methods to QNetworkCacheMetaData to provide an interface
to work with QHttpHeaders.
Task-number: QTBUG-107751
Change-Id: I1dfed5c2e03f4912de0da96156425cd6b713c1d5
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/access/qabstractnetworkcache.cpp | 43 | ||||
-rw-r--r-- | src/network/access/qabstractnetworkcache.h | 3 | ||||
-rw-r--r-- | src/network/access/qnetworkdiskcache.cpp | 58 | ||||
-rw-r--r-- | src/network/access/qnetworkrequest.cpp | 53 | ||||
-rw-r--r-- | src/network/access/qnetworkrequest_p.h | 3 |
5 files changed, 119 insertions, 41 deletions
diff --git a/src/network/access/qabstractnetworkcache.cpp b/src/network/access/qabstractnetworkcache.cpp index c8b940d801..3cd55d46fa 100644 --- a/src/network/access/qabstractnetworkcache.cpp +++ b/src/network/access/qabstractnetworkcache.cpp @@ -3,6 +3,8 @@ #include "qabstractnetworkcache.h" #include "qabstractnetworkcache_p.h" +#include "qnetworkrequest_p.h" +#include "qhttpheadershelper_p.h" #include <qdatastream.h> #include <qdatetime.h> @@ -28,14 +30,14 @@ public: url == other.url && lastModified == other.lastModified && expirationDate == other.expirationDate - && headers == other.headers - && saveToDisk == other.saveToDisk; + && saveToDisk == other.saveToDisk + && QHttpHeadersHelper::compareStrict(headers, other.headers); } QUrl url; QDateTime lastModified; QDateTime expirationDate; - QNetworkCacheMetaData::RawHeaderList headers; + QHttpHeaders headers; QNetworkCacheMetaData::AttributesMap attributes; bool saveToDisk; @@ -207,21 +209,45 @@ void QNetworkCacheMetaData::setUrl(const QUrl &url) Returns a list of all raw headers that are set in this meta data. The list is in the same order that the headers were set. - \sa setRawHeaders() + \sa setRawHeaders(), headers() */ QNetworkCacheMetaData::RawHeaderList QNetworkCacheMetaData::rawHeaders() const { - return d->headers; + return QNetworkHeadersPrivate::fromHttpToRaw(d->headers); } /*! Sets the raw headers to \a list. - \sa rawHeaders() + \sa rawHeaders(), setHeaders() */ void QNetworkCacheMetaData::setRawHeaders(const RawHeaderList &list) { - d->headers = list; + d->headers = QNetworkHeadersPrivate::fromRawToHttp(list); +} + +/*! + \since 6.8 + + Returns headers in form of QHttpHeaders that are set in this meta data. + + \sa setHeaders() +*/ +QHttpHeaders QNetworkCacheMetaData::headers() const +{ + return d->headers; +} + +/*! + \since 6.8 + + Sets the headers of this network cache meta data to \a headers. + + \sa headers() +*/ +void QNetworkCacheMetaData::setHeaders(const QHttpHeaders &headers) +{ + d->headers = headers; } /*! @@ -367,7 +393,8 @@ void QNetworkCacheMetaDataPrivate::load(QDataStream &in, QNetworkCacheMetaData & in >> p->lastModified; in >> p->saveToDisk; in >> p->attributes; - in >> p->headers; + QNetworkCacheMetaData::RawHeaderList list; in >> list; + metaData.setRawHeaders(list); } /*! diff --git a/src/network/access/qabstractnetworkcache.h b/src/network/access/qabstractnetworkcache.h index c70dcf737c..b12fd4f863 100644 --- a/src/network/access/qabstractnetworkcache.h +++ b/src/network/access/qabstractnetworkcache.h @@ -48,6 +48,9 @@ public: RawHeaderList rawHeaders() const; void setRawHeaders(const RawHeaderList &headers); + QHttpHeaders headers() const; + void setHeaders(const QHttpHeaders &headers); + QDateTime lastModified() const; void setLastModified(const QDateTime &dateTime); diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp index c883a61886..b39924025e 100644 --- a/src/network/access/qnetworkdiskcache.cpp +++ b/src/network/access/qnetworkdiskcache.cpp @@ -154,15 +154,11 @@ QIODevice *QNetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData) return nullptr; } - const auto headers = metaData.rawHeaders(); - for (const auto &header : headers) { - if (header.first.compare("content-length", Qt::CaseInsensitive) == 0) { - const qint64 size = header.second.toLongLong(); - if (size > (maximumCacheSize() * 3)/4) - return nullptr; - break; - } - } + const auto sizeValue = metaData.headers().value(QHttpHeaders::WellKnownHeader::ContentLength); + const qint64 size = sizeValue.toLongLong(); + if (size > (maximumCacheSize() * 3)/4) + return nullptr; + std::unique_ptr<QCacheItem> cacheItem = std::make_unique<QCacheItem>(); cacheItem->metaData = metaData; @@ -578,31 +574,27 @@ QString QNetworkDiskCachePrivate::cacheFileName(const QUrl &url) const */ bool QCacheItem::canCompress() const { - bool sizeOk = false; - bool typeOk = false; - const auto headers = metaData.rawHeaders(); - for (const auto &header : headers) { - if (header.first.compare("content-length", Qt::CaseInsensitive) == 0) { - qint64 size = header.second.toLongLong(); - if (size > MAX_COMPRESSION_SIZE) - return false; - else - sizeOk = true; - } + const auto h = metaData.headers(); - if (header.first.compare("content-type", Qt::CaseInsensitive) == 0) { - QByteArray type = header.second; - if (type.startsWith("text/") - || (type.startsWith("application/") - && (type.endsWith("javascript") || type.endsWith("ecmascript")))) - typeOk = true; - else - return false; - } - if (sizeOk && typeOk) - return true; + const auto sizeValue = h.value(QHttpHeaders::WellKnownHeader::ContentLength); + if (sizeValue.empty()) + return false; + + qint64 size = sizeValue.toLongLong(); + if (size > MAX_COMPRESSION_SIZE) + return false; + + const auto type = h.value(QHttpHeaders::WellKnownHeader::ContentType); + if (!type.empty()) + return false; + + if (!type.startsWith("text/") + && !(type.startsWith("application/") + && (type.endsWith("javascript") || type.endsWith("ecmascript")))) { + return false; } - return false; + + return true; } enum @@ -673,7 +665,7 @@ bool QCacheItem::read(QFileDevice *device, bool readData) if (!device->fileName().endsWith(expectedFilename)) return false; - return metaData.isValid() && !metaData.rawHeaders().isEmpty(); + return metaData.isValid() && !metaData.headers().isEmpty(); } QT_END_NAMESPACE diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index ad83dd38e3..a59de42a44 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -1602,6 +1602,59 @@ QByteArray QNetworkHeadersPrivate::toHttpDate(const QDateTime &dt) return QLocale::c().toString(dt.toUTC(), u"ddd, dd MMM yyyy hh:mm:ss 'GMT'").toLatin1(); } +QNetworkHeadersPrivate::RawHeadersList QNetworkHeadersPrivate::fromHttpToRaw(const QHttpHeaders &headers) +{ + if (headers.isEmpty()) + return {}; + + QNetworkHeadersPrivate::RawHeadersList list; + QHash<QByteArray, qsizetype> nameToIndex; + list.reserve(headers.size()); + nameToIndex.reserve(headers.size()); + + for (qsizetype i = 0; i < headers.size(); ++i) { + const auto nameL1 = headers.nameAt(i); + const auto value = headers.valueAt(i); + + const bool isSetCookie = nameL1 == QHttpHeaders::wellKnownHeaderName( + QHttpHeaders::WellKnownHeader::SetCookie); + + const auto name = QByteArray(nameL1.data(), nameL1.size()); + if (auto it = nameToIndex.find(name); it != nameToIndex.end()) { + list[it.value()].second += isSetCookie ? "\n" : ", "; + list[it.value()].second += value; + } else { + nameToIndex[name] = list.size(); + list.emplaceBack(name, value.toByteArray()); + } + } + + return list; +} + +QHttpHeaders QNetworkHeadersPrivate::fromRawToHttp(const RawHeadersList &raw) +{ + if (raw.empty()) + return {}; + + QHttpHeaders headers; + headers.reserve(raw.size()); + + for (const auto &[key, value] : raw) { + const bool isSetCookie = key.compare(QHttpHeaders::wellKnownHeaderName( + QHttpHeaders::WellKnownHeader::SetCookie), + Qt::CaseInsensitive) == 0; + if (isSetCookie) { + for (auto header : QLatin1StringView(value).tokenize('\n'_L1)) + headers.append(key, header); + } else { + headers.append(key, value); + } + } + + return headers; +} + QT_END_NAMESPACE #include "moc_qnetworkrequest.cpp" diff --git a/src/network/access/qnetworkrequest_p.h b/src/network/access/qnetworkrequest_p.h index 88fb8cb246..a73d8f2162 100644 --- a/src/network/access/qnetworkrequest_p.h +++ b/src/network/access/qnetworkrequest_p.h @@ -59,6 +59,9 @@ public: static QDateTime fromHttpDate(const QByteArray &value); static QByteArray toHttpDate(const QDateTime &dt); + static RawHeadersList fromHttpToRaw(const QHttpHeaders &headers); + static QHttpHeaders fromRawToHttp(const RawHeadersList &raw); + private: void setRawHeaderInternal(const QByteArray &key, const QByteArray &value); void parseAndSetHeader(const QByteArray &key, const QByteArray &value); |