access/qnetworkcookiejar.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
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 Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qnetworkcookiejar.h" -
43#include "qnetworkcookiejar_p.h" -
44 -
45#include "QtNetwork/qnetworkcookie.h" -
46#include "QtCore/qurl.h" -
47#include "QtCore/qdatetime.h" -
48#include "private/qtldurl_p.h" -
49 -
50QT_BEGIN_NAMESPACE -
51 -
52/*! -
53 \class QNetworkCookieJar -
54 \since 4.4 -
55 \inmodule QtNetwork -
56 -
57 \brief The QNetworkCookieJar class implements a simple jar of QNetworkCookie objects -
58 -
59 Cookies are small bits of information that stateless protocols -
60 like HTTP use to maintain some persistent information across -
61 requests. -
62 -
63 A cookie is set by a remote server when it replies to a request -
64 and it expects the same cookie to be sent back when further -
65 requests are sent. -
66 -
67 The cookie jar is the object that holds all cookies set in -
68 previous requests. Web browsers save their cookie jars to disk in -
69 order to conserve permanent cookies across invocations of the -
70 application. -
71 -
72 QNetworkCookieJar does not implement permanent storage: it only -
73 keeps the cookies in memory. Once the QNetworkCookieJar object is -
74 deleted, all cookies it held will be discarded as well. If you -
75 want to save the cookies, you should derive from this class and -
76 implement the saving to disk to your own storage format. -
77 -
78 This class implements only the basic security recommended by the -
79 cookie specifications and does not implement any cookie acceptance -
80 policy (it accepts all cookies set by any requests). In order to -
81 override those rules, you should reimplement the -
82 cookiesForUrl() and setCookiesFromUrl() virtual -
83 functions. They are called by QNetworkReply and -
84 QNetworkAccessManager when they detect new cookies and when they -
85 require cookies. -
86 -
87 \sa QNetworkCookie, QNetworkAccessManager, QNetworkReply, -
88 QNetworkRequest, QNetworkAccessManager::setCookieJar() -
89*/ -
90 -
91/*! -
92 Creates a QNetworkCookieJar object and sets the parent object to -
93 be \a parent. -
94 -
95 The cookie jar is initialized to empty. -
96*/ -
97QNetworkCookieJar::QNetworkCookieJar(QObject *parent) -
98 : QObject(*new QNetworkCookieJarPrivate, parent) -
99{ -
100}
executed: }
Execution Count:284
284
101 -
102/*! -
103 Destroys this cookie jar object and discards all cookies stored in -
104 it. Cookies are not saved to disk in the QNetworkCookieJar default -
105 implementation. -
106 -
107 If you need to save the cookies to disk, you have to derive from -
108 QNetworkCookieJar and save the cookies to disk yourself. -
109*/ -
110QNetworkCookieJar::~QNetworkCookieJar() -
111{ -
112} -
113 -
114/*! -
115 Returns all cookies stored in this cookie jar. This function is -
116 suitable for derived classes to save cookies to disk, as well as -
117 to implement cookie expiration and other policies. -
118 -
119 \sa setAllCookies(), cookiesForUrl() -
120*/ -
121QList<QNetworkCookie> QNetworkCookieJar::allCookies() const -
122{ -
123 return d_func()->allCookies;
executed: return d_func()->allCookies;
Execution Count:35
35
124} -
125 -
126/*! -
127 Sets the internal list of cookies held by this cookie jar to be \a -
128 cookieList. This function is suitable for derived classes to -
129 implement loading cookies from permanent storage, or their own -
130 cookie acceptance policies by reimplementing -
131 setCookiesFromUrl(). -
132 -
133 \sa allCookies(), setCookiesFromUrl() -
134*/ -
135void QNetworkCookieJar::setAllCookies(const QList<QNetworkCookie> &cookieList) -
136{ -
137 Q_D(QNetworkCookieJar);
executed (the execution status of this line is deduced): QNetworkCookieJarPrivate * const d = d_func();
-
138 d->allCookies = cookieList;
executed (the execution status of this line is deduced): d->allCookies = cookieList;
-
139}
executed: }
Execution Count:1255
1255
140 -
141static inline bool isParentPath(QString path, QString reference) -
142{ -
143 if (path.startsWith(reference)) {
evaluated: path.startsWith(reference)
TRUEFALSE
yes
Evaluation Count:206
yes
Evaluation Count:44
44-206
144 //The cookie-path and the request-path are identical. -
145 if (path.length() == reference.length())
evaluated: path.length() == reference.length()
TRUEFALSE
yes
Evaluation Count:24
yes
Evaluation Count:182
24-182
146 return true;
executed: return true;
Execution Count:24
24
147 //The cookie-path is a prefix of the request-path, and the last -
148 //character of the cookie-path is %x2F ("/"). -
149 if (reference.endsWith('/'))
evaluated: reference.endsWith('/')
TRUEFALSE
yes
Evaluation Count:161
yes
Evaluation Count:21
21-161
150 return true;
executed: return true;
Execution Count:161
161
151 //The cookie-path is a prefix of the request-path, and the first -
152 //character of the request-path that is not included in the cookie- -
153 //path is a %x2F ("/") character. -
154 if (path.at(reference.length()) == '/')
evaluated: path.at(reference.length()) == '/'
TRUEFALSE
yes
Evaluation Count:19
yes
Evaluation Count:2
2-19
155 return true;
executed: return true;
Execution Count:19
19
156 }
executed: }
Execution Count:2
2
157 return false;
executed: return false;
Execution Count:46
46
158} -
159 -
160static inline bool isParentDomain(QString domain, QString reference) -
161{ -
162 if (!reference.startsWith(QLatin1Char('.')))
evaluated: !reference.startsWith(QLatin1Char('.'))
TRUEFALSE
yes
Evaluation Count:437
yes
Evaluation Count:148
148-437
163 return domain == reference;
executed: return domain == reference;
Execution Count:437
437
164 -
165 return domain.endsWith(reference) || domain == reference.mid(1);
executed: return domain.endsWith(reference) || domain == reference.mid(1);
Execution Count:148
148
166} -
167 -
168/*! -
169 Adds the cookies in the list \a cookieList to this cookie -
170 jar. Before being inserted cookies are normalized. -
171 -
172 Returns true if one or more cookies are set for \a url, -
173 otherwise false. -
174 -
175 If a cookie already exists in the cookie jar, it will be -
176 overridden by those in \a cookieList. -
177 -
178 The default QNetworkCookieJar class implements only a very basic -
179 security policy (it makes sure that the cookies' domain and path -
180 match the reply's). To enhance the security policy with your own -
181 algorithms, override setCookiesFromUrl(). -
182 -
183 Also, QNetworkCookieJar does not have a maximum cookie jar -
184 size. Reimplement this function to discard older cookies to create -
185 room for new ones. -
186 -
187 \sa cookiesForUrl(), QNetworkAccessManager::setCookieJar(), QNetworkCookie::normalize() -
188*/ -
189bool QNetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, -
190 const QUrl &url) -
191{ -
192 bool added = false;
executed (the execution status of this line is deduced): bool added = false;
-
193 foreach (QNetworkCookie cookie, cookieList) {
executed (the execution status of this line is deduced): for (QForeachContainer<__typeof__(cookieList)> _container_(cookieList); !_container_.brk && _container_.i != _container_.e; __extension__ ({ ++_container_.brk; ++_container_.i; })) for (QNetworkCookie cookie = *_container_.i;; __extension__ ({--_container_.brk; break;})) {
-
194 cookie.normalize(url);
executed (the execution status of this line is deduced): cookie.normalize(url);
-
195 if (validateCookie(cookie, url) && insertCookie(cookie))
evaluated: validateCookie(cookie, url)
TRUEFALSE
yes
Evaluation Count:231
yes
Evaluation Count:22
evaluated: insertCookie(cookie)
TRUEFALSE
yes
Evaluation Count:220
yes
Evaluation Count:11
11-231
196 added = true;
executed: added = true;
Execution Count:220
220
197 }
executed: }
Execution Count:253
253
198 return added;
executed: return added;
Execution Count:251
251
199} -
200 -
201/*! -
202 Returns the cookies to be added to when a request is sent to -
203 \a url. This function is called by the default -
204 QNetworkAccessManager::createRequest(), which adds the -
205 cookies returned by this function to the request being sent. -
206 -
207 If more than one cookie with the same name is found, but with -
208 differing paths, the one with longer path is returned before the -
209 one with shorter path. In other words, this function returns -
210 cookies sorted decreasingly by path length. -
211 -
212 The default QNetworkCookieJar class implements only a very basic -
213 security policy (it makes sure that the cookies' domain and path -
214 match the reply's). To enhance the security policy with your own -
215 algorithms, override cookiesForUrl(). -
216 -
217 \sa setCookiesFromUrl(), QNetworkAccessManager::setCookieJar() -
218*/ -
219QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const -
220{ -
221// \b Warning! This is only a dumb implementation! -
222// It does NOT follow all of the recommendations from -
223// http://wp.netscape.com/newsref/std/cookie_spec.html -
224// It does not implement a very good cross-domain verification yet. -
225 -
226 Q_D(const QNetworkCookieJar);
executed (the execution status of this line is deduced): const QNetworkCookieJarPrivate * const d = d_func();
-
227 QDateTime now = QDateTime::currentDateTime();
executed (the execution status of this line is deduced): QDateTime now = QDateTime::currentDateTime();
-
228 QList<QNetworkCookie> result;
executed (the execution status of this line is deduced): QList<QNetworkCookie> result;
-
229 bool isEncrypted = url.scheme().toLower() == QLatin1String("https");
executed (the execution status of this line is deduced): bool isEncrypted = url.scheme().toLower() == QLatin1String("https");
-
230 -
231 // scan our cookies for something that matches -
232 QList<QNetworkCookie>::ConstIterator it = d->allCookies.constBegin(),
executed (the execution status of this line is deduced): QList<QNetworkCookie>::ConstIterator it = d->allCookies.constBegin(),
-
233 end = d->allCookies.constEnd();
executed (the execution status of this line is deduced): end = d->allCookies.constEnd();
-
234 for ( ; it != end; ++it) {
evaluated: it != end
TRUEFALSE
yes
Evaluation Count:270
yes
Evaluation Count:854
270-854
235 if (!isParentDomain(url.host(), it->domain()))
evaluated: !isParentDomain(url.host(), it->domain())
TRUEFALSE
yes
Evaluation Count:20
yes
Evaluation Count:250
20-250
236 continue;
executed: continue;
Execution Count:20
20
237 if (!isParentPath(url.path(), it->path()))
evaluated: !isParentPath(url.path(), it->path())
TRUEFALSE
yes
Evaluation Count:46
yes
Evaluation Count:204
46-204
238 continue;
executed: continue;
Execution Count:46
46
239 if (!(*it).isSessionCookie() && (*it).expirationDate() < now)
evaluated: !(*it).isSessionCookie()
TRUEFALSE
yes
Evaluation Count:14
yes
Evaluation Count:190
partially evaluated: (*it).expirationDate() < now
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:14
0-190
240 continue;
never executed: continue;
0
241 if ((*it).isSecure() && !isEncrypted)
evaluated: (*it).isSecure()
TRUEFALSE
yes
Evaluation Count:18
yes
Evaluation Count:186
evaluated: !isEncrypted
TRUEFALSE
yes
Evaluation Count:16
yes
Evaluation Count:2
2-186
242 continue;
executed: continue;
Execution Count:16
16
243 -
244 // insert this cookie into result, sorted by path -
245 QList<QNetworkCookie>::Iterator insertIt = result.begin();
executed (the execution status of this line is deduced): QList<QNetworkCookie>::Iterator insertIt = result.begin();
-
246 while (insertIt != result.end()) {
evaluated: insertIt != result.end()
TRUEFALSE
yes
Evaluation Count:28
yes
Evaluation Count:178
28-178
247 if (insertIt->path().length() < it->path().length()) {
evaluated: insertIt->path().length() < it->path().length()
TRUEFALSE
yes
Evaluation Count:10
yes
Evaluation Count:18
10-18
248 // insert here -
249 insertIt = result.insert(insertIt, *it);
executed (the execution status of this line is deduced): insertIt = result.insert(insertIt, *it);
-
250 break;
executed: break;
Execution Count:10
10
251 } else { -
252 ++insertIt;
executed (the execution status of this line is deduced): ++insertIt;
-
253 }
executed: }
Execution Count:18
18
254 } -
255 -
256 // this is the shortest path yet, just append -
257 if (insertIt == result.end())
evaluated: insertIt == result.end()
TRUEFALSE
yes
Evaluation Count:178
yes
Evaluation Count:10
10-178
258 result += *it;
executed: result += *it;
Execution Count:178
178
259 }
executed: }
Execution Count:188
188
260 -
261 return result;
executed: return result;
Execution Count:854
854
262} -
263 -
264/*! -
265 \since 5.0 -
266 Adds \a cookie to this cookie jar. -
267 -
268 Returns true if \a cookie was added, false otherwise. -
269 -
270 If a cookie with the same identifier already exists in the -
271 cookie jar, it will be overridden. -
272*/ -
273bool QNetworkCookieJar::insertCookie(const QNetworkCookie &cookie) -
274{ -
275 Q_D(QNetworkCookieJar);
executed (the execution status of this line is deduced): QNetworkCookieJarPrivate * const d = d_func();
-
276 QDateTime now = QDateTime::currentDateTime();
executed (the execution status of this line is deduced): QDateTime now = QDateTime::currentDateTime();
-
277 bool isDeletion = !cookie.isSessionCookie() &&
evaluated: !cookie.isSessionCookie()
TRUEFALSE
yes
Evaluation Count:27
yes
Evaluation Count:204
27-204
278 cookie.expirationDate() < now;
evaluated: cookie.expirationDate() < now
TRUEFALSE
yes
Evaluation Count:11
yes
Evaluation Count:16
11-16
279 -
280 deleteCookie(cookie);
executed (the execution status of this line is deduced): deleteCookie(cookie);
-
281 -
282 if (!isDeletion) {
evaluated: !isDeletion
TRUEFALSE
yes
Evaluation Count:220
yes
Evaluation Count:11
11-220
283 d->allCookies += cookie;
executed (the execution status of this line is deduced): d->allCookies += cookie;
-
284 return true;
executed: return true;
Execution Count:220
220
285 } -
286 return false;
executed: return false;
Execution Count:11
11
287} -
288 -
289/*! -
290 \since 5.0 -
291 If a cookie with the same identifier as \a cookie exists in this cookie jar -
292 it will be updated. This function uses insertCookie(). -
293 -
294 Returns true if \a cookie was updated, false if no cookie in the jar matches -
295 the identifier of \a cookie. -
296 -
297 \sa QNetworkCookie::hasSameIdentifier() -
298*/ -
299bool QNetworkCookieJar::updateCookie(const QNetworkCookie &cookie) -
300{ -
301 if (deleteCookie(cookie))
never evaluated: deleteCookie(cookie)
0
302 return insertCookie(cookie);
never executed: return insertCookie(cookie);
0
303 return false;
never executed: return false;
0
304} -
305 -
306/*! -
307 \since 5.0 -
308 Deletes from cookie jar the cookie found to have the same identifier as \a cookie. -
309 -
310 Returns true if a cookie was deleted, false otherwise. -
311 -
312 \sa QNetworkCookie::hasSameIdentifier() -
313*/ -
314bool QNetworkCookieJar::deleteCookie(const QNetworkCookie &cookie) -
315{ -
316 Q_D(QNetworkCookieJar);
executed (the execution status of this line is deduced): QNetworkCookieJarPrivate * const d = d_func();
-
317 QList<QNetworkCookie>::Iterator it;
executed (the execution status of this line is deduced): QList<QNetworkCookie>::Iterator it;
-
318 for (it = d->allCookies.begin(); it != d->allCookies.end(); it++)
evaluated: it != d->allCookies.end()
TRUEFALSE
yes
Evaluation Count:45
yes
Evaluation Count:224
45-224
319 if (it->hasSameIdentifier(cookie)) {
evaluated: it->hasSameIdentifier(cookie)
TRUEFALSE
yes
Evaluation Count:7
yes
Evaluation Count:38
7-38
320 d->allCookies.erase(it);
executed (the execution status of this line is deduced): d->allCookies.erase(it);
-
321 return true;
executed: return true;
Execution Count:7
7
322 } -
323 return false;
executed: return false;
Execution Count:224
224
324} -
325 -
326/*! -
327 \since 5.0 -
328 Returns true if the domain and path of \a cookie are valid, false otherwise. -
329 The \a url parameter is used to determine if the domain specified in the cookie -
330 is allowed. -
331*/ -
332bool QNetworkCookieJar::validateCookie(const QNetworkCookie &cookie, const QUrl &url) const -
333{ -
334 QString domain = cookie.domain();
executed (the execution status of this line is deduced): QString domain = cookie.domain();
-
335 if (!(isParentDomain(domain, url.host()) || isParentDomain(url.host(), domain)))
evaluated: isParentDomain(domain, url.host())
TRUEFALSE
yes
Evaluation Count:191
yes
Evaluation Count:62
evaluated: isParentDomain(url.host(), domain)
TRUEFALSE
yes
Evaluation Count:47
yes
Evaluation Count:15
15-191
336 return false; // not accepted
executed: return false;
Execution Count:15
15
337 -
338 // the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2 -
339 // redundant; the "leading dot" rule has been relaxed anyway, see QNetworkCookie::normalize() -
340 // we remove the leading dot for this check if it's present -
341 if (qIsEffectiveTLD(domain.startsWith('.') ? domain.remove(0, 1) : domain))
evaluated: qIsEffectiveTLD(domain.startsWith('.') ? domain.remove(0, 1) : domain)
TRUEFALSE
yes
Evaluation Count:7
yes
Evaluation Count:231
7-231
342 return false; // not accepted
executed: return false;
Execution Count:7
7
343 -
344 return true;
executed: return true;
Execution Count:231
231
345} -
346 -
347QT_END_NAMESPACE -
348 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial