12#include <QNetworkCookie>
15#include <QtConcurrentRun>
22 : QNetworkCookieJar (parent)
28 FilterTrackingCookies_ = filter;
38 MatchDomainExactly_ = enabled;
53 auto cookies = allCookies ();
55 for (
const auto& cookie : cookies)
57 result += cookie.toRawForm ();
65 bool IsExpired (
const QNetworkCookie& cookie,
const QDateTime& now)
67 return !cookie.isSessionCookie () && cookie.expirationDate () < now;
74 for (
const auto& ba : data.split (
'\n'))
75 cookies << QNetworkCookie::parseCookies (ba);
77 const auto& now = QDateTime::currentDateTime ();
78 for (
const auto& cookie : cookies)
80 if (FilterTrackingCookies_ &&
81 cookie.name ().startsWith (
"__utm"))
84 if (IsExpired (cookie, now))
87 filteredCookies << cookie;
90 setAllCookies (filteredCookies);
95 const auto& cookies = allCookies ();
97 const auto& now = QDateTime::currentDateTime ();
98 for (
const auto& cookie : cookies)
100 if (IsExpired (cookie, now))
103 if (result.contains (cookie))
108 qDebug () << Q_FUNC_INFO << cookies.size () << result.size ();
109 setAllCookies (result);
118 for (
const auto& cookie : QNetworkCookieJar::cookiesForUrl (url))
119 if (!filtered.contains (cookie))
126 bool MatchDomain (
const QString& rawDomain,
const QString& rawCookieDomain)
128 auto normalize = [] (QStringView s)
130 return s.startsWith (
'.') ? s.mid (1) : s;
132 const auto& domain = normalize (rawDomain);
133 const auto& cookieDomain = normalize (rawCookieDomain);
135 if (domain == cookieDomain)
138 const auto idx = domain.indexOf (cookieDomain);
139 return idx > 0 && domain.at (idx - 1) ==
'.';
144 return std::any_of (list.begin (), list.end (),
145 [&str] (
const auto& rx) { return str == rx.pattern () || rx.exactMatch (str); });
150 QList<QNetworkCookie> Added_;
151 QList<QNetworkCookie> Removed_;
154 auto CookieToTuple (
const QNetworkCookie& c)
156 return std::make_tuple (c.isHttpOnly (),
158 c.isSessionCookie (),
163 c.expirationDate ());
168 bool operator() (
const QNetworkCookie& left,
const QNetworkCookie& right)
const
170 return CookieToTuple (left) < CookieToTuple (right);
174 CookiesDiff CheckDifferences (
const QList<QNetworkCookie>& previousList,
175 const QList<QNetworkCookie>& currentList)
177 using Set_t = std::set<QNetworkCookie, CookieLess>;
178 Set_t previous { previousList.begin (), previousList.end () };
179 Set_t current { currentList.begin (), currentList.end () };
182 std::set_difference (previous.begin (), previous.end (),
183 current.begin (), current.end (),
184 std::back_inserter (diff.Removed_),
186 std::set_difference (current.begin (), current.end (),
187 previous.begin (), previous.end (),
188 std::back_inserter (diff.Added_),
200 filtered.reserve (cookieList.size ());
201 for (
auto cookie : cookieList)
203 if (cookie.domain ().isEmpty ())
204 cookie.setDomain (url.host ());
206 bool checkWhitelist =
false;
209 if (checkWhitelist && Check (WL_, cookie.domain ()))
213 if (MatchDomainExactly_ && !MatchDomain (url.host (), cookie.domain ()))
215 checkWhitelist =
true;
219 if (FilterTrackingCookies_ &&
220 cookie.name ().startsWith (
"__utm"))
222 checkWhitelist =
true;
226 if (!Check (BL_, cookie.domain ()))
231 if (existing.isEmpty ())
234 Util::Sequence (
this, QtConcurrent::run (CheckDifferences, existing, filtered)) >>
235 [
this] (
const CookiesDiff& diff)
237 if (!diff.Removed_.isEmpty ())
239 if (!diff.Added_.isEmpty ())
243 return QNetworkCookieJar::setCookiesFromUrl (filtered, url);
void SetBlacklist(const QList< QRegExp > &list)
Sets the cookies blacklist.
void SetFilterTrackingCookies(bool filter)
void SetWhitelist(const QList< QRegExp > &list)
Sets the cookies whitelist.
void SetEnabled(bool enabled)
Enables or disables the cookies.
void SetExactDomainMatch(bool enabled)
Sets whether exact domain matching is enabled.
void cookiesRemoved(const QList< QNetworkCookie > &)
bool setCookiesFromUrl(const QList< QNetworkCookie > &cookieList, const QUrl &url) override
Adds the cookieList for the given url to the jar.
void Load(const QByteArray &data)
QList< QNetworkCookie > cookiesForUrl(const QUrl &url) const override
Returns cookies for the given url.
void cookiesAdded(const QList< QNetworkCookie > &)
CustomCookieJar(QObject *parent=nullptr)
Constructs the cookie jar.
detail::ScopeGuard< F > MakeScopeGuard(const F &f)
Returns an object performing passed function on scope exit.