Disable CFURLCache in WebKit2
https://bugs.webkit.org/show_bug.cgi?id=234988
<rdar://problem/87619196>

Reviewed by Geoffrey Garen.

Source/WebCore:

_CFURLStorageSessionCopyCache can be slow (see rdar://85418732) and UI process may kill network process for
being unresponsive. Since WebKit does not use CFURLCache, we should disable it to avoid the hang.

* platform/network/NetworkStorageSession.h:
* platform/network/cf/NetworkStorageSessionCFNet.cpp:
(WebCore::NetworkStorageSession::createCFStorageSessionForIdentifier):
* platform/network/cocoa/NetworkStorageSessionCocoa.mm:
(WebCore::createPrivateStorageSession):

Source/WebCore/PAL:

* pal/spi/cf/CFNetworkSPI.h:

Source/WebKit:

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::newTestingSession):
(WebKit::NetworkProcess::ensureSession):

Source/WebKitLegacy:

* WebCoreSupport/NetworkStorageSessionMap.cpp:
(NetworkStorageSessionMap::ensureSession):

Source/WTF:

* wtf/PlatformHave.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@288389 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index b29da3c..ee437a7 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,13 @@
+2022-01-21  Sihui Liu  <sihui_liu@apple.com>
+
+        Disable CFURLCache in WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=234988
+        <rdar://problem/87619196>
+
+        Reviewed by Geoffrey Garen.
+
+        * wtf/PlatformHave.h:
+
 2022-01-21  Mike Gorse  <mgorse@suse.com>
 
         Build failure with g++ 12: std::exchange undefined
diff --git a/Source/WTF/wtf/PlatformHave.h b/Source/WTF/wtf/PlatformHave.h
index 58c6370..c615d26 100644
--- a/Source/WTF/wtf/PlatformHave.h
+++ b/Source/WTF/wtf/PlatformHave.h
@@ -1152,3 +1152,10 @@
 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 120200
 #define HAVE_PLATFORM_SCROLL_MOMENTUM_INTERRUPTION_REASON 1
 #endif
+
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 120300) \
+    || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150400) \
+    || (PLATFORM(APPLETV) && __TV_OS_VERSION_MAX_ALLOWED >= 150400) \
+    || (PLATFORM(WATCHOS) && __WATCH_OS_VERSION_MAX_ALLOWED >= 80500)
+#define HAVE_CFNETWORK_DISABLE_CACHE_SPI 1
+#endif
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 7cd4a8f..7fa94de 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,20 @@
+2022-01-21  Sihui Liu  <sihui_liu@apple.com>
+
+        Disable CFURLCache in WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=234988
+        <rdar://problem/87619196>
+
+        Reviewed by Geoffrey Garen.
+
+        _CFURLStorageSessionCopyCache can be slow (see rdar://85418732) and UI process may kill network process for
+        being unresponsive. Since WebKit does not use CFURLCache, we should disable it to avoid the hang.
+
+        * platform/network/NetworkStorageSession.h:
+        * platform/network/cf/NetworkStorageSessionCFNet.cpp:
+        (WebCore::NetworkStorageSession::createCFStorageSessionForIdentifier):
+        * platform/network/cocoa/NetworkStorageSessionCocoa.mm:
+        (WebCore::createPrivateStorageSession):
+
 2022-01-21  Tim Horton  <timothy_horton@apple.com>
 
         imported/w3c/web-platform-tests/css/css-color/parsing/color-valid.html fails in debug
diff --git a/Source/WebCore/PAL/ChangeLog b/Source/WebCore/PAL/ChangeLog
index dd1bdd7d..3280989 100644
--- a/Source/WebCore/PAL/ChangeLog
+++ b/Source/WebCore/PAL/ChangeLog
@@ -1,3 +1,13 @@
+2022-01-21  Sihui Liu  <sihui_liu@apple.com>
+
+        Disable CFURLCache in WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=234988
+        <rdar://problem/87619196>
+
+        Reviewed by Geoffrey Garen.
+
+        * pal/spi/cf/CFNetworkSPI.h:
+
 2022-01-18  Alex Christensen  <achristensen@webkit.org>
 
         Use c++2a instead of gnu++2a for Cocoa builds
diff --git a/Source/WebCore/PAL/pal/spi/cf/CFNetworkSPI.h b/Source/WebCore/PAL/pal/spi/cf/CFNetworkSPI.h
index d247a2d..a7a809f 100644
--- a/Source/WebCore/PAL/pal/spi/cf/CFNetworkSPI.h
+++ b/Source/WebCore/PAL/pal/spi/cf/CFNetworkSPI.h
@@ -359,6 +359,9 @@
 void _CFCachedURLResponseSetBecameFileBackedCallBackBlock(CFCachedURLResponseRef, CFCachedURLResponseCallBackBlock, dispatch_queue_t);
 #endif
 
+#if HAVE(CFNETWORK_DISABLE_CACHE_SPI)
+void _CFURLStorageSessionDisableCache(CFURLStorageSessionRef);
+#endif
 CFURLStorageSessionRef _CFURLStorageSessionCreate(CFAllocatorRef, CFStringRef, CFDictionaryRef);
 CFURLCacheRef _CFURLStorageSessionCopyCache(CFAllocatorRef, CFURLStorageSessionRef);
 void CFURLRequestSetShouldStartSynchronously(CFURLRequestRef, Boolean);
diff --git a/Source/WebCore/platform/network/NetworkStorageSession.h b/Source/WebCore/platform/network/NetworkStorageSession.h
index 31bc157..3309945 100644
--- a/Source/WebCore/platform/network/NetworkStorageSession.h
+++ b/Source/WebCore/platform/network/NetworkStorageSession.h
@@ -120,7 +120,8 @@
 #endif
 
 #if PLATFORM(COCOA) || USE(CFURLCONNECTION)
-    WEBCORE_EXPORT static RetainPtr<CFURLStorageSessionRef> createCFStorageSessionForIdentifier(CFStringRef identifier);
+    enum class ShouldDisableCFURLCache : bool { No, Yes };
+    WEBCORE_EXPORT static RetainPtr<CFURLStorageSessionRef> createCFStorageSessionForIdentifier(CFStringRef identifier, ShouldDisableCFURLCache = ShouldDisableCFURLCache::No);
     enum class IsInMemoryCookieStore : bool { No, Yes };
     WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID, RetainPtr<CFURLStorageSessionRef>&&, RetainPtr<CFHTTPCookieStorageRef>&&, IsInMemoryCookieStore = IsInMemoryCookieStore::No);
     WEBCORE_EXPORT explicit NetworkStorageSession(PAL::SessionID);
@@ -301,7 +302,7 @@
 };
 
 #if PLATFORM(COCOA) || USE(CFURLCONNECTION)
-WEBCORE_EXPORT RetainPtr<CFURLStorageSessionRef> createPrivateStorageSession(CFStringRef identifier, std::optional<HTTPCookieAcceptPolicy> = std::nullopt);
+WEBCORE_EXPORT RetainPtr<CFURLStorageSessionRef> createPrivateStorageSession(CFStringRef identifier, std::optional<HTTPCookieAcceptPolicy> = std::nullopt, NetworkStorageSession::ShouldDisableCFURLCache = NetworkStorageSession::ShouldDisableCFURLCache::No);
 #endif
 
 }
diff --git a/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp b/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp
index 48fad82..38036eb 100644
--- a/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp
+++ b/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp
@@ -39,21 +39,31 @@
 
 namespace WebCore {
 
-RetainPtr<CFURLStorageSessionRef> NetworkStorageSession::createCFStorageSessionForIdentifier(CFStringRef identifier)
+RetainPtr<CFURLStorageSessionRef> NetworkStorageSession::createCFStorageSessionForIdentifier(CFStringRef identifier, ShouldDisableCFURLCache shouldDisableCFURLCache)
 {
     auto storageSession = adoptCF(_CFURLStorageSessionCreate(kCFAllocatorDefault, identifier, nullptr));
 
     if (!storageSession)
         return nullptr;
 
-    auto cache = adoptCF(_CFURLStorageSessionCopyCache(kCFAllocatorDefault, storageSession.get()));
-    if (!cache)
-        return nullptr;
+    if (shouldDisableCFURLCache == ShouldDisableCFURLCache::Yes) {
+#if HAVE(CFNETWORK_DISABLE_CACHE_SPI)
+        _CFURLStorageSessionDisableCache(storageSession.get());
+#else
+        shouldDisableCFURLCache = ShouldDisableCFURLCache::No;
+#endif
+    }
 
-    CFURLCacheSetDiskCapacity(cache.get(), 0);
+    if (shouldDisableCFURLCache == ShouldDisableCFURLCache::No) {
+        auto cache = adoptCF(_CFURLStorageSessionCopyCache(kCFAllocatorDefault, storageSession.get()));
+        if (!cache)
+            return nullptr;
 
-    auto sharedCache = adoptCF(CFURLCacheCopySharedURLCache());
-    CFURLCacheSetMemoryCapacity(cache.get(), CFURLCacheMemoryCapacity(sharedCache.get()));
+        CFURLCacheSetDiskCapacity(cache.get(), 0);
+
+        auto sharedCache = adoptCF(CFURLCacheCopySharedURLCache());
+        CFURLCacheSetMemoryCapacity(cache.get(), CFURLCacheMemoryCapacity(sharedCache.get()));
+    }
 
     if (!NetworkStorageSession::processMayUseCookieAPI())
         return storageSession;
diff --git a/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNetWin.cpp b/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNetWin.cpp
index 8272f76..03b40b2 100644
--- a/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNetWin.cpp
+++ b/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNetWin.cpp
@@ -79,7 +79,7 @@
     return CFHTTPCookieStorageAcceptPolicyAlways;
 }
 
-RetainPtr<CFURLStorageSessionRef> createPrivateStorageSession(CFStringRef identifier, std::optional<HTTPCookieAcceptPolicy> cookieAcceptPolicy)
+RetainPtr<CFURLStorageSessionRef> createPrivateStorageSession(CFStringRef identifier, std::optional<HTTPCookieAcceptPolicy> cookieAcceptPolicy, NetworkStorageSession::ShouldDisableCFURLCache)
 {
     const void* sessionPropertyKeys[] = { _kCFURLStorageSessionIsPrivate };
     const void* sessionPropertyValues[] = { kCFBooleanTrue };
diff --git a/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm b/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
index b28ebbd..299fc4b 100644
--- a/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
+++ b/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
@@ -171,7 +171,7 @@
     return *m_cookieStorageObserver;
 }
 
-RetainPtr<CFURLStorageSessionRef> createPrivateStorageSession(CFStringRef identifier, std::optional<HTTPCookieAcceptPolicy> cookieAcceptPolicy)
+RetainPtr<CFURLStorageSessionRef> createPrivateStorageSession(CFStringRef identifier, std::optional<HTTPCookieAcceptPolicy> cookieAcceptPolicy, NetworkStorageSession::ShouldDisableCFURLCache shouldDisableCFURLCache)
 {
     const void* sessionPropertyKeys[] = { _kCFURLStorageSessionIsPrivate };
     const void* sessionPropertyValues[] = { kCFBooleanTrue };
@@ -181,6 +181,14 @@
     if (!storageSession)
         return nullptr;
 
+    if (shouldDisableCFURLCache == NetworkStorageSession::ShouldDisableCFURLCache::Yes) {
+#if HAVE(CFNETWORK_DISABLE_CACHE_SPI)
+        _CFURLStorageSessionDisableCache(storageSession.get());
+#else
+        shouldDisableCFURLCache = NetworkStorageSession::ShouldDisableCFURLCache::No;
+#endif
+    }
+
     // The private storage session should have the same properties as the default storage session,
     // with the exception that it should be in-memory only storage.
 
@@ -188,12 +196,13 @@
     // This could occur if there is an issue figuring out where to place a storage on disk (e.g. the
     // sandbox does not allow CFNetwork access).
 
-    auto cache = adoptCF(_CFURLStorageSessionCopyCache(kCFAllocatorDefault, storageSession.get()));
-    if (!cache)
-        return nullptr;
+    if (shouldDisableCFURLCache == NetworkStorageSession::ShouldDisableCFURLCache::No) {
+        auto cache = adoptCF(_CFURLStorageSessionCopyCache(kCFAllocatorDefault, storageSession.get()));
+        if (!cache)
+            return nullptr;
 
-    CFURLCacheSetDiskCapacity(cache.get(), 0); // Setting disk cache size should not be necessary once <rdar://problem/12656814> is fixed.
-    CFURLCacheSetMemoryCapacity(cache.get(), [[NSURLCache sharedURLCache] memoryCapacity]);
+        CFURLCacheSetMemoryCapacity(cache.get(), [[NSURLCache sharedURLCache] memoryCapacity]);
+    }
 
     auto cookieStorage = adoptCF(_CFURLStorageSessionCopyCookieStorage(kCFAllocatorDefault, storageSession.get()));
     if (!cookieStorage)
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 4f53f5c..6841603 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,15 @@
+2022-01-21  Sihui Liu  <sihui_liu@apple.com>
+
+        Disable CFURLCache in WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=234988
+        <rdar://problem/87619196>
+
+        Reviewed by Geoffrey Garen.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::newTestingSession):
+        (WebKit::NetworkProcess::ensureSession):
+
 2022-01-21  Per Arne Vollan  <pvollan@apple.com>
 
         Inject Launch Services database before NSApplication is initialized
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.cpp b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
index 26bd107..310c6c5 100644
--- a/Source/WebKit/NetworkProcess/NetworkProcess.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
@@ -443,7 +443,7 @@
 {
 #if PLATFORM(COCOA)
     // Session name should be short enough for shared memory region name to be under the limit, otherwise sandbox rules won't work (see <rdar://problem/13642852>).
-    auto session = WebCore::createPrivateStorageSession(makeString("WebKit Test-", getCurrentProcessID()).createCFString().get());
+    auto session = WebCore::createPrivateStorageSession(makeString("WebKit Test-", getCurrentProcessID()).createCFString().get(), std::nullopt, NetworkStorageSession::ShouldDisableCFURLCache::Yes);
     RetainPtr<CFHTTPCookieStorageRef> cookieStorage;
     if (WebCore::NetworkStorageSession::processMayUseCookieAPI()) {
         ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));
@@ -475,7 +475,7 @@
     RetainPtr<CFURLStorageSessionRef> storageSession;
     RetainPtr<CFStringRef> cfIdentifier = makeString(identifierBase, ".PrivateBrowsing.", createCanonicalUUIDString()).createCFString();
     if (sessionID.isEphemeral())
-        storageSession = createPrivateStorageSession(cfIdentifier.get());
+        storageSession = createPrivateStorageSession(cfIdentifier.get(), std::nullopt, WebCore::NetworkStorageSession::ShouldDisableCFURLCache::Yes);
     else if (sessionID != PAL::SessionID::defaultSessionID())
         storageSession = WebCore::NetworkStorageSession::createCFStorageSessionForIdentifier(cfIdentifier.get());
 
diff --git a/Source/WebKitLegacy/ChangeLog b/Source/WebKitLegacy/ChangeLog
index 2a38a60..3238c23 100644
--- a/Source/WebKitLegacy/ChangeLog
+++ b/Source/WebKitLegacy/ChangeLog
@@ -1,3 +1,14 @@
+2022-01-21  Sihui Liu  <sihui_liu@apple.com>
+
+        Disable CFURLCache in WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=234988
+        <rdar://problem/87619196>
+
+        Reviewed by Geoffrey Garen.
+
+        * WebCoreSupport/NetworkStorageSessionMap.cpp:
+        (NetworkStorageSessionMap::ensureSession):
+
 2022-01-11  Michael Saboff  <msaboff@apple.com>
 
         Fixed installhdr build failures in WebCore and WebKitLegacy
diff --git a/Source/WebKitLegacy/WebCoreSupport/NetworkStorageSessionMap.cpp b/Source/WebKitLegacy/WebCoreSupport/NetworkStorageSessionMap.cpp
index 4d0b26d..a4787a1 100644
--- a/Source/WebKitLegacy/WebCoreSupport/NetworkStorageSessionMap.cpp
+++ b/Source/WebKitLegacy/WebCoreSupport/NetworkStorageSessionMap.cpp
@@ -90,7 +90,7 @@
     if (sessionID.isEphemeral())
         storageSession = WebCore::createPrivateStorageSession(identifier.get());
     else
-        storageSession = WebCore::NetworkStorageSession::createCFStorageSessionForIdentifier(identifier.get());
+        storageSession = WebCore::NetworkStorageSession::createCFStorageSessionForIdentifier(identifier.get(), WebCore::NetworkStorageSession::ShouldDisableCFURLCache::Yes);
 
     RetainPtr<CFHTTPCookieStorageRef> cookieStorage;
     if (WebCore::NetworkStorageSession::processMayUseCookieAPI()) {