33 #include <QNetworkCookie>
36 #include <QtConcurrentRun>
45 : QNetworkCookieJar (parent)
49 void CustomCookieJar::SetFilterTrackingCookies (
bool filter)
51 FilterTrackingCookies_ = filter;
54 void CustomCookieJar::SetEnabled (
bool enabled)
59 void CustomCookieJar::SetExactDomainMatch (
bool enabled)
61 MatchDomainExactly_ = enabled;
74 QByteArray CustomCookieJar::Save ()
const
76 auto cookies = allCookies ();
78 for (
const auto& cookie : cookies)
80 result += cookie.toRawForm ();
88 bool IsExpired (
const QNetworkCookie& cookie,
const QDateTime& now)
90 return !cookie.isSessionCookie () && cookie.expirationDate () < now;
94 void CustomCookieJar::Load (
const QByteArray& data)
97 for (
const auto& ba : data.split (
'\n'))
98 cookies << QNetworkCookie::parseCookies (ba);
100 const auto& now = QDateTime::currentDateTime ();
101 for (
const auto& cookie : cookies)
103 if (FilterTrackingCookies_ &&
104 cookie.name ().startsWith (
"__utm"))
107 if (IsExpired (cookie, now))
110 filteredCookies << cookie;
112 emit cookiesAdded (filteredCookies);
113 setAllCookies (filteredCookies);
116 void CustomCookieJar::CollectGarbage ()
118 const auto& cookies = allCookies ();
120 const auto& now = QDateTime::currentDateTime ();
121 for (
const auto& cookie : cookies)
123 if (IsExpired (cookie, now))
126 if (result.contains (cookie))
131 qDebug () << Q_FUNC_INFO << cookies.size () << result.size ();
132 setAllCookies (result);
141 for (
const auto& cookie : QNetworkCookieJar::cookiesForUrl (url))
142 if (!filtered.contains (cookie))
149 bool MatchDomain (QString domain, QString cookieDomain)
151 auto normalize = [] (QString& s)
153 if (s.startsWith (
'.'))
157 normalize (cookieDomain);
159 if (domain == cookieDomain)
162 const auto idx = domain.indexOf (cookieDomain);
163 return idx > 0 && domain.at (idx - 1) ==
'.';
168 for (
auto& rx : list)
169 if (str == rx.pattern () || rx.exactMatch (str))
181 auto CookieToTuple (
const QNetworkCookie& c)
183 return std::make_tuple (c.isHttpOnly (),
185 c.isSessionCookie (),
190 c.expirationDate ());
195 bool operator() (
const QNetworkCookie& left,
const QNetworkCookie& right)
const
197 return CookieToTuple (left) < CookieToTuple (right);
204 using Set_t = std::set<QNetworkCookie, CookieLess>;
205 Set_t previous { previousList.begin (), previousList.end () };
206 Set_t current { currentList.begin (), currentList.end () };
209 std::set_difference (previous.begin (), previous.end (),
210 current.begin (), current.end (),
211 std::back_inserter (diff.Removed_),
213 std::set_difference (current.begin (), current.end (),
214 previous.begin (), previous.end (),
215 std::back_inserter (diff.Added_),
227 filtered.reserve (cookieList.size ());
228 for (
auto cookie : cookieList)
230 if (cookie.domain ().isEmpty ())
231 cookie.setDomain (url.host ());
233 bool checkWhitelist =
false;
236 if (checkWhitelist && Check (WL_, cookie.domain ()))
240 if (MatchDomainExactly_ && !MatchDomain (url.host (), cookie.domain ()))
242 checkWhitelist =
true;
246 if (FilterTrackingCookies_ &&
247 cookie.name ().startsWith (
"__utm"))
249 checkWhitelist =
true;
253 if (!Check (BL_, cookie.domain ()))
257 const auto& existing = cookiesForUrl (url);
258 if (existing.isEmpty ())
259 emit cookiesAdded (filtered);
261 Util::Sequence (
this, QtConcurrent::run (CheckDifferences, existing, filtered)) >>
262 [
this] (
const CookiesDiff& diff)
264 if (!diff.Removed_.isEmpty ())
265 emit cookiesRemoved (diff.Removed_);
266 if (!diff.Added_.isEmpty ())
267 emit cookiesAdded (diff.Added_);
270 return QNetworkCookieJar::setCookiesFromUrl (filtered, url);