Diff
Modified: trunk/LayoutTests/ChangeLog (243180 => 243181)
--- trunk/LayoutTests/ChangeLog 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/LayoutTests/ChangeLog 2019-03-20 00:22:09 UTC (rev 243181)
@@ -1,3 +1,14 @@
+2019-03-19 John Wilander <[email protected]>
+
+ Resource Load Statistics (experimental): Clear non-cookie website data for sites that have been navigated to, with link decoration, by a prevalent resource
+ https://bugs.webkit.org/show_bug.cgi?id=195923
+ <rdar://problem/49001272>
+
+ Reviewed by Alex Christensen.
+
+ * http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration-expected.txt: Added.
+ * http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration.html: Added.
+
2019-03-19 Ryosuke Niwa <[email protected]>
Reparenting during a mutation event inside appendChild could result in a circular DOM tree
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration-expected.txt (0 => 243181)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration-expected.txt 2019-03-20 00:22:09 UTC (rev 243181)
@@ -0,0 +1,35 @@
+Check that non-cookie website data gets removed after a navigation with link decoration from a prevalent resource.
+
+Before deletion: Client-side cookie exists.
+Before deletion: HttpOnly cookie exists.
+Before deletion: Regular server-side cookie exists.
+
+Before deletion: IDB entry does exist.
+
+After deletion: HttpOnly cookie exists.
+After deletion: Client-side cookie exists.
+After deletion: Regular server-side cookie exists.
+
+After deletion: IDB entry does not exist.
+
+
+Resource load statistics:
+
+Registrable domain: localhost
+ lastSeen: 0
+ hadUserInteraction: No
+ mostRecentUserInteraction: -1
+ grandfathered: No
+ gotLinkDecorationFromPrevalentResource: No isPrevalentResource: Yes
+ isVeryPrevalentResource: No
+ dataRecordsRemoved: 0
+Registrable domain: 127.0.0.1
+ lastSeen: 0
+ hadUserInteraction: No
+ mostRecentUserInteraction: -1
+ grandfathered: No
+ topFrameLinkDecorationsFrom:
+ localhost
+ gotLinkDecorationFromPrevalentResource: No isPrevalentResource: No
+ isVeryPrevalentResource: No
+ dataRecordsRemoved: 1
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration.html (0 => 243181)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration.html (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration.html 2019-03-20 00:22:09 UTC (rev 243181)
@@ -0,0 +1,138 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src=""
+ <script src=""
+</head>
+<body _onload_="setTimeout('runTest()', 0)">
+<div id="description">Check that non-cookie website data gets removed after a navigation with link decoration from a prevalent resource.</div>
+<br>
+<div id="output"></div>
+<br>
+<script>
+ testRunner.waitUntilDone();
+ testRunner.dumpAsText();
+
+ const httpOnlyCookieName = "http-only-cookie";
+ const serverSideCookieName = "server-side-cookie";
+ const clientSideCookieName = "client-side-cookie";
+
+ function sortStringArray(a, b) {
+ a = a.toLowerCase();
+ b = b.toLowerCase();
+
+ return a > b ? 1 : b > a ? -1 : 0;
+ }
+
+ function addLinebreakToOutput() {
+ let element = document.createElement("br");
+ output.appendChild(element);
+ }
+
+ function addOutput(message) {
+ let element = document.createElement("div");
+ element.innerText = message;
+ output.appendChild(element);
+ }
+
+ function checkCookies(isAfterDeletion) {
+ let unsortedTestPassedMessages = [];
+ let cookies = internals.getCookies();
+ if (!cookies.length)
+ testFailed((isAfterDeletion ? "After" : "Before") + " script-accessible deletion: No cookies found.");
+ for (let cookie of cookies) {
+ switch (cookie.name) {
+ case httpOnlyCookieName:
+ unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " deletion: " + (isAfterDeletion ? " " : "") + "HttpOnly cookie exists.");
+ break;
+ case serverSideCookieName:
+ unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " deletion: Regular server-side cookie exists.");
+ break;
+ case clientSideCookieName:
+ unsortedTestPassedMessages.push((isAfterDeletion ? "After" : "Before") + " deletion: Client-side cookie exists.");
+ break;
+ }
+ }
+ let sortedTestPassedMessages = unsortedTestPassedMessages.sort(sortStringArray);
+ for (let testPassedMessage of sortedTestPassedMessages) {
+ addOutput(testPassedMessage);
+ }
+ }
+
+ const dbName = "TestDatabase";
+
+ function createIDBDataStore(callback) {
+ let request = indexedDB.open(dbName);
+ request._onerror_ = function() {
+ addOutput("Couldn't create indexedDB.");
+ finishTest();
+ };
+ request._onupgradeneeded_ = function(event) {
+ let db = event.target.result;
+ let objStore = db.createObjectStore("test", {autoIncrement: true});
+ objStore.add("value");
+ callback();
+ }
+ }
+
+ function checkIDBDataStoreExists(isAfterDeletion, callback) {
+ let request = indexedDB.open(dbName);
+ request._onerror_ = function() {
+ addOutput("Couldn't open indexedDB.");
+ finishTest();
+ };
+ request._onupgradeneeded_ = function () {
+ addOutput((isAfterDeletion ? "After" : "Before") + " deletion: IDB entry does not exist.");
+ callback();
+ };
+ request._onsuccess_ = function() {
+ addOutput((isAfterDeletion ? "After" : "Before") + " deletion: IDB entry does exist.");
+ callback();
+ };
+ }
+
+ async function writeWebsiteDataAndContinue() {
+ // Write cookies.
+ await fetch("/cookies/resources/set-http-only-cookie.php?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
+ await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
+ document.cookie = clientSideCookieName + "=1";
+
+ checkCookies(false);
+ addLinebreakToOutput();
+
+ // Write IndexedDB.
+ createIDBDataStore(function () {
+ checkIDBDataStoreExists(false, processWebsiteDataAndContinue);
+ });
+ }
+
+ function processWebsiteDataAndContinue() {
+ testRunner.statisticsProcessStatisticsAndDataRecords();
+
+ addLinebreakToOutput();
+ checkCookies(true);
+ addLinebreakToOutput();
+ checkIDBDataStoreExists(true, finishTest);
+ }
+
+ function finishTest() {
+ resetCookies();
+ testRunner.dumpResourceLoadStatistics();
+ setEnableFeature(false, function() {
+ testRunner.notifyDone();
+ });
+ }
+
+ const prevalentResourceOrigin = "http://localhost:8000";
+ const destinationOrigin = "http://127.0.0.1:8000";
+ function runTest() {
+ setEnableFeature(true, function () {
+ testRunner.setStatisticsPrevalentResource(prevalentResourceOrigin, true, function() {
+ testRunner.setStatisticsCrossSiteLoadWithLinkDecoration(prevalentResourceOrigin, destinationOrigin);
+ writeWebsiteDataAndContinue();
+ });
+ });
+ }
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (243180 => 243181)
--- trunk/Source/WebCore/ChangeLog 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebCore/ChangeLog 2019-03-20 00:22:09 UTC (rev 243181)
@@ -1,3 +1,19 @@
+2019-03-19 John Wilander <[email protected]>
+
+ Resource Load Statistics (experimental): Clear non-cookie website data for sites that have been navigated to, with link decoration, by a prevalent resource
+ https://bugs.webkit.org/show_bug.cgi?id=195923
+ <rdar://problem/49001272>
+
+ Reviewed by Alex Christensen.
+
+ Adds a new experimental feature.
+
+ Test: http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration.html
+
+ * page/RuntimeEnabledFeatures.h:
+ (WebCore::RuntimeEnabledFeatures::setIsITPFirstPartyWebsiteDataRemovalEnabled):
+ (WebCore::RuntimeEnabledFeatures::isITPFirstPartyWebsiteDataRemovalEnabled const):
+
2019-03-19 Ryosuke Niwa <[email protected]>
Reparenting during a mutation event inside appendChild could result in a circular DOM tree
Modified: trunk/Source/WebCore/page/RuntimeEnabledFeatures.h (243180 => 243181)
--- trunk/Source/WebCore/page/RuntimeEnabledFeatures.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebCore/page/RuntimeEnabledFeatures.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -150,6 +150,9 @@
void setIsITPDatabaseEnabled(bool isEnabled) { m_isITPDatabaseEnabled = isEnabled; }
bool isITPDatabaseEnabled() const { return m_isITPDatabaseEnabled; }
+
+ void setIsITPFirstPartyWebsiteDataRemovalEnabled(bool isEnabled) { m_isITPFirstPartyWebsiteDataRemovalEnabled = isEnabled; }
+ bool isITPFirstPartyWebsiteDataRemovalEnabled() const { return m_isITPFirstPartyWebsiteDataRemovalEnabled; }
void setRestrictedHTTPResponseAccess(bool isEnabled) { m_isRestrictedHTTPResponseAccess = isEnabled; }
bool restrictedHTTPResponseAccess() const { return m_isRestrictedHTTPResponseAccess; }
@@ -537,6 +540,7 @@
#endif
bool m_isITPDatabaseEnabled { false };
+ bool m_isITPFirstPartyWebsiteDataRemovalEnabled { false };
bool m_referrerPolicyAttributeEnabled { false };
Modified: trunk/Source/WebKit/ChangeLog (243180 => 243181)
--- trunk/Source/WebKit/ChangeLog 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/ChangeLog 2019-03-20 00:22:09 UTC (rev 243181)
@@ -1,3 +1,97 @@
+2019-03-19 John Wilander <[email protected]>
+
+ Resource Load Statistics (experimental): Clear non-cookie website data for sites that have been navigated to, with link decoration, by a prevalent resource
+ https://bugs.webkit.org/show_bug.cgi?id=195923
+ <rdar://problem/49001272>
+
+ Reviewed by Alex Christensen.
+
+ Cross-site trackers abuse link query parameters to transport user identifiers and then store
+ them in first-party storage space. To address this, we've done three things:
+ - r236448 capped all persistent client-side cookies to seven days of storage.
+ - r242288 further capped persistent client-side cookies for navigations with link decoration from prevalent resources.
+ - r242603 added logging of navigations with link decoration from prevalent resources.
+
+ This patch introduces an experimental feature that removes non-cookie website data for sites
+ that have been navigated to, with link decoration, by a prevalent resource.
+
+ To achieve this, resource domains to remove website data for are now marked with an enum called
+ WebsiteDataToRemove with values All, AllButHttpOnlyCookies, AllButCookies. As resources are
+ iterated, they are marked for either of these values and the new function
+ ResourceLoadStatisticsMemoryStore::shouldRemoveAllButCookiesFor() leads to the marking with
+ WebsiteDataToRemove::AllButCookies.
+
+ Then NetworkProcess::deleteWebsiteDataForRegistrableDomains() looks at this setting and removes
+ website data accordingly.
+
+ The thinking behind this is that the lifetime cap applied in r236448 and r242288 take care of
+ script writable cookies, and this patch takes care of all other script writable storage.
+
+ The infrastructure to handle user interaction expiration is now parameterized so that multiple
+ expiries can be applied. In this particular case, seven days of browser use.
+
+ * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
+ (WebKit::ResourceLoadStatisticsDatabaseStore::grantStorageAccess):
+ (WebKit::ResourceLoadStatisticsDatabaseStore::grantStorageAccessInternal):
+ (WebKit::ResourceLoadStatisticsDatabaseStore::hasHadUserInteraction):
+ (WebKit::ResourceLoadStatisticsDatabaseStore::shouldRemoveAllWebsiteDataFor const):
+ (WebKit::ResourceLoadStatisticsDatabaseStore::shouldRemoveAllButCookiesFor const):
+ (WebKit::ResourceLoadStatisticsDatabaseStore::registrableDomainsToRemoveWebsiteDataFor):
+ * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:
+ * NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp:
+ (WebKit::ResourceLoadStatisticsMemoryStore::hasHadUserInteraction):
+ (WebKit::ResourceLoadStatisticsMemoryStore::hasHadUnexpiredRecentUserInteraction const):
+ (WebKit::ResourceLoadStatisticsMemoryStore::shouldRemoveAllWebsiteDataFor const):
+ (WebKit::ResourceLoadStatisticsMemoryStore::shouldRemoveAllButCookiesFor const):
+ (WebKit::ResourceLoadStatisticsMemoryStore::registrableDomainsToRemoveWebsiteDataFor):
+ * NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h:
+ * NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp:
+ (WebKit::domainsToString):
+ (WebKit::ResourceLoadStatisticsStore::removeDataRecords):
+ (WebKit::ResourceLoadStatisticsStore::statisticsEpirationTime const):
+ (WebKit::ResourceLoadStatisticsStore::mergeOperatingDates):
+ (WebKit::ResourceLoadStatisticsStore::includeTodayAsOperatingDateIfNecessary):
+ (WebKit::ResourceLoadStatisticsStore::hasStatisticsExpired const):
+ * NetworkProcess/Classifier/ResourceLoadStatisticsStore.h:
+ * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
+ (WebKit::WebResourceLoadStatisticsStore::hasHadUserInteraction):
+ (WebKit::WebResourceLoadStatisticsStore::deleteWebsiteDataForRegistrableDomains):
+ (WebKit::WebResourceLoadStatisticsStore::deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores): Deleted.
+ Renamed to reflect that it actually takes a parameter for which types of data to remove.
+ * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h:
+ * NetworkProcess/NetworkProcess.cpp:
+ (WebKit::NetworkProcess::initializeNetworkProcess):
+ (WebKit::NetworkProcess::setCrossSiteLoadWithLinkDecorationForTesting):
+ (WebKit::NetworkProcess::deleteWebsiteDataForRegistrableDomains):
+ (WebKit::NetworkProcess::deleteCookiesForTesting):
+ (WebKit::NetworkProcess::deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores): Deleted.
+ Renamed to reflect that it actually takes a parameter for which types of data to remove.
+ * NetworkProcess/NetworkProcess.h:
+ * NetworkProcess/NetworkProcess.messages.in:
+ * NetworkProcess/NetworkProcessCreationParameters.cpp:
+ (WebKit::NetworkProcessCreationParameters::encode const):
+ (WebKit::NetworkProcessCreationParameters::decode):
+ * NetworkProcess/NetworkProcessCreationParameters.h:
+ * NetworkProcess/NetworkSession.cpp:
+ (WebKit::NetworkSession::deleteWebsiteDataForRegistrableDomains):
+ (WebKit::NetworkSession::deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores): Deleted.
+ Renamed to reflect that it actually takes a parameter for which types of data to remove.
+ * NetworkProcess/NetworkSession.h:
+ * Shared/WebPreferences.yaml:
+ * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
+ (WKWebsiteDataStoreSetStatisticsCrossSiteLoadWithLinkDecoration):
+ (WKWebsiteDataStoreSetStatisticsTimeToLiveUserInteraction):
+ (WKWebsiteDataStoreStatisticsProcessStatisticsAndDataRecords):
+ * UIProcess/API/C/WKWebsiteDataStoreRef.h:
+ * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+ (WebKit::WebProcessPool::platformInitializeNetworkProcess):
+ * UIProcess/Network/NetworkProcessProxy.cpp:
+ (WebKit::NetworkProcessProxy::setCrossSiteLoadWithLinkDecorationForTesting):
+ * UIProcess/Network/NetworkProcessProxy.h:
+ * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+ (WebKit::WebsiteDataStore::setCrossSiteLoadWithLinkDecorationForTesting):
+ * UIProcess/WebsiteData/WebsiteDataStore.h:
+
2019-03-19 Chris Dumez <[email protected]>
Unreviewed build fix after r243173.
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -819,7 +819,7 @@
if (userWasPromptedNow) {
auto subFrameStatus = ensureResourceStatisticsForRegistrableDomain(subFrameDomain);
ASSERT(subFrameStatus.first == AddedRecord::No);
- ASSERT(hasHadUserInteraction(subFrameDomain));
+ ASSERT(hasHadUserInteraction(subFrameDomain, OperatingDatesWindow::Long));
insertDomainRelationship(m_storageAccessUnderTopFrameDomainsStatement, subFrameStatus.second, topFrameDomain);
}
@@ -839,7 +839,7 @@
#ifndef NDEBUG
auto subFrameStatus = ensureResourceStatisticsForRegistrableDomain(subFrameDomain);
ASSERT(subFrameStatus.first == AddedRecord::No);
- ASSERT(hasHadUserInteraction(subFrameDomain));
+ ASSERT(hasHadUserInteraction(subFrameDomain, OperatingDatesWindow::Long));
ASSERT(hasUserGrantedStorageAccessThroughPrompt(subFrameStatus.second, topFrameDomain));
#endif
setUserInteraction(subFrameDomain, true, WallTime::now());
@@ -1033,7 +1033,7 @@
}
}
-bool ResourceLoadStatisticsDatabaseStore::hasHadUserInteraction(const RegistrableDomain& domain)
+bool ResourceLoadStatisticsDatabaseStore::hasHadUserInteraction(const RegistrableDomain& domain, OperatingDatesWindow operatingDatesWindow)
{
ASSERT(!RunLoop::isMain());
@@ -1050,7 +1050,7 @@
WallTime mostRecentUserInteractionTime = WallTime::fromRawSeconds(m_hadUserInteractionStatement.getColumnDouble(1));
- if (hasStatisticsExpired(mostRecentUserInteractionTime)) {
+ if (hasStatisticsExpired(mostRecentUserInteractionTime, operatingDatesWindow)) {
// Drop privacy sensitive data because we no longer need it.
// Set timestamp to 0 so that statistics merge will know
// it has been reset as opposed to its default -1.
@@ -1492,8 +1492,20 @@
}
}
-Vector<RegistrableDomain> ResourceLoadStatisticsDatabaseStore::registrableDomainsToRemoveWebsiteDataFor()
+bool ResourceLoadStatisticsDatabaseStore::shouldRemoveAllWebsiteDataFor(const PrevalentDomainData& resourceStatistic, bool shouldCheckForGrandfathering) const
{
+ return !resourceStatistic.hadUserInteraction && (!shouldCheckForGrandfathering || !resourceStatistic.grandfathered);
+}
+
+bool ResourceLoadStatisticsDatabaseStore::shouldRemoveAllButCookiesFor(const PrevalentDomainData& resourceStatistic, bool shouldCheckForGrandfathering) const
+{
+ UNUSED_PARAM(resourceStatistic);
+ UNUSED_PARAM(shouldCheckForGrandfathering);
+ return false;
+}
+
+HashMap<RegistrableDomain, WebsiteDataToRemove> ResourceLoadStatisticsDatabaseStore::registrableDomainsToRemoveWebsiteDataFor()
+{
ASSERT(!RunLoop::isMain());
bool shouldCheckForGrandfathering = endOfGrandfatheringTimestamp() > WallTime::now();
@@ -1504,13 +1516,15 @@
clearExpiredUserInteractions();
- Vector<RegistrableDomain> prevalentResources;
+ HashMap<RegistrableDomain, WebsiteDataToRemove> domainsToRemoveWebsiteDataFor;
Vector<PrevalentDomainData> prevalentDomains = this->prevalentDomains();
Vector<unsigned> domainIDsToClearGrandfathering;
for (auto& statistic : prevalentDomains) {
- if (!statistic.hadUserInteraction && (!shouldCheckForGrandfathering || !statistic.grandfathered))
- prevalentResources.append(statistic.registerableDomain);
+ if (shouldRemoveAllWebsiteDataFor(statistic, shouldCheckForGrandfathering))
+ domainsToRemoveWebsiteDataFor.add(statistic.registerableDomain, WebsiteDataToRemove::All);
+ else if (shouldRemoveAllButCookiesFor(statistic, shouldCheckForGrandfathering))
+ domainsToRemoveWebsiteDataFor.add(statistic.registerableDomain, WebsiteDataToRemove::AllButCookies);
if (shouldClearGrandfathering && statistic.grandfathered)
domainIDsToClearGrandfathering.append(statistic.domainID);
@@ -1518,7 +1532,7 @@
clearGrandfathering(WTFMove(domainIDsToClearGrandfathering));
- return prevalentResources;
+ return domainsToRemoveWebsiteDataFor;
}
void ResourceLoadStatisticsDatabaseStore::pruneStatisticsIfNeeded()
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -101,7 +101,7 @@
void logCrossSiteLoadWithLinkDecoration(const NavigatedFromDomain&, const NavigatedToDomain&) override;
void clearUserInteraction(const RegistrableDomain&) override;
- bool hasHadUserInteraction(const RegistrableDomain&) override;
+ bool hasHadUserInteraction(const RegistrableDomain&, OperatingDatesWindow) override;
void setLastSeen(const RegistrableDomain&, Seconds) override;
@@ -158,7 +158,9 @@
void pruneStatisticsIfNeeded() override;
enum class AddedRecord { No, Yes };
std::pair<AddedRecord, unsigned> ensureResourceStatisticsForRegistrableDomain(const RegistrableDomain&);
- Vector<RegistrableDomain> registrableDomainsToRemoveWebsiteDataFor() override;
+ bool shouldRemoveAllWebsiteDataFor(const PrevalentDomainData&, bool shouldCheckForGrandfathering) const;
+ bool shouldRemoveAllButCookiesFor(const PrevalentDomainData&, bool shouldCheckForGrandfathering) const;
+ HashMap<RegistrableDomain, WebsiteDataToRemove> registrableDomainsToRemoveWebsiteDataFor() override;
bool isDatabaseStore() const final { return true; }
bool createSchema();
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -40,6 +40,7 @@
#include <WebCore/KeyedCoding.h>
#include <WebCore/NetworkStorageSession.h>
#include <WebCore/ResourceLoadStatistics.h>
+#include <WebCore/RuntimeEnabledFeatures.h>
#include <wtf/CallbackAggregator.h>
#include <wtf/DateMath.h>
#include <wtf/MathExtras.h>
@@ -444,12 +445,12 @@
statistics.mostRecentUserInteractionTime = { };
}
-bool ResourceLoadStatisticsMemoryStore::hasHadUserInteraction(const RegistrableDomain& domain)
+bool ResourceLoadStatisticsMemoryStore::hasHadUserInteraction(const RegistrableDomain& domain, OperatingDatesWindow operatingDatesWindow)
{
ASSERT(!RunLoop::isMain());
auto mapEntry = m_resourceStatisticsMap.find(domain);
- return mapEntry == m_resourceStatisticsMap.end() ? false: hasHadUnexpiredRecentUserInteraction(mapEntry->value);
+ return mapEntry == m_resourceStatisticsMap.end() ? false: hasHadUnexpiredRecentUserInteraction(mapEntry->value, operatingDatesWindow);
}
void ResourceLoadStatisticsMemoryStore::setPrevalentResource(ResourceLoadStatistics& resourceStatistic, ResourceLoadPrevalence newPrevalence)
@@ -785,11 +786,11 @@
processFunction(resourceStatistic);
}
-bool ResourceLoadStatisticsMemoryStore::hasHadUnexpiredRecentUserInteraction(ResourceLoadStatistics& resourceStatistic) const
+bool ResourceLoadStatisticsMemoryStore::hasHadUnexpiredRecentUserInteraction(ResourceLoadStatistics& resourceStatistic, OperatingDatesWindow operatingDatesWindow) const
{
ASSERT(!RunLoop::isMain());
- if (resourceStatistic.hadUserInteraction && hasStatisticsExpired(resourceStatistic)) {
+ if (resourceStatistic.hadUserInteraction && hasStatisticsExpired(resourceStatistic, operatingDatesWindow)) {
// Drop privacy sensitive data because we no longer need it.
// Set timestamp to 0 so that statistics merge will know
// it has been reset as opposed to its default -1.
@@ -801,8 +802,18 @@
return resourceStatistic.hadUserInteraction;
}
-Vector<RegistrableDomain> ResourceLoadStatisticsMemoryStore::registrableDomainsToRemoveWebsiteDataFor()
+bool ResourceLoadStatisticsMemoryStore::shouldRemoveAllWebsiteDataFor(ResourceLoadStatistics& resourceStatistic, bool shouldCheckForGrandfathering) const
{
+ return resourceStatistic.isPrevalentResource && !hasHadUnexpiredRecentUserInteraction(resourceStatistic, OperatingDatesWindow::Long) && (!shouldCheckForGrandfathering || !resourceStatistic.grandfathered);
+}
+
+bool ResourceLoadStatisticsMemoryStore::shouldRemoveAllButCookiesFor(ResourceLoadStatistics& resourceStatistic, bool shouldCheckForGrandfathering) const
+{
+ return RuntimeEnabledFeatures::sharedFeatures().isITPFirstPartyWebsiteDataRemovalEnabled() && resourceStatistic.gotLinkDecorationFromPrevalentResource && !hasHadUnexpiredRecentUserInteraction(resourceStatistic, OperatingDatesWindow::Short) && (!shouldCheckForGrandfathering || !resourceStatistic.grandfathered);
+}
+
+HashMap<RegistrableDomain, WebsiteDataToRemove> ResourceLoadStatisticsMemoryStore::registrableDomainsToRemoveWebsiteDataFor()
+{
ASSERT(!RunLoop::isMain());
bool shouldCheckForGrandfathering = endOfGrandfatheringTimestamp() > WallTime::now();
@@ -811,16 +822,20 @@
if (shouldClearGrandfathering)
clearEndOfGrandfatheringTimeStamp();
- Vector<RegistrableDomain> prevalentResources;
+ HashMap<RegistrableDomain, WebsiteDataToRemove> domainsToRemoveWebsiteDataFor;
for (auto& statistic : m_resourceStatisticsMap.values()) {
- if (statistic.isPrevalentResource && !hasHadUnexpiredRecentUserInteraction(statistic) && (!shouldCheckForGrandfathering || !statistic.grandfathered))
- prevalentResources.append(statistic.registrableDomain);
+ if (shouldRemoveAllWebsiteDataFor(statistic, shouldCheckForGrandfathering))
+ domainsToRemoveWebsiteDataFor.add(statistic.registrableDomain, WebsiteDataToRemove::All);
+ else if (shouldRemoveAllButCookiesFor(statistic, shouldCheckForGrandfathering)) {
+ domainsToRemoveWebsiteDataFor.add(statistic.registrableDomain, WebsiteDataToRemove::AllButCookies);
+ statistic.gotLinkDecorationFromPrevalentResource = false;
+ }
if (shouldClearGrandfathering && statistic.grandfathered)
statistic.grandfathered = false;
}
- return prevalentResources;
+ return domainsToRemoveWebsiteDataFor;
}
void ResourceLoadStatisticsMemoryStore::pruneStatisticsIfNeeded()
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -106,7 +106,7 @@
void logCrossSiteLoadWithLinkDecoration(const NavigatedFromDomain&, const NavigatedToDomain&) override;
void clearUserInteraction(const RegistrableDomain&) override;
- bool hasHadUserInteraction(const RegistrableDomain&) override;
+ bool hasHadUserInteraction(const RegistrableDomain&, OperatingDatesWindow) override;
void setLastSeen(const RegistrableDomain&, Seconds) override;
@@ -114,7 +114,9 @@
static bool shouldBlockAndKeepCookies(const ResourceLoadStatistics&);
static bool shouldBlockAndPurgeCookies(const ResourceLoadStatistics&);
static bool hasUserGrantedStorageAccessThroughPrompt(const ResourceLoadStatistics&, const RegistrableDomain&);
- bool hasHadUnexpiredRecentUserInteraction(ResourceLoadStatistics&) const;
+ bool hasHadUnexpiredRecentUserInteraction(ResourceLoadStatistics&, OperatingDatesWindow) const;
+ bool shouldRemoveAllWebsiteDataFor(ResourceLoadStatistics&, bool shouldCheckForGrandfathering) const;
+ bool shouldRemoveAllButCookiesFor(ResourceLoadStatistics&, bool shouldCheckForGrandfathering) const;
bool wasAccessedAsFirstPartyDueToUserInteraction(const ResourceLoadStatistics& current, const ResourceLoadStatistics& updated) const;
void incrementRecordsDeletedCountForDomains(HashSet<RegistrableDomain>&&) override;
void setPrevalentResource(ResourceLoadStatistics&, ResourceLoadPrevalence);
@@ -126,10 +128,9 @@
void removeDataRecords(CompletionHandler<void()>&&);
void pruneStatisticsIfNeeded() override;
ResourceLoadStatistics& ensureResourceStatisticsForRegistrableDomain(const RegistrableDomain&);
- Vector<RegistrableDomain> registrableDomainsToRemoveWebsiteDataFor() override;
+ HashMap<RegistrableDomain, WebsiteDataToRemove> registrableDomainsToRemoveWebsiteDataFor() override;
bool isMemoryStore() const final { return true; }
-
WeakPtr<ResourceLoadStatisticsPersistentStorage> m_persistentStorage;
HashMap<RegistrableDomain, ResourceLoadStatistics> m_resourceStatisticsMap;
};
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -50,7 +50,8 @@
using namespace WebCore;
constexpr Seconds minimumStatisticsProcessingInterval { 5_s };
-constexpr unsigned operatingDatesWindow { 30 };
+constexpr unsigned operatingDatesWindowLong { 30 };
+constexpr unsigned operatingDatesWindowShort { 7 };
#if !RELEASE_LOG_DISABLED
static String domainsToString(const Vector<RegistrableDomain>& domains)
@@ -63,6 +64,28 @@
}
return builder.toString();
}
+
+static String domainsToString(const HashMap<RegistrableDomain, WebsiteDataToRemove>& domainsToRemoveWebsiteDataFor)
+{
+ StringBuilder builder;
+ for (auto& domain : domainsToRemoveWebsiteDataFor.keys()) {
+ if (!builder.isEmpty())
+ builder.appendLiteral(", ");
+ builder.append(domain.string());
+ switch (domainsToRemoveWebsiteDataFor.get(domain)) {
+ case WebsiteDataToRemove::All:
+ builder.appendLiteral("(all data)");
+ break;
+ case WebsiteDataToRemove::AllButHttpOnlyCookies:
+ builder.appendLiteral("(all but HttpOnly cookies)");
+ break;
+ case WebsiteDataToRemove::AllButCookies:
+ builder.appendLiteral("(all but cookies)");
+ break;
+ }
+ }
+ return builder.toString();
+}
#endif
OperatingDate OperatingDate::fromWallTime(WallTime time)
@@ -157,12 +180,12 @@
m_parameters.shouldSubmitTelemetry = value;
}
-void ResourceLoadStatisticsStore::removeDataRecords(CompletionHandler<void()>&& callback)
+void ResourceLoadStatisticsStore::removeDataRecords(CompletionHandler<void()>&& completionHandler)
{
ASSERT(!RunLoop::isMain());
if (!shouldRemoveDataRecords()) {
- callback();
+ completionHandler();
return;
}
@@ -172,33 +195,33 @@
m_activePluginTokens.add(plugin->pluginProcessToken());
#endif
- auto prevalentResourceDomains = registrableDomainsToRemoveWebsiteDataFor();
- if (prevalentResourceDomains.isEmpty()) {
- callback();
+ auto domainsToRemoveWebsiteDataFor = registrableDomainsToRemoveWebsiteDataFor();
+ if (domainsToRemoveWebsiteDataFor.isEmpty()) {
+ completionHandler();
return;
}
#if !RELEASE_LOG_DISABLED
- RELEASE_LOG_INFO_IF(m_debugLoggingEnabled, ResourceLoadStatisticsDebug, "About to remove data records for %{public}s.", domainsToString(prevalentResourceDomains).utf8().data());
+ RELEASE_LOG_INFO_IF(m_debugLoggingEnabled, ResourceLoadStatisticsDebug, "About to remove data records for %{public}s.", domainsToString(domainsToRemoveWebsiteDataFor).utf8().data());
#endif
setDataRecordsBeingRemoved(true);
- RunLoop::main().dispatch([prevalentResourceDomains = crossThreadCopy(prevalentResourceDomains), callback = WTFMove(callback), weakThis = makeWeakPtr(*this), shouldNotifyPagesWhenDataRecordsWereScanned = m_parameters.shouldNotifyPagesWhenDataRecordsWereScanned, workQueue = m_workQueue.copyRef()] () mutable {
+ RunLoop::main().dispatch([domainsToRemoveWebsiteDataFor = crossThreadCopy(domainsToRemoveWebsiteDataFor), completionHandler = WTFMove(completionHandler), weakThis = makeWeakPtr(*this), shouldNotifyPagesWhenDataRecordsWereScanned = m_parameters.shouldNotifyPagesWhenDataRecordsWereScanned, workQueue = m_workQueue.copyRef()] () mutable {
if (!weakThis) {
- callback();
+ completionHandler();
return;
}
- weakThis->m_store.deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(WebResourceLoadStatisticsStore::monitoredDataTypes(), WTFMove(prevalentResourceDomains), shouldNotifyPagesWhenDataRecordsWereScanned, IncludeHttpOnlyCookies::Yes, [callback = WTFMove(callback), weakThis = WTFMove(weakThis), workQueue = workQueue.copyRef()](const HashSet<RegistrableDomain>& domainsWithDeletedWebsiteData) mutable {
- workQueue->dispatch([domainsWithDeletedWebsiteData = crossThreadCopy(domainsWithDeletedWebsiteData), callback = WTFMove(callback), weakThis = WTFMove(weakThis)] () mutable {
+ weakThis->m_store.deleteWebsiteDataForRegistrableDomains(WebResourceLoadStatisticsStore::monitoredDataTypes(), WTFMove(domainsToRemoveWebsiteDataFor), shouldNotifyPagesWhenDataRecordsWereScanned, [completionHandler = WTFMove(completionHandler), weakThis = WTFMove(weakThis), workQueue = workQueue.copyRef()](const HashSet<RegistrableDomain>& domainsWithDeletedWebsiteData) mutable {
+ workQueue->dispatch([domainsWithDeletedWebsiteData = crossThreadCopy(domainsWithDeletedWebsiteData), completionHandler = WTFMove(completionHandler), weakThis = WTFMove(weakThis)] () mutable {
if (!weakThis) {
- callback();
+ completionHandler();
return;
}
weakThis->incrementRecordsDeletedCountForDomains(WTFMove(domainsWithDeletedWebsiteData));
weakThis->setDataRecordsBeingRemoved(false);
- callback();
+ completionHandler();
#if !RELEASE_LOG_DISABLED
RELEASE_LOG_INFO_IF(weakThis->m_debugLoggingEnabled, ResourceLoadStatisticsDebug, "Done removing data records.");
#endif
@@ -430,7 +453,7 @@
if (m_parameters.timeToLiveUserInteraction)
return WallTime::now().secondsSinceEpoch() - m_parameters.timeToLiveUserInteraction.value();
- if (m_operatingDates.size() >= operatingDatesWindow)
+ if (m_operatingDates.size() >= operatingDatesWindowLong)
return m_operatingDates.first().secondsSinceEpoch();
return WTF::nullopt;
@@ -448,8 +471,8 @@
// Remove duplicate dates.
removeRepeatedElements(mergedDates);
- // Drop old dates until the Vector size reaches operatingDatesWindow.
- while (mergedDates.size() > operatingDatesWindow)
+ // Drop old dates until the Vector size reaches operatingDatesWindowLong.
+ while (mergedDates.size() > operatingDatesWindowLong)
mergedDates.remove(0);
return mergedDates;
@@ -468,17 +491,18 @@
if (!m_operatingDates.isEmpty() && today <= m_operatingDates.last())
return;
- while (m_operatingDates.size() >= operatingDatesWindow)
+ while (m_operatingDates.size() >= operatingDatesWindowLong)
m_operatingDates.remove(0);
m_operatingDates.append(today);
}
-bool ResourceLoadStatisticsStore::hasStatisticsExpired(WallTime mostRecentUserInteractionTime) const
+bool ResourceLoadStatisticsStore::hasStatisticsExpired(WallTime mostRecentUserInteractionTime, OperatingDatesWindow operatingDatesWindow) const
{
ASSERT(!RunLoop::isMain());
-
- if (m_operatingDates.size() >= operatingDatesWindow) {
+
+ unsigned operatingDatesWindowInDays = (operatingDatesWindow == OperatingDatesWindow::Long ? operatingDatesWindowLong : operatingDatesWindowShort);
+ if (m_operatingDates.size() >= operatingDatesWindowInDays) {
if (OperatingDate::fromWallTime(mostRecentUserInteractionTime) < m_operatingDates.first())
return true;
}
@@ -492,9 +516,9 @@
return false;
}
-bool ResourceLoadStatisticsStore::hasStatisticsExpired(const ResourceLoadStatistics& resourceStatistic) const
+bool ResourceLoadStatisticsStore::hasStatisticsExpired(const ResourceLoadStatistics& resourceStatistic, OperatingDatesWindow operatingDatesWindow) const
{
- return hasStatisticsExpired(resourceStatistic.mostRecentUserInteractionTime);
+ return hasStatisticsExpired(resourceStatistic.mostRecentUserInteractionTime, operatingDatesWindow);
}
void ResourceLoadStatisticsStore::setMaxStatisticsEntries(size_t maximumEntryCount)
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -71,6 +71,8 @@
int m_monthDay { 0 }; // [1, 31].
};
+enum class OperatingDatesWindow : bool { Long, Short };
+
// This is always constructed / used / destroyed on the WebResourceLoadStatisticsStore's statistics queue.
class ResourceLoadStatisticsStore : public CanMakeWeakPtr<ResourceLoadStatisticsStore> {
public:
@@ -168,7 +170,7 @@
virtual void logCrossSiteLoadWithLinkDecoration(const NavigatedFromDomain&, const NavigatedToDomain&) = 0;
virtual void clearUserInteraction(const RegistrableDomain&) = 0;
- virtual bool hasHadUserInteraction(const RegistrableDomain&) = 0;
+ virtual bool hasHadUserInteraction(const RegistrableDomain&, OperatingDatesWindow) = 0;
virtual void setLastSeen(const RegistrableDomain& primaryDomain, Seconds) = 0;
@@ -188,12 +190,12 @@
ResourceLoadStatisticsStore(WebResourceLoadStatisticsStore&, WorkQueue&, ShouldIncludeLocalhost);
- bool hasStatisticsExpired(const ResourceLoadStatistics&) const;
- bool hasStatisticsExpired(WallTime mostRecentUserInteractionTime) const;
+ bool hasStatisticsExpired(const ResourceLoadStatistics&, OperatingDatesWindow) const;
+ bool hasStatisticsExpired(WallTime mostRecentUserInteractionTime, OperatingDatesWindow) const;
void scheduleStatisticsProcessingRequestIfNecessary();
void mergeOperatingDates(Vector<OperatingDate>&&);
virtual Vector<RegistrableDomain> ensurePrevalentResourcesForDebugMode() = 0;
- virtual Vector<RegistrableDomain> registrableDomainsToRemoveWebsiteDataFor() = 0;
+ virtual HashMap<RegistrableDomain, WebsiteDataToRemove> registrableDomainsToRemoveWebsiteDataFor() = 0;
virtual void pruneStatisticsIfNeeded() = 0;
WebResourceLoadStatisticsStore& store() { return m_store; }
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -580,7 +580,7 @@
void WebResourceLoadStatisticsStore::hasHadUserInteraction(const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
{
postTask([this, domain, completionHandler = WTFMove(completionHandler)]() mutable {
- bool hadUserInteraction = m_statisticsStore ? m_statisticsStore->hasHadUserInteraction(domain) : false;
+ bool hadUserInteraction = m_statisticsStore ? m_statisticsStore->hasHadUserInteraction(domain, OperatingDatesWindow::Long) : false;
postTaskReply([hadUserInteraction, completionHandler = WTFMove(completionHandler)]() mutable {
completionHandler(hadUserInteraction);
});
@@ -1012,12 +1012,12 @@
m_networkSession->notifyResourceLoadStatisticsProcessed();
}
-void WebResourceLoadStatisticsStore::deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(OptionSet<WebsiteDataType> dataTypes, Vector<RegistrableDomain>&& domains, bool shouldNotifyPage, IncludeHttpOnlyCookies includeHttpOnlyCookies, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
+void WebResourceLoadStatisticsStore::deleteWebsiteDataForRegistrableDomains(OptionSet<WebsiteDataType> dataTypes, HashMap<RegistrableDomain, WebsiteDataToRemove>&& domainsToRemoveWebsiteDataFor, bool shouldNotifyPage, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
{
ASSERT(RunLoop::isMain());
if (m_networkSession) {
- m_networkSession->deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(dataTypes, WTFMove(domains), shouldNotifyPage, includeHttpOnlyCookies, WTFMove(completionHandler));
+ m_networkSession->deleteWebsiteDataForRegistrableDomains(dataTypes, WTFMove(domainsToRemoveWebsiteDataFor), shouldNotifyPage, WTFMove(completionHandler));
return;
}
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -60,6 +60,11 @@
enum class ShouldGrandfatherStatistics : bool;
enum class ShouldIncludeLocalhost : bool { No, Yes };
enum class EnableResourceLoadStatisticsDebugMode : bool { No, Yes };
+enum class WebsiteDataToRemove : uint8_t {
+ All,
+ AllButHttpOnlyCookies,
+ AllButCookies
+};
class WebResourceLoadStatisticsStore final : public ThreadSafeRefCounted<WebResourceLoadStatisticsStore, WTF::DestructionThread::Main>, public IPC::MessageReceiver {
public:
@@ -107,7 +112,7 @@
void logSubresourceRedirect(const RedirectedFromDomain&, const RedirectedToDomain&, CompletionHandler<void()>&&);
void logCrossSiteLoadWithLinkDecoration(const NavigatedFromDomain&, const NavigatedToDomain&, CompletionHandler<void()>&&);
void clearUserInteraction(const TopFrameDomain&, CompletionHandler<void()>&&);
- void deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(OptionSet<WebsiteDataType>, Vector<RegistrableDomain>&&, bool shouldNotifyPage, WebCore::IncludeHttpOnlyCookies, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&&);
+ void deleteWebsiteDataForRegistrableDomains(OptionSet<WebsiteDataType>, HashMap<RegistrableDomain, WebsiteDataToRemove>&&, bool shouldNotifyPage, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&&);
void registrableDomainsWithWebsiteData(OptionSet<WebsiteDataType>, bool shouldNotifyPage, CompletionHandler<void(HashSet<RegistrableDomain>&&)>&&);
bool grantStorageAccess(const SubFrameDomain&, const TopFrameDomain&, Optional<FrameID>, PageID);
void hasHadUserInteraction(const RegistrableDomain&, CompletionHandler<void(bool)>&&);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -313,6 +313,7 @@
switchToNewTestingSession();
WebCore::RuntimeEnabledFeatures::sharedFeatures().setIsITPDatabaseEnabled(parameters.shouldEnableITPDatabase);
+ WebCore::RuntimeEnabledFeatures::sharedFeatures().setIsITPFirstPartyWebsiteDataRemovalEnabled(parameters.isITPFirstPartyWebsiteDataRemovalEnabled);
SandboxExtension::consumePermanently(parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectoryExtensionHandle);
@@ -1220,6 +1221,19 @@
}
}
+void NetworkProcess::setCrossSiteLoadWithLinkDecorationForTesting(PAL::SessionID sessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, CompletionHandler<void()>&& completionHandler)
+{
+ if (auto* networkSession = this->networkSession(sessionID)) {
+ if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
+ resourceLoadStatistics->logCrossSiteLoadWithLinkDecoration(fromDomain, toDomain, WTFMove(completionHandler));
+ else
+ completionHandler();
+ } else {
+ ASSERT_NOT_REACHED();
+ completionHandler();
+ }
+}
+
void NetworkProcess::resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
{
if (auto* networkStorageSession = storageSession(sessionID))
@@ -1510,7 +1524,7 @@
return result;
}
-void NetworkProcess::deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, Vector<RegistrableDomain>&& domains, bool shouldNotifyPage, IncludeHttpOnlyCookies includeHttpOnlyCookies, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
+void NetworkProcess::deleteWebsiteDataForRegistrableDomains(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, HashMap<RegistrableDomain, WebsiteDataToRemove>&& domains, bool shouldNotifyPage, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
{
OptionSet<WebsiteDataFetchOption> fetchOptions = WebsiteDataFetchOption::DoNotCreateProcesses;
@@ -1552,13 +1566,37 @@
auto& websiteDataStore = callbackAggregator->m_websiteData;
+ Vector<RegistrableDomain> domainsToDeleteCookiesFor;
+ Vector<RegistrableDomain> domainsToDeleteAllButHttpOnlyCookiesFor;
+ Vector<RegistrableDomain> domainsToDeleteAllButCookiesFor;
Vector<String> hostnamesWithCookiesToDelete;
if (websiteDataTypes.contains(WebsiteDataType::Cookies)) {
+ for (auto& domain : domains.keys()) {
+ domainsToDeleteAllButCookiesFor.append(domain);
+ switch (domains.get(domain)) {
+ case WebsiteDataToRemove::All:
+ domainsToDeleteCookiesFor.append(domain);
+ break;
+ case WebsiteDataToRemove::AllButHttpOnlyCookies:
+ domainsToDeleteAllButHttpOnlyCookiesFor.append(domain);
+ break;
+ case WebsiteDataToRemove::AllButCookies:
+ // Already added.
+ break;
+ }
+ }
if (auto* networkStorageSession = storageSession(sessionID)) {
networkStorageSession->getHostnamesWithCookies(websiteDataStore.hostNamesWithCookies);
- hostnamesWithCookiesToDelete = filterForRegistrableDomains(domains, websiteDataStore.hostNamesWithCookies);
- networkStorageSession->deleteCookiesForHostnames(hostnamesWithCookiesToDelete, includeHttpOnlyCookies);
+
+ hostnamesWithCookiesToDelete = filterForRegistrableDomains(domainsToDeleteCookiesFor, websiteDataStore.hostNamesWithCookies);
+ networkStorageSession->deleteCookiesForHostnames(hostnamesWithCookiesToDelete, WebCore::IncludeHttpOnlyCookies::Yes);
+
+ hostnamesWithCookiesToDelete = filterForRegistrableDomains(domainsToDeleteAllButHttpOnlyCookiesFor, websiteDataStore.hostNamesWithCookies);
+ networkStorageSession->deleteCookiesForHostnames(hostnamesWithCookiesToDelete, WebCore::IncludeHttpOnlyCookies::No);
}
+ } else {
+ for (auto& domain : domains.keys())
+ domainsToDeleteAllButCookiesFor.append(domain);
}
Vector<String> hostnamesWithHSTSToDelete;
@@ -1566,7 +1604,7 @@
if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
if (auto* networkStorageSession = storageSession(sessionID)) {
getHostNamesWithHSTSCache(*networkStorageSession, websiteDataStore.hostNamesWithHSTSCache);
- hostnamesWithHSTSToDelete = filterForRegistrableDomains(domains, websiteDataStore.hostNamesWithHSTSCache);
+ hostnamesWithHSTSToDelete = filterForRegistrableDomains(domainsToDeleteAllButCookiesFor, websiteDataStore.hostNamesWithHSTSCache);
deleteHSTSCacheForHostNames(*networkStorageSession, hostnamesWithHSTSToDelete);
}
}
@@ -1581,9 +1619,9 @@
*/
if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) {
- CacheStorage::Engine::fetchEntries(*this, sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [this, domains, sessionID, callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
+ CacheStorage::Engine::fetchEntries(*this, sessionID, fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes), [this, domainsToDeleteAllButCookiesFor, sessionID, callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
- auto entriesToDelete = filterForRegistrableDomains(domains, entries);
+ auto entriesToDelete = filterForRegistrableDomains(domainsToDeleteAllButCookiesFor, entries);
callbackAggregator->m_websiteData.entries.appendVector(entriesToDelete);
@@ -1596,11 +1634,11 @@
auto path = m_idbDatabasePaths.get(sessionID);
if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases)) {
// FIXME: Pick the right database store based on the session ID.
- postStorageTask(CrossThreadTask([this, sessionID, callbackAggregator = callbackAggregator.copyRef(), path = WTFMove(path), domains]() mutable {
- RunLoop::main().dispatch([this, sessionID, domains = crossThreadCopy(domains), callbackAggregator = callbackAggregator.copyRef(), securityOrigins = indexedDatabaseOrigins(path)] {
+ postStorageTask(CrossThreadTask([this, sessionID, callbackAggregator = callbackAggregator.copyRef(), path = WTFMove(path), domainsToDeleteAllButCookiesFor]() mutable {
+ RunLoop::main().dispatch([this, sessionID, domainsToDeleteAllButCookiesFor = crossThreadCopy(domainsToDeleteAllButCookiesFor), callbackAggregator = callbackAggregator.copyRef(), securityOrigins = indexedDatabaseOrigins(path)] {
Vector<SecurityOriginData> entriesToDelete;
for (const auto& securityOrigin : securityOrigins) {
- if (!domains.contains(RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host)))
+ if (!domainsToDeleteAllButCookiesFor.contains(RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host)))
continue;
entriesToDelete.append(securityOrigin);
@@ -1616,9 +1654,9 @@
#if ENABLE(SERVICE_WORKER)
path = m_swDatabasePaths.get(sessionID);
if (!path.isEmpty() && websiteDataTypes.contains(WebsiteDataType::ServiceWorkerRegistrations)) {
- swServerForSession(sessionID).getOriginsWithRegistrations([this, sessionID, domains, callbackAggregator = callbackAggregator.copyRef()](const HashSet<SecurityOriginData>& securityOrigins) mutable {
+ swServerForSession(sessionID).getOriginsWithRegistrations([this, sessionID, domainsToDeleteAllButCookiesFor, callbackAggregator = callbackAggregator.copyRef()](const HashSet<SecurityOriginData>& securityOrigins) mutable {
for (auto& securityOrigin : securityOrigins) {
- if (!domains.contains(RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host)))
+ if (!domainsToDeleteAllButCookiesFor.contains(RegistrableDomain::uncheckedCreateFromHost(securityOrigin.host)))
continue;
callbackAggregator->m_websiteData.entries.append({ securityOrigin, WebsiteDataType::ServiceWorkerRegistrations, 0 });
swServerForSession(sessionID).clear(securityOrigin, [callbackAggregator = callbackAggregator.copyRef()] { });
@@ -1628,11 +1666,11 @@
#endif
if (websiteDataTypes.contains(WebsiteDataType::DiskCache)) {
- fetchDiskCacheEntries(cache(), sessionID, fetchOptions, [this, domains, callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
+ fetchDiskCacheEntries(cache(), sessionID, fetchOptions, [this, domainsToDeleteAllButCookiesFor, callbackAggregator = callbackAggregator.copyRef()](auto entries) mutable {
Vector<SecurityOriginData> entriesToDelete;
for (auto& entry : entries) {
- if (!domains.contains(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host)))
+ if (!domainsToDeleteAllButCookiesFor.contains(RegistrableDomain::uncheckedCreateFromHost(entry.origin.host)))
continue;
entriesToDelete.append(entry.origin);
callbackAggregator->m_websiteData.entries.append(entry);
@@ -1645,8 +1683,9 @@
void NetworkProcess::deleteCookiesForTesting(PAL::SessionID sessionID, RegistrableDomain domain, bool includeHttpOnlyCookies, CompletionHandler<void()>&& completionHandler)
{
OptionSet<WebsiteDataType> cookieType = WebsiteDataType::Cookies;
-
- deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(sessionID, cookieType, { domain }, true, includeHttpOnlyCookies ? IncludeHttpOnlyCookies::Yes : IncludeHttpOnlyCookies::No, [completionHandler = WTFMove(completionHandler)] (const HashSet<RegistrableDomain>& domainsDeletedFor) mutable {
+ HashMap<RegistrableDomain, WebsiteDataToRemove> toDeleteFor;
+ toDeleteFor.add(domain, includeHttpOnlyCookies ? WebsiteDataToRemove::All : WebsiteDataToRemove::AllButHttpOnlyCookies);
+ deleteWebsiteDataForRegistrableDomains(sessionID, cookieType, WTFMove(toDeleteFor), true, [completionHandler = WTFMove(completionHandler)] (const HashSet<RegistrableDomain>& domainsDeletedFor) mutable {
UNUSED_PARAM(domainsDeletedFor);
completionHandler();
});
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -32,6 +32,7 @@
#include "NetworkContentRuleListManager.h"
#include "NetworkHTTPSUpgradeChecker.h"
#include "SandboxExtension.h"
+#include "WebResourceLoadStatisticsStore.h"
#include <WebCore/AdClickAttribution.h>
#include <WebCore/ClientOrigin.h>
#include <WebCore/DiagnosticLoggingClient.h>
@@ -205,7 +206,7 @@
#if ENABLE(RESOURCE_LOAD_STATISTICS)
void clearPrevalentResource(PAL::SessionID, const RegistrableDomain&, CompletionHandler<void()>&&);
void clearUserInteraction(PAL::SessionID, const RegistrableDomain&, CompletionHandler<void()>&&);
- void deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(PAL::SessionID, OptionSet<WebsiteDataType>, Vector<RegistrableDomain>&&, bool shouldNotifyPage, WebCore::IncludeHttpOnlyCookies, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&&);
+ void deleteWebsiteDataForRegistrableDomains(PAL::SessionID, OptionSet<WebsiteDataType>, HashMap<RegistrableDomain, WebsiteDataToRemove>&&, bool shouldNotifyPage, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&&);
void deleteCookiesForTesting(PAL::SessionID, RegistrableDomain, bool includeHttpOnlyCookies, CompletionHandler<void()>&&);
void dumpResourceLoadStatistics(PAL::SessionID, CompletionHandler<void(String)>&&);
void updatePrevalentDomainsToBlockCookiesFor(PAL::SessionID, const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&&);
@@ -258,6 +259,7 @@
void setTopFrameUniqueRedirectFrom(PAL::SessionID, const TopFrameDomain&, const RedirectedFromDomain&, CompletionHandler<void()>&&);
void registrableDomainsWithWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, bool shouldNotifyPage, CompletionHandler<void(HashSet<RegistrableDomain>&&)>&&);
void committedCrossSiteLoadWithLinkDecoration(PAL::SessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, uint64_t pageID, CompletionHandler<void()>&&);
+ void setCrossSiteLoadWithLinkDecorationForTesting(PAL::SessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, CompletionHandler<void()>&&);
void resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID, CompletionHandler<void()>&&);
#endif
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2019-03-20 00:22:09 UTC (rev 243181)
@@ -136,6 +136,7 @@
SetTopFrameUniqueRedirectFrom(PAL::SessionID sessionID, WebCore::RegistrableDomain topFrameDomain, WebCore::RegistrableDomain redirectedFromDomain) -> () Async
ResetCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID) -> () Async
CommittedCrossSiteLoadWithLinkDecoration(PAL::SessionID sessionID, WebCore::RegistrableDomain fromDomain, WebCore::RegistrableDomain toDomain, uint64_t pageID) -> () Async
+ SetCrossSiteLoadWithLinkDecorationForTesting(PAL::SessionID sessionID, WebCore::RegistrableDomain fromDomain, WebCore::RegistrableDomain toDomain) -> () Async
ResetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID sessionID) -> () Async
DeleteCookiesForTesting(PAL::SessionID sessionID, WebCore::RegistrableDomain domain, bool includeHttpOnlyCookies) -> () Async
#endif
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.cpp (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -94,6 +94,7 @@
#endif
encoder << shouldEnableITPDatabase;
encoder << downloadMonitorSpeedMultiplier;
+ encoder << isITPFirstPartyWebsiteDataRemovalEnabled;
}
bool NetworkProcessCreationParameters::decode(IPC::Decoder& decoder, NetworkProcessCreationParameters& result)
@@ -224,7 +225,10 @@
if (!downloadMonitorSpeedMultiplier)
return false;
result.downloadMonitorSpeedMultiplier = *downloadMonitorSpeedMultiplier;
-
+
+ if (!decoder.decode(result.isITPFirstPartyWebsiteDataRemovalEnabled))
+ return false;
+
return true;
}
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcessCreationParameters.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -111,6 +111,7 @@
bool shouldDisableServiceWorkerProcessTerminationDelay { false };
#endif
bool shouldEnableITPDatabase { false };
+ bool isITPFirstPartyWebsiteDataRemovalEnabled { true };
uint32_t downloadMonitorSpeedMultiplier { 1 };
};
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -125,9 +125,9 @@
m_networkProcess->parentProcessConnection()->send(Messages::NetworkProcessProxy::NotifyResourceLoadStatisticsTelemetryFinished(totalPrevalentResources, totalPrevalentResourcesWithUserInteraction, top3SubframeUnderTopFrameOrigins), 0);
}
-void NetworkSession::deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(OptionSet<WebsiteDataType> dataTypes, Vector<RegistrableDomain>&& domains, bool shouldNotifyPage, IncludeHttpOnlyCookies includeHttpOnlyCookies, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
+void NetworkSession::deleteWebsiteDataForRegistrableDomains(OptionSet<WebsiteDataType> dataTypes, HashMap<RegistrableDomain, WebsiteDataToRemove>&& domains, bool shouldNotifyPage, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
{
- m_networkProcess->deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(m_sessionID, dataTypes, WTFMove(domains), shouldNotifyPage, includeHttpOnlyCookies, WTFMove(completionHandler));
+ m_networkProcess->deleteWebsiteDataForRegistrableDomains(m_sessionID, dataTypes, WTFMove(domains), shouldNotifyPage, WTFMove(completionHandler));
}
void NetworkSession::registrableDomainsWithWebsiteData(OptionSet<WebsiteDataType> dataTypes, bool shouldNotifyPage, CompletionHandler<void(HashSet<RegistrableDomain>&&)>&& completionHandler)
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.h (243180 => 243181)
--- trunk/Source/WebKit/NetworkProcess/NetworkSession.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -74,7 +74,7 @@
WebResourceLoadStatisticsStore* resourceLoadStatistics() const { return m_resourceLoadStatistics.get(); }
void setResourceLoadStatisticsEnabled(bool);
void notifyResourceLoadStatisticsProcessed();
- void deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(OptionSet<WebsiteDataType>, Vector<WebCore::RegistrableDomain>&&, bool shouldNotifyPage, WebCore::IncludeHttpOnlyCookies, CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&&);
+ void deleteWebsiteDataForRegistrableDomains(OptionSet<WebsiteDataType>, HashMap<WebCore::RegistrableDomain, WebsiteDataToRemove>&&, bool shouldNotifyPage, CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&&);
void registrableDomainsWithWebsiteData(OptionSet<WebsiteDataType>, bool shouldNotifyPage, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&&);
void logDiagnosticMessageWithValue(const String& message, const String& description, unsigned value, unsigned significantFigures, WebCore::ShouldSample);
void notifyPageStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins);
Modified: trunk/Source/WebKit/Shared/WebPreferences.yaml (243180 => 243181)
--- trunk/Source/WebKit/Shared/WebPreferences.yaml 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/Shared/WebPreferences.yaml 2019-03-20 00:22:09 UTC (rev 243181)
@@ -1381,6 +1381,14 @@
humanReadableDescription: "Media Capabilities Extensions"
category: experimental
+IsITPFirstPartyWebsiteDataRemovalEnabled:
+ type: bool
+ defaultValue: DEFAULT_EXPERIMENTAL_FEATURES_ENABLED
+ humanReadableName: "ITP First Party Website Data Removal"
+ humanReadableDescription: "Enable Intelligent Tracking Prevention First Party Website Data Removal"
+ webcoreBinding: RuntimeEnabledFeatures
+ category: experimental
+
# For internal features:
# The type should be boolean.
# You must provide a humanReadableName and humanReadableDescription for all debug features. They
Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp (243180 => 243181)
--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -297,20 +297,39 @@
#endif
}
-void WKWebsiteDataStoreSetStatisticsTimeToLiveUserInteraction(WKWebsiteDataStoreRef dataStoreRef, double seconds)
+void WKWebsiteDataStoreSetStatisticsCrossSiteLoadWithLinkDecoration(WKWebsiteDataStoreRef dataStoreRef, WKStringRef fromHost, WKStringRef toHost, void* context, WKWebsiteDataStoreSetStatisticsCrossSiteLoadWithLinkDecorationFunction callback)
{
#if ENABLE(RESOURCE_LOAD_STATISTICS)
- WebKit::toImpl(dataStoreRef)->websiteDataStore().setTimeToLiveUserInteraction(Seconds { seconds }, [] { });
+ WebKit::toImpl(dataStoreRef)->websiteDataStore().setCrossSiteLoadWithLinkDecorationForTesting(URL(URL(), WebKit::toImpl(fromHost)->string()), URL(URL(), WebKit::toImpl(toHost)->string()), [context, callback] {
+ callback(context);
+ });
+#else
+ callback(context);
#endif
}
-void WKWebsiteDataStoreStatisticsProcessStatisticsAndDataRecords(WKWebsiteDataStoreRef dataStoreRef)
+void WKWebsiteDataStoreSetStatisticsTimeToLiveUserInteraction(WKWebsiteDataStoreRef dataStoreRef, double seconds, void* context, WKWebsiteDataStoreSetStatisticsTimeToLiveUserInteractionFunction callback)
{
#if ENABLE(RESOURCE_LOAD_STATISTICS)
- WebKit::toImpl(dataStoreRef)->websiteDataStore().scheduleStatisticsAndDataRecordsProcessing([] { });
+ WebKit::toImpl(dataStoreRef)->websiteDataStore().setTimeToLiveUserInteraction(Seconds { seconds }, [context, callback] {
+ callback(context);
+ });
+#else
+ callback(context);
#endif
}
+void WKWebsiteDataStoreStatisticsProcessStatisticsAndDataRecords(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreStatisticsProcessStatisticsAndDataRecordsFunction callback)
+{
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+ WebKit::toImpl(dataStoreRef)->websiteDataStore().scheduleStatisticsAndDataRecordsProcessing([context, callback] {
+ callback(context);
+ });
+#else
+ callback(context);
+#endif
+}
+
void WKWebsiteDataStoreStatisticsUpdateCookieBlocking(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreStatisticsUpdateCookieBlockingFunction completionHandler)
{
#if ENABLE(RESOURCE_LOAD_STATISTICS)
Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h (243180 => 243181)
--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -73,8 +73,12 @@
WK_EXPORT void WKWebsiteDataStoreSetStatisticsSubresourceUniqueRedirectFrom(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, WKStringRef hostRedirectedFrom);
WK_EXPORT void WKWebsiteDataStoreSetStatisticsTopFrameUniqueRedirectTo(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, WKStringRef hostRedirectedTo);
WK_EXPORT void WKWebsiteDataStoreSetStatisticsTopFrameUniqueRedirectFrom(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, WKStringRef hostRedirectedFrom);
-WK_EXPORT void WKWebsiteDataStoreSetStatisticsTimeToLiveUserInteraction(WKWebsiteDataStoreRef dataStoreRef, double seconds);
-WK_EXPORT void WKWebsiteDataStoreStatisticsProcessStatisticsAndDataRecords(WKWebsiteDataStoreRef dataStoreRef);
+typedef void (*WKWebsiteDataStoreSetStatisticsCrossSiteLoadWithLinkDecorationFunction)(void* functionContext);
+WK_EXPORT void WKWebsiteDataStoreSetStatisticsCrossSiteLoadWithLinkDecoration(WKWebsiteDataStoreRef dataStoreRef, WKStringRef fromHost, WKStringRef toHost, void* context, WKWebsiteDataStoreSetStatisticsCrossSiteLoadWithLinkDecorationFunction callback);
+typedef void (*WKWebsiteDataStoreSetStatisticsTimeToLiveUserInteractionFunction)(void* functionContext);
+WK_EXPORT void WKWebsiteDataStoreSetStatisticsTimeToLiveUserInteraction(WKWebsiteDataStoreRef dataStoreRef, double seconds, void* context, WKWebsiteDataStoreSetStatisticsTimeToLiveUserInteractionFunction callback);
+typedef void (*WKWebsiteDataStoreStatisticsProcessStatisticsAndDataRecordsFunction)(void* functionContext);
+WK_EXPORT void WKWebsiteDataStoreStatisticsProcessStatisticsAndDataRecords(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreStatisticsProcessStatisticsAndDataRecordsFunction callback);
typedef void (*WKWebsiteDataStoreStatisticsUpdateCookieBlockingFunction)(void* functionContext);
WK_EXPORT void WKWebsiteDataStoreStatisticsUpdateCookieBlocking(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreStatisticsUpdateCookieBlockingFunction completionHandler);
WK_EXPORT void WKWebsiteDataStoreStatisticsSubmitTelemetry(WKWebsiteDataStoreRef dataStoreRef);
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm (243180 => 243181)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2019-03-20 00:22:09 UTC (rev 243181)
@@ -307,6 +307,12 @@
parameters.shouldEnableITPDatabase = [defaults boolForKey:[NSString stringWithFormat:@"InternalDebug%@", WebPreferencesKey::isITPDatabaseEnabledKey().createCFString().get()]];
parameters.downloadMonitorSpeedMultiplier = m_configuration->downloadMonitorSpeedMultiplier();
+
+ // Check if the feature has been turned off explicitly. This avoids interpreting
+ // a non-existing default as a false value.
+ auto isITPFirstPartyWebsiteDataRemovalEnabledStr = [defaults stringForKey:[NSString stringWithFormat:@"Experimental%@", WebPreferencesKey::isITPFirstPartyWebsiteDataRemovalEnabledKey().createCFString().get()]];
+ if ([isITPFirstPartyWebsiteDataRemovalEnabledStr isEqual:@"0"])
+ parameters.isITPFirstPartyWebsiteDataRemovalEnabled = false;
}
void WebProcessPool::platformInvalidateContext()
Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (243180 => 243181)
--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -962,6 +962,16 @@
sendWithAsyncReply(Messages::NetworkProcess::CommittedCrossSiteLoadWithLinkDecoration(sessionID, fromDomain, toDomain, pageID), WTFMove(completionHandler));
}
+void NetworkProcessProxy::setCrossSiteLoadWithLinkDecorationForTesting(PAL::SessionID sessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, CompletionHandler<void()>&& completionHandler)
+{
+ if (!canSendMessage()) {
+ completionHandler();
+ return;
+ }
+
+ sendWithAsyncReply(Messages::NetworkProcess::SetCrossSiteLoadWithLinkDecorationForTesting(sessionID, fromDomain, toDomain), WTFMove(completionHandler));
+}
+
void NetworkProcessProxy::resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
{
if (!canSendMessage()) {
Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (243180 => 243181)
--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -146,6 +146,7 @@
void setShouldClassifyResourcesBeforeDataRecordsRemoval(PAL::SessionID, bool, CompletionHandler<void()>&&);
void resetCacheMaxAgeCapForPrevalentResources(PAL::SessionID, CompletionHandler<void()>&&);
void committedCrossSiteLoadWithLinkDecoration(PAL::SessionID, const NavigatedFromDomain&, const NavigatedToDomain&, PageID, CompletionHandler<void()>&&);
+ void setCrossSiteLoadWithLinkDecorationForTesting(PAL::SessionID, const NavigatedFromDomain&, const NavigatedToDomain&, CompletionHandler<void()>&&);
void resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID, CompletionHandler<void()>&&);
void deleteCookiesForTesting(PAL::SessionID, const RegistrableDomain&, bool includeHttpOnlyCookies, CompletionHandler<void()>&&);
#endif
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (243180 => 243181)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -1764,6 +1764,18 @@
}
}
+void WebsiteDataStore::setCrossSiteLoadWithLinkDecorationForTesting(const URL& fromURL, const URL& toURL, CompletionHandler<void()>&& completionHandler)
+{
+ ASSERT(RunLoop::isMain());
+
+ auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
+
+ for (auto& processPool : processPools()) {
+ if (auto* process = processPool->networkProcess())
+ process->setCrossSiteLoadWithLinkDecorationForTesting(m_sessionID, RegistrableDomain { fromURL }, RegistrableDomain { toURL }, [processPool, callbackAggregator = callbackAggregator.copyRef()] { });
+ }
+}
+
void WebsiteDataStore::resetCrossSiteLoadsWithLinkDecorationForTesting(CompletionHandler<void()>&& completionHandler)
{
auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h (243180 => 243181)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -168,6 +168,7 @@
void requestStorageAccess(const String& subFrameHost, const String& topFrameHost, uint64_t frameID, uint64_t pageID, CompletionHandler<void(StorageAccessStatus)>&&);
void grantStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, bool userWasPrompted, CompletionHandler<void(bool)>&&);
void setSubframeUnderTopFrameDomain(const URL& subframe, const URL& topFrame);
+ void setCrossSiteLoadWithLinkDecorationForTesting(const URL& fromURL, const URL& toURL, CompletionHandler<void()>&&);
void resetCrossSiteLoadsWithLinkDecorationForTesting(CompletionHandler<void()>&&);
void deleteCookiesForTesting(const URL&, bool includeHttpOnlyCookies, CompletionHandler<void()>&&);
#endif
Modified: trunk/Tools/ChangeLog (243180 => 243181)
--- trunk/Tools/ChangeLog 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Tools/ChangeLog 2019-03-20 00:22:09 UTC (rev 243181)
@@ -1,3 +1,28 @@
+2019-03-19 John Wilander <[email protected]>
+
+ Resource Load Statistics (experimental): Clear non-cookie website data for sites that have been navigated to, with link decoration, by a prevalent resource
+ https://bugs.webkit.org/show_bug.cgi?id=195923
+ <rdar://problem/49001272>
+
+ Reviewed by Alex Christensen.
+
+ This patch does the following to the TestRunner:
+ - Adds setStatisticsCrossSiteLoadWithLinkDecoration().
+ - Makes setStatisticsTimeToLiveUserInteraction() wait for completion.
+ - Makes statisticsProcessStatisticsAndDataRecords() wait for completion.
+
+ * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+ * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+ (WTR::TestRunner::setStatisticsCrossSiteLoadWithLinkDecoration):
+ * WebKitTestRunner/InjectedBundle/TestRunner.h:
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::setStatisticsCrossSiteLoadWithLinkDecoration):
+ (WTR::TestController::setStatisticsTimeToLiveUserInteraction):
+ (WTR::TestController::statisticsProcessStatisticsAndDataRecords):
+ * WebKitTestRunner/TestController.h:
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
2019-03-19 Christopher Reid <[email protected]>
[CMake] Support more clang and gcc sanitizers
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (243180 => 243181)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2019-03-20 00:22:09 UTC (rev 243181)
@@ -303,6 +303,7 @@
void setStatisticsSubresourceUniqueRedirectFrom(DOMString hostName, DOMString hostNameRedirectedTo);
void setStatisticsTopFrameUniqueRedirectTo(DOMString hostName, DOMString hostNameRedirectedTo);
void setStatisticsTopFrameUniqueRedirectFrom(DOMString hostName, DOMString hostNameRedirectedTo);
+ void setStatisticsCrossSiteLoadWithLinkDecoration(DOMString fromHost, DOMString toHost);
void setStatisticsTimeToLiveUserInteraction(double seconds);
void statisticsNotifyObserver();
void statisticsProcessStatisticsAndDataRecords();
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (243180 => 243181)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -1851,6 +1851,29 @@
WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
}
+void TestRunner::setStatisticsCrossSiteLoadWithLinkDecoration(JSStringRef fromHost, JSStringRef toHost)
+{
+ Vector<WKRetainPtr<WKStringRef>> keys;
+ Vector<WKRetainPtr<WKTypeRef>> values;
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("FromHost") });
+ values.append({ AdoptWK, WKStringCreateWithJSString(fromHost) });
+
+ keys.append({ AdoptWK, WKStringCreateWithUTF8CString("ToHost") });
+ values.append({ AdoptWK, WKStringCreateWithJSString(toHost) });
+
+ Vector<WKStringRef> rawKeys(keys.size());
+ Vector<WKTypeRef> rawValues(values.size());
+
+ for (size_t i = 0; i < keys.size(); ++i) {
+ rawKeys[i] = keys[i].get();
+ rawValues[i] = values[i].get();
+ }
+
+ WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsCrossSiteLoadWithLinkDecoration"));
+ WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
void TestRunner::setStatisticsTimeToLiveUserInteraction(double seconds)
{
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (243180 => 243181)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -416,6 +416,7 @@
void setStatisticsSubresourceUniqueRedirectFrom(JSStringRef hostName, JSStringRef hostNameRedirectedFrom);
void setStatisticsTopFrameUniqueRedirectTo(JSStringRef hostName, JSStringRef hostNameRedirectedTo);
void setStatisticsTopFrameUniqueRedirectFrom(JSStringRef hostName, JSStringRef hostNameRedirectedFrom);
+ void setStatisticsCrossSiteLoadWithLinkDecoration(JSStringRef fromHost, JSStringRef toHost);
void setStatisticsTimeToLiveUserInteraction(double seconds);
void setStatisticsNotifyPagesWhenDataRecordsWereScanned(bool);
void setStatisticsIsRunningTest(bool);
Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (243180 => 243181)
--- trunk/Tools/WebKitTestRunner/TestController.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -3255,16 +3255,28 @@
WKWebsiteDataStoreSetStatisticsTopFrameUniqueRedirectFrom(dataStore, host, hostRedirectedFrom);
}
+void TestController::setStatisticsCrossSiteLoadWithLinkDecoration(WKStringRef fromHost, WKStringRef toHost)
+{
+ auto* dataStore = WKContextGetWebsiteDataStore(platformContext());
+ ResourceStatisticsCallbackContext context(*this);
+ WKWebsiteDataStoreSetStatisticsCrossSiteLoadWithLinkDecoration(dataStore, fromHost, toHost, &context, resourceStatisticsVoidResultCallback);
+ runUntil(context.done, noTimeout);
+}
+
void TestController::setStatisticsTimeToLiveUserInteraction(double seconds)
{
auto* dataStore = WKContextGetWebsiteDataStore(platformContext());
- WKWebsiteDataStoreSetStatisticsTimeToLiveUserInteraction(dataStore, seconds);
+ ResourceStatisticsCallbackContext context(*this);
+ WKWebsiteDataStoreSetStatisticsTimeToLiveUserInteraction(dataStore, seconds, &context, resourceStatisticsVoidResultCallback);
+ runUntil(context.done, noTimeout);
}
void TestController::statisticsProcessStatisticsAndDataRecords()
{
auto* dataStore = WKContextGetWebsiteDataStore(platformContext());
- WKWebsiteDataStoreStatisticsProcessStatisticsAndDataRecords(dataStore);
+ ResourceStatisticsCallbackContext context(*this);
+ WKWebsiteDataStoreStatisticsProcessStatisticsAndDataRecords(dataStore, &context, resourceStatisticsVoidResultCallback);
+ runUntil(context.done, noTimeout);
}
void TestController::statisticsUpdateCookieBlocking()
Modified: trunk/Tools/WebKitTestRunner/TestController.h (243180 => 243181)
--- trunk/Tools/WebKitTestRunner/TestController.h 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Tools/WebKitTestRunner/TestController.h 2019-03-20 00:22:09 UTC (rev 243181)
@@ -225,6 +225,7 @@
void setStatisticsSubresourceUniqueRedirectFrom(WKStringRef host, WKStringRef hostRedirectedFrom);
void setStatisticsTopFrameUniqueRedirectTo(WKStringRef host, WKStringRef hostRedirectedTo);
void setStatisticsTopFrameUniqueRedirectFrom(WKStringRef host, WKStringRef hostRedirectedFrom);
+ void setStatisticsCrossSiteLoadWithLinkDecoration(WKStringRef fromHost, WKStringRef toHost);
void setStatisticsTimeToLiveUserInteraction(double seconds);
void statisticsProcessStatisticsAndDataRecords();
void statisticsUpdateCookieBlocking();
Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (243180 => 243181)
--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2019-03-19 23:35:20 UTC (rev 243180)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2019-03-20 00:22:09 UTC (rev 243181)
@@ -1304,6 +1304,20 @@
return nullptr;
}
+ if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsCrossSiteLoadWithLinkDecoration")) {
+ ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+
+ WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+ auto fromHostKey = adoptWK(WKStringCreateWithUTF8CString("FromHost"));
+ auto toHostKey = adoptWK(WKStringCreateWithUTF8CString("ToHost"));
+
+ WKStringRef fromHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, fromHostKey.get()));
+ WKStringRef toHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, toHostKey.get()));
+
+ TestController::singleton().setStatisticsCrossSiteLoadWithLinkDecoration(fromHost, toHost);
+ return nullptr;
+ }
+
if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTimeToLiveUserInteraction")) {
ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);