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