1// Copyright (C) 2016 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
4#include "qabstractnetworkcache.h"
5#include "qabstractnetworkcache_p.h"
6#include "qnetworkrequest_p.h"
7#include "qhttpheadershelper_p.h"
8
9#include <qdatastream.h>
10#include <qdatetime.h>
11#include <qurl.h>
12#include <qhash.h>
13
14#include <qdebug.h>
15
16QT_BEGIN_NAMESPACE
17
18class QNetworkCacheMetaDataPrivate : public QSharedData
19{
20
21public:
22 QNetworkCacheMetaDataPrivate()
23 : QSharedData()
24 , saveToDisk(true)
25 {}
26
27 bool operator==(const QNetworkCacheMetaDataPrivate &other) const
28 {
29 return
30 url == other.url
31 && lastModified == other.lastModified
32 && expirationDate == other.expirationDate
33 && saveToDisk == other.saveToDisk
34 && QHttpHeadersHelper::compareStrict(left: headers, right: other.headers);
35 }
36
37 QUrl url;
38 QDateTime lastModified;
39 QDateTime expirationDate;
40 QHttpHeaders headers;
41 QNetworkCacheMetaData::AttributesMap attributes;
42 bool saveToDisk;
43
44 static void save(QDataStream &out, const QNetworkCacheMetaData &metaData);
45 static void load(QDataStream &in, QNetworkCacheMetaData &metaData);
46};
47Q_GLOBAL_STATIC(QNetworkCacheMetaDataPrivate, metadata_shared_invalid)
48
49/*!
50 \class QNetworkCacheMetaData
51 \since 4.5
52 \ingroup shared
53 \inmodule QtNetwork
54
55 \brief The QNetworkCacheMetaData class provides cache information.
56
57 QNetworkCacheMetaData provides information about a cache file including
58 the url, when it was last modified, when the cache file was created, headers
59 for file and if the file should be saved onto a disk.
60
61 \sa QAbstractNetworkCache
62*/
63
64/*!
65 \typedef QNetworkCacheMetaData::RawHeader
66
67 Synonym for QPair<QByteArray, QByteArray>
68*/
69
70/*!
71 \typedef QNetworkCacheMetaData::RawHeaderList
72
73 Synonym for QList<RawHeader>
74*/
75
76/*!
77 \typedef QNetworkCacheMetaData::AttributesMap
78
79 Synonym for QHash<QNetworkRequest::Attribute, QVariant>
80*/
81
82/*!
83 Constructs an invalid network cache meta data.
84
85 \sa isValid()
86 */
87QNetworkCacheMetaData::QNetworkCacheMetaData()
88 : d(new QNetworkCacheMetaDataPrivate)
89{
90}
91
92/*!
93 Destroys the network cache meta data.
94 */
95QNetworkCacheMetaData::~QNetworkCacheMetaData()
96{
97 // QSharedDataPointer takes care of freeing d
98}
99
100/*!
101 Constructs a copy of the \a other QNetworkCacheMetaData.
102 */
103QNetworkCacheMetaData::QNetworkCacheMetaData(const QNetworkCacheMetaData &other)
104 : d(other.d)
105{
106}
107
108/*!
109 Makes a copy of the \a other QNetworkCacheMetaData and returns a reference to the copy.
110 */
111QNetworkCacheMetaData &QNetworkCacheMetaData::operator=(const QNetworkCacheMetaData &other)
112{
113 d = other.d;
114 return *this;
115}
116
117/*!
118 \fn void QNetworkCacheMetaData::swap(QNetworkCacheMetaData &other)
119 \since 5.0
120
121 Swaps this metadata instance with \a other. This function is very
122 fast and never fails.
123 */
124
125/*!
126 Returns \c true if this meta data is equal to the \a other meta data; otherwise returns \c false.
127
128 \sa operator!=()
129 */
130bool QNetworkCacheMetaData::operator==(const QNetworkCacheMetaData &other) const
131{
132 if (d == other.d)
133 return true;
134 if (d && other.d)
135 return *d == *other.d;
136 return false;
137}
138
139/*!
140 \fn bool QNetworkCacheMetaData::operator!=(const QNetworkCacheMetaData &other) const
141
142 Returns \c true if this meta data is not equal to the \a other meta data; otherwise returns \c false.
143
144 \sa operator==()
145 */
146
147/*!
148 Returns \c true if this network cache meta data has attributes that have been set otherwise false.
149 */
150bool QNetworkCacheMetaData::isValid() const
151{
152 return !(*d == *metadata_shared_invalid());
153}
154
155/*!
156 Returns is this cache should be allowed to be stored on disk.
157
158 Some cache implementations can keep these cache items in memory for performance reasons,
159 but for security reasons they should not be written to disk.
160
161 Specifically with http, documents with Cache-control set to no-store or any
162 https document that doesn't have "Cache-control: public" set will
163 set the saveToDisk to false.
164
165 \sa setSaveToDisk()
166 */
167bool QNetworkCacheMetaData::saveToDisk() const
168{
169 return d->saveToDisk;
170}
171
172/*!
173 Sets whether this network cache meta data and associated content should be
174 allowed to be stored on disk to \a allow.
175
176 \sa saveToDisk()
177 */
178void QNetworkCacheMetaData::setSaveToDisk(bool allow)
179{
180 d->saveToDisk = allow;
181}
182
183/*!
184 Returns the URL this network cache meta data is referring to.
185
186 \sa setUrl()
187 */
188QUrl QNetworkCacheMetaData::url() const
189{
190 return d->url;
191}
192
193/*!
194 Sets the URL this network cache meta data to be \a url.
195
196 The password and fragment are removed from the url.
197
198 \sa url()
199 */
200void QNetworkCacheMetaData::setUrl(const QUrl &url)
201{
202 auto *p = d.data();
203 p->url = url;
204 p->url.setPassword(password: QString());
205 p->url.setFragment(fragment: QString());
206}
207
208/*!
209 Returns a list of all raw headers that are set in this meta data.
210 The list is in the same order that the headers were set.
211
212 \sa setRawHeaders(), headers()
213 */
214QNetworkCacheMetaData::RawHeaderList QNetworkCacheMetaData::rawHeaders() const
215{
216 return QNetworkHeadersPrivate::fromHttpToRaw(headers: d->headers);
217}
218
219/*!
220 Sets the raw headers to \a list.
221
222 \sa rawHeaders(), setHeaders()
223 */
224void QNetworkCacheMetaData::setRawHeaders(const RawHeaderList &list)
225{
226 d->headers = QNetworkHeadersPrivate::fromRawToHttp(raw: list);
227}
228
229/*!
230 \since 6.8
231
232 Returns headers in form of QHttpHeaders that are set in this meta data.
233
234 \sa setHeaders()
235*/
236QHttpHeaders QNetworkCacheMetaData::headers() const
237{
238 return d->headers;
239}
240
241/*!
242 \since 6.8
243
244 Sets the headers of this network cache meta data to \a headers.
245
246 \sa headers()
247*/
248void QNetworkCacheMetaData::setHeaders(const QHttpHeaders &headers)
249{
250 d->headers = headers;
251}
252
253/*!
254 Returns the date and time when the meta data was last modified.
255 */
256QDateTime QNetworkCacheMetaData::lastModified() const
257{
258 return d->lastModified;
259}
260
261/*!
262 Sets the date and time when the meta data was last modified to \a dateTime.
263 */
264void QNetworkCacheMetaData::setLastModified(const QDateTime &dateTime)
265{
266 d->lastModified = dateTime;
267}
268
269/*!
270 Returns the date and time when the meta data expires.
271 */
272QDateTime QNetworkCacheMetaData::expirationDate() const
273{
274 return d->expirationDate;
275}
276
277/*!
278 Sets the date and time when the meta data expires to \a dateTime.
279 */
280void QNetworkCacheMetaData::setExpirationDate(const QDateTime &dateTime)
281{
282 d->expirationDate = dateTime;
283}
284
285/*!
286 \since 4.6
287
288 Returns all the attributes stored with this cache item.
289
290 \sa setAttributes(), QNetworkRequest::Attribute
291*/
292QNetworkCacheMetaData::AttributesMap QNetworkCacheMetaData::attributes() const
293{
294 return d->attributes;
295}
296
297/*!
298 \since 4.6
299
300 Sets all attributes of this cache item to be the map \a attributes.
301
302 \sa attributes(), QNetworkRequest::setAttribute()
303*/
304void QNetworkCacheMetaData::setAttributes(const AttributesMap &attributes)
305{
306 d->attributes = attributes;
307}
308
309/*!
310 \relates QNetworkCacheMetaData
311 \since 4.5
312
313 Writes \a metaData to the \a out stream.
314
315 \sa {Serializing Qt Data Types}
316*/
317QDataStream &operator<<(QDataStream &out, const QNetworkCacheMetaData &metaData)
318{
319 QNetworkCacheMetaDataPrivate::save(out, metaData);
320 return out;
321}
322
323static inline QDataStream &operator<<(QDataStream &out, const QNetworkCacheMetaData::AttributesMap &hash)
324{
325 out << quint32(hash.size());
326 QNetworkCacheMetaData::AttributesMap::ConstIterator it = hash.begin();
327 QNetworkCacheMetaData::AttributesMap::ConstIterator end = hash.end();
328 while (it != end) {
329 out << int(it.key()) << it.value();
330 ++it;
331 }
332 return out;
333}
334
335void QNetworkCacheMetaDataPrivate::save(QDataStream &out, const QNetworkCacheMetaData &metaData)
336{
337 // note: if you change the contents of the meta data here
338 // remember to bump the cache version in qnetworkdiskcache.cpp CurrentCacheVersion
339 out << metaData.url();
340 out << metaData.expirationDate();
341 out << metaData.lastModified();
342 out << metaData.saveToDisk();
343 out << metaData.attributes();
344 out << metaData.rawHeaders();
345}
346
347/*!
348 \relates QNetworkCacheMetaData
349 \since 4.5
350
351 Reads a QNetworkCacheMetaData from the stream \a in into \a metaData.
352
353 \sa {Serializing Qt Data Types}
354*/
355QDataStream &operator>>(QDataStream &in, QNetworkCacheMetaData &metaData)
356{
357 QNetworkCacheMetaDataPrivate::load(in, metaData);
358 return in;
359}
360
361static inline QDataStream &operator>>(QDataStream &in, QNetworkCacheMetaData::AttributesMap &hash)
362{
363 hash.clear();
364 QDataStream::Status oldStatus = in.status();
365 in.resetStatus();
366 hash.clear();
367
368 quint32 n;
369 in >> n;
370
371 for (quint32 i = 0; i < n; ++i) {
372 if (in.status() != QDataStream::Ok)
373 break;
374
375 int k;
376 QVariant t;
377 in >> k >> t;
378 hash.insert(key: QNetworkRequest::Attribute(k), value: t);
379 }
380
381 if (in.status() != QDataStream::Ok)
382 hash.clear();
383 if (oldStatus != QDataStream::Ok)
384 in.setStatus(oldStatus);
385 return in;
386}
387
388void QNetworkCacheMetaDataPrivate::load(QDataStream &in, QNetworkCacheMetaData &metaData)
389{
390 auto *p = metaData.d.data();
391 in >> p->url;
392 in >> p->expirationDate;
393 in >> p->lastModified;
394 in >> p->saveToDisk;
395 in >> p->attributes;
396 QNetworkCacheMetaData::RawHeaderList list; in >> list;
397 metaData.setRawHeaders(list);
398}
399
400/*!
401 \class QAbstractNetworkCache
402 \since 4.5
403 \inmodule QtNetwork
404
405 \brief The QAbstractNetworkCache class provides the interface for cache implementations.
406
407 QAbstractNetworkCache is the base class for every standard cache that is used by
408 QNetworkAccessManager. QAbstractNetworkCache is an abstract class and cannot be
409 instantiated.
410
411 \sa QNetworkDiskCache
412*/
413
414/*!
415 Constructs an abstract network cache with the given \a parent.
416*/
417QAbstractNetworkCache::QAbstractNetworkCache(QObject *parent)
418 : QObject(*new QAbstractNetworkCachePrivate, parent)
419{
420}
421
422/*!
423 \internal
424*/
425QAbstractNetworkCache::QAbstractNetworkCache(QAbstractNetworkCachePrivate &dd, QObject *parent)
426 : QObject(dd, parent)
427{
428}
429
430/*!
431 Destroys the cache.
432
433 Any operations that have not been inserted are discarded.
434
435 \sa insert()
436 */
437QAbstractNetworkCache::~QAbstractNetworkCache()
438{
439}
440
441/*!
442 \fn QNetworkCacheMetaData QAbstractNetworkCache::metaData(const QUrl &url) = 0
443 Returns the meta data for the url \a url.
444
445 If the url is valid and the cache contains the data for url,
446 a valid QNetworkCacheMetaData is returned.
447
448 In the base class this is a pure virtual function.
449
450 \sa updateMetaData(), data()
451*/
452
453/*!
454 \fn void QAbstractNetworkCache::updateMetaData(const QNetworkCacheMetaData &metaData) = 0
455 Updates the cache meta date for the metaData's url to \a metaData
456
457 If the cache does not contains a cache item for the url then no action is taken.
458
459 In the base class this is a pure virtual function.
460
461 \sa metaData(), prepare()
462*/
463
464/*!
465 \fn QIODevice *QAbstractNetworkCache::data(const QUrl &url) = 0
466 Returns the data associated with \a url.
467
468 It is up to the application that requests the data to delete
469 the QIODevice when done with it.
470
471 If there is no cache for \a url, the url is invalid, or if there
472 is an internal cache error \nullptr is returned.
473
474 In the base class this is a pure virtual function.
475
476 \sa metaData(), prepare()
477*/
478
479/*!
480 \fn bool QAbstractNetworkCache::remove(const QUrl &url) = 0
481 Removes the cache entry for \a url, returning true if success otherwise false.
482
483 In the base class this is a pure virtual function.
484
485 \sa clear(), prepare()
486*/
487
488/*!
489 \fn QIODevice *QAbstractNetworkCache::prepare(const QNetworkCacheMetaData &metaData) = 0
490 Returns the device that should be populated with the data for
491 the cache item \a metaData. When all of the data has been written
492 insert() should be called. If metaData is invalid or the url in
493 the metadata is invalid \nullptr is returned.
494
495 The cache owns the device and will take care of deleting it when
496 it is inserted or removed.
497
498 To cancel a prepared inserted call remove() on the metadata's url.
499
500 In the base class this is a pure virtual function.
501
502 \sa remove(), updateMetaData(), insert()
503*/
504
505/*!
506 \fn void QAbstractNetworkCache::insert(QIODevice *device) = 0
507 Inserts the data in \a device and the prepared meta data into the cache.
508 After this function is called the data and meta data should be retrievable
509 using data() and metaData().
510
511 To cancel a prepared inserted call remove() on the metadata's url.
512
513 In the base class this is a pure virtual function.
514
515 \sa prepare(), remove()
516*/
517
518/*!
519 \fn qint64 QAbstractNetworkCache::cacheSize() const = 0
520 Returns the current size taken up by the cache. Depending upon
521 the cache implementation this might be disk or memory size.
522
523 In the base class this is a pure virtual function.
524
525 \sa clear()
526*/
527
528/*!
529 \fn void QAbstractNetworkCache::clear() = 0
530 Removes all items from the cache. Unless there was failures
531 clearing the cache cacheSize() should return 0 after a call to clear.
532
533 In the base class this is a pure virtual function.
534
535 \sa cacheSize(), remove()
536*/
537
538QT_END_NAMESPACE
539
540#include "moc_qabstractnetworkcache.cpp"
541

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/src/network/access/qabstractnetworkcache.cpp