Diff
Modified: trunk/LayoutTests/ChangeLog (248639 => 248640)
--- trunk/LayoutTests/ChangeLog 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/LayoutTests/ChangeLog 2019-08-13 22:34:29 UTC (rev 248640)
@@ -1,3 +1,16 @@
+2019-08-13 John Wilander <wilan...@apple.com>
+
+ Resource Load Statistics: Switch NSURLSession on top navigation to prevalent resource with user interaction
+ https://bugs.webkit.org/show_bug.cgi?id=200642
+ <rdar://problem/53962073>
+
+ Reviewed by Alex Christensen.
+
+ * http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction-expected.txt: Added.
+ * http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html: Added.
+ * http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction-expected.txt: Added.
+ * http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html: Added.
+
2019-08-13 Ryan Haddad <ryanhad...@apple.com>
[WebAuthN] Enable LocalAuthenticator for macOS
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction-expected.txt (0 => 248640)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction-expected.txt 2019-08-13 22:34:29 UTC (rev 248640)
@@ -0,0 +1,12 @@
+Tests that the session is not switched upon top frame navigation to a prevalent resource without user interaction.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Should have and has the session cookie.
+PASS Should have and has the persistent cookie.
+PASS Origin has no isolated session.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html (0 => 248640)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html 2019-08-13 22:34:29 UTC (rev 248640)
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <script src=""
+ <script src=""
+</head>
+<body _onload_="runTest()">
+<script>
+ description("Tests that the session is not switched upon top frame navigation to a prevalent resource without user interaction.");
+ jsTestIsAsync = true;
+
+ const prevalentOrigin = "http://127.0.0.1:8000";
+ const nonPrevalentOrigin = "http://localhost:8000";
+ const sessionCookieName = "sessionCookie";
+ const persistentCookieName = "persistentCookie";
+ const twoMinutesInSeconds = 120;
+
+ function setSessionCookie() {
+ document.cookie = sessionCookieName + "=1; path=/";
+ }
+
+ function setPersistentCookie() {
+ document.cookie = persistentCookieName + "=1; path=/; Max-Age=" + twoMinutesInSeconds + ";";
+ }
+
+ function checkCookies(shouldHaveSessionCookie, shouldHavePersistentCookie) {
+ let hasSessionCookie = (document.cookie + "").includes(sessionCookieName),
+ hasPersistentCookie = (document.cookie + "").includes(persistentCookieName);
+
+ if (shouldHaveSessionCookie && hasSessionCookie)
+ testPassed("Should have and has the session cookie.");
+ else if (shouldHaveSessionCookie && !hasSessionCookie) {
+ testFailed("Should have but doesn't have the session cookie.");
+ setEnableFeature(false, finishJSTest);
+ } else if (!shouldHaveSessionCookie && hasSessionCookie) {
+ testFailed("Shouldn't have but has the session cookie.");
+ setEnableFeature(false, finishJSTest);
+ } else
+ testPassed("Shouldn't have and doesn't have the session cookie.");
+
+
+ if (shouldHavePersistentCookie && hasPersistentCookie)
+ testPassed("Should have and has the persistent cookie.");
+ else if (shouldHavePersistentCookie && !hasPersistentCookie) {
+ testFailed("Should have but doesn't have the persistent cookie.");
+ setEnableFeature(false, finishJSTest);
+ } else if (!shouldHavePersistentCookie && hasPersistentCookie) {
+ testFailed("Shouldn't have but has the persistent cookie.");
+ setEnableFeature(false, finishJSTest);
+ } else
+ testPassed("Shouldn't have and doesn't have the persistent cookie.");
+ }
+
+ function runTest() {
+ switch (document.location.hash) {
+ case "#step1":
+ setSessionCookie();
+ setPersistentCookie();
+ checkCookies(true, true);
+ if (testRunner.hasStatisticsIsolatedSession(prevalentOrigin)) {
+ testFailed("Origin has isolated session.");
+ setEnableFeature(false, finishJSTest);
+ } else
+ testPassed("Origin has no isolated session.");
+ document.location.href = "" + "/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html#step2";
+ break;
+ case "#step2":
+ document.location.hash = "step3";
+ if (document.location.origin !== nonPrevalentOrigin)
+ testFailed("Step 2 is not on " + nonPrevalentOrigin + ".");
+ testRunner.setStatisticsPrevalentResource(prevalentOrigin, true, function() {
+ if (!testRunner.isStatisticsPrevalentResource(prevalentOrigin)) {
+ testFailed(prevalentOrigin + " did not get set as prevalent resource.");
+ setEnableFeature(false, finishJSTest);
+ }
+ testRunner.statisticsUpdateCookieBlocking(runTest);
+ });
+ break;
+ case "#step3":
+ document.location.href = "" + "/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html#step4";
+ break;
+ case "#step4":
+ checkCookies(true, true);
+ if (testRunner.hasStatisticsIsolatedSession(prevalentOrigin))
+ testFailed("Origin has isolated session.");
+ else
+ testPassed("Origin has no isolated session.");
+ setEnableFeature(false, finishJSTest);
+ break;
+ default:
+ testFailed("Unknown hash.");
+ setEnableFeature(false, finishJSTest);
+ }
+ }
+
+ if (document.location.hash === "") {
+ if (document.location.origin !== prevalentOrigin)
+ testFailed("Test is not starting out on " + prevalentOrigin + ".");
+ setEnableFeature(true, function () {
+ if (testRunner.isStatisticsPrevalentResource(prevalentOrigin))
+ testFailed(prevalentOrigin + " was classified as prevalent resource before the test starts.");
+ document.location.hash = "step1";
+ });
+ }
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction-expected.txt (0 => 248640)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction-expected.txt 2019-08-13 22:34:29 UTC (rev 248640)
@@ -0,0 +1,12 @@
+Tests that the session is switched upon top frame navigation to a prevalent resource with user interaction.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Should have and has the session cookie.
+PASS Should have and has the persistent cookie.
+PASS Origin has isolated session.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html (0 => 248640)
--- trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html (rev 0)
+++ trunk/LayoutTests/http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html 2019-08-13 22:34:29 UTC (rev 248640)
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <script src=""
+ <script src=""
+</head>
+<body _onload_="runTest()">
+<script>
+ description("Tests that the session is switched upon top frame navigation to a prevalent resource with user interaction.");
+ jsTestIsAsync = true;
+
+ const prevalentOrigin = "http://127.0.0.1:8000";
+ const nonPrevalentOrigin = "http://localhost:8000";
+ const sessionCookieName = "sessionCookie";
+ const persistentCookieName = "persistentCookie";
+ const twoMinutesInSeconds = 120;
+
+ function setSessionCookie() {
+ document.cookie = sessionCookieName + "=1; path=/";
+ }
+
+ function setPersistentCookie() {
+ document.cookie = persistentCookieName + "=1; path=/; Max-Age=" + twoMinutesInSeconds + ";";
+ }
+
+ function checkCookies(shouldHaveSessionCookie, shouldHavePersistentCookie) {
+ let hasSessionCookie = (document.cookie + "").includes(sessionCookieName),
+ hasPersistentCookie = (document.cookie + "").includes(persistentCookieName);
+
+ if (shouldHaveSessionCookie && hasSessionCookie)
+ testPassed("Should have and has the session cookie.");
+ else if (shouldHaveSessionCookie && !hasSessionCookie) {
+ testFailed("Should have but doesn't have the session cookie.");
+ setEnableFeature(false, finishJSTest);
+ } else if (!shouldHaveSessionCookie && hasSessionCookie) {
+ testFailed("Shouldn't have but has the session cookie.");
+ setEnableFeature(false, finishJSTest);
+ } else
+ testPassed("Shouldn't have and doesn't have the session cookie.");
+
+
+ if (shouldHavePersistentCookie && hasPersistentCookie)
+ testPassed("Should have and has the persistent cookie.");
+ else if (shouldHavePersistentCookie && !hasPersistentCookie) {
+ testFailed("Should have but doesn't have the persistent cookie.");
+ setEnableFeature(false, finishJSTest);
+ } else if (!shouldHavePersistentCookie && hasPersistentCookie) {
+ testFailed("Shouldn't have but has the persistent cookie.");
+ setEnableFeature(false, finishJSTest);
+ } else
+ testPassed("Shouldn't have and doesn't have the persistent cookie.");
+ }
+
+ function runTest() {
+ switch (document.location.hash) {
+ case "#step1":
+ testRunner.setStatisticsHasHadUserInteraction(prevalentOrigin, true, function() {
+ setSessionCookie();
+ setPersistentCookie();
+ checkCookies(true, true);
+ if (testRunner.hasStatisticsIsolatedSession(prevalentOrigin)) {
+ testFailed("Origin has isolated session.");
+ setEnableFeature(false, finishJSTest);
+ } else
+ testPassed("Origin has no isolated session.");
+ document.location.href = "" + "/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html#step2";
+ });
+ break;
+ case "#step2":
+ document.location.hash = "step3";
+ if (document.location.origin !== nonPrevalentOrigin)
+ testFailed("Step 2 is not on " + nonPrevalentOrigin + ".");
+ testRunner.setStatisticsPrevalentResource(prevalentOrigin, true, function() {
+ if (!testRunner.isStatisticsPrevalentResource(prevalentOrigin)) {
+ testFailed(prevalentOrigin + " did not get set as prevalent resource.");
+ setEnableFeature(false, finishJSTest);
+ }
+ testRunner.statisticsUpdateCookieBlocking(runTest);
+ });
+ break;
+ case "#step3":
+ document.location.href = "" + "/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html#step4";
+ break;
+ case "#step4":
+ checkCookies(true, true);
+ if (testRunner.hasStatisticsIsolatedSession(prevalentOrigin))
+ testPassed("Origin has isolated session.");
+ else
+ testFailed("Origin has no isolated session.");
+ setEnableFeature(false, finishJSTest);
+ break;
+ default:
+ testFailed("Unknown hash.");
+ setEnableFeature(false, finishJSTest);
+ }
+ }
+
+ if (document.location.hash === "") {
+ if (document.location.origin !== prevalentOrigin)
+ testFailed("Test is not starting out on " + prevalentOrigin + ".");
+ setEnableFeature(true, function () {
+ if (testRunner.isStatisticsPrevalentResource(prevalentOrigin))
+ testFailed(prevalentOrigin + " was classified as prevalent resource before the test starts.");
+ document.location.hash = "step1";
+ });
+ }
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (248639 => 248640)
--- trunk/Source/WebCore/ChangeLog 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebCore/ChangeLog 2019-08-13 22:34:29 UTC (rev 248640)
@@ -1,3 +1,32 @@
+2019-08-13 John Wilander <wilan...@apple.com>
+
+ Resource Load Statistics: Switch NSURLSession on top navigation to prevalent resource with user interaction
+ https://bugs.webkit.org/show_bug.cgi?id=200642
+ <rdar://problem/53962073>
+
+ Reviewed by Alex Christensen.
+
+ Tests: http/tests/resourceLoadStatistics/do-not-switch-session-on-navigation-to-prevalent-without-interaction.html
+ http/tests/resourceLoadStatistics/switch-session-on-navigation-to-prevalent-with-interaction.html
+
+ This patch splits m_registrableDomainsToBlockCookieFor in WebCore:NetworkStorageSession into:
+ - m_registrableDomainsToBlockAndDeleteCookiesFor
+ - m_registrableDomainsToBlockButKeepCookiesFor
+ ... to support different network load policies based on this distinction.
+
+ * page/RuntimeEnabledFeatures.h:
+ (WebCore::RuntimeEnabledFeatures::setITPSessionSwitchingEnabled):
+ (WebCore::RuntimeEnabledFeatures::itpSessionSwitchingEnabled const):
+ * page/Settings.yaml:
+ * platform/network/NetworkStorageSession.cpp:
+ (WebCore::NetworkStorageSession::shouldBlockThirdPartyCookies const):
+ (WebCore::NetworkStorageSession::shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor const):
+ (WebCore::NetworkStorageSession::setPrevalentDomainsToBlockAndDeleteCookiesFor):
+ (WebCore::NetworkStorageSession::setPrevalentDomainsToBlockButKeepCookiesFor):
+ (WebCore::NetworkStorageSession::removePrevalentDomains):
+ (WebCore::NetworkStorageSession::setPrevalentDomainsToBlockCookiesFor): Deleted.
+ * platform/network/NetworkStorageSession.h:
+
2019-08-13 Zalan Bujtas <za...@apple.com>
[ContentChangeObserver] setShouldObserveDOMTimerScheduling and setShouldObserveTransitions are always called in pairs.
Modified: trunk/Source/WebCore/page/RuntimeEnabledFeatures.h (248639 => 248640)
--- trunk/Source/WebCore/page/RuntimeEnabledFeatures.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebCore/page/RuntimeEnabledFeatures.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -147,6 +147,9 @@
void setIsITPDatabaseEnabled(bool isEnabled) { m_isITPDatabaseEnabled = isEnabled; }
bool isITPDatabaseEnabled() const { return m_isITPDatabaseEnabled; }
+ void setIsITPSessionSwitchingEnabled(bool isEnabled) { m_isITPSessionSwitchingEnabled = isEnabled; }
+ bool isITPSessionSwitchingEnabled() const { return m_isITPSessionSwitchingEnabled; }
+
void setRestrictedHTTPResponseAccess(bool isEnabled) { m_isRestrictedHTTPResponseAccess = isEnabled; }
bool restrictedHTTPResponseAccess() const { return m_isRestrictedHTTPResponseAccess; }
@@ -410,6 +413,7 @@
bool m_accessibilityObjectModelEnabled { false };
bool m_ariaReflectionEnabled { true };
bool m_itpDebugMode { false };
+ bool m_isITPSessionSwitchingEnabled { true };
bool m_isRestrictedHTTPResponseAccess { true };
bool m_crossOriginResourcePolicyEnabled { true };
bool m_isWebGLCompressedTextureASTCSupportEnabled { false };
Modified: trunk/Source/WebCore/page/Settings.yaml (248639 => 248640)
--- trunk/Source/WebCore/page/Settings.yaml 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebCore/page/Settings.yaml 2019-08-13 22:34:29 UTC (rev 248640)
@@ -861,6 +861,9 @@
initial: true
inspectorOverride: true
+isITPSessionSwitchingEnabled:
+ initial: true
+
# Deprecated
iceCandidateFilteringEnabled:
Modified: trunk/Source/WebCore/platform/network/NetworkStorageSession.cpp (248639 => 248640)
--- trunk/Source/WebCore/platform/network/NetworkStorageSession.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebCore/platform/network/NetworkStorageSession.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -63,9 +63,22 @@
if (registrableDomain.isEmpty())
return false;
- return m_registrableDomainsToBlockCookieFor.contains(registrableDomain);
+ ASSERT(!(m_registrableDomainsToBlockAndDeleteCookiesFor.contains(registrableDomain) && m_registrableDomainsToBlockButKeepCookiesFor.contains(registrableDomain)));
+
+ return m_registrableDomainsToBlockAndDeleteCookiesFor.contains(registrableDomain)
+ || m_registrableDomainsToBlockButKeepCookiesFor.contains(registrableDomain);
}
+bool NetworkStorageSession::shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor(const RegistrableDomain& registrableDomain) const
+{
+ if (registrableDomain.isEmpty())
+ return false;
+
+ ASSERT(!(m_registrableDomainsToBlockAndDeleteCookiesFor.contains(registrableDomain) && m_registrableDomainsToBlockButKeepCookiesFor.contains(registrableDomain)));
+
+ return m_registrableDomainsToBlockButKeepCookiesFor.contains(registrableDomain);
+}
+
bool NetworkStorageSession::shouldBlockCookies(const ResourceRequest& request, Optional<uint64_t> frameID, Optional<PageIdentifier> pageID) const
{
return shouldBlockCookies(request.firstPartyForCookies(), request.url(), frameID, pageID);
@@ -103,16 +116,24 @@
m_ageCapForClientSideCookiesShort = seconds ? Seconds { seconds->seconds() / 7. } : seconds;
}
-void NetworkStorageSession::setPrevalentDomainsToBlockCookiesFor(const Vector<RegistrableDomain>& domains)
+void NetworkStorageSession::setPrevalentDomainsToBlockAndDeleteCookiesFor(const Vector<RegistrableDomain>& domains)
{
- m_registrableDomainsToBlockCookieFor.clear();
- m_registrableDomainsToBlockCookieFor.add(domains.begin(), domains.end());
+ m_registrableDomainsToBlockAndDeleteCookiesFor.clear();
+ m_registrableDomainsToBlockAndDeleteCookiesFor.add(domains.begin(), domains.end());
}
+void NetworkStorageSession::setPrevalentDomainsToBlockButKeepCookiesFor(const Vector<RegistrableDomain>& domains)
+{
+ m_registrableDomainsToBlockButKeepCookiesFor.clear();
+ m_registrableDomainsToBlockButKeepCookiesFor.add(domains.begin(), domains.end());
+}
+
void NetworkStorageSession::removePrevalentDomains(const Vector<RegistrableDomain>& domains)
{
- for (auto& domain : domains)
- m_registrableDomainsToBlockCookieFor.remove(domain);
+ for (auto& domain : domains) {
+ m_registrableDomainsToBlockAndDeleteCookiesFor.remove(domain);
+ m_registrableDomainsToBlockButKeepCookiesFor.remove(domain);
+ }
}
bool NetworkStorageSession::hasStorageAccess(const RegistrableDomain& resourceDomain, const RegistrableDomain& firstPartyDomain, Optional<uint64_t> frameID, PageIdentifier pageID) const
Modified: trunk/Source/WebCore/platform/network/NetworkStorageSession.h (248639 => 248640)
--- trunk/Source/WebCore/platform/network/NetworkStorageSession.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebCore/platform/network/NetworkStorageSession.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -143,7 +143,9 @@
WEBCORE_EXPORT bool shouldBlockCookies(const ResourceRequest&, Optional<uint64_t> frameID, Optional<PageIdentifier>) const;
WEBCORE_EXPORT bool shouldBlockCookies(const URL& firstPartyForCookies, const URL& resource, Optional<uint64_t> frameID, Optional<PageIdentifier>) const;
WEBCORE_EXPORT bool shouldBlockThirdPartyCookies(const RegistrableDomain&) const;
- WEBCORE_EXPORT void setPrevalentDomainsToBlockCookiesFor(const Vector<RegistrableDomain>&);
+ WEBCORE_EXPORT bool shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor(const RegistrableDomain&) const;
+ WEBCORE_EXPORT void setPrevalentDomainsToBlockAndDeleteCookiesFor(const Vector<RegistrableDomain>&);
+ WEBCORE_EXPORT void setPrevalentDomainsToBlockButKeepCookiesFor(const Vector<RegistrableDomain>&);
WEBCORE_EXPORT void setAgeCapForClientSideCookies(Optional<Seconds>);
WEBCORE_EXPORT void removePrevalentDomains(const Vector<RegistrableDomain>& domains);
WEBCORE_EXPORT bool hasStorageAccess(const RegistrableDomain& resourceDomain, const RegistrableDomain& firstPartyDomain, Optional<uint64_t> frameID, PageIdentifier) const;
@@ -181,7 +183,8 @@
#if ENABLE(RESOURCE_LOAD_STATISTICS)
Optional<Seconds> clientSideCookieCap(const RegistrableDomain& firstParty, Optional<PageIdentifier>) const;
- HashSet<RegistrableDomain> m_registrableDomainsToBlockCookieFor;
+ HashSet<RegistrableDomain> m_registrableDomainsToBlockAndDeleteCookiesFor;
+ HashSet<RegistrableDomain> m_registrableDomainsToBlockButKeepCookiesFor;
HashMap<PageIdentifier, HashMap<uint64_t, RegistrableDomain, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>> m_framesGrantedStorageAccess;
HashMap<PageIdentifier, HashMap<RegistrableDomain, RegistrableDomain>> m_pagesGrantedStorageAccess;
Optional<Seconds> m_cacheMaxAgeCapForPrevalentResources { };
Modified: trunk/Source/WebKit/ChangeLog (248639 => 248640)
--- trunk/Source/WebKit/ChangeLog 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/ChangeLog 2019-08-13 22:34:29 UTC (rev 248640)
@@ -1,3 +1,93 @@
+2019-08-13 John Wilander <wilan...@apple.com>
+
+ Resource Load Statistics: Switch NSURLSession on top navigation to prevalent resource with user interaction
+ https://bugs.webkit.org/show_bug.cgi?id=200642
+ <rdar://problem/53962073>
+
+ Reviewed by Alex Christensen.
+
+ Since prevalent resources with user interaction get to keep their cookies and website
+ data, we should use a different NSURLSessions for when they are first-party websites
+ and have access to that data. This patch achieves that.
+
+ The WebKit::NetworkDataTaskCocoa constructor now checks with the network storage session
+ if the first party for this load should be isolated. The category for which this is true
+ is checked in the new function
+ WebCore:NetworkStorageSession::shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor()
+ which in turn is backed by a new split of m_registrableDomainsToBlockCookieFor into:
+ - m_registrableDomainsToBlockAndDeleteCookiesFor
+ - m_registrableDomainsToBlockButKeepCookiesFor
+ ... in WebCore:NetworkStorageSession.
+
+ Non-isolated sessions are now picked up through the convenience function
+ WebKit::NetworkSessionCocoa::session() whereas isolated sessions are created lazily and
+ picked up through WebKit::NetworkSessionCocoa::isolatedSession().
+
+ The number of isolated NSURLSessions in memory is capped to 10. When the cap is hit,
+ the session that's been unused the longest is aged out.
+
+ The C API changes are test infrastructure.
+
+ * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
+ (WebKit::ResourceLoadStatisticsDatabaseStore::clear):
+ (WebKit::ResourceLoadStatisticsDatabaseStore::domainsToBlockAndDeleteCookiesFor const):
+ (WebKit::ResourceLoadStatisticsDatabaseStore::domainsToBlockButKeepCookiesFor const):
+ (WebKit::ResourceLoadStatisticsDatabaseStore::updateCookieBlocking):
+ (WebKit::ResourceLoadStatisticsDatabaseStore::domainsToBlock const): Deleted.
+ * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:
+ * NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp:
+ (WebKit::ResourceLoadStatisticsMemoryStore::clear):
+ (WebKit::ResourceLoadStatisticsMemoryStore::updateCookieBlocking):
+ * NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp:
+ (WebKit::ResourceLoadStatisticsStore::updateCookieBlockingForDomains):
+ (WebKit::ResourceLoadStatisticsStore::debugLogDomainsInBatches):
+ * NetworkProcess/Classifier/ResourceLoadStatisticsStore.h:
+ * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
+ (WebKit::WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesForHandler):
+ (WebKit::WebResourceLoadStatisticsStore::scheduleCookieBlockingUpdateForDomains): Deleted.
+ (WebKit::WebResourceLoadStatisticsStore::scheduleClearBlockingStateForDomains): Deleted.
+ Dead code.
+ * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h:
+ (WebKit::RegistrableDomainsToBlockCookiesFor::isolatedCopy const):
+ * NetworkProcess/NetworkProcess.cpp:
+ (WebKit::NetworkProcess::updatePrevalentDomainsToBlockCookiesFor):
+ (WebKit::NetworkProcess::scheduleClearInMemoryAndPersistent):
+ (WebKit::NetworkProcess::hasIsolatedSession const):
+ * NetworkProcess/NetworkProcess.h:
+ * NetworkProcess/NetworkProcess.messages.in:
+ * NetworkProcess/NetworkSession.h:
+ (WebKit::NetworkSession::shouldIsolateSessionsForPrevalentTopFrames const):
+ (WebKit::NetworkSession::hasIsolatedSession const):
+ (WebKit::NetworkSession::clearIsolatedSessions):
+ * NetworkProcess/NetworkSessionCreationParameters.cpp:
+ (WebKit::NetworkSessionCreationParameters::encode const):
+ (WebKit::NetworkSessionCreationParameters::decode):
+ * NetworkProcess/NetworkSessionCreationParameters.h:
+ * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
+ (WebKit::NetworkDataTaskCocoa::NetworkDataTaskCocoa):
+ * NetworkProcess/cocoa/NetworkSessionCocoa.h:
+ * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+ (WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
+ (WebKit::NetworkSessionCocoa::session):
+ (WebKit::NetworkSessionCocoa::isolatedSession):
+ (WebKit::NetworkSessionCocoa::hasIsolatedSession const):
+ (WebKit::NetworkSessionCocoa::clearIsolatedSessions):
+ (WebKit::NetworkSessionCocoa::invalidateAndCancel):
+ (WebKit::NetworkSessionCocoa::clearCredentials):
+ * Shared/WebPreferences.yaml:
+ * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
+ (WKWebsiteDataStoreStatisticsHasIsolatedSession):
+ * UIProcess/API/C/WKWebsiteDataStoreRef.h:
+ * UIProcess/Network/NetworkProcessProxy.cpp:
+ (WebKit::NetworkProcessProxy::hasIsolatedSession):
+ * UIProcess/Network/NetworkProcessProxy.h:
+ * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
+ (WebKit::WebsiteDataStore::parameters):
+ * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+ (WebKit::WebsiteDataStore::hasLocalStorageForTesting const):
+ (WebKit::WebsiteDataStore::hasIsolatedSessionForTesting const):
+ * UIProcess/WebsiteData/WebsiteDataStore.h:
+
2019-08-13 Chris Dumez <cdu...@apple.com>
Fix potential thread safety issue under WebResourceLoadStatisticsStore::hasHadUserInteraction()
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -1317,8 +1317,9 @@
removeAllStorageAccess([callbackAggregator = callbackAggregator.copyRef()] { });
- auto primaryDomainsToBlock = ensurePrevalentResourcesForDebugMode();
- updateCookieBlockingForDomains(primaryDomainsToBlock, [callbackAggregator = callbackAggregator.copyRef()] { });
+ auto registrableDomainsToBlockAndDeleteCookiesFor = ensurePrevalentResourcesForDebugMode();
+ RegistrableDomainsToBlockCookiesFor domainsToBlock { registrableDomainsToBlockAndDeleteCookiesFor, { } };
+ updateCookieBlockingForDomains(domainsToBlock, [callbackAggregator = callbackAggregator.copyRef()] { });
}
ResourceLoadStatisticsDatabaseStore::CookieTreatmentResult ResourceLoadStatisticsDatabaseStore::cookieTreatmentForOrigin(const RegistrableDomain& domain) const
@@ -1353,12 +1354,27 @@
return !statement.getColumnInt(0) ? StorageAccessPromptWasShown::Yes : StorageAccessPromptWasShown::No;
}
-Vector<RegistrableDomain> ResourceLoadStatisticsDatabaseStore::domainsToBlock() const
+Vector<RegistrableDomain> ResourceLoadStatisticsDatabaseStore::domainsToBlockAndDeleteCookiesFor() const
{
ASSERT(!RunLoop::isMain());
+
+ Vector<RegistrableDomain> results;
+ SQLiteStatement statement(m_database, "SELECT registrableDomain FROM ObservedDomains WHERE isPrevalent = 1 AND hadUserInteraction = 0"_s);
+ if (statement.prepare() != SQLITE_OK)
+ return results;
+
+ while (statement.step() == SQLITE_ROW)
+ results.append(RegistrableDomain::uncheckedCreateFromRegistrableDomainString(statement.getColumnText(0)));
+
+ return results;
+}
+Vector<RegistrableDomain> ResourceLoadStatisticsDatabaseStore::domainsToBlockButKeepCookiesFor() const
+{
+ ASSERT(!RunLoop::isMain());
+
Vector<RegistrableDomain> results;
- SQLiteStatement statement(m_database, "SELECT registrableDomain FROM ObservedDomains WHERE isPrevalent = 1"_s);
+ SQLiteStatement statement(m_database, "SELECT registrableDomain FROM ObservedDomains WHERE isPrevalent = 1 AND hadUserInteraction = 1"_s);
if (statement.prepare() != SQLITE_OK)
return results;
@@ -1372,14 +1388,17 @@
{
ASSERT(!RunLoop::isMain());
- auto domainsToBlock = this->domainsToBlock();
+ auto domainsToBlockAndDeleteCookiesFor = this->domainsToBlockAndDeleteCookiesFor();
+ auto domainsToBlockButKeepCookiesFor = this->domainsToBlockButKeepCookiesFor();
- if (domainsToBlock.isEmpty()) {
+ if (domainsToBlockAndDeleteCookiesFor.isEmpty() && domainsToBlockButKeepCookiesFor.isEmpty()) {
completionHandler();
return;
}
- if (debugLoggingEnabled() && !domainsToBlock.isEmpty())
+ RegistrableDomainsToBlockCookiesFor domainsToBlock { domainsToBlockAndDeleteCookiesFor, domainsToBlockButKeepCookiesFor };
+
+ if (debugLoggingEnabled() && !domainsToBlockAndDeleteCookiesFor.isEmpty() && !domainsToBlockButKeepCookiesFor.isEmpty())
debugLogDomainsInBatches("block", domainsToBlock);
RunLoop::main().dispatch([weakThis = makeWeakPtr(*this), store = makeRef(store()), domainsToBlock = crossThreadCopy(domainsToBlock), completionHandler = WTFMove(completionHandler)] () mutable {
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -117,7 +117,8 @@
#endif
void updateLastSeen(const RegistrableDomain&, WallTime);
void setUserInteraction(const RegistrableDomain&, bool hadUserInteraction, WallTime);
- Vector<RegistrableDomain> domainsToBlock() const;
+ Vector<RegistrableDomain> domainsToBlockAndDeleteCookiesFor() const;
+ Vector<RegistrableDomain> domainsToBlockButKeepCookiesFor() const;
struct PrevalentDomainData {
unsigned domainID;
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -712,8 +712,9 @@
removeAllStorageAccess([callbackAggregator = callbackAggregator.copyRef()] { });
- auto primaryDomainsToBlock = ensurePrevalentResourcesForDebugMode();
- updateCookieBlockingForDomains(primaryDomainsToBlock, [callbackAggregator = callbackAggregator.copyRef()] { });
+ auto registrableDomainsToBlockAndDeleteCookiesFor = ensurePrevalentResourcesForDebugMode();
+ RegistrableDomainsToBlockCookiesFor domainsToBlock { registrableDomainsToBlockAndDeleteCookiesFor, { } };
+ updateCookieBlockingForDomains(domainsToBlock, [callbackAggregator = callbackAggregator.copyRef()] { });
}
bool ResourceLoadStatisticsMemoryStore::wasAccessedAsFirstPartyDueToUserInteraction(const ResourceLoadStatistics& current, const ResourceLoadStatistics& updated) const
@@ -761,18 +762,25 @@
{
ASSERT(!RunLoop::isMain());
- Vector<RegistrableDomain> domainsToBlock;
+ Vector<RegistrableDomain> domainsToBlockAndDeleteCookiesFor;
+ Vector<RegistrableDomain> domainsToBlockButKeepCookiesFor;
for (auto& resourceStatistic : m_resourceStatisticsMap.values()) {
- if (resourceStatistic.isPrevalentResource)
- domainsToBlock.append(resourceStatistic.registrableDomain);
+ if (resourceStatistic.isPrevalentResource) {
+ if (hasHadUnexpiredRecentUserInteraction(resourceStatistic, OperatingDatesWindow::Long))
+ domainsToBlockButKeepCookiesFor.append(resourceStatistic.registrableDomain);
+ else
+ domainsToBlockAndDeleteCookiesFor.append(resourceStatistic.registrableDomain);
+ }
}
- if (domainsToBlock.isEmpty() && !debugModeEnabled()) {
+ if (domainsToBlockAndDeleteCookiesFor.isEmpty() && domainsToBlockButKeepCookiesFor.isEmpty() && !debugModeEnabled()) {
completionHandler();
return;
}
- if (debugLoggingEnabled() && !domainsToBlock.isEmpty())
+ RegistrableDomainsToBlockCookiesFor domainsToBlock { domainsToBlockAndDeleteCookiesFor, domainsToBlockButKeepCookiesFor };
+
+ if (debugLoggingEnabled() && !domainsToBlockAndDeleteCookiesFor.isEmpty() && !domainsToBlockButKeepCookiesFor.isEmpty())
debugLogDomainsInBatches("block", domainsToBlock);
RunLoop::main().dispatch([weakThis = makeWeakPtr(*this), store = makeRef(store()), domainsToBlock = crossThreadCopy(domainsToBlock), completionHandler = WTFMove(completionHandler)] () mutable {
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -413,7 +413,7 @@
m_lastTimeDataRecordsWereRemoved = MonotonicTime::now();
}
-void ResourceLoadStatisticsStore::updateCookieBlockingForDomains(const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
+void ResourceLoadStatisticsStore::updateCookieBlockingForDomains(const RegistrableDomainsToBlockCookiesFor& domainsToBlock, CompletionHandler<void()>&& completionHandler)
{
ASSERT(!RunLoop::isMain());
@@ -571,8 +571,11 @@
updateClientSideCookiesAgeCap();
}
-void ResourceLoadStatisticsStore::debugLogDomainsInBatches(const char* action, const Vector<RegistrableDomain>& domains)
+void ResourceLoadStatisticsStore::debugLogDomainsInBatches(const char* action, const RegistrableDomainsToBlockCookiesFor& domainsToBlock)
{
+ Vector<RegistrableDomain> domains;
+ domains.appendVector(domainsToBlock.domainsToBlockAndDeleteCookiesFor);
+ domains.appendVector(domainsToBlock.domainsToBlockButKeepCookiesFor);
static const auto maxNumberOfDomainsInOneLogStatement = 50;
if (domains.isEmpty())
return;
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -98,7 +98,7 @@
virtual bool isEmpty() const = 0;
virtual void updateCookieBlocking(CompletionHandler<void()>&&) = 0;
- void updateCookieBlockingForDomains(const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&&);
+ void updateCookieBlockingForDomains(const RegistrableDomainsToBlockCookiesFor&, CompletionHandler<void()>&&);
void clearBlockingStateForDomains(const Vector<RegistrableDomain>& domains, CompletionHandler<void()>&&);
void includeTodayAsOperatingDateIfNecessary();
@@ -186,7 +186,7 @@
protected:
static unsigned computeImportance(const WebCore::ResourceLoadStatistics&);
static Vector<OperatingDate> mergeOperatingDates(const Vector<OperatingDate>& existingDates, Vector<OperatingDate>&& newDates);
- static void debugLogDomainsInBatches(const char* action, const Vector<RegistrableDomain>& domains);
+ static void debugLogDomainsInBatches(const char* action, const RegistrableDomainsToBlockCookiesFor&);
ResourceLoadStatisticsStore(WebResourceLoadStatisticsStore&, WorkQueue&, ShouldIncludeLocalhost);
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -840,38 +840,6 @@
});
}
-void WebResourceLoadStatisticsStore::scheduleCookieBlockingUpdateForDomains(const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
-{
- // Helper function used by testing system. Should only be called from the main thread.
- ASSERT(RunLoop::isMain());
- postTask([this, domainsToBlock = crossThreadCopy(domainsToBlock), completionHandler = WTFMove(completionHandler)]() mutable {
- if (!m_statisticsStore) {
- postTaskReply(WTFMove(completionHandler));
- return;
- }
-
- m_statisticsStore->updateCookieBlockingForDomains(domainsToBlock, [completionHandler = WTFMove(completionHandler)]() mutable {
- postTaskReply(WTFMove(completionHandler));
- });
- });
-}
-
-void WebResourceLoadStatisticsStore::scheduleClearBlockingStateForDomains(const Vector<RegistrableDomain>& domains, CompletionHandler<void()>&& completionHandler)
-{
- // Helper function used by testing system. Should only be called from the main thread.
- ASSERT(RunLoop::isMain());
- postTask([this, domains = crossThreadCopy(domains), completionHandler = WTFMove(completionHandler)]() mutable {
- if (!m_statisticsStore) {
- postTaskReply(WTFMove(completionHandler));
- return;
- }
-
- m_statisticsStore->clearBlockingStateForDomains(domains, [completionHandler = WTFMove(completionHandler)]() mutable {
- postTaskReply(WTFMove(completionHandler));
- });
- });
-}
-
void WebResourceLoadStatisticsStore::scheduleClearInMemoryAndPersistent(ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
{
ASSERT(RunLoop::isMain());
@@ -956,13 +924,15 @@
completionHandler();
}
-void WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesForHandler(const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
+void WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesForHandler(const RegistrableDomainsToBlockCookiesFor& domainsToBlock, CompletionHandler<void()>&& completionHandler)
{
ASSERT(RunLoop::isMain());
if (m_networkSession) {
- if (auto* storageSession = m_networkSession->networkStorageSession())
- storageSession->setPrevalentDomainsToBlockCookiesFor(domainsToBlock);
+ if (auto* storageSession = m_networkSession->networkStorageSession()) {
+ storageSession->setPrevalentDomainsToBlockAndDeleteCookiesFor(domainsToBlock.domainsToBlockAndDeleteCookiesFor);
+ storageSession->setPrevalentDomainsToBlockButKeepCookiesFor(domainsToBlock.domainsToBlockButKeepCookiesFor);
+ }
}
completionHandler();
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -63,11 +63,17 @@
enum class ShouldGrandfatherStatistics : bool;
enum class ShouldIncludeLocalhost : bool { No, Yes };
enum class EnableResourceLoadStatisticsDebugMode : bool { No, Yes };
+enum class EnableResourceLoadStatisticsNSURLSessionSwitching : bool { No, Yes };
enum class WebsiteDataToRemove : uint8_t {
All,
AllButHttpOnlyCookies,
AllButCookies
};
+struct RegistrableDomainsToBlockCookiesFor {
+ Vector<WebCore::RegistrableDomain> domainsToBlockAndDeleteCookiesFor;
+ Vector<WebCore::RegistrableDomain> domainsToBlockButKeepCookiesFor;
+ RegistrableDomainsToBlockCookiesFor isolatedCopy() const { return { domainsToBlockAndDeleteCookiesFor.isolatedCopy(), domainsToBlockButKeepCookiesFor.isolatedCopy() }; }
+};
class WebResourceLoadStatisticsStore final : public ThreadSafeRefCounted<WebResourceLoadStatisticsStore, WTF::DestructionThread::Main> {
public:
@@ -168,7 +174,7 @@
void logTestingEvent(const String&);
void callGrantStorageAccessHandler(const SubFrameDomain&, const TopFrameDomain&, Optional<FrameID>, WebCore::PageIdentifier, CompletionHandler<void(StorageAccessWasGranted)>&&);
void removeAllStorageAccess(CompletionHandler<void()>&&);
- void callUpdatePrevalentDomainsToBlockCookiesForHandler(const Vector<RegistrableDomain>&, CompletionHandler<void()>&&);
+ void callUpdatePrevalentDomainsToBlockCookiesForHandler(const RegistrableDomainsToBlockCookiesFor&, CompletionHandler<void()>&&);
void callRemoveDomainsHandler(const Vector<RegistrableDomain>&);
void callHasStorageAccessForFrameHandler(const SubFrameDomain&, const TopFrameDomain&, FrameID, WebCore::PageIdentifier, CompletionHandler<void(bool)>&&);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -636,7 +636,7 @@
void NetworkProcess::updatePrevalentDomainsToBlockCookiesFor(PAL::SessionID sessionID, const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
{
if (auto* networkStorageSession = storageSession(sessionID))
- networkStorageSession->setPrevalentDomainsToBlockCookiesFor(domainsToBlock);
+ networkStorageSession->setPrevalentDomainsToBlockAndDeleteCookiesFor(domainsToBlock);
completionHandler();
}
@@ -780,6 +780,7 @@
void NetworkProcess::scheduleClearInMemoryAndPersistent(PAL::SessionID sessionID, Optional<WallTime> modifiedSince, ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
{
if (auto* networkSession = this->networkSession(sessionID)) {
+ networkSession->clearIsolatedSessions();
if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
if (modifiedSince)
resourceLoadStatistics->scheduleClearInMemoryAndPersistent(modifiedSince.value(), shouldGrandfather, WTFMove(completionHandler));
@@ -1235,6 +1236,14 @@
ASSERT_NOT_REACHED();
completionHandler();
}
+
+void NetworkProcess::hasIsolatedSession(PAL::SessionID sessionID, const WebCore::RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler) const
+{
+ bool result = false;
+ if (auto* networkSession = this->networkSession(sessionID))
+ result = networkSession->hasIsolatedSession(domain);
+ completionHandler(result);
+}
#endif // ENABLE(RESOURCE_LOAD_STATISTICS)
bool NetworkProcess::sessionIsControlledByAutomation(PAL::SessionID sessionID) const
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -259,6 +259,7 @@
void didCommitCrossSiteLoadWithDataTransfer(PAL::SessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, OptionSet<WebCore::CrossSiteNavigationDataTransfer::Flag>, WebCore::PageIdentifier);
void setCrossSiteLoadWithLinkDecorationForTesting(PAL::SessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, CompletionHandler<void()>&&);
void resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID, CompletionHandler<void()>&&);
+ void hasIsolatedSession(PAL::SessionID, const WebCore::RegistrableDomain&, CompletionHandler<void(bool)>&&) const;
#endif
using CacheStorageRootPathCallback = CompletionHandler<void(String&&)>;
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2019-08-13 22:34:29 UTC (rev 248640)
@@ -137,6 +137,7 @@
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
+ HasIsolatedSession(PAL::SessionID sessionID, WebCore::RegistrableDomain domain) -> (bool hasIsolatedSession) Async
#endif
SetSessionIsControlledByAutomation(PAL::SessionID sessionID, bool controlled);
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.h (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/NetworkSession.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -93,6 +93,9 @@
void notifyPageStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins);
bool enableResourceLoadStatisticsLogTestingEvent() const { return m_enableResourceLoadStatisticsLogTestingEvent; }
void setResourceLoadStatisticsLogTestingEvent(bool log) { m_enableResourceLoadStatisticsLogTestingEvent = log; }
+ bool shouldIsolateSessionsForPrevalentTopFrames() const { return m_enableResourceLoadStatisticsNSURLSessionSwitching == EnableResourceLoadStatisticsNSURLSessionSwitching::Yes; }
+ virtual bool hasIsolatedSession(const WebCore::RegistrableDomain) const { return false; }
+ virtual void clearIsolatedSessions() { }
#endif
void storeAdClickAttribution(WebCore::AdClickAttribution&&);
void handleAdClickAttributionConversion(WebCore::AdClickAttribution::Conversion&&, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest);
@@ -133,6 +136,7 @@
ShouldIncludeLocalhost m_shouldIncludeLocalhostInResourceLoadStatistics { ShouldIncludeLocalhost::Yes };
EnableResourceLoadStatisticsDebugMode m_enableResourceLoadStatisticsDebugMode { EnableResourceLoadStatisticsDebugMode::No };
WebCore::RegistrableDomain m_resourceLoadStatisticsManualPrevalentResource;
+ EnableResourceLoadStatisticsNSURLSessionSwitching m_enableResourceLoadStatisticsNSURLSessionSwitching { EnableResourceLoadStatisticsNSURLSessionSwitching::No };
bool m_enableResourceLoadStatisticsLogTestingEvent;
#endif
UniqueRef<AdClickAttributionManager> m_adClickAttribution;
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -50,7 +50,7 @@
#if USE(CURL)
, { }, { }
#endif
- , { }, { }, false, false, { }, { }, { }, { }, { }, { }, { }, { }, { }
+ , { }, { }, false, false, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
};
}
@@ -84,6 +84,7 @@
encoder << shouldIncludeLocalhostInResourceLoadStatistics;
encoder << enableResourceLoadStatisticsDebugMode;
encoder << resourceLoadStatisticsManualPrevalentResource;
+ encoder << enableResourceLoadStatisticsNSURLSessionSwitching;
encoder << localStorageDirectory << localStorageDirectoryExtensionHandle;
encoder << networkCacheDirectory << networkCacheDirectoryExtensionHandle;
@@ -208,6 +209,11 @@
if (!resourceLoadStatisticsManualPrevalentResource)
return WTF::nullopt;
+ Optional<bool> enableResourceLoadStatisticsNSURLSessionSwitching;
+ decoder >> enableResourceLoadStatisticsNSURLSessionSwitching;
+ if (!enableResourceLoadStatisticsNSURLSessionSwitching)
+ return WTF::nullopt;
+
Optional<String> localStorageDirectory;
decoder >> localStorageDirectory;
if (!localStorageDirectory)
@@ -266,6 +272,7 @@
, WTFMove(*enableResourceLoadStatisticsLogTestingEvent)
, WTFMove(*shouldIncludeLocalhostInResourceLoadStatistics)
, WTFMove(*enableResourceLoadStatisticsDebugMode)
+ , WTFMove(*enableResourceLoadStatisticsNSURLSessionSwitching)
, WTFMove(*deviceManagementRestrictionsEnabled)
, WTFMove(*allLoadsBlockedByDeviceManagementRestrictionsForTesting)
, WTFMove(*resourceLoadStatisticsManualPrevalentResource)
Modified: trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -87,6 +87,7 @@
bool enableResourceLoadStatisticsLogTestingEvent { false };
bool shouldIncludeLocalhostInResourceLoadStatistics { true };
bool enableResourceLoadStatisticsDebugMode { false };
+ bool enableResourceLoadStatisticsNSURLSessionSwitching { true };
bool deviceManagementRestrictionsEnabled { false };
bool allLoadsBlockedByDeviceManagementRestrictionsForTesting { false };
WebCore::RegistrableDomain resourceLoadStatisticsManualPrevalentResource { };
Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm 2019-08-13 22:34:29 UTC (rev 248640)
@@ -38,6 +38,7 @@
#import <WebCore/AuthenticationChallenge.h>
#import <WebCore/NetworkStorageSession.h>
#import <WebCore/NotImplemented.h>
+#import <WebCore/RegistrableDomain.h>
#import <WebCore/ResourceRequest.h>
#import <pal/spi/cf/CFNetworkSPI.h>
#import <wtf/BlockPtr.h>
@@ -205,9 +206,15 @@
#endif
bool shouldBlockCookies = false;
+ bool needsIsolatedSession = false;
+ auto firstParty = WebCore::RegistrableDomain(request.firstPartyForCookies());
#if ENABLE(RESOURCE_LOAD_STATISTICS)
- shouldBlockCookies = storedCredentialsPolicy == WebCore::StoredCredentialsPolicy::EphemeralStatelessCookieless
- || (session.networkStorageSession() && session.networkStorageSession()->shouldBlockCookies(request, frameID, pageID));
+ shouldBlockCookies = storedCredentialsPolicy == WebCore::StoredCredentialsPolicy::EphemeralStatelessCookieless;
+ if (auto* networkStorageSession = session.networkStorageSession()) {
+ if (!shouldBlockCookies)
+ shouldBlockCookies = networkStorageSession->shouldBlockCookies(request, frameID, pageID);
+ needsIsolatedSession = session.shouldIsolateSessionsForPrevalentTopFrames() && networkStorageSession->shouldBlockThirdPartyCookiesButKeepFirstPartyCookiesFor(firstParty);
+ }
#endif
restrictRequestReferrerToOriginIfNeeded(request, shouldBlockCookies);
@@ -215,23 +222,22 @@
applySniffingPoliciesAndBindRequestToInferfaceIfNeeded(nsRequest, shouldContentSniff == WebCore::ContentSniffingPolicy::SniffContent && !url.isLocalFile(), shouldContentEncodingSniff == WebCore::ContentEncodingSniffingPolicy::Sniff);
auto& cocoaSession = static_cast<NetworkSessionCocoa&>(*m_session);
+ if (needsIsolatedSession)
+ m_task = [cocoaSession.isolatedSession(storedCredentialsPolicy, firstParty) dataTaskWithRequest:nsRequest];
+ else
+ m_task = [cocoaSession.session(storedCredentialsPolicy) dataTaskWithRequest:nsRequest];
switch (storedCredentialsPolicy) {
case WebCore::StoredCredentialsPolicy::Use:
- m_task = [cocoaSession.m_sessionWithCredentialStorage dataTaskWithRequest:nsRequest];
ASSERT(!cocoaSession.m_dataTaskMapWithCredentials.contains([m_task taskIdentifier]));
cocoaSession.m_dataTaskMapWithCredentials.add([m_task taskIdentifier], this);
LOG(NetworkSession, "%llu Creating stateful NetworkDataTask with URL %s", [m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);
break;
case WebCore::StoredCredentialsPolicy::DoNotUse:
- m_task = [cocoaSession.m_statelessSession dataTaskWithRequest:nsRequest];
ASSERT(!cocoaSession.m_dataTaskMapWithoutState.contains([m_task taskIdentifier]));
cocoaSession.m_dataTaskMapWithoutState.add([m_task taskIdentifier], this);
LOG(NetworkSession, "%llu Creating stateless NetworkDataTask with URL %s", [m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);
break;
case WebCore::StoredCredentialsPolicy::EphemeralStatelessCookieless:
- if (!cocoaSession.m_ephemeralStatelessCookielessSession)
- cocoaSession.initializeEphemeralStatelessCookielessSession();
- m_task = [cocoaSession.m_ephemeralStatelessCookielessSession dataTaskWithRequest:nsRequest];
ASSERT(!cocoaSession.m_dataTaskMapEphemeralStatelessCookieless.contains([m_task taskIdentifier]));
cocoaSession.m_dataTaskMapEphemeralStatelessCookieless.add([m_task taskIdentifier], this);
LOG(NetworkSession, "%llu Creating ephemeral, stateless, cookieless NetworkDataTask with URL %s", [m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);
Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -38,7 +38,9 @@
#include "NetworkSession.h"
#include "WebSocketTask.h"
#include <WebCore/NetworkLoadMetrics.h>
+#include <WebCore/RegistrableDomain.h>
#include <wtf/HashMap.h>
+#include <wtf/Seconds.h>
namespace WebKit {
@@ -83,6 +85,11 @@
CFDictionaryRef proxyConfiguration() const { return m_proxyConfiguration.get(); }
+ NSURLSession* session(WebCore::StoredCredentialsPolicy);
+ NSURLSession* isolatedSession(WebCore::StoredCredentialsPolicy, const WebCore::RegistrableDomain);
+ bool hasIsolatedSession(const WebCore::RegistrableDomain) const override;
+ void clearIsolatedSessions() override;
+
private:
void invalidateAndCancel() override;
void clearCredentials() override;
@@ -103,6 +110,16 @@
HashMap<NetworkDataTaskCocoa::TaskIdentifier, WebSocketTask*> m_webSocketDataTaskMap;
#endif
+ struct IsolatedSession {
+ RetainPtr<NSURLSession> sessionWithCredentialStorage;
+ RetainPtr<WKNetworkSessionDelegate> sessionWithCredentialStorageDelegate;
+ RetainPtr<NSURLSession> statelessSession;
+ RetainPtr<WKNetworkSessionDelegate> statelessSessionDelegate;
+ WallTime lastUsed;
+ };
+
+ HashMap<WebCore::RegistrableDomain, IsolatedSession> m_isolatedSessions;
+
RetainPtr<NSURLSession> m_sessionWithCredentialStorage;
RetainPtr<WKNetworkSessionDelegate> m_sessionWithCredentialStorageDelegate;
RetainPtr<NSURLSession> m_statelessSession;
Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm (248639 => 248640)
--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm 2019-08-13 22:34:29 UTC (rev 248640)
@@ -67,6 +67,8 @@
CFStringRef const WebKit2HTTPProxyDefaultsKey = static_cast<CFStringRef>(@"WebKit2HTTPProxy");
CFStringRef const WebKit2HTTPSProxyDefaultsKey = static_cast<CFStringRef>(@"WebKit2HTTPSProxy");
+constexpr unsigned maxNumberOfIsolatedSessions { 10 };
+
static NSURLSessionResponseDisposition toNSURLSessionResponseDisposition(WebCore::PolicyAction disposition)
{
switch (disposition) {
@@ -1034,6 +1036,7 @@
m_shouldIncludeLocalhostInResourceLoadStatistics = parameters.shouldIncludeLocalhostInResourceLoadStatistics ? ShouldIncludeLocalhost::Yes : ShouldIncludeLocalhost::No;
m_enableResourceLoadStatisticsDebugMode = parameters.enableResourceLoadStatisticsDebugMode ? EnableResourceLoadStatisticsDebugMode::Yes : EnableResourceLoadStatisticsDebugMode::No;
m_resourceLoadStatisticsManualPrevalentResource = parameters.resourceLoadStatisticsManualPrevalentResource;
+ m_enableResourceLoadStatisticsNSURLSessionSwitching = parameters.enableResourceLoadStatisticsNSURLSessionSwitching ? EnableResourceLoadStatisticsNSURLSessionSwitching::Yes : EnableResourceLoadStatisticsNSURLSessionSwitching::No;
setResourceLoadStatisticsEnabled(parameters.enableResourceLoadStatistics);
#endif
@@ -1068,6 +1071,75 @@
m_ephemeralStatelessCookielessSession = [NSURLSession sessionWithConfiguration:configuration delegate:static_cast<id>(m_ephemeralStatelessCookielessSessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
}
+NSURLSession* NetworkSessionCocoa::session(WebCore::StoredCredentialsPolicy storedCredentialsPolicy)
+{
+ switch (storedCredentialsPolicy) {
+ case WebCore::StoredCredentialsPolicy::Use:
+ return m_sessionWithCredentialStorage.get();
+ case WebCore::StoredCredentialsPolicy::DoNotUse:
+ return m_statelessSession.get();
+ case WebCore::StoredCredentialsPolicy::EphemeralStatelessCookieless:
+ if (!m_ephemeralStatelessCookielessSession)
+ initializeEphemeralStatelessCookielessSession();
+ return m_ephemeralStatelessCookielessSession.get();
+ }
+}
+
+NSURLSession* NetworkSessionCocoa::isolatedSession(WebCore::StoredCredentialsPolicy storedCredentialsPolicy, const WebCore::RegistrableDomain firstPartyDomain)
+{
+ auto entry = m_isolatedSessions.ensure(firstPartyDomain, [this] {
+ IsolatedSession newEntry { };
+ newEntry.sessionWithCredentialStorageDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this withCredentials:true]);
+ newEntry.sessionWithCredentialStorage = [NSURLSession sessionWithConfiguration:m_sessionWithCredentialStorage.get().configuration delegate:static_cast<id>(newEntry.sessionWithCredentialStorageDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
+
+ newEntry.statelessSessionDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this withCredentials:false]);
+ newEntry.statelessSession = [NSURLSession sessionWithConfiguration:m_statelessSession.get().configuration delegate:static_cast<id>(newEntry.statelessSessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
+
+ return newEntry;
+ }).iterator->value;
+
+ entry.lastUsed = WallTime::now();
+
+ if (m_isolatedSessions.size() > maxNumberOfIsolatedSessions) {
+ WebCore::RegistrableDomain keyToRemove;
+ auto oldestTimestamp = WallTime::now();
+ for (auto& key : m_isolatedSessions.keys()) {
+ auto timestamp = m_isolatedSessions.get(key).lastUsed;
+ if (timestamp < oldestTimestamp) {
+ oldestTimestamp = timestamp;
+ keyToRemove = key;
+ }
+ }
+ LOG(NetworkSession, "About to remove isolated NSURLSession.");
+ m_isolatedSessions.remove(keyToRemove);
+ }
+
+ RELEASE_ASSERT(m_isolatedSessions.size() <= maxNumberOfIsolatedSessions);
+
+ switch (storedCredentialsPolicy) {
+ case WebCore::StoredCredentialsPolicy::Use:
+ LOG(NetworkSession, "Using isolated NSURLSession with credential storage.");
+ return entry.sessionWithCredentialStorage.get();
+ case WebCore::StoredCredentialsPolicy::DoNotUse:
+ LOG(NetworkSession, "Using isolated NSURLSession without credential storage.");
+ return entry.statelessSession.get();
+ case WebCore::StoredCredentialsPolicy::EphemeralStatelessCookieless:
+ if (!m_ephemeralStatelessCookielessSession)
+ initializeEphemeralStatelessCookielessSession();
+ return m_ephemeralStatelessCookielessSession.get();
+ }
+}
+
+bool NetworkSessionCocoa::hasIsolatedSession(const WebCore::RegistrableDomain domain) const
+{
+ return m_isolatedSessions.contains(domain);
+}
+
+void NetworkSessionCocoa::clearIsolatedSessions()
+{
+ m_isolatedSessions.clear();
+}
+
void NetworkSessionCocoa::invalidateAndCancel()
{
NetworkSession::invalidateAndCancel();
@@ -1078,6 +1150,12 @@
[m_sessionWithCredentialStorageDelegate sessionInvalidated];
[m_statelessSessionDelegate sessionInvalidated];
[m_ephemeralStatelessCookielessSessionDelegate sessionInvalidated];
+
+ for (auto& session : m_isolatedSessions.values()) {
+ [session.sessionWithCredentialStorage invalidateAndCancel];
+ [session.sessionWithCredentialStorageDelegate sessionInvalidated];
+ }
+ m_isolatedSessions.clear();
}
void NetworkSessionCocoa::clearCredentials()
@@ -1089,6 +1167,8 @@
// FIXME: Use resetWithCompletionHandler instead.
m_sessionWithCredentialStorage = [NSURLSession sessionWithConfiguration:m_sessionWithCredentialStorage.get().configuration delegate:static_cast<id>(m_sessionWithCredentialStorageDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
m_statelessSession = [NSURLSession sessionWithConfiguration:m_statelessSession.get().configuration delegate:static_cast<id>(m_statelessSessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
+ for (auto& entry : m_isolatedSessions.values())
+ entry.session = [NSURLSession sessionWithConfiguration:entry.session.get().configuration delegate:static_cast<id>(entry.delegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
#endif
}
Modified: trunk/Source/WebKit/Shared/WebPreferences.yaml (248639 => 248640)
--- trunk/Source/WebKit/Shared/WebPreferences.yaml 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/Shared/WebPreferences.yaml 2019-08-13 22:34:29 UTC (rev 248640)
@@ -1723,6 +1723,14 @@
webcoreBinding: RuntimeEnabledFeatures
category: experimental
+IsITPSessionSwitchingEnabled:
+ type: bool
+ defaultValue: true
+ humanReadableName: "ITP Session Switching"
+ humanReadableDescription: "Enable session switching for domains classified by ITP"
+ webcoreBinding: RuntimeEnabledFeatures
+ category: internal
+
# Deprecated
ICECandidateFilteringEnabled:
Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp (248639 => 248640)
--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -472,6 +472,17 @@
#endif
}
+void WKWebsiteDataStoreStatisticsHasIsolatedSession(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreStatisticsHasIsolatedSessionFunction callback)
+{
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+ WebKit::toImpl(dataStoreRef)->websiteDataStore().hasIsolatedSessionForTesting(URL(URL(), WebKit::toImpl(host)->string()), [context, callback](bool hasIsolatedSession) {
+ callback(hasIsolatedSession, context);
+ });
+#else
+ callback(false, context);
+#endif
+}
+
void WKWebsiteDataStoreStatisticsResetToConsistentState(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreStatisticsResetToConsistentStateFunction completionHandler)
{
#if ENABLE(RESOURCE_LOAD_STATISTICS)
Modified: trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h (248639 => 248640)
--- trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -103,6 +103,8 @@
WK_EXPORT void WKWebsiteDataStoreStatisticsHasLocalStorage(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreStatisticsHasLocalStorageFunction callback);
typedef void (*WKWebsiteDataStoreSetStatisticsCacheMaxAgeCapFunction)(void* functionContext);
WK_EXPORT void WKWebsiteDataStoreSetStatisticsCacheMaxAgeCap(WKWebsiteDataStoreRef dataStoreRef, double seconds, void* context, WKWebsiteDataStoreSetStatisticsCacheMaxAgeCapFunction);
+typedef void (*WKWebsiteDataStoreStatisticsHasIsolatedSessionFunction)(bool hasIsolatedSession, void* functionContext);
+WK_EXPORT void WKWebsiteDataStoreStatisticsHasIsolatedSession(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreStatisticsHasIsolatedSessionFunction callback);
typedef void (*WKWebsiteDataStoreStatisticsResetToConsistentStateFunction)(void* functionContext);
WK_EXPORT void WKWebsiteDataStoreStatisticsResetToConsistentState(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreStatisticsResetToConsistentStateFunction completionHandler);
Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (248639 => 248640)
--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -974,6 +974,16 @@
});
}
+void NetworkProcessProxy::hasIsolatedSession(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
+{
+ if (!canSendMessage()) {
+ completionHandler(false);
+ return;
+ }
+
+ sendWithAsyncReply(Messages::NetworkProcess::HasIsolatedSession(sessionID, domain), WTFMove(completionHandler));
+}
+
#endif // ENABLE(RESOURCE_LOAD_STATISTICS)
void NetworkProcessProxy::sendProcessWillSuspendImminently()
Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (248639 => 248640)
--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -150,6 +150,7 @@
void resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID, CompletionHandler<void()>&&);
void deleteCookiesForTesting(PAL::SessionID, const RegistrableDomain&, bool includeHttpOnlyCookies, CompletionHandler<void()>&&);
void deleteWebsiteDataInUIProcessForRegistrableDomains(PAL::SessionID, OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, Vector<RegistrableDomain>, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&&);
+ void hasIsolatedSession(PAL::SessionID, const RegistrableDomain&, CompletionHandler<void(bool)>&&);
#endif
void processReadyToSuspend();
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm (248639 => 248640)
--- trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm 2019-08-13 22:34:29 UTC (rev 248640)
@@ -32,6 +32,7 @@
#import "WebsiteDataStoreParameters.h"
#import <WebCore/RegistrableDomain.h>
#import <WebCore/RuntimeApplicationChecks.h>
+#import <WebCore/RuntimeEnabledFeatures.h>
#import <WebCore/SearchPopupMenuCocoa.h>
#import <pal/spi/cf/CFNetworkSPI.h>
#import <wtf/FileSystem.h>
@@ -66,6 +67,7 @@
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
bool shouldLogCookieInformation = false;
bool enableResourceLoadStatisticsDebugMode = false;
+ bool enableResourceLoadStatisticsNSURLSessionSwitching = WebCore::RuntimeEnabledFeatures::sharedFeatures().isITPSessionSwitchingEnabled();
WebCore::RegistrableDomain resourceLoadStatisticsManualPrevalentResource { };
#if ENABLE(RESOURCE_LOAD_STATISTICS)
enableResourceLoadStatisticsDebugMode = [defaults boolForKey:@"ITPDebugMode"];
@@ -137,6 +139,7 @@
false,
shouldIncludeLocalhostInResourceLoadStatistics,
enableResourceLoadStatisticsDebugMode,
+ enableResourceLoadStatisticsNSURLSessionSwitching,
m_configuration->deviceManagementRestrictionsEnabled(),
m_configuration->allLoadsBlockedByDeviceManagementRestrictionsForTesting(),
WTFMove(resourceLoadStatisticsManualPrevalentResource),
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (248639 => 248640)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -1684,6 +1684,18 @@
}
ASSERT(!completionHandler);
}
+
+void WebsiteDataStore::hasIsolatedSessionForTesting(const URL& url, CompletionHandler<void(bool)>&& completionHandler) const
+{
+ for (auto& processPool : processPools()) {
+ if (auto* networkProcess = processPool->networkProcess()) {
+ networkProcess->hasIsolatedSession(m_sessionID, WebCore::RegistrableDomain { url }, WTFMove(completionHandler));
+ ASSERT(processPools().size() == 1);
+ break;
+ }
+ }
+ ASSERT(!completionHandler);
+}
#endif // ENABLE(RESOURCE_LOAD_STATISTICS)
void WebsiteDataStore::setCacheMaxAgeCapForPrevalentResources(Seconds seconds, CompletionHandler<void()>&& completionHandler)
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h (248639 => 248640)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -179,6 +179,7 @@
void resetCrossSiteLoadsWithLinkDecorationForTesting(CompletionHandler<void()>&&);
void deleteCookiesForTesting(const URL&, bool includeHttpOnlyCookies, CompletionHandler<void()>&&);
void hasLocalStorageForTesting(const URL&, CompletionHandler<void(bool)>&&) const;
+ void hasIsolatedSessionForTesting(const URL&, CompletionHandler<void(bool)>&&) const;
#endif
void setCacheMaxAgeCapForPrevalentResources(Seconds, CompletionHandler<void()>&&);
void resetCacheMaxAgeCapForPrevalentResources(CompletionHandler<void()>&&);
Modified: trunk/Tools/ChangeLog (248639 => 248640)
--- trunk/Tools/ChangeLog 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/ChangeLog 2019-08-13 22:34:29 UTC (rev 248640)
@@ -1,3 +1,24 @@
+2019-08-13 John Wilander <wilan...@apple.com>
+
+ Resource Load Statistics: Switch NSURLSession on top navigation to prevalent resource with user interaction
+ https://bugs.webkit.org/show_bug.cgi?id=200642
+ <rdar://problem/53962073>
+
+ Reviewed by Alex Christensen.
+
+ This patch adds test infrastructure to query whether an origin has an
+ isolated NSURLSession or not.
+
+ * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+ * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+ (WTR::TestRunner::hasStatisticsIsolatedSession):
+ * WebKitTestRunner/InjectedBundle/TestRunner.h:
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::hasStatisticsIsolatedSession):
+ * WebKitTestRunner/TestController.h:
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
2019-08-13 Zhifei Fang <zhifei_f...@apple.com>
Update my status in contributors.json to committer.
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (248639 => 248640)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2019-08-13 22:34:29 UTC (rev 248640)
@@ -333,6 +333,7 @@
boolean isStatisticsHasLocalStorage(DOMString hostName);
void setStatisticsCacheMaxAgeCap(double seconds);
void statisticsResetToConsistentState(object completionHandler);
+ boolean hasStatisticsIsolatedSession(DOMString hostName);
// Injected bundle form client.
void installTextDidChangeInTextFieldCallback(object callback);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (248639 => 248640)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -2066,6 +2066,16 @@
WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
}
+bool TestRunner::hasStatisticsIsolatedSession(JSStringRef hostName)
+{
+ auto messageName = adoptWK(WKStringCreateWithUTF8CString("HasStatisticsIsolatedSession"));
+ auto messageBody = adoptWK(WKStringCreateWithJSString(hostName));
+ WKTypeRef returnData = nullptr;
+ WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData);
+ ASSERT(WKGetTypeID(returnData) == WKBooleanGetTypeID());
+ return WKBooleanGetValue(adoptWK(static_cast<WKBooleanRef>(returnData)).get());
+}
+
void TestRunner::statisticsCallClearThroughWebsiteDataRemovalCallback()
{
callTestRunnerCallback(StatisticsDidClearThroughWebsiteDataRemovalCallbackID);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (248639 => 248640)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -431,6 +431,7 @@
void statisticsCallClearThroughWebsiteDataRemovalCallback();
bool isStatisticsHasLocalStorage(JSStringRef hostName);
void setStatisticsCacheMaxAgeCap(double seconds);
+ bool hasStatisticsIsolatedSession(JSStringRef hostName);
void statisticsResetToConsistentState(JSValueRef completionHandler);
void statisticsCallDidResetToConsistentStateCallback();
Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (248639 => 248640)
--- trunk/Tools/WebKitTestRunner/TestController.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -3511,6 +3511,15 @@
runUntil(context.done, noTimeout);
}
+bool TestController::hasStatisticsIsolatedSession(WKStringRef host)
+{
+ auto* dataStore = WKContextGetWebsiteDataStore(platformContext());
+ ResourceStatisticsCallbackContext context(*this);
+ WKWebsiteDataStoreStatisticsHasIsolatedSession(dataStore, host, &context, resourceStatisticsBooleanResultCallback);
+ runUntil(context.done, noTimeout);
+ return context.result;
+}
+
void TestController::statisticsResetToConsistentState()
{
auto* dataStore = WKContextGetWebsiteDataStore(platformContext());
Modified: trunk/Tools/WebKitTestRunner/TestController.h (248639 => 248640)
--- trunk/Tools/WebKitTestRunner/TestController.h 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/TestController.h 2019-08-13 22:34:29 UTC (rev 248640)
@@ -244,6 +244,7 @@
void statisticsDeleteCookiesForHost(WKStringRef host, bool includeHttpOnlyCookies);
bool isStatisticsHasLocalStorage(WKStringRef hostName);
void setStatisticsCacheMaxAgeCap(double seconds);
+ bool hasStatisticsIsolatedSession(WKStringRef hostName);
void statisticsResetToConsistentState();
void getAllStorageAccessEntries();
Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (248639 => 248640)
--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2019-08-13 22:30:44 UTC (rev 248639)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp 2019-08-13 22:34:29 UTC (rev 248640)
@@ -1462,6 +1462,15 @@
return nullptr;
}
+ if (WKStringIsEqualToUTF8CString(messageName, "HasStatisticsIsolatedSession")) {
+ ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
+
+ WKStringRef hostName = static_cast<WKStringRef>(messageBody);
+ bool hasIsolatedSession = TestController::singleton().hasStatisticsIsolatedSession(hostName);
+ auto result = adoptWK(WKBooleanCreate(hasIsolatedSession));
+ return result;
+ }
+
if (WKStringIsEqualToUTF8CString(messageName, "RemoveAllSessionCredentials")) {
TestController::singleton().removeAllSessionCredentials();
return nullptr;