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

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