Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qnetworkcookiejar.cpp
Go to the documentation of this file.
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 "qnetworkcookiejar.h"
6
7#include "QtNetwork/qnetworkcookie.h"
8#include "QtCore/qurl.h"
9#include "QtCore/qdatetime.h"
10#if QT_CONFIG(topleveldomain)
11#include "private/qtldurl_p.h"
12#else
14static bool qIsEffectiveTLD(QStringView domain)
15{
16 // provide minimal checking by not accepting cookies on real TLDs
17 return !domain.contains(u'.');
18}
20#endif
21
23
24using namespace Qt::StringLiterals;
25
75
87
95QList<QNetworkCookie> QNetworkCookieJar::allCookies() const
96{
97 return d_func()->allCookies;
98}
99
109void QNetworkCookieJar::setAllCookies(const QList<QNetworkCookie> &cookieList)
110{
112 d->allCookies = cookieList;
113}
114
116{
117 if ((path.isEmpty() && reference == "/"_L1) || path.startsWith(reference)) {
118 //The cookie-path and the request-path are identical.
119 if (path.size() == reference.size())
120 return true;
121 //The cookie-path is a prefix of the request-path, and the last
122 //character of the cookie-path is %x2F ("/").
123 if (reference.endsWith(u'/'))
124 return true;
125 //The cookie-path is a prefix of the request-path, and the first
126 //character of the request-path that is not included in the cookie-
127 //path is a %x2F ("/") character.
128 if (path.at(reference.size()) == u'/')
129 return true;
130 }
131 return false;
132}
133
135{
136 if (!reference.startsWith(u'.'))
137 return domain == reference;
138
139 return domain.endsWith(reference) || domain == reference.mid(1);
140}
141
163bool QNetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList,
164 const QUrl &url)
165{
166 bool added = false;
167 for (QNetworkCookie cookie : cookieList) {
168 cookie.normalize(url);
169 if (validateCookie(cookie, url) && insertCookie(cookie))
170 added = true;
171 }
172 return added;
173}
174
193QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const
194{
195// \b Warning! This is only a dumb implementation!
196// It does NOT follow all of the recommendations from
197// http://wp.netscape.com/newsref/std/cookie_spec.html
198// It does not implement a very good cross-domain verification yet.
199
200 Q_D(const QNetworkCookieJar);
202 QList<QNetworkCookie> result;
203 const bool isEncrypted = url.scheme() == "https"_L1;
204
205 // scan our cookies for something that matches
206 for (const auto &cookie : std::as_const(d->allCookies)) {
207 if (!isEncrypted && cookie.isSecure())
208 continue;
209 if (!cookie.isSessionCookie() && cookie.expirationDate() < now)
210 continue;
211 const QString urlHost = url.host();
212 const QString cookieDomain = cookie.domain();
213 if (!isParentDomain(urlHost, cookieDomain))
214 continue;
215 if (!isParentPath(url.path(), cookie.path()))
216 continue;
217
218 QStringView domain = cookieDomain;
219 if (domain.startsWith(u'.'))
220 domain = domain.sliced(1);
221#if QT_CONFIG(topleveldomain)
222 if (urlHost != domain && qIsEffectiveTLD(domain))
223 continue;
224#else
225 if (!domain.contains(u'.') && urlHost != domain)
226 continue;
227#endif // topleveldomain
228
229 result += cookie;
230 }
231
232 auto longerPath = [](const auto &c1, const auto &c2)
233 { return c1.path().size() > c2.path().size(); };
234 std::sort(result.begin(), result.end(), longerPath);
235 return result;
236}
237
248{
251 bool isDeletion = !cookie.isSessionCookie() &&
252 cookie.expirationDate() < now;
253
254 deleteCookie(cookie);
255
256 if (!isDeletion) {
257 d->allCookies += cookie;
258 return true;
259 }
260 return false;
261}
262
274{
275 if (deleteCookie(cookie))
276 return insertCookie(cookie);
277 return false;
278}
279
289{
291 const auto it = std::find_if(d->allCookies.cbegin(), d->allCookies.cend(),
292 [&cookie](const auto &c) { return c.hasSameIdentifier(cookie); });
293 if (it != d->allCookies.cend()) {
294 d->allCookies.erase(it);
295 return true;
296 }
297 return false;
298}
299
307{
308 const QString cookieDomain = cookie.domain();
309 QStringView domain = cookieDomain;
310 const QString host = url.host();
311 if (!isParentDomain(domain, host) && !isParentDomain(host, domain))
312 return false; // not accepted
313
314 if (domain.startsWith(u'.'))
315 domain = domain.sliced(1);
316
317 // We shouldn't reject if:
318 // "[...] the domain-attribute is identical to the canonicalized request-host"
319 // https://tools.ietf.org/html/rfc6265#section-5.3 step 5
320 if (host == domain)
321 return true;
322 // the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2
323 // redundant; the "leading dot" rule has been relaxed anyway, see QNetworkCookie::normalize()
324 // we remove the leading dot for this check if it's present
325 // Normally defined in qtldurl_p.h, but uses fall-back in this file when topleveldomain isn't
326 // configured:
327 return !qIsEffectiveTLD(domain);
328}
329
331
332#include "moc_qnetworkcookiejar.cpp"
\inmodule QtCore\reentrant
Definition qdatetime.h:283
static QDateTime currentDateTimeUtc()
The QNetworkCookieJar class implements a simple jar of QNetworkCookie objects.
void setAllCookies(const QList< QNetworkCookie > &cookieList)
Sets the internal list of cookies held by this cookie jar to be cookieList.
virtual ~QNetworkCookieJar()
Destroys this cookie jar object and discards all cookies stored in it.
QList< QNetworkCookie > allCookies() const
Returns all cookies stored in this cookie jar.
virtual QList< QNetworkCookie > cookiesForUrl(const QUrl &url) const
Returns the cookies to be added to when a request is sent to url.
virtual bool insertCookie(const QNetworkCookie &cookie)
QNetworkCookieJar(QObject *parent=nullptr)
Creates a QNetworkCookieJar object and sets the parent object to be parent.
virtual bool updateCookie(const QNetworkCookie &cookie)
virtual bool validateCookie(const QNetworkCookie &cookie, const QUrl &url) const
virtual bool deleteCookie(const QNetworkCookie &cookie)
virtual bool setCookiesFromUrl(const QList< QNetworkCookie > &cookieList, const QUrl &url)
Adds the cookies in the list cookieList to this cookie jar.
The QNetworkCookie class holds one network cookie.
bool isSessionCookie() const
Returns true if this cookie is a session cookie.
QString domain() const
Returns the domain this cookie is associated with.
QDateTime expirationDate() const
Returns the expiration date for this cookie.
\inmodule QtCore
Definition qobject.h:103
const_iterator cend() const noexcept
Definition qset.h:142
\inmodule QtCore
Definition qstringview.h:78
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
bool startsWith(QStringView s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
bool endsWith(QStringView s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
constexpr QStringView sliced(qsizetype pos) const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qurl.h:94
QString host(ComponentFormattingOptions=FullyDecoded) const
Returns the host of the URL if it is defined; otherwise an empty string is returned.
Definition qurl.cpp:2340
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1991
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
Definition qurl.cpp:2468
QSet< QString >::iterator it
Combined button and popup list for selecting options.
static bool isEncrypted(const my_mach_header *header)
static QT_BEGIN_NAMESPACE bool qIsEffectiveTLD(QStringView domain)
static bool isParentDomain(QStringView domain, QStringView reference)
static bool isParentPath(QStringView path, QStringView reference)
GLint reference
const GLubyte * c
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
QUrl url("example.com")
[constructor-url-reference]
MyCustomStruct c2