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 | |
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 | */ |
130 | bool 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 | */ |
150 | bool 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 | */ |
167 | bool 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 | */ |
178 | void 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 | */ |
188 | QUrl 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 | */ |
200 | void 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 | */ |
214 | QNetworkCacheMetaData::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 | */ |
224 | void 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 | */ |
236 | QHttpHeaders 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 | */ |
248 | void 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 | */ |
256 | QDateTime 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 | */ |
264 | void 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 | */ |
272 | QDateTime 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 | */ |
280 | void 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 | */ |
292 | QNetworkCacheMetaData::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 | */ |
304 | void 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 | */ |
317 | QDataStream &operator<<(QDataStream &out, const QNetworkCacheMetaData &metaData) |
318 | { |
319 | QNetworkCacheMetaDataPrivate::save(out, metaData); |
320 | return out; |
321 | } |
322 | |
323 | static 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 | |
335 | void 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 | */ |
355 | QDataStream &operator>>(QDataStream &in, QNetworkCacheMetaData &metaData) |
356 | { |
357 | QNetworkCacheMetaDataPrivate::load(in, metaData); |
358 | return in; |
359 | } |
360 | |
361 | static 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 | |
388 | void 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 | */ |
417 | QAbstractNetworkCache::QAbstractNetworkCache(QObject *parent) |
418 | : QObject(*new QAbstractNetworkCachePrivate, parent) |
419 | { |
420 | } |
421 | |
422 | /*! |
423 | \internal |
424 | */ |
425 | QAbstractNetworkCache::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 | */ |
437 | QAbstractNetworkCache::~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 | |
538 | QT_END_NAMESPACE |
539 | |
540 | #include "moc_qabstractnetworkcache.cpp" |
541 |
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 to use CMake with our Intro Training
Find out more